[libgda: 1/3] sqlcipher.patch was updated against sqlcipehr
- From: Rodrigo Moya <rodrigo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda: 1/3] sqlcipher.patch was updated against sqlcipehr
- Date: Tue, 3 Apr 2018 10:31:37 +0000 (UTC)
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>→<td>BLOB result
++** <tr><td><b>sqlite3_column_double</b><td>→<td>REAL result
++** <tr><td><b>sqlite3_column_int</b><td>→<td>32-bit INTEGER result
++** <tr><td><b>sqlite3_column_int64</b><td>→<td>64-bit INTEGER result
++** <tr><td><b>sqlite3_column_text</b><td>→<td>UTF-8 TEXT result
++** <tr><td><b>sqlite3_column_text16</b><td>→<td>UTF-16 TEXT result
++** <tr><td><b>sqlite3_column_value</b><td>→<td>The result as an
++** [sqlite3_value|unprotected sqlite3_value] object.
++** <tr><td> <td> <td>
++** <tr><td><b>sqlite3_column_bytes</b><td>→<td>Size of a BLOB
++** or a UTF-8 TEXT result in bytes
++** <tr><td><b>sqlite3_column_bytes16 </b>
++** <td>→ <td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_column_type</b><td>→<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>→<td>BLOB value
++** <tr><td><b>sqlite3_value_double</b><td>→<td>REAL value
++** <tr><td><b>sqlite3_value_int</b><td>→<td>32-bit INTEGER value
++** <tr><td><b>sqlite3_value_int64</b><td>→<td>64-bit INTEGER value
++** <tr><td><b>sqlite3_value_pointer</b><td>→<td>Pointer value
++** <tr><td><b>sqlite3_value_text</b><td>→<td>UTF-8 TEXT value
++** <tr><td><b>sqlite3_value_text16</b><td>→<td>UTF-16 TEXT value in
++** the native byteorder
++** <tr><td><b>sqlite3_value_text16be</b><td>→<td>UTF-16be TEXT value
++** <tr><td><b>sqlite3_value_text16le</b><td>→<td>UTF-16le TEXT value
++** <tr><td> <td> <td>
++** <tr><td><b>sqlite3_value_bytes</b><td>→<td>Size of a BLOB
++** or a UTF-8 TEXT in bytes
++** <tr><td><b>sqlite3_value_bytes16 </b>
++** <td>→ <td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_value_type</b><td>→<td>Default
++** datatype of the value
++** <tr><td><b>sqlite3_value_numeric_type </b>
++** <td>→ <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>
++** int nChangeset,
++** void *pChangeset,
++** </pre>
++**
++** Is replaced by:
++**
++** <pre>
++** int (*xInput)(void *pIn, void *pData, int *pnData),
++** 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>
++** int *pnChangeset,
++** void **ppChangeset,
++** </pre>
++**
++** Is replaced by:
++**
++** <pre>
++** int (*xOutput)(void *pOut, const void *pData, int nData),
++** 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>→<td>BLOB result
++** <tr><td><b>sqlite3_column_double</b><td>→<td>REAL result
++** <tr><td><b>sqlite3_column_int</b><td>→<td>32-bit INTEGER result
++** <tr><td><b>sqlite3_column_int64</b><td>→<td>64-bit INTEGER result
++** <tr><td><b>sqlite3_column_text</b><td>→<td>UTF-8 TEXT result
++** <tr><td><b>sqlite3_column_text16</b><td>→<td>UTF-16 TEXT result
++** <tr><td><b>sqlite3_column_value</b><td>→<td>The result as an
++** [sqlite3_value|unprotected sqlite3_value] object.
++** <tr><td> <td> <td>
++** <tr><td><b>sqlite3_column_bytes</b><td>→<td>Size of a BLOB
++** or a UTF-8 TEXT result in bytes
++** <tr><td><b>sqlite3_column_bytes16 </b>
++** <td>→ <td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_column_type</b><td>→<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>→<td>BLOB value
++** <tr><td><b>sqlite3_value_double</b><td>→<td>REAL value
++** <tr><td><b>sqlite3_value_int</b><td>→<td>32-bit INTEGER value
++** <tr><td><b>sqlite3_value_int64</b><td>→<td>64-bit INTEGER value
++** <tr><td><b>sqlite3_value_pointer</b><td>→<td>Pointer value
++** <tr><td><b>sqlite3_value_text</b><td>→<td>UTF-8 TEXT value
++** <tr><td><b>sqlite3_value_text16</b><td>→<td>UTF-16 TEXT value in
++** the native byteorder
++** <tr><td><b>sqlite3_value_text16be</b><td>→<td>UTF-16be TEXT value
++** <tr><td><b>sqlite3_value_text16le</b><td>→<td>UTF-16le TEXT value
++** <tr><td> <td> <td>
++** <tr><td><b>sqlite3_value_bytes</b><td>→<td>Size of a BLOB
++** or a UTF-8 TEXT in bytes
++** <tr><td><b>sqlite3_value_bytes16 </b>
++** <td>→ <td>Size of UTF-16
++** TEXT in bytes
++** <tr><td><b>sqlite3_value_type</b><td>→<td>Default
++** datatype of the value
++** <tr><td><b>sqlite3_value_numeric_type </b>
++** <td>→ <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>
++** int nChangeset,
++** void *pChangeset,
++** </pre>
++**
++** Is replaced by:
++**
++** <pre>
++** int (*xInput)(void *pIn, void *pData, int *pnData),
++** 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>
++** int *pnChangeset,
++** void **ppChangeset,
++** </pre>
++**
++** Is replaced by:
++**
++** <pre>
++** int (*xOutput)(void *pOut, const void *pData, int nData),
++** 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, ¬Used);
++ 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], ¬Used, 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' → BLOB
++** <li> P2=='B' → TEXT
++** <li> P2=='C' → NUMERIC
++** <li> P2=='D' → INTEGER
++** <li> P2=='E' → 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(©);
++ }
++ }
++ 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, ®Free1);
++ r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2);
++ 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, ®ToFree);
+@@ -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, ®Free1);
+- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+- 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, ®Free1);
+- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+- 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, ®Free1);
++ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
++ 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, ®Free1);
+ 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, ®Free1);
+- r2 = sqlite3ExprCodeTemp(pParse, pRight, ®Free2);
+- 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, ®Free2);
+- 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, ®Free1));
++ exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1));
+ 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, ®Free1));
+- if( jumpIfTrue ){
+- sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
+- }else{
+- sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
++ exprToRegister(&exprX, exprCodeVector(pParse, &exprX, ®Free1));
++ 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, ®Free1);
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+@@ -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, ®Free1);
+- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+- 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, ®Free1);
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+@@ -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, ®Free1);
+- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+- 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, ¬Used, 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, ¤tSize);
-- 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, ¤tSize);
-+ 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, ¬Used, 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, ¬Used, 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]