merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sun, 02 Apr 2017 18:52:13 +0200
changeset 350870 38894655c89e68bcd8f45d31a0d3005f2c2b53db
parent 350837 8fcb1f73a45d2d1619622ef8f30c77dac70cf555 (current diff)
parent 350869 89b885c2cb80f6f346205d986933fef47001738b (diff)
child 350871 6ba6c3b755870fbc711b5050b88d887d2fdff851
child 350898 f2d18607854251fc668b6e156c24282888858680
child 351373 2afb34b24e7814031d145d40e853bc5b27b46f62
push id39961
push userarchaeopteryx@coole-files.de
push dateSun, 02 Apr 2017 16:54:14 +0000
treeherderautoland@6ba6c3b75587 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone55.0a1
first release with
nightly linux32
38894655c89e / 55.0a1 / 20170403100136 / files
nightly linux64
38894655c89e / 55.0a1 / 20170403100136 / files
nightly mac
38894655c89e / 55.0a1 / 20170403030207 / files
nightly win32
38894655c89e / 55.0a1 / 20170403030207 / files
nightly win64
38894655c89e / 55.0a1 / 20170403030207 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central. r=merge a=merge MozReview-Commit-ID: EjvlThqFc40
browser/components/extensions/ext-desktop-runtime.js
db/sqlite3/src/sqlite3.c
db/sqlite3/src/sqlite3.h
dom/svg/SVGZoomEvent.cpp
dom/svg/SVGZoomEvent.h
layout/base/nsCSSFrameConstructor.cpp
mobile/android/base/resources/layout/webapp_activity.xml
toolkit/components/extensions/test/xpcshell/test_ext_apimanager.js
toolkit/components/extensions/test/xpcshell/test_ext_schemas_api_injection.js
old mode 100755
new mode 100644
--- a/db/sqlite3/src/sqlite3.c
+++ b/db/sqlite3/src/sqlite3.c
@@ -1,11 +1,11 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.17.0.  By combining all the individual C code files into this
+** version 3.18.0.  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
 ** of 5% or more are commonly seen when SQLite is compiled as a single
 ** translation unit.
 **
 ** 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
@@ -386,26 +386,26 @@ extern "C" {
 ** and Z will be reset to zero.
 **
 ** 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.17.0"
-#define SQLITE_VERSION_NUMBER 3017000
-#define SQLITE_SOURCE_ID      "2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c"
+#define SQLITE_VERSION        "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID      "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
 ** 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
@@ -2312,30 +2312,40 @@ SQLITE_API int sqlite3_extended_result_c
 ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
 ** has a unique 64-bit signed
 ** integer key called the [ROWID | "rowid"]. ^The rowid is always available
 ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
 ** names are not also used by explicitly declared columns. ^If
 ** 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
 ** routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
 ** and INSERT OR ABORT make no changes to the return value of this
 ** routine when their insertion fails.  ^(When INSERT OR REPLACE
 ** encounters a constraint violation, it does not fail.  The
 ** INSERT continues to completion after deleting rows that caused
@@ -2353,16 +2363,26 @@ SQLITE_API int sqlite3_extended_result_c
 ** function is running and thus changes the last insert [rowid],
 ** then the value returned by [sqlite3_last_insert_rowid()] is
 ** unpredictable and might not equal either the old or the new
 ** last insert [rowid].
 */
 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
 ** METHOD: sqlite3
 **
 ** ^This function returns the number of rows modified, inserted or
 ** deleted by the most recently completed INSERT, UPDATE or DELETE
 ** statement on the database connection specified by the only parameter.
 ** ^Executing any other type of SQL statement does not modify the value
 ** returned by this function.
@@ -3676,19 +3696,19 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
 **
 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
 **
 ** [[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>)^
 **
 ** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
 ** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
 **
 ** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
@@ -3716,16 +3736,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 #define SQLITE_LIMIT_VDBE_OP                   5
 #define SQLITE_LIMIT_FUNCTION_ARG              6
 #define SQLITE_LIMIT_ATTACHED                  7
 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
 #define SQLITE_LIMIT_WORKER_THREADS           11
 
+
 /*
 ** CAPI3REF: Compiling An SQL Statement
 ** KEYWORDS: {SQL statement compiler}
 ** METHOD: sqlite3
 ** CONSTRUCTOR: sqlite3_stmt
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
 ** program using one of these routines.
@@ -10843,17 +10864,17 @@ struct fts5_api {
 # define SQLITE_MAX_COMPOUND_SELECT 500
 #endif
 
 /*
 ** The maximum number of opcodes in a VDBE program.
 ** Not currently enforced.
 */
 #ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
+# define SQLITE_MAX_VDBE_OP 250000000
 #endif
 
 /*
 ** The maximum number of arguments to an SQL function.
 */
 #ifndef SQLITE_MAX_FUNCTION_ARG
 # define SQLITE_MAX_FUNCTION_ARG 127
 #endif
@@ -12454,16 +12475,17 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCur
 SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
 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);
@@ -12620,16 +12642,17 @@ typedef struct VdbeOp VdbeOp;
 /*
 ** A sub-routine used to implement a trigger program.
 */
 struct SubProgram {
   VdbeOp *aOp;                  /* Array of opcodes for sub-program */
   int nOp;                      /* Elements in aOp[] */
   int nMem;                     /* Number of memory cells required */
   int nCsr;                     /* Number of cursors required */
+  u8 *aOnce;                    /* Array of OP_Once flags */
   void *token;                  /* id that may be used to recursive triggers */
   SubProgram *pNext;            /* Next sub-program already visited */
 };
 
 /*
 ** A smaller version of VdbeOp used for the VdbeAddOpList() function because
 ** it takes up less space.
 */
@@ -12754,123 +12777,125 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_Add            47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
 #define OP_Subtract       48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
 #define OP_Multiply       49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
 #define OP_Divide         50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
 #define OP_Remainder      51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
 #define OP_Concat         52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
 #define OP_Last           53
 #define OP_BitNot         54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_SorterSort     55
-#define OP_Sort           56
-#define OP_Rewind         57
-#define OP_IdxLE          58 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxGT          59 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxLT          60 /* synopsis: key=r[P3@P4]                     */
-#define OP_IdxGE          61 /* synopsis: key=r[P3@P4]                     */
-#define OP_RowSetRead     62 /* synopsis: r[P3]=rowset(P1)                 */
-#define OP_RowSetTest     63 /* synopsis: if r[P3] in rowset(P1) goto P2   */
-#define OP_Program        64
-#define OP_FkIfZero       65 /* synopsis: if fkctr[P1]==0 goto P2          */
-#define OP_IfPos          66 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero      67 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
-#define OP_DecrJumpZero   68 /* synopsis: if (--r[P1])==0 goto P2          */
-#define OP_IncrVacuum     69
-#define OP_VNext          70
-#define OP_Init           71 /* synopsis: Start at P2                      */
-#define OP_Return         72
-#define OP_EndCoroutine   73
-#define OP_HaltIfNull     74 /* synopsis: if r[P3]=null halt               */
-#define OP_Halt           75
-#define OP_Integer        76 /* synopsis: r[P2]=P1                         */
-#define OP_Int64          77 /* synopsis: r[P2]=P4                         */
-#define OP_String         78 /* synopsis: r[P2]='P4' (len=P1)              */
-#define OP_Null           79 /* synopsis: r[P2..P3]=NULL                   */
-#define OP_SoftNull       80 /* synopsis: r[P1]=NULL                       */
-#define OP_Blob           81 /* synopsis: r[P2]=P4 (len=P1)                */
-#define OP_Variable       82 /* synopsis: r[P2]=parameter(P1,P4)           */
-#define OP_Move           83 /* synopsis: r[P2@P3]=r[P1@P3]                */
-#define OP_Copy           84 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
-#define OP_SCopy          85 /* synopsis: r[P2]=r[P1]                      */
-#define OP_IntCopy        86 /* synopsis: r[P2]=r[P1]                      */
-#define OP_ResultRow      87 /* synopsis: output=r[P1@P2]                  */
-#define OP_CollSeq        88
-#define OP_Function0      89 /* synopsis: r[P3]=func(r[P2@P5])             */
-#define OP_Function       90 /* synopsis: r[P3]=func(r[P2@P5])             */
-#define OP_AddImm         91 /* synopsis: r[P1]=r[P1]+P2                   */
-#define OP_RealAffinity   92
-#define OP_Cast           93 /* synopsis: affinity(r[P1])                  */
-#define OP_Permutation    94
-#define OP_Compare        95 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
-#define OP_Column         96 /* synopsis: r[P3]=PX                         */
+#define OP_IfSmaller      55
+#define OP_SorterSort     56
+#define OP_Sort           57
+#define OP_Rewind         58
+#define OP_IdxLE          59 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxGT          60 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxLT          61 /* synopsis: key=r[P3@P4]                     */
+#define OP_IdxGE          62 /* synopsis: key=r[P3@P4]                     */
+#define OP_RowSetRead     63 /* synopsis: r[P3]=rowset(P1)                 */
+#define OP_RowSetTest     64 /* synopsis: if r[P3] in rowset(P1) goto P2   */
+#define OP_Program        65
+#define OP_FkIfZero       66 /* synopsis: if fkctr[P1]==0 goto P2          */
+#define OP_IfPos          67 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero      68 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_DecrJumpZero   69 /* synopsis: if (--r[P1])==0 goto P2          */
+#define OP_IncrVacuum     70
+#define OP_VNext          71
+#define OP_Init           72 /* synopsis: Start at P2                      */
+#define OP_Return         73
+#define OP_EndCoroutine   74
+#define OP_HaltIfNull     75 /* synopsis: if r[P3]=null halt               */
+#define OP_Halt           76
+#define OP_Integer        77 /* synopsis: r[P2]=P1                         */
+#define OP_Int64          78 /* synopsis: r[P2]=P4                         */
+#define OP_String         79 /* synopsis: r[P2]='P4' (len=P1)              */
+#define OP_Null           80 /* synopsis: r[P2..P3]=NULL                   */
+#define OP_SoftNull       81 /* synopsis: r[P1]=NULL                       */
+#define OP_Blob           82 /* synopsis: r[P2]=P4 (len=P1)                */
+#define OP_Variable       83 /* synopsis: r[P2]=parameter(P1,P4)           */
+#define OP_Move           84 /* synopsis: r[P2@P3]=r[P1@P3]                */
+#define OP_Copy           85 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+#define OP_SCopy          86 /* synopsis: r[P2]=r[P1]                      */
+#define OP_IntCopy        87 /* synopsis: r[P2]=r[P1]                      */
+#define OP_ResultRow      88 /* synopsis: output=r[P1@P2]                  */
+#define OP_CollSeq        89
+#define OP_Function0      90 /* synopsis: r[P3]=func(r[P2@P5])             */
+#define OP_Function       91 /* synopsis: r[P3]=func(r[P2@P5])             */
+#define OP_AddImm         92 /* synopsis: r[P1]=r[P1]+P2                   */
+#define OP_RealAffinity   93
+#define OP_Cast           94 /* synopsis: affinity(r[P1])                  */
+#define OP_Permutation    95
+#define OP_Compare        96 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
 #define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
-#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_OpenAutoindex 106 /* synopsis: nColumn=P2                       */
-#define OP_OpenEphemeral 107 /* synopsis: nColumn=P2                       */
-#define OP_SorterOpen    108
-#define OP_SequenceTest  109 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
-#define OP_OpenPseudo    110 /* synopsis: P3 columns in r[P2]              */
-#define OP_Close         111
-#define OP_ColumnsUsed   112
-#define OP_Sequence      113 /* synopsis: r[P2]=cursor[P1].ctr++           */
-#define OP_NewRowid      114 /* synopsis: r[P2]=rowid                      */
-#define OP_Insert        115 /* synopsis: intkey=r[P3] data=r[P2]          */
-#define OP_InsertInt     116 /* synopsis: intkey=P3 data=r[P2]             */
-#define OP_Delete        117
-#define OP_ResetCount    118
-#define OP_SorterCompare 119 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData    120 /* synopsis: r[P2]=data                       */
-#define OP_RowData       121 /* synopsis: r[P2]=data                       */
-#define OP_Rowid         122 /* synopsis: r[P2]=rowid                      */
-#define OP_NullRow       123
-#define OP_SorterInsert  124 /* synopsis: key=r[P2]                        */
-#define OP_IdxInsert     125 /* synopsis: key=r[P2]                        */
-#define OP_IdxDelete     126 /* synopsis: key=r[P2@P3]                     */
-#define OP_Seek          127 /* synopsis: Move P3 to P1.rowid              */
-#define OP_IdxRowid      128 /* synopsis: r[P2]=rowid                      */
-#define OP_Destroy       129
-#define OP_Clear         130
-#define OP_ResetSorter   131
+#define OP_Column         98 /* synopsis: r[P3]=PX                         */
+#define OP_Affinity       99 /* synopsis: affinity(r[P1@P2])               */
+#define OP_MakeRecord    100 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+#define OP_Count         101 /* synopsis: r[P2]=count()                    */
+#define OP_ReadCookie    102
+#define OP_SetCookie     103
+#define OP_ReopenIdx     104 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenRead      105 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenWrite     106 /* synopsis: root=P2 iDb=P3                   */
+#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_Seek          128 /* synopsis: Move P3 to P1.rowid              */
+#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_CreateIndex   133 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_CreateTable   134 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_ParseSchema   135
-#define OP_LoadAnalysis  136
-#define OP_DropTable     137
-#define OP_DropIndex     138
-#define OP_DropTrigger   139
-#define OP_IntegrityCk   140
-#define OP_RowSetAdd     141 /* synopsis: rowset(P1)=r[P2]                 */
-#define OP_Param         142
-#define OP_FkCounter     143 /* synopsis: fkctr[P1]+=P2                    */
-#define OP_MemMax        144 /* synopsis: r[P1]=max(r[P1],r[P2])           */
-#define OP_OffsetLimit   145 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggStep0      146 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-#define OP_AggStep       147 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-#define OP_AggFinal      148 /* synopsis: accum=r[P1] N=P2                 */
-#define OP_Expire        149
-#define OP_TableLock     150 /* synopsis: iDb=P1 root=P2 write=P3          */
-#define OP_VBegin        151
-#define OP_VCreate       152
-#define OP_VDestroy      153
-#define OP_VOpen         154
-#define OP_VColumn       155 /* synopsis: r[P3]=vcolumn(P2)                */
-#define OP_VRename       156
-#define OP_Pagecount     157
-#define OP_MaxPgcnt      158
-#define OP_CursorHint    159
-#define OP_Noop          160
-#define OP_Explain       161
+#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_CursorHint    161
+#define OP_Noop          162
+#define OP_Explain       163
 
 /* 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        0x01  /* jump:  P2 holds jmp target */
 #define OPFLG_IN1         0x02  /* in1:   P1 is an input */
 #define OPFLG_IN2         0x04  /* in2:   P2 is an input */
@@ -12880,38 +12905,38 @@ typedef struct VdbeOpList VdbeOpList;
 #define OPFLG_INITIALIZER {\
 /*   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, 0x09,\
 /*  24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\
 /*  32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
 /*  40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\
 /*  48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\
-/*  56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23, 0x0b,\
-/*  64 */ 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,\
-/*  72 */ 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10,\
-/*  80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/*  88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
-/*  96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/*  56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23,\
+/*  64 */ 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\
+/*  72 */ 0x01, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\
+/*  80 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\
+/*  88 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\
+/*  96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
 /* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00, 0x00,\
-/* 128 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
-/* 144 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/* 160 */ 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,}
 
 /* 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  71  /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE  72  /* Maximum JUMP opcode */
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
 ** for a description of what each of these routines does.
 */
@@ -13865,17 +13890,17 @@ SQLITE_PRIVATE void sqlite3OsCloseFree(s
 **   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 (PAGER_SYNCHRONOUS_FULL-1)
+# 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
 ** of the following structure.  There are normally two of these structures
@@ -14071,16 +14096,17 @@ struct sqlite3 {
   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() */
   int nTotalChange;             /* Value returned by sqlite3_total_changes() */
   int aLimit[SQLITE_N_LIMIT];   /* Limits */
   int nMaxSorterMmap;           /* Maximum size of regions mapped by sorter */
   struct sqlite3InitInfo {      /* Information used during initialization */
     int newTnum;                /* Rootpage of table being initialized */
@@ -14586,24 +14612,24 @@ struct Table {
   Index *pIndex;       /* List of SQL indexes on this table. */
   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 */
   ExprList *pCheck;    /* All CHECK constraints */
                        /*   ... 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 */
   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;  /* 0: module 1: schema 2: vtab name 3...: args */
   VTable *pVTable;     /* List of VTable objects. */
@@ -14617,33 +14643,35 @@ struct Table {
 ** Allowed values for Table.tabFlags.
 **
 ** 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.  PRIMARY KEY is the key */
-#define TF_NoVisibleRowid  0x40    /* No user-visible "rowid" column */
-#define TF_OOOHidden       0x80    /* 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
 ** done as a macro so that it will be optimized out when virtual
 ** table support is omitted from the build.
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-#  define IsVirtual(X)      (((X)->tabFlags & TF_Virtual)!=0)
+#  define IsVirtual(X)      ((X)->nModuleArg)
 #else
 #  define IsVirtual(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
@@ -14868,16 +14896,17 @@ struct Index {
   u16 nColumn;             /* Number of columns stored in the index */
   u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   unsigned idxType:2;      /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
   unsigned bUnordered:1;   /* Use this index for == or IN queries only */
   unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
   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 */
   tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
   IndexSample *aSample;    /* Samples of the left-most key */
   tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
   tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
 #endif
@@ -15178,17 +15207,17 @@ struct Expr {
 ** column expression as it exists in a SELECT statement.  However, if
 ** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
 ** of the result column in the form: DATABASE.TABLE.COLUMN.  This later
 ** form is used for name resolution with nested FROM clauses.
 */
 struct ExprList {
   int nExpr;             /* Number of expressions on the list */
   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 */
     unsigned done :1;       /* A flag to indicate when processing is finished */
     unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
     unsigned reusable :1;   /* Constant expression is reusable */
     union {
       struct {
@@ -16501,16 +16530,17 @@ SQLITE_PRIVATE Table *sqlite3LocateTable
 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*,Token*);
 SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
 SQLITE_PRIVATE int sqlite3ExprCompare(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 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
@@ -17447,25 +17477,31 @@ static const char * const azCompileOpt[]
 #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
+#ifdef 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_DEFAULT_SYNCHRONOUS
+  "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
+#endif
+#if SQLITE_DEFAULT_WAL_SYNCHRONOUS
+  "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
+#endif
 #if SQLITE_DIRECT_OVERFLOW_READ
   "DIRECT_OVERFLOW_READ",
 #endif
 #if SQLITE_DISABLE_DIRSYNC
   "DISABLE_DIRSYNC",
 #endif
 #if SQLITE_DISABLE_LFS
   "DISABLE_LFS",
@@ -18032,16 +18068,17 @@ struct VdbeCursor {
 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 */
   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 nChildMem;          /* Number of memory cells for child frame */
@@ -19502,28 +19539,29 @@ static int parseModifier(
     case 's': {
       /*
       **    start of TTTTT
       **
       ** Move the date backwards to the beginning of the current day,
       ** or month or year.
       */
       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( sqlite3_stricmp(z,"month")==0 ){
         p->D = 1;
         rc = 0;
       }else if( sqlite3_stricmp(z,"year")==0 ){
-        computeYMD(p);
         p->M = 1;
         p->D = 1;
         rc = 0;
       }else if( sqlite3_stricmp(z,"day")==0 ){
         rc = 0;
       }
       break;
     }
@@ -20635,17 +20673,19 @@ SQLITE_PRIVATE void sqlite3MemSetDefault
 #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
 
 /*
 ** Use the zone allocator available on apple products unless the
 ** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
 */
 #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));
 #define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
 #define SQLITE_MALLOCSIZE(x) \
         (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
 
 #else /* if not __APPLE__ */
@@ -20828,29 +20868,20 @@ static int sqlite3MemInit(void *NotUsed)
   /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
   sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
   if( cpuCount>1 ){
     /* defer MT decisions to system malloc */
     _sqliteZone_ = malloc_default_zone();
   }else{
     /* only 1 core, use our own zone to contention over global locks, 
     ** e.g. we have our own dedicated locks */
-    bool success;
-    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
-    malloc_set_zone_name(newzone, "Sqlite_Heap");
-    do{
-      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
-                                 (void * volatile *)&_sqliteZone_);
-    }while(!_sqliteZone_);
-    if( !success ){
-      /* somebody registered a zone first */
-      malloc_destroy_zone(newzone);
-    }
-  }
-#endif
+    _sqliteZone_ = malloc_create_zone(4096, 0);
+    malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
+  }
+#endif /*  defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
   UNUSED_PARAMETER(NotUsed);
   return SQLITE_OK;
 }
 
 /*
 ** Deinitialize this module.
 */
 static void sqlite3MemShutdown(void *NotUsed){
@@ -24047,18 +24078,18 @@ static void winMutexEnter(sqlite3_mutex 
 #endif
   assert( winMutex_isInit==1 );
   EnterCriticalSection(&p->mutex);
 #ifdef SQLITE_DEBUG
   assert( p->nRef>0 || p->owner==0 );
   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
 }
 
 static int winMutexTry(sqlite3_mutex *p){
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   DWORD tid = GetCurrentThreadId();
 #endif
@@ -24090,18 +24121,18 @@ static int winMutexTry(sqlite3_mutex *p)
 #endif
     rc = SQLITE_OK;
   }
 #else
   UNUSED_PARAMETER(p);
 #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;
 }
 
 /*
 ** The sqlite3_mutex_leave() routine exits a mutex that was
 ** previously entered by the same thread.  The behavior
@@ -24119,18 +24150,18 @@ static void winMutexLeave(sqlite3_mutex 
   p->nRef--;
   if( p->nRef==0 ) p->owner = 0;
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
 #endif
   assert( winMutex_isInit==1 );
   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
 }
 
 SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
   static const sqlite3_mutex_methods sMutex = {
     winMutexInit,
     winMutexEnd,
@@ -24381,16 +24412,23 @@ static void mallocWithAlarm(int n, void 
 
   /* 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);
 
+#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;
       sqlite3MallocAlarm(nFull);
     }else{
       mem0.nearlyFull = 0;
@@ -24569,17 +24607,17 @@ static int isLookaside(sqlite3 *db, void
 */
 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
   assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   return sqlite3GlobalConfig.m.xSize(p);
 }
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
   assert( p!=0 );
   if( db==0 || !isLookaside(db,p) ){
-#if SQLITE_DEBUG
+#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)) );
     }
 #endif
@@ -24630,17 +24668,17 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite
   if( p==0 ) return;
   if( db ){
     if( db->pnBytesFreed ){
       measureAllocationSize(db, p);
       return;
     }
     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
       pBuf->pNext = db->lookaside.pFree;
       db->lookaside.pFree = pBuf;
       db->lookaside.nOut--;
       return;
     }
@@ -24999,17 +25037,17 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite
 ** SQLite.
 */
 /* #include "sqliteInt.h" */
 
 /*
 ** Conversion types fall into various categories as defined by the
 ** following enumeration.
 */
-#define etRADIX       0 /* Integer types.  %d, %x, %o, and so forth */
+#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 */
@@ -25017,18 +25055,19 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite
 #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      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 etINVALID    16 /* Any unrecognized conversion type */
+#define etDECIMAL    16 /* %d or %u, but not %x, %o */
+
+#define etINVALID    17 /* Any unrecognized conversion type */
 
 
 /*
 ** An "etByte" is an 8-bit unsigned value.
 */
 typedef unsigned char etByte;
 
 /*
@@ -25042,46 +25081,46 @@ typedef struct et_info {   /* Informatio
   etByte type;             /* Conversion paradigm */
   etByte charset;          /* Offset into aDigits[] of the digits string */
   etByte prefix;           /* Offset into aPrefix[] of the prefix string */
 } et_info;
 
 /*
 ** Allowed values for et_info.flags
 */
-#define FLAG_SIGNED  1     /* True if the value to convert is signed */
-#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 */
 
 
 /*
 ** The following table is searched linearly, so it is good to put the
 ** most frequently used conversion types first.
 */
 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 },
   {  'q',  0, 4, etSQLESCAPE,  0,  0 },
   {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
   {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
   {  'c',  0, 0, etCHARX,      0,  0 },
   {  'o',  8, 0, etRADIX,      0,  2 },
-  {  'u', 10, 0, etRADIX,      0,  0 },
+  {  'u', 10, 0, etDECIMAL,    0,  0 },
   {  'x', 16, 0, etRADIX,      16, 1 },
   {  'X', 16, 0, etRADIX,      0,  4 },
 #ifndef SQLITE_OMIT_FLOATING_POINT
   {  'f',  0, 1, etFLOAT,      0,  0 },
   {  'e',  0, 1, etEXP,        30, 0 },
   {  'E',  0, 1, etEXP,        14, 0 },
   {  'G',  0, 1, etGENERIC,    14, 0 },
 #endif
-  {  'i', 10, 1, etRADIX,      0,  0 },
+  {  '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 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 },
@@ -25163,24 +25202,23 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
 ){
   int c;                     /* Next character in the format string */
   char *bufpt;               /* Pointer to the conversion buffer */
   int precision;             /* Precision of the current field */
   int length;                /* Length of the field */
   int idx;                   /* A general purpose loop counter */
   int width;                 /* Width of the current field */
   etByte flag_leftjustify;   /* True if "-" flag is present */
-  etByte flag_plussign;      /* True if "+" flag is present */
-  etByte flag_blanksign;     /* True if " " flag is present */
+  etByte flag_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 cThousand;          /* Thousands separator for %d and %u */
   etByte xtype = etINVALID;  /* Conversion paradigm */
   u8 bArgList;               /* True for SQLITE_PRINTF_SQLFUNC */
   char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
   sqlite_uint64 longvalue;   /* Value for integer types */
   LONGDOUBLE_TYPE realvalue; /* Value for real types */
   const et_info *infop;      /* Pointer to the appropriate info structure */
   char *zOut;                /* Rendering buffer */
   int nOut;                  /* Size of the rendering buffer */
@@ -25213,27 +25251,28 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
       sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
       if( *fmt==0 ) break;
     }
     if( (c=(*++fmt))==0 ){
       sqlite3StrAccumAppend(pAccum, "%", 1);
       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 );
     /* Get the field width */
     if( c=='*' ){
       if( bArgList ){
         width = (int)getIntArg(pArgList);
       }else{
@@ -25293,23 +25332,21 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
 #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;
+      }
+    }else{
+      flag_long = 0;
     }
     /* Fetch the info entry for the field */
     infop = &fmtinfo[0];
     xtype = etINVALID;
     for(idx=0; idx<ArraySize(fmtinfo); idx++){
       if( c==fmtinfo[idx].fmttype ){
         infop = &fmtinfo[idx];
         xtype = infop->type;
@@ -25317,89 +25354,91 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
       }
     }
 
     /*
     ** At this point, variables are initialized as follows:
     **
     **   flag_alternateform          TRUE if a '#' is present.
     **   flag_altform2               TRUE if a '!' is present.
-    **   flag_plussign               TRUE if a '+' is present.
+    **   flag_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
     **                               is -1.
     **   xtype                       The class of the conversion.
     **   infop                       Pointer to the appropriate info struct.
     */
     switch( xtype ){
       case etPOINTER:
-        flag_longlong = sizeof(char*)==sizeof(i64);
-        flag_long = sizeof(char*)==sizeof(long int);
+        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);
           }
           if( v<0 ){
             if( v==SMALLEST_INT64 ){
               longvalue = ((u64)1)<<63;
             }else{
               longvalue = -v;
             }
             prefix = '-';
           }else{
             longvalue = v;
-            if( flag_plussign )        prefix = '+';
-            else if( flag_blanksign )  prefix = ' ';
-            else                       prefix = 0;
+            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);
           }
           prefix = 0;
         }
         if( longvalue==0 ) flag_alternateform = 0;
         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 ){
           static const char zOrd[] = "thstndrd";
           int x = (int)(longvalue % 10);
           if( x>=4 || (longvalue/10)%10==1 ){
             x = 0;
           }
@@ -25410,18 +25449,33 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           const char *cset = &aDigits[infop->charset];
           u8 base = infop->base;
           do{                                           /* Convert to ascii */
             *(--bufpt) = cset[longvalue%base];
             longvalue = longvalue/base;
           }while( longvalue>0 );
         }
         length = (int)(&zOut[nOut-1]-bufpt);
-        for(idx=precision-length; idx>0; idx--){
+        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" */
           const char *pre;
           char x;
           pre = &aPrefix[infop->prefix];
           for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
         }
@@ -25438,19 +25492,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
 #ifdef SQLITE_OMIT_FLOATING_POINT
         length = 0;
 #else
         if( precision<0 ) precision = 6;         /* Set default precision */
         if( realvalue<0.0 ){
           realvalue = -realvalue;
           prefix = '-';
         }else{
-          if( flag_plussign )          prefix = '+';
-          else if( flag_blanksign )    prefix = ' ';
-          else                         prefix = 0;
+          prefix = flag_prefix;
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
         testcase( precision>0xfff );
         for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
         if( sqlite3IsNaN((double)realvalue) ){
@@ -26212,16 +26264,20 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(
 
 
 /*
 ** Generate a human-readable description of a Select object.
 */
 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);
   }
   do{
     sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
@@ -29461,123 +29517,125 @@ SQLITE_PRIVATE const char *sqlite3Opcode
     /*  47 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
     /*  48 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
     /*  49 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
     /*  50 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
     /*  51 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
     /*  52 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
     /*  53 */ "Last"             OpHelp(""),
     /*  54 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
-    /*  55 */ "SorterSort"       OpHelp(""),
-    /*  56 */ "Sort"             OpHelp(""),
-    /*  57 */ "Rewind"           OpHelp(""),
-    /*  58 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
-    /*  59 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
-    /*  60 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
-    /*  61 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
-    /*  62 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
-    /*  63 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
-    /*  64 */ "Program"          OpHelp(""),
-    /*  65 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
-    /*  66 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
-    /*  67 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
-    /*  68 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
-    /*  69 */ "IncrVacuum"       OpHelp(""),
-    /*  70 */ "VNext"            OpHelp(""),
-    /*  71 */ "Init"             OpHelp("Start at P2"),
-    /*  72 */ "Return"           OpHelp(""),
-    /*  73 */ "EndCoroutine"     OpHelp(""),
-    /*  74 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
-    /*  75 */ "Halt"             OpHelp(""),
-    /*  76 */ "Integer"          OpHelp("r[P2]=P1"),
-    /*  77 */ "Int64"            OpHelp("r[P2]=P4"),
-    /*  78 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
-    /*  79 */ "Null"             OpHelp("r[P2..P3]=NULL"),
-    /*  80 */ "SoftNull"         OpHelp("r[P1]=NULL"),
-    /*  81 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
-    /*  82 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
-    /*  83 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
-    /*  84 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
-    /*  85 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
-    /*  86 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
-    /*  87 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
-    /*  88 */ "CollSeq"          OpHelp(""),
-    /*  89 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
-    /*  90 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
-    /*  91 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
-    /*  92 */ "RealAffinity"     OpHelp(""),
-    /*  93 */ "Cast"             OpHelp("affinity(r[P1])"),
-    /*  94 */ "Permutation"      OpHelp(""),
-    /*  95 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
-    /*  96 */ "Column"           OpHelp("r[P3]=PX"),
+    /*  55 */ "IfSmaller"        OpHelp(""),
+    /*  56 */ "SorterSort"       OpHelp(""),
+    /*  57 */ "Sort"             OpHelp(""),
+    /*  58 */ "Rewind"           OpHelp(""),
+    /*  59 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
+    /*  60 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
+    /*  61 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
+    /*  62 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
+    /*  63 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
+    /*  64 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+    /*  65 */ "Program"          OpHelp(""),
+    /*  66 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+    /*  67 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+    /*  68 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+    /*  69 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+    /*  70 */ "IncrVacuum"       OpHelp(""),
+    /*  71 */ "VNext"            OpHelp(""),
+    /*  72 */ "Init"             OpHelp("Start at P2"),
+    /*  73 */ "Return"           OpHelp(""),
+    /*  74 */ "EndCoroutine"     OpHelp(""),
+    /*  75 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
+    /*  76 */ "Halt"             OpHelp(""),
+    /*  77 */ "Integer"          OpHelp("r[P2]=P1"),
+    /*  78 */ "Int64"            OpHelp("r[P2]=P4"),
+    /*  79 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
+    /*  80 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+    /*  81 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+    /*  82 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+    /*  83 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+    /*  84 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+    /*  85 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+    /*  86 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+    /*  87 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
+    /*  88 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+    /*  89 */ "CollSeq"          OpHelp(""),
+    /*  90 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
+    /*  91 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
+    /*  92 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+    /*  93 */ "RealAffinity"     OpHelp(""),
+    /*  94 */ "Cast"             OpHelp("affinity(r[P1])"),
+    /*  95 */ "Permutation"      OpHelp(""),
+    /*  96 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
     /*  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 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
-    /* 107 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
-    /* 108 */ "SorterOpen"       OpHelp(""),
-    /* 109 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
-    /* 110 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
-    /* 111 */ "Close"            OpHelp(""),
-    /* 112 */ "ColumnsUsed"      OpHelp(""),
-    /* 113 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
-    /* 114 */ "NewRowid"         OpHelp("r[P2]=rowid"),
-    /* 115 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
-    /* 116 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
-    /* 117 */ "Delete"           OpHelp(""),
-    /* 118 */ "ResetCount"       OpHelp(""),
-    /* 119 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
-    /* 120 */ "SorterData"       OpHelp("r[P2]=data"),
-    /* 121 */ "RowData"          OpHelp("r[P2]=data"),
-    /* 122 */ "Rowid"            OpHelp("r[P2]=rowid"),
-    /* 123 */ "NullRow"          OpHelp(""),
-    /* 124 */ "SorterInsert"     OpHelp("key=r[P2]"),
-    /* 125 */ "IdxInsert"        OpHelp("key=r[P2]"),
-    /* 126 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
-    /* 127 */ "Seek"             OpHelp("Move P3 to P1.rowid"),
-    /* 128 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
-    /* 129 */ "Destroy"          OpHelp(""),
-    /* 130 */ "Clear"            OpHelp(""),
-    /* 131 */ "ResetSorter"      OpHelp(""),
+    /*  98 */ "Column"           OpHelp("r[P3]=PX"),
+    /*  99 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+    /* 100 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+    /* 101 */ "Count"            OpHelp("r[P2]=count()"),
+    /* 102 */ "ReadCookie"       OpHelp(""),
+    /* 103 */ "SetCookie"        OpHelp(""),
+    /* 104 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+    /* 105 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+    /* 106 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+    /* 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 */ "Seek"             OpHelp("Move P3 to P1.rowid"),
+    /* 129 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+    /* 130 */ "Destroy"          OpHelp(""),
+    /* 131 */ "Clear"            OpHelp(""),
     /* 132 */ "Real"             OpHelp("r[P2]=P4"),
-    /* 133 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
-    /* 134 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
-    /* 135 */ "ParseSchema"      OpHelp(""),
-    /* 136 */ "LoadAnalysis"     OpHelp(""),
-    /* 137 */ "DropTable"        OpHelp(""),
-    /* 138 */ "DropIndex"        OpHelp(""),
-    /* 139 */ "DropTrigger"      OpHelp(""),
-    /* 140 */ "IntegrityCk"      OpHelp(""),
-    /* 141 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
-    /* 142 */ "Param"            OpHelp(""),
-    /* 143 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
-    /* 144 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
-    /* 145 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
-    /* 146 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
-    /* 147 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
-    /* 148 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
-    /* 149 */ "Expire"           OpHelp(""),
-    /* 150 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
-    /* 151 */ "VBegin"           OpHelp(""),
-    /* 152 */ "VCreate"          OpHelp(""),
-    /* 153 */ "VDestroy"         OpHelp(""),
-    /* 154 */ "VOpen"            OpHelp(""),
-    /* 155 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
-    /* 156 */ "VRename"          OpHelp(""),
-    /* 157 */ "Pagecount"        OpHelp(""),
-    /* 158 */ "MaxPgcnt"         OpHelp(""),
-    /* 159 */ "CursorHint"       OpHelp(""),
-    /* 160 */ "Noop"             OpHelp(""),
-    /* 161 */ "Explain"          OpHelp(""),
+    /* 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 */ "CursorHint"       OpHelp(""),
+    /* 162 */ "Noop"             OpHelp(""),
+    /* 163 */ "Explain"          OpHelp(""),
   };
   return azName[i];
 }
 #endif
 
 /************** End of opcodes.c *********************************************/
 /************** Begin file os_unix.c *****************************************/
 /*
@@ -37949,52 +38007,90 @@ struct winVfsAppData {
  * WARNING: It is important to note that when this setting is non-zero and the
  *          winMemShutdown function is called (e.g. by the sqlite3_shutdown
  *          function), all data that was allocated using the isolated heap will
  *          be freed immediately and any attempt to access any of that freed
  *          data will almost certainly result in an immediate access violation.
  ******************************************************************************
  */
 #ifndef SQLITE_WIN32_HEAP_CREATE
-#  define SQLITE_WIN32_HEAP_CREATE    (TRUE)
+#  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)
+#    define SQLITE_WIN32_CACHE_SIZE     (SQLITE_DEFAULT_CACHE_SIZE)
 #  else
-#    define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
+#    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_WIN32_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
 
 /*
  * The extra flags to use in calls to the Win32 heap APIs.  This value may be
  * zero for the default behavior.
  */
 #ifndef SQLITE_WIN32_HEAP_FLAGS
-#  define SQLITE_WIN32_HEAP_FLAGS     (0)
+#  define SQLITE_WIN32_HEAP_FLAGS       (0)
 #endif
 
 
 /*
 ** The winMemData structure stores information required by the Win32-specific
 ** sqlite3_mem_methods implementation.
 */
 typedef struct winMemData winMemData;
@@ -44081,17 +44177,17 @@ struct PCache {
 ** 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) );
 */
-#if SQLITE_DEBUG
+#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 */
@@ -60174,56 +60270,103 @@ static void ptrmapPutOvflPtr(MemPage *pP
     Pgno ovfl = get4byte(&pCell[info.nSize-4]);
     ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
   }
 }
 #endif
 
 
 /*
-** 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 */
   int size;                  /* Size of a cell */
   int usableSize;            /* Number of usable bytes on a page */
   int cellOffset;            /* Offset to the cell pointer array */
   int cbrk;                  /* Offset to the cell content area */
   int nCell;                 /* Number of cells on the page */
   unsigned char *data;       /* The page data */
   unsigned char *temp;       /* Temp area for cell content */
   unsigned char *src;        /* Source of content */
   int iCellFirst;            /* First allowable cell index */
   int iCellLast;             /* Last possible cell index */
 
-
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( pPage->pBt!=0 );
   assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
   assert( pPage->nOverflow==0 );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   temp = 0;
   src = data = pPage->aData;
   hdr = pPage->hdrOffset;
   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_BKPT;
+          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 */
     pAddr = &data[cellOffset + i*2];
     pc = get2byte(pAddr);
     testcase( pc==iCellFirst );
     testcase( pc==iCellLast );
     /* These conditions have already been verified in btreeInitPage()
@@ -60247,26 +60390,28 @@ static int defragmentPage(MemPage *pPage
       if( cbrk==pc ) continue;
       temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
       x = get2byte(&data[hdr+5]);
       memcpy(&temp[x], &data[x], (cbrk+size) - x);
       src = temp;
     }
     memcpy(&data[cbrk], &src[pc], size);
   }
+  data[hdr+7] = 0;
+
+ defragment_out:
+  if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
+    return SQLITE_CORRUPT_BKPT;
+  }
   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;
 }
 
 /*
 ** Search the free-list on page pPg for space to store a cell nByte bytes in
 ** size. If one can be found, return a pointer to the space and remove it
 ** from the free-list.
 **
@@ -60394,20 +60539,20 @@ static int allocateSpace(MemPage *pPage,
   }
 
   /* The request could not be fulfilled using a freelist slot.  Check
   ** to see if defragmentation is necessary.
   */
   testcase( gap+2+nByte==top );
   if( gap+2+nByte>top ){
     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 );
   }
 
 
   /* Allocate memory from the gap in between the cell pointer array
   ** and the cell content area.  The btreeInitPage() call has already
   ** validated the freelist.  Given that the freelist is valid, there
   ** is no way that the allocation can extend off the end of the page.
   ** The assert() below verifies the previous sentence.
@@ -61669,16 +61814,41 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVa
     (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL:
     BTREE_AUTOVACUUM_INCR
   );
   sqlite3BtreeLeave(p);
   return rc;
 #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
 ** also acquire a readlock on that file.
 **
 ** SQLITE_OK is returned on success.  If the file is not a
 ** well-formed database file, then SQLITE_CORRUPT is returned.
 ** SQLITE_BUSY is returned if the database is locked.  SQLITE_NOMEM
@@ -61742,36 +61912,25 @@ static int lockBtree(BtShared *pBt){
     ** file.
     */
     if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
       int isOpen = 0;
       rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
       if( rc!=SQLITE_OK ){
         goto page1_init_failed;
       }else{
-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
-        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==SQLITE_DEFAULT_SYNCHRONOUS+1
-          ){
-            pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1;
-            sqlite3PagerSetFlags(pBt->pPager,
-               pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
-          }
-        }
-#endif
+        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
 
     /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
     ** fractions and the leaf payload fraction values must be 64, 32, and 32.
     **
     ** The original design allowed these amounts to vary, but as of
     ** version 3.6.0, we require them to be fixed.
@@ -63633,17 +63792,17 @@ static int moveToChild(BtCursor *pCur, u
   pCur->info.nSize = 0;
   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
   pCur->iPage++;
   pCur->aiIdx[pCur->iPage] = 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
 ** cell in page pParent. Or, if iIdx is equal to the total number of
 ** cells in pParent, that page number iChild is the right-child of
 ** the page.
 */
 static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
@@ -64177,16 +64336,40 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCur
   /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
   ** have been deleted? This API will need to change to return an error code
   ** as well as the boolean result value.
   */
   return (CURSOR_VALID!=pCur->eState);
 }
 
 /*
+** 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.  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.
 **
 ** The main entry point is sqlite3BtreeNext().  That routine is optimized
 ** for the common case of merely incrementing the cell counter BtCursor.aiIdx
 ** to the next cell on the current page.  The (slower) btreeNext() helper
@@ -65020,17 +65203,17 @@ static int fillInCell(
   **   spaceLeft          Space available at pPayload.  If nPayload>spaceLeft,
   **                      that means content must spill into overflow pages.
   **   *pnSize            Size of the local cell (not counting overflow pages)
   **   pPrior             Where to write the pgno of the first overflow page
   **
   ** Use a call to btreeParseCellPtr() to verify that the values above
   ** were computed correctly.
   */
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
   {
     CellInfo info;
     pPage->xParseCell(pPage, pCell, &info);
     assert( nHeader==(int)(info.pPayload - pCell) );
     assert( info.nKey==pX->nKey );
     assert( *pnSize == info.nSize );
     assert( spaceLeft == info.nLocal );
   }
@@ -66546,17 +66729,17 @@ static int balance_nonroot(
     ** for which the pointer is stored within the content being copied.
     **
     ** It is critical that the child page be defragmented before being
     ** copied into the parent, because if the parent is page 1 then it will
     ** by smaller than the child due to the database header, and so all the
     ** free space needs to be up front.
     */
     assert( nNew==1 || CORRUPT_DB );
-    rc = defragmentPage(apNew[0]);
+    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)
       || rc!=SQLITE_OK
     );
     copyNodeContent(apNew[0], pParent, &rc);
     freePage(apNew[0], &rc);
   }else if( ISAUTOVACUUM && !leafCorrection ){
@@ -71198,16 +71381,17 @@ SQLITE_PRIVATE void sqlite3VdbeError(Vdb
 }
 
 /*
 ** Remember the SQL string for a prepared statement.
 */
 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
   assert( isPrepareV2==1 || isPrepareV2==0 );
   if( p==0 ) return;
+  if( !isPrepareV2 ) p->expmask = 0;
 #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;
 }
 
@@ -71226,16 +71410,17 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe
   pB->pNext = pTmp;
   pTmp = pA->pPrev;
   pA->pPrev = pB->pPrev;
   pB->pPrev = pTmp;
   zTmp = pA->zSql;
   pA->zSql = pB->zSql;
   pB->zSql = zTmp;
   pB->isPrepareV2 = pA->isPrepareV2;
+  pB->expmask = pA->expmask;
 }
 
 /*
 ** Resize the Vdbe.aOp array so that it is at least nOp elements larger 
 ** than its current size. nOp is guaranteed to be less than or equal
 ** to 1024/sizeof(Op).
 **
 ** If an out-of-memory error occurs while resizing the array, return
@@ -71256,16 +71441,22 @@ static int growOpArray(Vdbe *v, int nOp)
   ** size of the op array or add 1KB of space, whichever is smaller. */
 #ifdef SQLITE_TEST_REALLOC_STRESS
   int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
 #else
   int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
   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->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
     p->nOpAlloc = p->szOpAlloc/sizeof(Op);
     v->aOp = pNew;
   }
@@ -73750,23 +73941,23 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe 
   **     SQLITE_FULL
   **     SQLITE_INTERRUPT
   **
   ** Then the internal cache might have been left in an inconsistent
   ** state.  We need to rollback the statement transaction, if there is
   ** one, or the complete transaction if there is no statement transaction.
   */
 
+  if( p->magic!=VDBE_MAGIC_RUN ){
+    return SQLITE_OK;
+  }
   if( db->mallocFailed ){
     p->rc = SQLITE_NOMEM_BKPT;
   }
   closeAllCursors(p);
-  if( p->magic!=VDBE_MAGIC_RUN ){
-    return SQLITE_OK;
-  }
   checkActiveVdbeCnt(db);
 
   /* No commit or rollback needed if the program never started or if the
   ** SQL statement does not read or write a database file.  */
   if( p->pc>=0 && p->bIsReader ){
     int mrc;   /* Primary error code from p->rc */
     int eStatementOp = 0;
     int isSpecialError;            /* Set to true if a 'special' error */
@@ -74703,17 +74894,17 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnp
     d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
     pMem++;
     if( (++u)>=p->nField ) break;
   }
   assert( u<=pKeyInfo->nField + 1 );
   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(),
 ** this function deserializes and compares values using the
 ** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
 ** in assert() statements to ensure that the optimized code in
 ** sqlite3VdbeRecordCompare() returns results with these two primitives.
 **
@@ -74808,17 +74999,17 @@ debugCompareEnd:
   if( desiredResult<0 && rc<0 ) return 1;
   if( desiredResult>0 && rc>0 ) return 1;
   if( CORRUPT_DB ) return 1;
   if( pKeyInfo->db->mallocFailed ) return 1;
   return 0;
 }
 #endif
 
-#if SQLITE_DEBUG
+#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
 ** limit given by pKeyInfo->nField + pKeyInfo->nXField.
 **
 ** If this constraint is not satisfied, it means that the high-speed
 ** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
 ** not work correctly.  If this assert() ever fires, it probably means
@@ -75691,18 +75882,18 @@ SQLITE_PRIVATE sqlite3_value *sqlite3Vdb
 
 /*
 ** Configure SQL variable iVar so that binding a new value to it signals
 ** to sqlite3_reoptimize() that re-preparing the statement may result
 ** in a better query plan.
 */
 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
   assert( iVar>0 );
-  if( iVar>32 ){
-    v->expmask = 0xffffffff;
+  if( iVar>=32 ){
+    v->expmask |= 0x80000000;
   }else{
     v->expmask |= ((u32)1 << (iVar-1));
   }
 }
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 /*
 ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
@@ -75962,17 +76153,18 @@ SQLITE_API int sqlite3_clear_bindings(sq
 #if SQLITE_THREADSAFE
   sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
 #endif
   sqlite3_mutex_enter(mutex);
   for(i=0; i<p->nVar; i++){
     sqlite3VdbeMemRelease(&p->aVar[i]);
     p->aVar[i].flags = MEM_Null;
   }
-  if( p->isPrepareV2 && p->expmask ){
+  assert( p->isPrepareV2 || p->expmask==0 );
+  if( p->expmask ){
     p->expired = 1;
   }
   sqlite3_mutex_leave(mutex);
   return rc;
 }
 
 
 /**************************** sqlite3_value_  *******************************
@@ -77066,19 +77258,18 @@ static int vdbeUnbind(Vdbe *p, int i){
   ** binding a new value to this variable invalidates the current query plan.
   **
   ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
   ** parameter in the WHERE clause might influence the choice of query plan
   ** for a statement, then the statement will be automatically recompiled,
   ** 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->isPrepareV2 || p->expmask==0 );
+  if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
     p->expired = 1;
   }
   return SQLITE_OK;
 }
 
 /*
 ** Bind a text or BLOB value.
 */
@@ -77331,20 +77522,22 @@ SQLITE_PRIVATE int sqlite3TransferBindin
 ** SQLITE_OK is returned.
 */
 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->isPrepareV2 || pTo->expmask==0 );
+  if( pTo->expmask ){
     pTo->expired = 1;
   }
-  if( pFrom->isPrepareV2 && pFrom->expmask ){
+  assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
+  if( pFrom->expmask ){
     pFrom->expired = 1;
   }
   return sqlite3TransferBindings(pFromStmt, pToStmt);
 }
 #endif
 
 /*
 ** Return the sqlite3* database handle to which the prepared statement given
@@ -78300,33 +78493,29 @@ SQLITE_PRIVATE void sqlite3VdbeMemPretty
       c = 't';
       assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
     }else if( f & MEM_Ephem ){
       c = 'e';
       assert( (f & (MEM_Static|MEM_Dyn))==0 );
     }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++){
       sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
       zCsr += sqlite3Strlen30(zCsr);
     }
     for(i=0; i<16 && i<pMem->n; i++){
       char z = pMem->z[i];
       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);
     }
     *zCsr = '\0';
   }else if( f & MEM_Str ){
     int j, k;
     zBuf[0] = ' ';
@@ -79655,45 +79844,45 @@ case OP_Function: {
   ** 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, pCtx->pOut);
+  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(pCtx->pOut, MEM_Null);
+  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(pCtx->pOut));
+      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(pCtx->pOut, encoding);
-    if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
-  }
-
-  REGISTER_TRACE(pOp->p3, pCtx->pOut);
-  UPDATE_MAX_BLOBSIZE(pCtx->pOut);
+    sqlite3VdbeChangeEncoding(pOut, encoding);
+    if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
+  }
+
+  REGISTER_TRACE(pOp->p3, pOut);
+  UPDATE_MAX_BLOBSIZE(pOut);
   break;
 }
 
 /* Opcode: BitAnd P1 P2 P3 * *
 ** 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.
@@ -80184,17 +80373,17 @@ case OP_Compare: {
     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+1 - p->nCursor)+1 );
     assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 );
   }else{
     assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 );
     assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 );
@@ -80322,29 +80511,49 @@ case OP_BitNot: {             /* same as
     pOut->flags = MEM_Int;
     pOut->u.i = ~sqlite3VdbeIntValue(pIn1);
   }
   break;
 }
 
 /* Opcode: Once P1 P2 * * *
 **
-** If the P1 value is equal to the P1 value on the OP_Init opcode at
-** instruction 0, then jump to P2.  If the two P1 values differ, then
-** set the P1 value on this opcode to equal the P1 value on the OP_Init
-** and fall through.
+** 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 */
+  u32 iAddr;                /* Address of this instruction */
   assert( p->aOp[0].opcode==OP_Init );
-  VdbeBranchTaken(p->aOp[0].p1==pOp->p1, 2);
-  if( p->aOp[0].p1==pOp->p1 ){
-    goto jump_to_p2;
-  }else{
-    pOp->p1 = p->aOp[0].p1;
-  }
+  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{
+    if( p->aOp[0].p1==pOp->p1 ){
+      VdbeBranchTaken(1, 2);
+      goto jump_to_p2;
+    }
+  }
+  VdbeBranchTaken(0, 2);
+  pOp->p1 = p->aOp[0].p1;
   break;
 }
 
 /* Opcode: If P1 P2 P3 * *
 **
 ** Jump to P2 if the value in register P1 is true.  The value
 ** is considered true if it is numeric and non-zero.  If the value
 ** in P1 is NULL then take the jump if and only if P3 is non-zero.
@@ -80647,18 +80856,23 @@ case OP_Column: {
           && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
      || (len = sqlite3VdbeSerialTypeLen(t))==0
     ){
       /* Content is irrelevant for
       **    1. the typeof() function,
       **    2. the length(X) function if X is a blob, and
       **    3. if the content length is zero.
       ** So we might as well use bogus content rather than reading
-      ** content from disk. */
-      static u8 aZero[8];  /* This is the bogus content */
+      ** 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(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;
     }
   }
@@ -82833,16 +83047,43 @@ case OP_Last: {        /* jump */
       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
@@ -83477,16 +83718,28 @@ case OP_CreateTable: {          /* out2 
     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
 ** that match the WHERE clause P4. 
 **
 ** This opcode invokes the parser to create a new virtual machine,
 ** then runs the new virtual machine.  It is thus a re-entrant opcode.
 */
@@ -83597,17 +83850,17 @@ case OP_DropTrigger: {
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
 /* 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 integers
 ** stored in P4_INTARRAY argument.
 **
 ** If P5 is not zero, the check is done on the auxiliary database
@@ -83630,24 +83883,24 @@ case OP_IntegrityCk: {
   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];
   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);
-  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);
   sqlite3VdbeChangeEncoding(pIn1, encoding);
   break;
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
@@ -83816,17 +84069,18 @@ case OP_Program: {        /* jump */
     ** cell is required for each cursor used by the program. Set local
     ** 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->nCsr * sizeof(VdbeCursor*)
+              + (pProgram->nOp + 7)/8;
     pFrame = sqlite3DbMallocZero(db, nByte);
     if( !pFrame ){
       goto no_mem;
     }
     sqlite3VdbeMemRelease(pRt);
     pRt->flags = MEM_Frame;
     pRt->u.pFrame = pFrame;
 
@@ -83867,16 +84121,18 @@ case OP_Program: {        /* jump */
   pFrame->pAuxData = p->pAuxData;
   p->pAuxData = 0;
   p->nChange = 0;
   p->pFrame = pFrame;
   p->aMem = aMem = VdbeFrameMem(pFrame);
   p->nMem = pFrame->nChildMem;
   p->nCursor = (u16)pFrame->nChildCsr;
   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;
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   p->anExec = 0;
 #endif
   pOp = &aOp[-1];
 
   break;
@@ -84896,17 +85152,21 @@ case OP_Init: {          /* jump */
 #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 j;
     for(j=0; j<db->nDb; j++){
@@ -88784,21 +89044,21 @@ SQLITE_PRIVATE int sqlite3JournalSize(sq
 ** of the expression, while descending.  (In other words, the callback
 ** is invoked before visiting children.)
 **
 ** The return value from the callback should be one of the WRC_*
 ** constants to specify how to proceed with the walk.
 **
 **    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.
 */
 static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
   int rc;
   testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
   testcase( ExprHasProperty(pExpr, EP_Reduced) );
@@ -89150,17 +89410,18 @@ static int lookupName(
           pSchema = db->aDb[i].pSchema;
           break;
         }
       }
     }
   }
 
   /* 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;
 
     if( pSrcList ){
       for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
         pTab = pItem->pTab;
         assert( pTab!=0 && pTab->zName!=0 );
         assert( pTab->nCol>0 );
@@ -89335,21 +89596,21 @@ static int lookupName(
           goto lookupname_end;
         }
       } 
     }
 
     /* 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
   ** supplied) and the value of Z is enclosed in double-quotes, then
   ** Z is a string literal if it doesn't match any column names.  In that
   ** case, we need to return right away and not make any changes to
   ** pExpr.
   **
@@ -89529,43 +89790,48 @@ static int resolveExprStep(Walker *pWalk
       pExpr->iTable = pItem->iCursor;
       pExpr->iColumn = -1;
       pExpr->affinity = SQLITE_AFF_INTEGER;
       break;
     }
 #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; */
-      notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
-      pRight = pExpr->pRight;
-      if( pRight->op==TK_ID ){
+      if( pExpr->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;
+        zTable = 0;
+        zColumn = pExpr->u.zToken;
+      }else{
+        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);
     }
 
     /* Resolve function names
     */
     case TK_FUNCTION: {
       ExprList *pList = pExpr->x.pList;    /* The argument list */
@@ -92323,16 +92589,17 @@ SQLITE_PRIVATE int sqlite3ExprContainsSu
 /*
 ** 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
 ** in *pValue.  If the expression is not an integer or if it is too big
 ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
 */
 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 */
   assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
            || sqlite3GetInt32(p->u.zToken, &rc)==0 );
 
   if( p->flags & EP_IntValue ){
     *pValue = p->u.iValue;
@@ -92830,17 +93097,17 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
 */
 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 = sqlite3DbMallocZero(pParse->db, nVal+1);
+  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{
@@ -92995,17 +93262,16 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
         assert( !isRowid );
         /* 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);
-          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) ){
             sqlite3DbFree(pParse->db, dest.zAffSdst);
             sqlite3KeyInfoUnref(pKeyInfo);
             return 0;
           }
@@ -93735,17 +94001,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetCo
 
 
 /*
 ** Clear all column cache entries.
 */
 SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
   int i;
 
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
   if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
     printf("CLEAR\n");
   }
 #endif
   for(i=0; i<pParse->nColCache; i++){
     if( pParse->aColCache[i].tempReg
      && pParse->nTempReg<ArraySize(pParse->aTempReg)
     ){
@@ -95144,16 +95410,27 @@ SQLITE_PRIVATE int sqlite3ExprListCompar
     Expr *pExprB = pB->a[i].pExpr;
     if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
     if( sqlite3ExprCompare(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(
+             sqlite3ExprSkipCollate(pA),
+             sqlite3ExprSkipCollate(pB),
+             iTab);
+}
+
+/*
 ** Return true if we can prove the pE2 will always be true if pE1 is
 ** true.  Return false if we cannot complete the proof or if pE2 might
 ** be false.  Examples:
 **
 **     pE1: x==5       pE2: x==5             Result: true
 **     pE1: x>0        pE2: x==5             Result: false
 **     pE1: x=21       pE2: x=21 OR y=43     Result: true
 **     pE1: x!=123     pE2: x IS NOT NULL    Result: true
@@ -96695,16 +96972,17 @@ struct Stat4Accum {
   int nCol;                 /* Number of columns in index + pk/rowid */
   int nKeyCol;              /* Number of index columns w/o the pk/rowid */
   int mxSample;             /* Maximum number of samples to accumulate */
   Stat4Sample current;      /* Current row as a Stat4Sample */
   u32 iPrn;                 /* Pseudo-random number used for sampling */
   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() */
 };
 
 /* Reclaim memory used by a Stat4Sample
 */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -96959,16 +97237,23 @@ static int sampleIsBetter(
 */
 static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
   Stat4Sample *pSample = 0;
   int i;
 
   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 );
 
     /* This sample is being added because the prefix that ends in column 
     ** iCol occurs many times in the table. However, if we have already
     ** added a sample that shares this prefix, there is no need to add
     ** this one. Instead, upgrade the priority of the highest priority
@@ -97056,22 +97341,32 @@ static void samplePushPrevious(Stat4Accu
   for(i=(p->nCol-2); i>=iChng; i--){
     Stat4Sample *pBest = &p->aBest[i];
     pBest->anEq[i] = p->current.anEq[i];
     if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
       sampleInsert(p, pBest, i);
     }
   }
 
-  /* 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
 
 #if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
   if( iChng==0 ){
     tRowcnt nLt = p->current.anLt[0];
     tRowcnt nEq = p->current.anEq[0];
 
@@ -97591,17 +97886,17 @@ static void analyzeOneTable(
     if( HasRowid(pTab) ){
       sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
     }else{
       Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
       int j, k, regKey;
       regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
       for(j=0; j<pPk->nKeyCol; j++){
         k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
-        assert( k>=0 && k<pTab->nCol );
+        assert( k>=0 && k<pIdx->nColumn );
         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
         VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
       }
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
       sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
     }
 #endif
     assert( regChng==(regStat4+1) );
@@ -97775,50 +98070,38 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse
 
   assert( pName2!=0 || pName1==0 );
   if( pName1==0 ){
     /* Form 1:  Analyze everything */
     for(i=0; i<db->nDb; i++){
       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{
-    /* Form 3: Analyze the fully qualified table name */
+  }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 table or index named as an argument */
     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
     if( iDb>=0 ){
-      zDb = db->aDb[iDb].zDbSName;
+      zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
       z = sqlite3NameFromToken(db, pTableName);
       if( z ){
         if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
           analyzeTable(pParse, pIdx->pTable, pIdx);
         }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){
           analyzeTable(pParse, pTab, 0);
         }
         sqlite3DbFree(db, z);
       }
-    }   
-  }
-  v = sqlite3GetVdbe(pParse);
-  if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
+    }
+  }
+  if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+    sqlite3VdbeAddOp0(v, OP_Expire);
+  }
 }
 
 /*
 ** Used to pass information from the analyzer reader through to the
 ** callback routine.
 */
 typedef struct analysisInfo analysisInfo;
 struct analysisInfo {
@@ -97937,25 +98220,30 @@ static int analysisLoader(void *pData, i
     if( pIndex->aiRowEst==0 ){
       pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
       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;
 #ifdef SQLITE_ENABLE_COSTMULT
     fakeIdx.pTable = pTable;
 #endif
     decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
     pTable->szTabRow = fakeIdx.szIdxRow;
+    pTable->tabFlags |= TF_HasStat1;
   }
 
   return 0;
 }
 
 /*
 ** If the Index.aSample variable is not NULL, delete the aSample[] array
 ** and its contents.
@@ -98240,25 +98528,30 @@ static int loadStat4(sqlite3 *db, const 
 ** This means if the caller does not care about other errors, the return
 ** code may be ignored.
 */
 SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
   analysisInfo sInfo;
   HashElem *i;
   char *zSql;
   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);
-    pIdx->aiRowLogEst[0] = 0;
+    pIdx->hasStat1 = 0;
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
     sqlite3DeleteIndexSamples(db, pIdx);
     pIdx->aSample = 0;
 #endif
   }
 
   /* Load new statistics out of the sqlite_stat1 table */
   sInfo.db = db;
@@ -98271,29 +98564,29 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(s
     }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(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+  for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
     Index *pIdx = sqliteHashData(i);
-    if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
+    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) ){
     db->lookaside.bDisable++;
     rc = loadStat4(db, sInfo.zDatabase);
     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;
   }
 #endif
 
   if( rc==SQLITE_NOMEM ){
     sqlite3OomFault(db);
@@ -100268,16 +100561,17 @@ SQLITE_PRIVATE void sqlite3AddColumn(Par
 ** been seen on a column.  This routine sets the notNull flag on
 ** the column currently under construction.
 */
 SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
   Table *p;
   p = pParse->pNewTable;
   if( p==0 || NEVER(p->nCol<1) ) return;
   p->aCol[p->nCol-1].notNull = (u8)onError;
+  p->tabFlags |= TF_HasNotNull;
 }
 
 /*
 ** Scan the column type name zType (length nType) and return the
 ** associated affinity type.
 **
 ** This routine does a case-independent search of zType for the 
 ** substrings in the following table. If one of the substrings is
@@ -102607,16 +102901,19 @@ exit_create_index:
 */
 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
   /*                10,  9,  8,  7,  6 */
   LogEst aVal[] = { 33, 32, 30, 28, 26 };
   LogEst *a = pIdx->aiRowLogEst;
   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 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( 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
@@ -105190,25 +105487,23 @@ static void instrFunc(
   typeNeedle = sqlite3_value_type(argv[1]);
   if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
   nHaystack = sqlite3_value_bytes(argv[0]);
   nNeedle = sqlite3_value_bytes(argv[1]);
   if( nNeedle>0 ){
     if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
       zHaystack = sqlite3_value_blob(argv[0]);
       zNeedle = sqlite3_value_blob(argv[1]);
-      assert( zNeedle!=0 );
-      assert( zHaystack!=0 || nHaystack==0 );
       isText = 0;
     }else{
       zHaystack = sqlite3_value_text(argv[0]);
       zNeedle = sqlite3_value_text(argv[1]);
       isText = 1;
-      if( zHaystack==0 || zNeedle==0 ) return;
-    }
+    }
+    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;
@@ -109795,16 +110090,19 @@ SQLITE_PRIVATE void sqlite3GenerateConst
           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));
       }
     }
     sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
     VdbeComment((v, "for %s", pIdx->zName));
+#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
     ** primary key, then no collision is possible.  The collision detection
     ** logic below can all be skipped. */
     if( isUpdate && pPk==pIdx && pkChng==0 ){
       sqlite3VdbeResolveLabel(v, addrUniqueOk);
       continue;
@@ -109950,18 +110248,21 @@ SQLITE_PRIVATE void sqlite3GenerateConst
 */
 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; i>1 && pTab->aCol[i-1].pDflt==0; i--){}
-  sqlite3VdbeChangeP5(v, i);
+  for(i=pTab->nCol-1; i>0; i--){
+    if( pTab->aCol[i].pDflt!=0 ) break;
+    if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
+  }
+  sqlite3VdbeChangeP5(v, i+1);
 }
 #endif
 
 /*
 ** This routine generates code to finish the INSERT or UPDATE operation
 ** that was started by a prior call to sqlite3GenerateConstraintChecks.
 ** A consecutive range of registers starting at regNewData contains the
 ** rowid and the content to be inserted.
@@ -110241,17 +110542,17 @@ static int xferOptimization(
     ** attached to it. Proceeding may generate a false "no such table: xxx"
     ** error if pSelect reads from a CTE named "xxx".  */
     return 0;
   }
   if( sqlite3TriggerList(pParse, pDest) ){
     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
   if( onError==OE_Default ){
     if( pDest->iPKey>=0 ) onError = pDest->keyConf;
     if( onError==OE_Default ) onError = OE_Abort;
   }
   assert(pSelect->pSrc);   /* allocated even if there is no FROM clause */
@@ -110303,17 +110604,17 @@ static int xferOptimization(
   }
   if( pSrc==pDest ){
     return 0;   /* tab1 and tab2 may not be the same table */
   }
   if( HasRowid(pDest)!=HasRowid(pSrc) ){
     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
   if( pSrc->pSelect ){
     return 0;   /* tab2 may not be a view */
   }
   if( pDest->nCol!=pSrc->nCol ){
     return 0;   /* Number of columns must be the same in tab1 and tab2 */
@@ -110489,18 +110790,16 @@ static int xferOptimization(
       **
       ** If any of the indexed columns use a collation sequence other than
       ** BINARY, this optimization is disabled. This is because the user 
       ** might change the definition of a collation sequence and then run
       ** a VACUUM command. In that case keys may not be written in strictly
       ** sorted order.  */
       for(i=0; i<pSrcIdx->nColumn; i++){
         const char *zColl = pSrcIdx->azColl[i];
-        assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
-                    || sqlite3StrBINARY==zColl );
         if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
       }
       if( i==pSrcIdx->nColumn ){
         idxInsFlags = OPFLAG_USESEEKRESULT;
         sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
       }
     }
     if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
@@ -110600,17 +110899,17 @@ SQLITE_API int sqlite3_exec(
       int i;
       rc = sqlite3_step(pStmt);
 
       /* Invoke the callback function if required */
       if( xCallback && (SQLITE_ROW==rc || 
           (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;
           }
           for(i=0; i<nCol; i++){
             azCols[i] = (char *)sqlite3_column_name(pStmt, i);
             /* sqlite3VdbeSetColName() installs column names as UTF8
             ** strings so there is no way for sqlite3_column_name() to fail. */
             assert( azCols[i]!=0 );
@@ -110621,16 +110920,17 @@ SQLITE_API int sqlite3_exec(
           azVals = &azCols[nCol];
           for(i=0; i<nCol; i++){
             azVals[i] = (char *)sqlite3_column_text(pStmt, i);
             if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
               sqlite3OomFault(db);
               goto exec_out;
             }
           }
+          azVals[i] = 0;
         }
         if( xCallback(pArg, nCol, azVals, azCols) ){
           /* EVIDENCE-OF: R-38229-40159 If the callback function to
           ** sqlite3_exec() returns non-zero, then sqlite3_exec() will
           ** return SQLITE_ABORT. */
           rc = SQLITE_ABORT;
           sqlite3VdbeFinalize((Vdbe *)pStmt);
           pStmt = 0;
@@ -110976,16 +111276,18 @@ struct sqlite3_api_routines {
   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);
 };
 
 /*
 ** 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. */
@@ -111234,16 +111536,18 @@ typedef int (*sqlite3_loadext_entry)(
 #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
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #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;
 # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;
 # define SQLITE_EXTENSION_INIT3     \
@@ -111659,17 +111963,19 @@ static const sqlite3_api_routines sqlite
   /* 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
+  sqlite3_expanded_sql,
+  /* Version 3.18.0 and later */
+  sqlite3_set_last_insert_rowid
 };
 
 /*
 ** Attempt to load an SQLite extension library contained in the file
 ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
 ** default entry point name (sqlite3_extension_init) is used.  Use
 ** of the default name is recommended.
 **
@@ -112091,34 +112397,35 @@ SQLITE_PRIVATE void sqlite3AutoLoadExten
 #define PragTyp_INDEX_LIST                    17
 #define PragTyp_INTEGRITY_CHECK               18
 #define PragTyp_JOURNAL_MODE                  19
 #define PragTyp_JOURNAL_SIZE_LIMIT            20
 #define PragTyp_LOCK_PROXY_FILE               21
 #define PragTyp_LOCKING_MODE                  22
 #define PragTyp_PAGE_COUNT                    23
 #define PragTyp_MMAP_SIZE                     24
-#define PragTyp_PAGE_SIZE                     25
-#define PragTyp_SECURE_DELETE                 26
-#define PragTyp_SHRINK_MEMORY                 27
-#define PragTyp_SOFT_HEAP_LIMIT               28
-#define PragTyp_STATS                         29
+#define PragTyp_OPTIMIZE                      25
+#define PragTyp_PAGE_SIZE                     26
+#define PragTyp_SECURE_DELETE                 27
+#define PragTyp_SHRINK_MEMORY                 28
+#define PragTyp_SOFT_HEAP_LIMIT               29
 #define PragTyp_SYNCHRONOUS                   30
 #define PragTyp_TABLE_INFO                    31
 #define PragTyp_TEMP_STORE                    32
 #define PragTyp_TEMP_STORE_DIRECTORY          33
 #define PragTyp_THREADS                       34
 #define PragTyp_WAL_AUTOCHECKPOINT            35
 #define PragTyp_WAL_CHECKPOINT                36
 #define PragTyp_ACTIVATE_EXTENSIONS           37
 #define PragTyp_HEXKEY                        38
 #define PragTyp_KEY                           39
 #define PragTyp_REKEY                         40
 #define PragTyp_LOCK_STATUS                   41
 #define PragTyp_PARSER_TRACE                  42
+#define PragTyp_STATS                         43
 
 /* 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 */
@@ -112132,57 +112439,58 @@ SQLITE_PRIVATE void sqlite3AutoLoadExten
 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 */ "table",       /* Used by: stats */
-  /*   8 */ "index",      
-  /*   9 */ "width",      
-  /*  10 */ "height",     
-  /*  11 */ "seqno",       /* Used by: index_info */
-  /*  12 */ "cid",        
-  /*  13 */ "name",       
-  /*  14 */ "seqno",       /* Used by: index_xinfo */
-  /*  15 */ "cid",        
-  /*  16 */ "name",       
-  /*  17 */ "desc",       
-  /*  18 */ "coll",       
-  /*  19 */ "key",        
-  /*  20 */ "seq",         /* Used by: index_list */
-  /*  21 */ "name",       
-  /*  22 */ "unique",     
-  /*  23 */ "origin",     
-  /*  24 */ "partial",    
-  /*  25 */ "seq",         /* Used by: database_list */
-  /*  26 */ "name",       
-  /*  27 */ "file",       
-  /*  28 */ "seq",         /* Used by: collation_list */
-  /*  29 */ "name",       
-  /*  30 */ "id",          /* Used by: foreign_key_list */
-  /*  31 */ "seq",        
-  /*  32 */ "table",      
-  /*  33 */ "from",       
-  /*  34 */ "to",         
-  /*  35 */ "on_update",  
-  /*  36 */ "on_delete",  
-  /*  37 */ "match",      
-  /*  38 */ "table",       /* Used by: foreign_key_check */
-  /*  39 */ "rowid",      
-  /*  40 */ "parent",     
-  /*  41 */ "fkid",       
-  /*  42 */ "busy",        /* Used by: wal_checkpoint */
-  /*  43 */ "log",        
-  /*  44 */ "checkpointed",
-  /*  45 */ "timeout",     /* Used by: busy_timeout */
-  /*  46 */ "database",    /* Used by: lock_status */
-  /*  47 */ "status",     
+  /*   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 */ "seq",         /* Used by: collation_list */
+  /*  30 */ "name",       
+  /*  31 */ "id",          /* Used by: foreign_key_list */
+  /*  32 */ "seq",        
+  /*  33 */ "table",      
+  /*  34 */ "from",       
+  /*  35 */ "to",         
+  /*  36 */ "on_update",  
+  /*  37 */ "on_delete",  
+  /*  38 */ "match",      
+  /*  39 */ "table",       /* Used by: foreign_key_check */
+  /*  40 */ "rowid",      
+  /*  41 */ "parent",     
+  /*  42 */ "fkid",       
+  /*  43 */ "busy",        /* Used by: wal_checkpoint */
+  /*  44 */ "log",        
+  /*  45 */ "checkpointed",
+  /*  46 */ "timeout",     /* Used by: busy_timeout */
+  /*  47 */ "database",    /* Used by: lock_status */
+  /*  48 */ "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[] */
@@ -112218,17 +112526,17 @@ static const PragmaName aPragmaName[] = 
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ SQLITE_AutoIndex },
 #endif
 #endif
  {/* zName:     */ "busy_timeout",
   /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
   /* ePragFlg:  */ PragFlg_Result0,
-  /* ColNames:  */ 45, 1,
+  /* ColNames:  */ 46, 1,
   /* iArg:      */ 0 },
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "cache_size",
   /* ePragTyp:  */ PragTyp_CACHE_SIZE,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
@@ -112255,17 +112563,17 @@ static const PragmaName aPragmaName[] = 
   /* 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,
   /* ePragFlg:  */ PragFlg_Result0,
-  /* ColNames:  */ 28, 2,
+  /* ColNames:  */ 29, 2,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
  {/* zName:     */ "compile_options",
   /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
   /* ePragFlg:  */ PragFlg_Result0,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
@@ -112290,17 +112598,17 @@ static const PragmaName aPragmaName[] = 
   /* 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,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
-  /* ColNames:  */ 25, 3,
+  /* 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,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 1,
   /* iArg:      */ 0 },
@@ -112327,24 +112635,24 @@ static const PragmaName aPragmaName[] = 
   /* 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,
   /* ePragFlg:  */ PragFlg_NeedSchema,
-  /* ColNames:  */ 38, 4,
+  /* ColNames:  */ 39, 4,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_FOREIGN_KEY)
  {/* zName:     */ "foreign_key_list",
   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
-  /* ColNames:  */ 30, 8,
+  /* ColNames:  */ 31, 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,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
@@ -112397,27 +112705,27 @@ static const PragmaName aPragmaName[] = 
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_NoColumns,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
  {/* zName:     */ "index_info",
   /* ePragTyp:  */ PragTyp_INDEX_INFO,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
-  /* ColNames:  */ 11, 3,
+  /* ColNames:  */ 12, 3,
   /* iArg:      */ 0 },
  {/* zName:     */ "index_list",
   /* ePragTyp:  */ PragTyp_INDEX_LIST,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
-  /* ColNames:  */ 20, 5,
+  /* ColNames:  */ 21, 5,
   /* iArg:      */ 0 },
  {/* zName:     */ "index_xinfo",
   /* ePragTyp:  */ PragTyp_INDEX_INFO,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
-  /* ColNames:  */ 14, 6,
+  /* ColNames:  */ 15, 6,
   /* iArg:      */ 1 },
 #endif
 #if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
  {/* zName:     */ "integrity_check",
   /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
   /* ePragFlg:  */ PragFlg_NeedSchema,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
@@ -112454,17 +112762,17 @@ static const PragmaName aPragmaName[] = 
   /* ePragFlg:  */ PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  {/* zName:     */ "lock_status",
   /* ePragTyp:  */ PragTyp_LOCK_STATUS,
   /* ePragFlg:  */ PragFlg_Result0,
-  /* ColNames:  */ 46, 2,
+  /* ColNames:  */ 47, 2,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "locking_mode",
   /* ePragTyp:  */ PragTyp_LOCKING_MODE,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
@@ -112473,16 +112781,23 @@ static const PragmaName aPragmaName[] = 
   /* 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
+ {/* zName:     */ "optimize",
+  /* ePragTyp:  */ PragTyp_OPTIMIZE,
+  /* ePragFlg:  */ PragFlg_Result1,
+  /* 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,
@@ -112571,21 +112886,21 @@ static const PragmaName aPragmaName[] = 
 #if defined(SQLITE_DEBUG)
  {/* 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)
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
  {/* zName:     */ "stats",
   /* ePragTyp:  */ PragTyp_STATS,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
-  /* ColNames:  */ 7, 4,
+  /* ColNames:  */ 7, 5,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
  {/* zName:     */ "synchronous",
   /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
@@ -112654,28 +112969,28 @@ static const PragmaName aPragmaName[] = 
  {/* 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:  */ 42, 3,
+  /* ColNames:  */ 43, 3,
   /* iArg:      */ 0 },
 #endif
 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
  {/* zName:     */ "writable_schema",
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
 #endif
 };
-/* Number of pragmas: 60 on by default, 73 total. */
+/* Number of pragmas: 60 on by default, 74 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, 2 for FULL, and 3 for EXTRA.  Return 1 for an empty or 
 ** unrecognized string argument.  The FULL and EXTRA option is disallowed
@@ -112936,16 +113251,32 @@ static const PragmaName *pragmaLocate(co
     }else{
       lwr = mid + 1;
     }
   }
   return lwr>upr ? 0 : &aPragmaName[mid];
 }
 
 /*
+** Helper subroutine for PRAGMA integrity_check:
+**
+** 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;
+}
+
+/*
 ** Process a pragma statement.  
 **
 ** Pragmas are of this form:
 **
 **      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
@@ -113639,17 +113970,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
   */
   case PragTyp_SYNCHRONOUS: {
     if( !zRight ){
       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);
       }
     }
     break;
@@ -113738,39 +114069,43 @@ SQLITE_PRIVATE void sqlite3Pragma(
                pCol->pDflt ? pCol->pDflt->u.zToken : 0,
                k);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
       }
     }
   }
   break;
 
+#ifdef SQLITE_DEBUG
   case PragTyp_STATS: {
     Index *pIdx;
     HashElem *i;
-    pParse->nMem = 4;
+    pParse->nMem = 5;
     sqlite3CodeVerifySchema(pParse, iDb);
     for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
       Table *pTab = sqliteHashData(i);
-      sqlite3VdbeMultiLoad(v, 1, "ssii",
+      sqlite3VdbeMultiLoad(v, 1, "ssiii",
            pTab->zName,
            0,
            pTab->szTabRow,
-           pTab->nRowLogEst);
-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+           pTab->nRowLogEst,
+           pTab->tabFlags);
+      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
       for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-        sqlite3VdbeMultiLoad(v, 2, "sii",
+        sqlite3VdbeMultiLoad(v, 2, "siii",
            pIdx->zName,
            pIdx->szIdxRow,
-           pIdx->aiRowLogEst[0]);
-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+           pIdx->aiRowLogEst[0],
+           pIdx->hasStat1);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
       }
     }
   }
   break;
+#endif
 
   case PragTyp_INDEX_INFO: if( zRight ){
     Index *pIdx;
     Table *pTab;
     pIdx = sqlite3FindIndex(db, zRight, zDb);
     if( pIdx ){
       int i;
       int mx;
@@ -114017,19 +114352,27 @@ SQLITE_PRIVATE void sqlite3Pragma(
   }
   break;
 
 #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
 # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
 #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;
 
     int isQuick = (sqlite3Tolower(zLeft[0])=='q');
 
     /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
     ** then iDb is set to the index of the database identified by <db>.
@@ -114050,35 +114393,31 @@ SQLITE_PRIVATE void sqlite3Pragma(
     /* Set the maximum error count */
     mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
     if( zRight ){
       sqlite3GetInt32(zRight, &mxErr);
       if( mxErr<=0 ){
         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 finding the root pages numbers
       ** for all tables and indices in the database.
       */
       assert( sqlite3SchemaMutexHeld(db, i, 0) );
       pTbls = &db->aDb[i].pSchema->tblHash;
@@ -114108,87 +114447,104 @@ SQLITE_PRIVATE void sqlite3Pragma(
       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].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;
         int loopTop;
         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, 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 */
         }
         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 ){
+          int addrCkFault = sqlite3VdbeMakeLabel(v);
+          int addrCkOk = sqlite3VdbeMakeLabel(v);
+          ExprList *pCheck = pTab->pCheck;
+          char *zErr;
+          int k;
+          pParse->iSelfTab = iDataCur;
+          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);
+          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);
         }
         /* 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;
           r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
                                        pPrior, r1);
           pPrior = pIdx;
           sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);  /* increment entry count */
           /* 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 */
           sqlite3VdbeLoadString(v, 3, "row ");
           sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
           sqlite3VdbeLoadString(v, 4, " missing from index ");
           sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
           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
           ** or (2) the next entry has a different key */
           if( IsUniqueIndex(pIdx) ){
             int uniqOk = sqlite3VdbeMakeLabel(v);
             int jmp6;
             int kk;
@@ -114199,57 +114555,55 @@ SQLITE_PRIVATE void sqlite3Pragma(
               sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
               VdbeCoverage(v);
             }
             jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
             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 */
             sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
             sqlite3VdbeGoto(v, jmp5);
             sqlite3VdbeResolveLabel(v, uniqOk);
           }
           sqlite3VdbeJumpHere(v, jmp4);
           sqlite3ResolvePartIdxLabel(pParse, jmp3);
         }
         sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
         sqlite3VdbeJumpHere(v, loopTop-1);
 #ifndef SQLITE_OMIT_BTREECOUNT
-        sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
-        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);
-          sqlite3VdbeLoadString(v, 3, pIdx->zName);
-          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 */
       } 
     }
     {
       static const int iLn = VDBE_OFFSET_LINENO(2);
       static const VdbeOpList endCode[] = {
         { OP_AddImm,      1, 0,        0},    /* 0 */
-        { OP_If,          1, 4,        0},    /* 1 */
+        { 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 = -mxErr;
+        aOp[0].p2 = 1-mxErr;
         aOp[2].p4type = P4_STATIC;
         aOp[2].p4.z = "ok";
       }
     }
   }
   break;
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
@@ -114465,16 +114819,128 @@ SQLITE_PRIVATE void sqlite3Pragma(
   ** can, by calling sqlite3_db_release_memory().
   */
   case PragTyp_SHRINK_MEMORY: {
     sqlite3_db_release_memory(db);
     break;
   }
 
   /*
+  **  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;
+  }
+
+  /*
   **   PRAGMA busy_timeout
   **   PRAGMA busy_timeout = N
   **
   ** Call sqlite3_busy_timeout(db, N).  Return the current timeout value
   ** if one is set.  If no busy handler or a different busy handler is set
   ** then 0 is returned.  Setting the busy_timeout to 0 or negative
   ** disables the timeout.
   */
@@ -119525,17 +119991,19 @@ static int flattenSubquery(
       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 = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
     }
-    substSelect(pParse, pParent, iParent, pSub->pEList, 0);
+    if( db->mallocFailed==0 ){
+      substSelect(pParse, pParent, iParent, pSub->pEList, 0);
+    }
   
     /* The flattened query is distinct if either the inner or the
     ** outer query is distinct. 
     */
     pParent->selFlags |= pSub->selFlags & SF_Distinct;
   
     /*
     ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
@@ -123779,18 +124247,35 @@ static int execSqlF(sqlite3 *db, char **
 ** and renaming the transient database as the original.  But that will
 ** not work if other processes are attached to the original database.
 ** And a power loss in between deleting the original and renaming the
 ** transient would cause the database file to appear to be deleted
 ** following reboot.
 */
 SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
   Vdbe *v = sqlite3GetVdbe(pParse);
-  int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
-  if( v && (iDb>=2 || iDb==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( iDb!=1 ){
     sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
     sqlite3VdbeUsesBtree(v, iDb);
   }
   return;
 }
 
 /*
 ** This routine implements the OP_Vacuum opcode of the VDBE.
@@ -124374,18 +124859,17 @@ SQLITE_PRIVATE void sqlite3VtabBeginPars
   pTable = pParse->pNewTable;
   if( pTable==0 ) return;
   assert( 0==pTable->pIndex );
 
   db = pParse->db;
   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));
   assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
        || (pParse->sNameToken.z==pName1->z && pName2->z==0)
   );
   pParse->sNameToken.n = (int)(
       &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
@@ -124663,17 +125147,17 @@ static int vtabCallConstructor(
 */
 SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
   sqlite3 *db = pParse->db;
   const char *zMod;
   Module *pMod;
   int rc;
 
   assert( pTab );
-  if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
+  if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
     return SQLITE_OK;
   }
 
   /* Locate the required virtual table module */
   zMod = pTab->azModuleArg[0];
   pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
 
   if( !pMod ){
@@ -124733,17 +125217,17 @@ static void addToVTrans(sqlite3 *db, VTa
 */
 SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
   int rc = SQLITE_OK;
   Table *pTab;
   Module *pMod;
   const char *zMod;
 
   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
-  assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
+  assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
 
   /* Locate the required virtual table module */
   zMod = pTab->azModuleArg[0];
   pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
 
   /* If the module has been registered and includes a Create method, 
   ** invoke it now. If the module has not been registered, return an 
   ** error. Otherwise, do nothing.
@@ -124787,31 +125271,31 @@ SQLITE_API int sqlite3_declare_vtab(sqli
   sqlite3_mutex_enter(db->mutex);
   pCtx = db->pVtabCtx;
   if( !pCtx || pCtx->bDeclared ){
     sqlite3Error(db, SQLITE_MISUSE);
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_MISUSE_BKPT;
   }
   pTab = pCtx->pTab;
-  assert( (pTab->tabFlags & TF_Virtual)!=0 );
+  assert( IsVirtual(pTab) );
 
   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
   if( pParse==0 ){
     rc = SQLITE_NOMEM_BKPT;
   }else{
     pParse->declareVtab = 1;
     pParse->db = db;
     pParse->nQueryLoop = 1;
   
     if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) 
      && pParse->pNewTable
      && !db->mallocFailed
      && !pParse->pNewTable->pSelect
-     && (pParse->pNewTable->tabFlags & TF_Virtual)==0
+     && !IsVirtual(pParse->pNewTable)
     ){
       if( !pTab->aCol ){
         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;
@@ -125090,17 +125574,17 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverl
   unsigned char *z;
 
 
   /* Check to see the left operand is a column in a virtual table */
   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( !IsVirtual(pTab) ) return pDef;
   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
   assert( pVtab!=0 );
   assert( pVtab->pModule!=0 );
   pMod = (sqlite3_module *)pVtab->pModule;
   if( pMod->xFindFunction==0 ) return pDef;
  
   /* Call the xFindFunction method on the virtual table implementation
   ** to see if the implementation wants to overload this function 
@@ -125185,18 +125669,17 @@ SQLITE_PRIVATE int sqlite3VtabEponymousT
   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;
-  pTab->tabFlags |= TF_Virtual;
-  pTab->nModuleArg = 0;
+  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);
@@ -125257,17 +125740,17 @@ SQLITE_API int sqlite3_vtab_config(sqlit
   sqlite3_mutex_enter(db->mutex);
   va_start(ap, op);
   switch( op ){
     case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
       VtabCtx *p = db->pVtabCtx;
       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;
     }
     default:
       rc = SQLITE_MISUSE_BKPT;
       break;
   }
@@ -125696,33 +126179,38 @@ struct WhereLoopBuilder {
   WhereClause *pWC;         /* WHERE clause terms */
   ExprList *pOrderBy;       /* ORDER BY clause */
   WhereLoop *pNew;          /* Template WhereLoop */
   WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   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
 ** half does the tail of the WHERE loop.  An instance of
 ** this structure is returned by the first half and passed
 ** into the second half to give some continuity.
 **
 ** An instance of this object holds the complete state of the query
 ** planner.
 */
 struct WhereInfo {
   Parse *pParse;            /* Parsing and code generating context */
   SrcList *pTabList;        /* List of tables in the join */
   ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
-  ExprList *pDistinctSet;   /* DISTINCT over all these values */
+  ExprList *pResultSet;     /* Result set of the query */
   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 */
@@ -126896,16 +127384,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeO
   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 */
 
   pParse = pWInfo->pParse;
   v = pParse->pVdbe;
   pWC = &pWInfo->sWC;
   db = pParse->db;
@@ -126937,16 +127426,21 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeO
   ** 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;
@@ -127121,17 +127615,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeO
       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, addrBrk);
+      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 );
@@ -127767,17 +128261,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeO
     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, addrBrk);
+      pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
       VdbeCoverageIf(v, bRev==0);
       VdbeCoverageIf(v, bRev!=0);
       pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
     }
   }
 
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
@@ -128092,41 +128586,49 @@ static int isLikeOrGlob(
   if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
     return 0;
   }
 #ifdef SQLITE_EBCDIC
   if( *pnoCase ) return 0;
 #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 ){
     Vdbe *pReprepare = pParse->pReprepare;
     int iCol = pRight->iColumn;
     pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
     if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
       z = (char *)sqlite3_value_text(pVal);
     }
     sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
     assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
   }else if( op==TK_STRING ){
     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++;
     }
     if( cnt!=0 && 255!=(u8)z[cnt-1] ){
       Expr *pPrefix;
       *pisComplete = c==wc[0] && z[cnt+1]==0;
       pPrefix = sqlite3Expr(db, TK_STRING, z);
@@ -128745,17 +129247,17 @@ static int exprMightBeIndexed(
   if( mPrereq==0 ) return 0;                 /* No table references */
   if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
   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( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+      if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
         *piCur = iCur;
         *piColumn = XN_EXPR;
         return 1;
       }
     }
   }
   return 0;
 }
@@ -129536,17 +130038,18 @@ static WhereTerm *whereScanNext(WhereSca
     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
-             || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
+             || 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++){
@@ -129843,24 +130346,26 @@ static LogEst estLog(LogEst N){
 ** 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(
-  Vdbe *v,            /* The VDBE containing code to translate */
+  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 ){
@@ -130128,17 +130633,19 @@ static void constructAutomaticIndex(
   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);
   if( pTabItem->fg.viaCoroutine ){
     sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
-    translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
+    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);
@@ -131713,16 +132220,21 @@ static int whereLoopAddBtreeIndex(
      && !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;
     pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
@@ -132260,17 +132772,25 @@ static int whereLoopAddBtree(
         ApplyCostMultiplier(pNew->rRun, pTab->costMult);
         whereLoopOutputAdjust(pWC, pNew, rSize);
         rc = whereLoopInsert(pBuilder, pNew);
         pNew->nOut = rSize;
         if( rc ) break;
       }
     }
 
+    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;
     pBuilder->pRec = 0;
 #endif
 
     /* If there was an INDEXED BY clause, then only that one index is
     ** considered. */
@@ -133440,19 +133960,19 @@ static int wherePathSolver(WhereInfo *pW
     pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
   }
   if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
    && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
    && pWInfo->eDistinct==WHERE_DISTINCT_NOOP
    && nRowEst
   ){
     Bitmask notUsed;
-    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
+    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
                  WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
-    if( rc==pWInfo->pDistinctSet->nExpr ){
+    if( rc==pWInfo->pResultSet->nExpr ){
       pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
     }
   }
   if( pWInfo->pOrderBy ){
     if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
       if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
         pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
       }
@@ -133679,17 +134199,17 @@ static int whereShortCut(WhereLoopBuilde
 ** be used to compute the appropriate cursor depending on which index is
 ** 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 *pDistinctSet, /* Try not to output two rows that duplicate these */
+  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 */
   WhereInfo *pWInfo;         /* Will become the return value of this function */
   Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
@@ -133755,17 +134275,17 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBe
   if( db->mallocFailed ){
     sqlite3DbFree(db, pWInfo);
     pWInfo = 0;
     goto whereBeginError;
   }
   pWInfo->pParse = pParse;
   pWInfo->pTabList = pTabList;
   pWInfo->pOrderBy = pOrderBy;
-  pWInfo->pDistinctSet = pDistinctSet;
+  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));
@@ -133833,23 +134353,23 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBe
   }
 #endif
 
   /* Analyze all of the subexpressions. */
   sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
   if( db->mallocFailed ) goto whereBeginError;
 
   if( wctrlFlags & WHERE_WANT_DISTINCT ){
-    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
+    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
       /* The DISTINCT marking is pointless.  Ignore it. */
       pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
     }else if( pOrderBy==0 ){
       /* Try to ORDER BY the result set to make distinct processing easier */
       pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
-      pWInfo->pOrderBy = pDistinctSet;
+      pWInfo->pOrderBy = pResultSet;
     }
   }
 
   /* Construct the WhereLoop objects */
 #if defined(WHERETRACE_ENABLED)
   if( sqlite3WhereTrace & 0xffff ){
     sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
     if( wctrlFlags & WHERE_USE_LIMIT ){
@@ -133915,20 +134435,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBe
     sqlite3DebugPrintf("\n");
     for(ii=0; ii<pWInfo->nLevel; ii++){
       whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
     }
   }
 #endif
   /* Attempt to omit tables from the join that do not effect the result */
   if( pWInfo->nLevel>=2
-   && pDistinctSet!=0
+   && pResultSet!=0
    && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
   ){
-    Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
+    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].fg.jointype & JT_LEFT)==0 ) break;
       if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
@@ -134233,18 +134753,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(Wher
     Table *pTab = pTabItem->pTab;
     assert( pTab!=0 );
     pLoop = pLevel->pWLoop;
 
     /* For a co-routine, change all OP_Column references to the table of
     ** the co-routine into OP_Copy of result contained in a register.
     ** OP_Rowid becomes OP_Null.
     */
-    if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
-      translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
+    if( pTabItem->fg.viaCoroutine ){
+      testcase( pParse->db->mallocFailed );
+      translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
                             pTabItem->regResult, 0);
       continue;
     }
 
     /* If this scan uses an index, make VDBE code substitutions to read data
     ** from the index instead of from the table where possible.  In some cases
     ** this optimization prevents the table from ever being read, which can
     ** yield a significant performance boost.
@@ -134701,172 +135222,172 @@ typedef union {
 **  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.
 **
 *********** Begin parsing tables **********************************************/
 #define YY_ACTTAB_COUNT (1567)
 static const YYACTIONTYPE yy_action[] = {
  /*     0 */   325,  832,  351,  825,    5,  203,  203,  819,   99,  100,
- /*    10 */    90,  842,  842,  854,  857,  846,  846,   97,   97,   98,
+ /*    10 */    90,  978,  978,  853,  856,  845,  845,   97,   97,   98,
  /*    20 */    98,   98,   98,  301,   96,   96,   96,   96,   95,   95,
- /*    30 */    94,   94,   94,   93,  351,  325,  977,  977,  824,  824,
- /*    40 */   826,  947,  354,   99,  100,   90,  842,  842,  854,  857,
- /*    50 */   846,  846,   97,   97,   98,   98,   98,   98,  338,   96,
+ /*    30 */    94,   94,   94,   93,  351,  325,  976,  976,  824,  824,
+ /*    40 */   826,  946,  354,   99,  100,   90,  978,  978,  853,  856,
+ /*    50 */   845,  845,   97,   97,   98,   98,   98,   98,  338,   96,
  /*    60 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  351,
- /*    70 */    95,   95,   94,   94,   94,   93,  351,  791,  977,  977,
+ /*    70 */    95,   95,   94,   94,   94,   93,  351,  791,  976,  976,
  /*    80 */   325,   94,   94,   94,   93,  351,  792,   75,   99,  100,
- /*    90 */    90,  842,  842,  854,  857,  846,  846,   97,   97,   98,
+ /*    90 */    90,  978,  978,  853,  856,  845,  845,   97,   97,   98,
  /*   100 */    98,   98,   98,  450,   96,   96,   96,   96,   95,   95,
  /*   110 */    94,   94,   94,   93,  351, 1333,  155,  155,    2,  325,
  /*   120 */   275,  146,  132,   52,   52,   93,  351,   99,  100,   90,
- /*   130 */   842,  842,  854,  857,  846,  846,   97,   97,   98,   98,
+ /*   130 */   978,  978,  853,  856,  845,  845,   97,   97,   98,   98,
  /*   140 */    98,   98,  101,   96,   96,   96,   96,   95,   95,   94,
- /*   150 */    94,   94,   93,  351,  958,  958,  325,  268,  428,  413,
- /*   160 */   411,   61,  752,  752,   99,  100,   90,  842,  842,  854,
- /*   170 */   857,  846,  846,   97,   97,   98,   98,   98,   98,   60,
+ /*   150 */    94,   94,   93,  351,  957,  957,  325,  268,  428,  413,
+ /*   160 */   411,   61,  752,  752,   99,  100,   90,  978,  978,  853,
+ /*   170 */   856,  845,  845,   97,   97,   98,   98,   98,   98,   60,
  /*   180 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
- /*   190 */   351,  325,  270,  329,  273,  277,  959,  960,  250,   99,
- /*   200 */   100,   90,  842,  842,  854,  857,  846,  846,   97,   97,
+ /*   190 */   351,  325,  270,  329,  273,  277,  958,  959,  250,   99,
+ /*   200 */   100,   90,  978,  978,  853,  856,  845,  845,   97,   97,
  /*   210 */    98,   98,   98,   98,  301,   96,   96,   96,   96,   95,
- /*   220 */    95,   94,   94,   94,   93,  351,  325,  938, 1326,  698,
- /*   230 */   706, 1326,  242,  412,   99,  100,   90,  842,  842,  854,
- /*   240 */   857,  846,  846,   97,   97,   98,   98,   98,   98,  347,
+ /*   220 */    95,   94,   94,   94,   93,  351,  325,  937, 1326,  698,
+ /*   230 */   706, 1326,  242,  412,   99,  100,   90,  978,  978,  853,
+ /*   240 */   856,  845,  845,   97,   97,   98,   98,   98,   98,  347,
  /*   250 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
- /*   260 */   351,  325,  938, 1327,  384,  699, 1327,  381,  379,   99,
- /*   270 */   100,   90,  842,  842,  854,  857,  846,  846,   97,   97,
+ /*   260 */   351,  325,  937, 1327,  384,  699, 1327,  381,  379,   99,
+ /*   270 */   100,   90,  978,  978,  853,  856,  845,  845,   97,   97,
  /*   280 */    98,   98,   98,   98,  701,   96,   96,   96,   96,   95,
  /*   290 */    95,   94,   94,   94,   93,  351,  325,   92,   89,  178,
- /*   300 */   833,  936,  373,  700,   99,  100,   90,  842,  842,  854,
- /*   310 */   857,  846,  846,   97,   97,   98,   98,   98,   98,  375,
+ /*   300 */   833,  935,  373,  700,   99,  100,   90,  978,  978,  853,
+ /*   310 */   856,  845,  845,   97,   97,   98,   98,   98,   98,  375,
  /*   320 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
- /*   330 */   351,  325, 1276,  947,  354,  818,  936,  739,  739,   99,
- /*   340 */   100,   90,  842,  842,  854,  857,  846,  846,   97,   97,
+ /*   330 */   351,  325, 1275,  946,  354,  818,  935,  739,  739,   99,
+ /*   340 */   100,   90,  978,  978,  853,  856,  845,  845,   97,   97,
  /*   350 */    98,   98,   98,   98,  230,   96,   96,   96,   96,   95,
- /*   360 */    95,   94,   94,   94,   93,  351,  325,  969,  227,   92,
- /*   370 */    89,  178,  373,  300,   99,  100,   90,  842,  842,  854,
- /*   380 */   857,  846,  846,   97,   97,   98,   98,   98,   98,  921,
+ /*   360 */    95,   94,   94,   94,   93,  351,  325,  968,  227,   92,
+ /*   370 */    89,  178,  373,  300,   99,  100,   90,  978,  978,  853,
+ /*   380 */   856,  845,  845,   97,   97,   98,   98,   98,   98,  920,
  /*   390 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
  /*   400 */   351,  325,  449,  447,  447,  447,  147,  737,  737,   99,
- /*   410 */   100,   90,  842,  842,  854,  857,  846,  846,   97,   97,
+ /*   410 */   100,   90,  978,  978,  853,  856,  845,  845,   97,   97,
  /*   420 */    98,   98,   98,   98,  296,   96,   96,   96,   96,   95,
- /*   430 */    95,   94,   94,   94,   93,  351,  325,  419,  231,  958,
- /*   440 */   958,  158,   25,  422,   99,  100,   90,  842,  842,  854,
- /*   450 */   857,  846,  846,   97,   97,   98,   98,   98,   98,  450,
+ /*   430 */    95,   94,   94,   94,   93,  351,  325,  419,  231,  957,
+ /*   440 */   957,  158,   25,  422,   99,  100,   90,  978,  978,  853,
+ /*   450 */   856,  845,  845,   97,   97,   98,   98,   98,   98,  450,
  /*   460 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
- /*   470 */   351,  443,  224,  224,  420,  958,  958,  962,  325,   52,
- /*   480 */    52,  959,  960,  176,  415,   78,   99,  100,   90,  842,
- /*   490 */   842,  854,  857,  846,  846,   97,   97,   98,   98,   98,
+ /*   470 */   351,  443,  224,  224,  420,  957,  957,  961,  325,   52,
+ /*   480 */    52,  958,  959,  176,  415,   78,   99,  100,   90,  978,
+ /*   490 */   978,  853,  856,  845,  845,   97,   97,   98,   98,   98,
  /*   500 */    98,  379,   96,   96,   96,   96,   95,   95,   94,   94,
- /*   510 */    94,   93,  351,  325,  428,  418,  298,  959,  960,  962,
- /*   520 */    81,   99,   88,   90,  842,  842,  854,  857,  846,  846,
+ /*   510 */    94,   93,  351,  325,  428,  418,  298,  958,  959,  961,
+ /*   520 */    81,   99,   88,   90,  978,  978,  853,  856,  845,  845,
  /*   530 */    97,   97,   98,   98,   98,   98,  717,   96,   96,   96,
- /*   540 */    96,   95,   95,   94,   94,   94,   93,  351,  325,  843,
- /*   550 */   843,  855,  858,  996,  318,  343,  379,  100,   90,  842,
- /*   560 */   842,  854,  857,  846,  846,   97,   97,   98,   98,   98,
+ /*   540 */    96,   95,   95,   94,   94,   94,   93,  351,  325,  842,
+ /*   550 */   842,  854,  857,  996,  318,  343,  379,  100,   90,  978,
+ /*   560 */   978,  853,  856,  845,  845,   97,   97,   98,   98,   98,
  /*   570 */    98,  450,   96,   96,   96,   96,   95,   95,   94,   94,
  /*   580 */    94,   93,  351,  325,  350,  350,  350,  260,  377,  340,
- /*   590 */   929,   52,   52,   90,  842,  842,  854,  857,  846,  846,
+ /*   590 */   928,   52,   52,   90,  978,  978,  853,  856,  845,  845,
  /*   600 */    97,   97,   98,   98,   98,   98,  361,   96,   96,   96,
  /*   610 */    96,   95,   95,   94,   94,   94,   93,  351,   86,  445,
- /*   620 */   847,    3, 1203,  361,  360,  378,  344,  813,  958,  958,
- /*   630 */  1300,   86,  445,  729,    3,  212,  169,  287,  405,  282,
+ /*   620 */   846,    3, 1202,  361,  360,  378,  344,  813,  957,  957,
+ /*   630 */  1299,   86,  445,  729,    3,  212,  169,  287,  405,  282,
  /*   640 */   404,  199,  232,  450,  300,  760,   83,   84,  280,  245,
  /*   650 */   262,  365,  251,   85,  352,  352,   92,   89,  178,   83,
  /*   660 */    84,  242,  412,   52,   52,  448,   85,  352,  352,  246,
- /*   670 */   959,  960,  194,  455,  670,  402,  399,  398,  448,  243,
+ /*   670 */   958,  959,  194,  455,  670,  402,  399,  398,  448,  243,
  /*   680 */   221,  114,  434,  776,  361,  450,  397,  268,  747,  224,
  /*   690 */   224,  132,  132,  198,  832,  434,  452,  451,  428,  427,
  /*   700 */   819,  415,  734,  713,  132,   52,   52,  832,  268,  452,
- /*   710 */   451,  734,  194,  819,  363,  402,  399,  398,  450, 1271,
- /*   720 */  1271,   23,  958,  958,   86,  445,  397,    3,  228,  429,
- /*   730 */   895,  824,  824,  826,  827,   19,  203,  720,   52,   52,
+ /*   710 */   451,  734,  194,  819,  363,  402,  399,  398,  450, 1270,
+ /*   720 */  1270,   23,  957,  957,   86,  445,  397,    3,  228,  429,
+ /*   730 */   894,  824,  824,  826,  827,   19,  203,  720,   52,   52,
  /*   740 */   428,  408,  439,  249,  824,  824,  826,  827,   19,  229,
  /*   750 */   403,  153,   83,   84,  761,  177,  241,  450,  721,   85,
- /*   760 */   352,  352,  120,  157,  959,  960,   58,  977,  409,  355,
+ /*   760 */   352,  352,  120,  157,  958,  959,   58,  976,  409,  355,
  /*   770 */   330,  448,  268,  428,  430,  320,  790,   32,   32,   86,
  /*   780 */   445,  776,    3,  341,   98,   98,   98,   98,  434,   96,
  /*   790 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  351,
- /*   800 */   832,  120,  452,  451,  813,  887,  819,   83,   84,  977,
- /*   810 */   813,  132,  410,  920,   85,  352,  352,  132,  407,  789,
- /*   820 */   958,  958,   92,   89,  178,  917,  448,  262,  370,  261,
- /*   830 */    82,  914,   80,  262,  370,  261,  776,  824,  824,  826,
- /*   840 */   827,   19,  934,  434,   96,   96,   96,   96,   95,   95,
- /*   850 */    94,   94,   94,   93,  351,  832,   74,  452,  451,  958,
- /*   860 */   958,  819,  959,  960,  120,   92,   89,  178,  945,    2,
- /*   870 */   918,  965,  268,    1,  976,   76,  445,  762,    3,  708,
- /*   880 */   901,  901,  387,  958,  958,  757,  919,  371,  740,  778,
+ /*   800 */   832,  120,  452,  451,  813,  886,  819,   83,   84,  976,
+ /*   810 */   813,  132,  410,  919,   85,  352,  352,  132,  407,  789,
+ /*   820 */   957,  957,   92,   89,  178,  916,  448,  262,  370,  261,
+ /*   830 */    82,  913,   80,  262,  370,  261,  776,  824,  824,  826,
+ /*   840 */   827,   19,  933,  434,   96,   96,   96,   96,   95,   95,
+ /*   850 */    94,   94,   94,   93,  351,  832,   74,  452,  451,  957,
+ /*   860 */   957,  819,  958,  959,  120,   92,   89,  178,  944,    2,
+ /*   870 */   917,  964,  268,    1,  975,   76,  445,  762,    3,  708,
+ /*   880 */   900,  900,  387,  957,  957,  757,  918,  371,  740,  778,
  /*   890 */   756,  257,  824,  824,  826,  827,   19,  417,  741,  450,
- /*   900 */    24,  959,  960,   83,   84,  369,  958,  958,  177,  226,
- /*   910 */    85,  352,  352,  885,  315,  314,  313,  215,  311,   10,
- /*   920 */    10,  683,  448,  349,  348,  959,  960,  909,  777,  157,
- /*   930 */   120,  958,  958,  337,  776,  416,  711,  310,  450,  434,
- /*   940 */   450,  321,  450,  791,  103,  200,  175,  450,  959,  960,
- /*   950 */   908,  832,  792,  452,  451,    9,    9,  819,   10,   10,
+ /*   900 */    24,  958,  959,   83,   84,  369,  957,  957,  177,  226,
+ /*   910 */    85,  352,  352,  884,  315,  314,  313,  215,  311,   10,
+ /*   920 */    10,  683,  448,  349,  348,  958,  959,  908,  777,  157,
+ /*   930 */   120,  957,  957,  337,  776,  416,  711,  310,  450,  434,
+ /*   940 */   450,  321,  450,  791,  103,  200,  175,  450,  958,  959,
+ /*   950 */   907,  832,  792,  452,  451,    9,    9,  819,   10,   10,
  /*   960 */    52,   52,   51,   51,  180,  716,  248,   10,   10,  171,
- /*   970 */   170,  167,  339,  959,  960,  247,  984,  702,  702,  450,
- /*   980 */   715,  233,  686,  982,  889,  983,  182,  914,  824,  824,
+ /*   970 */   170,  167,  339,  958,  959,  247,  984,  702,  702,  450,
+ /*   980 */   715,  233,  686,  982,  888,  983,  182,  913,  824,  824,
  /*   990 */   826,  827,   19,  183,  256,  423,  132,  181,  394,   10,
- /*  1000 */    10,  889,  891,  749,  958,  958,  917,  268,  985,  198,
+ /*  1000 */    10,  888,  890,  749,  957,  957,  916,  268,  985,  198,
  /*  1010 */   985,  349,  348,  425,  415,  299,  817,  832,  326,  825,
  /*  1020 */   120,  332,  133,  819,  268,   98,   98,   98,   98,   91,
  /*  1030 */    96,   96,   96,   96,   95,   95,   94,   94,   94,   93,
- /*  1040 */   351,  157,  810,  371,  382,  359,  959,  960,  358,  268,
- /*  1050 */   450,  918,  368,  324,  824,  824,  826,  450,  709,  450,
- /*  1060 */   264,  380,  889,  450,  877,  746,  253,  919,  255,  433,
+ /*  1040 */   351,  157,  810,  371,  382,  359,  958,  959,  358,  268,
+ /*  1050 */   450,  917,  368,  324,  824,  824,  826,  450,  709,  450,
+ /*  1060 */   264,  380,  888,  450,  876,  746,  253,  918,  255,  433,
  /*  1070 */    36,   36,  234,  450,  234,  120,  269,   37,   37,   12,
  /*  1080 */    12,  334,  272,   27,   27,  450,  330,  118,  450,  162,
  /*  1090 */   742,  280,  450,   38,   38,  450,  985,  356,  985,  450,
- /*  1100 */   709, 1210,  450,  132,  450,   39,   39,  450,   40,   40,
+ /*  1100 */   709, 1209,  450,  132,  450,   39,   39,  450,   40,   40,
  /*  1110 */   450,  362,   41,   41,  450,   42,   42,  450,  254,   28,
  /*  1120 */    28,  450,   29,   29,   31,   31,  450,   43,   43,  450,
  /*  1130 */    44,   44,  450,  714,   45,   45,  450,   11,   11,  767,
  /*  1140 */   450,   46,   46,  450,  268,  450,  105,  105,  450,   47,
  /*  1150 */    47,  450,   48,   48,  450,  237,   33,   33,  450,  172,
  /*  1160 */    49,   49,  450,   50,   50,   34,   34,  274,  122,  122,
- /*  1170 */   450,  123,  123,  450,  124,  124,  450,  898,   56,   56,
- /*  1180 */   450,  897,   35,   35,  450,  267,  450,  817,  450,  817,
+ /*  1170 */   450,  123,  123,  450,  124,  124,  450,  897,   56,   56,
+ /*  1180 */   450,  896,   35,   35,  450,  267,  450,  817,  450,  817,
  /*  1190 */   106,  106,  450,   53,   53,  385,  107,  107,  450,  817,
  /*  1200 */   108,  108,  817,  450,  104,  104,  121,  121,  119,  119,
  /*  1210 */   450,  117,  112,  112,  450,  276,  450,  225,  111,  111,
- /*  1220 */   450,  730,  450,  109,  109,  450,  673,  674,  675,  912,
+ /*  1220 */   450,  730,  450,  109,  109,  450,  673,  674,  675,  911,
  /*  1230 */   110,  110,  317,  998,   55,   55,   57,   57,  692,  331,
- /*  1240 */    54,   54,   26,   26,  696,   30,   30,  317,  937,  197,
+ /*  1240 */    54,   54,   26,   26,  696,   30,   30,  317,  936,  197,
  /*  1250 */   196,  195,  335,  281,  336,  446,  331,  745,  689,  436,
- /*  1260 */   440,  444,  120,   72,  386,  223,  175,  345,  757,  933,
+ /*  1260 */   440,  444,  120,   72,  386,  223,  175,  345,  757,  932,
  /*  1270 */    20,  286,  319,  756,  815,  372,  374,  202,  202,  202,
- /*  1280 */   263,  395,  285,   74,  208,   21,  696,  719,  718,  884,
+ /*  1280 */   263,  395,  285,   74,  208,   21,  696,  719,  718,  883,
  /*  1290 */   120,  120,  120,  120,  120,  754,  278,  828,   77,   74,
- /*  1300 */   726,  727,  785,  783,  880,  202,  999,  208,  894,  893,
- /*  1310 */   894,  893,  694,  816,  763,  116,  774, 1290,  431,  432,
+ /*  1300 */   726,  727,  785,  783,  879,  202,  999,  208,  893,  892,
+ /*  1310 */   893,  892,  694,  816,  763,  116,  774, 1289,  431,  432,
  /*  1320 */   302,  999,  390,  303,  823,  697,  691,  680,  159,  289,
- /*  1330 */   679,  884,  681,  952,  291,  218,  293,    7,  316,  828,
- /*  1340 */   173,  805,  259,  364,  252,  911,  376,  713,  295,  435,
- /*  1350 */   308,  168,  955,  993,  135,  400,  990,  284,  882,  881,
- /*  1360 */   205,  928,  926,   59,  333,   62,  144,  156,  130,   72,
+ /*  1330 */   679,  883,  681,  951,  291,  218,  293,    7,  316,  828,
+ /*  1340 */   173,  805,  259,  364,  252,  910,  376,  713,  295,  435,
+ /*  1350 */   308,  168,  954,  993,  135,  400,  990,  284,  881,  880,
+ /*  1360 */   205,  927,  925,   59,  333,   62,  144,  156,  130,   72,
  /*  1370 */   802,  366,  367,  393,  137,  185,  189,  160,  139,  383,
- /*  1380 */    67,  896,  140,  141,  142,  148,  389,  812,  775,  266,
- /*  1390 */   219,  190,  154,  391,  913,  876,  271,  406,  191,  322,
+ /*  1380 */    67,  895,  140,  141,  142,  148,  389,  812,  775,  266,
+ /*  1390 */   219,  190,  154,  391,  912,  875,  271,  406,  191,  322,
  /*  1400 */   682,  733,  192,  342,  732,  724,  731,  711,  723,  421,
  /*  1410 */   705,   71,  323,    6,  204,  771,  288,   79,  297,  346,
- /*  1420 */   772,  704,  290,  283,  703,  770,  292,  294,  967,  239,
- /*  1430 */   769,  102,  862,  438,  426,  240,  424,  442,   73,  213,
- /*  1440 */   688,  238,   22,  453,  953,  214,  217,  216,  454,  677,
+ /*  1420 */   772,  704,  290,  283,  703,  770,  292,  294,  966,  239,
+ /*  1430 */   769,  102,  861,  438,  426,  240,  424,  442,   73,  213,
+ /*  1440 */   688,  238,   22,  453,  952,  214,  217,  216,  454,  677,
  /*  1450 */   676,  671,  753,  125,  115,  235,  126,  669,  353,  166,
- /*  1460 */   127,  244,  179,  357,  306,  304,  305,  307,  113,  892,
- /*  1470 */   327,  890,  811,  328,  134,  128,  136,  138,  743,  258,
- /*  1480 */   907,  184,  143,  129,  910,  186,   63,   64,  145,  187,
- /*  1490 */   906,   65,    8,   66,   13,  188,  202,  899,  265,  149,
+ /*  1460 */   127,  244,  179,  357,  306,  304,  305,  307,  113,  891,
+ /*  1470 */   327,  889,  811,  328,  134,  128,  136,  138,  743,  258,
+ /*  1480 */   906,  184,  143,  129,  909,  186,   63,   64,  145,  187,
+ /*  1490 */   905,   65,    8,   66,   13,  188,  202,  898,  265,  149,
  /*  1500 */   987,  388,  150,  685,  161,  392,  285,  193,  279,  396,
  /*  1510 */   151,  401,   68,   14,   15,  722,   69,  236,  831,  131,
- /*  1520 */   830,  860,   70,  751,   16,  414,  755,    4,  174,  220,
- /*  1530 */   222,  784,  201,  152,  779,   77,   74,   17,   18,  875,
- /*  1540 */   861,  859,  916,  864,  915,  207,  206,  942,  163,  437,
- /*  1550 */   948,  943,  164,  209, 1002,  441,  863,  165,  210,  829,
- /*  1560 */   695,   87,  312,  211, 1292, 1291,  309,
+ /*  1520 */   830,  859,   70,  751,   16,  414,  755,    4,  174,  220,
+ /*  1530 */   222,  784,  201,  152,  779,   77,   74,   17,   18,  874,
+ /*  1540 */   860,  858,  915,  863,  914,  207,  206,  941,  163,  437,
+ /*  1550 */   947,  942,  164,  209, 1002,  441,  862,  165,  210,  829,
+ /*  1560 */   695,   87,  312,  211, 1291, 1290,  309,
 };
 static const YYCODETYPE yy_lookahead[] = {
  /*     0 */    19,   95,   53,   97,   22,   24,   24,  101,   27,   28,
  /*    10 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
  /*    20 */    39,   40,   41,  152,   43,   44,   45,   46,   47,   48,
  /*    30 */    49,   50,   51,   52,   53,   19,   55,   55,  132,  133,
  /*    40 */   134,    1,    2,   27,   28,   29,   30,   31,   32,   33,
  /*    50 */    34,   35,   36,   37,   38,   39,   40,   41,  187,   43,
@@ -135109,61 +135630,61 @@ static const short yy_reduce_ofst[] = {
  /*   270 */  1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
  /*   280 */  1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
  /*   290 */  1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
  /*   300 */  1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
  /*   310 */  1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
  /*   320 */  1288, 1291, 1276, 1277, 1295,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */  1281, 1271, 1271, 1271, 1203, 1203, 1203, 1203, 1271, 1096,
- /*    10 */  1125, 1125, 1255, 1332, 1332, 1332, 1332, 1332, 1332, 1202,
- /*    20 */  1332, 1332, 1332, 1332, 1271, 1100, 1131, 1332, 1332, 1332,
- /*    30 */  1332, 1204, 1205, 1332, 1332, 1332, 1254, 1256, 1141, 1140,
- /*    40 */  1139, 1138, 1237, 1112, 1136, 1129, 1133, 1204, 1198, 1199,
- /*    50 */  1197, 1201, 1205, 1332, 1132, 1167, 1182, 1166, 1332, 1332,
+ /*     0 */  1280, 1270, 1270, 1270, 1202, 1202, 1202, 1202, 1270, 1096,
+ /*    10 */  1125, 1125, 1254, 1332, 1332, 1332, 1332, 1332, 1332, 1201,
+ /*    20 */  1332, 1332, 1332, 1332, 1270, 1100, 1131, 1332, 1332, 1332,
+ /*    30 */  1332, 1203, 1204, 1332, 1332, 1332, 1253, 1255, 1141, 1140,
+ /*    40 */  1139, 1138, 1236, 1112, 1136, 1129, 1133, 1203, 1197, 1198,
+ /*    50 */  1196, 1200, 1204, 1332, 1132, 1167, 1181, 1166, 1332, 1332,
  /*    60 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*    70 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*    80 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*    90 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /*   100 */  1332, 1332, 1332, 1332, 1176, 1181, 1188, 1180, 1177, 1169,
+ /*   100 */  1332, 1332, 1332, 1332, 1175, 1180, 1187, 1179, 1176, 1169,
  /*   110 */  1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172,
- /*   120 */  1332, 1173, 1185, 1184, 1183, 1262, 1289, 1288, 1332, 1332,
+ /*   120 */  1332, 1173, 1184, 1183, 1182, 1261, 1288, 1287, 1332, 1332,
  /*   130 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   140 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /*   150 */  1332, 1332, 1332, 1332, 1332, 1281, 1271, 1025, 1025, 1332,
- /*   160 */  1271, 1271, 1271, 1271, 1271, 1271, 1267, 1100, 1091, 1332,
+ /*   150 */  1332, 1332, 1332, 1332, 1332, 1280, 1270, 1025, 1025, 1332,
+ /*   160 */  1270, 1270, 1270, 1270, 1270, 1270, 1266, 1100, 1091, 1332,
  /*   170 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /*   180 */  1259, 1257, 1332, 1218, 1332, 1332, 1332, 1332, 1332, 1332,
+ /*   180 */  1258, 1256, 1332, 1217, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   190 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   200 */  1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332,
- /*   210 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1283, 1332, 1232,
+ /*   210 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1282, 1332, 1231,
  /*   220 */  1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114,
- /*   230 */  1321, 1135, 1321, 1042, 1303, 1039, 1125, 1114, 1200, 1125,
+ /*   230 */  1321, 1135, 1321, 1042, 1302, 1039, 1125, 1114, 1199, 1125,
  /*   240 */  1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105,
  /*   250 */  1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135,
- /*   260 */  1146, 1070, 1070, 1135, 1105, 1016, 1236, 1318, 1105, 1105,
- /*   270 */  1016, 1211, 1105, 1016, 1105, 1016, 1211, 1068, 1068, 1068,
- /*   280 */  1057, 1211, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
- /*   290 */  1118, 1113, 1118, 1113, 1118, 1113, 1105, 1206, 1105, 1332,
- /*   300 */  1211, 1215, 1215, 1211, 1130, 1119, 1128, 1126, 1135, 1022,
- /*   310 */  1060, 1286, 1286, 1282, 1282, 1282, 1282, 1329, 1329, 1267,
- /*   320 */  1298, 1298, 1044, 1044, 1298, 1332, 1332, 1332, 1332, 1332,
- /*   330 */  1332, 1293, 1332, 1220, 1332, 1332, 1332, 1332, 1332, 1332,
+ /*   260 */  1146, 1070, 1070, 1135, 1105, 1016, 1235, 1318, 1105, 1105,
+ /*   270 */  1016, 1210, 1105, 1016, 1105, 1016, 1210, 1068, 1068, 1068,
+ /*   280 */  1057, 1210, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
+ /*   290 */  1118, 1113, 1118, 1113, 1118, 1113, 1105, 1205, 1105, 1332,
+ /*   300 */  1210, 1214, 1214, 1210, 1130, 1119, 1128, 1126, 1135, 1022,
+ /*   310 */  1060, 1285, 1285, 1281, 1281, 1281, 1281, 1329, 1329, 1266,
+ /*   320 */  1297, 1297, 1044, 1044, 1297, 1332, 1332, 1332, 1332, 1332,
+ /*   330 */  1332, 1292, 1332, 1219, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   340 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /*   350 */  1332, 1332, 1152, 1332, 1000, 1264, 1332, 1332, 1263, 1332,
+ /*   350 */  1332, 1332, 1152, 1332, 1000, 1263, 1332, 1332, 1262, 1332,
  /*   360 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   370 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320,
- /*   380 */  1332, 1332, 1332, 1332, 1332, 1332, 1235, 1234, 1332, 1332,
+ /*   380 */  1332, 1332, 1332, 1332, 1332, 1332, 1234, 1233, 1332, 1332,
  /*   390 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
  /*   400 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
- /*   410 */  1332, 1082, 1332, 1332, 1332, 1307, 1332, 1332, 1332, 1332,
+ /*   410 */  1332, 1082, 1332, 1332, 1332, 1306, 1332, 1332, 1332, 1332,
  /*   420 */  1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332,
- /*   430 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1273,
- /*   440 */  1332, 1332, 1332, 1272, 1332, 1332, 1332, 1332, 1332, 1154,
+ /*   430 */  1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1272,
+ /*   440 */  1332, 1332, 1332, 1271, 1332, 1332, 1332, 1332, 1332, 1154,
  /*   450 */  1332, 1153, 1157, 1332, 1010, 1332,
 };
 /********** 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.
@@ -135599,153 +136120,153 @@ static const char *const yyRuleName[] = 
  /* 166 */ "expr ::= expr AND expr",
  /* 167 */ "expr ::= expr OR expr",
  /* 168 */ "expr ::= expr LT|GT|GE|LE expr",
  /* 169 */ "expr ::= expr EQ|NE expr",
  /* 170 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
  /* 171 */ "expr ::= expr PLUS|MINUS expr",
  /* 172 */ "expr ::= expr STAR|SLASH|REM expr",
  /* 173 */ "expr ::= expr CONCAT expr",
- /* 174 */ "likeop ::= LIKE_KW|MATCH",
- /* 175 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 176 */ "expr ::= expr likeop expr",
- /* 177 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 178 */ "expr ::= expr ISNULL|NOTNULL",
- /* 179 */ "expr ::= expr NOT NULL",
- /* 180 */ "expr ::= expr IS expr",
- /* 181 */ "expr ::= expr IS NOT expr",
- /* 182 */ "expr ::= NOT expr",
- /* 183 */ "expr ::= BITNOT expr",
- /* 184 */ "expr ::= MINUS expr",
- /* 185 */ "expr ::= PLUS expr",
- /* 186 */ "between_op ::= BETWEEN",
- /* 187 */ "between_op ::= NOT BETWEEN",
- /* 188 */ "expr ::= expr between_op expr AND expr",
- /* 189 */ "in_op ::= IN",
- /* 190 */ "in_op ::= NOT IN",
- /* 191 */ "expr ::= expr in_op LP exprlist RP",
- /* 192 */ "expr ::= LP select RP",
- /* 193 */ "expr ::= expr in_op LP select RP",
- /* 194 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 195 */ "expr ::= EXISTS LP select RP",
- /* 196 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 197 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 198 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 199 */ "case_else ::= ELSE expr",
- /* 200 */ "case_else ::=",
- /* 201 */ "case_operand ::= expr",
- /* 202 */ "case_operand ::=",
- /* 203 */ "exprlist ::=",
- /* 204 */ "nexprlist ::= nexprlist COMMA expr",
- /* 205 */ "nexprlist ::= expr",
- /* 206 */ "paren_exprlist ::=",
- /* 207 */ "paren_exprlist ::= LP exprlist RP",
- /* 208 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 209 */ "uniqueflag ::= UNIQUE",
- /* 210 */ "uniqueflag ::=",
- /* 211 */ "eidlist_opt ::=",
- /* 212 */ "eidlist_opt ::= LP eidlist RP",
- /* 213 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 214 */ "eidlist ::= nm collate sortorder",
- /* 215 */ "collate ::=",
- /* 216 */ "collate ::= COLLATE ID|STRING",
- /* 217 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 218 */ "cmd ::= VACUUM",
- /* 219 */ "cmd ::= VACUUM nm",
- /* 220 */ "cmd ::= PRAGMA nm dbnm",
- /* 221 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 222 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 223 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 224 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 225 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 226 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 227 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 228 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 229 */ "trigger_time ::= BEFORE",
- /* 230 */ "trigger_time ::= AFTER",
- /* 231 */ "trigger_time ::= INSTEAD OF",
- /* 232 */ "trigger_time ::=",
- /* 233 */ "trigger_event ::= DELETE|INSERT",
- /* 234 */ "trigger_event ::= UPDATE",
- /* 235 */ "trigger_event ::= UPDATE OF idlist",
- /* 236 */ "when_clause ::=",
- /* 237 */ "when_clause ::= WHEN expr",
- /* 238 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 239 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 240 */ "trnm ::= nm DOT nm",
- /* 241 */ "tridxby ::= INDEXED BY nm",
- /* 242 */ "tridxby ::= NOT INDEXED",
- /* 243 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 244 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
- /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 246 */ "trigger_cmd ::= select",
- /* 247 */ "expr ::= RAISE LP IGNORE RP",
- /* 248 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 249 */ "raisetype ::= ROLLBACK",
- /* 250 */ "raisetype ::= ABORT",
- /* 251 */ "raisetype ::= FAIL",
- /* 252 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 253 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 254 */ "cmd ::= DETACH database_kw_opt expr",
- /* 255 */ "key_opt ::=",
- /* 256 */ "key_opt ::= KEY expr",
- /* 257 */ "cmd ::= REINDEX",
- /* 258 */ "cmd ::= REINDEX nm dbnm",
- /* 259 */ "cmd ::= ANALYZE",
- /* 260 */ "cmd ::= ANALYZE nm dbnm",
- /* 261 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 262 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 263 */ "add_column_fullname ::= fullname",
- /* 264 */ "cmd ::= create_vtab",
- /* 265 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 266 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 267 */ "vtabarg ::=",
- /* 268 */ "vtabargtoken ::= ANY",
- /* 269 */ "vtabargtoken ::= lp anylist RP",
- /* 270 */ "lp ::= LP",
- /* 271 */ "with ::=",
- /* 272 */ "with ::= WITH wqlist",
- /* 273 */ "with ::= WITH RECURSIVE wqlist",
- /* 274 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 275 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 276 */ "input ::= cmdlist",
- /* 277 */ "cmdlist ::= cmdlist ecmd",
- /* 278 */ "cmdlist ::= ecmd",
- /* 279 */ "ecmd ::= SEMI",
- /* 280 */ "ecmd ::= explain cmdx SEMI",
- /* 281 */ "explain ::=",
- /* 282 */ "trans_opt ::=",
- /* 283 */ "trans_opt ::= TRANSACTION",
- /* 284 */ "trans_opt ::= TRANSACTION nm",
- /* 285 */ "savepoint_opt ::= SAVEPOINT",
- /* 286 */ "savepoint_opt ::=",
- /* 287 */ "cmd ::= create_table create_table_args",
- /* 288 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 289 */ "columnlist ::= columnname carglist",
- /* 290 */ "nm ::= ID|INDEXED",
- /* 291 */ "nm ::= STRING",
- /* 292 */ "nm ::= JOIN_KW",
- /* 293 */ "typetoken ::= typename",
- /* 294 */ "typename ::= ID|STRING",
- /* 295 */ "signed ::= plus_num",
- /* 296 */ "signed ::= minus_num",
- /* 297 */ "carglist ::= carglist ccons",
- /* 298 */ "carglist ::=",
- /* 299 */ "ccons ::= NULL onconf",
- /* 300 */ "conslist_opt ::= COMMA conslist",
- /* 301 */ "conslist ::= conslist tconscomma tcons",
- /* 302 */ "conslist ::= tcons",
- /* 303 */ "tconscomma ::=",
- /* 304 */ "defer_subclause_opt ::= defer_subclause",
- /* 305 */ "resolvetype ::= raisetype",
- /* 306 */ "selectnowith ::= oneselect",
- /* 307 */ "oneselect ::= values",
- /* 308 */ "sclp ::= selcollist COMMA",
- /* 309 */ "as ::= ID|STRING",
- /* 310 */ "expr ::= term",
+ /* 174 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 175 */ "expr ::= expr likeop expr",
+ /* 176 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 177 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 178 */ "expr ::= expr NOT NULL",
+ /* 179 */ "expr ::= expr IS expr",
+ /* 180 */ "expr ::= expr IS NOT expr",
+ /* 181 */ "expr ::= NOT expr",
+ /* 182 */ "expr ::= BITNOT expr",
+ /* 183 */ "expr ::= MINUS expr",
+ /* 184 */ "expr ::= PLUS expr",
+ /* 185 */ "between_op ::= BETWEEN",
+ /* 186 */ "between_op ::= NOT BETWEEN",
+ /* 187 */ "expr ::= expr between_op expr AND expr",
+ /* 188 */ "in_op ::= IN",
+ /* 189 */ "in_op ::= NOT IN",
+ /* 190 */ "expr ::= expr in_op LP exprlist RP",
+ /* 191 */ "expr ::= LP select RP",
+ /* 192 */ "expr ::= expr in_op LP select RP",
+ /* 193 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 194 */ "expr ::= EXISTS LP select RP",
+ /* 195 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 196 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 197 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 198 */ "case_else ::= ELSE expr",
+ /* 199 */ "case_else ::=",
+ /* 200 */ "case_operand ::= expr",
+ /* 201 */ "case_operand ::=",
+ /* 202 */ "exprlist ::=",
+ /* 203 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 204 */ "nexprlist ::= expr",
+ /* 205 */ "paren_exprlist ::=",
+ /* 206 */ "paren_exprlist ::= LP exprlist RP",
+ /* 207 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 208 */ "uniqueflag ::= UNIQUE",
+ /* 209 */ "uniqueflag ::=",
+ /* 210 */ "eidlist_opt ::=",
+ /* 211 */ "eidlist_opt ::= LP eidlist RP",
+ /* 212 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 213 */ "eidlist ::= nm collate sortorder",
+ /* 214 */ "collate ::=",
+ /* 215 */ "collate ::= COLLATE ID|STRING",
+ /* 216 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 217 */ "cmd ::= VACUUM",
+ /* 218 */ "cmd ::= VACUUM nm",
+ /* 219 */ "cmd ::= PRAGMA nm dbnm",
+ /* 220 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 221 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 222 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 223 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 224 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 225 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 226 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 227 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 228 */ "trigger_time ::= BEFORE",
+ /* 229 */ "trigger_time ::= AFTER",
+ /* 230 */ "trigger_time ::= INSTEAD OF",
+ /* 231 */ "trigger_time ::=",
+ /* 232 */ "trigger_event ::= DELETE|INSERT",
+ /* 233 */ "trigger_event ::= UPDATE",
+ /* 234 */ "trigger_event ::= UPDATE OF idlist",
+ /* 235 */ "when_clause ::=",
+ /* 236 */ "when_clause ::= WHEN expr",
+ /* 237 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 238 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 239 */ "trnm ::= nm DOT nm",
+ /* 240 */ "tridxby ::= INDEXED BY nm",
+ /* 241 */ "tridxby ::= NOT INDEXED",
+ /* 242 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 243 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 244 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 245 */ "trigger_cmd ::= select",
+ /* 246 */ "expr ::= RAISE LP IGNORE RP",
+ /* 247 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 248 */ "raisetype ::= ROLLBACK",
+ /* 249 */ "raisetype ::= ABORT",
+ /* 250 */ "raisetype ::= FAIL",
+ /* 251 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 252 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 253 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 254 */ "key_opt ::=",
+ /* 255 */ "key_opt ::= KEY expr",
+ /* 256 */ "cmd ::= REINDEX",
+ /* 257 */ "cmd ::= REINDEX nm dbnm",
+ /* 258 */ "cmd ::= ANALYZE",
+ /* 259 */ "cmd ::= ANALYZE nm dbnm",
+ /* 260 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 261 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 262 */ "add_column_fullname ::= fullname",
+ /* 263 */ "cmd ::= create_vtab",
+ /* 264 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 265 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 266 */ "vtabarg ::=",
+ /* 267 */ "vtabargtoken ::= ANY",
+ /* 268 */ "vtabargtoken ::= lp anylist RP",
+ /* 269 */ "lp ::= LP",
+ /* 270 */ "with ::=",
+ /* 271 */ "with ::= WITH wqlist",
+ /* 272 */ "with ::= WITH RECURSIVE wqlist",
+ /* 273 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 274 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 275 */ "input ::= cmdlist",
+ /* 276 */ "cmdlist ::= cmdlist ecmd",
+ /* 277 */ "cmdlist ::= ecmd",
+ /* 278 */ "ecmd ::= SEMI",
+ /* 279 */ "ecmd ::= explain cmdx SEMI",
+ /* 280 */ "explain ::=",
+ /* 281 */ "trans_opt ::=",
+ /* 282 */ "trans_opt ::= TRANSACTION",
+ /* 283 */ "trans_opt ::= TRANSACTION nm",
+ /* 284 */ "savepoint_opt ::= SAVEPOINT",
+ /* 285 */ "savepoint_opt ::=",
+ /* 286 */ "cmd ::= create_table create_table_args",
+ /* 287 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 288 */ "columnlist ::= columnname carglist",
+ /* 289 */ "nm ::= ID|INDEXED",
+ /* 290 */ "nm ::= STRING",
+ /* 291 */ "nm ::= JOIN_KW",
+ /* 292 */ "typetoken ::= typename",
+ /* 293 */ "typename ::= ID|STRING",
+ /* 294 */ "signed ::= plus_num",
+ /* 295 */ "signed ::= minus_num",
+ /* 296 */ "carglist ::= carglist ccons",
+ /* 297 */ "carglist ::=",
+ /* 298 */ "ccons ::= NULL onconf",
+ /* 299 */ "conslist_opt ::= COMMA conslist",
+ /* 300 */ "conslist ::= conslist tconscomma tcons",
+ /* 301 */ "conslist ::= tcons",
+ /* 302 */ "tconscomma ::=",
+ /* 303 */ "defer_subclause_opt ::= defer_subclause",
+ /* 304 */ "resolvetype ::= raisetype",
+ /* 305 */ "selectnowith ::= oneselect",
+ /* 306 */ "oneselect ::= values",
+ /* 307 */ "sclp ::= selcollist COMMA",
+ /* 308 */ "as ::= ID|STRING",
+ /* 309 */ "expr ::= term",
+ /* 310 */ "likeop ::= LIKE_KW|MATCH",
  /* 311 */ "exprlist ::= nexprlist",
  /* 312 */ "nmnum ::= plus_num",
  /* 313 */ "nmnum ::= nm",
  /* 314 */ "nmnum ::= ON",
  /* 315 */ "nmnum ::= DELETE",
  /* 316 */ "nmnum ::= DEFAULT",
  /* 317 */ "plus_num ::= INTEGER|FLOAT",
  /* 318 */ "foreach_clause ::=",
@@ -136372,17 +136893,16 @@ static const struct {
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
   { 173, 3 },
-  { 221, 1 },
   { 221, 2 },
   { 173, 3 },
   { 173, 5 },
   { 173, 2 },
   { 173, 3 },
   { 173, 3 },
   { 173, 4 },
   { 173, 2 },
@@ -136509,16 +137029,17 @@ static const struct {
   { 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 },
@@ -136651,17 +137172,17 @@ static void yy_reduce(
       case 16: /* ifnotexists ::= */
       case 19: /* temp ::= */ yytestcase(yyruleno==19);
       case 22: /* table_options ::= */ yytestcase(yyruleno==22);
       case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
       case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
       case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
       case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
       case 90: /* distinct ::= */ yytestcase(yyruleno==90);
-      case 215: /* collate ::= */ yytestcase(yyruleno==215);
+      case 214: /* collate ::= */ yytestcase(yyruleno==214);
 {yymsp[1].minor.yy194 = 0;}
         break;
       case 17: /* ifnotexists ::= IF NOT EXISTS */
 {yymsp[-2].minor.yy194 = 1;}
         break;
       case 18: /* temp ::= TEMP */
       case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
 {yymsp[0].minor.yy194 = 1;}
@@ -136795,19 +137316,19 @@ static void yy_reduce(
         break;
       case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
       case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
       case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
 {yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
         break;
       case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
       case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
-      case 187: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==187);
-      case 190: /* in_op ::= NOT IN */ yytestcase(yyruleno==190);
-      case 216: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==216);
+      case 186: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==186);
+      case 189: /* in_op ::= NOT IN */ yytestcase(yyruleno==189);
+      case 215: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==215);
 {yymsp[-1].minor.yy194 = 1;}
         break;
       case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
 {yymsp[-1].minor.yy194 = 0;}
         break;
       case 61: /* tconscomma ::= COMMA */
 {pParse->constraintName.n = 0;}
         break;
@@ -136961,19 +137482,19 @@ static void yy_reduce(
 {yymsp[0].minor.yy194 = SF_Distinct;}
         break;
       case 89: /* distinct ::= ALL */
 {yymsp[0].minor.yy194 = SF_All;}
         break;
       case 91: /* sclp ::= */
       case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
       case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
-      case 203: /* exprlist ::= */ yytestcase(yyruleno==203);
-      case 206: /* paren_exprlist ::= */ yytestcase(yyruleno==206);
-      case 211: /* eidlist_opt ::= */ yytestcase(yyruleno==211);
+      case 202: /* exprlist ::= */ yytestcase(yyruleno==202);
+      case 205: /* paren_exprlist ::= */ yytestcase(yyruleno==205);
+      case 210: /* eidlist_opt ::= */ yytestcase(yyruleno==210);
 {yymsp[1].minor.yy148 = 0;}
         break;
       case 92: /* selcollist ::= sclp expr as */
 {
    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);
 }
@@ -136989,18 +137510,18 @@ static void yy_reduce(
   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 95: /* as ::= AS nm */
       case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
-      case 225: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
-      case 226: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==226);
+      case 224: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
+      case 225: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
         break;
       case 97: /* from ::= */
 {yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
         break;
       case 98: /* from ::= FROM seltablist */
 {
   yymsp[-1].minor.yy185 = yymsp[0].minor.yy185;
@@ -137073,24 +137594,24 @@ static void yy_reduce(
 {yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
         break;
       case 111: /* 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 112: /* on_opt ::= ON expr */
       case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
       case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
-      case 199: /* case_else ::= ELSE expr */ yytestcase(yyruleno==199);
+      case 198: /* case_else ::= ELSE expr */ yytestcase(yyruleno==198);
 {yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
         break;
       case 113: /* on_opt ::= */
       case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
       case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
-      case 200: /* case_else ::= */ yytestcase(yyruleno==200);
-      case 202: /* case_operand ::= */ yytestcase(yyruleno==202);
+      case 199: /* case_else ::= */ yytestcase(yyruleno==199);
+      case 201: /* case_operand ::= */ yytestcase(yyruleno==201);
 {yymsp[1].minor.yy72 = 0;}
         break;
       case 115: /* indexed_opt ::= INDEXED BY nm */
 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
         break;
       case 116: /* indexed_opt ::= NOT INDEXED */
 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
         break;
@@ -137227,17 +137748,17 @@ static void yy_reduce(
   yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
 }
         break;
       case 158: /* term ::= INTEGER */
 {
   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;
-  if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf;
+  if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf|EP_Resolved;
 }
   yymsp[0].minor.yy190 = yylhsminor.yy190;
         break;
       case 159: /* expr ::= VARIABLE */
 {
   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);
@@ -137317,96 +137838,93 @@ static void yy_reduce(
       case 168: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==168);
       case 169: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==169);
       case 170: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==170);
       case 171: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==171);
       case 172: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==172);
       case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173);
 {spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
         break;
-      case 174: /* likeop ::= LIKE_KW|MATCH */
-{yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/}
-        break;
-      case 175: /* likeop ::= NOT LIKE_KW|MATCH */
+      case 174: /* 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 176: /* expr ::= expr likeop expr */
+      case 175: /* expr ::= expr likeop expr */
 {
   ExprList *pList;
   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 177: /* expr ::= expr likeop expr ESCAPE expr */
+      case 176: /* expr ::= expr likeop expr ESCAPE expr */
 {
   ExprList *pList;
   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 178: /* expr ::= expr ISNULL|NOTNULL */
+      case 177: /* expr ::= expr ISNULL|NOTNULL */
 {spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
         break;
-      case 179: /* expr ::= expr NOT NULL */
+      case 178: /* expr ::= expr NOT NULL */
 {spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
         break;
-      case 180: /* expr ::= expr IS expr */
+      case 179: /* expr ::= expr IS expr */
 {
   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 181: /* expr ::= expr IS NOT expr */
+      case 180: /* expr ::= expr IS NOT expr */
 {
   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 182: /* expr ::= NOT expr */
-      case 183: /* expr ::= BITNOT expr */ yytestcase(yyruleno==183);
+      case 181: /* expr ::= NOT expr */
+      case 182: /* expr ::= BITNOT expr */ yytestcase(yyruleno==182);
 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
         break;
-      case 184: /* expr ::= MINUS expr */
+      case 183: /* expr ::= MINUS expr */
 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
         break;
-      case 185: /* expr ::= PLUS expr */
+      case 184: /* expr ::= PLUS expr */
 {spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
         break;
-      case 186: /* between_op ::= BETWEEN */
-      case 189: /* in_op ::= IN */ yytestcase(yyruleno==189);
+      case 185: /* between_op ::= BETWEEN */
+      case 188: /* in_op ::= IN */ yytestcase(yyruleno==188);
 {yymsp[0].minor.yy194 = 0;}
         break;
-      case 188: /* expr ::= expr between_op expr AND expr */
+      case 187: /* expr ::= expr between_op expr AND expr */
 {
   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);
   } 
   exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
   yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
 }
         break;
-      case 191: /* expr ::= expr in_op LP exprlist RP */
+      case 190: /* expr ::= expr in_op LP exprlist RP */
 {
     if( yymsp[-1].minor.yy148==0 ){
       /* Expressions of the form
       **
       **      expr1 IN ()
       **      expr1 NOT IN ()
       **
       ** simplify to constants 0 (false) and 1 (true), respectively,
@@ -137449,366 +137967,367 @@ static void yy_reduce(
       }else{
         sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
       }
       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 192: /* expr ::= LP select RP */
+      case 191: /* expr ::= LP select RP */
 {
     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 193: /* expr ::= expr in_op LP select RP */
+      case 192: /* expr ::= expr in_op LP select RP */
 {
     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 194: /* expr ::= expr in_op nm dbnm paren_exprlist */
+      case 193: /* expr ::= expr in_op nm dbnm paren_exprlist */
 {
     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 195: /* expr ::= EXISTS LP select RP */
+      case 194: /* expr ::= EXISTS LP select RP */
 {
     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 196: /* expr ::= CASE case_operand case_exprlist case_else END */
+      case 195: /* expr ::= CASE case_operand case_exprlist case_else END */
 {
   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.yy148);
     sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
   }
 }
         break;
-      case 197: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+      case 196: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
 {
   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 198: /* case_exprlist ::= WHEN expr THEN expr */
+      case 197: /* case_exprlist ::= WHEN expr THEN expr */
 {
   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 201: /* case_operand ::= expr */
+      case 200: /* case_operand ::= expr */
 {yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
         break;
-      case 204: /* nexprlist ::= nexprlist COMMA expr */
+      case 203: /* nexprlist ::= nexprlist COMMA expr */
 {yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
         break;
-      case 205: /* nexprlist ::= expr */
+      case 204: /* nexprlist ::= expr */
 {yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
         break;
-      case 207: /* paren_exprlist ::= LP exprlist RP */
-      case 212: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==212);
+      case 206: /* paren_exprlist ::= LP exprlist RP */
+      case 211: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==211);
 {yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
         break;
-      case 208: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+      case 207: /* 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.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 209: /* uniqueflag ::= UNIQUE */
-      case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250);
+      case 208: /* uniqueflag ::= UNIQUE */
+      case 249: /* raisetype ::= ABORT */ yytestcase(yyruleno==249);
 {yymsp[0].minor.yy194 = OE_Abort;}
         break;
-      case 210: /* uniqueflag ::= */
+      case 209: /* uniqueflag ::= */
 {yymsp[1].minor.yy194 = OE_None;}
         break;
-      case 213: /* eidlist ::= eidlist COMMA nm collate sortorder */
+      case 212: /* eidlist ::= eidlist COMMA nm collate sortorder */
 {
   yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
 }
         break;
-      case 214: /* eidlist ::= nm collate sortorder */
+      case 213: /* eidlist ::= nm collate sortorder */
 {
   yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
 }
         break;
-      case 217: /* cmd ::= DROP INDEX ifexists fullname */
+      case 216: /* cmd ::= DROP INDEX ifexists fullname */
 {sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
         break;
-      case 218: /* cmd ::= VACUUM */
+      case 217: /* cmd ::= VACUUM */
 {sqlite3Vacuum(pParse,0);}
         break;
-      case 219: /* cmd ::= VACUUM nm */
+      case 218: /* cmd ::= VACUUM nm */
 {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 220: /* cmd ::= PRAGMA nm dbnm */
+      case 219: /* cmd ::= PRAGMA nm dbnm */
 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
         break;
-      case 221: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+      case 220: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
         break;
-      case 222: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+      case 221: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
         break;
-      case 223: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+      case 222: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
         break;
-      case 224: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+      case 223: /* 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 227: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+      case 226: /* 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.yy145, &all);
 }
         break;
-      case 228: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+      case 227: /* 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.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 229: /* trigger_time ::= BEFORE */
+      case 228: /* trigger_time ::= BEFORE */
 { yymsp[0].minor.yy194 = TK_BEFORE; }
         break;
-      case 230: /* trigger_time ::= AFTER */
+      case 229: /* trigger_time ::= AFTER */
 { yymsp[0].minor.yy194 = TK_AFTER;  }
         break;
-      case 231: /* trigger_time ::= INSTEAD OF */
+      case 230: /* trigger_time ::= INSTEAD OF */
 { yymsp[-1].minor.yy194 = TK_INSTEAD;}
         break;
-      case 232: /* trigger_time ::= */
+      case 231: /* trigger_time ::= */
 { yymsp[1].minor.yy194 = TK_BEFORE; }
         break;
-      case 233: /* trigger_event ::= DELETE|INSERT */
-      case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234);
+      case 232: /* trigger_event ::= DELETE|INSERT */
+      case 233: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==233);
 {yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
         break;
-      case 235: /* trigger_event ::= UPDATE OF idlist */
+      case 234: /* trigger_event ::= UPDATE OF idlist */
 {yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
         break;
-      case 236: /* when_clause ::= */
-      case 255: /* key_opt ::= */ yytestcase(yyruleno==255);
+      case 235: /* when_clause ::= */
+      case 254: /* key_opt ::= */ yytestcase(yyruleno==254);
 { yymsp[1].minor.yy72 = 0; }
         break;
-      case 237: /* when_clause ::= WHEN expr */
-      case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256);
+      case 236: /* when_clause ::= WHEN expr */
+      case 255: /* key_opt ::= KEY expr */ yytestcase(yyruleno==255);
 { yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
         break;
-      case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+      case 237: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
 {
   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 239: /* trigger_cmd_list ::= trigger_cmd SEMI */
+      case 238: /* trigger_cmd_list ::= trigger_cmd SEMI */
 { 
   assert( yymsp[-1].minor.yy145!=0 );
   yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
 }
         break;
-      case 240: /* trnm ::= nm DOT nm */
+      case 239: /* trnm ::= nm DOT nm */
 {
   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 241: /* tridxby ::= INDEXED BY nm */
+      case 240: /* tridxby ::= INDEXED BY nm */
 {
   sqlite3ErrorMsg(pParse,
         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      case 242: /* tridxby ::= NOT INDEXED */
+      case 241: /* tridxby ::= NOT INDEXED */
 {
   sqlite3ErrorMsg(pParse,
         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+      case 242: /* 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 244: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+      case 243: /* 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 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+      case 244: /* 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 246: /* trigger_cmd ::= select */
+      case 245: /* trigger_cmd ::= select */
 {yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
         break;
-      case 247: /* expr ::= RAISE LP IGNORE RP */
+      case 246: /* expr ::= RAISE LP IGNORE RP */
 {
   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;
   }
 }
         break;
-      case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */
+      case 247: /* expr ::= RAISE LP raisetype COMMA nm RP */
 {
   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;
   }
 }
         break;
-      case 249: /* raisetype ::= ROLLBACK */
+      case 248: /* raisetype ::= ROLLBACK */
 {yymsp[0].minor.yy194 = OE_Rollback;}
         break;
-      case 251: /* raisetype ::= FAIL */
+      case 250: /* raisetype ::= FAIL */
 {yymsp[0].minor.yy194 = OE_Fail;}
         break;
-      case 252: /* cmd ::= DROP TRIGGER ifexists fullname */
+      case 251: /* cmd ::= DROP TRIGGER ifexists fullname */
 {
   sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
 }
         break;
-      case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+      case 252: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
 {
   sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
 }
         break;
-      case 254: /* cmd ::= DETACH database_kw_opt expr */
+      case 253: /* cmd ::= DETACH database_kw_opt expr */
 {
   sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
 }
         break;
-      case 257: /* cmd ::= REINDEX */
+      case 256: /* cmd ::= REINDEX */
 {sqlite3Reindex(pParse, 0, 0);}
         break;
-      case 258: /* cmd ::= REINDEX nm dbnm */
+      case 257: /* cmd ::= REINDEX nm dbnm */
 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 259: /* cmd ::= ANALYZE */
+      case 258: /* cmd ::= ANALYZE */
 {sqlite3Analyze(pParse, 0, 0);}
         break;
-      case 260: /* cmd ::= ANALYZE nm dbnm */
+      case 259: /* cmd ::= ANALYZE nm dbnm */
 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 261: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+      case 260: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 {
   sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
 }
         break;
-      case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+      case 261: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
 {
   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 263: /* add_column_fullname ::= fullname */
+      case 262: /* add_column_fullname ::= fullname */
 {
   disableLookaside(pParse);
   sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
 }
         break;
-      case 264: /* cmd ::= create_vtab */
+      case 263: /* cmd ::= create_vtab */
 {sqlite3VtabFinishParse(pParse,0);}
         break;
-      case 265: /* cmd ::= create_vtab LP vtabarglist RP */
+      case 264: /* cmd ::= create_vtab LP vtabarglist RP */
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 266: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+      case 265: /* 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.yy194);
 }
         break;
-      case 267: /* vtabarg ::= */
+      case 266: /* vtabarg ::= */
 {sqlite3VtabArgInit(pParse);}
         break;
-      case 268: /* vtabargtoken ::= ANY */
-      case 269: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==269);
-      case 270: /* lp ::= LP */ yytestcase(yyruleno==270);
+      case 267: /* vtabargtoken ::= ANY */
+      case 268: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==268);
+      case 269: /* lp ::= LP */ yytestcase(yyruleno==269);
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 271: /* with ::= */
+      case 270: /* with ::= */
 {yymsp[1].minor.yy285 = 0;}
         break;
-      case 272: /* with ::= WITH wqlist */
+      case 271: /* with ::= WITH wqlist */
 { yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
         break;
-      case 273: /* with ::= WITH RECURSIVE wqlist */
+      case 272: /* with ::= WITH RECURSIVE wqlist */
 { yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
         break;
-      case 274: /* wqlist ::= nm eidlist_opt AS LP select RP */
+      case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
 {
   yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
 }
         break;
-      case 275: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+      case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
 {
   yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
 }
         break;
       default:
-      /* (276) input ::= cmdlist */ yytestcase(yyruleno==276);
-      /* (277) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==277);
-      /* (278) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=278);
-      /* (279) ecmd ::= SEMI */ yytestcase(yyruleno==279);
-      /* (280) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==280);
-      /* (281) explain ::= */ yytestcase(yyruleno==281);
-      /* (282) trans_opt ::= */ yytestcase(yyruleno==282);
-      /* (283) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==283);
-      /* (284) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==284);
-      /* (285) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==285);
-      /* (286) savepoint_opt ::= */ yytestcase(yyruleno==286);
-      /* (287) cmd ::= create_table create_table_args */ yytestcase(yyruleno==287);
-      /* (288) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==288);
-      /* (289) columnlist ::= columnname carglist */ yytestcase(yyruleno==289);
-      /* (290) nm ::= ID|INDEXED */ yytestcase(yyruleno==290);
-      /* (291) nm ::= STRING */ yytestcase(yyruleno==291);
-      /* (292) nm ::= JOIN_KW */ yytestcase(yyruleno==292);
-      /* (293) typetoken ::= typename */ yytestcase(yyruleno==293);
-      /* (294) typename ::= ID|STRING */ yytestcase(yyruleno==294);
-      /* (295) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
-      /* (296) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=296);
-      /* (297) carglist ::= carglist ccons */ yytestcase(yyruleno==297);
-      /* (298) carglist ::= */ yytestcase(yyruleno==298);
-      /* (299) ccons ::= NULL onconf */ yytestcase(yyruleno==299);
-      /* (300) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==300);
-      /* (301) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==301);
-      /* (302) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=302);
-      /* (303) tconscomma ::= */ yytestcase(yyruleno==303);
-      /* (304) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=304);
-      /* (305) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=305);
-      /* (306) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=306);
-      /* (307) oneselect ::= values */ yytestcase(yyruleno==307);
-      /* (308) sclp ::= selcollist COMMA */ yytestcase(yyruleno==308);
-      /* (309) as ::= ID|STRING */ yytestcase(yyruleno==309);
-      /* (310) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=310);
+      /* (275) input ::= cmdlist */ yytestcase(yyruleno==275);
+      /* (276) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==276);
+      /* (277) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=277);
+      /* (278) ecmd ::= SEMI */ yytestcase(yyruleno==278);
+      /* (279) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==279);
+      /* (280) explain ::= */ yytestcase(yyruleno==280);
+      /* (281) trans_opt ::= */ yytestcase(yyruleno==281);
+      /* (282) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==282);
+      /* (283) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==283);
+      /* (284) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==284);
+      /* (285) savepoint_opt ::= */ yytestcase(yyruleno==285);
+      /* (286) cmd ::= create_table create_table_args */ yytestcase(yyruleno==286);
+      /* (287) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==287);
+      /* (288) columnlist ::= columnname carglist */ yytestcase(yyruleno==288);
+      /* (289) nm ::= ID|INDEXED */ yytestcase(yyruleno==289);
+      /* (290) nm ::= STRING */ yytestcase(yyruleno==290);
+      /* (291) nm ::= JOIN_KW */ yytestcase(yyruleno==291);
+      /* (292) typetoken ::= typename */ yytestcase(yyruleno==292);
+      /* (293) typename ::= ID|STRING */ yytestcase(yyruleno==293);
+      /* (294) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=294);
+      /* (295) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
+      /* (296) carglist ::= carglist ccons */ yytestcase(yyruleno==296);
+      /* (297) carglist ::= */ yytestcase(yyruleno==297);
+      /* (298) ccons ::= NULL onconf */ yytestcase(yyruleno==298);
+      /* (299) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==299);
+      /* (300) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==300);
+      /* (301) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=301);
+      /* (302) tconscomma ::= */ yytestcase(yyruleno==302);
+      /* (303) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=303);
+      /* (304) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=304);
+      /* (305) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=305);
+      /* (306) oneselect ::= values */ yytestcase(yyruleno==306);
+      /* (307) sclp ::= selcollist COMMA */ yytestcase(yyruleno==307);
+      /* (308) as ::= ID|STRING */ yytestcase(yyruleno==308);
+      /* (309) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=309);
+      /* (310) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==310);
       /* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311);
       /* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312);
       /* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313);
       /* (314) nmnum ::= ON */ yytestcase(yyruleno==314);
       /* (315) nmnum ::= DELETE */ yytestcase(yyruleno==315);
       /* (316) nmnum ::= DEFAULT */ yytestcase(yyruleno==316);
       /* (317) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==317);
       /* (318) foreach_clause ::= */ yytestcase(yyruleno==318);
@@ -138851,34 +139370,33 @@ SQLITE_PRIVATE int sqlite3GetToken(const
 ** Run the parser on the given SQL string.  The parser structure is
 ** passed in.  An SQLITE_ status code is returned.  If an error occurs
 ** then an and attempt is made to write an error message into 
 ** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
 ** error message.
 */
 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 */
   sqlite3 *db = pParse->db;       /* The database connection */
   int mxSqlLen;                   /* Max length of an SQL string */
 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
   unsigned char zSpace[sizeof(yyParser)];  /* Space for parser engine object */
 #endif
 
   assert( zSql!=0 );
   mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
   if( db->nVdbeActive==0 ){
     db->u1.isInterrupted = 0;
   }
   pParse->rc = SQLITE_OK;
   pParse->zTail = zSql;
-  i = 0;
   assert( pzErrMsg!=0 );
   /* sqlite3ParserTrace(stdout, "parser: "); */
 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
   pEngine = zSpace;
   sqlite3ParserInit(pEngine);
 #else
   pEngine = sqlite3ParserAlloc(sqlite3Malloc);
   if( pEngine==0 ){
@@ -138886,55 +139404,57 @@ SQLITE_PRIVATE int sqlite3RunParser(Pars
     return SQLITE_NOMEM_BKPT;
   }
 #endif
   assert( pParse->pNewTable==0 );
   assert( pParse->pNewTrigger==0 );
   assert( pParse->nVar==0 );
   assert( pParse->pVList==0 );
   while( 1 ){
-    assert( i>=0 );
-    if( zSql[i]!=0 ){
-      pParse->sLastToken.z = &zSql[i];
-      pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType);
-      i += pParse->sLastToken.n;
-      if( i>mxSqlLen ){
+    if( zSql[0]!=0 ){
+      n = sqlite3GetToken((u8*)zSql, &tokenType);
+      mxSqlLen -= n;
+      if( mxSqlLen<0 ){
         pParse->rc = SQLITE_TOOBIG;
         break;
       }
     }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;
       }
+      zSql -= n;
     }
     if( tokenType>=TK_SPACE ){
       assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
       if( db->u1.isInterrupted ){
         pParse->rc = SQLITE_INTERRUPT;
         break;
       }
       if( tokenType==TK_ILLEGAL ){
-        sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
-                        &pParse->sLastToken);
-        break;
-      }
-    }else{
+        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;
     }
   }
   assert( nErr==0 );
-  pParse->zTail = &zSql[i];
+  pParse->zTail = zSql;
 #ifdef YYTRACKMAXSTACKDEPTH
   sqlite3_mutex_enter(sqlite3MallocMutex());
   sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
       sqlite3ParserStackPeak(pEngine)
   );
   sqlite3_mutex_leave(sqlite3MallocMutex());
 #endif /* YYDEBUG */
 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
@@ -140300,16 +140820,31 @@ SQLITE_API sqlite_int64 sqlite3_last_ins
     (void)SQLITE_MISUSE_BKPT;
     return 0;
   }
 #endif
   return db->lastRowid;
 }
 
 /*
+** Set the value returned by the sqlite3_last_insert_rowid() API function.
+*/
+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);
+}
+
+/*
 ** Return the number of changes in the most recent call to sqlite3_exec().
 */
 SQLITE_API int sqlite3_changes(sqlite3 *db){
 #ifdef SQLITE_ENABLE_API_ARMOR
   if( !sqlite3SafetyCheckOk(db) ){
     (void)SQLITE_MISUSE_BKPT;
     return 0;
   }
@@ -145049,18 +145584,19 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(
   v = (*ptr++);                                               \
   if( (v & mask2)==0 ){ var = v; return ret; }
 
 /* 
 ** Read a 64-bit variable-length integer from memory starting at p[0].
 ** 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;
 
   GETVARINT_INIT(a, p, 0,  0x00,     0x80, *v, 1);
   GETVARINT_STEP(a, p, 7,  0x7F,     0x4000, *v, 2);
   GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *v, 3);
   GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4);
@@ -146097,17 +146633,19 @@ static int fts3InitVtab(
   memcpy(zCsr, argv[1], nDb);
   zCsr += nDb;
 
   /* Fill in the azColumn array */
   for(iCol=0; iCol<nCol; iCol++){
     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;
     zCsr += n+1;
     assert( zCsr <= &((char *)p)[nByte] );
   }
 
   /* Fill in the abNotindexed array */
@@ -148108,32 +148646,35 @@ static int fts3SyncMethod(sqlite3_vtab *
   ** Of course, updating the input segments also involves deleting a bunch
   ** of blocks from the segments table. But this is not considered overhead
   ** as it would also be required by a crisis-merge that used the same input 
   ** segments.
   */
   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
   ){
     int mxLevel = 0;              /* Maximum relative level value in db */
     int A;                        /* Incr-merge parameter A */
 
     rc = sqlite3Fts3MaxLevel(p, &mxLevel);
     assert( rc==SQLITE_OK || mxLevel==0 );
     A = p->nLeafAdd * mxLevel;
     A += (A/2);
     if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
   }
   sqlite3Fts3SegmentsClose(p);
+  sqlite3_set_last_insert_rowid(p->db, iLastRowid);
   return rc;
 }
 
 /*
 ** If it is currently unknown whether or not the FTS table has an %_stat
 ** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat
 ** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code
 ** if an error occurs.
@@ -159734,21 +160275,24 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(
   sqlite3_free(hint.a);
   return rc;
 }
 
 /*
 ** 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;
 }
 
 /*
 ** Process statements of the form:
 **
 **    INSERT INTO table(table) VALUES('merge=A,B');
@@ -162304,49 +162848,49 @@ static int unicodeDestroy(sqlite3_tokeni
 static int unicodeAddExceptions(
   unicode_tokenizer *p,           /* Tokenizer to add exceptions to */
   int bAlnum,                     /* Replace Isalnum() return value with this */
   const char *zIn,                /* Array of characters to make exceptions */
   int nIn                         /* Length of z in bytes */
 ){
   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++;
     }
   }
 
   if( nEntry ){
     int *aNew;                    /* New aiException[] array */
     int nNew;                     /* Number of valid entries in array aNew[] */
 
     aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
     if( aNew==0 ) return SQLITE_NOMEM;
     nNew = p->nException;
 
     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++;
       }
     }
     p->aiException = aNew;
     p->nException = nNew;
   }
 
   return SQLITE_OK;
@@ -162486,29 +163030,29 @@ static int unicodeNext(
   const char **paToken,           /* OUT: Token text */
   int *pnToken,                   /* OUT: Number of bytes at *paToken */
   int *piStart,                   /* OUT: Starting offset of token */
   int *piEnd,                     /* OUT: Ending offset of token */
   int *piPos                      /* OUT: Position integer of token */
 ){
   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;
   const unsigned char *zEnd;
   const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput];
 
   /* Scan past any delimiter characters before the start of the next token.
   ** Return SQLITE_DONE early if this takes us all the way to the end of 
   ** 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;
 
   zOut = pCsr->zToken;
   do {
     int iOut;
 
@@ -162518,26 +163062,26 @@ static int unicodeNext(
       if( !zNew ) return SQLITE_NOMEM;
       zOut = &zNew[zOut - pCsr->zToken];
       pCsr->zToken = zNew;
       pCsr->nAlloc += 64;
     }
 
     /* 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);
     }
 
     /* 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. */
   pCsr->iOff = (int)(z - pCsr->aInput);
   *paToken = pCsr->zToken;
   *pnToken = (int)(zOut - pCsr->zToken);
   *piStart = (int)(zStart - pCsr->aInput);
   *piEnd = (int)(zEnd - pCsr->aInput);
@@ -162691,19 +163235,19 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsal
     0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
     0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
     0x380400F0,
   };
   static const unsigned int aAscii[4] = {
     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;
     int iLo = 0;
     while( iHi>=iLo ){
       int iTest = (iHi + iLo) / 2;
       if( key >= aEntry[iTest] ){
         iRes = iTest;
@@ -162886,44 +163430,43 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold
    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( 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);
       if( cmp>=0 ){
         iRes = iTest;
         iLo = iTest+1;
       }else{
         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);
   }
   
   else if( c>=66560 && c<66600 ){
     ret = c + 40;
   }
@@ -163390,25 +163933,25 @@ static i64 readInt64(u8 *p){
   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)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)
+  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
 }
 
 /*
 ** Functions to serialize a 16 bit integer, 32 bit real number and
 ** 64 bit integer. The value returned is the number of bytes written
 ** to the argument buffer (always 2, 4 and 8 respectively).
@@ -168459,16 +169002,17 @@ struct sqlite3rbu {
   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;
@@ -170723,16 +171267,33 @@ static void rbuSetupCheckpoint(sqlite3rb
     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.
@@ -171378,19 +171939,36 @@ SQLITE_API int sqlite3rbu_step(sqlite3rb
               }
             }
   
             if( p->rc==SQLITE_OK ){
               p->eStage = RBU_STAGE_DONE;
               p->rc = SQLITE_DONE;
             }
           }else{
-            RbuFrame *pFrame = &p->aFrame[p->nStep];
-            rbuCheckpointFrame(p, pFrame);
-            p->nStep++;
+            /* 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;
@@ -171821,16 +172399,22 @@ SQLITE_API int sqlite3rbu_close(sqlite3r
   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);
@@ -171945,16 +172529,22 @@ SQLITE_API int sqlite3rbu_savestate(sqli
   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);
@@ -178360,32 +178950,34 @@ 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.iVal */
-#define JNODE_APPEND  0x10         /* More ARRAY/OBJECT entries at u.iAppend */
-#define JNODE_LABEL   0x20         /* Is a label of an object */
+#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 */
-  u8 iVal;               /* Replacement value when JNODE_REPLACE */
   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 */
@@ -178632,16 +179224,23 @@ static void jsonParseReset(JsonParse *pP
 ** 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);
@@ -178663,22 +179262,17 @@ static void jsonRenderNode(
       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|JNODE_REPLACE) ){
-            if( pNode[j].jnFlags & JNODE_REPLACE ){
-              jsonAppendSeparator(pOut);
-              jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
-            }
-          }else{
+          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;
@@ -178690,21 +179284,17 @@ static void jsonRenderNode(
       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, ':');
-            if( pNode[j+1].jnFlags & JNODE_REPLACE ){
-              jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
-            }else{
-              jsonRenderNode(&pNode[j+1], pOut, aReplace);
-            }
+            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, '}');
@@ -178921,17 +179511,16 @@ static int jsonParseAddNode(
 ){
   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->iVal = 0;
   p->n = n;
   p->u.zJContent = zContent;
   return pParse->nNode++;
 }
 
 /*
 ** Return true if z[] begins with 4 (or more) hexadecimal digits
 */
@@ -179387,16 +179976,35 @@ static void jsonWrongNumArgs(
   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
@@ -179579,16 +180187,115 @@ static void jsonExtractFunc(
     jsonAppendChar(&jx, ']');
     jsonResult(&jx);
     sqlite3_result_subtype(ctx, JSON_SUBTYPE);
   }
   jsonReset(&jx);
   jsonParseReset(&x);
 }
 
+/* This is the RFC 7396 MergePatch algorithm.
+*/
+static JsonNode *jsonMergePatch(
+  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
+  int 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,
@@ -179682,21 +180389,21 @@ static void jsonReplaceFunc(
   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->iVal = (u8)(i+1);
+      pNode->u.iReplace = i + 1;
     }
   }
   if( x.aNode[0].jnFlags & JNODE_REPLACE ){
-    sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
   }else{
     jsonReturnJson(x.aNode, ctx, argv);
   }
 replace_err:
   jsonParseReset(&x);
 }
 
 /*
@@ -179736,21 +180443,21 @@ static void jsonSetFunc(
     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->iVal = (u8)(i+1);
+      pNode->u.iReplace = i + 1;
     }
   }
   if( x.aNode[0].jnFlags & JNODE_REPLACE ){
-    sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
   }else{
     jsonReturnJson(x.aNode, ctx, argv);
   }
 jsonSetDone:
   jsonParseReset(&x);
 }
 
 /*
@@ -180383,16 +181090,17 @@ SQLITE_PRIVATE int sqlite3Json1Init(sqli
   } 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         },
 
@@ -181076,17 +181784,19 @@ SQLITE_EXTENSION_INIT1
 
 typedef unsigned char  u8;
 typedef unsigned int   u32;
 typedef unsigned short u16;
 typedef short i16;
 typedef sqlite3_int64 i64;
 typedef sqlite3_uint64 u64;
 
-#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#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))
 
@@ -186299,17 +187009,20 @@ static int fts5ExprNodeNext_OR(
   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 ) return rc;
+        if( rc!=SQLITE_OK ){
+          pNode->bNomatch = 0;
+          return rc;
+        }
       }
     }
   }
 
   fts5ExprNodeTest_OR(pExpr, pNode);
   return SQLITE_OK;
 }
 
@@ -186330,17 +187043,20 @@ static int fts5ExprNodeTest_AND(
     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 ) return rc;
+        if( rc!=SQLITE_OK ){
+          pAnd->bNomatch = 0;
+          return rc;
+        }
       }
 
       /* 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 ){
@@ -186369,16 +187085,18 @@ 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 */
 ){
@@ -186411,16 +187129,19 @@ static int fts5ExprNodeNext_NOT(
   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.
 */
@@ -197531,17 +198252,17 @@ static void fts5Fts5Func(
 */
 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-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c", -1, SQLITE_TRANSIENT);
+  sqlite3_result_text(pCtx, "fts5: 2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37", -1, SQLITE_TRANSIENT);
 }
 
 static int fts5Init(sqlite3 *db){
   static const sqlite3_module fts5Mod = {
     /* iVersion      */ 2,
     /* xCreate       */ fts5CreateMethod,
     /* xConnect      */ fts5ConnectMethod,
     /* xBestIndex    */ fts5BestIndexMethod,
@@ -198194,21 +198915,16 @@ static int sqlite3Fts5StorageDelete(Fts5
     }
     if( rc==SQLITE_OK ){
       sqlite3_bind_int64(pDel, 1, iDel);
       sqlite3_step(pDel);
       rc = sqlite3_reset(pDel);
     }
   }
 
-  /* Write the averages record */
-  if( rc==SQLITE_OK ){
-    rc = fts5StorageSaveTotals(p);
-  }
-
   return rc;
 }
 
 /*
 ** Delete all entries in the FTS5 index.
 */
 static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
   Fts5Config *pConfig = p->pConfig;
@@ -198402,21 +199118,16 @@ static int sqlite3Fts5StorageIndexInsert
   p->nTotalRow++;
 
   /* Write the %_docsize record */
   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 fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){
   Fts5Config *pConfig = p->pConfig;
   char *zSql;
   int rc;
 
@@ -198741,22 +199452,27 @@ static int sqlite3Fts5StorageRowCount(Ft
   }
   return rc;
 }
 
 /*
 ** Flush any data currently held in-memory to disk.
 */
 static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
-  if( bCommit && p->bTotalsValid ){
-    int rc = fts5StorageSaveTotals(p);
-    p->bTotalsValid = 0;
-    if( rc!=SQLITE_OK ) return rc;
-  }
-  return sqlite3Fts5IndexSync(p->pIndex, bCommit);
+  int rc = SQLITE_OK;
+  i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+  if( p->bTotalsValid ){
+    rc = fts5StorageSaveTotals(p);
+    if( bCommit ) p->bTotalsValid = 0;
+  }
+  if( rc==SQLITE_OK ){
+    rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
+  }
+  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(
old mode 100755
new mode 100644
--- a/db/sqlite3/src/sqlite3.h
+++ b/db/sqlite3/src/sqlite3.h
@@ -109,26 +109,26 @@ extern "C" {
 ** and Z will be reset to zero.
 **
 ** 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.17.0"
-#define SQLITE_VERSION_NUMBER 3017000
-#define SQLITE_SOURCE_ID      "2017-02-13 16:02:40 ada05cfa86ad7f5645450ac7a2a21c9aa6e57d2c"
+#define SQLITE_VERSION        "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID      "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
 ** 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
@@ -2035,30 +2035,40 @@ SQLITE_API int sqlite3_extended_result_c
 ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
 ** has a unique 64-bit signed
 ** integer key called the [ROWID | "rowid"]. ^The rowid is always available
 ** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
 ** names are not also used by explicitly declared columns. ^If
 ** 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
 ** routine.  ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
 ** and INSERT OR ABORT make no changes to the return value of this
 ** routine when their insertion fails.  ^(When INSERT OR REPLACE
 ** encounters a constraint violation, it does not fail.  The
 ** INSERT continues to completion after deleting rows that caused
@@ -2076,16 +2086,26 @@ SQLITE_API int sqlite3_extended_result_c
 ** function is running and thus changes the last insert [rowid],
 ** then the value returned by [sqlite3_last_insert_rowid()] is
 ** unpredictable and might not equal either the old or the new
 ** last insert [rowid].
 */
 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
 ** METHOD: sqlite3
 **
 ** ^This function returns the number of rows modified, inserted or
 ** deleted by the most recently completed INSERT, UPDATE or DELETE
 ** statement on the database connection specified by the only parameter.
 ** ^Executing any other type of SQL statement does not modify the value
 ** returned by this function.
@@ -3399,19 +3419,19 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
 ** <dd>The maximum depth of the parse tree on any expression.</dd>)^
 **
 ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
 ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
 **
 ** [[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>)^
 **
 ** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
 ** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
 **
 ** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
@@ -3439,16 +3459,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, i
 #define SQLITE_LIMIT_VDBE_OP                   5
 #define SQLITE_LIMIT_FUNCTION_ARG              6
 #define SQLITE_LIMIT_ATTACHED                  7
 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
 #define SQLITE_LIMIT_WORKER_THREADS           11
 
+
 /*
 ** CAPI3REF: Compiling An SQL Statement
 ** KEYWORDS: {SQL statement compiler}
 ** METHOD: sqlite3
 ** CONSTRUCTOR: sqlite3_stmt
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
 ** program using one of these routines.
--- a/devtools/client/debugger/new/debugger.js
+++ b/devtools/client/debugger/new/debugger.js
@@ -2022,67 +2022,67 @@ return /******/ (function(modules) { // 
 
 	module.exports = __WEBPACK_EXTERNAL_MODULE_31__;
 
 /***/ },
 /* 32 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* This Source Code Form is subject to the terms of the Mozilla Public
-	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
-	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-	const React = __webpack_require__(2);
-	const ReactDOM = __webpack_require__(31);
-	const { DOM: dom, PropTypes } = React;
-
-	const Draggable = React.createClass({
-	  displayName: "Draggable",
-
-	  propTypes: {
-	    onMove: PropTypes.func.isRequired,
-	    onStart: PropTypes.func,
-	    onStop: PropTypes.func,
-	    style: PropTypes.object,
-	    className: PropTypes.string
-	  },
-
-	  startDragging(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.addEventListener("mousemove", this.onMove);
-	    doc.addEventListener("mouseup", this.onUp);
-	    this.props.onStart && this.props.onStart();
-	  },
-
-	  onMove(ev) {
+	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+	const React = __webpack_require__(2);
+	const ReactDOM = __webpack_require__(31);
+	const { DOM: dom, PropTypes } = React;
+
+	const Draggable = React.createClass({
+	  displayName: "Draggable",
+
+	  propTypes: {
+	    onMove: PropTypes.func.isRequired,
+	    onStart: PropTypes.func,
+	    onStop: PropTypes.func,
+	    style: PropTypes.object,
+	    className: PropTypes.string
+	  },
+
+	  startDragging(ev) {
+	    ev.preventDefault();
+	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+	    doc.addEventListener("mousemove", this.onMove);
+	    doc.addEventListener("mouseup", this.onUp);
+	    this.props.onStart && this.props.onStart();
+	  },
+
+	  onMove(ev) {
 	    ev.preventDefault();
 	    // We pass the whole event because we don't know which properties
 	    // the callee needs.
 	    this.props.onMove(ev);
-	  },
-
-	  onUp(ev) {
-	    ev.preventDefault();
-	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
-	    doc.removeEventListener("mousemove", this.onMove);
-	    doc.removeEventListener("mouseup", this.onUp);
-	    this.props.onStop && this.props.onStop();
-	  },
-
-	  render() {
-	    return dom.div({
-	      style: this.props.style,
-	      className: this.props.className,
-	      onMouseDown: this.startDragging
-	    });
-	  }
-	});
-
-	module.exports = Draggable;
+	  },
+
+	  onUp(ev) {
+	    ev.preventDefault();
+	    const doc = ReactDOM.findDOMNode(this).ownerDocument;
+	    doc.removeEventListener("mousemove", this.onMove);
+	    doc.removeEventListener("mouseup", this.onUp);
+	    this.props.onStop && this.props.onStop();
+	  },
+
+	  render() {
+	    return dom.div({
+	      style: this.props.style,
+	      className: this.props.className,
+	      onMouseDown: this.startDragging
+	    });
+	  }
+	});
+
+	module.exports = Draggable;
 
 
 /***/ },
 /* 33 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/**
 	 * Copyright (c) 2007-2016, Alexandru Marasteanu <hello [at) alexei (dot] ro>
@@ -10031,26 +10031,26 @@ return /******/ (function(modules) { // 
 	}(this));
 
 	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(51)(module), (function() { return this; }())))
 
 /***/ },
 /* 51 */
 /***/ function(module, exports) {
 
-	module.exports = function(module) {
-		if(!module.webpackPolyfill) {
-			module.deprecate = function() {};
-			module.paths = [];
-			// module.parent = undefined by default
-			module.children = [];
-			module.webpackPolyfill = 1;
-		}
-		return module;
-	}
+	module.exports = function(module) {
+		if(!module.webpackPolyfill) {
+			module.deprecate = function() {};
+			module.paths = [];
+			// module.parent = undefined by default
+			module.children = [];
+			module.webpackPolyfill = 1;
+		}
+		return module;
+	}
 
 
 /***/ },
 /* 52 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/utf8js v2.0.0 by @mathias */
 	;(function(root) {
@@ -32333,176 +32333,176 @@ return /******/ (function(modules) { // 
 	module.exports = {
 	  originalToGeneratedId, generatedToOriginalId, isOriginalId, isGeneratedId
 	};
 
 /***/ },
 /* 248 */
 /***/ function(module, exports, __webpack_require__) {
 
-	(function(){
-	  var crypt = __webpack_require__(249),
-	      utf8 = __webpack_require__(250).utf8,
-	      isBuffer = __webpack_require__(251),
-	      bin = __webpack_require__(250).bin,
-
-	  // The core
-	  md5 = function (message, options) {
-	    // Convert to byte array
-	    if (message.constructor == String)
-	      if (options && options.encoding === 'binary')
-	        message = bin.stringToBytes(message);
-	      else
-	        message = utf8.stringToBytes(message);
-	    else if (isBuffer(message))
-	      message = Array.prototype.slice.call(message, 0);
-	    else if (!Array.isArray(message))
-	      message = message.toString();
-	    // else, assume byte array already
-
-	    var m = crypt.bytesToWords(message),
-	        l = message.length * 8,
-	        a =  1732584193,
-	        b = -271733879,
-	        c = -1732584194,
-	        d =  271733878;
-
-	    // Swap endian
-	    for (var i = 0; i < m.length; i++) {
-	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
-	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
-	    }
-
-	    // Padding
-	    m[l >>> 5] |= 0x80 << (l % 32);
-	    m[(((l + 64) >>> 9) << 4) + 14] = l;
-
-	    // Method shortcuts
-	    var FF = md5._ff,
-	        GG = md5._gg,
-	        HH = md5._hh,
-	        II = md5._ii;
-
-	    for (var i = 0; i < m.length; i += 16) {
-
-	      var aa = a,
-	          bb = b,
-	          cc = c,
-	          dd = d;
-
-	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
-	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
-	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
-	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
-	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
-	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
-	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
-	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
-	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
-	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
-	      c = FF(c, d, a, b, m[i+10], 17, -42063);
-	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
-	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
-	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
-	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
-	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
-
-	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
-	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
-	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
-	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
-	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
-	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
-	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
-	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
-	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
-	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
-	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
-	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
-	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
-	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
-	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
-	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
-
-	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
-	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
-	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
-	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
-	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
-	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
-	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
-	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
-	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
-	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
-	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
-	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
-	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
-	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
-	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
-	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
-
-	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
-	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
-	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
-	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
-	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
-	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
-	      c = II(c, d, a, b, m[i+10], 15, -1051523);
-	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
-	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
-	      d = II(d, a, b, c, m[i+15], 10, -30611744);
-	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
-	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
-	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
-	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
-	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
-	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
-
-	      a = (a + aa) >>> 0;
-	      b = (b + bb) >>> 0;
-	      c = (c + cc) >>> 0;
-	      d = (d + dd) >>> 0;
-	    }
-
-	    return crypt.endian([a, b, c, d]);
-	  };
-
-	  // Auxiliary functions
-	  md5._ff  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._gg  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._hh  = function (a, b, c, d, x, s, t) {
-	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-	  md5._ii  = function (a, b, c, d, x, s, t) {
-	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
-	    return ((n << s) | (n >>> (32 - s))) + b;
-	  };
-
-	  // Package private blocksize
-	  md5._blocksize = 16;
-	  md5._digestsize = 16;
-
-	  module.exports = function (message, options) {
-	    if (message === undefined || message === null)
-	      throw new Error('Illegal argument ' + message);
-
-	    var digestbytes = crypt.wordsToBytes(md5(message, options));
-	    return options && options.asBytes ? digestbytes :
-	        options && options.asString ? bin.bytesToString(digestbytes) :
-	        crypt.bytesToHex(digestbytes);
-	  };
-
-	})();
+	(function(){
+	  var crypt = __webpack_require__(249),
+	      utf8 = __webpack_require__(250).utf8,
+	      isBuffer = __webpack_require__(251),
+	      bin = __webpack_require__(250).bin,
+
+	  // The core
+	  md5 = function (message, options) {
+	    // Convert to byte array
+	    if (message.constructor == String)
+	      if (options && options.encoding === 'binary')
+	        message = bin.stringToBytes(message);
+	      else
+	        message = utf8.stringToBytes(message);
+	    else if (isBuffer(message))
+	      message = Array.prototype.slice.call(message, 0);
+	    else if (!Array.isArray(message))
+	      message = message.toString();
+	    // else, assume byte array already
+
+	    var m = crypt.bytesToWords(message),
+	        l = message.length * 8,
+	        a =  1732584193,
+	        b = -271733879,
+	        c = -1732584194,
+	        d =  271733878;
+
+	    // Swap endian
+	    for (var i = 0; i < m.length; i++) {
+	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
+	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
+	    }
+
+	    // Padding
+	    m[l >>> 5] |= 0x80 << (l % 32);
+	    m[(((l + 64) >>> 9) << 4) + 14] = l;
+
+	    // Method shortcuts
+	    var FF = md5._ff,
+	        GG = md5._gg,
+	        HH = md5._hh,
+	        II = md5._ii;
+
+	    for (var i = 0; i < m.length; i += 16) {
+
+	      var aa = a,
+	          bb = b,
+	          cc = c,
+	          dd = d;
+
+	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
+	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
+	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
+	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
+	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
+	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
+	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
+	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
+	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
+	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
+	      c = FF(c, d, a, b, m[i+10], 17, -42063);
+	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
+	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
+	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
+	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
+	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
+
+	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
+	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
+	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
+	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
+	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
+	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
+	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
+	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
+	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
+	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
+	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
+	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
+	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
+	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
+	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
+	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
+
+	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
+	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
+	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
+	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
+	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
+	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
+	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
+	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
+	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
+	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
+	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
+	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
+	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
+	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
+	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
+	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
+
+	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
+	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
+	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
+	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
+	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
+	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
+	      c = II(c, d, a, b, m[i+10], 15, -1051523);
+	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
+	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
+	      d = II(d, a, b, c, m[i+15], 10, -30611744);
+	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
+	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
+	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
+	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
+	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
+	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
+
+	      a = (a + aa) >>> 0;
+	      b = (b + bb) >>> 0;
+	      c = (c + cc) >>> 0;
+	      d = (d + dd) >>> 0;
+	    }
+
+	    return crypt.endian([a, b, c, d]);
+	  };
+
+	  // Auxiliary functions
+	  md5._ff  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._gg  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._hh  = function (a, b, c, d, x, s, t) {
+	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+	  md5._ii  = function (a, b, c, d, x, s, t) {
+	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
+	    return ((n << s) | (n >>> (32 - s))) + b;
+	  };
+
+	  // Package private blocksize
+	  md5._blocksize = 16;
+	  md5._digestsize = 16;
+
+	  module.exports = function (message, options) {
+	    if (message === undefined || message === null)
+	      throw new Error('Illegal argument ' + message);
+
+	    var digestbytes = crypt.wordsToBytes(md5(message, options));
+	    return options && options.asBytes ? digestbytes :
+	        options && options.asString ? bin.bytesToString(digestbytes) :
+	        crypt.bytesToHex(digestbytes);
+	  };
+
+	})();
 
 
 /***/ },
 /* 249 */
 /***/ function(module, exports) {
 
 	(function() {
 	  var base64map
--- a/docshell/base/nsDocShellTreeOwner.cpp
+++ b/docshell/base/nsDocShellTreeOwner.cpp
@@ -1552,17 +1552,17 @@ ChromeContextMenuListener::HandleEvent(n
         flags |= nsIContextMenuListener::CONTEXT_IMAGE;
         flags2 |= nsIContextMenuListener2::CONTEXT_IMAGE;
         targetDOMnode = node;
       }
     }
 
     nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
     if (formControl) {
-      if (formControl->GetType() == NS_FORM_TEXTAREA) {
+      if (formControl->ControlType() == NS_FORM_TEXTAREA) {
         flags |= nsIContextMenuListener::CONTEXT_TEXT;
         flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
         targetDOMnode = node;
       } else {
         nsCOMPtr<nsIDOMHTMLInputElement> inputElement(
           do_QueryInterface(formControl));
         if (inputElement) {
           flags |= nsIContextMenuListener::CONTEXT_INPUT;
--- a/docshell/test/chrome/chrome.ini
+++ b/docshell/test/chrome/chrome.ini
@@ -41,16 +41,17 @@ support-files =
   bug89419_window.xul
   bug909218.html
   bug909218.js
   bug92598_window.xul
   docshell_helpers.js
   file_viewsource_forbidden_in_iframe.html
   generic.html
   mozFrameType_window.xul
+  test_docRedirect.sjs
 
 [test_allowContentRetargeting.html]
 [test_bug112564.xul]
 [test_bug113934.xul]
 [test_bug215405.xul]
 [test_bug293235.xul]
 [test_bug294258.xul]
 [test_bug298622.xul]
@@ -81,8 +82,9 @@ skip-if = os == 'linux' || os == 'mac' #
 [test_bug89419.xul]
 [test_bug909218.html]
 [test_bug92598.xul]
 [test_mozFrameType.xul]
 [test_principalInherit.xul]
 [test_private_hidden_window.html]
 [test_viewsource_forbidden_in_iframe.xul]
 skip-if = true # bug 1019315
+[test_docRedirect.xul]
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_docRedirect.sjs
@@ -0,0 +1,5 @@
+function handleRequest(request, response) {
+  response.setStatusLine(request.httpVersion, 301, "Moved Permanently");
+  response.setHeader("Location", "http://example.org/");
+  response.write("Hello world!");
+}
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_docRedirect.xul
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1342989
+-->
+<window title="Mozilla Bug 1342989"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <script type="application/javascript">
+  <![CDATA[
+  SimpleTest.waitForExplicitFinish();
+
+  var Ci = Components.interfaces;
+  var Cc = Components.classes;
+
+  const WEB_PROGRESS_LISTENER_FLAGS =
+      Object.keys(Ci.nsIWebProgressListener).filter(
+    propName => propName.startsWith("STATE_")
+  );
+
+  function bitFlagsToNames(flags, knownNames, intf) {
+    return knownNames.map( (F) => {
+      return (flags & intf[F]) ? F : undefined;
+    }).filter( (s) => !!s );
+  }
+
+  var progressListener = {
+    add: function(docShell, callback) {
+      this.callback = callback;
+      this.docShell = docShell;
+      docShell.
+            QueryInterface(Ci.nsIInterfaceRequestor).
+            getInterface(Ci.nsIWebProgress).
+            addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_ALL);
+    },
+
+    finish: function(success) {
+      this.docShell.
+            QueryInterface(Ci.nsIInterfaceRequestor).
+            getInterface(Ci.nsIWebProgress).
+            removeProgressListener(this);
+      this.callback(success);
+    },
+
+    onStateChange: function (webProgress, req, flags, status) {
+      if (!(flags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) &&
+          !(flags & Ci.nsIWebProgressListener.STATE_IS_REDIRECTED_DOCUMENT))
+        return;
+
+      var channel = req.QueryInterface(Ci.nsIChannel);
+
+      if (flags & Ci.nsIWebProgressListener.STATE_IS_REDIRECTED_DOCUMENT) {
+        SimpleTest.is(channel.URI.host, "example.org",
+            "Should be redirected to example.org (see test_docRedirect.sjs)");
+        this.finish(true);
+      }
+
+      // Fail in case we didn't receive document redirection event.
+      if (flags & Ci.nsIWebProgressListener.STATE_STOP)
+        this.finish(false);
+    },
+
+    QueryInterface: function(iid) {
+      if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
+          iid.equals(Components.interfaces.nsISupportsWeakReference))
+        return this;
+      throw Components.results.NS_ERROR_NO_INTERFACE;
+    }
+  }
+
+  var webNav = Cc["@mozilla.org/appshell/appShellService;1"].
+      getService(Ci.nsIAppShellService).createWindowlessBrowser(true);
+  var docShell = webNav.QueryInterface(Ci.nsIInterfaceRequestor).
+      getInterface(Ci.nsIDocShell);
+  docShell.createAboutBlankContentViewer(
+      Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal));
+
+  progressListener.add(docShell, function(success) {
+    webNav.close();
+    SimpleTest.is(success, true, "Received document redirect event");
+    SimpleTest.finish();
+  });
+
+  var win = docShell.contentViewer.DOMDocument.defaultView;
+  win.location = "http://example.com/chrome/docshell/test/chrome/test_docRedirect.sjs"
+
+  ]]>
+  </script>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1342989"
+     target="_blank">Mozilla Bug 1342989</a>
+  </body>
+</window>
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -2347,27 +2347,28 @@ Element::SetAttr(int32_t aNamespaceID, n
                                      preparsedAttrValue);
   }
 
   nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Hold a script blocker while calling ParseAttribute since that can call
   // out to id-observers
-  nsAutoScriptBlocker scriptBlocker;
+  nsIDocument* document = GetComposedDoc();
+  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
 
   // Even the value was pre-parsed, we still need to call ParseAttribute because
   // it can have side effects.
   if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
     attrValue.SetTo(aValue);
   }
 
   return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
                           attrValue, modType, hasListeners, aNotify,
-                          kCallAfterSetAttr);
+                          kCallAfterSetAttr, document, updateBatch);
 }
 
 nsresult
 Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
                        nsIAtom* aPrefix, nsAttrValue& aParsedValue,
                        bool aNotify)
 {
   // Keep this in sync with SetAttr above
@@ -2394,37 +2395,37 @@ Element::SetParsedAttr(int32_t aNamespac
   if (aNotify) {
     nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType,
                                      &aParsedValue);
   }
 
   nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsIDocument* document = GetComposedDoc();
+  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
   return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
                           aParsedValue, modType, hasListeners, aNotify,
-                          kCallAfterSetAttr);
+                          kCallAfterSetAttr, document, updateBatch);
 }
 
 nsresult
 Element::SetAttrAndNotify(int32_t aNamespaceID,
                           nsIAtom* aName,
                           nsIAtom* aPrefix,
                           const nsAttrValue& aOldValue,
                           nsAttrValue& aParsedValue,
                           uint8_t aModType,
                           bool aFireMutation,
                           bool aNotify,
-                          bool aCallAfterSetAttr)
+                          bool aCallAfterSetAttr,
+                          nsIDocument* aComposedDocument,
+                          const mozAutoDocUpdate&)
 {
   nsresult rv;
-
-  nsIDocument* document = GetComposedDoc();
-  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
-
   nsMutationGuard::DidMutate();
 
   // Copy aParsedValue for later use since it will be lost when we call
   // SetAndSwapMappedAttr below
   nsAttrValue valueForAfterSetAttr;
   if (aCallAfterSetAttr) {
     valueForAfterSetAttr.SetTo(aParsedValue);
   }
@@ -2436,17 +2437,17 @@ Element::SetAttrAndNotify(int32_t aNames
     if (aName == nsGkAtoms::dir) {
       hadValidDir = HasValidDir() || IsHTMLElement(nsGkAtoms::bdi);
       hadDirAuto = HasDirAuto(); // already takes bdi into account
     }
 
     // XXXbz Perhaps we should push up the attribute mapping function
     // stuff to Element?
     if (!IsAttributeMapped(aName) ||
-        !SetMappedAttribute(document, aName, aParsedValue, &rv)) {
+        !SetMappedAttribute(aComposedDocument, aName, aParsedValue, &rv)) {
       rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue);
     }
   }
   else {
     RefPtr<mozilla::dom::NodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
                                                    aNamespaceID,
                                                    nsIDOMNode::ATTRIBUTE_NODE);
@@ -2455,17 +2456,17 @@ Element::SetAttrAndNotify(int32_t aNames
   }
 
   // If the old value owns its own data, we know it is OK to keep using it.
   const nsAttrValue* oldValue =
       aParsedValue.StoresOwnData() ? &aParsedValue : &aOldValue;
 
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
+  if (aComposedDocument || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     RefPtr<nsXBLBinding> binding = GetXBLBinding();
     if (binding) {
       binding->AttributeChanged(aName, aNamespaceID, false, aNotify);
     }
   }
 
   nsIDocument* ownerDoc = OwnerDoc();
   if (ownerDoc && GetCustomElementData()) {
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -37,16 +37,17 @@
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/DOMTokenListSupportedTokens.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "Units.h"
 #include "DOMIntersectionObserver.h"
 
+class mozAutoDocUpdate;
 class nsIFrame;
 class nsIDOMMozNamedAttrMap;
 class nsIMozBrowserFrame;
 class nsIURI;
 class nsIScrollableFrame;
 class nsAttrValueOrString;
 class nsContentList;
 class nsDOMTokenList;
@@ -1336,26 +1337,29 @@ protected:
    * @param aParsedValue  parsed new value of attribute. Replaced by the
    *                      old value of the attribute. This old value is only
    *                      useful if either it or the new value is StoresOwnData.
    * @param aModType      nsIDOMMutationEvent::MODIFICATION or ADDITION.  Only
    *                      needed if aFireMutation or aNotify is true.
    * @param aFireMutation should mutation-events be fired?
    * @param aNotify       should we notify document-observers?
    * @param aCallAfterSetAttr should we call AfterSetAttr?
+   * @param aComposedDocument The current composed document of the element.
    */
   nsresult SetAttrAndNotify(int32_t aNamespaceID,
                             nsIAtom* aName,
                             nsIAtom* aPrefix,
                             const nsAttrValue& aOldValue,
                             nsAttrValue& aParsedValue,
                             uint8_t aModType,
                             bool aFireMutation,
                             bool aNotify,
-                            bool aCallAfterSetAttr);
+                            bool aCallAfterSetAttr,
+                            nsIDocument* aComposedDocument,
+                            const mozAutoDocUpdate& aGuard);
 
   /**
    * Scroll to a new position using behavior evaluated from CSS and
    * a CSSOM-View DOM method ScrollOptions dictionary.  The scrolling may
    * be performed asynchronously or synchronously depending on the resolved
    * scroll-behavior.
    *
    * @param aScroll       Destination of scroll, in CSS pixels
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -461,17 +461,17 @@ DragDataProducer::Produce(DataTransfer* 
 
     {
       // only drag form elements by using the alt key,
       // otherwise buttons and select widgets are hard to use
 
       // Note that while <object> elements implement nsIFormControl, we should
       // really allow dragging them if they happen to be images.
       nsCOMPtr<nsIFormControl> form(do_QueryInterface(mTarget));
-      if (form && !mIsAltKeyPressed && form->GetType() != NS_FORM_OBJECT) {
+      if (form && !mIsAltKeyPressed && form->ControlType() != NS_FORM_OBJECT) {
         *aCanDrag = false;
         return NS_OK;
       }
 
       draggedNode = mTarget;
     }
 
     nsCOMPtr<nsIDOMHTMLAreaElement>   area;   // client-side image map
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2758,17 +2758,17 @@ nsContentUtils::GenerateStateKey(nsICont
     //
     // XXX We don't need to use index if name is there
     // XXXbz We don't?  Why not?  I don't follow.
     //
     nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
     if (control && htmlFormControls && htmlForms) {
 
       // Append the control type
-      KeyAppendInt(control->GetType(), aKey);
+      KeyAppendInt(control->ControlType(), aKey);
 
       // If in a form, add form name / index of form / index in form
       int32_t index = -1;
       Element *formElement = control->GetFormElement();
       if (formElement) {
         if (IsAutocompleteOff(formElement)) {
           aKey.Truncate();
           return NS_OK;
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -864,17 +864,17 @@ nsCopySupport::FireClipboardEvent(EventM
     nsCOMPtr<nsIContent> srcNode = content;
     if (content->IsInNativeAnonymousSubtree()) {
       srcNode = content->FindFirstNonChromeOnlyAccessContent();
     }
 
     // check if we are looking at a password input
     nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(srcNode);
     if (formControl) {
-      if (formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
+      if (formControl->ControlType() == NS_FORM_INPUT_PASSWORD) {
         return false;
       }
     }
 
     // when cutting non-editable content, do nothing
     // XXX this is probably the wrong editable flag to check
     if (originalEventMessage != eCut || content->IsEditable()) {
       // get the data from the selection if any
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -313,17 +313,17 @@ nsFocusManager::GetFocusedDescendant(nsP
 
 // static
 nsIContent*
 nsFocusManager::GetRedirectedFocus(nsIContent* aContent)
 {
   // For input number, redirect focus to our anonymous text control.
   if (aContent->IsHTMLElement(nsGkAtoms::input)) {
     bool typeIsNumber =
-      static_cast<dom::HTMLInputElement*>(aContent)->GetType() ==
+      static_cast<dom::HTMLInputElement*>(aContent)->ControlType() ==
         NS_FORM_INPUT_NUMBER;
 
     if (typeIsNumber) {
       nsNumberControlFrame* numberControlFrame =
         do_QueryFrame(aContent->GetPrimaryFrame());
 
       if (numberControlFrame) {
         HTMLInputElement* textControl =
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -1315,16 +1315,18 @@ nsImageLoadingContent::MakePendingReques
   ImageLoadType loadType = \
     (mPendingRequestFlags & REQUEST_IS_IMAGESET) ? eImageLoadType_Imageset
                                                  : eImageLoadType_Normal;
 
   PrepareCurrentRequest(loadType) = mPendingRequest;
   mPendingRequest = nullptr;
   mCurrentRequestFlags = mPendingRequestFlags;
   mPendingRequestFlags = 0;
+  mCurrentRequestRegistered = mPendingRequestRegistered;
+  mPendingRequestRegistered = false;
   ResetAnimationIfNeeded();
 }
 
 void
 nsImageLoadingContent::ClearCurrentRequest(nsresult aReason,
                                            const Maybe<OnNonvisible>& aNonvisibleAction)
 {
   if (!mCurrentRequest) {
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -107,17 +107,18 @@ FreeEntry(void* pool, PLHashEntry* he, u
 static PLHashAllocOps allocOps =
   { AllocTable, FreeTable, AllocEntry, FreeEntry };
 
 nsNodeInfoManager::nsNodeInfoManager()
   : mDocument(nullptr),
     mNonDocumentNodeInfos(0),
     mTextNodeInfo(nullptr),
     mCommentNodeInfo(nullptr),
-    mDocumentNodeInfo(nullptr)
+    mDocumentNodeInfo(nullptr),
+    mRecentlyUsedNodeInfos{}
 {
   nsLayoutStatics::AddRef();
 
   if (gNodeInfoManagerLeakPRLog)
     MOZ_LOG(gNodeInfoManagerLeakPRLog, LogLevel::Debug,
            ("NODEINFOMANAGER %p created", this));
 
   mNodeInfoHash = PL_NewHashTable(32, GetNodeInfoInnerHashValue,
@@ -227,21 +228,29 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *
                                int32_t aNamespaceID, uint16_t aNodeType,
                                nsIAtom* aExtraName /* = nullptr */)
 {
   CheckValidNodeInfo(aNodeType, aName, aNamespaceID, aExtraName);
 
   NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType,
                                  aExtraName);
 
+  uint32_t index =
+    GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE;
+  NodeInfo* ni = mRecentlyUsedNodeInfos[index];
+  if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) {
+    RefPtr<NodeInfo> nodeInfo = ni;
+    return nodeInfo.forget();
+  }
+
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     RefPtr<NodeInfo> nodeInfo = static_cast<NodeInfo*>(node);
-
+    mRecentlyUsedNodeInfos[index] = nodeInfo;
     return nodeInfo.forget();
   }
 
   RefPtr<NodeInfo> newNodeInfo =
     new NodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName, this);
 
   DebugOnly<PLHashEntry*> he =
     PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
@@ -249,16 +258,17 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *
 
   // Have to do the swap thing, because already_AddRefed<nsNodeInfo>
   // doesn't cast to already_AddRefed<mozilla::dom::NodeInfo>
   ++mNonDocumentNodeInfos;
   if (mNonDocumentNodeInfos == 1) {
     NS_IF_ADDREF(mDocument);
   }
 
+  mRecentlyUsedNodeInfos[index] = newNodeInfo;
   return newNodeInfo.forget();
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
                                int32_t aNamespaceID, uint16_t aNodeType,
                                NodeInfo** aNodeInfo)
@@ -267,20 +277,30 @@ nsNodeInfoManager::GetNodeInfo(const nsA
   {
     nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName);
     CheckValidNodeInfo(aNodeType, nameAtom, aNamespaceID, nullptr);
   }
 #endif
 
   NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType);
 
+  uint32_t index =
+    GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE;
+  NodeInfo* ni = mRecentlyUsedNodeInfos[index];
+  if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) {
+    RefPtr<NodeInfo> nodeInfo = ni;
+    nodeInfo.forget(aNodeInfo);
+    return NS_OK;
+  }
+
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     RefPtr<NodeInfo> nodeInfo = static_cast<NodeInfo*>(node);
+    mRecentlyUsedNodeInfos[index] = nodeInfo;
     nodeInfo.forget(aNodeInfo);
 
     return NS_OK;
   }
 
   nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
@@ -292,16 +312,17 @@ nsNodeInfoManager::GetNodeInfo(const nsA
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
   NS_ENSURE_TRUE(he, NS_ERROR_FAILURE);
 
   ++mNonDocumentNodeInfos;
   if (mNonDocumentNodeInfos == 1) {
     NS_IF_ADDREF(mDocument);
   }
 
+  mRecentlyUsedNodeInfos[index] = newNodeInfo;
   newNodeInfo.forget(aNodeInfo);
 
   return NS_OK;
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
@@ -419,15 +440,21 @@ nsNodeInfoManager::RemoveNodeInfo(NodeIn
     if (aNodeInfo == mTextNodeInfo) {
       mTextNodeInfo = nullptr;
     }
     else if (aNodeInfo == mCommentNodeInfo) {
       mCommentNodeInfo = nullptr;
     }
   }
 
+  uint32_t index =
+    GetNodeInfoInnerHashValue(&aNodeInfo->mInner) % RECENTLY_USED_NODEINFOS_SIZE;
+  if (mRecentlyUsedNodeInfos[index] == aNodeInfo) {
+    mRecentlyUsedNodeInfos[index] = nullptr;
+  }
+
 #ifdef DEBUG
   bool ret =
 #endif
   PL_HashTableRemove(mNodeInfoHash, &aNodeInfo->mInner);
 
   NS_POSTCONDITION(ret, "Can't find mozilla::dom::NodeInfo to remove!!!");
 }
--- a/dom/base/nsNodeInfoManager.h
+++ b/dom/base/nsNodeInfoManager.h
@@ -27,16 +27,18 @@ struct PLHashTable;
 template<class T> struct already_AddRefed;
 
 namespace mozilla {
 namespace dom {
 class NodeInfo;
 } // namespace dom
 } // namespace mozilla
 
+#define RECENTLY_USED_NODEINFOS_SIZE 31
+
 class nsNodeInfoManager final
 {
 private:
   ~nsNodeInfoManager();
 
 public:
   nsNodeInfoManager();
 
@@ -132,11 +134,12 @@ private:
   nsIDocument * MOZ_NON_OWNING_REF mDocument; // WEAK
   uint32_t mNonDocumentNodeInfos;
   nsCOMPtr<nsIPrincipal> mPrincipal; // Never null after Init() succeeds.
   nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null after Init() succeeds
   mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mTextNodeInfo; // WEAK to avoid circular ownership
   mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mCommentNodeInfo; // WEAK to avoid circular ownership
   mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mDocumentNodeInfo; // WEAK to avoid circular ownership
   RefPtr<nsBindingManager> mBindingManager;
+  mozilla::dom::NodeInfo* mRecentlyUsedNodeInfos[RECENTLY_USED_NODEINFOS_SIZE];
 };
 
 #endif /* nsNodeInfoManager_h___ */
--- a/dom/base/nsStyledElement.cpp
+++ b/dom/base/nsStyledElement.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsStyledElement.h"
+#include "mozAutoDocUpdate.h"
 #include "nsGkAtoms.h"
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "nsDOMCSSDeclaration.h"
 #include "nsDOMCSSAttrDeclaration.h"
 #include "nsServiceManagerUtils.h"
@@ -81,19 +82,22 @@ nsStyledElement::SetInlineStyleDeclarati
 
   nsAttrValue attrValue(do_AddRef(aDeclaration), aSerialized);
 
   // XXXbz do we ever end up with ADDITION here?  I doubt it.
   uint8_t modType = modification ?
     static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
     static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
 
+  nsIDocument* document = GetComposedDoc();
+  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
   return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
                           oldValue, attrValue, modType, hasListeners,
-                          aNotify, kDontCallAfterSetAttr);
+                          aNotify, kDontCallAfterSetAttr, document,
+                          updateBatch);
 }
 
 // ---------------------------------------------------------------
 // Others and helpers
 
 nsICSSDeclaration*
 nsStyledElement::Style()
 {
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1529,17 +1529,17 @@ EventStateManager::FireContextClick()
         }
       }
     }
     else if (mGestureDownContent->IsHTMLElement()) {
       nsCOMPtr<nsIFormControl> formCtrl(do_QueryInterface(mGestureDownContent));
 
       if (formCtrl) {
         allowedToDispatch = formCtrl->IsTextOrNumberControl(/*aExcludePassword*/ false) ||
-                            formCtrl->GetType() == NS_FORM_INPUT_FILE;
+                            formCtrl->ControlType() == NS_FORM_INPUT_FILE;
       }
       else if (mGestureDownContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
                                                         nsGkAtoms::embed,
                                                         nsGkAtoms::object,
                                                         nsGkAtoms::label)) {
         allowedToDispatch = false;
       }
     }
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -1030,17 +1030,17 @@ IMEStateManager::SetIMEState(const IMESt
         // is this an html form and does it only have a single text input element?
         } else if (formElement && formElement->IsHTMLElement(nsGkAtoms::form) &&
                    !static_cast<dom::HTMLFormElement*>(formElement)->
                      ImplicitSubmissionIsDisabled()) {
           willSubmit = true;
         }
       }
       context.mActionHint.Assign(
-        willSubmit ? (control->GetType() == NS_FORM_INPUT_SEARCH ?
+        willSubmit ? (control->ControlType() == NS_FORM_INPUT_SEARCH ?
                        NS_LITERAL_STRING("search") : NS_LITERAL_STRING("go")) :
                      (formElement ?
                        NS_LITERAL_STRING("next") : EmptyString()));
     }
   }
 
   // XXX I think that we should use nsContentUtils::IsCallerChrome() instead
   //     of the process type.
--- a/dom/file/moz.build
+++ b/dom/file/moz.build
@@ -60,11 +60,13 @@ UNIFIED_SOURCES += [
 ]
 
 LOCAL_INCLUDES += [
     '/dom/workers',
 ]
 
 MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
 
+XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell.ini']
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/dom/file/nsHostObjectProtocolHandler.cpp
+++ b/dom/file/nsHostObjectProtocolHandler.cpp
@@ -29,16 +29,17 @@
 #define RELEASING_TIMER 1000
 
 using mozilla::DOMMediaStream;
 using mozilla::dom::BlobImpl;
 using mozilla::dom::MediaSource;
 using mozilla::ErrorResult;
 using mozilla::net::LoadInfo;
 using mozilla::Move;
+using mozilla::Unused;
 
 // -----------------------------------------------------------------------
 // Hash table
 struct DataInfo
 {
   enum ObjectType {
     eBlobImpl,
     eMediaStream,
@@ -741,17 +742,36 @@ nsHostObjectProtocolHandler::GetDefaultP
   *result = -1;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHostObjectProtocolHandler::GetProtocolFlags(uint32_t *result)
 {
   *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
-            URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
+            URI_NON_PERSISTABLE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHostObjectProtocolHandler::GetFlagsForURI(nsIURI *aURI, uint32_t *aResult)
+{
+  Unused << nsHostObjectProtocolHandler::GetProtocolFlags(aResult);
+  if (IsFontTableURI(aURI) || IsBlobURI(aURI)) {
+    *aResult |= URI_IS_LOCAL_RESOURCE;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsBlobProtocolHandler::GetProtocolFlags(uint32_t *result)
+{
+  Unused << nsHostObjectProtocolHandler::GetProtocolFlags(result);
+  *result |= URI_IS_LOCAL_RESOURCE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
                                     const char *aCharset,
                                     nsIURI *aBaseURI,
                                     nsIURI **aResult)
@@ -872,16 +892,24 @@ nsHostObjectProtocolHandler::AllowPort(i
 NS_IMETHODIMP
 nsBlobProtocolHandler::GetScheme(nsACString &result)
 {
   result.AssignLiteral(BLOBURI_SCHEME);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsFontTableProtocolHandler::GetProtocolFlags(uint32_t *result)
+{
+  Unused << nsHostObjectProtocolHandler::GetProtocolFlags(result);
+  *result |= URI_IS_LOCAL_RESOURCE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsFontTableProtocolHandler::GetScheme(nsACString &result)
 {
   result.AssignLiteral(FONTTABLEURI_SCHEME);
   return NS_OK;
 }
 
 nsresult
 NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
--- a/dom/file/nsHostObjectProtocolHandler.h
+++ b/dom/file/nsHostObjectProtocolHandler.h
@@ -27,30 +27,34 @@ namespace dom {
 class BlobImpl;
 class BlobURLRegistrationData;
 class ContentParent;
 class MediaSource;
 } // namespace dom
 } // namespace mozilla
 
 class nsHostObjectProtocolHandler : public nsIProtocolHandler
+                                  , public nsIProtocolHandlerWithDynamicFlags
 {
 public:
   nsHostObjectProtocolHandler();
   NS_DECL_ISUPPORTS
 
   // nsIProtocolHandler methods, except for GetScheme which is only defined
   // in subclasses.
   NS_IMETHOD GetDefaultPort(int32_t *aDefaultPort) override;
   NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags) override;
   NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval) override;
   NS_IMETHOD NewChannel2(nsIURI *aURI, nsILoadInfo *aLoadinfo, nsIChannel * *_retval) override;
   NS_IMETHOD NewChannel(nsIURI *aURI, nsIChannel * *_retval) override;
   NS_IMETHOD AllowPort(int32_t port, const char * scheme, bool *_retval) override;
 
+  // nsIProtocolHandlerWithDynamicFlags methods
+  NS_IMETHOD GetFlagsForURI(nsIURI *aURI, uint32_t *aResult) override;
+
   // If principal is not null, its origin will be used to generate the URI.
   static nsresult GenerateURIString(const nsACString &aScheme,
                                     nsIPrincipal* aPrincipal,
                                     nsACString &aUri);
   static nsresult GenerateURIStringForBlobURL(nsIPrincipal* aPrincipal,
                                               nsACString &aUri);
 
   // Methods for managing uri->object mapping
@@ -89,24 +93,29 @@ protected:
 
 private:
   static void Init();
 };
 
 class nsBlobProtocolHandler : public nsHostObjectProtocolHandler
 {
 public:
+  NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags) override;
   NS_IMETHOD GetScheme(nsACString &result) override;
 };
 
 class nsFontTableProtocolHandler : public nsHostObjectProtocolHandler
 {
 public:
-  NS_IMETHOD GetScheme(nsACString &result);
-  NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval);
+  NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags) override;
+  NS_IMETHOD GetScheme(nsACString &result) override;
+  NS_IMETHOD NewURI(const nsACString & aSpec,
+                    const char *aOriginCharset,
+                    nsIURI *aBaseURI,
+                    nsIURI **_retval) override;
 };
 
 bool IsBlobURI(nsIURI* aUri);
 bool IsMediaStreamURI(nsIURI* aUri);
 bool IsMediaSourceURI(nsIURI* aUri);
 
 inline bool IsRtspURI(nsIURI* aUri)
 {
new file mode 100644
--- /dev/null
+++ b/dom/file/tests/test_bloburi.js
@@ -0,0 +1,33 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+
+var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+var uris = [
+  {
+    uri: "blob:https://example.com/230d5d50-35f9-9745-a64a-15e47b731a81",
+    local: true,
+  },
+  {
+    uri: "rstp://1.2.3.4/some_path?param=a",
+    local: false,
+  },
+  {
+    uri: "moz-fonttable://something",
+    local: true,
+  }
+];
+
+function run_test()
+{
+  for (let i = 0; i < uris.length; i++) {
+    let uri = ios.newURI(uris[i].uri);
+    let handler = ios.getProtocolHandler(uri.scheme).QueryInterface(Ci.nsIProtocolHandler);
+    let flags = handler.protocolFlags;
+    
+    do_check_eq(Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE & flags,
+                (uris[i].local) ? Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE : 0);
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/dom/file/tests/xpcshell.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[test_bloburi.js]
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -52,18 +52,17 @@ static const nsAttrValue::EnumTable kBut
 
 // Default type is 'submit'.
 static const nsAttrValue::EnumTable* kButtonDefaultType = &kButtonTypeTable[2];
 
 
 // Construction, destruction
 HTMLButtonElement::HTMLButtonElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo),
-    mType(kButtonDefaultType->value),
+  : nsGenericHTMLFormElementWithState(aNodeInfo, kButtonDefaultType->value),
     mDisabledChanged(false),
     mInInternalActivate(false),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT))
 {
   // Set up our default state: enabled
   AddStatesSilently(NS_EVENT_STATE_ENABLED);
 }
 
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -42,17 +42,16 @@ public:
   {
     return true;
   }
 
   // nsIDOMHTMLButtonElement
   NS_DECL_NSIDOMHTMLBUTTONELEMENT
 
   // overriden nsIFormControl methods
-  NS_IMETHOD_(uint32_t) GetType() const override { return mType; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   bool RestoreState(nsPresState* aState) override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
@@ -167,17 +166,16 @@ public:
   // nsIConstraintValidation::CheckValidity() is fine.
   using nsIConstraintValidation::CheckValidity;
   using nsIConstraintValidation::ReportValidity;
   // nsIConstraintValidation::SetCustomValidity() is fine.
 
 protected:
   virtual ~HTMLButtonElement();
 
-  uint8_t mType;
   bool mDisabledChanged;
   bool mInInternalActivate;
   bool mInhibitStateRestoration;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -13,17 +13,17 @@
 #include "nsQueryObject.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
 
 namespace mozilla {
 namespace dom {
 
 HTMLFieldSetElement::HTMLFieldSetElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-  : nsGenericHTMLFormElement(aNodeInfo)
+  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_FIELDSET)
   , mElements(nullptr)
   , mFirstLegend(nullptr)
   , mInvalidElementsCount(0)
 {
   // <fieldset> is always barred from constraint validation.
   SetBarredFromConstraintValidation(true);
 
   // We start out enabled and valid.
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -45,17 +45,16 @@ public:
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify) override;
 
   virtual nsresult InsertChildAt(nsIContent* aChild, uint32_t aIndex,
                                      bool aNotify) override;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
 
   // nsIFormControl
-  NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_FIELDSET; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   const nsIContent* GetFirstLegend() const { return mFirstLegend; }
 
   void AddElement(nsGenericHTMLFormElement* aElement);
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -24,17 +24,17 @@ namespace dom {
 
 /* static */ bool
 HTMLFormControlsCollection::ShouldBeInElements(nsIFormControl* aFormControl)
 {
   // For backwards compatibility (with 4.x and IE) we must not add
   // <input type=image> elements to the list of form controls in a
   // form.
 
-  switch (aFormControl->GetType()) {
+  switch (aFormControl->ControlType()) {
   case NS_FORM_BUTTON_BUTTON :
   case NS_FORM_BUTTON_RESET :
   case NS_FORM_BUTTON_SUBMIT :
   case NS_FORM_INPUT_BUTTON :
   case NS_FORM_INPUT_CHECKBOX :
   case NS_FORM_INPUT_COLOR :
   case NS_FORM_INPUT_EMAIL :
   case NS_FORM_INPUT_FILE :
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -1246,17 +1246,17 @@ HTMLFormElement::AddElement(nsGenericHTM
       mControls->mElements : mControls->mNotInElements;
 
   bool lastElement = AddElementToList(controlList, aChild, this);
 
 #ifdef DEBUG
   AssertDocumentOrder(controlList, this);
 #endif
 
-  int32_t type = aChild->GetType();
+  int32_t type = aChild->ControlType();
 
   //
   // If it is a password control, and the password manager has not yet been
   // initialized, initialize the password manager
   //
   if (type == NS_FORM_INPUT_PASSWORD) {
     if (!gPasswordManagerInitialized) {
       gPasswordManagerInitialized = true;
@@ -1347,17 +1347,17 @@ HTMLFormElement::RemoveElement(nsGeneric
                                bool aUpdateValidity)
 {
   RemoveElementFromPastNamesMap(aChild);
 
   //
   // Remove it from the radio group if it's a radio button
   //
   nsresult rv = NS_OK;
-  if (aChild->GetType() == NS_FORM_INPUT_RADIO) {
+  if (aChild->ControlType() == NS_FORM_INPUT_RADIO) {
     RefPtr<HTMLInputElement> radio =
       static_cast<HTMLInputElement*>(aChild);
     radio->WillRemoveFromRadioGroup();
   }
 
   // Determine whether to remove the child from the elements list
   // or the not in elements list.
   bool childInElements = HTMLFormControlsCollection::ShouldBeInElements(aChild);
@@ -1813,17 +1813,17 @@ HTMLFormElement::IsDefaultSubmitElement(
 bool
 HTMLFormElement::ImplicitSubmissionIsDisabled() const
 {
   // Input text controls are always in the elements list.
   uint32_t numDisablingControlsFound = 0;
   uint32_t length = mControls->mElements.Length();
   for (uint32_t i = 0; i < length && numDisablingControlsFound < 2; ++i) {
     if (mControls->mElements[i]->IsSingleLineTextControl(false) ||
-        mControls->mElements[i]->GetType() == NS_FORM_INPUT_NUMBER) {
+        mControls->mElements[i]->ControlType() == NS_FORM_INPUT_NUMBER) {
       numDisablingControlsFound++;
     }
   }
   return numDisablingControlsFound != 1;
 }
 
 NS_IMETHODIMP
 HTMLFormElement::GetEncoding(nsAString& aEncoding)
@@ -2019,17 +2019,17 @@ One should be implemented!");
 bool
 HTMLFormElement::SubmissionCanProceed(Element* aSubmitter)
 {
 #ifdef DEBUG
   if (aSubmitter) {
     nsCOMPtr<nsIFormControl> fc = do_QueryInterface(aSubmitter);
     MOZ_ASSERT(fc);
 
-    uint32_t type = fc->GetType();
+    uint32_t type = fc->ControlType();
     MOZ_ASSERT(type == NS_FORM_INPUT_SUBMIT ||
                type == NS_FORM_INPUT_IMAGE ||
                type == NS_FORM_BUTTON_SUBMIT,
                "aSubmitter is not a submit control?");
   }
 #endif
 
   // Modified step 2 of
@@ -2220,17 +2220,17 @@ HTMLFormElement::GetNextRadioButton(cons
       if (--index < 0) {
         index = numRadios -1;
       }
     }
     else if (++index >= (int32_t)numRadios) {
       index = 0;
     }
     radio = HTMLInputElement::FromContentOrNull(radioGroup->Item(index));
-    isRadio = radio && radio->GetType() == NS_FORM_INPUT_RADIO;
+    isRadio = radio && radio->ControlType() == NS_FORM_INPUT_RADIO;
     if (!isRadio) {
       continue;
     }
 
     nsAutoString name;
     radio->GetName(name);
     isRadio = aName.Equals(name);
   } while (!isRadio || (radio->Disabled() && radio != currentRadio));
@@ -2248,17 +2248,17 @@ HTMLFormElement::WalkRadioGroup(const ns
     //
     // XXX If the name is empty, it's not stored in the control list.  There
     // *must* be a more efficient way to do this.
     //
     nsCOMPtr<nsIFormControl> control;
     uint32_t len = GetElementCount();
     for (uint32_t i = 0; i < len; i++) {
       control = GetElementAt(i);
-      if (control->GetType() == NS_FORM_INPUT_RADIO) {
+      if (control->ControlType() == NS_FORM_INPUT_RADIO) {
         nsCOMPtr<nsIContent> controlContent = do_QueryInterface(control);
         if (controlContent &&
             controlContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
                                         EmptyString(), eCaseMatters) &&
             !aVisitor->Visit(control)) {
           break;
         }
       }
@@ -2270,33 +2270,33 @@ HTMLFormElement::WalkRadioGroup(const ns
   nsCOMPtr<nsISupports> item = DoResolveName(aName, aFlushContent);
   if (!item) {
     return NS_ERROR_FAILURE;
   }
 
   // If it's just a lone radio button, then select it.
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(item);
   if (formControl) {
-    if (formControl->GetType() == NS_FORM_INPUT_RADIO) {
+    if (formControl->ControlType() == NS_FORM_INPUT_RADIO) {
       aVisitor->Visit(formControl);
     }
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(item);
   if (!nodeList) {
     return NS_OK;
   }
   uint32_t length = 0;
   nodeList->GetLength(&length);
   for (uint32_t i = 0; i < length; i++) {
     nsCOMPtr<nsIDOMNode> node;
     nodeList->Item(i, getter_AddRefs(node));
     nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(node);
-    if (formControl && formControl->GetType() == NS_FORM_INPUT_RADIO &&
+    if (formControl && formControl->ControlType() == NS_FORM_INPUT_RADIO &&
         !aVisitor->Visit(formControl)) {
       break;
     }
   }
   return NS_OK;
 }
 
 void
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -1049,18 +1049,17 @@ static nsresult FireEventForAccessibilit
 #endif
 
 //
 // construction, destruction
 //
 
 HTMLInputElement::HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                    FromParser aFromParser, FromClone aFromClone)
-  : nsGenericHTMLFormElementWithState(aNodeInfo)
-  , mType(kInputDefaultType->value)
+  : nsGenericHTMLFormElementWithState(aNodeInfo, kInputDefaultType->value)
   , mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown)
   , mDisabledChanged(false)
   , mValueChanged(false)
   , mLastValueChangeWasInteractive(false)
   , mCheckedChanged(false)
   , mChecked(false)
   , mHandlingSelectEvent(false)
   , mShouldInitChecked(false)
@@ -3509,17 +3508,17 @@ HTMLInputElement::Focus(ErrorResult& aEr
   // being two buttons (when the picker is a directory picker) the user can
   // tab to the next one.
   nsIFrame* frame = GetPrimaryFrame();
   if (frame) {
     for (nsIFrame* childFrame : frame->PrincipalChildList()) {
       // See if the child is a button control.
       nsCOMPtr<nsIFormControl> formCtrl =
         do_QueryInterface(childFrame->GetContent());
-      if (formCtrl && formCtrl->GetType() == NS_FORM_BUTTON_BUTTON) {
+      if (formCtrl && formCtrl->ControlType() == NS_FORM_BUTTON_BUTTON) {
         nsCOMPtr<nsIDOMElement> element = do_QueryInterface(formCtrl);
         nsIFocusManager* fm = nsFocusManager::GetFocusManager();
         if (fm && element) {
           fm->SetFocus(element, 0);
         }
         break;
       }
     }
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -159,17 +159,16 @@ public:
   NS_IMETHOD GetEditor(nsIEditor** aEditor) override
   {
     return nsGenericHTMLElement::GetEditor(aEditor);
   }
 
   NS_IMETHOD SetUserInput(const nsAString& aInput) override;
 
   // Overriden nsIFormControl methods
-  NS_IMETHOD_(uint32_t) GetType() const override { return mType; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
   virtual bool AllowDrop() override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
@@ -1604,22 +1603,16 @@ protected:
   static const double kMaximumDayInMaximumYear;
   // Maximum valid month is 275760-09.
   static const double kMaximumMonthInMaximumYear;
   // Long years in a ISO calendar have 53 weeks in them.
   static const double kMaximumWeekInYear;
   // Milliseconds in a day.
   static const double kMsPerDay;
 
-
-  /**
-   * The type of this input (<input type=...>) as an integer.
-   * @see nsIFormControl.h (specifically NS_FORM_INPUT_*)
-   */
-  uint8_t                  mType;
   nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
   bool                     mDisabledChanged     : 1;
   bool                     mValueChanged        : 1;
   bool                     mLastValueChangeWasInteractive : 1;
   bool                     mCheckedChanged      : 1;
   bool                     mChecked             : 1;
   bool                     mHandlingSelectEvent : 1;
   bool                     mShouldInitChecked   : 1;
--- a/dom/html/HTMLObjectElement.cpp
+++ b/dom/html/HTMLObjectElement.cpp
@@ -25,17 +25,17 @@
 #include "nsFocusManager.h"
 #endif
 
 namespace mozilla {
 namespace dom {
 
 HTMLObjectElement::HTMLObjectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElement(aNodeInfo),
+  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_OBJECT),
     mIsDoneAddingChildren(!aFromParser)
 {
   RegisterActivityObserver();
   SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
 
   // <object> is always barred from constraint validation.
   SetBarredFromConstraintValidation(true);
 
--- a/dom/html/HTMLObjectElement.h
+++ b/dom/html/HTMLObjectElement.h
@@ -64,21 +64,16 @@ public:
                            bool aNotify) override;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) override;
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
   virtual IMEState GetDesiredIMEState() override;
 
   // Overriden nsIFormControl methods
-  NS_IMETHOD_(uint32_t) GetType() const override
-  {
-    return NS_FORM_OBJECT;
-  }
-
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission *aFormSubmission) override;
 
   virtual bool IsDisabled() const override { return false; }
 
   virtual void DoneAddingChildren(bool aHaveNotified) override;
   virtual bool IsDoneAddingChildren() override;
 
--- a/dom/html/HTMLOutputElement.cpp
+++ b/dom/html/HTMLOutputElement.cpp
@@ -16,17 +16,17 @@
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output)
 
 namespace mozilla {
 namespace dom {
 
 HTMLOutputElement::HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElement(aNodeInfo)
+  : nsGenericHTMLFormElement(aNodeInfo, NS_FORM_OUTPUT)
   , mValueModeFlag(eModeDefault)
   , mIsDoneAddingChildren(!aFromParser)
 {
   AddMutationObserver(this);
 
   // We start out valid and ui-valid (since we have no form).
   AddStatesSilently(NS_EVENT_STATE_VALID | NS_EVENT_STATE_MOZ_UI_VALID);
 }
--- a/dom/html/HTMLOutputElement.h
+++ b/dom/html/HTMLOutputElement.h
@@ -26,17 +26,16 @@ public:
 
   explicit HTMLOutputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                              FromParser aFromParser = NOT_FROM_PARSER);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIFormControl
-  NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_OUTPUT; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
 
   virtual bool IsDisabled() const override { return false; }
 
   nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
 
   bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -112,17 +112,17 @@ SafeOptionListMutation::~SafeOptionListM
 // HTMLSelectElement
 //
 
 // construction, destruction
 
 
 HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                      FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo),
+  : nsGenericHTMLFormElementWithState(aNodeInfo, NS_FORM_SELECT),
     mOptions(new HTMLOptionsCollection(this)),
     mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
     mIsDoneAddingChildren(!aFromParser),
     mDisabledChanged(false),
     mMutating(false),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mSelectionHasChanged(false),
     mDefaultSelectionSet(false),
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -291,17 +291,16 @@ public:
                      EventChainPostVisitor& aVisitor) override;
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable, int32_t* aTabIndex) override;
   virtual nsresult InsertChildAt(nsIContent* aKid, uint32_t aIndex,
                                  bool aNotify) override;
   virtual void RemoveChildAt(uint32_t aIndex, bool aNotify) override;
 
   // Overriden nsIFormControl methods
-  NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_SELECT; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -48,17 +48,17 @@ static NS_DEFINE_CID(kXULControllersCID,
 
 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(TextArea)
 
 namespace mozilla {
 namespace dom {
 
 HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                                          FromParser aFromParser)
-  : nsGenericHTMLFormElementWithState(aNodeInfo),
+  : nsGenericHTMLFormElementWithState(aNodeInfo, NS_FORM_TEXTAREA),
     mValueChanged(false),
     mLastValueChangeWasInteractive(false),
     mHandlingSelect(false),
     mDoneAddingChildren(!aFromParser),
     mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
     mDisabledChanged(false),
     mCanShowInvalidUI(true),
     mCanShowValidUI(true),
--- a/dom/html/HTMLTextAreaElement.h
+++ b/dom/html/HTMLTextAreaElement.h
@@ -67,17 +67,16 @@ public:
   // nsIDOMNSEditableElement
   NS_IMETHOD GetEditor(nsIEditor** aEditor) override
   {
     return nsGenericHTMLElement::GetEditor(aEditor);
   }
   NS_IMETHOD SetUserInput(const nsAString& aInput) override;
 
   // nsIFormControl
-  NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_TEXTAREA; }
   NS_IMETHOD Reset() override;
   NS_IMETHOD SubmitNamesValues(HTMLFormSubmission* aFormSubmission) override;
   NS_IMETHOD SaveState() override;
   virtual bool RestoreState(nsPresState* aState) override;
   virtual bool IsDisabledForEvents(EventMessage aMessage) override;
 
   virtual void FieldSetDisabledChanged(bool aNotify) override;
 
--- a/dom/html/RadioNodeList.cpp
+++ b/dom/html/RadioNodeList.cpp
@@ -20,17 +20,17 @@ RadioNodeList::WrapObject(JSContext* aCx
 {
   return RadioNodeListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 HTMLInputElement*
 GetAsRadio(nsIContent* node)
 {
   HTMLInputElement* el = HTMLInputElement::FromContent(node);
-  if (el && el->GetType() == NS_FORM_INPUT_RADIO) {
+  if (el && el->ControlType() == NS_FORM_INPUT_RADIO) {
     return el;
   }
   return nullptr;
 }
 
 void
 RadioNodeList::GetValue(nsString& retval, CallerType aCallerType)
 {
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -398,17 +398,17 @@ nsGenericHTMLElement::Spellcheck()
 
   // Anything else that's not a form control is not spellchecked by default
   nsCOMPtr<nsIFormControl> formControl = do_QueryObject(this);
   if (!formControl) {
     return false;                       // Not spellchecked by default
   }
 
   // Is this a multiline plaintext input?
-  int32_t controlType = formControl->GetType();
+  int32_t controlType = formControl->ControlType();
   if (controlType == NS_FORM_TEXTAREA) {
     return true;             // Spellchecked by default
   }
 
   // Is this anything other than an input text?
   // Other inputs are not spellchecked.
   if (controlType != NS_FORM_INPUT_TEXT) {
     return false;                       // Not spellchecked by default
@@ -1725,18 +1725,20 @@ nsGenericHTMLElement::IsInteractiveHTMLC
 bool
 nsGenericHTMLElement::TouchEventsEnabled(JSContext* aCx, JSObject* aGlobal)
 {
   return TouchEvent::PrefEnabled(aCx, aGlobal);
 }
 
 //----------------------------------------------------------------------
 
-nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
+nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+                                                   uint8_t aType)
   : nsGenericHTMLElement(aNodeInfo)
+  , nsIFormControl(aType)
   , mForm(nullptr)
   , mFieldSet(nullptr)
 {
   // We should add the NS_EVENT_STATE_ENABLED bit here as needed, but
   // that depends on our type, which is not initialized yet.  So we
   // have to do this in subclasses.
 }
 
@@ -2085,17 +2087,17 @@ nsGenericHTMLFormElement::ForgetFieldSet
   if (mFieldSet == aFieldset) {
     mFieldSet = nullptr;
   }
 }
 
 bool
 nsGenericHTMLFormElement::CanBeDisabled() const
 {
-  int32_t type = GetType();
+  int32_t type = ControlType();
   // It's easier to test the types that _cannot_ be disabled
   return
     type != NS_FORM_OBJECT &&
     type != NS_FORM_OUTPUT;
 }
 
 bool
 nsGenericHTMLFormElement::IsHTMLFocusable(bool aWithMouse,
@@ -2398,17 +2400,17 @@ nsGenericHTMLFormElement::FieldSetDisabl
 {
   UpdateState(aNotify);
 }
 
 bool
 nsGenericHTMLFormElement::IsLabelable() const
 {
   // TODO: keygen should be in that list, see bug 101019.
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return (type & NS_FORM_INPUT_ELEMENT && type != NS_FORM_INPUT_HIDDEN) ||
          type & NS_FORM_BUTTON_ELEMENT ||
          // type == NS_FORM_KEYGEN ||
          type == NS_FORM_OUTPUT ||
          type == NS_FORM_SELECT ||
          type == NS_FORM_TEXTAREA;
 }
 
@@ -2725,19 +2727,19 @@ nsGenericHTMLElement::ChangeEditableStat
   nsAutoScriptBlocker scriptBlocker;
   MakeContentDescendantsEditable(this, document);
 }
 
 
 //----------------------------------------------------------------------
 
 nsGenericHTMLFormElementWithState::nsGenericHTMLFormElementWithState(
-    already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo
+    already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo, uint8_t aType
   )
-  : nsGenericHTMLFormElement(aNodeInfo)
+  : nsGenericHTMLFormElement(aNodeInfo, aType)
 {
   mStateKey.SetIsVoid(true);
 }
 
 nsresult
 nsGenericHTMLFormElementWithState::GenerateStateKey()
 {
   // Keep the key if already computed
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -1203,17 +1203,18 @@ ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPE
 
 /**
  * A helper class for form elements that can contain children
  */
 class nsGenericHTMLFormElement : public nsGenericHTMLElement,
                                  public nsIFormControl
 {
 public:
-  explicit nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+                           uint8_t aType);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   nsINode* GetScopeChainParent() const override;
 
   virtual bool IsNodeOfType(uint32_t aFlags) const override;
   virtual void SaveSubtreeState() override;
 
@@ -1363,17 +1364,18 @@ protected:
 
   /* This is a pointer to our closest fieldset parent if any */
   mozilla::dom::HTMLFieldSetElement* mFieldSet;
 };
 
 class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
 {
 public:
-  explicit nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
+  nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
+                                    uint8_t aType);
 
   /**
    * Get the presentation state for a piece of content, or create it if it does
    * not exist.  Generally used by SaveState().
    */
   nsPresState* GetPrimaryPresState();
 
   /**
--- a/dom/html/nsIFormControl.h
+++ b/dom/html/nsIFormControl.h
@@ -87,16 +87,20 @@ static_assert(static_cast<uint32_t>(eInp
 /**
  * Interface which all form controls (e.g. buttons, checkboxes, text,
  * radio buttons, select, etc) implement in addition to their dom specific
  * interface.
  */
 class nsIFormControl : public nsISupports
 {
 public:
+  nsIFormControl(uint8_t aType)
+  : mType(aType)
+  {
+  }
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFORMCONTROL_IID)
 
   /**
    * Get the fieldset for this form control.
    * @return the fieldset
    */
   virtual mozilla::dom::HTMLFieldSetElement *GetFieldSet() = 0;
@@ -125,17 +129,17 @@ public:
    *        from the form.  (Used by nsFormControlList::Clear())
    */
   virtual void ClearForm(bool aRemoveFromForm) = 0;
 
   /**
    * Get the type of this control as an int (see NS_FORM_* above)
    * @return the type of this control
    */
-  NS_IMETHOD_(uint32_t) GetType() const = 0 ;
+  uint32_t ControlType() const { return mType; }
 
   /**
    * Reset this form control (as it should be when the user clicks the Reset
    * button)
    */
   NS_IMETHOD Reset() = 0;
 
   /**
@@ -221,45 +225,47 @@ protected:
    */
   inline static bool IsSingleLineTextControl(bool aExcludePassword, uint32_t aType);
 
   /**
    * Returns whether this is a auto-focusable form control.
    * @return whether this is a auto-focusable form control.
    */
   inline bool IsAutofocusable() const;
+
+  uint8_t                  mType;
 };
 
 bool
 nsIFormControl::IsSubmitControl() const
 {
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return type == NS_FORM_INPUT_SUBMIT ||
          type == NS_FORM_INPUT_IMAGE ||
          type == NS_FORM_BUTTON_SUBMIT;
 }
 
 bool
 nsIFormControl::IsTextControl(bool aExcludePassword) const
 {
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return type == NS_FORM_TEXTAREA ||
          IsSingleLineTextControl(aExcludePassword, type);
 }
 
 bool
 nsIFormControl::IsTextOrNumberControl(bool aExcludePassword) const
 {
-  return IsTextControl(aExcludePassword) || GetType() == NS_FORM_INPUT_NUMBER;
+  return IsTextControl(aExcludePassword) || ControlType() == NS_FORM_INPUT_NUMBER;
 }
 
 bool
 nsIFormControl::IsSingleLineTextControl(bool aExcludePassword) const
 {
-  return IsSingleLineTextControl(aExcludePassword, GetType());
+  return IsSingleLineTextControl(aExcludePassword, ControlType());
 }
 
 /*static*/
 bool
 nsIFormControl::IsSingleLineTextControl(bool aExcludePassword, uint32_t aType)
 {
   return aType == NS_FORM_INPUT_TEXT ||
          aType == NS_FORM_INPUT_EMAIL ||
@@ -277,38 +283,38 @@ nsIFormControl::IsSingleLineTextControl(
          aType == NS_FORM_INPUT_DATETIME_LOCAL ||
          (!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
 }
 
 bool
 nsIFormControl::IsSubmittableControl() const
 {
   // TODO: keygen should be in that list, see bug 101019.
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return type == NS_FORM_OBJECT ||
          type == NS_FORM_TEXTAREA ||
          type == NS_FORM_SELECT ||
          // type == NS_FORM_KEYGEN ||
          type & NS_FORM_BUTTON_ELEMENT ||
          type & NS_FORM_INPUT_ELEMENT;
 }
 
 bool
 nsIFormControl::AllowDraggableChildren() const
 {
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return type == NS_FORM_OBJECT ||
          type == NS_FORM_FIELDSET ||
          type == NS_FORM_OUTPUT;
 }
 
 bool
 nsIFormControl::IsAutofocusable() const
 {
-  uint32_t type = GetType();
+  uint32_t type = ControlType();
   return type & NS_FORM_INPUT_ELEMENT ||
          type & NS_FORM_BUTTON_ELEMENT ||
          type == NS_FORM_TEXTAREA ||
          type == NS_FORM_SELECT;
 }
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormControl, NS_IFORMCONTROL_IID)
 
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -1974,17 +1974,17 @@ nsTextEditorState::GetParentNumberContro
   }
   HTMLInputElement* input = HTMLInputElement::FromContent(parentOfParent);
   if (input) {
     // This function might be called during frame reconstruction as a result
     // of changing the input control's type from number to something else. In
     // that situation, the type of the control has changed, but its frame has
     // not been reconstructed yet.  So we need to check the type of the input
     // control in addition to the type of the frame.
-    return (input->GetType() == NS_FORM_INPUT_NUMBER) ? input : nullptr;
+    return (input->ControlType() == NS_FORM_INPUT_NUMBER) ? input : nullptr;
   }
 
   return nullptr;
 }
 
 void
 nsTextEditorState::DestroyEditor()
 {
--- a/dom/svg/nsSVGElement.cpp
+++ b/dom/svg/nsSVGElement.cpp
@@ -12,16 +12,17 @@
 
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGTests.h"
 #include "nsContentUtils.h"
 #include "nsICSSDeclaration.h"
 #include "nsIDocument.h"
 #include "nsIDOMMutationEvent.h"
 #include "mozilla/InternalMutationEvent.h"
+#include "mozAutoDocUpdate.h"
 #include "nsError.h"
 #include "nsIPresShell.h"
 #include "nsGkAtoms.h"
 #include "nsRuleWalker.h"
 #include "mozilla/css/Declaration.h"
 #include "nsCSSProps.h"
 #include "nsCSSParser.h"
 #include "mozilla/EventListenerManager.h"
@@ -1465,19 +1466,23 @@ nsSVGElement::DidChangeValue(nsIAtom* aN
 {
   bool hasListeners =
     nsContentUtils::HasMutationListeners(this,
                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
                                          this);
   uint8_t modType = HasAttr(kNameSpaceID_None, aName)
                   ? static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION)
                   : static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+
+  nsIDocument* document = GetComposedDoc();
+  mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL,
+                               kNotifyDocumentObservers);
   SetAttrAndNotify(kNameSpaceID_None, aName, nullptr, aEmptyOrOldValue,
                    aNewValue, modType, hasListeners, kNotifyDocumentObservers,
-                   kCallAfterSetAttr);
+                   kCallAfterSetAttr, document, updateBatch);
 }
 
 void
 nsSVGElement::MaybeSerializeAttrBeforeRemoval(nsIAtom* aName, bool aNotify)
 {
   if (!aNotify ||
       !nsContentUtils::HasMutationListeners(this,
                                             NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -1203,17 +1203,17 @@ PersistNodeFixup::FixupNode(nsIDOMNode *
 
             nsAutoString valueStr;
             NS_NAMED_LITERAL_STRING(valueAttr, "value");
             // Update element node attributes with user-entered form state
             nsCOMPtr<nsIContent> content = do_QueryInterface(*aNodeOut);
             RefPtr<dom::HTMLInputElement> outElt =
               dom::HTMLInputElement::FromContentOrNull(content);
             nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(*aNodeOut);
-            switch (formControl->GetType()) {
+            switch (formControl->ControlType()) {
                 case NS_FORM_INPUT_EMAIL:
                 case NS_FORM_INPUT_SEARCH:
                 case NS_FORM_INPUT_TEXT:
                 case NS_FORM_INPUT_TEL:
                 case NS_FORM_INPUT_URL:
                 case NS_FORM_INPUT_NUMBER:
                 case NS_FORM_INPUT_RANGE:
                 case NS_FORM_INPUT_DATE:
--- a/editor/libeditor/EditorEventListener.cpp
+++ b/editor/libeditor/EditorEventListener.cpp
@@ -1203,17 +1203,17 @@ EditorEventListener::IsFileControlTextBo
   if (!root || !root->ChromeOnlyAccess()) {
     return false;
   }
   nsIContent* parent = root->FindFirstNonChromeOnlyAccessContent();
   if (!parent || !parent->IsHTMLElement(nsGkAtoms::input)) {
     return false;
   }
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(parent);
-  return formControl->GetType() == NS_FORM_INPUT_FILE;
+  return formControl->ControlType() == NS_FORM_INPUT_FILE;
 }
 
 bool
 EditorEventListener::ShouldHandleNativeKeyBindings(
                        WidgetKeyboardEvent* aKeyboardEvent)
 {
   MOZ_ASSERT(!DetachedFromEditor());
 
--- a/js/src/jit-test/tests/ctypes/function-definition.js
+++ b/js/src/jit-test/tests/ctypes/function-definition.js
@@ -22,17 +22,17 @@ function test() {
                          "return type cannot be an array or function (got ctypes.int32_t.array())");
   assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t, []), []); },
                          "return type cannot be an array or function (got ctypes.FunctionType(ctypes.default_abi, ctypes.int32_t))");
   assertTypeErrorMessage(() => { ctypes.FunctionType(ctypes.default_abi, ctypes.StructType("a"), []); },
                          "return type must have defined size (got ctypes.StructType(\"a\"))");
 
   let lib;
   try {
-    lib = ctypes.open(ctypes.libraryName("c"));
+    lib = ctypes.open(ctypes.libraryName("m"));
   } catch (e) {
   }
   if (!lib)
     return;
 
   let func = lib.declare("hypot",
                          ctypes.default_abi,
                          ctypes.double,
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3723,17 +3723,17 @@ nsCSSFrameConstructor::FindInputData(Ele
                                  nsCSSAnonBoxes::buttonContent) }
     // Keeping hidden inputs out of here on purpose for so they get frames by
     // display (in practice, none).
   };
 
   nsCOMPtr<nsIFormControl> control = do_QueryInterface(aElement);
   NS_ASSERTION(control, "input doesn't implement nsIFormControl?");
 
-  auto controlType = control->GetType();
+  auto controlType = control->ControlType();
 
   // Note that Android/Gonk widgets don't have theming support and thus
   // appearance:none is the same as any other appearance value.
   // So this chunk doesn't apply there:
 #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
   // radio and checkbox inputs with appearance:none should be constructed
   // by display type.  (Note that we're not checking that appearance is
   // not (respectively) NS_THEME_RADIO and NS_THEME_CHECKBOX.)
--- a/layout/forms/nsColorControlFrame.cpp
+++ b/layout/forms/nsColorControlFrame.cpp
@@ -116,17 +116,17 @@ nsColorControlFrame::AttributeChanged(in
                                       int32_t  aModType)
 {
   NS_ASSERTION(mColorContent, "The color div must exist");
 
   // If the value attribute is set, update the color box, but only if we're
   // still a color control, which might not be the case if the type attribute
   // was removed/changed.
   nsCOMPtr<nsIFormControl> fctrl = do_QueryInterface(GetContent());
-  if (fctrl->GetType() == NS_FORM_INPUT_COLOR &&
+  if (fctrl->ControlType() == NS_FORM_INPUT_COLOR &&
       aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
     UpdateColor();
   }
   return nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute,
                                                     aModType);
 }
 
 nsContainerFrame*
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1445,17 +1445,17 @@ nsComboboxControlFrame::SetInitialChildL
                                             nsFrameList&    aChildList)
 {
   if (kSelectPopupList == aListID) {
     mPopupFrames.SetFrames(aChildList);
   } else {
     for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
       nsCOMPtr<nsIFormControl> formControl =
         do_QueryInterface(e.get()->GetContent());
-      if (formControl && formControl->GetType() == NS_FORM_BUTTON_BUTTON) {
+      if (formControl && formControl->ControlType() == NS_FORM_BUTTON_BUTTON) {
         mButtonFrame = e.get();
         break;
       }
     }
     NS_ASSERTION(mButtonFrame, "missing button frame in initial child list");
     nsBlockFrame::SetInitialChildList(aListID, aChildList);
   }
 }
--- a/layout/forms/nsDateTimeControlFrame.cpp
+++ b/layout/forms/nsDateTimeControlFrame.cpp
@@ -378,18 +378,18 @@ nsDateTimeControlFrame::AttributeChanged
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::value ||
         aAttribute == nsGkAtoms::readonly ||
         aAttribute == nsGkAtoms::tabindex) {
       MOZ_ASSERT(mContent->IsHTMLElement(nsGkAtoms::input), "bad cast");
       auto contentAsInputElem = static_cast<dom::HTMLInputElement*>(mContent);
       // If script changed the <input>'s type before setting these attributes
       // then we don't need to do anything since we are going to be reframed.
-      if (contentAsInputElem->GetType() == NS_FORM_INPUT_TIME ||
-          contentAsInputElem->GetType() == NS_FORM_INPUT_DATE) {
+      if (contentAsInputElem->ControlType() == NS_FORM_INPUT_TIME ||
+          contentAsInputElem->ControlType() == NS_FORM_INPUT_DATE) {
         nsCOMPtr<nsIDateTimeInputArea> inputAreaContent =
           do_QueryInterface(mInputAreaContent);
         if (aAttribute == nsGkAtoms::value) {
           if (inputAreaContent) {
             nsContentUtils::AddScriptRunner(NewRunnableMethod(inputAreaContent,
               &nsIDateTimeInputArea::NotifyInputElementValueChanged));
           }
         } else {
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -89,17 +89,17 @@ NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButt
 // label from a string bundle as is done for all other UI strings.
 // See bug 16999 for further details.
 nsresult
 nsGfxButtonControlFrame::GetDefaultLabel(nsXPIDLString& aString) const
 {
   nsCOMPtr<nsIFormControl> form = do_QueryInterface(mContent);
   NS_ENSURE_TRUE(form, NS_ERROR_UNEXPECTED);
 
-  int32_t type = form->GetType();
+  int32_t type = form->ControlType();
   const char *prop;
   if (type == NS_FORM_INPUT_RESET) {
     prop = "Reset";
   }
   else if (type == NS_FORM_INPUT_SUBMIT) {
     prop = "Submit";
   }
   else {
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -484,17 +484,17 @@ nsRangeFrame::AccessibleType()
 #endif
 
 double
 nsRangeFrame::GetValueAsFractionOfRange()
 {
   MOZ_ASSERT(mContent->IsHTMLElement(nsGkAtoms::input), "bad cast");
   dom::HTMLInputElement* input = static_cast<dom::HTMLInputElement*>(mContent);
 
-  MOZ_ASSERT(input->GetType() == NS_FORM_INPUT_RANGE);
+  MOZ_ASSERT(input->ControlType() == NS_FORM_INPUT_RANGE);
 
   Decimal value = input->GetValueAsDecimal();
   Decimal minimum = input->GetMinimum();
   Decimal maximum = input->GetMaximum();
 
   MOZ_ASSERT(value.isFinite() && minimum.isFinite() && maximum.isFinite(),
              "type=range should have a default maximum/minimum");
   
@@ -513,17 +513,17 @@ nsRangeFrame::GetValueAtEventPoint(Widge
 {
   MOZ_ASSERT(aEvent->mClass == eMouseEventClass ||
              aEvent->mClass == eTouchEventClass,
              "Unexpected event type - aEvent->mRefPoint may be meaningless");
 
   MOZ_ASSERT(mContent->IsHTMLElement(nsGkAtoms::input), "bad cast");
   dom::HTMLInputElement* input = static_cast<dom::HTMLInputElement*>(mContent);
 
-  MOZ_ASSERT(input->GetType() == NS_FORM_INPUT_RANGE);
+  MOZ_ASSERT(input->ControlType() == NS_FORM_INPUT_RANGE);
 
   Decimal minimum = input->GetMinimum();
   Decimal maximum = input->GetMaximum();
   MOZ_ASSERT(minimum.isFinite() && maximum.isFinite(),
              "type=range should have a default maximum/minimum");
   if (maximum <= minimum) {
     return minimum;
   }
@@ -745,17 +745,18 @@ nsRangeFrame::AttributeChanged(int32_t  
       // SetAttr(..., nsGkAtoms::value, ...) call in HTMLInputElement::
       // HandleTypeChange. In that case the HTMLInputElement's type will
       // already have changed, and if we call UpdateForValueChange()
       // we'll fail the asserts under that call that check the type of our
       // HTMLInputElement. Given that we're changing away from being a range
       // and this frame will shortly be destroyed, there's no point in calling
       // UpdateForValueChange() anyway.
       MOZ_ASSERT(mContent->IsHTMLElement(nsGkAtoms::input), "bad cast");
-      bool typeIsRange = static_cast<dom::HTMLInputElement*>(mContent)->GetType() ==
+      bool typeIsRange =
+        static_cast<dom::HTMLInputElement*>(mCont