From 05104ff48aa3da22bf9973398dd6306f73cfa1ae Mon Sep 17 00:00:00 2001
From: Gordon Tetlow <gordon@FreeBSD.org>
Date: Wed, 9 Jan 2019 19:17:54 +0000
Subject: [PATCH] Add EN-19:01 through EN-19:05.

Approved by:	so
---
 .../advisories/FreeBSD-EN-19:01.cc_cubic.asc  |   133 +
 .../advisories/FreeBSD-EN-19:02.tcp.asc       |   128 +
 .../advisories/FreeBSD-EN-19:03.sqlite.asc    |   145 +
 .../advisories/FreeBSD-EN-19:04.tzdata.asc    |   147 +
 .../advisories/FreeBSD-EN-19:05.kqueue.asc    |   126 +
 .../security/patches/EN-19:01/cc_cubic.patch  |   194 +
 .../patches/EN-19:01/cc_cubic.patch.asc       |    18 +
 share/security/patches/EN-19:02/tcp.patch     |    56 +
 share/security/patches/EN-19:02/tcp.patch.asc |    18 +
 .../security/patches/EN-19:03/sqlite-11.patch | 76146 ++++++++++++++++
 .../patches/EN-19:03/sqlite-11.patch.asc      |    18 +
 .../security/patches/EN-19:03/sqlite-12.patch | 65012 +++++++++++++
 .../patches/EN-19:03/sqlite-12.patch.asc      |    18 +
 .../patches/EN-19:04/tzdata-2018i.patch       |  1448 +
 .../patches/EN-19:04/tzdata-2018i.patch.asc   |    18 +
 share/security/patches/EN-19:05/kqueue.patch  |    49 +
 .../patches/EN-19:05/kqueue.patch.asc         |    18 +
 share/xml/notices.xml                         |    33 +
 18 files changed, 143725 insertions(+)
 create mode 100644 share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc
 create mode 100644 share/security/advisories/FreeBSD-EN-19:02.tcp.asc
 create mode 100644 share/security/advisories/FreeBSD-EN-19:03.sqlite.asc
 create mode 100644 share/security/advisories/FreeBSD-EN-19:04.tzdata.asc
 create mode 100644 share/security/advisories/FreeBSD-EN-19:05.kqueue.asc
 create mode 100644 share/security/patches/EN-19:01/cc_cubic.patch
 create mode 100644 share/security/patches/EN-19:01/cc_cubic.patch.asc
 create mode 100644 share/security/patches/EN-19:02/tcp.patch
 create mode 100644 share/security/patches/EN-19:02/tcp.patch.asc
 create mode 100644 share/security/patches/EN-19:03/sqlite-11.patch
 create mode 100644 share/security/patches/EN-19:03/sqlite-11.patch.asc
 create mode 100644 share/security/patches/EN-19:03/sqlite-12.patch
 create mode 100644 share/security/patches/EN-19:03/sqlite-12.patch.asc
 create mode 100644 share/security/patches/EN-19:04/tzdata-2018i.patch
 create mode 100644 share/security/patches/EN-19:04/tzdata-2018i.patch.asc
 create mode 100644 share/security/patches/EN-19:05/kqueue.patch
 create mode 100644 share/security/patches/EN-19:05/kqueue.patch.asc

diff --git a/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc b/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc
new file mode 100644
index 0000000000..7b88ad20df
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc
@@ -0,0 +1,133 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-19:01.cc_cubic                                       Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          Connection stalls with CUBIC congestion control
+
+Category:       core
+Module:         tcp
+Announced:      2019-01-09
+Credits:        Matt Garber, Hiren Panchasara
+Affects:        FreeBSD 12.0
+Corrected:      2018-12-17 21:46:42 UTC (stable/12, 12.0-STABLE)
+                2019-01-09 18:38:35 UTC (releng/12.0, 12.0-RELEASE-p2)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+CUBIC is a modern congestion control algorithm for the Transmission Control
+Protocol (TCP), which along with its predecessor BIC TCP is specifically
+optimized for high bandwidth, high latency networks.  It is widely
+implemented across a variety of operating systems, and is the default TCP
+implementation or enabled by default in recent versions of Linux and
+Microsoft Windows.  CUBIC is available as an alternate congestion control
+algorithm since FreeBSD 9.0 using the cc_cubic module.
+
+II.  Problem Description
+
+Changes to the cc_cubic module in FreeBSD 12.0 can cause network stuttering
+or connection stalls when loaded and enabled as default.
+
+III. Impact
+
+FreeBSD 12.0 systems loading cc_cubic and setting non-default sysctl value
+net.inet.tcp.cc.algorithm=cubic exhibit stuttering and complete stalls of
+network connections.  Under certain conditions, this may cause loss of system
+availability over the network or service unreachability.
+
+IV.  Workaround
+
+Disabling cc_cubic and selecting one of the alternate included congestion
+control algorithms (e.g., newreno, htcp) will restore normal network
+connectivity and alleviate stuttering and stalls.  Note that disabling CUBIC
+may cause a reduction in expected performance based on specific, unique
+network condition characteristics and the module used as a workaround.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date, and reboot the system.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +30 "Rebooting for FreeBSD errata update"
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 12.0]
+# fetch https://security.FreeBSD.org/patches/EN-19:01/cc_cubic.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:01/cc_cubic.patch.asc
+# gpg --verify cc_cubic.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/12/                                                        r342181
+releng/12.0/                                                      r342893
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-19:01.cc_cubic.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2Rb5fFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJGyRAAnpturBqU4XIZMdvInaVHOXA5P6KemeFuJkwz/aMtIbgefm49lvZVS4q6
+RO8/GytONX1OHaoJQDdincVfRbe9x+ID+ulCJfSLuZMhjLYpxDQJo9d4NWZtvpBn
+3wJNEQEXB0AjrYUOrebiT7yd3zA4f+7zSHu0Uvq4k5Tk0Xxsqxsx3/MG5ezEmdxx
+IWub1RnYvgmUVJBKn/C5A4v17dE12VnZtLrnfhZ4K3U3mVZYc3cJxF34wSscVqYd
+iAsntF786FV+hAXBX7wHa3JIqe+uXE2uemrquNmxgup+zrbVWPWPirgku2TVcvsm
+m9aQILNc9RvJ/XkViLV8+ypqCymBFsl3VhO3dzmOnsbL72G9rqjQtgdYWT2dp69p
+VyU4EWsTULXIbIBNxyrYhinT+DAqyt8bdrtyT3AhcVJaVk5B5APWnXiwjgS4mPN9
+hf2mCjZw10tJgsqYYrBlTERomgHU/pyliu0Rt2sof5+iGArbe7ZhEorHrM7YhD9n
+Hc+3oNzA0dYDStJQpEb4rJ7dEKP/mpppwIosMhPbku6u3ViafCJVq2dIGNQpDope
+Mh00Kk7cY0o3Rukw2lGNc9vDbIyUSqT/jV4lBDhp4k5ilQynvkMZETLlynI+KQUH
+J2uOOvYzkIZLzZyXtaQfkmrkV6DxzmjxDsqwiMz5DB7o70w/M54=
+=e8Wg
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-19:02.tcp.asc b/share/security/advisories/FreeBSD-EN-19:02.tcp.asc
new file mode 100644
index 0000000000..7446692818
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-19:02.tcp.asc
@@ -0,0 +1,128 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-19:02.tcp                                            Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          TCP connections may stall and eventually fail in case of
+                packet loss
+
+Category:       core
+Module:         kernel
+Announced:      2019-01-09
+Credits:        Michael Tuexen
+Affects:        FreeBSD 12.0
+Corrected:      2018-12-23 09:48:36 UTC (stable/12, 12.0-STABLE)
+                2019-09-09 18:42:40 UTC (releng/12.0, 12.0-RELEASE-p2)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+The TCP stack limits the resources used for TCP connections.  Once a limit
+is reached, further received TCP segments for the TCP connection are dropped.
+
+II.  Problem Description
+
+To continue delivering data to the application, accepting the TCP segment
+with the next expected sequence number is required.  If this TCP segment is
+dropped due to a resource limit, no further progress can be made. Therefore
+exceptions for this particular TCP segment have to be implemented.
+
+III. Impact
+
+In case of lost TCP segments, TCP connections may stall and then eventually
+fail.
+
+IV.  Workaround
+
+No workaround is available.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date.
+
+Afterward, reboot the system.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+Afterward, reboot the system.
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 12.0]
+# fetch https://security.FreeBSD.org/patches/EN-19:02/tcp.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:02/tcp.patch.asc
+# gpg --verify tcp.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/12/                                                        r342378
+releng/12.0/                                                      r342894
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-19:02.tcp.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2Rc1fFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJtnxAAgOIJjP9Dg76onxJUPJWiKTAR5VZeZ8od0RJREIeZMUpgFiVUVH82fr8z
+ajAzGZbVFhEgFvYwQRU4R/MokNqONoG1O3YPdjcMFyW5HPBoAG+9h67qD3CtLgTN
+xnXMR72ed83oY8ts1WSfYVAKF+9X6U5G6FtchBgAhap2k9tI22QKiEmTTmqzUnoy
+ddLZatOyKmig8MZKshMmleEpvU+BoYR66d2K9CYxcjHqgNNJOQwQK6yLR3oX41Z9
+n5Akkg/KC7wD02CPFjmO9008ZC4fFiQ8D4eGt9D/lPI4AzLcfkvRdzt5CjMlamXm
+Rjf2H5/2f4iYSXiEi2wkChFJHh+MQuYgcfTqRJdNB0qf3DbLwTL5wULfrMVNn7LU
+rLHd8CNRTN4+d+//p7nZ/atFbuLjJE08YFqE2ODcMa8eJFaY09/+X+NMIqO6AdTE
+hGzqDuiVmI/1MSFjD7dxUotw6Y2iRf+DiLx+JUmb0L+C0FXfl/u8x1ErYbzuLyyL
+vD1qb66fDuuSC8aNWO6Qv55bBWAhYhO668CQwfmvEgree72ShbzJPEn3vUN2dIX4
+zg0kTs30QOlizAT2lxQchiPBKkQ+IExPurTT7lW0cZ5PID8y/FSKl49yeQo/nhrD
+j/vnF7yMgc6roCyasNlREdi20yTYbp2PItfhaSXWVrtYAFN1jNc=
+=3a3w
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc b/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc
new file mode 100644
index 0000000000..c5deeb3a96
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc
@@ -0,0 +1,145 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-19:03.sqlite                                         Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          sqlite update
+
+Category:       contrib
+Module:         sqlite3
+Announced:      2019-01-09
+Credits:        Cy Schubert
+Affects:        All supported versions of FreeBSD.
+Corrected:      2018-12-21 01:58:01 UTC (stable/12, 12.0-STABLE)
+                2019-01-09 18:47:10 UTC (releng/12.0, 12.0-RELEASE-p2)
+                2018-12-21 02:04:15 UTC (stable/11, 11.2-STABLE)
+                2019-01-09 18:50:27 UTC (releng/11.2, 11.2-RELEASE-p8)
+CVE Name:       CVE-2018-20346, CVE-2018-20505, CVE-2018-20506
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+SQLite is an SQL database engine in a C library.  Programs that link the
+SQLite library can have SQL database access without running a separate RDBMS
+process.  The distribution comes with a standalone command-line access
+program (sqlite3) that can be used to administer an SQLite database and which
+serves as an example of how to use the SQLite library.
+
+II.  Problem Description
+
+According to https://blade.tencent.com/magellan/index_en.html, the
+vulnerabilities known as Magellan are a group vulnerabilities that exist
+in sqlite3, documented by CVE-2018-20346, CVE-2018-20505, and CVE-2018-20506.
+
+When the FTS3 extension is enabled an integer overflow resulting in a buffer
+overflow when allowing remote attackers to run arbitrary SQL statements which
+can be leveraged to execute arbitrary code.
+
+III. Impact
+
+The vulnerabilities were discovered by Tencent Blade Team and verified to be
+able to successfully implement remote code execution in Chromium browsers.
+
+IV.  Workaround
+
+No workaround is available.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 11.2]
+# fetch https://security.FreeBSD.org/patches/EN-19:03/sqlite-11.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:03/sqlite-11.patch.asc
+# gpg --verify sqlite-11.patch.asc
+
+[FreeBSD 12.0]
+# fetch https://security.FreeBSD.org/patches/EN-19:03/sqlite-12.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:03/sqlite-12.patch.asc
+# gpg --verify sqlite-12.patch.asc
+
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all daemons that use the library, or reboot the system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/12/                                                        r342291
+releng/12.0/                                                      r342895
+stable/11/                                                        r342292
+releng/11.2/                                                      r342896
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://blade.tencent.com/magellan/index_en.html>
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234113>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-19:03.sqlite.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RdFfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLtJg/9EM0jQbTBrSgVy5X1AyQ2rcFz9KbjtA0L48wOuOLiAh7eeYxh4Wxuz9k1
+QnEJavMbpVr71yhmt6maEAbRzyGUvemDh4vlu0wjcYSlEzcvk7xaRzfXimippxky
+GumFBCvs7UKDIiGRr62ukmxu3FgfEaTM/Cc4bNcuV5k4za+DWIGTu+97i0+B2ieX
+/IZ5hQq42w1YIUY5QOy2vj87rnQf2t+uShcBjRg8HsnPsG9BfQfI8vfuWjjtaKMI
+iva++F5UJWcsykjZo5J3aaZFxnHsW2hs3buQN+AhoEt7oKdGquOHdweSw8xtSlp9
+3Y+qj+veD7u4Mt95OtnYrJOg8Kynlrzg5uMDbNGbyqktbxfpi2gqBbPEVmx2+nGj
+Aj9PDSHMliBZsVKvr1opExfYp4HL0LB9Kqhato08lFxs05TUxiT6LRcel/iXiIfl
+vCqfWhKJYVZ+alAW+Kjic6iWw7AtmVLbV64dDu03jxS/14RtRp1Hbk1BRCrnJeLn
+sLSdFj6bi2mQx6OXAd9G9jhReoxylyZwRXyhPSsPG1E4mzX6ZRbJfnkriSazW4hq
+F+PjTyXidn3uhS6z6CZB08Ltw2NBd3baRl/TQBEiFHd6SSGByqX6gMguK/tQV92U
+uM/Q4Ak4H/Q+nEN8/LdXioW0P7ZEC6X/9GXKWv+bUs6LjcZXftA=
+=TG5W
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc b/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc
new file mode 100644
index 0000000000..8fda0df158
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc
@@ -0,0 +1,147 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-19:04.tzdata                                         Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          Timezone database information update
+
+Category:       contrib
+Module:         zoneinfo
+Announced:      2019-01-09
+Credits:        Philip Paeps
+Affects:        All supported versions of FreeBSD.
+Corrected:      2019-01-01 10:04:49 UTC (stable/12, 12.0-STABLE)
+                2019-01-09 18:53:35 UTC (releng/12.0, 12.0-RELEASE-p2)
+                2019-01-01 10:05:12 UTC (stable/11, 11.2-STABLE)
+                2019-01-09 18:54:42 UTC (releng/11.2, 11.2-RELEASE-p8)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+The tzsetup(8) program allows the user to specify the default local timezone.
+Based on the selected timezone, tzsetup(8) copies one of the files from
+/usr/share/zoneinfo to /etc/localtime.  This file actually controls the
+conversion.
+
+II.  Problem Description
+
+Several changes in Daylight Savings Time happened after previous FreeBSD
+releases were released that would affect many people who live in different
+countries.  Because of these changes, the data in the zoneinfo files need to
+be updated, and if the local timezone on the running system is affected,
+tzsetup(8) needs to be run so the /etc/localtime is updated.
+
+III. Impact
+
+An incorrect time will be displayed on a system configured to use one of the
+affected timezones if the /usr/share/zoneinfo and /etc/localtime files are
+not updated, and all applications on the system that rely on the system time,
+such as cron(8) and syslog(8), will be affected.
+
+IV.  Workaround
+
+The system administrator can install an updated timezone database from the
+misc/zoneinfo port and run tzsetup(8) to get the timezone database corrected.
+
+Applications that store and display times in Coordinated Universal Time (UTC)
+are not affected.
+
+V.   Solution
+
+Please note that some third party software, for instance PHP, Ruby, Java and
+Perl, may be using different zoneinfo data source, in such cases this
+software must be updated separately.  For software packages that is installed
+via binary packages, they can be upgraded by executing `pkg upgrade'.
+
+Following the instructions in this Errata Notice will update all of the
+zoneinfo files to be the same as what was released with FreeBSD release.
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date.  Restart all the affected
+applications and daemons, or reboot the system.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+Restart all the affected applications and daemons, or reboot the system.
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/EN-19:04/tzdata-2018i.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:04/tzdata-2018i.patch.asc
+# gpg --verify tzdata-2018i.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all the affected applications and daemons, or reboot the system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/12/                                                        r342667
+releng/12.0/                                                      r342897
+stable/11/                                                        r342668
+releng/11.2/                                                      r342898
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-19:04.tzdata.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RdRfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cKd+Q//QYBUcMdBnW6URT8bWCrIOTPP84aGpMKmU4ZZYidUfI6CJiiWVaGQHJgD
+tmdQjaHemSRfxQ+yAZ5XR8oUIBxrzBhA51cM5QMNnJMXBkpqz9yCbHefH3Fxfr6n
+Dg+Vt2cZ745MHPK9uhjtUTmLYRF2iztUqlATr3R1NxBbJ6QQzQuVEyeAvTSY9Jdw
+/+cQM72m28iHPP+ff5v9n2MLqoTg74HbchwJthtDvgK9elfQFuC1F07i8I6F4krT
+FHnPRISpg4EEOKYG/Jjedk9FQBUpKiOhsDz+siGtjQoivz8TemaH5nTMI7P/WP/7
+jFJ6+jQirc2vCvcUzmiPGrBXRx3OptYcIiLOeKfgc+wCtgEHap4Nrl4Damt1QC13
+T4kpaOi3TcqtDtKxZyxwR8tOtJGEayqXFHA5FL1Fgr63JcvbZTXlBg0BT4oAd7mX
+DuvDkap5hXh6jlQ2BM4L9J+I+GNMfrpULsM4drsqd7GVBcLrnu06po3M8jgja44T
+rVzNB62FuOX19Q2W8kZ7LOfAwW+ho02GNzwuYWiLCpP4JSTaxtHrd1LexpCzO4Lg
+zsttA2bkNjmzHxfcbAPbS5IMX539iJdTgZiDlBNzUi+QqiCG83/fRcVvgD7qH1iM
+kF7DipZUURjlV/RbtCZFU/fsKVzR7rF5MSQl9q7llwe5uMto6lQ=
+=1NIG
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc b/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc
new file mode 100644
index 0000000000..b32b9bd112
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc
@@ -0,0 +1,126 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-19:05.kqueue                                         Errata Notice
+                                                          The FreeBSD Project
+
+Topic:          kqueue race condition and kernel panic
+
+Category:       core
+Module:         kqueue
+Announced:      2019-01-09
+Credits:        Mark Johnston
+Affects:        FreeBSD 11.2
+Corrected:      2019-11-24 17:11:47 UTC (stable/11, 11.2-STABLE)
+                2019-01-09 18:57:38 UTC (releng/11.2, 11.2-RELEASE-p8)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I.   Background
+
+kevent(2) is a system call which provides a generic method of notifying the
+caller when a caller-specified event happens or a condition holds.  One use
+for kevent(2) is to wait for a specified timeout to elapse.
+
+II.  Problem Description
+
+The kevent(2) implementation in the kernel contains a race condition which
+can be triggered when an event is added and fires shortly after.  Most event
+types are not affected, but timer events can trigger the race if the timeout
+duration is very short.
+
+III. Impact
+
+The race condition can cause corruption of a queue structure, leading to
+a kernel panic when it is later accessed.  Applications using kevent(2) may
+trigger the panic if their usage causes the race condition to occur.
+
+IV.  Workaround
+
+No workaround is available.
+
+V.   Solution
+
+Perform one of the following:
+
+1) Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date, and reboot.
+
+2) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +30 "Rebooting for errata update"
+
+3) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 11.2]
+# fetch https://security.FreeBSD.org/patches/EN-19:05/kqueue.patch
+# fetch https://security.FreeBSD.org/patches/EN-19:05/kqueue.patch.asc
+# gpg --verify kqueue.patch.asc
+
+b) Apply the patch.  Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI.  Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path                                                      Revision
+- -------------------------------------------------------------------------
+stable/11/                                                        r340904
+releng/11.2/                                                      r342899
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-19:05.kqueue.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RdZfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cK0nRAAgPsdkc/TyBTqpvJrvvNaVd0xgNC2lxnYK3HxOPbo5kqj6XHZxb3KvrrN
+He6TyGvwGCPHNzlFwHILH+FtFkgrvGVBoPu/U0e/NKRrkhyxPHJMz0bZPu7yqQoG
+GDFRIsw5D3JKZW38yMD9Menh3mag81OVZii1LfzkcDLLKfwX/zcx1vV7MSwMzoNs
+5L7Fm8lg0uIxrrlKvvmrPxfWoZENhCr9CAAdg8moL3thl64NaVVmPo7tXDXosNGo
+EQYT19SY0FBSboUcpVaChgyZaCFzOeCPuXuJPoUYppIWNiv2S8ZTjuq9d1g4R4SD
+7GBMozz8EG1rN0pzhx8mVEECZBzdt5rjggiWKjkOVxH/sy5LQjppONK3VVOygoCz
+dve2wGq6S1ke/b2NDRpAinmIr8I3x3b7JLNkE5OvNJ6bTLk3ZmpIRYQNYT+eu8Fx
+GNe/oTU9DRbB4yv0kcKsypHqQ0cKdn6+duYzKGZ4+c86B7IHJgsYoG/NTKYfFzQx
+BHWuI/P/9pakHESNiDidKRz+z5w679+jIfZDcbBIXaw+PCqzg5a1GFN8Bub2mGLw
+2wmVQJV1nbdE+6UbWvaV2seV/bo+N/L8k4QS6OPIDUefLPGgCdRFr/MlLoiTaJ43
+p+L3iVlVbiOTCfsCGI/QVQq+IOngKzqSUXN3Ys7PXvvAzSyaTFg=
+=fD2U
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:01/cc_cubic.patch b/share/security/patches/EN-19:01/cc_cubic.patch
new file mode 100644
index 0000000000..263715f214
--- /dev/null
+++ b/share/security/patches/EN-19:01/cc_cubic.patch
@@ -0,0 +1,194 @@
+--- sys/netinet/cc/cc.h.orig
++++ sys/netinet/cc/cc.h
+@@ -102,8 +102,6 @@
+ #define	CCF_ACKNOW		0x0008	/* Will this ack be sent now? */
+ #define	CCF_IPHDR_CE		0x0010	/* Does this packet set CE bit? */
+ #define	CCF_TCPHDR_CWR		0x0020	/* Does this packet set CWR bit? */
+-#define	CCF_MAX_CWND		0x0040	/* Have we reached maximum cwnd? */
+-#define	CCF_CHG_MAX_CWND	0x0080	/* Cubic max_cwnd changed, for K */
+ 
+ /* ACK types passed to the ack_received() hook. */
+ #define	CC_ACK		0x0001	/* Regular in sequence ACK. */
+--- sys/netinet/cc/cc_cubic.c.orig
++++ sys/netinet/cc/cc_cubic.c
+@@ -88,8 +88,6 @@
+ 	unsigned long	max_cwnd;
+ 	/* cwnd at the previous congestion event. */
+ 	unsigned long	prev_max_cwnd;
+-	/* Cached value for t_maxseg when K was computed */
+-	uint32_t        k_maxseg;
+ 	/* Number of congestion events. */
+ 	uint32_t	num_cong_events;
+ 	/* Minimum observed rtt in ticks. */
+@@ -126,9 +124,6 @@
+ 	cubic_data = ccv->cc_data;
+ 	cubic_record_rtt(ccv);
+ 
+-	if (ccv->flags & CCF_MAX_CWND)
+-		return;
+-
+ 	/*
+ 	 * Regular ACK and we're not in cong/fast recovery and we're cwnd
+ 	 * limited and we're either not doing ABC or are slow starting or are
+@@ -156,12 +151,6 @@
+ 			    cubic_data->mean_rtt_ticks, cubic_data->max_cwnd,
+ 			    CCV(ccv, t_maxseg));
+ 
+-			if (ccv->flags & CCF_CHG_MAX_CWND || cubic_data->k_maxseg != CCV(ccv, t_maxseg)) {
+-				cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
+-				cubic_data->k_maxseg = CCV(ccv, t_maxseg);
+-				ccv->flags &= ~(CCF_MAX_CWND|CCF_CHG_MAX_CWND);
+-			}
+-
+ 			w_cubic_next = cubic_cwnd(ticks_since_cong +
+ 			    cubic_data->mean_rtt_ticks, cubic_data->max_cwnd,
+ 			    CCV(ccv, t_maxseg), cubic_data->K);
+@@ -173,18 +162,13 @@
+ 				 * TCP-friendly region, follow tf
+ 				 * cwnd growth.
+ 				 */
+-				CCV(ccv, snd_cwnd) = ulmin(w_tf, TCP_MAXWIN << CCV(ccv, snd_scale));
++				CCV(ccv, snd_cwnd) = w_tf;
+ 
+ 			else if (CCV(ccv, snd_cwnd) < w_cubic_next) {
+ 				/*
+ 				 * Concave or convex region, follow CUBIC
+ 				 * cwnd growth.
+ 				 */
+-				if (w_cubic_next >= TCP_MAXWIN << CCV(ccv, snd_scale)) {
+-					w_cubic_next = TCP_MAXWIN << CCV(ccv, snd_scale);
+-					ccv->flags |= CCF_MAX_CWND;
+-				}
+-				w_cubic_next = ulmin(w_cubic_next, TCP_MAXWIN << CCV(ccv, snd_scale));
+ 				if (V_tcp_do_rfc3465)
+ 					CCV(ccv, snd_cwnd) = w_cubic_next;
+ 				else
+@@ -202,10 +186,8 @@
+ 			 * max_cwnd.
+ 			 */
+ 			if (cubic_data->num_cong_events == 0 &&
+-			    cubic_data->max_cwnd < CCV(ccv, snd_cwnd)) {
++			    cubic_data->max_cwnd < CCV(ccv, snd_cwnd))
+ 				cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+-				ccv->flags |= CCF_CHG_MAX_CWND;
+-			}
+ 		}
+ 	}
+ }
+@@ -254,7 +236,6 @@
+ 				cubic_data->num_cong_events++;
+ 				cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
+ 				cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+-				ccv->flags |= CCF_CHG_MAX_CWND;
+ 			}
+ 			ENTER_RECOVERY(CCV(ccv, t_flags));
+ 		}
+@@ -267,8 +248,6 @@
+ 			cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
+ 			cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+ 			cubic_data->t_last_cong = ticks;
+-			ccv->flags |= CCF_CHG_MAX_CWND;
+-			ccv->flags &= ~CCF_MAX_CWND;
+ 			CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
+ 			ENTER_CONGRECOVERY(CCV(ccv, t_flags));
+ 		}
+@@ -285,7 +264,6 @@
+ 		if (CCV(ccv, t_rxtshift) >= 2) {
+ 			cubic_data->num_cong_events++;
+ 			cubic_data->t_last_cong = ticks;
+-			ccv->flags &= ~CCF_MAX_CWND;
+ 		}
+ 		break;
+ 	}
+@@ -304,7 +282,6 @@
+ 	 * get used.
+ 	 */
+ 	cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+-	ccv->flags |= CCF_CHG_MAX_CWND;
+ }
+ 
+ static int
+@@ -329,11 +306,9 @@
+ 	pipe = 0;
+ 
+ 	/* Fast convergence heuristic. */
+-	if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd) {
++	if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd)
+ 		cubic_data->max_cwnd = (cubic_data->max_cwnd * CUBIC_FC_FACTOR)
+ 		    >> CUBIC_SHIFT;
+-		ccv->flags |= CCF_CHG_MAX_CWND;
+-	}
+ 
+ 	if (IN_FASTRECOVERY(CCV(ccv, t_flags))) {
+ 		/*
+@@ -356,7 +331,6 @@
+ 			    cubic_data->max_cwnd) >> CUBIC_SHIFT));
+ 	}
+ 	cubic_data->t_last_cong = ticks;
+-	ccv->flags &= ~CCF_MAX_CWND;
+ 
+ 	/* Calculate the average RTT between congestion epochs. */
+ 	if (cubic_data->epoch_ack_count > 0 &&
+@@ -367,6 +341,7 @@
+ 
+ 	cubic_data->epoch_ack_count = 0;
+ 	cubic_data->sum_rtt_ticks = 0;
++	cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg));
+ }
+ 
+ /*
+--- sys/netinet/cc/cc_cubic.h.orig
++++ sys/netinet/cc/cc_cubic.h
+@@ -41,8 +41,6 @@
+ #ifndef _NETINET_CC_CUBIC_H_
+ #define _NETINET_CC_CUBIC_H_
+ 
+-#include <sys/limits.h>
+-
+ /* Number of bits of precision for fixed point math calcs. */
+ #define	CUBIC_SHIFT		8
+ 
+@@ -163,6 +161,8 @@
+ /*
+  * Compute the new cwnd value using an implementation of eqn 1 from the I-D.
+  * Thanks to Kip Macy for help debugging this function.
++ *
++ * XXXLAS: Characterise bounds for overflow.
+  */
+ static __inline unsigned long
+ cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss, int64_t K)
+@@ -174,15 +174,6 @@
+ 	/* t - K, with CUBIC_SHIFT worth of precision. */
+ 	cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz;
+ 
+-	/* moved this calculation up because it cannot overflow or underflow */
+-	cwnd *= CUBIC_C_FACTOR * smss;
+-
+-	if (cwnd > 2097151) /* 2^21 cubed is long max */
+-		return INT_MAX;
+-
+-	if (cwnd < -2097152) /* -2^21 cubed is long min */
+-		return smss;
+-
+ 	/* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */
+ 	cwnd *= (cwnd * cwnd);
+ 
+@@ -191,17 +182,8 @@
+ 	 * The down shift by CUBIC_SHIFT_4 is because cwnd has 4 lots of
+ 	 * CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above,
+ 	 * and an extra from multiplying through by CUBIC_C_FACTOR.
+-	 *
+-	 * The original formula was this:
+-	 * cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;
+-         *
+-         * CUBIC_C_FACTOR and smss factors were moved up to an earlier
+-	 * calculation to simplify overflow and underflow detection.
+ 	 */
+-	cwnd = (cwnd >> CUBIC_SHIFT_4) + wmax;
+-
+-	if (cwnd < 0)
+-		return 1;
++	cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;
+ 
+ 	return ((unsigned long)cwnd);
+ }
diff --git a/share/security/patches/EN-19:01/cc_cubic.patch.asc b/share/security/patches/EN-19:01/cc_cubic.patch.asc
new file mode 100644
index 0000000000..990bff2a54
--- /dev/null
+++ b/share/security/patches/EN-19:01/cc_cubic.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RhZfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cK6Bw/+NJXfzNxz2c9hS4RgZSeDZxtqPEC6ZG5aKN2vc7RzwYsGgv5f4VzuU40A
+MsRNRmbDjoQYj9zkBKOYUWaIX6ZffOjUwc7DZ1Us4ykXRxlB2Ys4R98z5lY6mQDA
+hcTnCPvKTMChcXO3hQ77W3bUPk+p5+XvcDhks8K8N5/Xixj1xoy5J8dmbGvQ9i/R
+JZa2loacsPab/c2Fr/6L7DyHU3bbXIh+27HknCUOyK0dekbZ8g0oP+u/qb4VX/7s
+BkSbIkLUNq3dBkb0vOAoTry/M2kKpU8Dz/SITuW4bSJqfvNWN2hiT7YTQaNg+E0J
+VaaKHhpGO5TrYDnYRfmJyrAiobROEbpoGXg9TvfZ9VLk0sGOPcBN598DNJLkiZCa
+dzMrimOOcgeeyPhvG0Mq4ZGBkYgqj88jb29bwJbkCLvjTfaL3kPeKxky1bylgEmR
+Vevzqlp9IhrnSW21u0Kd8ZWuXka8ni+uKe2B24FyOZntziODWOi/rFAE7DV21y1V
+gZsX2v9kwr/M2ApFpAhtEnF3JHX0sl5J8mF9Wnv0CdJP3fTpC9M0byZsCc2qy84g
+5f6KPu57CgvuHG/YRKLDxG7tt1jXYi/LFsR7iGbbCCbthx5pImQrYfKMOdSR81s+
+Iwa8j657nxF+YjM+aq8l7E3g1uonJ2aWT95WFssUnv2ww+O14fw=
+=4RIV
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:02/tcp.patch b/share/security/patches/EN-19:02/tcp.patch
new file mode 100644
index 0000000000..2dc3a3381d
--- /dev/null
+++ b/share/security/patches/EN-19:02/tcp.patch
@@ -0,0 +1,56 @@
+--- sys/netinet/tcp_reass.c.orig
++++ sys/netinet/tcp_reass.c
+@@ -579,7 +579,8 @@
+ 	 */
+ 	lenofoh = tcp_reass_overhead_of_chain(m, &mlast);
+ 	sb = &tp->t_inpcb->inp_socket->so_rcv;
+-	if ((sb->sb_mbcnt + tp->t_segqmbuflen + lenofoh) > sb->sb_mbmax) {
++	if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
++	    (sb->sb_mbcnt + tp->t_segqmbuflen + lenofoh) > sb->sb_mbmax) {
+ 		/* No room */
+ 		TCPSTAT_INC(tcps_rcvreassfull);
+ #ifdef TCP_REASS_COUNTERS
+@@ -588,6 +589,11 @@
+ #ifdef TCP_REASS_LOGGING
+ 		tcp_log_reassm(tp, NULL, NULL, th->th_seq, lenofoh, TCP_R_LOG_LIMIT_REACHED, 0);
+ #endif
++		if ((s = tcp_log_addrs(&tp->t_inpcb->inp_inc, th, NULL, NULL))) {
++			log(LOG_DEBUG, "%s; %s: mbuf count limit reached, "
++			    "segment dropped\n", s, __func__);
++			free(s, M_TCPLOG);
++		}
+ 		m_freem(m);
+ 		*tlenp = 0;
+ #ifdef TCP_REASS_LOGGING
+@@ -936,6 +942,20 @@
+ 	 * is understood.
+ 	 */
+ new_entry:
++	if (th->th_seq == tp->rcv_nxt && TCPS_HAVEESTABLISHED(tp->t_state)) {
++		tp->rcv_nxt += *tlenp;
++		flags = th->th_flags & TH_FIN;
++		TCPSTAT_INC(tcps_rcvoopack);
++		TCPSTAT_ADD(tcps_rcvoobyte, *tlenp);
++		SOCKBUF_LOCK(&so->so_rcv);
++		if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
++			m_freem(m);
++		} else {
++			sbappendstream_locked(&so->so_rcv, m, 0);
++		}
++		sorwakeup_locked(so);
++		return (flags);
++	}
+ 	if (tcp_new_limits) {
+ 		if ((tp->t_segqlen > tcp_reass_queue_guard) &&
+ 		    (*tlenp < MSIZE)) {
+@@ -960,9 +980,7 @@
+ 			return (0);
+ 		}
+ 	} else {
+-
+-		if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) &&
+-		    tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1,
++		if (tp->t_segqlen >= min((so->so_rcv.sb_hiwat / tp->t_maxseg) + 1,
+ 					 tcp_reass_maxqueuelen)) {
+ 			TCPSTAT_INC(tcps_rcvreassfull);
+ 			*tlenp = 0;
diff --git a/share/security/patches/EN-19:02/tcp.patch.asc b/share/security/patches/EN-19:02/tcp.patch.asc
new file mode 100644
index 0000000000..c93a17a849
--- /dev/null
+++ b/share/security/patches/EN-19:02/tcp.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RhxfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cIsjBAAiM9K9Y/ci+sVsH0HrunEbdJT5dI4oabI6Z7zV7X2F5OZobC0neXYCpqH
+sknU/phwdWTmSdLlqxI37At2rQPRFnnAF0sfyByJEmnrNq3CPg/cFabvuNWfetPh
+wpHQc7XUJAz58Lk5o382Dn4POZP+aBmo1e6ULHIXCcgR8xHvGAtQoCLJFh9VXKZx
+tSP+PiwCfHXjIF1J+bEPhv6IO3H59COb5daj1qhTbUnkCmacPBDCFzrSqqbUPOru
+MAvXxcUP3mhPDrIx5eDUNo5C1t54PF6fPzBj8Pq+SUKXrHI1PYHxw2yL+y0vn7vT
+TImWde+rRdDwzab2mt/IP2WaRnC5wVNS+QHZc9M+QB+ujAx8e278uK/eiJwKkm59
+MShtZ46YB96aoZuLYibk+i53jW7OOJbCH9xwFXvZb2n3ObBfJcqig4aXtvug7BOr
+v/90s6Q72jKpJUopgzFut6E2XtJ6ImAvq8qDxo0qLix5vASu57tst/5vyfj4dt79
+AJ05x20KKKKhaNzpnwyOWW4/egeElJPLHg8WsWzwtsRW1ZMWBRIqAzS+dLlDNod9
+ywSbOYb0FMmYe0rtv1gbm5wWjAQ8QYEe/8JoD7y5O04mUVmxmubeYYQ2vAxtxDPs
+ODiJtLdALWkPidb8ynn4r5LBYDjQRvni1+3j2E+nCh9Z08nHzzs=
+=KVpY
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:03/sqlite-11.patch b/share/security/patches/EN-19:03/sqlite-11.patch
new file mode 100644
index 0000000000..774a894939
--- /dev/null
+++ b/share/security/patches/EN-19:03/sqlite-11.patch
@@ -0,0 +1,76146 @@
+--- contrib/sqlite3/Makefile.am.orig
++++ contrib/sqlite3/Makefile.am
+@@ -1,6 +1,5 @@
+ 
+-AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
+-
++AM_CFLAGS = @BUILD_CFLAGS@ 
+ lib_LTLIBRARIES = libsqlite3.la
+ libsqlite3_la_SOURCES = sqlite3.c
+ libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
+@@ -10,11 +9,11 @@
+ EXTRA_sqlite3_SOURCES = sqlite3.c
+ sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
+ sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
+-sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
++sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
+ 
+ include_HEADERS = sqlite3.h sqlite3ext.h
+ 
+-EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
++EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
+ pkgconfigdir = ${libdir}/pkgconfig
+ pkgconfig_DATA = sqlite3.pc
+ 
+--- contrib/sqlite3/Makefile.fallback.orig
++++ contrib/sqlite3/Makefile.fallback
+@@ -0,0 +1,19 @@
++#!/usr/bin/make
++#
++# If the configure script does not work, then this Makefile is available
++# as a backup.  Manually configure the variables below.
++#
++# Note:  This makefile works out-of-the-box on MacOS 10.2 (Jaguar)
++#
++CC = gcc
++CFLAGS = -O0 -I.
++LIBS = -lz
++COPTS += -D_BSD_SOURCE
++COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0
++COPTS += -DSQLITE_THREADSAFE=0
++COPTS += -DSQLITE_OMIT_LOAD_EXTENSION
++COPTS += -DSQLITE_WITHOUT_ZONEMALLOC
++COPTS += -DSQLITE_ENABLE_RTREE
++
++sqlite3:	shell.c sqlite3.c
++	$(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS)
+--- contrib/sqlite3/Makefile.in.orig
++++ contrib/sqlite3/Makefile.in
+@@ -260,7 +260,6 @@
+ DLLTOOL = @DLLTOOL@
+ DSYMUTIL = @DSYMUTIL@
+ DUMPBIN = @DUMPBIN@
+-DYNAMIC_EXTENSION_FLAGS = @DYNAMIC_EXTENSION_FLAGS@
+ ECHO_C = @ECHO_C@
+ ECHO_N = @ECHO_N@
+ ECHO_T = @ECHO_T@
+@@ -268,7 +267,6 @@
+ EXEEXT = @EXEEXT@
+ EXTRA_SHELL_OBJ = @EXTRA_SHELL_OBJ@
+ FGREP = @FGREP@
+-FTS5_FLAGS = @FTS5_FLAGS@
+ GREP = @GREP@
+ INSTALL = @INSTALL@
+ INSTALL_DATA = @INSTALL_DATA@
+@@ -275,7 +273,6 @@
+ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+-JSON1_FLAGS = @JSON1_FLAGS@
+ LD = @LD@
+ LDFLAGS = @LDFLAGS@
+ LIBOBJS = @LIBOBJS@
+@@ -305,11 +302,10 @@
+ RANLIB = @RANLIB@
+ READLINE_LIBS = @READLINE_LIBS@
+ SED = @SED@
+-SESSION_FLAGS = @SESSION_FLAGS@
+ SET_MAKE = @SET_MAKE@
+ SHELL = @SHELL@
++SHELL_CFLAGS = @SHELL_CFLAGS@
+ STRIP = @STRIP@
+-THREADSAFE_FLAGS = @THREADSAFE_FLAGS@
+ VERSION = @VERSION@
+ abs_builddir = @abs_builddir@
+ abs_srcdir = @abs_srcdir@
+@@ -363,7 +359,7 @@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
++AM_CFLAGS = @BUILD_CFLAGS@ 
+ lib_LTLIBRARIES = libsqlite3.la
+ libsqlite3_la_SOURCES = sqlite3.c
+ libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
+@@ -371,9 +367,9 @@
+ EXTRA_sqlite3_SOURCES = sqlite3.c
+ sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
+ sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
+-sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
++sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
+ include_HEADERS = sqlite3.h sqlite3ext.h
+-EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
++EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
+ pkgconfigdir = ${libdir}/pkgconfig
+ pkgconfig_DATA = sqlite3.pc
+ man_MANS = sqlite3.1
+--- contrib/sqlite3/Makefile.msc.orig
++++ contrib/sqlite3/Makefile.msc
+@@ -277,6 +277,12 @@
+ !IF $(MINIMAL_AMALGAMATION)==0
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
+ !ENDIF
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
+ !ENDIF
+@@ -561,6 +567,7 @@
+ !ENDIF
+ !ENDIF
+ 
++
+ # This is the core library that the shell executable should link with.
+ #
+ !IFNDEF SHELL_CORE_LIB
+@@ -808,7 +815,7 @@
+ # If requested, link to the RPCRT4 library.
+ #
+ !IF $(USE_RPCRT4_LIB)!=0
+-LTLINK = $(LTLINK) rpcrt4.lib
++LTLIBS = $(LTLIBS) rpcrt4.lib
+ !ENDIF
+ 
+ # If a platform was set, force the linker to target that.
+@@ -927,7 +934,9 @@
+ # when the shell is not being dynamically linked.
+ #
+ !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
+-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
+ !ENDIF
+ 
+ 
+@@ -934,8 +943,16 @@
+ # This is the default Makefile target.  The objects listed here
+ # are what get build when you type just "make" with no arguments.
+ #
+-all:	dll shell
++core:	dll shell
+ 
++# Targets that require the Tcl library.
++#
++tcl:	$(ALL_TCL_TARGETS)
++
++# This Makefile target builds all of the standard binaries.
++#
++all:	core tcl
++
+ # Dynamic link library section.
+ #
+ dll:	$(SQLITE3DLL)
+@@ -954,11 +971,11 @@
+ sqlite3.def:	Replace.exe $(LIBOBJ)
+ 	echo EXPORTS > sqlite3.def
+ 	dumpbin /all $(LIBOBJ) \
+-		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
++		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
+ 		| sort >> sqlite3.def
+ 
+-$(SQLITE3EXE):	$(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
+-	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
++$(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
++	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \
+ 		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
+ 
+ 
+@@ -973,7 +990,7 @@
+ !IF $(USE_RC)!=0
+ _HASHCHAR=^#
+ !IF ![echo !IFNDEF VERSION > rcver.vc] && \
+-    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
++    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
+     ![echo !ENDIF >> rcver.vc]
+ !INCLUDE rcver.vc
+ !ENDIF
+--- contrib/sqlite3/configure.orig
++++ contrib/sqlite3/configure
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.69 for sqlite 3.20.0.
++# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
+ #
+ # Report bugs to <http://www.sqlite.org>.
+ #
+@@ -590,8 +590,8 @@
+ # Identity of this package.
+ PACKAGE_NAME='sqlite'
+ PACKAGE_TARNAME='sqlite'
+-PACKAGE_VERSION='3.20.0'
+-PACKAGE_STRING='sqlite 3.20.0'
++PACKAGE_VERSION='3.26.0'
++PACKAGE_STRING='sqlite 3.26.0'
+ PACKAGE_BUGREPORT='http://www.sqlite.org'
+ PACKAGE_URL=''
+ 
+@@ -636,12 +636,8 @@
+ am__EXEEXT_TRUE
+ LTLIBOBJS
+ LIBOBJS
++SHELL_CFLAGS
+ EXTRA_SHELL_OBJ
+-SESSION_FLAGS
+-JSON1_FLAGS
+-FTS5_FLAGS
+-DYNAMIC_EXTENSION_FLAGS
+-THREADSAFE_FLAGS
+ READLINE_LIBS
+ BUILD_CFLAGS
+ CPP
+@@ -775,9 +771,13 @@
+ enable_readline
+ enable_threadsafe
+ enable_dynamic_extensions
++enable_fts4
++enable_fts3
+ enable_fts5
+ enable_json1
++enable_rtree
+ enable_session
++enable_debug
+ enable_static_shell
+ '
+       ac_precious_vars='build_alias
+@@ -1330,7 +1330,7 @@
+   # Omit some internal or obsolete options to make the list less imposing.
+   # This message is too long to be a string in the A/UX 3.1 sh.
+   cat <<_ACEOF
+-\`configure' configures sqlite 3.20.0 to adapt to many kinds of systems.
++\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
+ 
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+ 
+@@ -1400,7 +1400,7 @@
+ 
+ if test -n "$ac_init_help"; then
+   case $ac_init_help in
+-     short | recursive ) echo "Configuration of sqlite 3.20.0:";;
++     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
+    esac
+   cat <<\_ACEOF
+ 
+@@ -1425,9 +1425,13 @@
+   --enable-threadsafe     build a thread-safe library [default=yes]
+   --enable-dynamic-extensions
+                           support loadable extensions [default=yes]
+-  --enable-fts5           include fts5 support [default=no]
+-  --enable-json1          include json1 support [default=no]
++  --enable-fts4           include fts4 support [default=yes]
++  --enable-fts3           include fts3 support [default=no]
++  --enable-fts5           include fts5 support [default=yes]
++  --enable-json1          include json1 support [default=yes]
++  --enable-rtree          include rtree support [default=yes]
+   --enable-session        enable the session extension [default=no]
++  --enable-debug          build with debugging features enabled [default=no]
+   --enable-static-shell   statically link libsqlite3 into shell tool
+                           [default=yes]
+ 
+@@ -1521,7 +1525,7 @@
+ test -n "$ac_init_help" && exit $ac_status
+ if $ac_init_version; then
+   cat <<\_ACEOF
+-sqlite configure 3.20.0
++sqlite configure 3.26.0
+ generated by GNU Autoconf 2.69
+ 
+ Copyright (C) 2012 Free Software Foundation, Inc.
+@@ -1936,7 +1940,7 @@
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+ 
+-It was created by sqlite $as_me 3.20.0, which was
++It was created by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   $ $0 $@
+@@ -2285,12 +2289,8 @@
+ 
+ 
+ 
+-
+-# Use automake.
+-am__api_version='1.15'
+-
+ ac_aux_dir=
+-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
++for ac_dir in . "$srcdir"/.; do
+   if test -f "$ac_dir/install-sh"; then
+     ac_aux_dir=$ac_dir
+     ac_install_sh="$ac_aux_dir/install-sh -c"
+@@ -2306,7 +2306,7 @@
+   fi
+ done
+ if test -z "$ac_aux_dir"; then
+-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
++  as_fn_error $? "cannot find install-sh, install.sh, or shtool in . \"$srcdir\"/." "$LINENO" 5
+ fi
+ 
+ # These three variables are undocumented and unsupported,
+@@ -2318,6 +2318,10 @@
+ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+ 
+ 
++
++# Use automake.
++am__api_version='1.15'
++
+ # Find a good install program.  We prefer a C program (faster),
+ # so one script is as good as another.  But avoid the broken or
+ # incompatible versions:
+@@ -2802,7 +2806,7 @@
+ 
+ # Define the identity of the package.
+  PACKAGE='sqlite'
+- VERSION='3.20.0'
++ VERSION='3.26.0'
+ 
+ 
+ cat >>confdefs.h <<_ACEOF
+@@ -13038,6 +13042,7 @@
+ 
+ ac_config_files="$ac_config_files Makefile sqlite3.pc"
+ 
++BUILD_CFLAGS=
+ 
+ 
+ #-------------------------------------------------------------------------
+@@ -13302,9 +13307,8 @@
+   enable_threadsafe=yes
+ fi
+ 
+-THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
+ if test x"$enable_threadsafe" != "xno"; then
+-  THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
++  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5
+ $as_echo_n "checking for library containing pthread_create... " >&6; }
+ if ${ac_cv_search_pthread_create+:} false; then :
+@@ -13418,7 +13422,6 @@
+ fi
+ 
+ fi
+-
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -13489,16 +13492,43 @@
+ fi
+ 
+ else
+-  DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to support dynamic extensions" >&5
+ $as_echo_n "checking for whether to support dynamic extensions... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dynamic_extensions" >&5
+ $as_echo "$enable_dynamic_extensions" >&6; }
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-fts4
++#
++# Check whether --enable-fts4 was given.
++if test "${enable_fts4+set}" = set; then :
++  enableval=$enable_fts4;
++else
++  enable_fts4=yes
++fi
+ 
++if test x"$enable_fts4" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
++#   --enable-fts3
++#
++# Check whether --enable-fts3 was given.
++if test "${enable_fts3+set}" = set; then :
++  enableval=$enable_fts3;
++fi
++
++if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-fts5
+ #
+ # Check whether --enable-fts5 was given.
+@@ -13505,7 +13535,7 @@
+ if test "${enable_fts5+set}" = set; then :
+   enableval=$enable_fts5;
+ else
+-  enable_fts5=no
++  enable_fts5=yes
+ fi
+ 
+ if test x"$enable_fts5" = "xyes"; then
+@@ -13565,9 +13595,8 @@
+ 
+ fi
+ 
+-  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+ fi
+-
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -13577,32 +13606,57 @@
+ if test "${enable_json1+set}" = set; then :
+   enableval=$enable_json1;
+ else
+-  enable_json1=no
++  enable_json1=yes
+ fi
+ 
+ if test x"$enable_json1" = "xyes"; then
+-  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ fi
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-rtree
++#
++# Check whether --enable-rtree was given.
++if test "${enable_rtree+set}" = set; then :
++  enableval=$enable_rtree;
++else
++  enable_rtree=yes
++fi
+ 
++if test x"$enable_rtree" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-session
+ #
+ # Check whether --enable-session was given.
+ if test "${enable_session+set}" = set; then :
+   enableval=$enable_session;
+-else
+-  enable_session=no
+ fi
+ 
+ if test x"$enable_session" = "xyes"; then
+-  SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ fi
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-debug
++#
++# Check whether --enable-debug was given.
++if test "${enable_debug+set}" = set; then :
++  enableval=$enable_debug;
++fi
+ 
++if test x"$enable_debug" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
++  CFLAGS="-g -O0"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-static-shell
+ #
+ # Check whether --enable-static-shell was given.
+@@ -13631,7 +13685,136 @@
+ fi
+ done
+ 
++for ac_header in zlib.h
++do :
++  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
++if test "x$ac_cv_header_zlib_h" = xyes; then :
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_ZLIB_H 1
++_ACEOF
+ 
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5
++$as_echo_n "checking for library containing deflate... " >&6; }
++if ${ac_cv_search_deflate+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char deflate ();
++int
++main ()
++{
++return deflate ();
++  ;
++  return 0;
++}
++_ACEOF
++for ac_lib in '' z; do
++  if test -z "$ac_lib"; then
++    ac_res="none required"
++  else
++    ac_res=-l$ac_lib
++    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
++  fi
++  if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_search_deflate=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext
++  if ${ac_cv_search_deflate+:} false; then :
++  break
++fi
++done
++if ${ac_cv_search_deflate+:} false; then :
++
++else
++  ac_cv_search_deflate=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5
++$as_echo "$ac_cv_search_deflate" >&6; }
++ac_res=$ac_cv_search_deflate
++if test "$ac_res" != no; then :
++  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"
++fi
++
++
++fi
++
++done
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing system" >&5
++$as_echo_n "checking for library containing system... " >&6; }
++if ${ac_cv_search_system+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char system ();
++int
++main ()
++{
++return system ();
++  ;
++  return 0;
++}
++_ACEOF
++for ac_lib in '' ; do
++  if test -z "$ac_lib"; then
++    ac_res="none required"
++  else
++    ac_res=-l$ac_lib
++    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
++  fi
++  if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_search_system=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext
++  if ${ac_cv_search_system+:} false; then :
++  break
++fi
++done
++if ${ac_cv_search_system+:} false; then :
++
++else
++  ac_cv_search_system=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_system" >&5
++$as_echo "$ac_cv_search_system" >&6; }
++ac_res=$ac_cv_search_system
++if test "$ac_res" != no; then :
++  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++else
++  SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"
++fi
++
++
++
+ #-----------------------------------------------------------------------
+ # UPDATE: Maybe it's better if users just set CFLAGS before invoking
+ # configure. This option doesn't really add much...
+@@ -14227,7 +14410,7 @@
+ # report actual input values of CONFIG_FILES etc. instead of their
+ # values after options handling.
+ ac_log="
+-This file was extended by sqlite $as_me 3.20.0, which was
++This file was extended by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   CONFIG_FILES    = $CONFIG_FILES
+@@ -14284,7 +14467,7 @@
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ ac_cs_version="\\
+-sqlite config.status 3.20.0
++sqlite config.status 3.26.0
+ configured by $0, generated by GNU Autoconf 2.69,
+   with options \\"\$ac_cs_config\\"
+ 
+--- contrib/sqlite3/configure.ac.orig
++++ contrib/sqlite3/configure.ac
+@@ -10,8 +10,9 @@
+ #
+ 
+ AC_PREREQ(2.61)
+-AC_INIT(sqlite, 3.20.0, http://www.sqlite.org)
++AC_INIT(sqlite, 3.26.0, http://www.sqlite.org)
+ AC_CONFIG_SRCDIR([sqlite3.c])
++AC_CONFIG_AUX_DIR([.])
+ 
+ # Use automake.
+ AM_INIT_AUTOMAKE([foreign])
+@@ -28,6 +29,7 @@
+ AC_FUNC_STRERROR_R
+ 
+ AC_CONFIG_FILES([Makefile sqlite3.pc])
++BUILD_CFLAGS=
+ AC_SUBST(BUILD_CFLAGS)
+ 
+ #-------------------------------------------------------------------------
+@@ -85,13 +87,11 @@
+ AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
+   [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
+   [], [enable_threadsafe=yes])
+-THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
+ if test x"$enable_threadsafe" != "xno"; then
+-  THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
++  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
+   AC_SEARCH_LIBS(pthread_create, pthread)
+   AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
+ fi
+-AC_SUBST(THREADSAFE_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -103,24 +103,44 @@
+ if test x"$enable_dynamic_extensions" != "xno"; then
+   AC_SEARCH_LIBS(dlopen, dl)
+ else
+-  DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
+ fi
+ AC_MSG_CHECKING([for whether to support dynamic extensions])
+ AC_MSG_RESULT($enable_dynamic_extensions)
+-AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-fts4
++#
++AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
++  [--enable-fts4], [include fts4 support [default=yes]])], 
++  [], [enable_fts4=yes])
++if test x"$enable_fts4" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
++#   --enable-fts3
++#
++AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
++  [--enable-fts3], [include fts3 support [default=no]])], 
++  [], [])
++if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-fts5
+ #
+ AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
+-  [--enable-fts5], [include fts5 support [default=no]])], 
+-  [], [enable_fts5=no])
++  [--enable-fts5], [include fts5 support [default=yes]])], 
++  [], [enable_fts5=yes])
+ if test x"$enable_fts5" = "xyes"; then
+   AC_SEARCH_LIBS(log, m)
+-  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+ fi
+-AC_SUBST(FTS5_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -127,27 +147,48 @@
+ #   --enable-json1
+ #
+ AC_ARG_ENABLE(json1, [AS_HELP_STRING(
+-  [--enable-json1], [include json1 support [default=no]])], 
+-  [], [enable_json1=no])
++  [--enable-json1], [include json1 support [default=yes]])], 
++  [],[enable_json1=yes])
+ if test x"$enable_json1" = "xyes"; then
+-  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ fi
+-AC_SUBST(JSON1_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-rtree
++#
++AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
++  [--enable-rtree], [include rtree support [default=yes]])], 
++  [], [enable_rtree=yes])
++if test x"$enable_rtree" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-session
+ #
+ AC_ARG_ENABLE(session, [AS_HELP_STRING(
+   [--enable-session], [enable the session extension [default=no]])], 
+-  [], [enable_session=no])
++  [], [])
+ if test x"$enable_session" = "xyes"; then
+-  SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ fi
+-AC_SUBST(SESSION_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-debug
++#
++AC_ARG_ENABLE(debug, [AS_HELP_STRING(
++  [--enable-debug], [build with debugging features enabled [default=no]])], 
++  [], [])
++if test x"$enable_debug" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
++  CFLAGS="-g -O0"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-static-shell
+ #
+ AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
+@@ -163,7 +204,13 @@
+ #-----------------------------------------------------------------------
+ 
+ AC_CHECK_FUNCS(posix_fallocate)
++AC_CHECK_HEADERS(zlib.h,[
++  AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"])
++])
+ 
++AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"])
++AC_SUBST(SHELL_CFLAGS)
++
+ #-----------------------------------------------------------------------
+ # UPDATE: Maybe it's better if users just set CFLAGS before invoking
+ # configure. This option doesn't really add much...
+--- contrib/sqlite3/shell.c.orig
++++ contrib/sqlite3/shell.c
+@@ -79,6 +79,9 @@
+ #include <stdio.h>
+ #include <assert.h>
+ #include "sqlite3.h"
++typedef sqlite3_int64 i64;
++typedef sqlite3_uint64 u64;
++typedef unsigned char u8;
+ #if SQLITE_USER_AUTHENTICATION
+ # include "sqlite3userauth.h"
+ #endif
+@@ -90,9 +93,22 @@
+ # if !defined(__RTP__) && !defined(_WRS_KERNEL)
+ #  include <pwd.h>
+ # endif
++#endif
++#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
+ # include <unistd.h>
+-# include <sys/types.h>
++# include <dirent.h>
++# define GETPID getpid
++# if defined(__MINGW32__)
++#  define DIRENT dirent
++#  ifndef S_ISLNK
++#   define S_ISLNK(mode) (0)
++#  endif
++# endif
++#else
++# define GETPID (int)GetCurrentProcessId
+ #endif
++#include <sys/types.h>
++#include <sys/stat.h>
+ 
+ #if HAVE_READLINE
+ # include <readline/readline.h>
+@@ -137,6 +153,9 @@
+ # ifndef access
+ #  define access(f,m) _access((f),(m))
+ # endif
++# ifndef unlink
++#  define unlink _unlink
++# endif
+ # undef popen
+ # define popen _popen
+ # undef pclose
+@@ -358,6 +377,11 @@
+ #define UNUSED_PARAMETER(x) (void)(x)
+ 
+ /*
++** Number of elements in an array
++*/
++#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
++
++/*
+ ** If the following flag is set, then command execution stops
+ ** at an error if we are not interactive.
+ */
+@@ -433,6 +457,12 @@
+ # define raw_printf fprintf
+ #endif
+ 
++/* Indicate out-of-memory and exit. */
++static void shell_out_of_memory(void){
++  raw_printf(stderr,"Error: out of memory\n");
++  exit(1);
++}
++
+ /*
+ ** Write I/O traces to the following stream.
+ */
+@@ -556,7 +586,7 @@
+     if( n+100>nLine ){
+       nLine = nLine*2 + 100;
+       zLine = realloc(zLine, nLine);
+-      if( zLine==0 ) return 0;
++      if( zLine==0 ) shell_out_of_memory();
+     }
+     if( fgets(&zLine[n], nLine - n, in)==0 ){
+       if( n==0 ){
+@@ -583,10 +613,7 @@
+       int nTrans = strlen30(zTrans)+1;
+       if( nTrans>nLine ){
+         zLine = realloc(zLine, nTrans);
+-        if( zLine==0 ){
+-          sqlite3_free(zTrans);
+-          return 0;
+-        }
++        if( zLine==0 ) shell_out_of_memory();
+       }
+       memcpy(zLine, zTrans, nTrans);
+       sqlite3_free(zTrans);
+@@ -629,7 +656,66 @@
+   }
+   return zResult;
+ }
++
++
+ /*
++** Return the value of a hexadecimal digit.  Return -1 if the input
++** is not a hex digit.
++*/
++static int hexDigitValue(char c){
++  if( c>='0' && c<='9' ) return c - '0';
++  if( c>='a' && c<='f' ) return c - 'a' + 10;
++  if( c>='A' && c<='F' ) return c - 'A' + 10;
++  return -1;
++}
++
++/*
++** Interpret zArg as an integer value, possibly with suffixes.
++*/
++static sqlite3_int64 integerValue(const char *zArg){
++  sqlite3_int64 v = 0;
++  static const struct { char *zSuffix; int iMult; } aMult[] = {
++    { "KiB", 1024 },
++    { "MiB", 1024*1024 },
++    { "GiB", 1024*1024*1024 },
++    { "KB",  1000 },
++    { "MB",  1000000 },
++    { "GB",  1000000000 },
++    { "K",   1000 },
++    { "M",   1000000 },
++    { "G",   1000000000 },
++  };
++  int i;
++  int isNeg = 0;
++  if( zArg[0]=='-' ){
++    isNeg = 1;
++    zArg++;
++  }else if( zArg[0]=='+' ){
++    zArg++;
++  }
++  if( zArg[0]=='0' && zArg[1]=='x' ){
++    int x;
++    zArg += 2;
++    while( (x = hexDigitValue(zArg[0]))>=0 ){
++      v = (v<<4) + x;
++      zArg++;
++    }
++  }else{
++    while( IsDigit(zArg[0]) ){
++      v = v*10 + zArg[0] - '0';
++      zArg++;
++    }
++  }
++  for(i=0; i<ArraySize(aMult); i++){
++    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
++      v *= aMult[i].iMult;
++      break;
++    }
++  }
++  return isNeg? -v : v;
++}
++
++/*
+ ** A variable length string to which one can append text.
+ */
+ typedef struct ShellText ShellText;
+@@ -674,10 +760,7 @@
+   if( p->n+len>=p->nAlloc ){
+     p->nAlloc = p->nAlloc*2 + len + 20;
+     p->z = realloc(p->z, p->nAlloc);
+-    if( p->z==0 ){
+-      memset(p, 0, sizeof(*p));
+-      return;
+-    }
++    if( p->z==0 ) shell_out_of_memory();
+   }
+ 
+   if( quote ){
+@@ -706,48 +789,82 @@
+ ** Return '"' if quoting is required.  Return 0 if no quoting is required.
+ */
+ static char quoteChar(const char *zName){
+-  /* All SQLite keywords, in alphabetical order */
+-  static const char *azKeywords[] = {
+-    "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
+-    "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
+-    "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
+-    "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
+-    "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
+-    "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
+-    "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
+-    "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
+-    "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
+-    "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
+-    "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
+-    "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
+-    "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
+-    "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
+-    "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
+-    "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
+-    "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
+-    "WITH", "WITHOUT",
+-  };
+-  int i, lwr, upr, mid, c;
++  int i;
+   if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
+   for(i=0; zName[i]; i++){
+     if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
+   }
+-  lwr = 0;
+-  upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
+-  while( lwr<=upr ){
+-    mid = (lwr+upr)/2;
+-    c = sqlite3_stricmp(azKeywords[mid], zName);
+-    if( c==0 ) return '"';
+-    if( c<0 ){
+-      lwr = mid+1;
+-    }else{
+-      upr = mid-1;
+-    }
++  return sqlite3_keyword_check(zName, i) ? '"' : 0;
++}
++
++/*
++** Construct a fake object name and column list to describe the structure
++** of the view, virtual table, or table valued function zSchema.zName.
++*/
++static char *shellFakeSchema(
++  sqlite3 *db,            /* The database connection containing the vtab */
++  const char *zSchema,    /* Schema of the database holding the vtab */
++  const char *zName       /* The name of the virtual table */
++){
++  sqlite3_stmt *pStmt = 0;
++  char *zSql;
++  ShellText s;
++  char cQuote;
++  char *zDiv = "(";
++  int nRow = 0;
++
++  zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;",
++                         zSchema ? zSchema : "main", zName);
++  sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
++  sqlite3_free(zSql);
++  initText(&s);
++  if( zSchema ){
++    cQuote = quoteChar(zSchema);
++    if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0;
++    appendText(&s, zSchema, cQuote);
++    appendText(&s, ".", 0);
+   }
+-  return 0;
++  cQuote = quoteChar(zName);
++  appendText(&s, zName, cQuote);
++  while( sqlite3_step(pStmt)==SQLITE_ROW ){
++    const char *zCol = (const char*)sqlite3_column_text(pStmt, 1);
++    nRow++;
++    appendText(&s, zDiv, 0);
++    zDiv = ",";
++    cQuote = quoteChar(zCol);
++    appendText(&s, zCol, cQuote);
++  }
++  appendText(&s, ")", 0);
++  sqlite3_finalize(pStmt);
++  if( nRow==0 ){
++    freeText(&s);
++    s.z = 0;
++  }
++  return s.z;
+ }
+ 
+ /*
++** SQL function:  shell_module_schema(X)
++**
++** Return a fake schema for the table-valued function or eponymous virtual
++** table X.
++*/
++static void shellModuleSchema(
++  sqlite3_context *pCtx,
++  int nVal,
++  sqlite3_value **apVal
++){
++  const char *zName = (const char*)sqlite3_value_text(apVal[0]);
++  char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
++  UNUSED_PARAMETER(nVal);
++  if( zFake ){
++    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
++                        -1, sqlite3_free);
++    free(zFake);
++  }
++}
++
++/*
+ ** SQL function:  shell_add_schema(S,X)
+ **
+ ** Add the schema name X to the CREATE statement in S and return the result.
+@@ -782,20 +899,38 @@
+   int i = 0;
+   const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
+   const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
+-  assert( nVal==2 );
++  const char *zName = (const char*)sqlite3_value_text(apVal[2]);
++  sqlite3 *db = sqlite3_context_db_handle(pCtx);
++  UNUSED_PARAMETER(nVal);
+   if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
+     for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
+       int n = strlen30(aPrefix[i]);
+       if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
+-        char cQuote = quoteChar(zSchema);
+-        char *z;
+-        if( cQuote ){
+-         z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
+-        }else{
+-          z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
++        char *z = 0;
++        char *zFake = 0;
++        if( zSchema ){
++          char cQuote = quoteChar(zSchema);
++          if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){
++            z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
++          }else{
++            z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
++          }
+         }
+-        sqlite3_result_text(pCtx, z, -1, sqlite3_free);
+-        return;
++        if( zName
++         && aPrefix[i][0]=='V'
++         && (zFake = shellFakeSchema(db, zSchema, zName))!=0
++        ){
++          if( z==0 ){
++            z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
++          }else{
++            z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
++          }
++          free(zFake);
++        }
++        if( z ){
++          sqlite3_result_text(pCtx, z, -1, sqlite3_free);
++          return;
++        }
+       }
+     }
+   }
+@@ -811,6 +946,364 @@
+ #define SQLITE_EXTENSION_INIT1
+ #define SQLITE_EXTENSION_INIT2(X) (void)(X)
+ 
++#if defined(_WIN32) && defined(_MSC_VER)
++/************************* Begin test_windirent.h ******************/
++/*
++** 2015 November 30
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains declarations for most of the opendir() family of
++** POSIX functions on Win32 using the MSVCRT.
++*/
++
++#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
++#define SQLITE_WINDIRENT_H
++
++/*
++** We need several data types from the Windows SDK header.
++*/
++
++#ifndef WIN32_LEAN_AND_MEAN
++#define WIN32_LEAN_AND_MEAN
++#endif
++
++#include "windows.h"
++
++/*
++** We need several support functions from the SQLite core.
++*/
++
++
++/*
++** We need several things from the ANSI and MSVCRT headers.
++*/
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <io.h>
++#include <limits.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++
++/*
++** We may need several defines that should have been in "sys/stat.h".
++*/
++
++#ifndef S_ISREG
++#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
++#endif
++
++#ifndef S_ISDIR
++#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
++#endif
++
++#ifndef S_ISLNK
++#define S_ISLNK(mode) (0)
++#endif
++
++/*
++** We may need to provide the "mode_t" type.
++*/
++
++#ifndef MODE_T_DEFINED
++  #define MODE_T_DEFINED
++  typedef unsigned short mode_t;
++#endif
++
++/*
++** We may need to provide the "ino_t" type.
++*/
++
++#ifndef INO_T_DEFINED
++  #define INO_T_DEFINED
++  typedef unsigned short ino_t;
++#endif
++
++/*
++** We need to define "NAME_MAX" if it was not present in "limits.h".
++*/
++
++#ifndef NAME_MAX
++#  ifdef FILENAME_MAX
++#    define NAME_MAX (FILENAME_MAX)
++#  else
++#    define NAME_MAX (260)
++#  endif
++#endif
++
++/*
++** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
++*/
++
++#ifndef NULL_INTPTR_T
++#  define NULL_INTPTR_T ((intptr_t)(0))
++#endif
++
++#ifndef BAD_INTPTR_T
++#  define BAD_INTPTR_T ((intptr_t)(-1))
++#endif
++
++/*
++** We need to provide the necessary structures and related types.
++*/
++
++#ifndef DIRENT_DEFINED
++#define DIRENT_DEFINED
++typedef struct DIRENT DIRENT;
++typedef DIRENT *LPDIRENT;
++struct DIRENT {
++  ino_t d_ino;               /* Sequence number, do not use. */
++  unsigned d_attributes;     /* Win32 file attributes. */
++  char d_name[NAME_MAX + 1]; /* Name within the directory. */
++};
++#endif
++
++#ifndef DIR_DEFINED
++#define DIR_DEFINED
++typedef struct DIR DIR;
++typedef DIR *LPDIR;
++struct DIR {
++  intptr_t d_handle; /* Value returned by "_findfirst". */
++  DIRENT d_first;    /* DIRENT constructed based on "_findfirst". */
++  DIRENT d_next;     /* DIRENT constructed based on "_findnext". */
++};
++#endif
++
++/*
++** Provide a macro, for use by the implementation, to determine if a
++** particular directory entry should be skipped over when searching for
++** the next directory entry that should be returned by the readdir() or
++** readdir_r() functions.
++*/
++
++#ifndef is_filtered
++#  define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM))
++#endif
++
++/*
++** Provide the function prototype for the POSIX compatiable getenv()
++** function.  This function is not thread-safe.
++*/
++
++extern const char *windirent_getenv(const char *name);
++
++/*
++** Finally, we can provide the function prototypes for the opendir(),
++** readdir(), readdir_r(), and closedir() POSIX functions.
++*/
++
++extern LPDIR opendir(const char *dirname);
++extern LPDIRENT readdir(LPDIR dirp);
++extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
++extern INT closedir(LPDIR dirp);
++
++#endif /* defined(WIN32) && defined(_MSC_VER) */
++
++/************************* End test_windirent.h ********************/
++/************************* Begin test_windirent.c ******************/
++/*
++** 2015 November 30
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains code to implement most of the opendir() family of
++** POSIX functions on Win32 using the MSVCRT.
++*/
++
++#if defined(_WIN32) && defined(_MSC_VER)
++/* #include "test_windirent.h" */
++
++/*
++** Implementation of the POSIX getenv() function using the Win32 API.
++** This function is not thread-safe.
++*/
++const char *windirent_getenv(
++  const char *name
++){
++  static char value[32768]; /* Maximum length, per MSDN */
++  DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
++  DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
++
++  memset(value, 0, sizeof(value));
++  dwRet = GetEnvironmentVariableA(name, value, dwSize);
++  if( dwRet==0 || dwRet>dwSize ){
++    /*
++    ** The function call to GetEnvironmentVariableA() failed -OR-
++    ** the buffer is not large enough.  Either way, return NULL.
++    */
++    return 0;
++  }else{
++    /*
++    ** The function call to GetEnvironmentVariableA() succeeded
++    ** -AND- the buffer contains the entire value.
++    */
++    return value;
++  }
++}
++
++/*
++** Implementation of the POSIX opendir() function using the MSVCRT.
++*/
++LPDIR opendir(
++  const char *dirname
++){
++  struct _finddata_t data;
++  LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
++  SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
++
++  if( dirp==NULL ) return NULL;
++  memset(dirp, 0, sizeof(DIR));
++
++  /* TODO: Remove this if Unix-style root paths are not used. */
++  if( sqlite3_stricmp(dirname, "/")==0 ){
++    dirname = windirent_getenv("SystemDrive");
++  }
++
++  memset(&data, 0, sizeof(struct _finddata_t));
++  _snprintf(data.name, namesize, "%s\\*", dirname);
++  dirp->d_handle = _findfirst(data.name, &data);
++
++  if( dirp->d_handle==BAD_INTPTR_T ){
++    closedir(dirp);
++    return NULL;
++  }
++
++  /* TODO: Remove this block to allow hidden and/or system files. */
++  if( is_filtered(data) ){
++next:
++
++    memset(&data, 0, sizeof(struct _finddata_t));
++    if( _findnext(dirp->d_handle, &data)==-1 ){
++      closedir(dirp);
++      return NULL;
++    }
++
++    /* TODO: Remove this block to allow hidden and/or system files. */
++    if( is_filtered(data) ) goto next;
++  }
++
++  dirp->d_first.d_attributes = data.attrib;
++  strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
++  dirp->d_first.d_name[NAME_MAX] = '\0';
++
++  return dirp;
++}
++
++/*
++** Implementation of the POSIX readdir() function using the MSVCRT.
++*/
++LPDIRENT readdir(
++  LPDIR dirp
++){
++  struct _finddata_t data;
++
++  if( dirp==NULL ) return NULL;
++
++  if( dirp->d_first.d_ino==0 ){
++    dirp->d_first.d_ino++;
++    dirp->d_next.d_ino++;
++
++    return &dirp->d_first;
++  }
++
++next:
++
++  memset(&data, 0, sizeof(struct _finddata_t));
++  if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
++
++  /* TODO: Remove this block to allow hidden and/or system files. */
++  if( is_filtered(data) ) goto next;
++
++  dirp->d_next.d_ino++;
++  dirp->d_next.d_attributes = data.attrib;
++  strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
++  dirp->d_next.d_name[NAME_MAX] = '\0';
++
++  return &dirp->d_next;
++}
++
++/*
++** Implementation of the POSIX readdir_r() function using the MSVCRT.
++*/
++INT readdir_r(
++  LPDIR dirp,
++  LPDIRENT entry,
++  LPDIRENT *result
++){
++  struct _finddata_t data;
++
++  if( dirp==NULL ) return EBADF;
++
++  if( dirp->d_first.d_ino==0 ){
++    dirp->d_first.d_ino++;
++    dirp->d_next.d_ino++;
++
++    entry->d_ino = dirp->d_first.d_ino;
++    entry->d_attributes = dirp->d_first.d_attributes;
++    strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
++    entry->d_name[NAME_MAX] = '\0';
++
++    *result = entry;
++    return 0;
++  }
++
++next:
++
++  memset(&data, 0, sizeof(struct _finddata_t));
++  if( _findnext(dirp->d_handle, &data)==-1 ){
++    *result = NULL;
++    return ENOENT;
++  }
++
++  /* TODO: Remove this block to allow hidden and/or system files. */
++  if( is_filtered(data) ) goto next;
++
++  entry->d_ino = (ino_t)-1; /* not available */
++  entry->d_attributes = data.attrib;
++  strncpy(entry->d_name, data.name, NAME_MAX);
++  entry->d_name[NAME_MAX] = '\0';
++
++  *result = entry;
++  return 0;
++}
++
++/*
++** Implementation of the POSIX closedir() function using the MSVCRT.
++*/
++INT closedir(
++  LPDIR dirp
++){
++  INT result = 0;
++
++  if( dirp==NULL ) return EINVAL;
++
++  if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
++    result = _findclose(dirp->d_handle);
++  }
++
++  sqlite3_free(dirp);
++  return result;
++}
++
++#endif /* defined(WIN32) && defined(_MSC_VER) */
++
++/************************* End test_windirent.c ********************/
++#define dirent DIRENT
++#endif
+ /************************* Begin ../ext/misc/shathree.c ******************/
+ /*
+ ** 2017-03-08
+@@ -824,7 +1317,7 @@
+ **
+ ******************************************************************************
+ **
+-** This SQLite extension implements a functions that compute SHA1 hashes.
++** This SQLite extension implements functions that compute SHA3 hashes.
+ ** Two SQL functions are implemented:
+ **
+ **     sha3(X,SIZE)
+@@ -844,7 +1337,7 @@
+ #include <assert.h>
+ #include <string.h>
+ #include <stdarg.h>
+-typedef sqlite3_uint64 u64;
++/* typedef sqlite3_uint64 u64; */
+ 
+ /******************************************************************************
+ ** The Hash Engine
+@@ -891,9 +1384,9 @@
+ */
+ static void KeccakF1600Step(SHA3Context *p){
+   int i;
+-  u64 B0, B1, B2, B3, B4;
+-  u64 C0, C1, C2, C3, C4;
+-  u64 D0, D1, D2, D3, D4;
++  u64 b0, b1, b2, b3, b4;
++  u64 c0, c1, c2, c3, c4;
++  u64 d0, d1, d2, d3, d4;
+   static const u64 RC[] = {
+     0x0000000000000001ULL,  0x0000000000008082ULL,
+     0x800000000000808aULL,  0x8000000080008000ULL,
+@@ -908,301 +1401,301 @@
+     0x8000000080008081ULL,  0x8000000000008080ULL,
+     0x0000000080000001ULL,  0x8000000080008008ULL
+   };
+-# define A00 (p->u.s[0])
+-# define A01 (p->u.s[1])
+-# define A02 (p->u.s[2])
+-# define A03 (p->u.s[3])
+-# define A04 (p->u.s[4])
+-# define A10 (p->u.s[5])
+-# define A11 (p->u.s[6])
+-# define A12 (p->u.s[7])
+-# define A13 (p->u.s[8])
+-# define A14 (p->u.s[9])
+-# define A20 (p->u.s[10])
+-# define A21 (p->u.s[11])
+-# define A22 (p->u.s[12])
+-# define A23 (p->u.s[13])
+-# define A24 (p->u.s[14])
+-# define A30 (p->u.s[15])
+-# define A31 (p->u.s[16])
+-# define A32 (p->u.s[17])
+-# define A33 (p->u.s[18])
+-# define A34 (p->u.s[19])
+-# define A40 (p->u.s[20])
+-# define A41 (p->u.s[21])
+-# define A42 (p->u.s[22])
+-# define A43 (p->u.s[23])
+-# define A44 (p->u.s[24])
++# define a00 (p->u.s[0])
++# define a01 (p->u.s[1])
++# define a02 (p->u.s[2])
++# define a03 (p->u.s[3])
++# define a04 (p->u.s[4])
++# define a10 (p->u.s[5])
++# define a11 (p->u.s[6])
++# define a12 (p->u.s[7])
++# define a13 (p->u.s[8])
++# define a14 (p->u.s[9])
++# define a20 (p->u.s[10])
++# define a21 (p->u.s[11])
++# define a22 (p->u.s[12])
++# define a23 (p->u.s[13])
++# define a24 (p->u.s[14])
++# define a30 (p->u.s[15])
++# define a31 (p->u.s[16])
++# define a32 (p->u.s[17])
++# define a33 (p->u.s[18])
++# define a34 (p->u.s[19])
++# define a40 (p->u.s[20])
++# define a41 (p->u.s[21])
++# define a42 (p->u.s[22])
++# define a43 (p->u.s[23])
++# define a44 (p->u.s[24])
+ # define ROL64(a,x) ((a<<x)|(a>>(64-x)))
+ 
+   for(i=0; i<24; i+=4){
+-    C0 = A00^A10^A20^A30^A40;
+-    C1 = A01^A11^A21^A31^A41;
+-    C2 = A02^A12^A22^A32^A42;
+-    C3 = A03^A13^A23^A33^A43;
+-    C4 = A04^A14^A24^A34^A44;
+-    D0 = C4^ROL64(C1, 1);
+-    D1 = C0^ROL64(C2, 1);
+-    D2 = C1^ROL64(C3, 1);
+-    D3 = C2^ROL64(C4, 1);
+-    D4 = C3^ROL64(C0, 1);
++    c0 = a00^a10^a20^a30^a40;
++    c1 = a01^a11^a21^a31^a41;
++    c2 = a02^a12^a22^a32^a42;
++    c3 = a03^a13^a23^a33^a43;
++    c4 = a04^a14^a24^a34^a44;
++    d0 = c4^ROL64(c1, 1);
++    d1 = c0^ROL64(c2, 1);
++    d2 = c1^ROL64(c3, 1);
++    d3 = c2^ROL64(c4, 1);
++    d4 = c3^ROL64(c0, 1);
+ 
+-    B0 = (A00^D0);
+-    B1 = ROL64((A11^D1), 44);
+-    B2 = ROL64((A22^D2), 43);
+-    B3 = ROL64((A33^D3), 21);
+-    B4 = ROL64((A44^D4), 14);
+-    A00 =   B0 ^((~B1)&  B2 );
+-    A00 ^= RC[i];
+-    A11 =   B1 ^((~B2)&  B3 );
+-    A22 =   B2 ^((~B3)&  B4 );
+-    A33 =   B3 ^((~B4)&  B0 );
+-    A44 =   B4 ^((~B0)&  B1 );
++    b0 = (a00^d0);
++    b1 = ROL64((a11^d1), 44);
++    b2 = ROL64((a22^d2), 43);
++    b3 = ROL64((a33^d3), 21);
++    b4 = ROL64((a44^d4), 14);
++    a00 =   b0 ^((~b1)&  b2 );
++    a00 ^= RC[i];
++    a11 =   b1 ^((~b2)&  b3 );
++    a22 =   b2 ^((~b3)&  b4 );
++    a33 =   b3 ^((~b4)&  b0 );
++    a44 =   b4 ^((~b0)&  b1 );
+ 
+-    B2 = ROL64((A20^D0), 3);
+-    B3 = ROL64((A31^D1), 45);
+-    B4 = ROL64((A42^D2), 61);
+-    B0 = ROL64((A03^D3), 28);
+-    B1 = ROL64((A14^D4), 20);
+-    A20 =   B0 ^((~B1)&  B2 );
+-    A31 =   B1 ^((~B2)&  B3 );
+-    A42 =   B2 ^((~B3)&  B4 );
+-    A03 =   B3 ^((~B4)&  B0 );
+-    A14 =   B4 ^((~B0)&  B1 );
++    b2 = ROL64((a20^d0), 3);
++    b3 = ROL64((a31^d1), 45);
++    b4 = ROL64((a42^d2), 61);
++    b0 = ROL64((a03^d3), 28);
++    b1 = ROL64((a14^d4), 20);
++    a20 =   b0 ^((~b1)&  b2 );
++    a31 =   b1 ^((~b2)&  b3 );
++    a42 =   b2 ^((~b3)&  b4 );
++    a03 =   b3 ^((~b4)&  b0 );
++    a14 =   b4 ^((~b0)&  b1 );
+ 
+-    B4 = ROL64((A40^D0), 18);
+-    B0 = ROL64((A01^D1), 1);
+-    B1 = ROL64((A12^D2), 6);
+-    B2 = ROL64((A23^D3), 25);
+-    B3 = ROL64((A34^D4), 8);
+-    A40 =   B0 ^((~B1)&  B2 );
+-    A01 =   B1 ^((~B2)&  B3 );
+-    A12 =   B2 ^((~B3)&  B4 );
+-    A23 =   B3 ^((~B4)&  B0 );
+-    A34 =   B4 ^((~B0)&  B1 );
++    b4 = ROL64((a40^d0), 18);
++    b0 = ROL64((a01^d1), 1);
++    b1 = ROL64((a12^d2), 6);
++    b2 = ROL64((a23^d3), 25);
++    b3 = ROL64((a34^d4), 8);
++    a40 =   b0 ^((~b1)&  b2 );
++    a01 =   b1 ^((~b2)&  b3 );
++    a12 =   b2 ^((~b3)&  b4 );
++    a23 =   b3 ^((~b4)&  b0 );
++    a34 =   b4 ^((~b0)&  b1 );
+ 
+-    B1 = ROL64((A10^D0), 36);
+-    B2 = ROL64((A21^D1), 10);
+-    B3 = ROL64((A32^D2), 15);
+-    B4 = ROL64((A43^D3), 56);
+-    B0 = ROL64((A04^D4), 27);
+-    A10 =   B0 ^((~B1)&  B2 );
+-    A21 =   B1 ^((~B2)&  B3 );
+-    A32 =   B2 ^((~B3)&  B4 );
+-    A43 =   B3 ^((~B4)&  B0 );
+-    A04 =   B4 ^((~B0)&  B1 );
++    b1 = ROL64((a10^d0), 36);
++    b2 = ROL64((a21^d1), 10);
++    b3 = ROL64((a32^d2), 15);
++    b4 = ROL64((a43^d3), 56);
++    b0 = ROL64((a04^d4), 27);
++    a10 =   b0 ^((~b1)&  b2 );
++    a21 =   b1 ^((~b2)&  b3 );
++    a32 =   b2 ^((~b3)&  b4 );
++    a43 =   b3 ^((~b4)&  b0 );
++    a04 =   b4 ^((~b0)&  b1 );
+ 
+-    B3 = ROL64((A30^D0), 41);
+-    B4 = ROL64((A41^D1), 2);
+-    B0 = ROL64((A02^D2), 62);
+-    B1 = ROL64((A13^D3), 55);
+-    B2 = ROL64((A24^D4), 39);
+-    A30 =   B0 ^((~B1)&  B2 );
+-    A41 =   B1 ^((~B2)&  B3 );
+-    A02 =   B2 ^((~B3)&  B4 );
+-    A13 =   B3 ^((~B4)&  B0 );
+-    A24 =   B4 ^((~B0)&  B1 );
++    b3 = ROL64((a30^d0), 41);
++    b4 = ROL64((a41^d1), 2);
++    b0 = ROL64((a02^d2), 62);
++    b1 = ROL64((a13^d3), 55);
++    b2 = ROL64((a24^d4), 39);
++    a30 =   b0 ^((~b1)&  b2 );
++    a41 =   b1 ^((~b2)&  b3 );
++    a02 =   b2 ^((~b3)&  b4 );
++    a13 =   b3 ^((~b4)&  b0 );
++    a24 =   b4 ^((~b0)&  b1 );
+ 
+-    C0 = A00^A20^A40^A10^A30;
+-    C1 = A11^A31^A01^A21^A41;
+-    C2 = A22^A42^A12^A32^A02;
+-    C3 = A33^A03^A23^A43^A13;
+-    C4 = A44^A14^A34^A04^A24;
+-    D0 = C4^ROL64(C1, 1);
+-    D1 = C0^ROL64(C2, 1);
+-    D2 = C1^ROL64(C3, 1);
+-    D3 = C2^ROL64(C4, 1);
+-    D4 = C3^ROL64(C0, 1);
++    c0 = a00^a20^a40^a10^a30;
++    c1 = a11^a31^a01^a21^a41;
++    c2 = a22^a42^a12^a32^a02;
++    c3 = a33^a03^a23^a43^a13;
++    c4 = a44^a14^a34^a04^a24;
++    d0 = c4^ROL64(c1, 1);
++    d1 = c0^ROL64(c2, 1);
++    d2 = c1^ROL64(c3, 1);
++    d3 = c2^ROL64(c4, 1);
++    d4 = c3^ROL64(c0, 1);
+ 
+-    B0 = (A00^D0);
+-    B1 = ROL64((A31^D1), 44);
+-    B2 = ROL64((A12^D2), 43);
+-    B3 = ROL64((A43^D3), 21);
+-    B4 = ROL64((A24^D4), 14);
+-    A00 =   B0 ^((~B1)&  B2 );
+-    A00 ^= RC[i+1];
+-    A31 =   B1 ^((~B2)&  B3 );
+-    A12 =   B2 ^((~B3)&  B4 );
+-    A43 =   B3 ^((~B4)&  B0 );
+-    A24 =   B4 ^((~B0)&  B1 );
++    b0 = (a00^d0);
++    b1 = ROL64((a31^d1), 44);
++    b2 = ROL64((a12^d2), 43);
++    b3 = ROL64((a43^d3), 21);
++    b4 = ROL64((a24^d4), 14);
++    a00 =   b0 ^((~b1)&  b2 );
++    a00 ^= RC[i+1];
++    a31 =   b1 ^((~b2)&  b3 );
++    a12 =   b2 ^((~b3)&  b4 );
++    a43 =   b3 ^((~b4)&  b0 );
++    a24 =   b4 ^((~b0)&  b1 );
+ 
+-    B2 = ROL64((A40^D0), 3);
+-    B3 = ROL64((A21^D1), 45);
+-    B4 = ROL64((A02^D2), 61);
+-    B0 = ROL64((A33^D3), 28);
+-    B1 = ROL64((A14^D4), 20);
+-    A40 =   B0 ^((~B1)&  B2 );
+-    A21 =   B1 ^((~B2)&  B3 );
+-    A02 =   B2 ^((~B3)&  B4 );
+-    A33 =   B3 ^((~B4)&  B0 );
+-    A14 =   B4 ^((~B0)&  B1 );
++    b2 = ROL64((a40^d0), 3);
++    b3 = ROL64((a21^d1), 45);
++    b4 = ROL64((a02^d2), 61);
++    b0 = ROL64((a33^d3), 28);
++    b1 = ROL64((a14^d4), 20);
++    a40 =   b0 ^((~b1)&  b2 );
++    a21 =   b1 ^((~b2)&  b3 );
++    a02 =   b2 ^((~b3)&  b4 );
++    a33 =   b3 ^((~b4)&  b0 );
++    a14 =   b4 ^((~b0)&  b1 );
+ 
+-    B4 = ROL64((A30^D0), 18);
+-    B0 = ROL64((A11^D1), 1);
+-    B1 = ROL64((A42^D2), 6);
+-    B2 = ROL64((A23^D3), 25);
+-    B3 = ROL64((A04^D4), 8);
+-    A30 =   B0 ^((~B1)&  B2 );
+-    A11 =   B1 ^((~B2)&  B3 );
+-    A42 =   B2 ^((~B3)&  B4 );
+-    A23 =   B3 ^((~B4)&  B0 );
+-    A04 =   B4 ^((~B0)&  B1 );
++    b4 = ROL64((a30^d0), 18);
++    b0 = ROL64((a11^d1), 1);
++    b1 = ROL64((a42^d2), 6);
++    b2 = ROL64((a23^d3), 25);
++    b3 = ROL64((a04^d4), 8);
++    a30 =   b0 ^((~b1)&  b2 );
++    a11 =   b1 ^((~b2)&  b3 );
++    a42 =   b2 ^((~b3)&  b4 );
++    a23 =   b3 ^((~b4)&  b0 );
++    a04 =   b4 ^((~b0)&  b1 );
+ 
+-    B1 = ROL64((A20^D0), 36);
+-    B2 = ROL64((A01^D1), 10);
+-    B3 = ROL64((A32^D2), 15);
+-    B4 = ROL64((A13^D3), 56);
+-    B0 = ROL64((A44^D4), 27);
+-    A20 =   B0 ^((~B1)&  B2 );
+-    A01 =   B1 ^((~B2)&  B3 );
+-    A32 =   B2 ^((~B3)&  B4 );
+-    A13 =   B3 ^((~B4)&  B0 );
+-    A44 =   B4 ^((~B0)&  B1 );
++    b1 = ROL64((a20^d0), 36);
++    b2 = ROL64((a01^d1), 10);
++    b3 = ROL64((a32^d2), 15);
++    b4 = ROL64((a13^d3), 56);
++    b0 = ROL64((a44^d4), 27);
++    a20 =   b0 ^((~b1)&  b2 );
++    a01 =   b1 ^((~b2)&  b3 );
++    a32 =   b2 ^((~b3)&  b4 );
++    a13 =   b3 ^((~b4)&  b0 );
++    a44 =   b4 ^((~b0)&  b1 );
+ 
+-    B3 = ROL64((A10^D0), 41);
+-    B4 = ROL64((A41^D1), 2);
+-    B0 = ROL64((A22^D2), 62);
+-    B1 = ROL64((A03^D3), 55);
+-    B2 = ROL64((A34^D4), 39);
+-    A10 =   B0 ^((~B1)&  B2 );
+-    A41 =   B1 ^((~B2)&  B3 );
+-    A22 =   B2 ^((~B3)&  B4 );
+-    A03 =   B3 ^((~B4)&  B0 );
+-    A34 =   B4 ^((~B0)&  B1 );
++    b3 = ROL64((a10^d0), 41);
++    b4 = ROL64((a41^d1), 2);
++    b0 = ROL64((a22^d2), 62);
++    b1 = ROL64((a03^d3), 55);
++    b2 = ROL64((a34^d4), 39);
++    a10 =   b0 ^((~b1)&  b2 );
++    a41 =   b1 ^((~b2)&  b3 );
++    a22 =   b2 ^((~b3)&  b4 );
++    a03 =   b3 ^((~b4)&  b0 );
++    a34 =   b4 ^((~b0)&  b1 );
+ 
+-    C0 = A00^A40^A30^A20^A10;
+-    C1 = A31^A21^A11^A01^A41;
+-    C2 = A12^A02^A42^A32^A22;
+-    C3 = A43^A33^A23^A13^A03;
+-    C4 = A24^A14^A04^A44^A34;
+-    D0 = C4^ROL64(C1, 1);
+-    D1 = C0^ROL64(C2, 1);
+-    D2 = C1^ROL64(C3, 1);
+-    D3 = C2^ROL64(C4, 1);
+-    D4 = C3^ROL64(C0, 1);
++    c0 = a00^a40^a30^a20^a10;
++    c1 = a31^a21^a11^a01^a41;
++    c2 = a12^a02^a42^a32^a22;
++    c3 = a43^a33^a23^a13^a03;
++    c4 = a24^a14^a04^a44^a34;
++    d0 = c4^ROL64(c1, 1);
++    d1 = c0^ROL64(c2, 1);
++    d2 = c1^ROL64(c3, 1);
++    d3 = c2^ROL64(c4, 1);
++    d4 = c3^ROL64(c0, 1);
+ 
+-    B0 = (A00^D0);
+-    B1 = ROL64((A21^D1), 44);
+-    B2 = ROL64((A42^D2), 43);
+-    B3 = ROL64((A13^D3), 21);
+-    B4 = ROL64((A34^D4), 14);
+-    A00 =   B0 ^((~B1)&  B2 );
+-    A00 ^= RC[i+2];
+-    A21 =   B1 ^((~B2)&  B3 );
+-    A42 =   B2 ^((~B3)&  B4 );
+-    A13 =   B3 ^((~B4)&  B0 );
+-    A34 =   B4 ^((~B0)&  B1 );
++    b0 = (a00^d0);
++    b1 = ROL64((a21^d1), 44);
++    b2 = ROL64((a42^d2), 43);
++    b3 = ROL64((a13^d3), 21);
++    b4 = ROL64((a34^d4), 14);
++    a00 =   b0 ^((~b1)&  b2 );
++    a00 ^= RC[i+2];
++    a21 =   b1 ^((~b2)&  b3 );
++    a42 =   b2 ^((~b3)&  b4 );
++    a13 =   b3 ^((~b4)&  b0 );
++    a34 =   b4 ^((~b0)&  b1 );
+ 
+-    B2 = ROL64((A30^D0), 3);
+-    B3 = ROL64((A01^D1), 45);
+-    B4 = ROL64((A22^D2), 61);
+-    B0 = ROL64((A43^D3), 28);
+-    B1 = ROL64((A14^D4), 20);
+-    A30 =   B0 ^((~B1)&  B2 );
+-    A01 =   B1 ^((~B2)&  B3 );
+-    A22 =   B2 ^((~B3)&  B4 );
+-    A43 =   B3 ^((~B4)&  B0 );
+-    A14 =   B4 ^((~B0)&  B1 );
++    b2 = ROL64((a30^d0), 3);
++    b3 = ROL64((a01^d1), 45);
++    b4 = ROL64((a22^d2), 61);
++    b0 = ROL64((a43^d3), 28);
++    b1 = ROL64((a14^d4), 20);
++    a30 =   b0 ^((~b1)&  b2 );
++    a01 =   b1 ^((~b2)&  b3 );
++    a22 =   b2 ^((~b3)&  b4 );
++    a43 =   b3 ^((~b4)&  b0 );
++    a14 =   b4 ^((~b0)&  b1 );
+ 
+-    B4 = ROL64((A10^D0), 18);
+-    B0 = ROL64((A31^D1), 1);
+-    B1 = ROL64((A02^D2), 6);
+-    B2 = ROL64((A23^D3), 25);
+-    B3 = ROL64((A44^D4), 8);
+-    A10 =   B0 ^((~B1)&  B2 );
+-    A31 =   B1 ^((~B2)&  B3 );
+-    A02 =   B2 ^((~B3)&  B4 );
+-    A23 =   B3 ^((~B4)&  B0 );
+-    A44 =   B4 ^((~B0)&  B1 );
++    b4 = ROL64((a10^d0), 18);
++    b0 = ROL64((a31^d1), 1);
++    b1 = ROL64((a02^d2), 6);
++    b2 = ROL64((a23^d3), 25);
++    b3 = ROL64((a44^d4), 8);
++    a10 =   b0 ^((~b1)&  b2 );
++    a31 =   b1 ^((~b2)&  b3 );
++    a02 =   b2 ^((~b3)&  b4 );
++    a23 =   b3 ^((~b4)&  b0 );
++    a44 =   b4 ^((~b0)&  b1 );
+ 
+-    B1 = ROL64((A40^D0), 36);
+-    B2 = ROL64((A11^D1), 10);
+-    B3 = ROL64((A32^D2), 15);
+-    B4 = ROL64((A03^D3), 56);
+-    B0 = ROL64((A24^D4), 27);
+-    A40 =   B0 ^((~B1)&  B2 );
+-    A11 =   B1 ^((~B2)&  B3 );
+-    A32 =   B2 ^((~B3)&  B4 );
+-    A03 =   B3 ^((~B4)&  B0 );
+-    A24 =   B4 ^((~B0)&  B1 );
++    b1 = ROL64((a40^d0), 36);
++    b2 = ROL64((a11^d1), 10);
++    b3 = ROL64((a32^d2), 15);
++    b4 = ROL64((a03^d3), 56);
++    b0 = ROL64((a24^d4), 27);
++    a40 =   b0 ^((~b1)&  b2 );
++    a11 =   b1 ^((~b2)&  b3 );
++    a32 =   b2 ^((~b3)&  b4 );
++    a03 =   b3 ^((~b4)&  b0 );
++    a24 =   b4 ^((~b0)&  b1 );
+ 
+-    B3 = ROL64((A20^D0), 41);
+-    B4 = ROL64((A41^D1), 2);
+-    B0 = ROL64((A12^D2), 62);
+-    B1 = ROL64((A33^D3), 55);
+-    B2 = ROL64((A04^D4), 39);
+-    A20 =   B0 ^((~B1)&  B2 );
+-    A41 =   B1 ^((~B2)&  B3 );
+-    A12 =   B2 ^((~B3)&  B4 );
+-    A33 =   B3 ^((~B4)&  B0 );
+-    A04 =   B4 ^((~B0)&  B1 );
++    b3 = ROL64((a20^d0), 41);
++    b4 = ROL64((a41^d1), 2);
++    b0 = ROL64((a12^d2), 62);
++    b1 = ROL64((a33^d3), 55);
++    b2 = ROL64((a04^d4), 39);
++    a20 =   b0 ^((~b1)&  b2 );
++    a41 =   b1 ^((~b2)&  b3 );
++    a12 =   b2 ^((~b3)&  b4 );
++    a33 =   b3 ^((~b4)&  b0 );
++    a04 =   b4 ^((~b0)&  b1 );
+ 
+-    C0 = A00^A30^A10^A40^A20;
+-    C1 = A21^A01^A31^A11^A41;
+-    C2 = A42^A22^A02^A32^A12;
+-    C3 = A13^A43^A23^A03^A33;
+-    C4 = A34^A14^A44^A24^A04;
+-    D0 = C4^ROL64(C1, 1);
+-    D1 = C0^ROL64(C2, 1);
+-    D2 = C1^ROL64(C3, 1);
+-    D3 = C2^ROL64(C4, 1);
+-    D4 = C3^ROL64(C0, 1);
++    c0 = a00^a30^a10^a40^a20;
++    c1 = a21^a01^a31^a11^a41;
++    c2 = a42^a22^a02^a32^a12;
++    c3 = a13^a43^a23^a03^a33;
++    c4 = a34^a14^a44^a24^a04;
++    d0 = c4^ROL64(c1, 1);
++    d1 = c0^ROL64(c2, 1);
++    d2 = c1^ROL64(c3, 1);
++    d3 = c2^ROL64(c4, 1);
++    d4 = c3^ROL64(c0, 1);
+ 
+-    B0 = (A00^D0);
+-    B1 = ROL64((A01^D1), 44);
+-    B2 = ROL64((A02^D2), 43);
+-    B3 = ROL64((A03^D3), 21);
+-    B4 = ROL64((A04^D4), 14);
+-    A00 =   B0 ^((~B1)&  B2 );
+-    A00 ^= RC[i+3];
+-    A01 =   B1 ^((~B2)&  B3 );
+-    A02 =   B2 ^((~B3)&  B4 );
+-    A03 =   B3 ^((~B4)&  B0 );
+-    A04 =   B4 ^((~B0)&  B1 );
++    b0 = (a00^d0);
++    b1 = ROL64((a01^d1), 44);
++    b2 = ROL64((a02^d2), 43);
++    b3 = ROL64((a03^d3), 21);
++    b4 = ROL64((a04^d4), 14);
++    a00 =   b0 ^((~b1)&  b2 );
++    a00 ^= RC[i+3];
++    a01 =   b1 ^((~b2)&  b3 );
++    a02 =   b2 ^((~b3)&  b4 );
++    a03 =   b3 ^((~b4)&  b0 );
++    a04 =   b4 ^((~b0)&  b1 );
+ 
+-    B2 = ROL64((A10^D0), 3);
+-    B3 = ROL64((A11^D1), 45);
+-    B4 = ROL64((A12^D2), 61);
+-    B0 = ROL64((A13^D3), 28);
+-    B1 = ROL64((A14^D4), 20);
+-    A10 =   B0 ^((~B1)&  B2 );
+-    A11 =   B1 ^((~B2)&  B3 );
+-    A12 =   B2 ^((~B3)&  B4 );
+-    A13 =   B3 ^((~B4)&  B0 );
+-    A14 =   B4 ^((~B0)&  B1 );
++    b2 = ROL64((a10^d0), 3);
++    b3 = ROL64((a11^d1), 45);
++    b4 = ROL64((a12^d2), 61);
++    b0 = ROL64((a13^d3), 28);
++    b1 = ROL64((a14^d4), 20);
++    a10 =   b0 ^((~b1)&  b2 );
++    a11 =   b1 ^((~b2)&  b3 );
++    a12 =   b2 ^((~b3)&  b4 );
++    a13 =   b3 ^((~b4)&  b0 );
++    a14 =   b4 ^((~b0)&  b1 );
+ 
+-    B4 = ROL64((A20^D0), 18);
+-    B0 = ROL64((A21^D1), 1);
+-    B1 = ROL64((A22^D2), 6);
+-    B2 = ROL64((A23^D3), 25);
+-    B3 = ROL64((A24^D4), 8);
+-    A20 =   B0 ^((~B1)&  B2 );
+-    A21 =   B1 ^((~B2)&  B3 );
+-    A22 =   B2 ^((~B3)&  B4 );
+-    A23 =   B3 ^((~B4)&  B0 );
+-    A24 =   B4 ^((~B0)&  B1 );
++    b4 = ROL64((a20^d0), 18);
++    b0 = ROL64((a21^d1), 1);
++    b1 = ROL64((a22^d2), 6);
++    b2 = ROL64((a23^d3), 25);
++    b3 = ROL64((a24^d4), 8);
++    a20 =   b0 ^((~b1)&  b2 );
++    a21 =   b1 ^((~b2)&  b3 );
++    a22 =   b2 ^((~b3)&  b4 );
++    a23 =   b3 ^((~b4)&  b0 );
++    a24 =   b4 ^((~b0)&  b1 );
+ 
+-    B1 = ROL64((A30^D0), 36);
+-    B2 = ROL64((A31^D1), 10);
+-    B3 = ROL64((A32^D2), 15);
+-    B4 = ROL64((A33^D3), 56);
+-    B0 = ROL64((A34^D4), 27);
+-    A30 =   B0 ^((~B1)&  B2 );
+-    A31 =   B1 ^((~B2)&  B3 );
+-    A32 =   B2 ^((~B3)&  B4 );
+-    A33 =   B3 ^((~B4)&  B0 );
+-    A34 =   B4 ^((~B0)&  B1 );
++    b1 = ROL64((a30^d0), 36);
++    b2 = ROL64((a31^d1), 10);
++    b3 = ROL64((a32^d2), 15);
++    b4 = ROL64((a33^d3), 56);
++    b0 = ROL64((a34^d4), 27);
++    a30 =   b0 ^((~b1)&  b2 );
++    a31 =   b1 ^((~b2)&  b3 );
++    a32 =   b2 ^((~b3)&  b4 );
++    a33 =   b3 ^((~b4)&  b0 );
++    a34 =   b4 ^((~b0)&  b1 );
+ 
+-    B3 = ROL64((A40^D0), 41);
+-    B4 = ROL64((A41^D1), 2);
+-    B0 = ROL64((A42^D2), 62);
+-    B1 = ROL64((A43^D3), 55);
+-    B2 = ROL64((A44^D4), 39);
+-    A40 =   B0 ^((~B1)&  B2 );
+-    A41 =   B1 ^((~B2)&  B3 );
+-    A42 =   B2 ^((~B3)&  B4 );
+-    A43 =   B3 ^((~B4)&  B0 );
+-    A44 =   B4 ^((~B0)&  B1 );
++    b3 = ROL64((a40^d0), 41);
++    b4 = ROL64((a41^d1), 2);
++    b0 = ROL64((a42^d2), 62);
++    b1 = ROL64((a43^d3), 55);
++    b2 = ROL64((a44^d4), 39);
++    a40 =   b0 ^((~b1)&  b2 );
++    a41 =   b1 ^((~b2)&  b3 );
++    a42 =   b2 ^((~b3)&  b4 );
++    a43 =   b3 ^((~b4)&  b0 );
++    a44 =   b4 ^((~b0)&  b1 );
+   }
+ }
+ 
+@@ -1499,7 +1992,7 @@
+ 
+ 
+ #ifdef _WIN32
+-__declspec(dllexport)
++
+ #endif
+ int sqlite3_shathree_init(
+   sqlite3 *db,
+@@ -1541,29 +2034,122 @@
+ ******************************************************************************
+ **
+ ** This SQLite extension implements SQL functions readfile() and
+-** writefile().
++** writefile(), and eponymous virtual type "fsdir".
++**
++** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
++**
++**   If neither of the optional arguments is present, then this UDF
++**   function writes blob DATA to file FILE. If successful, the number
++**   of bytes written is returned. If an error occurs, NULL is returned.
++**
++**   If the first option argument - MODE - is present, then it must
++**   be passed an integer value that corresponds to a POSIX mode
++**   value (file type + permissions, as returned in the stat.st_mode
++**   field by the stat() system call). Three types of files may
++**   be written/created:
++**
++**     regular files:  (mode & 0170000)==0100000
++**     symbolic links: (mode & 0170000)==0120000
++**     directories:    (mode & 0170000)==0040000
++**
++**   For a directory, the DATA is ignored. For a symbolic link, it is
++**   interpreted as text and used as the target of the link. For a
++**   regular file, it is interpreted as a blob and written into the
++**   named file. Regardless of the type of file, its permissions are
++**   set to (mode & 0777) before returning.
++**
++**   If the optional MTIME argument is present, then it is interpreted
++**   as an integer - the number of seconds since the unix epoch. The
++**   modification-time of the target file is set to this value before
++**   returning.
++**
++**   If three or more arguments are passed to this function and an
++**   error is encountered, an exception is raised.
++**
++** READFILE(FILE):
++**
++**   Read and return the contents of file FILE (type blob) from disk.
++**
++** FSDIR:
++**
++**   Used as follows:
++**
++**     SELECT * FROM fsdir($path [, $dir]);
++**
++**   Parameter $path is an absolute or relative pathname. If the file that it
++**   refers to does not exist, it is an error. If the path refers to a regular
++**   file or symbolic link, it returns a single row. Or, if the path refers
++**   to a directory, it returns one row for the directory, and one row for each
++**   file within the hierarchy rooted at $path.
++**
++**   Each row has the following columns:
++**
++**     name:  Path to file or directory (text value).
++**     mode:  Value of stat.st_mode for directory entry (an integer).
++**     mtime: Value of stat.st_mtime for directory entry (an integer).
++**     data:  For a regular file, a blob containing the file data. For a
++**            symlink, a text value containing the text of the link. For a
++**            directory, NULL.
++**
++**   If a non-NULL value is specified for the optional $dir parameter and
++**   $path is a relative path, then $path is interpreted relative to $dir. 
++**   And the paths returned in the "name" column of the table are also 
++**   relative to directory $dir.
+ */
+ SQLITE_EXTENSION_INIT1
+ #include <stdio.h>
++#include <string.h>
++#include <assert.h>
+ 
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#if !defined(_WIN32) && !defined(WIN32)
++#  include <unistd.h>
++#  include <dirent.h>
++#  include <utime.h>
++#  include <sys/time.h>
++#else
++#  include "windows.h"
++#  include <io.h>
++#  include <direct.h>
++/* #  include "test_windirent.h" */
++#  define dirent DIRENT
++#  ifndef chmod
++#    define chmod _chmod
++#  endif
++#  ifndef stat
++#    define stat _stat
++#  endif
++#  define mkdir(path,mode) _mkdir(path)
++#  define lstat(path,buf) stat(path,buf)
++#endif
++#include <time.h>
++#include <errno.h>
++
++
+ /*
+-** Implementation of the "readfile(X)" SQL function.  The entire content
+-** of the file named X is read and returned as a BLOB.  NULL is returned
+-** if the file does not exist or is unreadable.
++** Structure of the fsdir() table-valued function
+ */
+-static void readfileFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  const char *zName;
++                 /*    0    1    2     3    4           5             */
++#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
++#define FSDIR_COLUMN_NAME     0     /* Name of the file */
++#define FSDIR_COLUMN_MODE     1     /* Access mode */
++#define FSDIR_COLUMN_MTIME    2     /* Last modification time */
++#define FSDIR_COLUMN_DATA     3     /* File content */
++#define FSDIR_COLUMN_PATH     4     /* Path to top of search */
++#define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */
++
++
++/*
++** Set the result stored by context ctx to a blob containing the 
++** contents of file zName.
++*/
++static void readFileContents(sqlite3_context *ctx, const char *zName){
+   FILE *in;
+   long nIn;
+   void *pBuf;
+ 
+-  (void)(argc);  /* Unused parameter */
+-  zName = (const char*)sqlite3_value_text(argv[0]);
+-  if( zName==0 ) return;
+   in = fopen(zName, "rb");
+   if( in==0 ) return;
+   fseek(in, 0, SEEK_END);
+@@ -1571,7 +2157,7 @@
+   rewind(in);
+   pBuf = sqlite3_malloc( nIn );
+   if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
+-    sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
++    sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free);
+   }else{
+     sqlite3_free(pBuf);
+   }
+@@ -1579,39 +2165,807 @@
+ }
+ 
+ /*
+-** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
+-** is written into file X.  The number of bytes written is returned.  Or
+-** NULL is returned if something goes wrong, such as being unable to open
+-** file X for writing.
++** Implementation of the "readfile(X)" SQL function.  The entire content
++** of the file named X is read and returned as a BLOB.  NULL is returned
++** if the file does not exist or is unreadable.
+ */
++static void readfileFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  const char *zName;
++  (void)(argc);  /* Unused parameter */
++  zName = (const char*)sqlite3_value_text(argv[0]);
++  if( zName==0 ) return;
++  readFileContents(context, zName);
++}
++
++/*
++** Set the error message contained in context ctx to the results of
++** vprintf(zFmt, ...).
++*/
++static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
++  char *zMsg = 0;
++  va_list ap;
++  va_start(ap, zFmt);
++  zMsg = sqlite3_vmprintf(zFmt, ap);
++  sqlite3_result_error(ctx, zMsg, -1);
++  sqlite3_free(zMsg);
++  va_end(ap);
++}
++
++#if defined(_WIN32)
++/*
++** This function is designed to convert a Win32 FILETIME structure into the
++** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
++*/
++static sqlite3_uint64 fileTimeToUnixTime(
++  LPFILETIME pFileTime
++){
++  SYSTEMTIME epochSystemTime;
++  ULARGE_INTEGER epochIntervals;
++  FILETIME epochFileTime;
++  ULARGE_INTEGER fileIntervals;
++
++  memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
++  epochSystemTime.wYear = 1970;
++  epochSystemTime.wMonth = 1;
++  epochSystemTime.wDay = 1;
++  SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
++  epochIntervals.LowPart = epochFileTime.dwLowDateTime;
++  epochIntervals.HighPart = epochFileTime.dwHighDateTime;
++
++  fileIntervals.LowPart = pFileTime->dwLowDateTime;
++  fileIntervals.HighPart = pFileTime->dwHighDateTime;
++
++  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
++}
++
++/*
++** This function attempts to normalize the time values found in the stat()
++** buffer to UTC.  This is necessary on Win32, where the runtime library
++** appears to return these values as local times.
++*/
++static void statTimesToUtc(
++  const char *zPath,
++  struct stat *pStatBuf
++){
++  HANDLE hFindFile;
++  WIN32_FIND_DATAW fd;
++  LPWSTR zUnicodeName;
++  extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
++  zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
++  if( zUnicodeName ){
++    memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
++    hFindFile = FindFirstFileW(zUnicodeName, &fd);
++    if( hFindFile!=NULL ){
++      pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
++      pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
++      pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
++      FindClose(hFindFile);
++    }
++    sqlite3_free(zUnicodeName);
++  }
++}
++#endif
++
++/*
++** This function is used in place of stat().  On Windows, special handling
++** is required in order for the included time to be returned as UTC.  On all
++** other systems, this function simply calls stat().
++*/
++static int fileStat(
++  const char *zPath,
++  struct stat *pStatBuf
++){
++#if defined(_WIN32)
++  int rc = stat(zPath, pStatBuf);
++  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
++  return rc;
++#else
++  return stat(zPath, pStatBuf);
++#endif
++}
++
++/*
++** This function is used in place of lstat().  On Windows, special handling
++** is required in order for the included time to be returned as UTC.  On all
++** other systems, this function simply calls lstat().
++*/
++static int fileLinkStat(
++  const char *zPath,
++  struct stat *pStatBuf
++){
++#if defined(_WIN32)
++  int rc = lstat(zPath, pStatBuf);
++  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
++  return rc;
++#else
++  return lstat(zPath, pStatBuf);
++#endif
++}
++
++/*
++** Argument zFile is the name of a file that will be created and/or written
++** by SQL function writefile(). This function ensures that the directory
++** zFile will be written to exists, creating it if required. The permissions
++** for any path components created by this function are set to (mode&0777).
++**
++** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
++** SQLITE_OK is returned if the directory is successfully created, or
++** SQLITE_ERROR otherwise.
++*/
++static int makeDirectory(
++  const char *zFile,
++  mode_t mode
++){
++  char *zCopy = sqlite3_mprintf("%s", zFile);
++  int rc = SQLITE_OK;
++
++  if( zCopy==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    int nCopy = (int)strlen(zCopy);
++    int i = 1;
++
++    while( rc==SQLITE_OK ){
++      struct stat sStat;
++      int rc2;
++
++      for(; zCopy[i]!='/' && i<nCopy; i++);
++      if( i==nCopy ) break;
++      zCopy[i] = '\0';
++
++      rc2 = fileStat(zCopy, &sStat);
++      if( rc2!=0 ){
++        if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
++      }else{
++        if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
++      }
++      zCopy[i] = '/';
++      i++;
++    }
++
++    sqlite3_free(zCopy);
++  }
++
++  return rc;
++}
++
++/*
++** This function does the work for the writefile() UDF. Refer to 
++** header comments at the top of this file for details.
++*/
++static int writeFile(
++  sqlite3_context *pCtx,          /* Context to return bytes written in */
++  const char *zFile,              /* File to write */
++  sqlite3_value *pData,           /* Data to write */
++  mode_t mode,                    /* MODE parameter passed to writefile() */
++  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
++){
++#if !defined(_WIN32) && !defined(WIN32)
++  if( S_ISLNK(mode) ){
++    const char *zTo = (const char*)sqlite3_value_text(pData);
++    if( symlink(zTo, zFile)<0 ) return 1;
++  }else
++#endif
++  {
++    if( S_ISDIR(mode) ){
++      if( mkdir(zFile, mode) ){
++        /* The mkdir() call to create the directory failed. This might not
++        ** be an error though - if there is already a directory at the same
++        ** path and either the permissions already match or can be changed
++        ** to do so using chmod(), it is not an error.  */
++        struct stat sStat;
++        if( errno!=EEXIST
++         || 0!=fileStat(zFile, &sStat)
++         || !S_ISDIR(sStat.st_mode)
++         || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
++        ){
++          return 1;
++        }
++      }
++    }else{
++      sqlite3_int64 nWrite = 0;
++      const char *z;
++      int rc = 0;
++      FILE *out = fopen(zFile, "wb");
++      if( out==0 ) return 1;
++      z = (const char*)sqlite3_value_blob(pData);
++      if( z ){
++        sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
++        nWrite = sqlite3_value_bytes(pData);
++        if( nWrite!=n ){
++          rc = 1;
++        }
++      }
++      fclose(out);
++      if( rc==0 && mode && chmod(zFile, mode & 0777) ){
++        rc = 1;
++      }
++      if( rc ) return 2;
++      sqlite3_result_int64(pCtx, nWrite);
++    }
++  }
++
++  if( mtime>=0 ){
++#if defined(_WIN32)
++    /* Windows */
++    FILETIME lastAccess;
++    FILETIME lastWrite;
++    SYSTEMTIME currentTime;
++    LONGLONG intervals;
++    HANDLE hFile;
++    LPWSTR zUnicodeName;
++    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
++
++    GetSystemTime(&currentTime);
++    SystemTimeToFileTime(&currentTime, &lastAccess);
++    intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
++    lastWrite.dwLowDateTime = (DWORD)intervals;
++    lastWrite.dwHighDateTime = intervals >> 32;
++    zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
++    if( zUnicodeName==0 ){
++      return 1;
++    }
++    hFile = CreateFileW(
++      zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
++      FILE_FLAG_BACKUP_SEMANTICS, NULL
++    );
++    sqlite3_free(zUnicodeName);
++    if( hFile!=INVALID_HANDLE_VALUE ){
++      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
++      CloseHandle(hFile);
++      return !bResult;
++    }else{
++      return 1;
++    }
++#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
++    /* Recent unix */
++    struct timespec times[2];
++    times[0].tv_nsec = times[1].tv_nsec = 0;
++    times[0].tv_sec = time(0);
++    times[1].tv_sec = mtime;
++    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
++      return 1;
++    }
++#else
++    /* Legacy unix */
++    struct timeval times[2];
++    times[0].tv_usec = times[1].tv_usec = 0;
++    times[0].tv_sec = time(0);
++    times[1].tv_sec = mtime;
++    if( utimes(zFile, times) ){
++      return 1;
++    }
++#endif
++  }
++
++  return 0;
++}
++
++/*
++** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.  
++** Refer to header comments at the top of this file for details.
++*/
+ static void writefileFunc(
+   sqlite3_context *context,
+   int argc,
+   sqlite3_value **argv
+ ){
+-  FILE *out;
+-  const char *z;
+-  sqlite3_int64 rc;
+   const char *zFile;
++  mode_t mode = 0;
++  int res;
++  sqlite3_int64 mtime = -1;
+ 
+-  (void)(argc);  /* Unused parameter */
++  if( argc<2 || argc>4 ){
++    sqlite3_result_error(context, 
++        "wrong number of arguments to function writefile()", -1
++    );
++    return;
++  }
++
+   zFile = (const char*)sqlite3_value_text(argv[0]);
+   if( zFile==0 ) return;
+-  out = fopen(zFile, "wb");
+-  if( out==0 ) return;
+-  z = (const char*)sqlite3_value_blob(argv[1]);
+-  if( z==0 ){
+-    rc = 0;
++  if( argc>=3 ){
++    mode = (mode_t)sqlite3_value_int(argv[2]);
++  }
++  if( argc==4 ){
++    mtime = sqlite3_value_int64(argv[3]);
++  }
++
++  res = writeFile(context, zFile, argv[1], mode, mtime);
++  if( res==1 && errno==ENOENT ){
++    if( makeDirectory(zFile, mode)==SQLITE_OK ){
++      res = writeFile(context, zFile, argv[1], mode, mtime);
++    }
++  }
++
++  if( argc>2 && res!=0 ){
++    if( S_ISLNK(mode) ){
++      ctxErrorMsg(context, "failed to create symlink: %s", zFile);
++    }else if( S_ISDIR(mode) ){
++      ctxErrorMsg(context, "failed to create directory: %s", zFile);
++    }else{
++      ctxErrorMsg(context, "failed to write file: %s", zFile);
++    }
++  }
++}
++
++/*
++** SQL function:   lsmode(MODE)
++**
++** Given a numberic st_mode from stat(), convert it into a human-readable
++** text string in the style of "ls -l".
++*/
++static void lsModeFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  int iMode = sqlite3_value_int(argv[0]);
++  char z[16];
++  (void)argc;
++  if( S_ISLNK(iMode) ){
++    z[0] = 'l';
++  }else if( S_ISREG(iMode) ){
++    z[0] = '-';
++  }else if( S_ISDIR(iMode) ){
++    z[0] = 'd';
+   }else{
+-    rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
++    z[0] = '?';
+   }
+-  fclose(out);
+-  sqlite3_result_int64(context, rc);
++  for(i=0; i<3; i++){
++    int m = (iMode >> ((2-i)*3));
++    char *a = &z[1 + i*3];
++    a[0] = (m & 0x4) ? 'r' : '-';
++    a[1] = (m & 0x2) ? 'w' : '-';
++    a[2] = (m & 0x1) ? 'x' : '-';
++  }
++  z[10] = '\0';
++  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+ }
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
+ 
++/* 
++** Cursor type for recursively iterating through a directory structure.
++*/
++typedef struct fsdir_cursor fsdir_cursor;
++typedef struct FsdirLevel FsdirLevel;
++
++struct FsdirLevel {
++  DIR *pDir;                 /* From opendir() */
++  char *zDir;                /* Name of directory (nul-terminated) */
++};
++
++struct fsdir_cursor {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++
++  int nLvl;                  /* Number of entries in aLvl[] array */
++  int iLvl;                  /* Index of current entry */
++  FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
++
++  const char *zBase;
++  int nBase;
++
++  struct stat sStat;         /* Current lstat() results */
++  char *zPath;               /* Path to current entry */
++  sqlite3_int64 iRowid;      /* Current rowid */
++};
++
++typedef struct fsdir_tab fsdir_tab;
++struct fsdir_tab {
++  sqlite3_vtab base;         /* Base class - must be first */
++};
++
++/*
++** Construct a new fsdir virtual table object.
++*/
++static int fsdirConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  fsdir_tab *pNew = 0;
++  int rc;
++  (void)pAux;
++  (void)argc;
++  (void)argv;
++  (void)pzErr;
++  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
++  if( rc==SQLITE_OK ){
++    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, sizeof(*pNew));
++  }
++  *ppVtab = (sqlite3_vtab*)pNew;
++  return rc;
++}
++
++/*
++** This method is the destructor for fsdir vtab objects.
++*/
++static int fsdirDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/*
++** Constructor for a new fsdir_cursor object.
++*/
++static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  fsdir_cursor *pCur;
++  (void)p;
++  pCur = sqlite3_malloc( sizeof(*pCur) );
++  if( pCur==0 ) return SQLITE_NOMEM;
++  memset(pCur, 0, sizeof(*pCur));
++  pCur->iLvl = -1;
++  *ppCursor = &pCur->base;
++  return SQLITE_OK;
++}
++
++/*
++** Reset a cursor back to the state it was in when first returned
++** by fsdirOpen().
++*/
++static void fsdirResetCursor(fsdir_cursor *pCur){
++  int i;
++  for(i=0; i<=pCur->iLvl; i++){
++    FsdirLevel *pLvl = &pCur->aLvl[i];
++    if( pLvl->pDir ) closedir(pLvl->pDir);
++    sqlite3_free(pLvl->zDir);
++  }
++  sqlite3_free(pCur->zPath);
++  sqlite3_free(pCur->aLvl);
++  pCur->aLvl = 0;
++  pCur->zPath = 0;
++  pCur->zBase = 0;
++  pCur->nBase = 0;
++  pCur->nLvl = 0;
++  pCur->iLvl = -1;
++  pCur->iRowid = 1;
++}
++
++/*
++** Destructor for an fsdir_cursor.
++*/
++static int fsdirClose(sqlite3_vtab_cursor *cur){
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++
++  fsdirResetCursor(pCur);
++  sqlite3_free(pCur);
++  return SQLITE_OK;
++}
++
++/*
++** Set the error message for the virtual table associated with cursor
++** pCur to the results of vprintf(zFmt, ...).
++*/
++static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
++  va_list ap;
++  va_start(ap, zFmt);
++  pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
++  va_end(ap);
++}
++
++
++/*
++** Advance an fsdir_cursor to its next row of output.
++*/
++static int fsdirNext(sqlite3_vtab_cursor *cur){
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++  mode_t m = pCur->sStat.st_mode;
++
++  pCur->iRowid++;
++  if( S_ISDIR(m) ){
++    /* Descend into this directory */
++    int iNew = pCur->iLvl + 1;
++    FsdirLevel *pLvl;
++    if( iNew>=pCur->nLvl ){
++      int nNew = iNew+1;
++      int nByte = nNew*sizeof(FsdirLevel);
++      FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte);
++      if( aNew==0 ) return SQLITE_NOMEM;
++      memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
++      pCur->aLvl = aNew;
++      pCur->nLvl = nNew;
++    }
++    pCur->iLvl = iNew;
++    pLvl = &pCur->aLvl[iNew];
++    
++    pLvl->zDir = pCur->zPath;
++    pCur->zPath = 0;
++    pLvl->pDir = opendir(pLvl->zDir);
++    if( pLvl->pDir==0 ){
++      fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
++      return SQLITE_ERROR;
++    }
++  }
++
++  while( pCur->iLvl>=0 ){
++    FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
++    struct dirent *pEntry = readdir(pLvl->pDir);
++    if( pEntry ){
++      if( pEntry->d_name[0]=='.' ){
++       if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
++       if( pEntry->d_name[1]=='\0' ) continue;
++      }
++      sqlite3_free(pCur->zPath);
++      pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
++      if( pCur->zPath==0 ) return SQLITE_NOMEM;
++      if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
++        fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
++        return SQLITE_ERROR;
++      }
++      return SQLITE_OK;
++    }
++    closedir(pLvl->pDir);
++    sqlite3_free(pLvl->zDir);
++    pLvl->pDir = 0;
++    pLvl->zDir = 0;
++    pCur->iLvl--;
++  }
++
++  /* EOF */
++  sqlite3_free(pCur->zPath);
++  pCur->zPath = 0;
++  return SQLITE_OK;
++}
++
++/*
++** Return values of columns for the row at which the series_cursor
++** is currently pointing.
++*/
++static int fsdirColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++  switch( i ){
++    case FSDIR_COLUMN_NAME: {
++      sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
++      break;
++    }
++
++    case FSDIR_COLUMN_MODE:
++      sqlite3_result_int64(ctx, pCur->sStat.st_mode);
++      break;
++
++    case FSDIR_COLUMN_MTIME:
++      sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
++      break;
++
++    case FSDIR_COLUMN_DATA: {
++      mode_t m = pCur->sStat.st_mode;
++      if( S_ISDIR(m) ){
++        sqlite3_result_null(ctx);
++#if !defined(_WIN32) && !defined(WIN32)
++      }else if( S_ISLNK(m) ){
++        char aStatic[64];
++        char *aBuf = aStatic;
++        int nBuf = 64;
++        int n;
++
++        while( 1 ){
++          n = readlink(pCur->zPath, aBuf, nBuf);
++          if( n<nBuf ) break;
++          if( aBuf!=aStatic ) sqlite3_free(aBuf);
++          nBuf = nBuf*2;
++          aBuf = sqlite3_malloc(nBuf);
++          if( aBuf==0 ){
++            sqlite3_result_error_nomem(ctx);
++            return SQLITE_NOMEM;
++          }
++        }
++
++        sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
++        if( aBuf!=aStatic ) sqlite3_free(aBuf);
++#endif
++      }else{
++        readFileContents(ctx, pCur->zPath);
++      }
++    }
++    case FSDIR_COLUMN_PATH:
++    default: {
++      /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
++      ** always return their values as NULL */
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/*
++** Return the rowid for the current row. In this implementation, the
++** first row returned is assigned rowid value 1, and each subsequent
++** row a value 1 more than that of the previous.
++*/
++static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++  *pRowid = pCur->iRowid;
++  return SQLITE_OK;
++}
++
++/*
++** Return TRUE if the cursor has been moved off of the last
++** row of output.
++*/
++static int fsdirEof(sqlite3_vtab_cursor *cur){
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++  return (pCur->zPath==0);
++}
++
++/*
++** xFilter callback.
++**
++** idxNum==1   PATH parameter only
++** idxNum==2   Both PATH and DIR supplied
++*/
++static int fsdirFilter(
++  sqlite3_vtab_cursor *cur, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  const char *zDir = 0;
++  fsdir_cursor *pCur = (fsdir_cursor*)cur;
++  (void)idxStr;
++  fsdirResetCursor(pCur);
++
++  if( idxNum==0 ){
++    fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
++    return SQLITE_ERROR;
++  }
++
++  assert( argc==idxNum && (argc==1 || argc==2) );
++  zDir = (const char*)sqlite3_value_text(argv[0]);
++  if( zDir==0 ){
++    fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
++    return SQLITE_ERROR;
++  }
++  if( argc==2 ){
++    pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
++  }
++  if( pCur->zBase ){
++    pCur->nBase = (int)strlen(pCur->zBase)+1;
++    pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
++  }else{
++    pCur->zPath = sqlite3_mprintf("%s", zDir);
++  }
++
++  if( pCur->zPath==0 ){
++    return SQLITE_NOMEM;
++  }
++  if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
++    fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
++    return SQLITE_ERROR;
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** SQLite will invoke this method one or more times while planning a query
++** that uses the generate_series virtual table.  This routine needs to create
++** a query plan for each invocation and compute an estimated cost for that
++** plan.
++**
++** In this implementation idxNum is used to represent the
++** query plan.  idxStr is unused.
++**
++** The query plan is represented by values of idxNum:
++**
++**  (1)  The path value is supplied by argv[0]
++**  (2)  Path is in argv[0] and dir is in argv[1]
++*/
++static int fsdirBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  int i;                 /* Loop over constraints */
++  int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
++  int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
++  int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
++  int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
++  const struct sqlite3_index_constraint *pConstraint;
++
++  (void)tab;
++  pConstraint = pIdxInfo->aConstraint;
++  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
++    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
++    switch( pConstraint->iColumn ){
++      case FSDIR_COLUMN_PATH: {
++        if( pConstraint->usable ){
++          idxPath = i;
++          seenPath = 0;
++        }else if( idxPath<0 ){
++          seenPath = 1;
++        }
++        break;
++      }
++      case FSDIR_COLUMN_DIR: {
++        if( pConstraint->usable ){
++          idxDir = i;
++          seenDir = 0;
++        }else if( idxDir<0 ){
++          seenDir = 1;
++        }
++        break;
++      }
++    } 
++  }
++  if( seenPath || seenDir ){
++    /* If input parameters are unusable, disallow this plan */
++    return SQLITE_CONSTRAINT;
++  }
++
++  if( idxPath<0 ){
++    pIdxInfo->idxNum = 0;
++    /* The pIdxInfo->estimatedCost should have been initialized to a huge
++    ** number.  Leave it unchanged. */
++    pIdxInfo->estimatedRows = 0x7fffffff;
++  }else{
++    pIdxInfo->aConstraintUsage[idxPath].omit = 1;
++    pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
++    if( idxDir>=0 ){
++      pIdxInfo->aConstraintUsage[idxDir].omit = 1;
++      pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
++      pIdxInfo->idxNum = 2;
++      pIdxInfo->estimatedCost = 10.0;
++    }else{
++      pIdxInfo->idxNum = 1;
++      pIdxInfo->estimatedCost = 100.0;
++    }
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** Register the "fsdir" virtual table.
++*/
++static int fsdirRegister(sqlite3 *db){
++  static sqlite3_module fsdirModule = {
++    0,                         /* iVersion */
++    0,                         /* xCreate */
++    fsdirConnect,              /* xConnect */
++    fsdirBestIndex,            /* xBestIndex */
++    fsdirDisconnect,           /* xDisconnect */
++    0,                         /* xDestroy */
++    fsdirOpen,                 /* xOpen - open a cursor */
++    fsdirClose,                /* xClose - close a cursor */
++    fsdirFilter,               /* xFilter - configure scan constraints */
++    fsdirNext,                 /* xNext - advance a cursor */
++    fsdirEof,                  /* xEof - check for end of scan */
++    fsdirColumn,               /* xColumn - read data */
++    fsdirRowid,                /* xRowid - read data */
++    0,                         /* xUpdate */
++    0,                         /* xBegin */
++    0,                         /* xSync */
++    0,                         /* xCommit */
++    0,                         /* xRollback */
++    0,                         /* xFindMethod */
++    0,                         /* xRename */
++    0,                         /* xSavepoint */
++    0,                         /* xRelease */
++    0,                         /* xRollbackTo */
++    0,                         /* xShadowName */
++  };
++
++  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
++  return rc;
++}
++#else         /* SQLITE_OMIT_VIRTUALTABLE */
++# define fsdirRegister(x) SQLITE_OK
++#endif
++
+ #ifdef _WIN32
+-__declspec(dllexport)
++
+ #endif
+ int sqlite3_fileio_init(
+   sqlite3 *db, 
+@@ -1624,9 +2978,16 @@
+   rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
+                                readfileFunc, 0, 0);
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
++    rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
+                                  writefileFunc, 0, 0);
+   }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
++                                 lsModeFunc, 0, 0);
++  }
++  if( rc==SQLITE_OK ){
++    rc = fsdirRegister(db);
++  }
+   return rc;
+ }
+ 
+@@ -1695,6 +3056,7 @@
+   char *zPrefix;             /* The prefix for the word we want to complete */
+   char *zLine;               /* The whole that we want to complete */
+   const char *zCurrentRow;   /* Current output row */
++  int szRow;                 /* Length of the zCurrentRow string */
+   sqlite3_stmt *pStmt;       /* Current statement */
+   sqlite3_int64 iRowid;      /* The rowid */
+   int ePhase;                /* Current phase */
+@@ -1711,7 +3073,7 @@
+ #define COMPLETION_INDEXES       5
+ #define COMPLETION_TRIGGERS      6
+ #define COMPLETION_DATABASES     7
+-#define COMPLETION_TABLES        8
++#define COMPLETION_TABLES        8    /* Also VIEWs and TRIGGERs */
+ #define COMPLETION_COLUMNS       9
+ #define COMPLETION_MODULES       10
+ #define COMPLETION_EOF           11
+@@ -1808,32 +3170,6 @@
+ }
+ 
+ /*
+-** All SQL keywords understood by SQLite
+-*/
+-static const char *completionKwrds[] = {
+-  "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
+-  "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
+-  "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
+-  "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
+-  "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
+-  "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
+-  "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
+-  "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
+-  "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
+-  "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
+-  "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
+-  "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
+-  "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
+-  "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
+-  "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
+-  "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
+-  "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
+-  "WITH", "WITHOUT",
+-};
+-#define completionKwCount \
+-   (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0]))
+-
+-/*
+ ** Advance a completion_cursor to its next row of output.
+ **
+ ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
+@@ -1855,11 +3191,11 @@
+   while( pCur->ePhase!=COMPLETION_EOF ){
+     switch( pCur->ePhase ){
+       case COMPLETION_KEYWORDS: {
+-        if( pCur->j >= completionKwCount ){
++        if( pCur->j >= sqlite3_keyword_count() ){
+           pCur->zCurrentRow = 0;
+           pCur->ePhase = COMPLETION_DATABASES;
+         }else{
+-          pCur->zCurrentRow = completionKwrds[pCur->j++];
++          sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
+         }
+         iCol = -1;
+         break;
+@@ -1883,8 +3219,7 @@
+             const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+             zSql = sqlite3_mprintf(
+                "%z%s"
+-               "SELECT name FROM \"%w\".sqlite_master"
+-               " WHERE type='table'",
++               "SELECT name FROM \"%w\".sqlite_master",
+                zSql, zSep, zDb
+             );
+             if( zSql==0 ) return SQLITE_NOMEM;
+@@ -1932,6 +3267,7 @@
+       if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
+         /* Extract the next row of content */
+         pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
++        pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
+       }else{
+         /* When all rows are finished, advance to the next phase */
+         sqlite3_finalize(pCur->pStmt);
+@@ -1941,7 +3277,9 @@
+       }
+     }
+     if( pCur->nPrefix==0 ) break;
+-    if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
++    if( pCur->nPrefix<=pCur->szRow
++     && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
++    ){
+       break;
+     }
+   }
+@@ -1961,7 +3299,7 @@
+   completion_cursor *pCur = (completion_cursor*)cur;
+   switch( i ){
+     case COMPLETION_COLUMN_CANDIDATE: {
+-      sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT);
++      sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
+       break;
+     }
+     case COMPLETION_COLUMN_PREFIX: {
+@@ -2021,7 +3359,7 @@
+       pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+       if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+     }
+-    iArg++;
++    iArg = 1;
+   }
+   if( idxNum & 2 ){
+     pCur->nLine = sqlite3_value_bytes(argv[iArg]);
+@@ -2029,7 +3367,6 @@
+       pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+       if( pCur->zLine==0 ) return SQLITE_NOMEM;
+     }
+-    iArg++;
+   }
+   if( pCur->zLine!=0 && pCur->zPrefix==0 ){
+     int i = pCur->nLine;
+@@ -2125,7 +3462,8 @@
+   0,                         /* xRename */
+   0,                         /* xSavepoint */
+   0,                         /* xRelease */
+-  0                          /* xRollbackTo */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
+ };
+ 
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -2139,7 +3477,7 @@
+ }
+ 
+ #ifdef _WIN32
+-__declspec(dllexport)
++
+ #endif
+ int sqlite3_completion_init(
+   sqlite3 *db, 
+@@ -2156,7 +3494,5004 @@
+ }
+ 
+ /************************* End ../ext/misc/completion.c ********************/
++/************************* Begin ../ext/misc/appendvfs.c ******************/
++/*
++** 2017-10-20
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file implements a VFS shim that allows an SQLite database to be
++** appended onto the end of some other file, such as an executable.
++**
++** A special record must appear at the end of the file that identifies the
++** file as an appended database and provides an offset to page 1.  For
++** best performance page 1 should be located at a disk page boundary, though
++** that is not required.
++**
++** When opening a database using this VFS, the connection might treat
++** the file as an ordinary SQLite database, or it might treat is as a
++** database appended onto some other file.  Here are the rules:
++**
++**  (1)  When opening a new empty file, that file is treated as an ordinary
++**       database.
++**
++**  (2)  When opening a file that begins with the standard SQLite prefix
++**       string "SQLite format 3", that file is treated as an ordinary
++**       database.
++**
++**  (3)  When opening a file that ends with the appendvfs trailer string
++**       "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
++**       database.
++**
++**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
++**       set, then a new database is appended to the already existing file.
++**
++**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
++**
++** To avoid unnecessary complications with the PENDING_BYTE, the size of
++** the file containing the database is limited to 1GB.  This VFS will refuse
++** to read or write past the 1GB mark.  This restriction might be lifted in
++** future versions.  For now, if you need a large database, then keep the
++** database in a separate file.
++**
++** If the file being opened is not an appended database, then this shim is
++** a pass-through into the default underlying VFS.
++**/
++SQLITE_EXTENSION_INIT1
++#include <string.h>
++#include <assert.h>
+ 
++/* The append mark at the end of the database is:
++**
++**     Start-Of-SQLite3-NNNNNNNN
++**     123456789 123456789 12345
++**
++** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
++** the offset to page 1.
++*/
++#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
++#define APND_MARK_PREFIX_SZ  17
++#define APND_MARK_SIZE       25
++
++/*
++** Maximum size of the combined prefix + database + append-mark.  This
++** must be less than 0x40000000 to avoid locking issues on Windows.
++*/
++#define APND_MAX_SIZE  (65536*15259)
++
++/*
++** Forward declaration of objects used by this utility
++*/
++typedef struct sqlite3_vfs ApndVfs;
++typedef struct ApndFile ApndFile;
++
++/* Access to a lower-level VFS that (might) implement dynamic loading,
++** access to randomness, etc.
++*/
++#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
++#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
++
++/* An open file */
++struct ApndFile {
++  sqlite3_file base;              /* IO methods */
++  sqlite3_int64 iPgOne;           /* File offset to page 1 */
++  sqlite3_int64 iMark;            /* Start of the append-mark */
++};
++
++/*
++** Methods for ApndFile
++*/
++static int apndClose(sqlite3_file*);
++static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
++static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
++static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
++static int apndSync(sqlite3_file*, int flags);
++static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
++static int apndLock(sqlite3_file*, int);
++static int apndUnlock(sqlite3_file*, int);
++static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
++static int apndFileControl(sqlite3_file*, int op, void *pArg);
++static int apndSectorSize(sqlite3_file*);
++static int apndDeviceCharacteristics(sqlite3_file*);
++static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
++static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
++static void apndShmBarrier(sqlite3_file*);
++static int apndShmUnmap(sqlite3_file*, int deleteFlag);
++static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
++static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
++
++/*
++** Methods for ApndVfs
++*/
++static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
++static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
++static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
++static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
++static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
++static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
++static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
++static void apndDlClose(sqlite3_vfs*, void*);
++static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
++static int apndSleep(sqlite3_vfs*, int microseconds);
++static int apndCurrentTime(sqlite3_vfs*, double*);
++static int apndGetLastError(sqlite3_vfs*, int, char *);
++static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
++static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
++static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
++static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
++
++static sqlite3_vfs apnd_vfs = {
++  3,                            /* iVersion (set when registered) */
++  0,                            /* szOsFile (set when registered) */
++  1024,                         /* mxPathname */
++  0,                            /* pNext */
++  "apndvfs",                    /* zName */
++  0,                            /* pAppData (set when registered) */ 
++  apndOpen,                     /* xOpen */
++  apndDelete,                   /* xDelete */
++  apndAccess,                   /* xAccess */
++  apndFullPathname,             /* xFullPathname */
++  apndDlOpen,                   /* xDlOpen */
++  apndDlError,                  /* xDlError */
++  apndDlSym,                    /* xDlSym */
++  apndDlClose,                  /* xDlClose */
++  apndRandomness,               /* xRandomness */
++  apndSleep,                    /* xSleep */
++  apndCurrentTime,              /* xCurrentTime */
++  apndGetLastError,             /* xGetLastError */
++  apndCurrentTimeInt64,         /* xCurrentTimeInt64 */
++  apndSetSystemCall,            /* xSetSystemCall */
++  apndGetSystemCall,            /* xGetSystemCall */
++  apndNextSystemCall            /* xNextSystemCall */
++};
++
++static const sqlite3_io_methods apnd_io_methods = {
++  3,                              /* iVersion */
++  apndClose,                      /* xClose */
++  apndRead,                       /* xRead */
++  apndWrite,                      /* xWrite */
++  apndTruncate,                   /* xTruncate */
++  apndSync,                       /* xSync */
++  apndFileSize,                   /* xFileSize */
++  apndLock,                       /* xLock */
++  apndUnlock,                     /* xUnlock */
++  apndCheckReservedLock,          /* xCheckReservedLock */
++  apndFileControl,                /* xFileControl */
++  apndSectorSize,                 /* xSectorSize */
++  apndDeviceCharacteristics,      /* xDeviceCharacteristics */
++  apndShmMap,                     /* xShmMap */
++  apndShmLock,                    /* xShmLock */
++  apndShmBarrier,                 /* xShmBarrier */
++  apndShmUnmap,                   /* xShmUnmap */
++  apndFetch,                      /* xFetch */
++  apndUnfetch                     /* xUnfetch */
++};
++
++
++
++/*
++** Close an apnd-file.
++*/
++static int apndClose(sqlite3_file *pFile){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xClose(pFile);
++}
++
++/*
++** Read data from an apnd-file.
++*/
++static int apndRead(
++  sqlite3_file *pFile, 
++  void *zBuf, 
++  int iAmt, 
++  sqlite_int64 iOfst
++){
++  ApndFile *p = (ApndFile *)pFile;
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
++}
++
++/*
++** Add the append-mark onto the end of the file.
++*/
++static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
++  int i;
++  unsigned char a[APND_MARK_SIZE];
++  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
++  for(i=0; i<8; i++){
++    a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
++  }
++  return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
++}
++
++/*
++** Write data to an apnd-file.
++*/
++static int apndWrite(
++  sqlite3_file *pFile,
++  const void *zBuf,
++  int iAmt,
++  sqlite_int64 iOfst
++){
++  int rc;
++  ApndFile *p = (ApndFile *)pFile;
++  pFile = ORIGFILE(pFile);
++  if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
++  rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
++  if( rc==SQLITE_OK &&  iOfst + iAmt + p->iPgOne > p->iMark ){
++    sqlite3_int64 sz = 0;
++    rc = pFile->pMethods->xFileSize(pFile, &sz);
++    if( rc==SQLITE_OK ){
++      p->iMark = sz - APND_MARK_SIZE;
++      if( iOfst + iAmt + p->iPgOne > p->iMark ){
++        p->iMark = p->iPgOne + iOfst + iAmt;
++        rc = apndWriteMark(p, pFile);
++      }
++    }
++  }
++  return rc;
++}
++
++/*
++** Truncate an apnd-file.
++*/
++static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
++  int rc;
++  ApndFile *p = (ApndFile *)pFile;
++  pFile = ORIGFILE(pFile);
++  rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
++  if( rc==SQLITE_OK ){
++    p->iMark = p->iPgOne+size;
++    rc = apndWriteMark(p, pFile);
++  }
++  return rc;
++}
++
++/*
++** Sync an apnd-file.
++*/
++static int apndSync(sqlite3_file *pFile, int flags){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xSync(pFile, flags);
++}
++
++/*
++** Return the current file-size of an apnd-file.
++*/
++static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
++  ApndFile *p = (ApndFile *)pFile;
++  int rc;
++  pFile = ORIGFILE(p);
++  rc = pFile->pMethods->xFileSize(pFile, pSize);
++  if( rc==SQLITE_OK && p->iPgOne ){
++    *pSize -= p->iPgOne + APND_MARK_SIZE;
++  }
++  return rc;
++}
++
++/*
++** Lock an apnd-file.
++*/
++static int apndLock(sqlite3_file *pFile, int eLock){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xLock(pFile, eLock);
++}
++
++/*
++** Unlock an apnd-file.
++*/
++static int apndUnlock(sqlite3_file *pFile, int eLock){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xUnlock(pFile, eLock);
++}
++
++/*
++** Check if another file-handle holds a RESERVED lock on an apnd-file.
++*/
++static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
++}
++
++/*
++** File control method. For custom operations on an apnd-file.
++*/
++static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
++  ApndFile *p = (ApndFile *)pFile;
++  int rc;
++  pFile = ORIGFILE(pFile);
++  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
++  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
++    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
++  }
++  return rc;
++}
++
++/*
++** Return the sector-size in bytes for an apnd-file.
++*/
++static int apndSectorSize(sqlite3_file *pFile){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xSectorSize(pFile);
++}
++
++/*
++** Return the device characteristic flags supported by an apnd-file.
++*/
++static int apndDeviceCharacteristics(sqlite3_file *pFile){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xDeviceCharacteristics(pFile);
++}
++
++/* Create a shared memory file mapping */
++static int apndShmMap(
++  sqlite3_file *pFile,
++  int iPg,
++  int pgsz,
++  int bExtend,
++  void volatile **pp
++){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
++}
++
++/* Perform locking on a shared-memory segment */
++static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
++}
++
++/* Memory barrier operation on shared memory */
++static void apndShmBarrier(sqlite3_file *pFile){
++  pFile = ORIGFILE(pFile);
++  pFile->pMethods->xShmBarrier(pFile);
++}
++
++/* Unmap a shared memory segment */
++static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
++}
++
++/* Fetch a page of a memory-mapped file */
++static int apndFetch(
++  sqlite3_file *pFile,
++  sqlite3_int64 iOfst,
++  int iAmt,
++  void **pp
++){
++  ApndFile *p = (ApndFile *)pFile;
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
++}
++
++/* Release a memory-mapped page */
++static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
++  ApndFile *p = (ApndFile *)pFile;
++  pFile = ORIGFILE(pFile);
++  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
++}
++
++/*
++** Check to see if the file is an ordinary SQLite database file.
++*/
++static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
++  int rc;
++  char zHdr[16];
++  static const char aSqliteHdr[] = "SQLite format 3";
++  if( sz<512 ) return 0;
++  rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
++  if( rc ) return 0;
++  return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
++}
++
++/*
++** Try to read the append-mark off the end of a file.  Return the
++** start of the appended database if the append-mark is present.  If
++** there is no append-mark, return -1;
++*/
++static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
++  int rc, i;
++  sqlite3_int64 iMark;
++  unsigned char a[APND_MARK_SIZE];
++
++  if( sz<=APND_MARK_SIZE ) return -1;
++  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
++  if( rc ) return -1;
++  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
++  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
++  for(i=1; i<8; i++){    
++    iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
++  }
++  return iMark;
++}
++
++/*
++** Open an apnd file handle.
++*/
++static int apndOpen(
++  sqlite3_vfs *pVfs,
++  const char *zName,
++  sqlite3_file *pFile,
++  int flags,
++  int *pOutFlags
++){
++  ApndFile *p;
++  sqlite3_file *pSubFile;
++  sqlite3_vfs *pSubVfs;
++  int rc;
++  sqlite3_int64 sz;
++  pSubVfs = ORIGVFS(pVfs);
++  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
++    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
++  }
++  p = (ApndFile*)pFile;
++  memset(p, 0, sizeof(*p));
++  pSubFile = ORIGFILE(pFile);
++  p->base.pMethods = &apnd_io_methods;
++  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
++  if( rc ) goto apnd_open_done;
++  rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
++  if( rc ){
++    pSubFile->pMethods->xClose(pSubFile);
++    goto apnd_open_done;
++  }
++  if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
++    memmove(pFile, pSubFile, pSubVfs->szOsFile);
++    return SQLITE_OK;
++  }
++  p->iMark = 0;
++  p->iPgOne = apndReadMark(sz, pFile);
++  if( p->iPgOne>0 ){
++    return SQLITE_OK;
++  }
++  if( (flags & SQLITE_OPEN_CREATE)==0 ){
++    pSubFile->pMethods->xClose(pSubFile);
++    rc = SQLITE_CANTOPEN;
++  }
++  p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
++apnd_open_done:
++  if( rc ) pFile->pMethods = 0;
++  return rc;
++}
++
++/*
++** All other VFS methods are pass-thrus.
++*/
++static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
++  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
++}
++static int apndAccess(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int flags, 
++  int *pResOut
++){
++  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
++}
++static int apndFullPathname(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int nOut, 
++  char *zOut
++){
++  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
++}
++static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
++  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
++}
++static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
++  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
++}
++static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
++  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
++}
++static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
++  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
++}
++static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
++  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
++}
++static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
++  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
++}
++static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
++  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
++}
++static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
++  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
++}
++static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
++  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
++}
++static int apndSetSystemCall(
++  sqlite3_vfs *pVfs,
++  const char *zName,
++  sqlite3_syscall_ptr pCall
++){
++  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
++}
++static sqlite3_syscall_ptr apndGetSystemCall(
++  sqlite3_vfs *pVfs,
++  const char *zName
++){
++  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
++}
++static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
++  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
++}
++
++  
++#ifdef _WIN32
++
++#endif
++/* 
++** This routine is called when the extension is loaded.
++** Register the new VFS.
++*/
++int sqlite3_appendvfs_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  int rc = SQLITE_OK;
++  sqlite3_vfs *pOrig;
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;
++  (void)db;
++  pOrig = sqlite3_vfs_find(0);
++  apnd_vfs.iVersion = pOrig->iVersion;
++  apnd_vfs.pAppData = pOrig;
++  apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
++  rc = sqlite3_vfs_register(&apnd_vfs, 0);
++#ifdef APPENDVFS_TEST
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
++  }
++#endif
++  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
++  return rc;
++}
++
++/************************* End ../ext/misc/appendvfs.c ********************/
++#ifdef SQLITE_HAVE_ZLIB
++/************************* Begin ../ext/misc/zipfile.c ******************/
++/*
++** 2017-12-26
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file implements a virtual table for reading and writing ZIP archive
++** files.
++**
++** Usage example:
++**
++**     SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
++**
++** Current limitations:
++**
++**    *  No support for encryption
++**    *  No support for ZIP archives spanning multiple files
++**    *  No support for zip64 extensions
++**    *  Only the "inflate/deflate" (zlib) compression method is supported
++*/
++SQLITE_EXTENSION_INIT1
++#include <stdio.h>
++#include <string.h>
++#include <assert.h>
++
++#include <zlib.h>
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++
++#ifndef SQLITE_AMALGAMATION
++
++/* typedef sqlite3_int64 i64; */
++/* typedef unsigned char u8; */
++typedef unsigned short u16;
++typedef unsigned long u32;
++#define MIN(a,b) ((a)<(b) ? (a) : (b))
++
++#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
++# define ALWAYS(X)      (1)
++# define NEVER(X)       (0)
++#elif !defined(NDEBUG)
++# define ALWAYS(X)      ((X)?1:(assert(0),0))
++# define NEVER(X)       ((X)?(assert(0),1):0)
++#else
++# define ALWAYS(X)      (X)
++# define NEVER(X)       (X)
++#endif
++
++#endif   /* SQLITE_AMALGAMATION */
++
++/*
++** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
++**
++** In some ways it would be better to obtain these values from system 
++** header files. But, the dependency is undesirable and (a) these
++** have been stable for decades, (b) the values are part of POSIX and
++** are also made explicit in [man stat], and (c) are part of the 
++** file format for zip archives.
++*/
++#ifndef S_IFDIR
++# define S_IFDIR 0040000
++#endif
++#ifndef S_IFREG
++# define S_IFREG 0100000
++#endif
++#ifndef S_IFLNK
++# define S_IFLNK 0120000
++#endif
++
++static const char ZIPFILE_SCHEMA[] = 
++  "CREATE TABLE y("
++    "name PRIMARY KEY,"  /* 0: Name of file in zip archive */
++    "mode,"              /* 1: POSIX mode for file */
++    "mtime,"             /* 2: Last modification time (secs since 1970)*/
++    "sz,"                /* 3: Size of object */
++    "rawdata,"           /* 4: Raw data */
++    "data,"              /* 5: Uncompressed data */
++    "method,"            /* 6: Compression method (integer) */
++    "z HIDDEN"           /* 7: Name of zip file */
++  ") WITHOUT ROWID;";
++
++#define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
++#define ZIPFILE_BUFFER_SIZE (64*1024)
++
++
++/*
++** Magic numbers used to read and write zip files.
++**
++** ZIPFILE_NEWENTRY_MADEBY:
++**   Use this value for the "version-made-by" field in new zip file
++**   entries. The upper byte indicates "unix", and the lower byte 
++**   indicates that the zip file matches pkzip specification 3.0. 
++**   This is what info-zip seems to do.
++**
++** ZIPFILE_NEWENTRY_REQUIRED:
++**   Value for "version-required-to-extract" field of new entries.
++**   Version 2.0 is required to support folders and deflate compression.
++**
++** ZIPFILE_NEWENTRY_FLAGS:
++**   Value for "general-purpose-bit-flags" field of new entries. Bit
++**   11 means "utf-8 filename and comment".
++**
++** ZIPFILE_SIGNATURE_CDS:
++**   First 4 bytes of a valid CDS record.
++**
++** ZIPFILE_SIGNATURE_LFH:
++**   First 4 bytes of a valid LFH record.
++**
++** ZIPFILE_SIGNATURE_EOCD
++**   First 4 bytes of a valid EOCD record.
++*/
++#define ZIPFILE_EXTRA_TIMESTAMP   0x5455
++#define ZIPFILE_NEWENTRY_MADEBY   ((3<<8) + 30)
++#define ZIPFILE_NEWENTRY_REQUIRED 20
++#define ZIPFILE_NEWENTRY_FLAGS    0x800
++#define ZIPFILE_SIGNATURE_CDS     0x02014b50
++#define ZIPFILE_SIGNATURE_LFH     0x04034b50
++#define ZIPFILE_SIGNATURE_EOCD    0x06054b50
++
++/*
++** The sizes of the fixed-size part of each of the three main data 
++** structures in a zip archive.
++*/
++#define ZIPFILE_LFH_FIXED_SZ      30
++#define ZIPFILE_EOCD_FIXED_SZ     22
++#define ZIPFILE_CDS_FIXED_SZ      46
++
++/*
++*** 4.3.16  End of central directory record:
++***
++***   end of central dir signature    4 bytes  (0x06054b50)
++***   number of this disk             2 bytes
++***   number of the disk with the
++***   start of the central directory  2 bytes
++***   total number of entries in the
++***   central directory on this disk  2 bytes
++***   total number of entries in
++***   the central directory           2 bytes
++***   size of the central directory   4 bytes
++***   offset of start of central
++***   directory with respect to
++***   the starting disk number        4 bytes
++***   .ZIP file comment length        2 bytes
++***   .ZIP file comment       (variable size)
++*/
++typedef struct ZipfileEOCD ZipfileEOCD;
++struct ZipfileEOCD {
++  u16 iDisk;
++  u16 iFirstDisk;
++  u16 nEntry;
++  u16 nEntryTotal;
++  u32 nSize;
++  u32 iOffset;
++};
++
++/*
++*** 4.3.12  Central directory structure:
++***
++*** ...
++***
++***   central file header signature   4 bytes  (0x02014b50)
++***   version made by                 2 bytes
++***   version needed to extract       2 bytes
++***   general purpose bit flag        2 bytes
++***   compression method              2 bytes
++***   last mod file time              2 bytes
++***   last mod file date              2 bytes
++***   crc-32                          4 bytes
++***   compressed size                 4 bytes
++***   uncompressed size               4 bytes
++***   file name length                2 bytes
++***   extra field length              2 bytes
++***   file comment length             2 bytes
++***   disk number start               2 bytes
++***   internal file attributes        2 bytes
++***   external file attributes        4 bytes
++***   relative offset of local header 4 bytes
++*/
++typedef struct ZipfileCDS ZipfileCDS;
++struct ZipfileCDS {
++  u16 iVersionMadeBy;
++  u16 iVersionExtract;
++  u16 flags;
++  u16 iCompression;
++  u16 mTime;
++  u16 mDate;
++  u32 crc32;
++  u32 szCompressed;
++  u32 szUncompressed;
++  u16 nFile;
++  u16 nExtra;
++  u16 nComment;
++  u16 iDiskStart;
++  u16 iInternalAttr;
++  u32 iExternalAttr;
++  u32 iOffset;
++  char *zFile;                    /* Filename (sqlite3_malloc()) */
++};
++
++/*
++*** 4.3.7  Local file header:
++***
++***   local file header signature     4 bytes  (0x04034b50)
++***   version needed to extract       2 bytes
++***   general purpose bit flag        2 bytes
++***   compression method              2 bytes
++***   last mod file time              2 bytes
++***   last mod file date              2 bytes
++***   crc-32                          4 bytes
++***   compressed size                 4 bytes
++***   uncompressed size               4 bytes
++***   file name length                2 bytes
++***   extra field length              2 bytes
++***   
++*/
++typedef struct ZipfileLFH ZipfileLFH;
++struct ZipfileLFH {
++  u16 iVersionExtract;
++  u16 flags;
++  u16 iCompression;
++  u16 mTime;
++  u16 mDate;
++  u32 crc32;
++  u32 szCompressed;
++  u32 szUncompressed;
++  u16 nFile;
++  u16 nExtra;
++};
++
++typedef struct ZipfileEntry ZipfileEntry;
++struct ZipfileEntry {
++  ZipfileCDS cds;            /* Parsed CDS record */
++  u32 mUnixTime;             /* Modification time, in UNIX format */
++  u8 *aExtra;                /* cds.nExtra+cds.nComment bytes of extra data */
++  i64 iDataOff;              /* Offset to data in file (if aData==0) */
++  u8 *aData;                 /* cds.szCompressed bytes of compressed data */
++  ZipfileEntry *pNext;       /* Next element in in-memory CDS */
++};
++
++/* 
++** Cursor type for zipfile tables.
++*/
++typedef struct ZipfileCsr ZipfileCsr;
++struct ZipfileCsr {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++  i64 iId;                   /* Cursor ID */
++  u8 bEof;                   /* True when at EOF */
++  u8 bNoop;                  /* If next xNext() call is no-op */
++
++  /* Used outside of write transactions */
++  FILE *pFile;               /* Zip file */
++  i64 iNextOff;              /* Offset of next record in central directory */
++  ZipfileEOCD eocd;          /* Parse of central directory record */
++
++  ZipfileEntry *pFreeEntry;  /* Free this list when cursor is closed or reset */
++  ZipfileEntry *pCurrent;    /* Current entry */
++  ZipfileCsr *pCsrNext;      /* Next cursor on same virtual table */
++};
++
++typedef struct ZipfileTab ZipfileTab;
++struct ZipfileTab {
++  sqlite3_vtab base;         /* Base class - must be first */
++  char *zFile;               /* Zip file this table accesses (may be NULL) */
++  sqlite3 *db;               /* Host database connection */
++  u8 *aBuffer;               /* Temporary buffer used for various tasks */
++
++  ZipfileCsr *pCsrList;      /* List of cursors */
++  i64 iNextCsrid;
++
++  /* The following are used by write transactions only */
++  ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
++  ZipfileEntry *pLastEntry;  /* Last element in pFirstEntry list */
++  FILE *pWriteFd;            /* File handle open on zip archive */
++  i64 szCurrent;             /* Current size of zip archive */
++  i64 szOrig;                /* Size of archive at start of transaction */
++};
++
++/*
++** Set the error message contained in context ctx to the results of
++** vprintf(zFmt, ...).
++*/
++static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
++  char *zMsg = 0;
++  va_list ap;
++  va_start(ap, zFmt);
++  zMsg = sqlite3_vmprintf(zFmt, ap);
++  sqlite3_result_error(ctx, zMsg, -1);
++  sqlite3_free(zMsg);
++  va_end(ap);
++}
++
++/*
++** If string zIn is quoted, dequote it in place. Otherwise, if the string
++** is not quoted, do nothing.
++*/
++static void zipfileDequote(char *zIn){
++  char q = zIn[0];
++  if( q=='"' || q=='\'' || q=='`' || q=='[' ){
++    int iIn = 1;
++    int iOut = 0;
++    if( q=='[' ) q = ']';
++    while( ALWAYS(zIn[iIn]) ){
++      char c = zIn[iIn++];
++      if( c==q && zIn[iIn++]!=q ) break;
++      zIn[iOut++] = c;
++    }
++    zIn[iOut] = '\0';
++  }
++}
++
++/*
++** Construct a new ZipfileTab virtual table object.
++** 
++**   argv[0]   -> module name  ("zipfile")
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**   argv[...] -> "column name" and other module argument fields.
++*/
++static int zipfileConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
++  int nFile = 0;
++  const char *zFile = 0;
++  ZipfileTab *pNew = 0;
++  int rc;
++
++  /* If the table name is not "zipfile", require that the argument be
++  ** specified. This stops zipfile tables from being created as:
++  **
++  **   CREATE VIRTUAL TABLE zzz USING zipfile();
++  **
++  ** It does not prevent:
++  **
++  **   CREATE VIRTUAL TABLE zipfile USING zipfile();
++  */
++  assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
++  if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
++    *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
++    return SQLITE_ERROR;
++  }
++
++  if( argc>3 ){
++    zFile = argv[3];
++    nFile = (int)strlen(zFile)+1;
++  }
++
++  rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
++  if( rc==SQLITE_OK ){
++    pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile);
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, nByte+nFile);
++    pNew->db = db;
++    pNew->aBuffer = (u8*)&pNew[1];
++    if( zFile ){
++      pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
++      memcpy(pNew->zFile, zFile, nFile);
++      zipfileDequote(pNew->zFile);
++    }
++  }
++  *ppVtab = (sqlite3_vtab*)pNew;
++  return rc;
++}
++
++/*
++** Free the ZipfileEntry structure indicated by the only argument.
++*/
++static void zipfileEntryFree(ZipfileEntry *p){
++  if( p ){
++    sqlite3_free(p->cds.zFile);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Release resources that should be freed at the end of a write 
++** transaction.
++*/
++static void zipfileCleanupTransaction(ZipfileTab *pTab){
++  ZipfileEntry *pEntry;
++  ZipfileEntry *pNext;
++
++  if( pTab->pWriteFd ){
++    fclose(pTab->pWriteFd);
++    pTab->pWriteFd = 0;
++  }
++  for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
++    pNext = pEntry->pNext;
++    zipfileEntryFree(pEntry);
++  }
++  pTab->pFirstEntry = 0;
++  pTab->pLastEntry = 0;
++  pTab->szCurrent = 0;
++  pTab->szOrig = 0;
++}
++
++/*
++** This method is the destructor for zipfile vtab objects.
++*/
++static int zipfileDisconnect(sqlite3_vtab *pVtab){
++  zipfileCleanupTransaction((ZipfileTab*)pVtab);
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/*
++** Constructor for a new ZipfileCsr object.
++*/
++static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
++  ZipfileTab *pTab = (ZipfileTab*)p;
++  ZipfileCsr *pCsr;
++  pCsr = sqlite3_malloc(sizeof(*pCsr));
++  *ppCsr = (sqlite3_vtab_cursor*)pCsr;
++  if( pCsr==0 ){
++    return SQLITE_NOMEM;
++  }
++  memset(pCsr, 0, sizeof(*pCsr));
++  pCsr->iId = ++pTab->iNextCsrid;
++  pCsr->pCsrNext = pTab->pCsrList;
++  pTab->pCsrList = pCsr;
++  return SQLITE_OK;
++}
++
++/*
++** Reset a cursor back to the state it was in when first returned
++** by zipfileOpen().
++*/
++static void zipfileResetCursor(ZipfileCsr *pCsr){
++  ZipfileEntry *p;
++  ZipfileEntry *pNext;
++
++  pCsr->bEof = 0;
++  if( pCsr->pFile ){
++    fclose(pCsr->pFile);
++    pCsr->pFile = 0;
++    zipfileEntryFree(pCsr->pCurrent);
++    pCsr->pCurrent = 0;
++  }
++
++  for(p=pCsr->pFreeEntry; p; p=pNext){
++    pNext = p->pNext;
++    zipfileEntryFree(p);
++  }
++}
++
++/*
++** Destructor for an ZipfileCsr.
++*/
++static int zipfileClose(sqlite3_vtab_cursor *cur){
++  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
++  ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
++  ZipfileCsr **pp;
++  zipfileResetCursor(pCsr);
++
++  /* Remove this cursor from the ZipfileTab.pCsrList list. */
++  for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext));
++  *pp = pCsr->pCsrNext;
++
++  sqlite3_free(pCsr);
++  return SQLITE_OK;
++}
++
++/*
++** Set the error message for the virtual table associated with cursor
++** pCsr to the results of vprintf(zFmt, ...).
++*/
++static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
++  va_list ap;
++  va_start(ap, zFmt);
++  sqlite3_free(pTab->base.zErrMsg);
++  pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
++  va_end(ap);
++}
++static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
++  va_list ap;
++  va_start(ap, zFmt);
++  sqlite3_free(pCsr->base.pVtab->zErrMsg);
++  pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
++  va_end(ap);
++}
++
++/*
++** Read nRead bytes of data from offset iOff of file pFile into buffer
++** aRead[]. Return SQLITE_OK if successful, or an SQLite error code
++** otherwise. 
++**
++** If an error does occur, output variable (*pzErrmsg) may be set to point
++** to an English language error message. It is the responsibility of the
++** caller to eventually free this buffer using
++** sqlite3_free().
++*/
++static int zipfileReadData(
++  FILE *pFile,                    /* Read from this file */
++  u8 *aRead,                      /* Read into this buffer */
++  int nRead,                      /* Number of bytes to read */
++  i64 iOff,                       /* Offset to read from */
++  char **pzErrmsg                 /* OUT: Error message (from sqlite3_malloc) */
++){
++  size_t n;
++  fseek(pFile, (long)iOff, SEEK_SET);
++  n = fread(aRead, 1, nRead, pFile);
++  if( (int)n!=nRead ){
++    *pzErrmsg = sqlite3_mprintf("error in fread()");
++    return SQLITE_ERROR;
++  }
++  return SQLITE_OK;
++}
++
++static int zipfileAppendData(
++  ZipfileTab *pTab,
++  const u8 *aWrite,
++  int nWrite
++){
++  size_t n;
++  fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
++  n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
++  if( (int)n!=nWrite ){
++    pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
++    return SQLITE_ERROR;
++  }
++  pTab->szCurrent += nWrite;
++  return SQLITE_OK;
++}
++
++/*
++** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
++*/
++static u16 zipfileGetU16(const u8 *aBuf){
++  return (aBuf[1] << 8) + aBuf[0];
++}
++
++/*
++** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
++*/
++static u32 zipfileGetU32(const u8 *aBuf){
++  return ((u32)(aBuf[3]) << 24)
++       + ((u32)(aBuf[2]) << 16)
++       + ((u32)(aBuf[1]) <<  8)
++       + ((u32)(aBuf[0]) <<  0);
++}
++
++/*
++** Write a 16-bit little endiate integer into buffer aBuf.
++*/
++static void zipfilePutU16(u8 *aBuf, u16 val){
++  aBuf[0] = val & 0xFF;
++  aBuf[1] = (val>>8) & 0xFF;
++}
++
++/*
++** Write a 32-bit little endiate integer into buffer aBuf.
++*/
++static void zipfilePutU32(u8 *aBuf, u32 val){
++  aBuf[0] = val & 0xFF;
++  aBuf[1] = (val>>8) & 0xFF;
++  aBuf[2] = (val>>16) & 0xFF;
++  aBuf[3] = (val>>24) & 0xFF;
++}
++
++#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
++#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
++
++#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
++#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
++
++/*
++** Magic numbers used to read CDS records.
++*/
++#define ZIPFILE_CDS_NFILE_OFF        28
++#define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
++
++/*
++** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
++** if the record is not well-formed, or SQLITE_OK otherwise.
++*/
++static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
++  u8 *aRead = aBuf;
++  u32 sig = zipfileRead32(aRead);
++  int rc = SQLITE_OK;
++  if( sig!=ZIPFILE_SIGNATURE_CDS ){
++    rc = SQLITE_ERROR;
++  }else{
++    pCDS->iVersionMadeBy = zipfileRead16(aRead);
++    pCDS->iVersionExtract = zipfileRead16(aRead);
++    pCDS->flags = zipfileRead16(aRead);
++    pCDS->iCompression = zipfileRead16(aRead);
++    pCDS->mTime = zipfileRead16(aRead);
++    pCDS->mDate = zipfileRead16(aRead);
++    pCDS->crc32 = zipfileRead32(aRead);
++    pCDS->szCompressed = zipfileRead32(aRead);
++    pCDS->szUncompressed = zipfileRead32(aRead);
++    assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
++    pCDS->nFile = zipfileRead16(aRead);
++    pCDS->nExtra = zipfileRead16(aRead);
++    pCDS->nComment = zipfileRead16(aRead);
++    pCDS->iDiskStart = zipfileRead16(aRead);
++    pCDS->iInternalAttr = zipfileRead16(aRead);
++    pCDS->iExternalAttr = zipfileRead32(aRead);
++    pCDS->iOffset = zipfileRead32(aRead);
++    assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
++  }
++
++  return rc;
++}
++
++/*
++** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
++** if the record is not well-formed, or SQLITE_OK otherwise.
++*/
++static int zipfileReadLFH(
++  u8 *aBuffer,
++  ZipfileLFH *pLFH
++){
++  u8 *aRead = aBuffer;
++  int rc = SQLITE_OK;
++
++  u32 sig = zipfileRead32(aRead);
++  if( sig!=ZIPFILE_SIGNATURE_LFH ){
++    rc = SQLITE_ERROR;
++  }else{
++    pLFH->iVersionExtract = zipfileRead16(aRead);
++    pLFH->flags = zipfileRead16(aRead);
++    pLFH->iCompression = zipfileRead16(aRead);
++    pLFH->mTime = zipfileRead16(aRead);
++    pLFH->mDate = zipfileRead16(aRead);
++    pLFH->crc32 = zipfileRead32(aRead);
++    pLFH->szCompressed = zipfileRead32(aRead);
++    pLFH->szUncompressed = zipfileRead32(aRead);
++    pLFH->nFile = zipfileRead16(aRead);
++    pLFH->nExtra = zipfileRead16(aRead);
++  }
++  return rc;
++}
++
++
++/*
++** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
++** Scan through this buffer to find an "extra-timestamp" field. If one
++** exists, extract the 32-bit modification-timestamp from it and store
++** the value in output parameter *pmTime.
++**
++** Zero is returned if no extra-timestamp record could be found (and so
++** *pmTime is left unchanged), or non-zero otherwise.
++**
++** The general format of an extra field is:
++**
++**   Header ID    2 bytes
++**   Data Size    2 bytes
++**   Data         N bytes
++*/
++static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
++  int ret = 0;
++  u8 *p = aExtra;
++  u8 *pEnd = &aExtra[nExtra];
++
++  while( p<pEnd ){
++    u16 id = zipfileRead16(p);
++    u16 nByte = zipfileRead16(p);
++
++    switch( id ){
++      case ZIPFILE_EXTRA_TIMESTAMP: {
++        u8 b = p[0];
++        if( b & 0x01 ){     /* 0x01 -> modtime is present */
++          *pmTime = zipfileGetU32(&p[1]);
++          ret = 1;
++        }
++        break;
++      }
++    }
++
++    p += nByte;
++  }
++  return ret;
++}
++
++/*
++** Convert the standard MS-DOS timestamp stored in the mTime and mDate
++** fields of the CDS structure passed as the only argument to a 32-bit
++** UNIX seconds-since-the-epoch timestamp. Return the result.
++**
++** "Standard" MS-DOS time format:
++**
++**   File modification time:
++**     Bits 00-04: seconds divided by 2
++**     Bits 05-10: minute
++**     Bits 11-15: hour
++**   File modification date:
++**     Bits 00-04: day
++**     Bits 05-08: month (1-12)
++**     Bits 09-15: years from 1980 
++**
++** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
++*/
++static u32 zipfileMtime(ZipfileCDS *pCDS){
++  int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
++  int M = ((pCDS->mDate >> 5) & 0x0F);
++  int D = (pCDS->mDate & 0x1F);
++  int B = -13;
++
++  int sec = (pCDS->mTime & 0x1F)*2;
++  int min = (pCDS->mTime >> 5) & 0x3F;
++  int hr = (pCDS->mTime >> 11) & 0x1F;
++  i64 JD;
++
++  /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
++
++  /* Calculate the JD in seconds for noon on the day in question */
++  if( M<3 ){
++    Y = Y-1;
++    M = M+12;
++  }
++  JD = (i64)(24*60*60) * (
++      (int)(365.25 * (Y + 4716))
++    + (int)(30.6001 * (M + 1))
++    + D + B - 1524
++  );
++
++  /* Correct the JD for the time within the day */
++  JD += (hr-12) * 3600 + min * 60 + sec;
++
++  /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
++  return (u32)(JD - (i64)(24405875) * 24*60*6);
++}
++
++/*
++** The opposite of zipfileMtime(). This function populates the mTime and
++** mDate fields of the CDS structure passed as the first argument according
++** to the UNIX timestamp value passed as the second.
++*/
++static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
++  /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
++  i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
++
++  int A, B, C, D, E;
++  int yr, mon, day;
++  int hr, min, sec;
++
++  A = (int)((JD - 1867216.25)/36524.25);
++  A = (int)(JD + 1 + A - (A/4));
++  B = A + 1524;
++  C = (int)((B - 122.1)/365.25);
++  D = (36525*(C&32767))/100;
++  E = (int)((B-D)/30.6001);
++
++  day = B - D - (int)(30.6001*E);
++  mon = (E<14 ? E-1 : E-13);
++  yr = mon>2 ? C-4716 : C-4715;
++
++  hr = (mUnixTime % (24*60*60)) / (60*60);
++  min = (mUnixTime % (60*60)) / 60;
++  sec = (mUnixTime % 60);
++
++  if( yr>=1980 ){
++    pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
++    pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
++  }else{
++    pCds->mDate = pCds->mTime = 0;
++  }
++
++  assert( mUnixTime<315507600 
++       || mUnixTime==zipfileMtime(pCds) 
++       || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) 
++       /* || (mUnixTime % 2) */
++  );
++}
++
++/*
++** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
++** size) containing an entire zip archive image. Or, if aBlob is NULL,
++** then pFile is a file-handle open on a zip file. In either case, this
++** function creates a ZipfileEntry object based on the zip archive entry
++** for which the CDS record is at offset iOff.
++**
++** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
++** the new object. Otherwise, an SQLite error code is returned and the
++** final value of (*ppEntry) undefined.
++*/
++static int zipfileGetEntry(
++  ZipfileTab *pTab,               /* Store any error message here */
++  const u8 *aBlob,                /* Pointer to in-memory file image */
++  int nBlob,                      /* Size of aBlob[] in bytes */
++  FILE *pFile,                    /* If aBlob==0, read from this file */
++  i64 iOff,                       /* Offset of CDS record */
++  ZipfileEntry **ppEntry          /* OUT: Pointer to new object */
++){
++  u8 *aRead;
++  char **pzErr = &pTab->base.zErrMsg;
++  int rc = SQLITE_OK;
++
++  if( aBlob==0 ){
++    aRead = pTab->aBuffer;
++    rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
++  }else{
++    aRead = (u8*)&aBlob[iOff];
++  }
++
++  if( rc==SQLITE_OK ){
++    int nAlloc;
++    ZipfileEntry *pNew;
++
++    int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
++    int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
++    nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
++
++    nAlloc = sizeof(ZipfileEntry) + nExtra;
++    if( aBlob ){
++      nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
++    }
++
++    pNew = (ZipfileEntry*)sqlite3_malloc(nAlloc);
++    if( pNew==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      memset(pNew, 0, sizeof(ZipfileEntry));
++      rc = zipfileReadCDS(aRead, &pNew->cds);
++      if( rc!=SQLITE_OK ){
++        *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
++      }else if( aBlob==0 ){
++        rc = zipfileReadData(
++            pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
++        );
++      }else{
++        aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      u32 *pt = &pNew->mUnixTime;
++      pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); 
++      pNew->aExtra = (u8*)&pNew[1];
++      memcpy(pNew->aExtra, &aRead[nFile], nExtra);
++      if( pNew->cds.zFile==0 ){
++        rc = SQLITE_NOMEM;
++      }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
++        pNew->mUnixTime = zipfileMtime(&pNew->cds);
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      static const int szFix = ZIPFILE_LFH_FIXED_SZ;
++      ZipfileLFH lfh;
++      if( pFile ){
++        rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
++      }else{
++        aRead = (u8*)&aBlob[pNew->cds.iOffset];
++      }
++
++      rc = zipfileReadLFH(aRead, &lfh);
++      if( rc==SQLITE_OK ){
++        pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
++        pNew->iDataOff += lfh.nFile + lfh.nExtra;
++        if( aBlob && pNew->cds.szCompressed ){
++          pNew->aData = &pNew->aExtra[nExtra];
++          memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
++        }
++      }else{
++        *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", 
++            (int)pNew->cds.iOffset
++        );
++      }
++    }
++
++    if( rc!=SQLITE_OK ){
++      zipfileEntryFree(pNew);
++    }else{
++      *ppEntry = pNew;
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Advance an ZipfileCsr to its next row of output.
++*/
++static int zipfileNext(sqlite3_vtab_cursor *cur){
++  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
++  int rc = SQLITE_OK;
++
++  if( pCsr->pFile ){
++    i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
++    zipfileEntryFree(pCsr->pCurrent);
++    pCsr->pCurrent = 0;
++    if( pCsr->iNextOff>=iEof ){
++      pCsr->bEof = 1;
++    }else{
++      ZipfileEntry *p = 0;
++      ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
++      rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
++      if( rc==SQLITE_OK ){
++        pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
++        pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
++      }
++      pCsr->pCurrent = p;
++    }
++  }else{
++    if( !pCsr->bNoop ){
++      pCsr->pCurrent = pCsr->pCurrent->pNext;
++    }
++    if( pCsr->pCurrent==0 ){
++      pCsr->bEof = 1;
++    }
++  }
++
++  pCsr->bNoop = 0;
++  return rc;
++}
++
++static void zipfileFree(void *p) { 
++  sqlite3_free(p); 
++}
++
++/*
++** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
++** size is nOut bytes. This function uncompresses the data and sets the
++** return value in context pCtx to the result (a blob).
++**
++** If an error occurs, an error code is left in pCtx instead.
++*/
++static void zipfileInflate(
++  sqlite3_context *pCtx,          /* Store result here */
++  const u8 *aIn,                  /* Compressed data */
++  int nIn,                        /* Size of buffer aIn[] in bytes */
++  int nOut                        /* Expected output size */
++){
++  u8 *aRes = sqlite3_malloc(nOut);
++  if( aRes==0 ){
++    sqlite3_result_error_nomem(pCtx);
++  }else{
++    int err;
++    z_stream str;
++    memset(&str, 0, sizeof(str));
++
++    str.next_in = (Byte*)aIn;
++    str.avail_in = nIn;
++    str.next_out = (Byte*)aRes;
++    str.avail_out = nOut;
++
++    err = inflateInit2(&str, -15);
++    if( err!=Z_OK ){
++      zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
++    }else{
++      err = inflate(&str, Z_NO_FLUSH);
++      if( err!=Z_STREAM_END ){
++        zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
++      }else{
++        sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
++        aRes = 0;
++      }
++    }
++    sqlite3_free(aRes);
++    inflateEnd(&str);
++  }
++}
++
++/*
++** Buffer aIn (size nIn bytes) contains uncompressed data. This function
++** compresses it and sets (*ppOut) to point to a buffer containing the
++** compressed data. The caller is responsible for eventually calling
++** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) 
++** is set to the size of buffer (*ppOut) in bytes.
++**
++** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
++** code is returned and an error message left in virtual-table handle
++** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
++** case.
++*/
++static int zipfileDeflate(
++  const u8 *aIn, int nIn,         /* Input */
++  u8 **ppOut, int *pnOut,         /* Output */
++  char **pzErr                    /* OUT: Error message */
++){
++  int nAlloc = (int)compressBound(nIn);
++  u8 *aOut;
++  int rc = SQLITE_OK;
++
++  aOut = (u8*)sqlite3_malloc(nAlloc);
++  if( aOut==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    int res;
++    z_stream str;
++    memset(&str, 0, sizeof(str));
++    str.next_in = (Bytef*)aIn;
++    str.avail_in = nIn;
++    str.next_out = aOut;
++    str.avail_out = nAlloc;
++
++    deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
++    res = deflate(&str, Z_FINISH);
++
++    if( res==Z_STREAM_END ){
++      *ppOut = aOut;
++      *pnOut = (int)str.total_out;
++    }else{
++      sqlite3_free(aOut);
++      *pzErr = sqlite3_mprintf("zipfile: deflate() error");
++      rc = SQLITE_ERROR;
++    }
++    deflateEnd(&str);
++  }
++
++  return rc;
++}
++
++
++/*
++** Return values of columns for the row at which the series_cursor
++** is currently pointing.
++*/
++static int zipfileColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
++  ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
++  int rc = SQLITE_OK;
++  switch( i ){
++    case 0:   /* name */
++      sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
++      break;
++    case 1:   /* mode */
++      /* TODO: Whether or not the following is correct surely depends on
++      ** the platform on which the archive was created.  */
++      sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
++      break;
++    case 2: { /* mtime */
++      sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
++      break;
++    }
++    case 3: { /* sz */
++      if( sqlite3_vtab_nochange(ctx)==0 ){
++        sqlite3_result_int64(ctx, pCDS->szUncompressed);
++      }
++      break;
++    }
++    case 4:   /* rawdata */
++      if( sqlite3_vtab_nochange(ctx) ) break;
++    case 5: { /* data */
++      if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
++        int sz = pCDS->szCompressed;
++        int szFinal = pCDS->szUncompressed;
++        if( szFinal>0 ){
++          u8 *aBuf;
++          u8 *aFree = 0;
++          if( pCsr->pCurrent->aData ){
++            aBuf = pCsr->pCurrent->aData;
++          }else{
++            aBuf = aFree = sqlite3_malloc(sz);
++            if( aBuf==0 ){
++              rc = SQLITE_NOMEM;
++            }else{
++              FILE *pFile = pCsr->pFile;
++              if( pFile==0 ){
++                pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
++              }
++              rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
++                  &pCsr->base.pVtab->zErrMsg
++              );
++            }
++          }
++          if( rc==SQLITE_OK ){
++            if( i==5 && pCDS->iCompression ){
++              zipfileInflate(ctx, aBuf, sz, szFinal);
++            }else{
++              sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
++            }
++          }
++          sqlite3_free(aFree);
++        }else{
++          /* Figure out if this is a directory or a zero-sized file. Consider
++          ** it to be a directory either if the mode suggests so, or if
++          ** the final character in the name is '/'.  */
++          u32 mode = pCDS->iExternalAttr >> 16;
++          if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
++            sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
++          }
++        }
++      }
++      break;
++    }
++    case 6:   /* method */
++      sqlite3_result_int(ctx, pCDS->iCompression);
++      break;
++    default:  /* z */
++      assert( i==7 );
++      sqlite3_result_int64(ctx, pCsr->iId);
++      break;
++  }
++
++  return rc;
++}
++
++/*
++** Return TRUE if the cursor is at EOF.
++*/
++static int zipfileEof(sqlite3_vtab_cursor *cur){
++  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
++  return pCsr->bEof;
++}
++
++/*
++** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
++** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
++** is guaranteed to be a file-handle open on a zip file.
++**
++** This function attempts to locate the EOCD record within the zip archive
++** and populate *pEOCD with the results of decoding it. SQLITE_OK is
++** returned if successful. Otherwise, an SQLite error code is returned and
++** an English language error message may be left in virtual-table pTab.
++*/
++static int zipfileReadEOCD(
++  ZipfileTab *pTab,               /* Return errors here */
++  const u8 *aBlob,                /* Pointer to in-memory file image */
++  int nBlob,                      /* Size of aBlob[] in bytes */
++  FILE *pFile,                    /* Read from this file if aBlob==0 */
++  ZipfileEOCD *pEOCD              /* Object to populate */
++){
++  u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
++  int nRead;                      /* Bytes to read from file */
++  int rc = SQLITE_OK;
++
++  if( aBlob==0 ){
++    i64 iOff;                     /* Offset to read from */
++    i64 szFile;                   /* Total size of file in bytes */
++    fseek(pFile, 0, SEEK_END);
++    szFile = (i64)ftell(pFile);
++    if( szFile==0 ){
++      memset(pEOCD, 0, sizeof(ZipfileEOCD));
++      return SQLITE_OK;
++    }
++    nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
++    iOff = szFile - nRead;
++    rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
++  }else{
++    nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
++    aRead = (u8*)&aBlob[nBlob-nRead];
++  }
++
++  if( rc==SQLITE_OK ){
++    int i;
++
++    /* Scan backwards looking for the signature bytes */
++    for(i=nRead-20; i>=0; i--){
++      if( aRead[i]==0x50 && aRead[i+1]==0x4b 
++       && aRead[i+2]==0x05 && aRead[i+3]==0x06 
++      ){
++        break;
++      }
++    }
++    if( i<0 ){
++      pTab->base.zErrMsg = sqlite3_mprintf(
++          "cannot find end of central directory record"
++      );
++      return SQLITE_ERROR;
++    }
++
++    aRead += i+4;
++    pEOCD->iDisk = zipfileRead16(aRead);
++    pEOCD->iFirstDisk = zipfileRead16(aRead);
++    pEOCD->nEntry = zipfileRead16(aRead);
++    pEOCD->nEntryTotal = zipfileRead16(aRead);
++    pEOCD->nSize = zipfileRead32(aRead);
++    pEOCD->iOffset = zipfileRead32(aRead);
++  }
++
++  return rc;
++}
++
++/*
++** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry 
++** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
++** to the end of the list. Otherwise, it is added to the list immediately
++** before pBefore (which is guaranteed to be a part of said list).
++*/
++static void zipfileAddEntry(
++  ZipfileTab *pTab, 
++  ZipfileEntry *pBefore, 
++  ZipfileEntry *pNew
++){
++  assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
++  assert( pNew->pNext==0 );
++  if( pBefore==0 ){
++    if( pTab->pFirstEntry==0 ){
++      pTab->pFirstEntry = pTab->pLastEntry = pNew;
++    }else{
++      assert( pTab->pLastEntry->pNext==0 );
++      pTab->pLastEntry->pNext = pNew;
++      pTab->pLastEntry = pNew;
++    }
++  }else{
++    ZipfileEntry **pp;
++    for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
++    pNew->pNext = pBefore;
++    *pp = pNew;
++  }
++}
++
++static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
++  ZipfileEOCD eocd;
++  int rc;
++  int i;
++  i64 iOff;
++
++  rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
++  iOff = eocd.iOffset;
++  for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
++    ZipfileEntry *pNew = 0;
++    rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
++
++    if( rc==SQLITE_OK ){
++      zipfileAddEntry(pTab, 0, pNew);
++      iOff += ZIPFILE_CDS_FIXED_SZ;
++      iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
++    }
++  }
++  return rc;
++}
++
++/*
++** xFilter callback.
++*/
++static int zipfileFilter(
++  sqlite3_vtab_cursor *cur, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
++  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
++  const char *zFile = 0;          /* Zip file to scan */
++  int rc = SQLITE_OK;             /* Return Code */
++  int bInMemory = 0;              /* True for an in-memory zipfile */
++
++  zipfileResetCursor(pCsr);
++
++  if( pTab->zFile ){
++    zFile = pTab->zFile;
++  }else if( idxNum==0 ){
++    zipfileCursorErr(pCsr, "zipfile() function requires an argument");
++    return SQLITE_ERROR;
++  }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
++    const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
++    int nBlob = sqlite3_value_bytes(argv[0]);
++    assert( pTab->pFirstEntry==0 );
++    rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
++    pCsr->pFreeEntry = pTab->pFirstEntry;
++    pTab->pFirstEntry = pTab->pLastEntry = 0;
++    if( rc!=SQLITE_OK ) return rc;
++    bInMemory = 1;
++  }else{
++    zFile = (const char*)sqlite3_value_text(argv[0]);
++  }
++
++  if( 0==pTab->pWriteFd && 0==bInMemory ){
++    pCsr->pFile = fopen(zFile, "rb");
++    if( pCsr->pFile==0 ){
++      zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
++      rc = SQLITE_ERROR;
++    }else{
++      rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
++      if( rc==SQLITE_OK ){
++        if( pCsr->eocd.nEntry==0 ){
++          pCsr->bEof = 1;
++        }else{
++          pCsr->iNextOff = pCsr->eocd.iOffset;
++          rc = zipfileNext(cur);
++        }
++      }
++    }
++  }else{
++    pCsr->bNoop = 1;
++    pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
++    rc = zipfileNext(cur);
++  }
++
++  return rc;
++}
++
++/*
++** xBestIndex callback.
++*/
++static int zipfileBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  int i;
++  int idx = -1;
++  int unusable = 0;
++
++  for(i=0; i<pIdxInfo->nConstraint; i++){
++    const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
++    if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
++    if( pCons->usable==0 ){
++      unusable = 1;
++    }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++      idx = i;
++    }
++  }
++  if( idx>=0 ){
++    pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[idx].omit = 1;
++    pIdxInfo->estimatedCost = 1000.0;
++    pIdxInfo->idxNum = 1;
++  }else if( unusable ){
++    return SQLITE_CONSTRAINT;
++  }
++  return SQLITE_OK;
++}
++
++static ZipfileEntry *zipfileNewEntry(const char *zPath){
++  ZipfileEntry *pNew;
++  pNew = sqlite3_malloc(sizeof(ZipfileEntry));
++  if( pNew ){
++    memset(pNew, 0, sizeof(ZipfileEntry));
++    pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
++    if( pNew->cds.zFile==0 ){
++      sqlite3_free(pNew);
++      pNew = 0;
++    }
++  }
++  return pNew;
++}
++
++static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
++  ZipfileCDS *pCds = &pEntry->cds;
++  u8 *a = aBuf;
++
++  pCds->nExtra = 9;
++
++  /* Write the LFH itself */
++  zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
++  zipfileWrite16(a, pCds->iVersionExtract);
++  zipfileWrite16(a, pCds->flags);
++  zipfileWrite16(a, pCds->iCompression);
++  zipfileWrite16(a, pCds->mTime);
++  zipfileWrite16(a, pCds->mDate);
++  zipfileWrite32(a, pCds->crc32);
++  zipfileWrite32(a, pCds->szCompressed);
++  zipfileWrite32(a, pCds->szUncompressed);
++  zipfileWrite16(a, (u16)pCds->nFile);
++  zipfileWrite16(a, pCds->nExtra);
++  assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
++
++  /* Add the file name */
++  memcpy(a, pCds->zFile, (int)pCds->nFile);
++  a += (int)pCds->nFile;
++
++  /* The "extra" data */
++  zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
++  zipfileWrite16(a, 5);
++  *a++ = 0x01;
++  zipfileWrite32(a, pEntry->mUnixTime);
++
++  return a-aBuf;
++}
++
++static int zipfileAppendEntry(
++  ZipfileTab *pTab,
++  ZipfileEntry *pEntry,
++  const u8 *pData,
++  int nData
++){
++  u8 *aBuf = pTab->aBuffer;
++  int nBuf;
++  int rc;
++
++  nBuf = zipfileSerializeLFH(pEntry, aBuf);
++  rc = zipfileAppendData(pTab, aBuf, nBuf);
++  if( rc==SQLITE_OK ){
++    pEntry->iDataOff = pTab->szCurrent;
++    rc = zipfileAppendData(pTab, pData, nData);
++  }
++
++  return rc;
++}
++
++static int zipfileGetMode(
++  sqlite3_value *pVal, 
++  int bIsDir,                     /* If true, default to directory */
++  u32 *pMode,                     /* OUT: Mode value */
++  char **pzErr                    /* OUT: Error message */
++){
++  const char *z = (const char*)sqlite3_value_text(pVal);
++  u32 mode = 0;
++  if( z==0 ){
++    mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
++  }else if( z[0]>='0' && z[0]<='9' ){
++    mode = (unsigned int)sqlite3_value_int(pVal);
++  }else{
++    const char zTemplate[11] = "-rwxrwxrwx";
++    int i;
++    if( strlen(z)!=10 ) goto parse_error;
++    switch( z[0] ){
++      case '-': mode |= S_IFREG; break;
++      case 'd': mode |= S_IFDIR; break;
++      case 'l': mode |= S_IFLNK; break;
++      default: goto parse_error;
++    }
++    for(i=1; i<10; i++){
++      if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
++      else if( z[i]!='-' ) goto parse_error;
++    }
++  }
++  if( ((mode & S_IFDIR)==0)==bIsDir ){
++    /* The "mode" attribute is a directory, but data has been specified.
++    ** Or vice-versa - no data but "mode" is a file or symlink.  */
++    *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
++    return SQLITE_CONSTRAINT;
++  }
++  *pMode = mode;
++  return SQLITE_OK;
++
++ parse_error:
++  *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
++  return SQLITE_ERROR;
++}
++
++/*
++** Both (const char*) arguments point to nul-terminated strings. Argument
++** nB is the value of strlen(zB). This function returns 0 if the strings are
++** identical, ignoring any trailing '/' character in either path.  */
++static int zipfileComparePath(const char *zA, const char *zB, int nB){
++  int nA = (int)strlen(zA);
++  if( zA[nA-1]=='/' ) nA--;
++  if( zB[nB-1]=='/' ) nB--;
++  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
++  return 1;
++}
++
++static int zipfileBegin(sqlite3_vtab *pVtab){
++  ZipfileTab *pTab = (ZipfileTab*)pVtab;
++  int rc = SQLITE_OK;
++
++  assert( pTab->pWriteFd==0 );
++
++  /* Open a write fd on the file. Also load the entire central directory
++  ** structure into memory. During the transaction any new file data is 
++  ** appended to the archive file, but the central directory is accumulated
++  ** in main-memory until the transaction is committed.  */
++  pTab->pWriteFd = fopen(pTab->zFile, "ab+");
++  if( pTab->pWriteFd==0 ){
++    pTab->base.zErrMsg = sqlite3_mprintf(
++        "zipfile: failed to open file %s for writing", pTab->zFile
++        );
++    rc = SQLITE_ERROR;
++  }else{
++    fseek(pTab->pWriteFd, 0, SEEK_END);
++    pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
++    rc = zipfileLoadDirectory(pTab, 0, 0);
++  }
++
++  if( rc!=SQLITE_OK ){
++    zipfileCleanupTransaction(pTab);
++  }
++
++  return rc;
++}
++
++/*
++** Return the current time as a 32-bit timestamp in UNIX epoch format (like
++** time(2)).
++*/
++static u32 zipfileTime(void){
++  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
++  u32 ret;
++  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
++    i64 ms;
++    pVfs->xCurrentTimeInt64(pVfs, &ms);
++    ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
++  }else{
++    double day;
++    pVfs->xCurrentTime(pVfs, &day);
++    ret = (u32)((day - 2440587.5) * 86400);
++  }
++  return ret;
++}
++
++/*
++** Return a 32-bit timestamp in UNIX epoch format.
++**
++** If the value passed as the only argument is either NULL or an SQL NULL,
++** return the current time. Otherwise, return the value stored in (*pVal)
++** cast to a 32-bit unsigned integer.
++*/
++static u32 zipfileGetTime(sqlite3_value *pVal){
++  if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
++    return zipfileTime();
++  }
++  return (u32)sqlite3_value_int64(pVal);
++}
++
++/*
++** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
++** linked list.  Remove it from the list and free the object.
++*/
++static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
++  if( pOld ){
++    ZipfileEntry **pp;
++    for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
++    *pp = (*pp)->pNext;
++    zipfileEntryFree(pOld);
++  }
++}
++
++/*
++** xUpdate method.
++*/
++static int zipfileUpdate(
++  sqlite3_vtab *pVtab, 
++  int nVal, 
++  sqlite3_value **apVal, 
++  sqlite_int64 *pRowid
++){
++  ZipfileTab *pTab = (ZipfileTab*)pVtab;
++  int rc = SQLITE_OK;             /* Return Code */
++  ZipfileEntry *pNew = 0;         /* New in-memory CDS entry */
++
++  u32 mode = 0;                   /* Mode for new entry */
++  u32 mTime = 0;                  /* Modification time for new entry */
++  i64 sz = 0;                     /* Uncompressed size */
++  const char *zPath = 0;          /* Path for new entry */
++  int nPath = 0;                  /* strlen(zPath) */
++  const u8 *pData = 0;            /* Pointer to buffer containing content */
++  int nData = 0;                  /* Size of pData buffer in bytes */
++  int iMethod = 0;                /* Compression method for new entry */
++  u8 *pFree = 0;                  /* Free this */
++  char *zFree = 0;                /* Also free this */
++  ZipfileEntry *pOld = 0;
++  ZipfileEntry *pOld2 = 0;
++  int bUpdate = 0;                /* True for an update that modifies "name" */
++  int bIsDir = 0;
++  u32 iCrc32 = 0;
++
++  if( pTab->pWriteFd==0 ){
++    rc = zipfileBegin(pVtab);
++    if( rc!=SQLITE_OK ) return rc;
++  }
++
++  /* If this is a DELETE or UPDATE, find the archive entry to delete. */
++  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
++    const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
++    int nDelete = (int)strlen(zDelete);
++    if( nVal>1 ){
++      const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
++      if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
++        bUpdate = 1;
++      }
++    }
++    for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
++      if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
++        break;
++      }
++      assert( pOld->pNext );
++    }
++  }
++
++  if( nVal>1 ){
++    /* Check that "sz" and "rawdata" are both NULL: */
++    if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
++      zipfileTableErr(pTab, "sz must be NULL");
++      rc = SQLITE_CONSTRAINT;
++    }
++    if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
++      zipfileTableErr(pTab, "rawdata must be NULL"); 
++      rc = SQLITE_CONSTRAINT;
++    }
++
++    if( rc==SQLITE_OK ){
++      if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
++        /* data=NULL. A directory */
++        bIsDir = 1;
++      }else{
++        /* Value specified for "data", and possibly "method". This must be
++        ** a regular file or a symlink. */
++        const u8 *aIn = sqlite3_value_blob(apVal[7]);
++        int nIn = sqlite3_value_bytes(apVal[7]);
++        int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
++
++        iMethod = sqlite3_value_int(apVal[8]);
++        sz = nIn;
++        pData = aIn;
++        nData = nIn;
++        if( iMethod!=0 && iMethod!=8 ){
++          zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
++          rc = SQLITE_CONSTRAINT;
++        }else{
++          if( bAuto || iMethod ){
++            int nCmp;
++            rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
++            if( rc==SQLITE_OK ){
++              if( iMethod || nCmp<nIn ){
++                iMethod = 8;
++                pData = pFree;
++                nData = nCmp;
++              }
++            }
++          }
++          iCrc32 = crc32(0, aIn, nIn);
++        }
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
++    }
++
++    if( rc==SQLITE_OK ){
++      zPath = (const char*)sqlite3_value_text(apVal[2]);
++      nPath = (int)strlen(zPath);
++      mTime = zipfileGetTime(apVal[4]);
++    }
++
++    if( rc==SQLITE_OK && bIsDir ){
++      /* For a directory, check that the last character in the path is a
++      ** '/'. This appears to be required for compatibility with info-zip
++      ** (the unzip command on unix). It does not create directories
++      ** otherwise.  */
++      if( zPath[nPath-1]!='/' ){
++        zFree = sqlite3_mprintf("%s/", zPath);
++        if( zFree==0 ){ rc = SQLITE_NOMEM; }
++        zPath = (const char*)zFree;
++        nPath++;
++      }
++    }
++
++    /* Check that we're not inserting a duplicate entry -OR- updating an
++    ** entry with a path, thereby making it into a duplicate. */
++    if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
++      ZipfileEntry *p;
++      for(p=pTab->pFirstEntry; p; p=p->pNext){
++        if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
++          switch( sqlite3_vtab_on_conflict(pTab->db) ){
++            case SQLITE_IGNORE: {
++              goto zipfile_update_done;
++            }
++            case SQLITE_REPLACE: {
++              pOld2 = p;
++              break;
++            }
++            default: {
++              zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
++              rc = SQLITE_CONSTRAINT;
++              break;
++            }
++          }
++          break;
++        }
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      /* Create the new CDS record. */
++      pNew = zipfileNewEntry(zPath);
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
++        pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
++        pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
++        pNew->cds.iCompression = (u16)iMethod;
++        zipfileMtimeToDos(&pNew->cds, mTime);
++        pNew->cds.crc32 = iCrc32;
++        pNew->cds.szCompressed = nData;
++        pNew->cds.szUncompressed = (u32)sz;
++        pNew->cds.iExternalAttr = (mode<<16);
++        pNew->cds.iOffset = (u32)pTab->szCurrent;
++        pNew->cds.nFile = (u16)nPath;
++        pNew->mUnixTime = (u32)mTime;
++        rc = zipfileAppendEntry(pTab, pNew, pData, nData);
++        zipfileAddEntry(pTab, pOld, pNew);
++      }
++    }
++  }
++
++  if( rc==SQLITE_OK && (pOld || pOld2) ){
++    ZipfileCsr *pCsr;
++    for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
++      if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
++        pCsr->pCurrent = pCsr->pCurrent->pNext;
++        pCsr->bNoop = 1;
++      }
++    }
++
++    zipfileRemoveEntryFromList(pTab, pOld);
++    zipfileRemoveEntryFromList(pTab, pOld2);
++  }
++
++zipfile_update_done:
++  sqlite3_free(pFree);
++  sqlite3_free(zFree);
++  return rc;
++}
++
++static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
++  u8 *a = aBuf;
++  zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
++  zipfileWrite16(a, p->iDisk);
++  zipfileWrite16(a, p->iFirstDisk);
++  zipfileWrite16(a, p->nEntry);
++  zipfileWrite16(a, p->nEntryTotal);
++  zipfileWrite32(a, p->nSize);
++  zipfileWrite32(a, p->iOffset);
++  zipfileWrite16(a, 0);        /* Size of trailing comment in bytes*/
++
++  return a-aBuf;
++}
++
++static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
++  int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
++  assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
++  return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
++}
++
++/*
++** Serialize the CDS structure into buffer aBuf[]. Return the number
++** of bytes written.
++*/
++static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
++  u8 *a = aBuf;
++  ZipfileCDS *pCDS = &pEntry->cds;
++
++  if( pEntry->aExtra==0 ){
++    pCDS->nExtra = 9;
++  }
++
++  zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
++  zipfileWrite16(a, pCDS->iVersionMadeBy);
++  zipfileWrite16(a, pCDS->iVersionExtract);
++  zipfileWrite16(a, pCDS->flags);
++  zipfileWrite16(a, pCDS->iCompression);
++  zipfileWrite16(a, pCDS->mTime);
++  zipfileWrite16(a, pCDS->mDate);
++  zipfileWrite32(a, pCDS->crc32);
++  zipfileWrite32(a, pCDS->szCompressed);
++  zipfileWrite32(a, pCDS->szUncompressed);
++  assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
++  zipfileWrite16(a, pCDS->nFile);
++  zipfileWrite16(a, pCDS->nExtra);
++  zipfileWrite16(a, pCDS->nComment);
++  zipfileWrite16(a, pCDS->iDiskStart);
++  zipfileWrite16(a, pCDS->iInternalAttr);
++  zipfileWrite32(a, pCDS->iExternalAttr);
++  zipfileWrite32(a, pCDS->iOffset);
++
++  memcpy(a, pCDS->zFile, pCDS->nFile);
++  a += pCDS->nFile;
++
++  if( pEntry->aExtra ){
++    int n = (int)pCDS->nExtra + (int)pCDS->nComment;
++    memcpy(a, pEntry->aExtra, n);
++    a += n;
++  }else{
++    assert( pCDS->nExtra==9 );
++    zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
++    zipfileWrite16(a, 5);
++    *a++ = 0x01;
++    zipfileWrite32(a, pEntry->mUnixTime);
++  }
++
++  return a-aBuf;
++}
++
++static int zipfileCommit(sqlite3_vtab *pVtab){
++  ZipfileTab *pTab = (ZipfileTab*)pVtab;
++  int rc = SQLITE_OK;
++  if( pTab->pWriteFd ){
++    i64 iOffset = pTab->szCurrent;
++    ZipfileEntry *p;
++    ZipfileEOCD eocd;
++    int nEntry = 0;
++
++    /* Write out all entries */
++    for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
++      int n = zipfileSerializeCDS(p, pTab->aBuffer);
++      rc = zipfileAppendData(pTab, pTab->aBuffer, n);
++      nEntry++;
++    }
++
++    /* Write out the EOCD record */
++    eocd.iDisk = 0;
++    eocd.iFirstDisk = 0;
++    eocd.nEntry = (u16)nEntry;
++    eocd.nEntryTotal = (u16)nEntry;
++    eocd.nSize = (u32)(pTab->szCurrent - iOffset);
++    eocd.iOffset = (u32)iOffset;
++    rc = zipfileAppendEOCD(pTab, &eocd);
++
++    zipfileCleanupTransaction(pTab);
++  }
++  return rc;
++}
++
++static int zipfileRollback(sqlite3_vtab *pVtab){
++  return zipfileCommit(pVtab);
++}
++
++static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
++  ZipfileCsr *pCsr;
++  for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
++    if( iId==pCsr->iId ) break;
++  }
++  return pCsr;
++}
++
++static void zipfileFunctionCds(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  ZipfileCsr *pCsr;
++  ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
++  assert( argc>0 );
++
++  pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
++  if( pCsr ){
++    ZipfileCDS *p = &pCsr->pCurrent->cds;
++    char *zRes = sqlite3_mprintf("{"
++        "\"version-made-by\" : %u, "
++        "\"version-to-extract\" : %u, "
++        "\"flags\" : %u, "
++        "\"compression\" : %u, "
++        "\"time\" : %u, "
++        "\"date\" : %u, "
++        "\"crc32\" : %u, "
++        "\"compressed-size\" : %u, "
++        "\"uncompressed-size\" : %u, "
++        "\"file-name-length\" : %u, "
++        "\"extra-field-length\" : %u, "
++        "\"file-comment-length\" : %u, "
++        "\"disk-number-start\" : %u, "
++        "\"internal-attr\" : %u, "
++        "\"external-attr\" : %u, "
++        "\"offset\" : %u }",
++        (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
++        (u32)p->flags, (u32)p->iCompression,
++        (u32)p->mTime, (u32)p->mDate,
++        (u32)p->crc32, (u32)p->szCompressed,
++        (u32)p->szUncompressed, (u32)p->nFile,
++        (u32)p->nExtra, (u32)p->nComment,
++        (u32)p->iDiskStart, (u32)p->iInternalAttr,
++        (u32)p->iExternalAttr, (u32)p->iOffset
++    );
++
++    if( zRes==0 ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
++      sqlite3_free(zRes);
++    }
++  }
++}
++
++/*
++** xFindFunction method.
++*/
++static int zipfileFindFunction(
++  sqlite3_vtab *pVtab,            /* Virtual table handle */
++  int nArg,                       /* Number of SQL function arguments */
++  const char *zName,              /* Name of SQL function */
++  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
++  void **ppArg                    /* OUT: User data for *pxFunc */
++){
++  if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
++    *pxFunc = zipfileFunctionCds;
++    *ppArg = (void*)pVtab;
++    return 1;
++  }
++  return 0;
++}
++
++typedef struct ZipfileBuffer ZipfileBuffer;
++struct ZipfileBuffer {
++  u8 *a;                          /* Pointer to buffer */
++  int n;                          /* Size of buffer in bytes */
++  int nAlloc;                     /* Byte allocated at a[] */
++};
++
++typedef struct ZipfileCtx ZipfileCtx;
++struct ZipfileCtx {
++  int nEntry;
++  ZipfileBuffer body;
++  ZipfileBuffer cds;
++};
++
++static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
++  if( pBuf->n+nByte>pBuf->nAlloc ){
++    u8 *aNew;
++    int nNew = pBuf->n ? pBuf->n*2 : 512;
++    int nReq = pBuf->n + nByte;
++
++    while( nNew<nReq ) nNew = nNew*2;
++    aNew = sqlite3_realloc(pBuf->a, nNew);
++    if( aNew==0 ) return SQLITE_NOMEM;
++    pBuf->a = aNew;
++    pBuf->nAlloc = nNew;
++  }
++  return SQLITE_OK;
++}
++
++/*
++** xStep() callback for the zipfile() aggregate. This can be called in
++** any of the following ways:
++**
++**   SELECT zipfile(name,data) ...
++**   SELECT zipfile(name,mode,mtime,data) ...
++**   SELECT zipfile(name,mode,mtime,data,method) ...
++*/
++void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
++  ZipfileCtx *p;                  /* Aggregate function context */
++  ZipfileEntry e;                 /* New entry to add to zip archive */
++
++  sqlite3_value *pName = 0;
++  sqlite3_value *pMode = 0;
++  sqlite3_value *pMtime = 0;
++  sqlite3_value *pData = 0;
++  sqlite3_value *pMethod = 0;
++
++  int bIsDir = 0;
++  u32 mode;
++  int rc = SQLITE_OK;
++  char *zErr = 0;
++
++  int iMethod = -1;               /* Compression method to use (0 or 8) */
++
++  const u8 *aData = 0;            /* Possibly compressed data for new entry */
++  int nData = 0;                  /* Size of aData[] in bytes */
++  int szUncompressed = 0;         /* Size of data before compression */
++  u8 *aFree = 0;                  /* Free this before returning */
++  u32 iCrc32 = 0;                 /* crc32 of uncompressed data */
++
++  char *zName = 0;                /* Path (name) of new entry */
++  int nName = 0;                  /* Size of zName in bytes */
++  char *zFree = 0;                /* Free this before returning */
++  int nByte;
++
++  memset(&e, 0, sizeof(e));
++  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
++  if( p==0 ) return;
++
++  /* Martial the arguments into stack variables */
++  if( nVal!=2 && nVal!=4 && nVal!=5 ){
++    zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
++    rc = SQLITE_ERROR;
++    goto zipfile_step_out;
++  }
++  pName = apVal[0];
++  if( nVal==2 ){
++    pData = apVal[1];
++  }else{
++    pMode = apVal[1];
++    pMtime = apVal[2];
++    pData = apVal[3];
++    if( nVal==5 ){
++      pMethod = apVal[4];
++    }
++  }
++
++  /* Check that the 'name' parameter looks ok. */
++  zName = (char*)sqlite3_value_text(pName);
++  nName = sqlite3_value_bytes(pName);
++  if( zName==0 ){
++    zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
++    rc = SQLITE_ERROR;
++    goto zipfile_step_out;
++  }
++
++  /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
++  ** deflate compression) or NULL (choose automatically).  */
++  if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
++    iMethod = (int)sqlite3_value_int64(pMethod);
++    if( iMethod!=0 && iMethod!=8 ){
++      zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
++      rc = SQLITE_ERROR;
++      goto zipfile_step_out;
++    }
++  }
++
++  /* Now inspect the data. If this is NULL, then the new entry must be a
++  ** directory.  Otherwise, figure out whether or not the data should
++  ** be deflated or simply stored in the zip archive. */
++  if( sqlite3_value_type(pData)==SQLITE_NULL ){
++    bIsDir = 1;
++    iMethod = 0;
++  }else{
++    aData = sqlite3_value_blob(pData);
++    szUncompressed = nData = sqlite3_value_bytes(pData);
++    iCrc32 = crc32(0, aData, nData);
++    if( iMethod<0 || iMethod==8 ){
++      int nOut = 0;
++      rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
++      if( rc!=SQLITE_OK ){
++        goto zipfile_step_out;
++      }
++      if( iMethod==8 || nOut<nData ){
++        aData = aFree;
++        nData = nOut;
++        iMethod = 8;
++      }else{
++        iMethod = 0;
++      }
++    }
++  }
++
++  /* Decode the "mode" argument. */
++  rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
++  if( rc ) goto zipfile_step_out;
++
++  /* Decode the "mtime" argument. */
++  e.mUnixTime = zipfileGetTime(pMtime);
++
++  /* If this is a directory entry, ensure that there is exactly one '/'
++  ** at the end of the path. Or, if this is not a directory and the path
++  ** ends in '/' it is an error. */
++  if( bIsDir==0 ){
++    if( zName[nName-1]=='/' ){
++      zErr = sqlite3_mprintf("non-directory name must not end with /");
++      rc = SQLITE_ERROR;
++      goto zipfile_step_out;
++    }
++  }else{
++    if( zName[nName-1]!='/' ){
++      zName = zFree = sqlite3_mprintf("%s/", zName);
++      nName++;
++      if( zName==0 ){
++        rc = SQLITE_NOMEM;
++        goto zipfile_step_out;
++      }
++    }else{
++      while( nName>1 && zName[nName-2]=='/' ) nName--;
++    }
++  }
++
++  /* Assemble the ZipfileEntry object for the new zip archive entry */
++  e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
++  e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
++  e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
++  e.cds.iCompression = (u16)iMethod;
++  zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
++  e.cds.crc32 = iCrc32;
++  e.cds.szCompressed = nData;
++  e.cds.szUncompressed = szUncompressed;
++  e.cds.iExternalAttr = (mode<<16);
++  e.cds.iOffset = p->body.n;
++  e.cds.nFile = (u16)nName;
++  e.cds.zFile = zName;
++
++  /* Append the LFH to the body of the new archive */
++  nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
++  if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
++  p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
++
++  /* Append the data to the body of the new archive */
++  if( nData>0 ){
++    if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
++    memcpy(&p->body.a[p->body.n], aData, nData);
++    p->body.n += nData;
++  }
++
++  /* Append the CDS record to the directory of the new archive */
++  nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
++  if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
++  p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
++
++  /* Increment the count of entries in the archive */
++  p->nEntry++;
++
++ zipfile_step_out:
++  sqlite3_free(aFree);
++  sqlite3_free(zFree);
++  if( rc ){
++    if( zErr ){
++      sqlite3_result_error(pCtx, zErr, -1);
++    }else{
++      sqlite3_result_error_code(pCtx, rc);
++    }
++  }
++  sqlite3_free(zErr);
++}
++
++/*
++** xFinalize() callback for zipfile aggregate function.
++*/
++void zipfileFinal(sqlite3_context *pCtx){
++  ZipfileCtx *p;
++  ZipfileEOCD eocd;
++  int nZip;
++  u8 *aZip;
++
++  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
++  if( p==0 ) return;
++  if( p->nEntry>0 ){
++    memset(&eocd, 0, sizeof(eocd));
++    eocd.nEntry = (u16)p->nEntry;
++    eocd.nEntryTotal = (u16)p->nEntry;
++    eocd.nSize = p->cds.n;
++    eocd.iOffset = p->body.n;
++
++    nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
++    aZip = (u8*)sqlite3_malloc(nZip);
++    if( aZip==0 ){
++      sqlite3_result_error_nomem(pCtx);
++    }else{
++      memcpy(aZip, p->body.a, p->body.n);
++      memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
++      zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
++      sqlite3_result_blob(pCtx, aZip, nZip, zipfileFree);
++    }
++  }
++
++  sqlite3_free(p->body.a);
++  sqlite3_free(p->cds.a);
++}
++
++
++/*
++** Register the "zipfile" virtual table.
++*/
++static int zipfileRegister(sqlite3 *db){
++  static sqlite3_module zipfileModule = {
++    1,                         /* iVersion */
++    zipfileConnect,            /* xCreate */
++    zipfileConnect,            /* xConnect */
++    zipfileBestIndex,          /* xBestIndex */
++    zipfileDisconnect,         /* xDisconnect */
++    zipfileDisconnect,         /* xDestroy */
++    zipfileOpen,               /* xOpen - open a cursor */
++    zipfileClose,              /* xClose - close a cursor */
++    zipfileFilter,             /* xFilter - configure scan constraints */
++    zipfileNext,               /* xNext - advance a cursor */
++    zipfileEof,                /* xEof - check for end of scan */
++    zipfileColumn,             /* xColumn - read data */
++    0,                         /* xRowid - read data */
++    zipfileUpdate,             /* xUpdate */
++    zipfileBegin,              /* xBegin */
++    0,                         /* xSync */
++    zipfileCommit,             /* xCommit */
++    zipfileRollback,           /* xRollback */
++    zipfileFindFunction,       /* xFindMethod */
++    0,                         /* xRename */
++  };
++
++  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
++  if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, 
++        zipfileStep, zipfileFinal
++    );
++  }
++  return rc;
++}
++#else         /* SQLITE_OMIT_VIRTUALTABLE */
++# define zipfileRegister(x) SQLITE_OK
++#endif
++
++#ifdef _WIN32
++
++#endif
++int sqlite3_zipfile_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return zipfileRegister(db);
++}
++
++/************************* End ../ext/misc/zipfile.c ********************/
++/************************* Begin ../ext/misc/sqlar.c ******************/
++/*
++** 2017-12-17
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
++** for working with sqlar archives and used by the shell tool's built-in
++** sqlar support.
++*/
++SQLITE_EXTENSION_INIT1
++#include <zlib.h>
++
++/*
++** Implementation of the "sqlar_compress(X)" SQL function.
++**
++** If the type of X is SQLITE_BLOB, and compressing that blob using
++** zlib utility function compress() yields a smaller blob, return the
++** compressed blob. Otherwise, return a copy of X.
++**
++** SQLar uses the "zlib format" for compressed content.  The zlib format
++** contains a two-byte identification header and a four-byte checksum at
++** the end.  This is different from ZIP which uses the raw deflate format.
++**
++** Future enhancements to SQLar might add support for new compression formats.
++** If so, those new formats will be identified by alternative headers in the
++** compressed data.
++*/
++static void sqlarCompressFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  assert( argc==1 );
++  if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
++    const Bytef *pData = sqlite3_value_blob(argv[0]);
++    uLong nData = sqlite3_value_bytes(argv[0]);
++    uLongf nOut = compressBound(nData);
++    Bytef *pOut;
++
++    pOut = (Bytef*)sqlite3_malloc(nOut);
++    if( pOut==0 ){
++      sqlite3_result_error_nomem(context);
++      return;
++    }else{
++      if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
++        sqlite3_result_error(context, "error in compress()", -1);
++      }else if( nOut<nData ){
++        sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
++      }else{
++        sqlite3_result_value(context, argv[0]);
++      }
++      sqlite3_free(pOut);
++    }
++  }else{
++    sqlite3_result_value(context, argv[0]);
++  }
++}
++
++/*
++** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
++**
++** Parameter SZ is interpreted as an integer. If it is less than or
++** equal to zero, then this function returns a copy of X. Or, if
++** SZ is equal to the size of X when interpreted as a blob, also
++** return a copy of X. Otherwise, decompress blob X using zlib
++** utility function uncompress() and return the results (another
++** blob).
++*/
++static void sqlarUncompressFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  uLong nData;
++  uLongf sz;
++
++  assert( argc==2 );
++  sz = sqlite3_value_int(argv[1]);
++
++  if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
++    sqlite3_result_value(context, argv[0]);
++  }else{
++    const Bytef *pData= sqlite3_value_blob(argv[0]);
++    Bytef *pOut = sqlite3_malloc(sz);
++    if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
++      sqlite3_result_error(context, "error in uncompress()", -1);
++    }else{
++      sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
++    }
++    sqlite3_free(pOut);
++  }
++}
++
++
++#ifdef _WIN32
++
++#endif
++int sqlite3_sqlar_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  int rc = SQLITE_OK;
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
++                               sqlarCompressFunc, 0, 0);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
++                                 sqlarUncompressFunc, 0, 0);
++  }
++  return rc;
++}
++
++/************************* End ../ext/misc/sqlar.c ********************/
++#endif
++/************************* Begin ../ext/expert/sqlite3expert.h ******************/
++/*
++** 2017 April 07
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++*/
++
++
++
++typedef struct sqlite3expert sqlite3expert;
++
++/*
++** Create a new sqlite3expert object.
++**
++** If successful, a pointer to the new object is returned and (*pzErr) set
++** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to
++** an English-language error message. In this case it is the responsibility
++** of the caller to eventually free the error message buffer using
++** sqlite3_free().
++*/
++sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr);
++
++/*
++** Configure an sqlite3expert object.
++**
++** EXPERT_CONFIG_SAMPLE:
++**   By default, sqlite3_expert_analyze() generates sqlite_stat1 data for
++**   each candidate index. This involves scanning and sorting the entire
++**   contents of each user database table once for each candidate index
++**   associated with the table. For large databases, this can be 
++**   prohibitively slow. This option allows the sqlite3expert object to
++**   be configured so that sqlite_stat1 data is instead generated based on a
++**   subset of each table, or so that no sqlite_stat1 data is used at all.
++**
++**   A single integer argument is passed to this option. If the value is less
++**   than or equal to zero, then no sqlite_stat1 data is generated or used by
++**   the analysis - indexes are recommended based on the database schema only.
++**   Or, if the value is 100 or greater, complete sqlite_stat1 data is
++**   generated for each candidate index (this is the default). Finally, if the
++**   value falls between 0 and 100, then it represents the percentage of user
++**   table rows that should be considered when generating sqlite_stat1 data.
++**
++**   Examples:
++**
++**     // Do not generate any sqlite_stat1 data
++**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0);
++**
++**     // Generate sqlite_stat1 data based on 10% of the rows in each table.
++**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10);
++*/
++int sqlite3_expert_config(sqlite3expert *p, int op, ...);
++
++#define EXPERT_CONFIG_SAMPLE 1    /* int */
++
++/*
++** Specify zero or more SQL statements to be included in the analysis.
++**
++** Buffer zSql must contain zero or more complete SQL statements. This
++** function parses all statements contained in the buffer and adds them
++** to the internal list of statements to analyze. If successful, SQLITE_OK
++** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example
++** due to a error in the SQL - an SQLite error code is returned and (*pzErr)
++** may be set to point to an English language error message. In this case
++** the caller is responsible for eventually freeing the error message buffer
++** using sqlite3_free().
++**
++** If an error does occur while processing one of the statements in the
++** buffer passed as the second argument, none of the statements in the
++** buffer are added to the analysis.
++**
++** This function must be called before sqlite3_expert_analyze(). If a call
++** to this function is made on an sqlite3expert object that has already
++** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned
++** immediately and no statements are added to the analysis.
++*/
++int sqlite3_expert_sql(
++  sqlite3expert *p,               /* From a successful sqlite3_expert_new() */
++  const char *zSql,               /* SQL statement(s) to add */
++  char **pzErr                    /* OUT: Error message (if any) */
++);
++
++
++/*
++** This function is called after the sqlite3expert object has been configured
++** with all SQL statements using sqlite3_expert_sql() to actually perform
++** the analysis. Once this function has been called, it is not possible to
++** add further SQL statements to the analysis.
++**
++** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if
++** an error occurs, an SQLite error code is returned and (*pzErr) set to 
++** point to a buffer containing an English language error message. In this
++** case it is the responsibility of the caller to eventually free the buffer
++** using sqlite3_free().
++**
++** If an error does occur within this function, the sqlite3expert object
++** is no longer useful for any purpose. At that point it is no longer
++** possible to add further SQL statements to the object or to re-attempt
++** the analysis. The sqlite3expert object must still be freed using a call
++** sqlite3_expert_destroy().
++*/
++int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr);
++
++/*
++** Return the total number of statements loaded using sqlite3_expert_sql().
++** The total number of SQL statements may be different from the total number
++** to calls to sqlite3_expert_sql().
++*/
++int sqlite3_expert_count(sqlite3expert*);
++
++/*
++** Return a component of the report.
++**
++** This function is called after sqlite3_expert_analyze() to extract the
++** results of the analysis. Each call to this function returns either a
++** NULL pointer or a pointer to a buffer containing a nul-terminated string.
++** The value passed as the third argument must be one of the EXPERT_REPORT_*
++** #define constants defined below.
++**
++** For some EXPERT_REPORT_* parameters, the buffer returned contains 
++** information relating to a specific SQL statement. In these cases that
++** SQL statement is identified by the value passed as the second argument.
++** SQL statements are numbered from 0 in the order in which they are parsed.
++** If an out-of-range value (less than zero or equal to or greater than the
++** value returned by sqlite3_expert_count()) is passed as the second argument
++** along with such an EXPERT_REPORT_* parameter, NULL is always returned.
++**
++** EXPERT_REPORT_SQL:
++**   Return the text of SQL statement iStmt.
++**
++** EXPERT_REPORT_INDEXES:
++**   Return a buffer containing the CREATE INDEX statements for all recommended
++**   indexes for statement iStmt. If there are no new recommeded indexes, NULL 
++**   is returned.
++**
++** EXPERT_REPORT_PLAN:
++**   Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query
++**   iStmt after the proposed indexes have been added to the database schema.
++**
++** EXPERT_REPORT_CANDIDATES:
++**   Return a pointer to a buffer containing the CREATE INDEX statements 
++**   for all indexes that were tested (for all SQL statements). The iStmt
++**   parameter is ignored for EXPERT_REPORT_CANDIDATES calls.
++*/
++const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
++
++/*
++** Values for the third argument passed to sqlite3_expert_report().
++*/
++#define EXPERT_REPORT_SQL        1
++#define EXPERT_REPORT_INDEXES    2
++#define EXPERT_REPORT_PLAN       3
++#define EXPERT_REPORT_CANDIDATES 4
++
++/*
++** Free an (sqlite3expert*) handle and all associated resources. There 
++** should be one call to this function for each successful call to 
++** sqlite3-expert_new().
++*/
++void sqlite3_expert_destroy(sqlite3expert*);
++
++
++
++/************************* End ../ext/expert/sqlite3expert.h ********************/
++/************************* Begin ../ext/expert/sqlite3expert.c ******************/
++/*
++** 2017 April 09
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++*/
++#include <assert.h>
++#include <string.h>
++#include <stdio.h>
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE 
++
++/* typedef sqlite3_int64 i64; */
++/* typedef sqlite3_uint64 u64; */
++
++typedef struct IdxColumn IdxColumn;
++typedef struct IdxConstraint IdxConstraint;
++typedef struct IdxScan IdxScan;
++typedef struct IdxStatement IdxStatement;
++typedef struct IdxTable IdxTable;
++typedef struct IdxWrite IdxWrite;
++
++#define STRLEN  (int)strlen
++
++/*
++** A temp table name that we assume no user database will actually use.
++** If this assumption proves incorrect triggers on the table with the
++** conflicting name will be ignored.
++*/
++#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
++
++/*
++** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
++** any other type of single-ended range constraint on a column).
++**
++** pLink:
++**   Used to temporarily link IdxConstraint objects into lists while
++**   creating candidate indexes.
++*/
++struct IdxConstraint {
++  char *zColl;                    /* Collation sequence */
++  int bRange;                     /* True for range, false for eq */
++  int iCol;                       /* Constrained table column */
++  int bFlag;                      /* Used by idxFindCompatible() */
++  int bDesc;                      /* True if ORDER BY <expr> DESC */
++  IdxConstraint *pNext;           /* Next constraint in pEq or pRange list */
++  IdxConstraint *pLink;           /* See above */
++};
++
++/*
++** A single scan of a single table.
++*/
++struct IdxScan {
++  IdxTable *pTab;                 /* Associated table object */
++  int iDb;                        /* Database containing table zTable */
++  i64 covering;                   /* Mask of columns required for cov. index */
++  IdxConstraint *pOrder;          /* ORDER BY columns */
++  IdxConstraint *pEq;             /* List of == constraints */
++  IdxConstraint *pRange;          /* List of < constraints */
++  IdxScan *pNextScan;             /* Next IdxScan object for same analysis */
++};
++
++/*
++** Information regarding a single database table. Extracted from 
++** "PRAGMA table_info" by function idxGetTableInfo().
++*/
++struct IdxColumn {
++  char *zName;
++  char *zColl;
++  int iPk;
++};
++struct IdxTable {
++  int nCol;
++  char *zName;                    /* Table name */
++  IdxColumn *aCol;
++  IdxTable *pNext;                /* Next table in linked list of all tables */
++};
++
++/*
++** An object of the following type is created for each unique table/write-op
++** seen. The objects are stored in a singly-linked list beginning at
++** sqlite3expert.pWrite.
++*/
++struct IdxWrite {
++  IdxTable *pTab;
++  int eOp;                        /* SQLITE_UPDATE, DELETE or INSERT */
++  IdxWrite *pNext;
++};
++
++/*
++** Each statement being analyzed is represented by an instance of this
++** structure.
++*/
++struct IdxStatement {
++  int iId;                        /* Statement number */
++  char *zSql;                     /* SQL statement */
++  char *zIdx;                     /* Indexes */
++  char *zEQP;                     /* Plan */
++  IdxStatement *pNext;
++};
++
++
++/*
++** A hash table for storing strings. With space for a payload string
++** with each entry. Methods are:
++**
++**   idxHashInit()
++**   idxHashClear()
++**   idxHashAdd()
++**   idxHashSearch()
++*/
++#define IDX_HASH_SIZE 1023
++typedef struct IdxHashEntry IdxHashEntry;
++typedef struct IdxHash IdxHash;
++struct IdxHashEntry {
++  char *zKey;                     /* nul-terminated key */
++  char *zVal;                     /* nul-terminated value string */
++  char *zVal2;                    /* nul-terminated value string 2 */
++  IdxHashEntry *pHashNext;        /* Next entry in same hash bucket */
++  IdxHashEntry *pNext;            /* Next entry in hash */
++};
++struct IdxHash {
++  IdxHashEntry *pFirst;
++  IdxHashEntry *aHash[IDX_HASH_SIZE];
++};
++
++/*
++** sqlite3expert object.
++*/
++struct sqlite3expert {
++  int iSample;                    /* Percentage of tables to sample for stat1 */
++  sqlite3 *db;                    /* User database */
++  sqlite3 *dbm;                   /* In-memory db for this analysis */
++  sqlite3 *dbv;                   /* Vtab schema for this analysis */
++  IdxTable *pTable;               /* List of all IdxTable objects */
++  IdxScan *pScan;                 /* List of scan objects */
++  IdxWrite *pWrite;               /* List of write objects */
++  IdxStatement *pStatement;       /* List of IdxStatement objects */
++  int bRun;                       /* True once analysis has run */
++  char **pzErrmsg;
++  int rc;                         /* Error code from whereinfo hook */
++  IdxHash hIdx;                   /* Hash containing all candidate indexes */
++  char *zCandidates;              /* For EXPERT_REPORT_CANDIDATES */
++};
++
++
++/*
++** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). 
++** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
++*/
++static void *idxMalloc(int *pRc, int nByte){
++  void *pRet;
++  assert( *pRc==SQLITE_OK );
++  assert( nByte>0 );
++  pRet = sqlite3_malloc(nByte);
++  if( pRet ){
++    memset(pRet, 0, nByte);
++  }else{
++    *pRc = SQLITE_NOMEM;
++  }
++  return pRet;
++}
++
++/*
++** Initialize an IdxHash hash table.
++*/
++static void idxHashInit(IdxHash *pHash){
++  memset(pHash, 0, sizeof(IdxHash));
++}
++
++/*
++** Reset an IdxHash hash table.
++*/
++static void idxHashClear(IdxHash *pHash){
++  int i;
++  for(i=0; i<IDX_HASH_SIZE; i++){
++    IdxHashEntry *pEntry;
++    IdxHashEntry *pNext;
++    for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
++      pNext = pEntry->pHashNext;
++      sqlite3_free(pEntry->zVal2);
++      sqlite3_free(pEntry);
++    }
++  }
++  memset(pHash, 0, sizeof(IdxHash));
++}
++
++/*
++** Return the index of the hash bucket that the string specified by the
++** arguments to this function belongs.
++*/
++static int idxHashString(const char *z, int n){
++  unsigned int ret = 0;
++  int i;
++  for(i=0; i<n; i++){
++    ret += (ret<<3) + (unsigned char)(z[i]);
++  }
++  return (int)(ret % IDX_HASH_SIZE);
++}
++
++/*
++** If zKey is already present in the hash table, return non-zero and do
++** nothing. Otherwise, add an entry with key zKey and payload string zVal to
++** the hash table passed as the second argument. 
++*/
++static int idxHashAdd(
++  int *pRc, 
++  IdxHash *pHash, 
++  const char *zKey,
++  const char *zVal
++){
++  int nKey = STRLEN(zKey);
++  int iHash = idxHashString(zKey, nKey);
++  int nVal = (zVal ? STRLEN(zVal) : 0);
++  IdxHashEntry *pEntry;
++  assert( iHash>=0 );
++  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
++    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
++      return 1;
++    }
++  }
++  pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
++  if( pEntry ){
++    pEntry->zKey = (char*)&pEntry[1];
++    memcpy(pEntry->zKey, zKey, nKey);
++    if( zVal ){
++      pEntry->zVal = &pEntry->zKey[nKey+1];
++      memcpy(pEntry->zVal, zVal, nVal);
++    }
++    pEntry->pHashNext = pHash->aHash[iHash];
++    pHash->aHash[iHash] = pEntry;
++
++    pEntry->pNext = pHash->pFirst;
++    pHash->pFirst = pEntry;
++  }
++  return 0;
++}
++
++/*
++** If zKey/nKey is present in the hash table, return a pointer to the 
++** hash-entry object.
++*/
++static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
++  int iHash;
++  IdxHashEntry *pEntry;
++  if( nKey<0 ) nKey = STRLEN(zKey);
++  iHash = idxHashString(zKey, nKey);
++  assert( iHash>=0 );
++  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
++    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
++      return pEntry;
++    }
++  }
++  return 0;
++}
++
++/*
++** If the hash table contains an entry with a key equal to the string
++** passed as the final two arguments to this function, return a pointer
++** to the payload string. Otherwise, if zKey/nKey is not present in the
++** hash table, return NULL.
++*/
++static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
++  IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
++  if( pEntry ) return pEntry->zVal;
++  return 0;
++}
++
++/*
++** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
++** variable to point to a copy of nul-terminated string zColl.
++*/
++static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
++  IdxConstraint *pNew;
++  int nColl = STRLEN(zColl);
++
++  assert( *pRc==SQLITE_OK );
++  pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
++  if( pNew ){
++    pNew->zColl = (char*)&pNew[1];
++    memcpy(pNew->zColl, zColl, nColl+1);
++  }
++  return pNew;
++}
++
++/*
++** An error associated with database handle db has just occurred. Pass
++** the error message to callback function xOut.
++*/
++static void idxDatabaseError(
++  sqlite3 *db,                    /* Database handle */
++  char **pzErrmsg                 /* Write error here */
++){
++  *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++}
++
++/*
++** Prepare an SQL statement.
++*/
++static int idxPrepareStmt(
++  sqlite3 *db,                    /* Database handle to compile against */
++  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
++  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
++  const char *zSql                /* SQL statement to compile */
++){
++  int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
++  if( rc!=SQLITE_OK ){
++    *ppStmt = 0;
++    idxDatabaseError(db, pzErrmsg);
++  }
++  return rc;
++}
++
++/*
++** Prepare an SQL statement using the results of a printf() formatting.
++*/
++static int idxPrintfPrepareStmt(
++  sqlite3 *db,                    /* Database handle to compile against */
++  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
++  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
++  const char *zFmt,               /* printf() format of SQL statement */
++  ...                             /* Trailing printf() arguments */
++){
++  va_list ap;
++  int rc;
++  char *zSql;
++  va_start(ap, zFmt);
++  zSql = sqlite3_vmprintf(zFmt, ap);
++  if( zSql==0 ){
++    rc = SQLITE_NOMEM;
++  }else{
++    rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
++    sqlite3_free(zSql);
++  }
++  va_end(ap);
++  return rc;
++}
++
++
++/*************************************************************************
++** Beginning of virtual table implementation.
++*/
++typedef struct ExpertVtab ExpertVtab;
++struct ExpertVtab {
++  sqlite3_vtab base;
++  IdxTable *pTab;
++  sqlite3expert *pExpert;
++};
++
++typedef struct ExpertCsr ExpertCsr;
++struct ExpertCsr {
++  sqlite3_vtab_cursor base;
++  sqlite3_stmt *pData;
++};
++
++static char *expertDequote(const char *zIn){
++  int n = STRLEN(zIn);
++  char *zRet = sqlite3_malloc(n);
++
++  assert( zIn[0]=='\'' );
++  assert( zIn[n-1]=='\'' );
++
++  if( zRet ){
++    int iOut = 0;
++    int iIn = 0;
++    for(iIn=1; iIn<(n-1); iIn++){
++      if( zIn[iIn]=='\'' ){
++        assert( zIn[iIn+1]=='\'' );
++        iIn++;
++      }
++      zRet[iOut++] = zIn[iIn];
++    }
++    zRet[iOut] = '\0';
++  }
++
++  return zRet;
++}
++
++/* 
++** This function is the implementation of both the xConnect and xCreate
++** methods of the r-tree virtual table.
++**
++**   argv[0]   -> module name
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**   argv[...] -> column names...
++*/
++static int expertConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  sqlite3expert *pExpert = (sqlite3expert*)pAux;
++  ExpertVtab *p = 0;
++  int rc;
++
++  if( argc!=4 ){
++    *pzErr = sqlite3_mprintf("internal error!");
++    rc = SQLITE_ERROR;
++  }else{
++    char *zCreateTable = expertDequote(argv[3]);
++    if( zCreateTable ){
++      rc = sqlite3_declare_vtab(db, zCreateTable);
++      if( rc==SQLITE_OK ){
++        p = idxMalloc(&rc, sizeof(ExpertVtab));
++      }
++      if( rc==SQLITE_OK ){
++        p->pExpert = pExpert;
++        p->pTab = pExpert->pTable;
++        assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
++      }
++      sqlite3_free(zCreateTable);
++    }else{
++      rc = SQLITE_NOMEM;
++    }
++  }
++
++  *ppVtab = (sqlite3_vtab*)p;
++  return rc;
++}
++
++static int expertDisconnect(sqlite3_vtab *pVtab){
++  ExpertVtab *p = (ExpertVtab*)pVtab;
++  sqlite3_free(p);
++  return SQLITE_OK;
++}
++
++static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
++  ExpertVtab *p = (ExpertVtab*)pVtab;
++  int rc = SQLITE_OK;
++  int n = 0;
++  IdxScan *pScan;
++  const int opmask = 
++    SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
++    SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
++    SQLITE_INDEX_CONSTRAINT_LE;
++
++  pScan = idxMalloc(&rc, sizeof(IdxScan));
++  if( pScan ){
++    int i;
++
++    /* Link the new scan object into the list */
++    pScan->pTab = p->pTab;
++    pScan->pNextScan = p->pExpert->pScan;
++    p->pExpert->pScan = pScan;
++
++    /* Add the constraints to the IdxScan object */
++    for(i=0; i<pIdxInfo->nConstraint; i++){
++      struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
++      if( pCons->usable 
++       && pCons->iColumn>=0 
++       && p->pTab->aCol[pCons->iColumn].iPk==0
++       && (pCons->op & opmask) 
++      ){
++        IdxConstraint *pNew;
++        const char *zColl = sqlite3_vtab_collation(pIdxInfo, i);
++        pNew = idxNewConstraint(&rc, zColl);
++        if( pNew ){
++          pNew->iCol = pCons->iColumn;
++          if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++            pNew->pNext = pScan->pEq;
++            pScan->pEq = pNew;
++          }else{
++            pNew->bRange = 1;
++            pNew->pNext = pScan->pRange;
++            pScan->pRange = pNew;
++          }
++        }
++        n++;
++        pIdxInfo->aConstraintUsage[i].argvIndex = n;
++      }
++    }
++
++    /* Add the ORDER BY to the IdxScan object */
++    for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
++      int iCol = pIdxInfo->aOrderBy[i].iColumn;
++      if( iCol>=0 ){
++        IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
++        if( pNew ){
++          pNew->iCol = iCol;
++          pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
++          pNew->pNext = pScan->pOrder;
++          pNew->pLink = pScan->pOrder;
++          pScan->pOrder = pNew;
++          n++;
++        }
++      }
++    }
++  }
++
++  pIdxInfo->estimatedCost = 1000000.0 / (n+1);
++  return rc;
++}
++
++static int expertUpdate(
++  sqlite3_vtab *pVtab, 
++  int nData, 
++  sqlite3_value **azData, 
++  sqlite_int64 *pRowid
++){
++  (void)pVtab;
++  (void)nData;
++  (void)azData;
++  (void)pRowid;
++  return SQLITE_OK;
++}
++
++/* 
++** Virtual table module xOpen method.
++*/
++static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
++  int rc = SQLITE_OK;
++  ExpertCsr *pCsr;
++  (void)pVTab;
++  pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
++  *ppCursor = (sqlite3_vtab_cursor*)pCsr;
++  return rc;
++}
++
++/* 
++** Virtual table module xClose method.
++*/
++static int expertClose(sqlite3_vtab_cursor *cur){
++  ExpertCsr *pCsr = (ExpertCsr*)cur;
++  sqlite3_finalize(pCsr->pData);
++  sqlite3_free(pCsr);
++  return SQLITE_OK;
++}
++
++/*
++** Virtual table module xEof method.
++**
++** Return non-zero if the cursor does not currently point to a valid 
++** record (i.e if the scan has finished), or zero otherwise.
++*/
++static int expertEof(sqlite3_vtab_cursor *cur){
++  ExpertCsr *pCsr = (ExpertCsr*)cur;
++  return pCsr->pData==0;
++}
++
++/* 
++** Virtual table module xNext method.
++*/
++static int expertNext(sqlite3_vtab_cursor *cur){
++  ExpertCsr *pCsr = (ExpertCsr*)cur;
++  int rc = SQLITE_OK;
++
++  assert( pCsr->pData );
++  rc = sqlite3_step(pCsr->pData);
++  if( rc!=SQLITE_ROW ){
++    rc = sqlite3_finalize(pCsr->pData);
++    pCsr->pData = 0;
++  }else{
++    rc = SQLITE_OK;
++  }
++
++  return rc;
++}
++
++/* 
++** Virtual table module xRowid method.
++*/
++static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  (void)cur;
++  *pRowid = 0;
++  return SQLITE_OK;
++}
++
++/* 
++** Virtual table module xColumn method.
++*/
++static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
++  ExpertCsr *pCsr = (ExpertCsr*)cur;
++  sqlite3_value *pVal;
++  pVal = sqlite3_column_value(pCsr->pData, i);
++  if( pVal ){
++    sqlite3_result_value(ctx, pVal);
++  }
++  return SQLITE_OK;
++}
++
++/* 
++** Virtual table module xFilter method.
++*/
++static int expertFilter(
++  sqlite3_vtab_cursor *cur, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  ExpertCsr *pCsr = (ExpertCsr*)cur;
++  ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
++  sqlite3expert *pExpert = pVtab->pExpert;
++  int rc;
++
++  (void)idxNum;
++  (void)idxStr;
++  (void)argc;
++  (void)argv;
++  rc = sqlite3_finalize(pCsr->pData);
++  pCsr->pData = 0;
++  if( rc==SQLITE_OK ){
++    rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
++        "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
++    );
++  }
++
++  if( rc==SQLITE_OK ){
++    rc = expertNext(cur);
++  }
++  return rc;
++}
++
++static int idxRegisterVtab(sqlite3expert *p){
++  static sqlite3_module expertModule = {
++    2,                            /* iVersion */
++    expertConnect,                /* xCreate - create a table */
++    expertConnect,                /* xConnect - connect to an existing table */
++    expertBestIndex,              /* xBestIndex - Determine search strategy */
++    expertDisconnect,             /* xDisconnect - Disconnect from a table */
++    expertDisconnect,             /* xDestroy - Drop a table */
++    expertOpen,                   /* xOpen - open a cursor */
++    expertClose,                  /* xClose - close a cursor */
++    expertFilter,                 /* xFilter - configure scan constraints */
++    expertNext,                   /* xNext - advance a cursor */
++    expertEof,                    /* xEof */
++    expertColumn,                 /* xColumn - read data */
++    expertRowid,                  /* xRowid - read data */
++    expertUpdate,                 /* xUpdate - write data */
++    0,                            /* xBegin - begin transaction */
++    0,                            /* xSync - sync transaction */
++    0,                            /* xCommit - commit transaction */
++    0,                            /* xRollback - rollback transaction */
++    0,                            /* xFindFunction - function overloading */
++    0,                            /* xRename - rename the table */
++    0,                            /* xSavepoint */
++    0,                            /* xRelease */
++    0,                            /* xRollbackTo */
++    0,                            /* xShadowName */
++  };
++
++  return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
++}
++/*
++** End of virtual table implementation.
++*************************************************************************/
++/*
++** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
++** is called, set it to the return value of sqlite3_finalize() before
++** returning. Otherwise, discard the sqlite3_finalize() return value.
++*/
++static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
++  int rc = sqlite3_finalize(pStmt);
++  if( *pRc==SQLITE_OK ) *pRc = rc;
++}
++
++/*
++** Attempt to allocate an IdxTable structure corresponding to table zTab
++** in the main database of connection db. If successful, set (*ppOut) to
++** point to the new object and return SQLITE_OK. Otherwise, return an
++** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
++** set to point to an error string.
++**
++** It is the responsibility of the caller to eventually free either the
++** IdxTable object or error message using sqlite3_free().
++*/
++static int idxGetTableInfo(
++  sqlite3 *db,                    /* Database connection to read details from */
++  const char *zTab,               /* Table name */
++  IdxTable **ppOut,               /* OUT: New object (if successful) */
++  char **pzErrmsg                 /* OUT: Error message (if not) */
++){
++  sqlite3_stmt *p1 = 0;
++  int nCol = 0;
++  int nTab = STRLEN(zTab);
++  int nByte = sizeof(IdxTable) + nTab + 1;
++  IdxTable *pNew = 0;
++  int rc, rc2;
++  char *pCsr = 0;
++
++  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
++    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
++    nByte += 1 + STRLEN(zCol);
++    rc = sqlite3_table_column_metadata(
++        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
++    );
++    nByte += 1 + STRLEN(zCol);
++    nCol++;
++  }
++  rc2 = sqlite3_reset(p1);
++  if( rc==SQLITE_OK ) rc = rc2;
++
++  nByte += sizeof(IdxColumn) * nCol;
++  if( rc==SQLITE_OK ){
++    pNew = idxMalloc(&rc, nByte);
++  }
++  if( rc==SQLITE_OK ){
++    pNew->aCol = (IdxColumn*)&pNew[1];
++    pNew->nCol = nCol;
++    pCsr = (char*)&pNew->aCol[nCol];
++  }
++
++  nCol = 0;
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
++    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
++    int nCopy = STRLEN(zCol) + 1;
++    pNew->aCol[nCol].zName = pCsr;
++    pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
++    memcpy(pCsr, zCol, nCopy);
++    pCsr += nCopy;
++
++    rc = sqlite3_table_column_metadata(
++        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
++    );
++    if( rc==SQLITE_OK ){
++      nCopy = STRLEN(zCol) + 1;
++      pNew->aCol[nCol].zColl = pCsr;
++      memcpy(pCsr, zCol, nCopy);
++      pCsr += nCopy;
++    }
++
++    nCol++;
++  }
++  idxFinalize(&rc, p1);
++
++  if( rc!=SQLITE_OK ){
++    sqlite3_free(pNew);
++    pNew = 0;
++  }else{
++    pNew->zName = pCsr;
++    memcpy(pNew->zName, zTab, nTab+1);
++  }
++
++  *ppOut = pNew;
++  return rc;
++}
++
++/*
++** This function is a no-op if *pRc is set to anything other than 
++** SQLITE_OK when it is called.
++**
++** If *pRc is initially set to SQLITE_OK, then the text specified by
++** the printf() style arguments is appended to zIn and the result returned
++** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
++** zIn before returning.
++*/
++static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
++  va_list ap;
++  char *zAppend = 0;
++  char *zRet = 0;
++  int nIn = zIn ? STRLEN(zIn) : 0;
++  int nAppend = 0;
++  va_start(ap, zFmt);
++  if( *pRc==SQLITE_OK ){
++    zAppend = sqlite3_vmprintf(zFmt, ap);
++    if( zAppend ){
++      nAppend = STRLEN(zAppend);
++      zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
++    }
++    if( zAppend && zRet ){
++      if( nIn ) memcpy(zRet, zIn, nIn);
++      memcpy(&zRet[nIn], zAppend, nAppend+1);
++    }else{
++      sqlite3_free(zRet);
++      zRet = 0;
++      *pRc = SQLITE_NOMEM;
++    }
++    sqlite3_free(zAppend);
++    sqlite3_free(zIn);
++  }
++  va_end(ap);
++  return zRet;
++}
++
++/*
++** Return true if zId must be quoted in order to use it as an SQL
++** identifier, or false otherwise.
++*/
++static int idxIdentifierRequiresQuotes(const char *zId){
++  int i;
++  for(i=0; zId[i]; i++){
++    if( !(zId[i]=='_')
++     && !(zId[i]>='0' && zId[i]<='9')
++     && !(zId[i]>='a' && zId[i]<='z')
++     && !(zId[i]>='A' && zId[i]<='Z')
++    ){
++      return 1;
++    }
++  }
++  return 0;
++}
++
++/*
++** This function appends an index column definition suitable for constraint
++** pCons to the string passed as zIn and returns the result.
++*/
++static char *idxAppendColDefn(
++  int *pRc,                       /* IN/OUT: Error code */
++  char *zIn,                      /* Column defn accumulated so far */
++  IdxTable *pTab,                 /* Table index will be created on */
++  IdxConstraint *pCons
++){
++  char *zRet = zIn;
++  IdxColumn *p = &pTab->aCol[pCons->iCol];
++  if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
++
++  if( idxIdentifierRequiresQuotes(p->zName) ){
++    zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
++  }else{
++    zRet = idxAppendText(pRc, zRet, "%s", p->zName);
++  }
++
++  if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
++    if( idxIdentifierRequiresQuotes(pCons->zColl) ){
++      zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
++    }else{
++      zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
++    }
++  }
++
++  if( pCons->bDesc ){
++    zRet = idxAppendText(pRc, zRet, " DESC");
++  }
++  return zRet;
++}
++
++/*
++** Search database dbm for an index compatible with the one idxCreateFromCons()
++** would create from arguments pScan, pEq and pTail. If no error occurs and 
++** such an index is found, return non-zero. Or, if no such index is found,
++** return zero.
++**
++** If an error occurs, set *pRc to an SQLite error code and return zero.
++*/
++static int idxFindCompatible(
++  int *pRc,                       /* OUT: Error code */
++  sqlite3* dbm,                   /* Database to search */
++  IdxScan *pScan,                 /* Scan for table to search for index on */
++  IdxConstraint *pEq,             /* List of == constraints */
++  IdxConstraint *pTail            /* List of range constraints */
++){
++  const char *zTbl = pScan->pTab->zName;
++  sqlite3_stmt *pIdxList = 0;
++  IdxConstraint *pIter;
++  int nEq = 0;                    /* Number of elements in pEq */
++  int rc;
++
++  /* Count the elements in list pEq */
++  for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
++
++  rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
++  while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
++    int bMatch = 1;
++    IdxConstraint *pT = pTail;
++    sqlite3_stmt *pInfo = 0;
++    const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
++
++    /* Zero the IdxConstraint.bFlag values in the pEq list */
++    for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
++
++    rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
++    while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
++      int iIdx = sqlite3_column_int(pInfo, 0);
++      int iCol = sqlite3_column_int(pInfo, 1);
++      const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
++
++      if( iIdx<nEq ){
++        for(pIter=pEq; pIter; pIter=pIter->pLink){
++          if( pIter->bFlag ) continue;
++          if( pIter->iCol!=iCol ) continue;
++          if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
++          pIter->bFlag = 1;
++          break;
++        }
++        if( pIter==0 ){
++          bMatch = 0;
++          break;
++        }
++      }else{
++        if( pT ){
++          if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
++            bMatch = 0;
++            break;
++          }
++          pT = pT->pLink;
++        }
++      }
++    }
++    idxFinalize(&rc, pInfo);
++
++    if( rc==SQLITE_OK && bMatch ){
++      sqlite3_finalize(pIdxList);
++      return 1;
++    }
++  }
++  idxFinalize(&rc, pIdxList);
++
++  *pRc = rc;
++  return 0;
++}
++
++static int idxCreateFromCons(
++  sqlite3expert *p,
++  IdxScan *pScan,
++  IdxConstraint *pEq, 
++  IdxConstraint *pTail
++){
++  sqlite3 *dbm = p->dbm;
++  int rc = SQLITE_OK;
++  if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
++    IdxTable *pTab = pScan->pTab;
++    char *zCols = 0;
++    char *zIdx = 0;
++    IdxConstraint *pCons;
++    unsigned int h = 0;
++    const char *zFmt;
++
++    for(pCons=pEq; pCons; pCons=pCons->pLink){
++      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
++    }
++    for(pCons=pTail; pCons; pCons=pCons->pLink){
++      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
++    }
++
++    if( rc==SQLITE_OK ){
++      /* Hash the list of columns to come up with a name for the index */
++      const char *zTable = pScan->pTab->zName;
++      char *zName;                /* Index name */
++      int i;
++      for(i=0; zCols[i]; i++){
++        h += ((h<<3) + zCols[i]);
++      }
++      zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
++      if( zName==0 ){ 
++        rc = SQLITE_NOMEM;
++      }else{
++        if( idxIdentifierRequiresQuotes(zTable) ){
++          zFmt = "CREATE INDEX '%q' ON %Q(%s)";
++        }else{
++          zFmt = "CREATE INDEX %s ON %s(%s)";
++        }
++        zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
++        if( !zIdx ){
++          rc = SQLITE_NOMEM;
++        }else{
++          rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
++          idxHashAdd(&rc, &p->hIdx, zName, zIdx);
++        }
++        sqlite3_free(zName);
++        sqlite3_free(zIdx);
++      }
++    }
++
++    sqlite3_free(zCols);
++  }
++  return rc;
++}
++
++/*
++** Return true if list pList (linked by IdxConstraint.pLink) contains
++** a constraint compatible with *p. Otherwise return false.
++*/
++static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
++  IdxConstraint *pCmp;
++  for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
++    if( p->iCol==pCmp->iCol ) return 1;
++  }
++  return 0;
++}
++
++static int idxCreateFromWhere(
++  sqlite3expert *p, 
++  IdxScan *pScan,                 /* Create indexes for this scan */
++  IdxConstraint *pTail            /* range/ORDER BY constraints for inclusion */
++){
++  IdxConstraint *p1 = 0;
++  IdxConstraint *pCon;
++  int rc;
++
++  /* Gather up all the == constraints. */
++  for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
++    if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
++      pCon->pLink = p1;
++      p1 = pCon;
++    }
++  }
++
++  /* Create an index using the == constraints collected above. And the
++  ** range constraint/ORDER BY terms passed in by the caller, if any. */
++  rc = idxCreateFromCons(p, pScan, p1, pTail);
++
++  /* If no range/ORDER BY passed by the caller, create a version of the
++  ** index for each range constraint.  */
++  if( pTail==0 ){
++    for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
++      assert( pCon->pLink==0 );
++      if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
++        rc = idxCreateFromCons(p, pScan, p1, pCon);
++      }
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Create candidate indexes in database [dbm] based on the data in 
++** linked-list pScan.
++*/
++static int idxCreateCandidates(sqlite3expert *p){
++  int rc = SQLITE_OK;
++  IdxScan *pIter;
++
++  for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
++    rc = idxCreateFromWhere(p, pIter, 0);
++    if( rc==SQLITE_OK && pIter->pOrder ){
++      rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
++    }
++  }
++
++  return rc;
++}
++
++/*
++** Free all elements of the linked list starting at pConstraint.
++*/
++static void idxConstraintFree(IdxConstraint *pConstraint){
++  IdxConstraint *pNext;
++  IdxConstraint *p;
++
++  for(p=pConstraint; p; p=pNext){
++    pNext = p->pNext;
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Free all elements of the linked list starting from pScan up until pLast
++** (pLast is not freed).
++*/
++static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
++  IdxScan *p;
++  IdxScan *pNext;
++  for(p=pScan; p!=pLast; p=pNext){
++    pNext = p->pNextScan;
++    idxConstraintFree(p->pOrder);
++    idxConstraintFree(p->pEq);
++    idxConstraintFree(p->pRange);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Free all elements of the linked list starting from pStatement up 
++** until pLast (pLast is not freed).
++*/
++static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
++  IdxStatement *p;
++  IdxStatement *pNext;
++  for(p=pStatement; p!=pLast; p=pNext){
++    pNext = p->pNext;
++    sqlite3_free(p->zEQP);
++    sqlite3_free(p->zIdx);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Free the linked list of IdxTable objects starting at pTab.
++*/
++static void idxTableFree(IdxTable *pTab){
++  IdxTable *pIter;
++  IdxTable *pNext;
++  for(pIter=pTab; pIter; pIter=pNext){
++    pNext = pIter->pNext;
++    sqlite3_free(pIter);
++  }
++}
++
++/*
++** Free the linked list of IdxWrite objects starting at pTab.
++*/
++static void idxWriteFree(IdxWrite *pTab){
++  IdxWrite *pIter;
++  IdxWrite *pNext;
++  for(pIter=pTab; pIter; pIter=pNext){
++    pNext = pIter->pNext;
++    sqlite3_free(pIter);
++  }
++}
++
++
++
++/*
++** This function is called after candidate indexes have been created. It
++** runs all the queries to see which indexes they prefer, and populates
++** IdxStatement.zIdx and IdxStatement.zEQP with the results.
++*/
++int idxFindIndexes(
++  sqlite3expert *p,
++  char **pzErr                         /* OUT: Error message (sqlite3_malloc) */
++){
++  IdxStatement *pStmt;
++  sqlite3 *dbm = p->dbm;
++  int rc = SQLITE_OK;
++
++  IdxHash hIdx;
++  idxHashInit(&hIdx);
++
++  for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
++    IdxHashEntry *pEntry;
++    sqlite3_stmt *pExplain = 0;
++    idxHashClear(&hIdx);
++    rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
++        "EXPLAIN QUERY PLAN %s", pStmt->zSql
++    );
++    while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
++      /* int iId = sqlite3_column_int(pExplain, 0); */
++      /* int iParent = sqlite3_column_int(pExplain, 1); */
++      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
++      const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
++      int nDetail = STRLEN(zDetail);
++      int i;
++
++      for(i=0; i<nDetail; i++){
++        const char *zIdx = 0;
++        if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
++          zIdx = &zDetail[i+13];
++        }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
++          zIdx = &zDetail[i+22];
++        }
++        if( zIdx ){
++          const char *zSql;
++          int nIdx = 0;
++          while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
++            nIdx++;
++          }
++          zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
++          if( zSql ){
++            idxHashAdd(&rc, &hIdx, zSql, 0);
++            if( rc ) goto find_indexes_out;
++          }
++          break;
++        }
++      }
++
++      if( zDetail[0]!='-' ){
++        pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
++      }
++    }
++
++    for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
++      pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
++    }
++
++    idxFinalize(&rc, pExplain);
++  }
++
++ find_indexes_out:
++  idxHashClear(&hIdx);
++  return rc;
++}
++
++static int idxAuthCallback(
++  void *pCtx,
++  int eOp,
++  const char *z3,
++  const char *z4,
++  const char *zDb,
++  const char *zTrigger
++){
++  int rc = SQLITE_OK;
++  (void)z4;
++  (void)zTrigger;
++  if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
++    if( sqlite3_stricmp(zDb, "main")==0 ){
++      sqlite3expert *p = (sqlite3expert*)pCtx;
++      IdxTable *pTab;
++      for(pTab=p->pTable; pTab; pTab=pTab->pNext){
++        if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
++      }
++      if( pTab ){
++        IdxWrite *pWrite;
++        for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
++          if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
++        }
++        if( pWrite==0 ){
++          pWrite = idxMalloc(&rc, sizeof(IdxWrite));
++          if( rc==SQLITE_OK ){
++            pWrite->pTab = pTab;
++            pWrite->eOp = eOp;
++            pWrite->pNext = p->pWrite;
++            p->pWrite = pWrite;
++          }
++        }
++      }
++    }
++  }
++  return rc;
++}
++
++static int idxProcessOneTrigger(
++  sqlite3expert *p, 
++  IdxWrite *pWrite, 
++  char **pzErr
++){
++  static const char *zInt = UNIQUE_TABLE_NAME;
++  static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
++  IdxTable *pTab = pWrite->pTab;
++  const char *zTab = pTab->zName;
++  const char *zSql = 
++    "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
++    "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
++    "ORDER BY type;";
++  sqlite3_stmt *pSelect = 0;
++  int rc = SQLITE_OK;
++  char *zWrite = 0;
++
++  /* Create the table and its triggers in the temp schema */
++  rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
++    const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
++    rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
++  }
++  idxFinalize(&rc, pSelect);
++
++  /* Rename the table in the temp schema to zInt */
++  if( rc==SQLITE_OK ){
++    char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
++    if( z==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
++      sqlite3_free(z);
++    }
++  }
++
++  switch( pWrite->eOp ){
++    case SQLITE_INSERT: {
++      int i;
++      zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
++      for(i=0; i<pTab->nCol; i++){
++        zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
++      }
++      zWrite = idxAppendText(&rc, zWrite, ")");
++      break;
++    }
++    case SQLITE_UPDATE: {
++      int i;
++      zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
++      for(i=0; i<pTab->nCol; i++){
++        zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", 
++            pTab->aCol[i].zName
++        );
++      }
++      break;
++    }
++    default: {
++      assert( pWrite->eOp==SQLITE_DELETE );
++      if( rc==SQLITE_OK ){
++        zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
++        if( zWrite==0 ) rc = SQLITE_NOMEM;
++      }
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    sqlite3_stmt *pX = 0;
++    rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
++    idxFinalize(&rc, pX);
++    if( rc!=SQLITE_OK ){
++      idxDatabaseError(p->dbv, pzErr);
++    }
++  }
++  sqlite3_free(zWrite);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
++  }
++
++  return rc;
++}
++
++static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
++  int rc = SQLITE_OK;
++  IdxWrite *pEnd = 0;
++  IdxWrite *pFirst = p->pWrite;
++
++  while( rc==SQLITE_OK && pFirst!=pEnd ){
++    IdxWrite *pIter;
++    for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
++      rc = idxProcessOneTrigger(p, pIter, pzErr);
++    }
++    pEnd = pFirst;
++    pFirst = p->pWrite;
++  }
++
++  return rc;
++}
++
++
++static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
++  int rc = idxRegisterVtab(p);
++  sqlite3_stmt *pSchema = 0;
++
++  /* For each table in the main db schema:
++  **
++  **   1) Add an entry to the p->pTable list, and
++  **   2) Create the equivalent virtual table in dbv.
++  */
++  rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
++      "SELECT type, name, sql, 1 FROM sqlite_master "
++      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
++      " UNION ALL "
++      "SELECT type, name, sql, 2 FROM sqlite_master "
++      "WHERE type = 'trigger'"
++      "  AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
++      "ORDER BY 4, 1"
++  );
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
++    const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
++    const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
++    const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
++
++    if( zType[0]=='v' || zType[1]=='r' ){
++      rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
++    }else{
++      IdxTable *pTab;
++      rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
++      if( rc==SQLITE_OK ){
++        int i;
++        char *zInner = 0;
++        char *zOuter = 0;
++        pTab->pNext = p->pTable;
++        p->pTable = pTab;
++
++        /* The statement the vtab will pass to sqlite3_declare_vtab() */
++        zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
++        for(i=0; i<pTab->nCol; i++){
++          zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", 
++              (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
++          );
++        }
++        zInner = idxAppendText(&rc, zInner, ")");
++
++        /* The CVT statement to create the vtab */
++        zOuter = idxAppendText(&rc, 0, 
++            "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
++        );
++        if( rc==SQLITE_OK ){
++          rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
++        }
++        sqlite3_free(zInner);
++        sqlite3_free(zOuter);
++      }
++    }
++  }
++  idxFinalize(&rc, pSchema);
++  return rc;
++}
++
++struct IdxSampleCtx {
++  int iTarget;
++  double target;                  /* Target nRet/nRow value */
++  double nRow;                    /* Number of rows seen */
++  double nRet;                    /* Number of rows returned */
++};
++
++static void idxSampleFunc(
++  sqlite3_context *pCtx,
++  int argc,
++  sqlite3_value **argv
++){
++  struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
++  int bRet;
++
++  (void)argv;
++  assert( argc==0 );
++  if( p->nRow==0.0 ){
++    bRet = 1;
++  }else{
++    bRet = (p->nRet / p->nRow) <= p->target;
++    if( bRet==0 ){
++      unsigned short rnd;
++      sqlite3_randomness(2, (void*)&rnd);
++      bRet = ((int)rnd % 100) <= p->iTarget;
++    }
++  }
++
++  sqlite3_result_int(pCtx, bRet);
++  p->nRow += 1.0;
++  p->nRet += (double)bRet;
++}
++
++struct IdxRemCtx {
++  int nSlot;
++  struct IdxRemSlot {
++    int eType;                    /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
++    i64 iVal;                     /* SQLITE_INTEGER value */
++    double rVal;                  /* SQLITE_FLOAT value */
++    int nByte;                    /* Bytes of space allocated at z */
++    int n;                        /* Size of buffer z */
++    char *z;                      /* SQLITE_TEXT/BLOB value */
++  } aSlot[1];
++};
++
++/*
++** Implementation of scalar function rem().
++*/
++static void idxRemFunc(
++  sqlite3_context *pCtx,
++  int argc,
++  sqlite3_value **argv
++){
++  struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
++  struct IdxRemSlot *pSlot;
++  int iSlot;
++  assert( argc==2 );
++
++  iSlot = sqlite3_value_int(argv[0]);
++  assert( iSlot<=p->nSlot );
++  pSlot = &p->aSlot[iSlot];
++
++  switch( pSlot->eType ){
++    case SQLITE_NULL:
++      /* no-op */
++      break;
++
++    case SQLITE_INTEGER:
++      sqlite3_result_int64(pCtx, pSlot->iVal);
++      break;
++
++    case SQLITE_FLOAT:
++      sqlite3_result_double(pCtx, pSlot->rVal);
++      break;
++
++    case SQLITE_BLOB:
++      sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
++      break;
++
++    case SQLITE_TEXT:
++      sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
++      break;
++  }
++
++  pSlot->eType = sqlite3_value_type(argv[1]);
++  switch( pSlot->eType ){
++    case SQLITE_NULL:
++      /* no-op */
++      break;
++
++    case SQLITE_INTEGER:
++      pSlot->iVal = sqlite3_value_int64(argv[1]);
++      break;
++
++    case SQLITE_FLOAT:
++      pSlot->rVal = sqlite3_value_double(argv[1]);
++      break;
++
++    case SQLITE_BLOB:
++    case SQLITE_TEXT: {
++      int nByte = sqlite3_value_bytes(argv[1]);
++      if( nByte>pSlot->nByte ){
++        char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
++        if( zNew==0 ){
++          sqlite3_result_error_nomem(pCtx);
++          return;
++        }
++        pSlot->nByte = nByte*2;
++        pSlot->z = zNew;
++      }
++      pSlot->n = nByte;
++      if( pSlot->eType==SQLITE_BLOB ){
++        memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
++      }else{
++        memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
++      }
++      break;
++    }
++  }
++}
++
++static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
++  int rc = SQLITE_OK;
++  const char *zMax = 
++    "SELECT max(i.seqno) FROM "
++    "  sqlite_master AS s, "
++    "  pragma_index_list(s.name) AS l, "
++    "  pragma_index_info(l.name) AS i "
++    "WHERE s.type = 'table'";
++  sqlite3_stmt *pMax = 0;
++
++  *pnMax = 0;
++  rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
++  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
++    *pnMax = sqlite3_column_int(pMax, 0) + 1;
++  }
++  idxFinalize(&rc, pMax);
++
++  return rc;
++}
++
++static int idxPopulateOneStat1(
++  sqlite3expert *p,
++  sqlite3_stmt *pIndexXInfo,
++  sqlite3_stmt *pWriteStat,
++  const char *zTab,
++  const char *zIdx,
++  char **pzErr
++){
++  char *zCols = 0;
++  char *zOrder = 0;
++  char *zQuery = 0;
++  int nCol = 0;
++  int i;
++  sqlite3_stmt *pQuery = 0;
++  int *aStat = 0;
++  int rc = SQLITE_OK;
++
++  assert( p->iSample>0 );
++
++  /* Formulate the query text */
++  sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
++  while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
++    const char *zComma = zCols==0 ? "" : ", ";
++    const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
++    const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
++    zCols = idxAppendText(&rc, zCols, 
++        "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
++    );
++    zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
++  }
++  sqlite3_reset(pIndexXInfo);
++  if( rc==SQLITE_OK ){
++    if( p->iSample==100 ){
++      zQuery = sqlite3_mprintf(
++          "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
++      );
++    }else{
++      zQuery = sqlite3_mprintf(
++          "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
++      );
++    }
++  }
++  sqlite3_free(zCols);
++  sqlite3_free(zOrder);
++
++  /* Formulate the query text */
++  if( rc==SQLITE_OK ){
++    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
++    rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
++  }
++  sqlite3_free(zQuery);
++
++  if( rc==SQLITE_OK ){
++    aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
++  }
++  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
++    IdxHashEntry *pEntry;
++    char *zStat = 0;
++    for(i=0; i<=nCol; i++) aStat[i] = 1;
++    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
++      aStat[0]++;
++      for(i=0; i<nCol; i++){
++        if( sqlite3_column_int(pQuery, i)==0 ) break;
++      }
++      for(/*no-op*/; i<nCol; i++){
++        aStat[i+1]++;
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      int s0 = aStat[0];
++      zStat = sqlite3_mprintf("%d", s0);
++      if( zStat==0 ) rc = SQLITE_NOMEM;
++      for(i=1; rc==SQLITE_OK && i<=nCol; i++){
++        zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
++      }
++    }
++
++    if( rc==SQLITE_OK ){
++      sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
++      sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
++      sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
++      sqlite3_step(pWriteStat);
++      rc = sqlite3_reset(pWriteStat);
++    }
++
++    pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
++    if( pEntry ){
++      assert( pEntry->zVal2==0 );
++      pEntry->zVal2 = zStat;
++    }else{
++      sqlite3_free(zStat);
++    }
++  }
++  sqlite3_free(aStat);
++  idxFinalize(&rc, pQuery);
++
++  return rc;
++}
++
++static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
++  int rc;
++  char *zSql;
++
++  rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
++  if( rc!=SQLITE_OK ) return rc;
++
++  zSql = sqlite3_mprintf(
++      "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
++  );
++  if( zSql==0 ) return SQLITE_NOMEM;
++  rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
++  sqlite3_free(zSql);
++
++  return rc;
++}
++
++/*
++** This function is called as part of sqlite3_expert_analyze(). Candidate
++** indexes have already been created in database sqlite3expert.dbm, this
++** function populates sqlite_stat1 table in the same database.
++**
++** The stat1 data is generated by querying the 
++*/
++static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
++  int rc = SQLITE_OK;
++  int nMax =0;
++  struct IdxRemCtx *pCtx = 0;
++  struct IdxSampleCtx samplectx; 
++  int i;
++  i64 iPrev = -100000;
++  sqlite3_stmt *pAllIndex = 0;
++  sqlite3_stmt *pIndexXInfo = 0;
++  sqlite3_stmt *pWrite = 0;
++
++  const char *zAllIndex =
++    "SELECT s.rowid, s.name, l.name FROM "
++    "  sqlite_master AS s, "
++    "  pragma_index_list(s.name) AS l "
++    "WHERE s.type = 'table'";
++  const char *zIndexXInfo = 
++    "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
++  const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
++
++  /* If iSample==0, no sqlite_stat1 data is required. */
++  if( p->iSample==0 ) return SQLITE_OK;
++
++  rc = idxLargestIndex(p->dbm, &nMax, pzErr);
++  if( nMax<=0 || rc!=SQLITE_OK ) return rc;
++
++  rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
++
++  if( rc==SQLITE_OK ){
++    int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
++    pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
++  }
++
++  if( rc==SQLITE_OK ){
++    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
++    rc = sqlite3_create_function(
++        dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
++    );
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_function(
++        p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
++    );
++  }
++
++  if( rc==SQLITE_OK ){
++    pCtx->nSlot = nMax+1;
++    rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
++  }
++  if( rc==SQLITE_OK ){
++    rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
++  }
++  if( rc==SQLITE_OK ){
++    rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
++  }
++
++  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
++    i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
++    const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
++    const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
++    if( p->iSample<100 && iPrev!=iRowid ){
++      samplectx.target = (double)p->iSample / 100.0;
++      samplectx.iTarget = p->iSample;
++      samplectx.nRow = 0.0;
++      samplectx.nRet = 0.0;
++      rc = idxBuildSampleTable(p, zTab);
++      if( rc!=SQLITE_OK ) break;
++    }
++    rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
++    iPrev = iRowid;
++  }
++  if( rc==SQLITE_OK && p->iSample<100 ){
++    rc = sqlite3_exec(p->dbv, 
++        "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
++    );
++  }
++
++  idxFinalize(&rc, pAllIndex);
++  idxFinalize(&rc, pIndexXInfo);
++  idxFinalize(&rc, pWrite);
++
++  for(i=0; i<pCtx->nSlot; i++){
++    sqlite3_free(pCtx->aSlot[i].z);
++  }
++  sqlite3_free(pCtx);
++
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
++  }
++
++  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
++  return rc;
++}
++
++/*
++** Allocate a new sqlite3expert object.
++*/
++sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
++  int rc = SQLITE_OK;
++  sqlite3expert *pNew;
++
++  pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
++
++  /* Open two in-memory databases to work with. The "vtab database" (dbv)
++  ** will contain a virtual table corresponding to each real table in
++  ** the user database schema, and a copy of each view. It is used to
++  ** collect information regarding the WHERE, ORDER BY and other clauses
++  ** of the user's query.
++  */
++  if( rc==SQLITE_OK ){
++    pNew->db = db;
++    pNew->iSample = 100;
++    rc = sqlite3_open(":memory:", &pNew->dbv);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_open(":memory:", &pNew->dbm);
++    if( rc==SQLITE_OK ){
++      sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0);
++    }
++  }
++  
++
++  /* Copy the entire schema of database [db] into [dbm]. */
++  if( rc==SQLITE_OK ){
++    sqlite3_stmt *pSql;
++    rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, 
++        "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
++        " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
++    );
++    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
++      const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
++      rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
++    }
++    idxFinalize(&rc, pSql);
++  }
++
++  /* Create the vtab schema */
++  if( rc==SQLITE_OK ){
++    rc = idxCreateVtabSchema(pNew, pzErrmsg);
++  }
++
++  /* Register the auth callback with dbv */
++  if( rc==SQLITE_OK ){
++    sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
++  }
++
++  /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
++  ** return the new sqlite3expert handle.  */
++  if( rc!=SQLITE_OK ){
++    sqlite3_expert_destroy(pNew);
++    pNew = 0;
++  }
++  return pNew;
++}
++
++/*
++** Configure an sqlite3expert object.
++*/
++int sqlite3_expert_config(sqlite3expert *p, int op, ...){
++  int rc = SQLITE_OK;
++  va_list ap;
++  va_start(ap, op);
++  switch( op ){
++    case EXPERT_CONFIG_SAMPLE: {
++      int iVal = va_arg(ap, int);
++      if( iVal<0 ) iVal = 0;
++      if( iVal>100 ) iVal = 100;
++      p->iSample = iVal;
++      break;
++    }
++    default:
++      rc = SQLITE_NOTFOUND;
++      break;
++  }
++
++  va_end(ap);
++  return rc;
++}
++
++/*
++** Add an SQL statement to the analysis.
++*/
++int sqlite3_expert_sql(
++  sqlite3expert *p,               /* From sqlite3_expert_new() */
++  const char *zSql,               /* SQL statement to add */
++  char **pzErr                    /* OUT: Error message (if any) */
++){
++  IdxScan *pScanOrig = p->pScan;
++  IdxStatement *pStmtOrig = p->pStatement;
++  int rc = SQLITE_OK;
++  const char *zStmt = zSql;
++
++  if( p->bRun ) return SQLITE_MISUSE;
++
++  while( rc==SQLITE_OK && zStmt && zStmt[0] ){
++    sqlite3_stmt *pStmt = 0;
++    rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
++    if( rc==SQLITE_OK ){
++      if( pStmt ){
++        IdxStatement *pNew;
++        const char *z = sqlite3_sql(pStmt);
++        int n = STRLEN(z);
++        pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
++        if( rc==SQLITE_OK ){
++          pNew->zSql = (char*)&pNew[1];
++          memcpy(pNew->zSql, z, n+1);
++          pNew->pNext = p->pStatement;
++          if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
++          p->pStatement = pNew;
++        }
++        sqlite3_finalize(pStmt);
++      }
++    }else{
++      idxDatabaseError(p->dbv, pzErr);
++    }
++  }
++
++  if( rc!=SQLITE_OK ){
++    idxScanFree(p->pScan, pScanOrig);
++    idxStatementFree(p->pStatement, pStmtOrig);
++    p->pScan = pScanOrig;
++    p->pStatement = pStmtOrig;
++  }
++
++  return rc;
++}
++
++int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
++  int rc;
++  IdxHashEntry *pEntry;
++
++  /* Do trigger processing to collect any extra IdxScan structures */
++  rc = idxProcessTriggers(p, pzErr);
++
++  /* Create candidate indexes within the in-memory database file */
++  if( rc==SQLITE_OK ){
++    rc = idxCreateCandidates(p);
++  }
++
++  /* Generate the stat1 data */
++  if( rc==SQLITE_OK ){
++    rc = idxPopulateStat1(p, pzErr);
++  }
++
++  /* Formulate the EXPERT_REPORT_CANDIDATES text */
++  for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
++    p->zCandidates = idxAppendText(&rc, p->zCandidates, 
++        "%s;%s%s\n", pEntry->zVal, 
++        pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
++    );
++  }
++
++  /* Figure out which of the candidate indexes are preferred by the query
++  ** planner and report the results to the user.  */
++  if( rc==SQLITE_OK ){
++    rc = idxFindIndexes(p, pzErr);
++  }
++
++  if( rc==SQLITE_OK ){
++    p->bRun = 1;
++  }
++  return rc;
++}
++
++/*
++** Return the total number of statements that have been added to this
++** sqlite3expert using sqlite3_expert_sql().
++*/
++int sqlite3_expert_count(sqlite3expert *p){
++  int nRet = 0;
++  if( p->pStatement ) nRet = p->pStatement->iId+1;
++  return nRet;
++}
++
++/*
++** Return a component of the report.
++*/
++const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
++  const char *zRet = 0;
++  IdxStatement *pStmt;
++
++  if( p->bRun==0 ) return 0;
++  for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
++  switch( eReport ){
++    case EXPERT_REPORT_SQL:
++      if( pStmt ) zRet = pStmt->zSql;
++      break;
++    case EXPERT_REPORT_INDEXES:
++      if( pStmt ) zRet = pStmt->zIdx;
++      break;
++    case EXPERT_REPORT_PLAN:
++      if( pStmt ) zRet = pStmt->zEQP;
++      break;
++    case EXPERT_REPORT_CANDIDATES:
++      zRet = p->zCandidates;
++      break;
++  }
++  return zRet;
++}
++
++/*
++** Free an sqlite3expert object.
++*/
++void sqlite3_expert_destroy(sqlite3expert *p){
++  if( p ){
++    sqlite3_close(p->dbm);
++    sqlite3_close(p->dbv);
++    idxScanFree(p->pScan, 0);
++    idxStatementFree(p->pStatement, 0);
++    idxTableFree(p->pTable);
++    idxWriteFree(p->pWrite);
++    idxHashClear(&p->hIdx);
++    sqlite3_free(p->zCandidates);
++    sqlite3_free(p);
++  }
++}
++
++#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
++
++/************************* End ../ext/expert/sqlite3expert.c ********************/
++
+ #if defined(SQLITE_ENABLE_SESSION)
+ /*
+ ** State information for a single open session
+@@ -2182,6 +8517,29 @@
+   int colWidth[100];  /* Column widths prior to ".explain on" */
+ };
+ 
++typedef struct ExpertInfo ExpertInfo;
++struct ExpertInfo {
++  sqlite3expert *pExpert;
++  int bVerbose;
++};
++
++/* A single line in the EQP output */
++typedef struct EQPGraphRow EQPGraphRow;
++struct EQPGraphRow {
++  int iEqpId;           /* ID for this row */
++  int iParentId;        /* ID of the parent row */
++  EQPGraphRow *pNext;   /* Next row in sequence */
++  char zText[1];        /* Text to display for this row */
++};
++
++/* All EQP output is collected into an instance of the following */
++typedef struct EQPGraph EQPGraph;
++struct EQPGraph {
++  EQPGraphRow *pRow;    /* Linked list of all rows of the EQP output */
++  EQPGraphRow *pLast;   /* Last element of the pRow list */
++  char zPrefix[100];    /* Graph prefix */
++};
++
+ /*
+ ** State information about the database connection is contained in an
+ ** instance of the following structure.
+@@ -2189,10 +8547,15 @@
+ typedef struct ShellState ShellState;
+ struct ShellState {
+   sqlite3 *db;           /* The database */
+-  int autoExplain;       /* Automatically turn on .explain mode */
+-  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
+-  int statsOn;           /* True to display memory stats before each finalize */
+-  int scanstatsOn;       /* True to display scan stats before each finalize */
++  u8 autoExplain;        /* Automatically turn on .explain mode */
++  u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
++  u8 autoEQPtest;        /* autoEQP is in test mode */
++  u8 statsOn;            /* True to display memory stats before each finalize */
++  u8 scanstatsOn;        /* True to display scan stats before each finalize */
++  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
++  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
++  u8 nEqpLevel;          /* Depth of the EQP output graph */
++  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
+   int outCount;          /* Revert to stdout when reaching zero */
+   int cnt;               /* Number of records displayed so far */
+   FILE *out;             /* Write results here */
+@@ -2199,6 +8562,7 @@
+   FILE *traceOut;        /* Output for sqlite3_trace() */
+   int nErr;              /* Number of errors seen */
+   int mode;              /* An output mode setting */
++  int modePrior;         /* Saved mode */
+   int cMode;             /* temporary output mode for the current query */
+   int normalMode;        /* Output mode before ".explain on" */
+   int writableSchema;    /* True if PRAGMA writable_schema=ON */
+@@ -2206,9 +8570,12 @@
+   int nCheck;            /* Number of ".check" commands run */
+   unsigned shellFlgs;    /* Various flags */
+   char *zDestTable;      /* Name of destination table when MODE_Insert */
++  char *zTempFile;       /* Temporary file that might need deleting */
+   char zTestcase[30];    /* Name of current test case */
+   char colSeparator[20]; /* Column separator character for several modes */
+   char rowSeparator[20]; /* Row separator character for MODE_Ascii */
++  char colSepPrior[20];  /* Saved column separator */
++  char rowSepPrior[20];  /* Saved row separator */
+   int colWidth[100];     /* Requested width of each column when in column mode*/
+   int actualWidth[100];  /* Actual width of each column */
+   char nullValue[20];    /* The text to print when a NULL comes back from
+@@ -2222,23 +8589,41 @@
+   int *aiIndent;         /* Array of indents used in MODE_Explain */
+   int nIndent;           /* Size of array aiIndent[] */
+   int iIndent;           /* Index of current op in aiIndent[] */
++  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
+ #if defined(SQLITE_ENABLE_SESSION)
+   int nSession;             /* Number of active sessions */
+   OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
+ #endif
++  ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
+ };
+ 
++
++/* Allowed values for ShellState.autoEQP
++*/
++#define AUTOEQP_off      0           /* Automatic EXPLAIN QUERY PLAN is off */
++#define AUTOEQP_on       1           /* Automatic EQP is on */
++#define AUTOEQP_trigger  2           /* On and also show plans for triggers */
++#define AUTOEQP_full     3           /* Show full EXPLAIN */
++
++/* Allowed values for ShellState.openMode
++*/
++#define SHELL_OPEN_UNSPEC      0      /* No open-mode specified */
++#define SHELL_OPEN_NORMAL      1      /* Normal database file */
++#define SHELL_OPEN_APPENDVFS   2      /* Use appendvfs */
++#define SHELL_OPEN_ZIPFILE     3      /* Use the zipfile virtual table */
++#define SHELL_OPEN_READONLY    4      /* Open a normal database read-only */
++#define SHELL_OPEN_DESERIALIZE 5      /* Open using sqlite3_deserialize() */
++
+ /*
+ ** These are the allowed shellFlgs values
+ */
+-#define SHFLG_Scratch        0x00000001 /* The --scratch option is used */
+-#define SHFLG_Pagecache      0x00000002 /* The --pagecache option is used */
+-#define SHFLG_Lookaside      0x00000004 /* Lookaside memory is used */
+-#define SHFLG_Backslash      0x00000008 /* The --backslash option is used */
+-#define SHFLG_PreserveRowid  0x00000010 /* .dump preserves rowid values */
+-#define SHFLG_Newlines       0x00000020 /* .dump --newline flag */
+-#define SHFLG_CountChanges   0x00000040 /* .changes setting */
+-#define SHFLG_Echo           0x00000080 /* .echo or --echo setting */
++#define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
++#define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
++#define SHFLG_Backslash      0x00000004 /* The --backslash option is used */
++#define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
++#define SHFLG_Newlines       0x00000010 /* .dump --newline flag */
++#define SHFLG_CountChanges   0x00000020 /* .changes setting */
++#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
+ 
+ /*
+ ** Macros for testing and setting shellFlgs
+@@ -2262,6 +8647,7 @@
+ #define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
+ #define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
+ #define MODE_Pretty  11  /* Pretty-print schemas */
++#define MODE_EQP     12  /* Converts EXPLAIN QUERY PLAN output into a graph */
+ 
+ static const char *modeDescr[] = {
+   "line",
+@@ -2276,6 +8662,7 @@
+   "explain",
+   "ascii",
+   "prettyprint",
++  "eqp"
+ };
+ 
+ /*
+@@ -2292,11 +8679,6 @@
+ #define SEP_Record    "\x1E"
+ 
+ /*
+-** Number of elements in an array
+-*/
+-#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
+-
+-/*
+ ** A callback for the sqlite3_log() interface.
+ */
+ static void shellLog(void *pArg, int iErrCode, const char *zMsg){
+@@ -2307,6 +8689,181 @@
+ }
+ 
+ /*
++** SQL function:  shell_putsnl(X)
++**
++** Write the text X to the screen (or whatever output is being directed)
++** adding a newline at the end, and then return X.
++*/
++static void shellPutsFunc(
++  sqlite3_context *pCtx,
++  int nVal,
++  sqlite3_value **apVal
++){
++  ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
++  (void)nVal;
++  utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
++  sqlite3_result_value(pCtx, apVal[0]);
++}
++
++/*
++** SQL function:   edit(VALUE)
++**                 edit(VALUE,EDITOR)
++**
++** These steps:
++**
++**     (1) Write VALUE into a temporary file.
++**     (2) Run program EDITOR on that temporary file.
++**     (3) Read the temporary file back and return its content as the result.
++**     (4) Delete the temporary file
++**
++** If the EDITOR argument is omitted, use the value in the VISUAL
++** environment variable.  If still there is no EDITOR, through an error.
++**
++** Also throw an error if the EDITOR program returns a non-zero exit code.
++*/
++#ifndef SQLITE_NOHAVE_SYSTEM
++static void editFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  const char *zEditor;
++  char *zTempFile = 0;
++  sqlite3 *db;
++  char *zCmd = 0;
++  int bBin;
++  int rc;
++  int hasCRNL = 0;
++  FILE *f = 0;
++  sqlite3_int64 sz;
++  sqlite3_int64 x;
++  unsigned char *p = 0;
++
++  if( argc==2 ){
++    zEditor = (const char*)sqlite3_value_text(argv[1]);
++  }else{
++    zEditor = getenv("VISUAL");
++  }
++  if( zEditor==0 ){
++    sqlite3_result_error(context, "no editor for edit()", -1);
++    return;
++  }
++  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
++    sqlite3_result_error(context, "NULL input to edit()", -1);
++    return;
++  }
++  db = sqlite3_context_db_handle(context);
++  zTempFile = 0;
++  sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
++  if( zTempFile==0 ){
++    sqlite3_uint64 r = 0;
++    sqlite3_randomness(sizeof(r), &r);
++    zTempFile = sqlite3_mprintf("temp%llx", r);
++    if( zTempFile==0 ){
++      sqlite3_result_error_nomem(context);
++      return;
++    }
++  }
++  bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
++  /* When writing the file to be edited, do \n to \r\n conversions on systems
++  ** that want \r\n line endings */
++  f = fopen(zTempFile, bBin ? "wb" : "w");
++  if( f==0 ){
++    sqlite3_result_error(context, "edit() cannot open temp file", -1);
++    goto edit_func_end;
++  }
++  sz = sqlite3_value_bytes(argv[0]);
++  if( bBin ){
++    x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
++  }else{
++    const char *z = (const char*)sqlite3_value_text(argv[0]);
++    /* Remember whether or not the value originally contained \r\n */
++    if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
++    x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
++  }
++  fclose(f);
++  f = 0;
++  if( x!=sz ){
++    sqlite3_result_error(context, "edit() could not write the whole file", -1);
++    goto edit_func_end;
++  }
++  zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
++  if( zCmd==0 ){
++    sqlite3_result_error_nomem(context);
++    goto edit_func_end;
++  }
++  rc = system(zCmd);
++  sqlite3_free(zCmd);
++  if( rc ){
++    sqlite3_result_error(context, "EDITOR returned non-zero", -1);
++    goto edit_func_end;
++  }
++  f = fopen(zTempFile, "rb");
++  if( f==0 ){
++    sqlite3_result_error(context,
++      "edit() cannot reopen temp file after edit", -1);
++    goto edit_func_end;
++  }
++  fseek(f, 0, SEEK_END);
++  sz = ftell(f);
++  rewind(f);
++  p = sqlite3_malloc64( sz+(bBin==0) );
++  if( p==0 ){
++    sqlite3_result_error_nomem(context);
++    goto edit_func_end;
++  }
++  x = fread(p, 1, sz, f);
++  fclose(f);
++  f = 0;
++  if( x!=sz ){
++    sqlite3_result_error(context, "could not read back the whole file", -1);
++    goto edit_func_end;
++  }
++  if( bBin ){
++    sqlite3_result_blob64(context, p, sz, sqlite3_free);
++  }else{
++    sqlite3_int64 i, j;
++    if( hasCRNL ){
++      /* If the original contains \r\n then do no conversions back to \n */
++      j = sz;
++    }else{
++      /* If the file did not originally contain \r\n then convert any new
++      ** \r\n back into \n */
++      for(i=j=0; i<sz; i++){
++        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
++        p[j++] = p[i];
++      }
++      sz = j;
++      p[sz] = 0;
++    } 
++    sqlite3_result_text64(context, (const char*)p, sz,
++                          sqlite3_free, SQLITE_UTF8);
++  }
++  p = 0;
++
++edit_func_end:
++  if( f ) fclose(f);
++  unlink(zTempFile);
++  sqlite3_free(zTempFile);
++  sqlite3_free(p);
++}
++#endif /* SQLITE_NOHAVE_SYSTEM */
++
++/*
++** Save or restore the current output mode
++*/
++static void outputModePush(ShellState *p){
++  p->modePrior = p->mode;
++  memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
++  memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
++}
++static void outputModePop(ShellState *p){
++  p->mode = p->modePrior;
++  memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
++  memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
++}
++
++/*
+ ** Output the given string as a hex-encoded blob (eg. X'1234' )
+ */
+ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
+@@ -2551,12 +9108,9 @@
+       }
+     }
+     if( i==0 ){
+-      putc('"', out);
+-      for(i=0; z[i]; i++){
+-        if( z[i]=='"' ) putc('"', out);
+-        putc(z[i], out);
+-      }
+-      putc('"', out);
++      char *zQuoted = sqlite3_mprintf("\"%w\"", z);
++      utf8_printf(out, "%s", zQuoted);
++      sqlite3_free(zQuoted);
+     }else{
+       utf8_printf(out, "%s", z);
+     }
+@@ -2566,7 +9120,6 @@
+   }
+ }
+ 
+-#ifdef SIGINT
+ /*
+ ** This routine runs when the user presses Ctrl-C
+ */
+@@ -2576,6 +9129,20 @@
+   if( seenInterrupt>2 ) exit(1);
+   if( globalDb ) sqlite3_interrupt(globalDb);
+ }
++
++#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
++/*
++** This routine runs for console events (e.g. Ctrl-C) on Win32
++*/
++static BOOL WINAPI ConsoleCtrlHandler(
++  DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
++){
++  if( dwCtrlType==CTRL_C_EVENT ){
++    interrupt_handler(0);
++    return TRUE;
++  }
++  return FALSE;
++}
+ #endif
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+@@ -2646,6 +9213,108 @@
+ }
+ 
+ /*
++** Return true if string z[] has nothing but whitespace and comments to the
++** end of the first line.
++*/
++static int wsToEol(const char *z){
++  int i;
++  for(i=0; z[i]; i++){
++    if( z[i]=='\n' ) return 1;
++    if( IsSpace(z[i]) ) continue;
++    if( z[i]=='-' && z[i+1]=='-' ) return 1;
++    return 0;
++  }
++  return 1;
++}
++
++/*
++** Add a new entry to the EXPLAIN QUERY PLAN data
++*/
++static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
++  EQPGraphRow *pNew;
++  int nText = strlen30(zText);
++  if( p->autoEQPtest ){
++    utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
++  }
++  pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
++  if( pNew==0 ) shell_out_of_memory();
++  pNew->iEqpId = iEqpId;
++  pNew->iParentId = p2;
++  memcpy(pNew->zText, zText, nText+1);
++  pNew->pNext = 0;
++  if( p->sGraph.pLast ){
++    p->sGraph.pLast->pNext = pNew;
++  }else{
++    p->sGraph.pRow = pNew;
++  }
++  p->sGraph.pLast = pNew;
++}
++
++/*
++** Free and reset the EXPLAIN QUERY PLAN data that has been collected
++** in p->sGraph.
++*/
++static void eqp_reset(ShellState *p){
++  EQPGraphRow *pRow, *pNext;
++  for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
++    pNext = pRow->pNext;
++    sqlite3_free(pRow);
++  }
++  memset(&p->sGraph, 0, sizeof(p->sGraph));
++}
++
++/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
++** pOld, or return the first such line if pOld is NULL
++*/
++static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
++  EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
++  while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
++  return pRow;
++}
++
++/* Render a single level of the graph that has iEqpId as its parent.  Called
++** recursively to render sublevels.
++*/
++static void eqp_render_level(ShellState *p, int iEqpId){
++  EQPGraphRow *pRow, *pNext;
++  int n = strlen30(p->sGraph.zPrefix);
++  char *z;
++  for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
++    pNext = eqp_next_row(p, iEqpId, pRow);
++    z = pRow->zText;
++    utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
++    if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
++      memcpy(&p->sGraph.zPrefix[n], pNext ? "|  " : "   ", 4);
++      eqp_render_level(p, pRow->iEqpId);
++      p->sGraph.zPrefix[n] = 0;
++    }
++  }
++}
++
++/*
++** Display and reset the EXPLAIN QUERY PLAN data
++*/
++static void eqp_render(ShellState *p){
++  EQPGraphRow *pRow = p->sGraph.pRow;
++  if( pRow ){
++    if( pRow->zText[0]=='-' ){
++      if( pRow->pNext==0 ){
++        eqp_reset(p);
++        return;
++      }
++      utf8_printf(p->out, "%s\n", pRow->zText+3);
++      p->sGraph.pRow = pRow->pNext;
++      sqlite3_free(pRow);
++    }else{
++      utf8_printf(p->out, "QUERY PLAN\n");
++    }
++    p->sGraph.zPrefix[0] = 0;
++    eqp_render_level(p, 0);
++    eqp_reset(p);
++  }
++}
++
++/*
+ ** This is the callback routine that the shell
+ ** invokes for each row of a query result.
+ */
+@@ -2659,6 +9328,7 @@
+   int i;
+   ShellState *p = (ShellState*)pArg;
+ 
++  if( azArg==0 ) return 0;
+   switch( p->cMode ){
+     case MODE_Line: {
+       int w = 5;
+@@ -2773,6 +9443,7 @@
+       for(i=0; IsSpace(z[i]); i++){}
+       for(; (c = z[i])!=0; i++){
+         if( IsSpace(c) ){
++          if( z[j-1]=='\r' ) z[j-1] = '\n';
+           if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
+         }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
+           j--;
+@@ -2782,7 +9453,7 @@
+       while( j>0 && IsSpace(z[j-1]) ){ j--; }
+       z[j] = 0;
+       if( strlen30(z)>=79 ){
+-        for(i=j=0; (c = z[i])!=0; i++){
++        for(i=j=0; (c = z[i])!=0; i++){  /* Copy changes from z[i] back to z[j] */
+           if( c==cEnd ){
+             cEnd = 0;
+           }else if( c=='"' || c=='\'' || c=='`' ){
+@@ -2789,6 +9460,8 @@
+             cEnd = c;
+           }else if( c=='[' ){
+             cEnd = ']';
++          }else if( c=='-' && z[i+1]=='-' ){
++            cEnd = '\n';
+           }else if( c=='(' ){
+             nParen++;
+           }else if( c==')' ){
+@@ -2799,7 +9472,9 @@
+             }
+           }
+           z[j++] = c;
+-          if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
++          if( nParen==1 && cEnd==0
++           && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
++          ){
+             if( c=='\n' ) j--;
+             printSchemaLineN(p->out, z, j, "\n  ");
+             j = 0;
+@@ -2919,8 +9594,16 @@
+         }else if( aiType && aiType[i]==SQLITE_FLOAT ){
+           char z[50];
+           double r = sqlite3_column_double(p->pStmt, i);
+-          sqlite3_snprintf(50,z,"%!.20g", r);
+-          raw_printf(p->out, "%s", z);
++          sqlite3_uint64 ur;
++          memcpy(&ur,&r,sizeof(r));
++          if( ur==0x7ff0000000000000LL ){
++            raw_printf(p->out, "1e999");
++          }else if( ur==0xfff0000000000000LL ){
++            raw_printf(p->out, "-1e999");
++          }else{
++            sqlite3_snprintf(50,z,"%!.20g", r);
++            raw_printf(p->out, "%s", z);
++          }
+         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
+           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
+           int nBlob = sqlite3_column_bytes(p->pStmt, i);
+@@ -2988,6 +9671,10 @@
+       utf8_printf(p->out, "%s", p->rowSeparator);
+       break;
+     }
++    case MODE_EQP: {
++      eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
++      break;
++    }
+   }
+   return 0;
+ }
+@@ -3009,6 +9696,7 @@
+   ShellText *p = (ShellText*)pArg;
+   int i;
+   UNUSED_PARAMETER(az);
++  if( azArg==0 ) return 0;
+   if( p->n ) appendText(p, "|", 0);
+   for(i=0; i<nArg; i++){
+     if( i ) appendText(p, ",", 0);
+@@ -3073,7 +9761,7 @@
+ */
+ static void set_table_name(ShellState *p, const char *zName){
+   int i, n;
+-  int cQuote;
++  char cQuote;
+   char *z;
+ 
+   if( p->zDestTable ){
+@@ -3085,10 +9773,7 @@
+   n = strlen30(zName);
+   if( cQuote ) n += n+2;
+   z = p->zDestTable = malloc( n+1 );
+-  if( z==0 ){
+-    raw_printf(stderr,"Error: out of memory\n");
+-    exit(1);
+-  }
++  if( z==0 ) shell_out_of_memory();
+   n = 0;
+   if( cQuote ) z[n++] = cQuote;
+   for(i=0; zName[i]; i++){
+@@ -3196,7 +9881,7 @@
+     };
+     int i;
+     for(i=0; i<ArraySize(aTrans); i++){
+-      int n = (int)strlen(aTrans[i].zPattern);
++      int n = strlen30(aTrans[i].zPattern);
+       if( strncmp(aTrans[i].zPattern, z, n)==0 ){
+         utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
+         break;
+@@ -3243,37 +9928,54 @@
+ ){
+   int iCur;
+   int iHiwtr;
++  FILE *out;
++  if( pArg==0 || pArg->out==0 ) return 0;
++  out = pArg->out;
+ 
+-  if( pArg && pArg->out ){
+-    displayStatLine(pArg, "Memory Used:",
+-       "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
+-    displayStatLine(pArg, "Number of Outstanding Allocations:",
+-       "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
+-    if( pArg->shellFlgs & SHFLG_Pagecache ){
+-      displayStatLine(pArg, "Number of Pcache Pages Used:",
+-         "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
++  if( pArg->pStmt && (pArg->statsOn & 2) ){
++    int nCol, i, x;
++    sqlite3_stmt *pStmt = pArg->pStmt;
++    char z[100];
++    nCol = sqlite3_column_count(pStmt);
++    raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
++    for(i=0; i<nCol; i++){
++      sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
++      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
++#ifndef SQLITE_OMIT_DECLTYPE
++      sqlite3_snprintf(30, z+x, "declared type:");
++      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
++#endif
++#ifdef SQLITE_ENABLE_COLUMN_METADATA
++      sqlite3_snprintf(30, z+x, "database name:");
++      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
++      sqlite3_snprintf(30, z+x, "table name:");
++      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
++      sqlite3_snprintf(30, z+x, "origin name:");
++      utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
++#endif
+     }
+-    displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
+-       "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
+-    if( pArg->shellFlgs & SHFLG_Scratch ){
+-      displayStatLine(pArg, "Number of Scratch Allocations Used:",
+-         "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset);
+-    }
+-    displayStatLine(pArg, "Number of Scratch Overflow Bytes:",
+-       "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset);
+-    displayStatLine(pArg, "Largest Allocation:",
+-       "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
+-    displayStatLine(pArg, "Largest Pcache Allocation:",
+-       "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
+-    displayStatLine(pArg, "Largest Scratch Allocation:",
+-       "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset);
++  }
++
++  displayStatLine(pArg, "Memory Used:",
++     "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
++  displayStatLine(pArg, "Number of Outstanding Allocations:",
++     "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
++  if( pArg->shellFlgs & SHFLG_Pagecache ){
++    displayStatLine(pArg, "Number of Pcache Pages Used:",
++       "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
++  }
++  displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
++     "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
++  displayStatLine(pArg, "Largest Allocation:",
++     "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
++  displayStatLine(pArg, "Largest Pcache Allocation:",
++     "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
+ #ifdef YYTRACKMAXSTACKDEPTH
+-    displayStatLine(pArg, "Deepest Parser Stack:",
+-       "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
++  displayStatLine(pArg, "Deepest Parser Stack:",
++     "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
+ #endif
+-  }
+ 
+-  if( pArg && pArg->out && db ){
++  if( db ){
+     if( pArg->shellFlgs & SHFLG_Lookaside ){
+       iHiwtr = iCur = -1;
+       sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
+@@ -3308,6 +10010,9 @@
+     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
+     raw_printf(pArg->out, "Page cache writes:                   %d\n", iCur);
+     iHiwtr = iCur = -1;
++    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
++    raw_printf(pArg->out, "Page cache spills:                   %d\n", iCur);
++    iHiwtr = iCur = -1;
+     sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
+     raw_printf(pArg->out, "Schema Heap Usage:                   %d bytes\n",
+             iCur);
+@@ -3317,7 +10022,7 @@
+             iCur);
+   }
+ 
+-  if( pArg && pArg->out && db && pArg->pStmt ){
++  if( pArg->pStmt ){
+     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
+                                bReset);
+     raw_printf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
+@@ -3327,6 +10032,12 @@
+     raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
+     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+     raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
++    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset);
++    raw_printf(pArg->out, "Reprepare operations:                %d\n", iCur);
++    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
++    raw_printf(pArg->out, "Number of times run:                 %d\n", iCur);
++    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
++    raw_printf(pArg->out, "Memory used by prepared stmt:        %d\n", iCur);
+   }
+ 
+ #ifdef __linux__
+@@ -3425,8 +10136,7 @@
+   int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
+   int iOp;                        /* Index of operation in p->aiIndent[] */
+ 
+-  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
+-                           "NextIfOpen", "PrevIfOpen", 0 };
++  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
+   const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
+                             "Rewind", 0 };
+   const char *azGoto[] = { "Goto", 0 };
+@@ -3476,7 +10186,9 @@
+       }
+       nAlloc += 100;
+       p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
++      if( p->aiIndent==0 ) shell_out_of_memory();
+       abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
++      if( abYield==0 ) shell_out_of_memory();
+     }
+     abYield[iOp] = str_in_array(zOp, azYield);
+     p->aiIndent[iOp] = 0;
+@@ -3542,8 +10254,7 @@
+ */
+ static void exec_prepared_stmt(
+   ShellState *pArg,                                /* Pointer to ShellState */
+-  sqlite3_stmt *pStmt,                             /* Statment to run */
+-  int (*xCallback)(void*,int,char**,char**,int*)   /* Callback function */
++  sqlite3_stmt *pStmt                              /* Statment to run */
+ ){
+   int rc;
+ 
+@@ -3553,57 +10264,181 @@
+   rc = sqlite3_step(pStmt);
+   /* if we have a result set... */
+   if( SQLITE_ROW == rc ){
+-    /* if we have a callback... */
+-    if( xCallback ){
+-      /* allocate space for col name ptr, value ptr, and type */
+-      int nCol = sqlite3_column_count(pStmt);
+-      void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
+-      if( !pData ){
+-        rc = SQLITE_NOMEM;
+-      }else{
+-        char **azCols = (char **)pData;      /* Names of result columns */
+-        char **azVals = &azCols[nCol];       /* Results */
+-        int *aiTypes = (int *)&azVals[nCol]; /* Result types */
+-        int i, x;
+-        assert(sizeof(int) <= sizeof(char *));
+-        /* save off ptrs to column names */
++    /* allocate space for col name ptr, value ptr, and type */
++    int nCol = sqlite3_column_count(pStmt);
++    void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
++    if( !pData ){
++      rc = SQLITE_NOMEM;
++    }else{
++      char **azCols = (char **)pData;      /* Names of result columns */
++      char **azVals = &azCols[nCol];       /* Results */
++      int *aiTypes = (int *)&azVals[nCol]; /* Result types */
++      int i, x;
++      assert(sizeof(int) <= sizeof(char *));
++      /* save off ptrs to column names */
++      for(i=0; i<nCol; i++){
++        azCols[i] = (char *)sqlite3_column_name(pStmt, i);
++      }
++      do{
++        /* extract the data and data types */
+         for(i=0; i<nCol; i++){
+-          azCols[i] = (char *)sqlite3_column_name(pStmt, i);
++          aiTypes[i] = x = sqlite3_column_type(pStmt, i);
++          if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
++            azVals[i] = "";
++          }else{
++            azVals[i] = (char*)sqlite3_column_text(pStmt, i);
++          }
++          if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
++            rc = SQLITE_NOMEM;
++            break; /* from for */
++          }
++        } /* end for */
++
++        /* if data and types extracted successfully... */
++        if( SQLITE_ROW == rc ){
++          /* call the supplied callback with the result row data */
++          if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
++            rc = SQLITE_ABORT;
++          }else{
++            rc = sqlite3_step(pStmt);
++          }
+         }
+-        do{
+-          /* extract the data and data types */
+-          for(i=0; i<nCol; i++){
+-            aiTypes[i] = x = sqlite3_column_type(pStmt, i);
+-            if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
+-              azVals[i] = "";
+-            }else{
+-              azVals[i] = (char*)sqlite3_column_text(pStmt, i);
+-            }
+-            if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
+-              rc = SQLITE_NOMEM;
+-              break; /* from for */
+-            }
+-          } /* end for */
++      } while( SQLITE_ROW == rc );
++      sqlite3_free(pData);
++    }
++  }
++}
+ 
+-          /* if data and types extracted successfully... */
+-          if( SQLITE_ROW == rc ){
+-            /* call the supplied callback with the result row data */
+-            if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
+-              rc = SQLITE_ABORT;
+-            }else{
+-              rc = sqlite3_step(pStmt);
+-            }
+-          }
+-        } while( SQLITE_ROW == rc );
+-        sqlite3_free(pData);
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++/*
++** This function is called to process SQL if the previous shell command
++** was ".expert". It passes the SQL in the second argument directly to
++** the sqlite3expert object.
++**
++** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
++** code. In this case, (*pzErr) may be set to point to a buffer containing
++** an English language error message. It is the responsibility of the
++** caller to eventually free this buffer using sqlite3_free().
++*/
++static int expertHandleSQL(
++  ShellState *pState, 
++  const char *zSql, 
++  char **pzErr
++){
++  assert( pState->expert.pExpert );
++  assert( pzErr==0 || *pzErr==0 );
++  return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr);
++}
++
++/*
++** This function is called either to silently clean up the object
++** created by the ".expert" command (if bCancel==1), or to generate a 
++** report from it and then clean it up (if bCancel==0).
++**
++** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
++** code. In this case, (*pzErr) may be set to point to a buffer containing
++** an English language error message. It is the responsibility of the
++** caller to eventually free this buffer using sqlite3_free().
++*/
++static int expertFinish(
++  ShellState *pState,
++  int bCancel,
++  char **pzErr
++){
++  int rc = SQLITE_OK;
++  sqlite3expert *p = pState->expert.pExpert;
++  assert( p );
++  assert( bCancel || pzErr==0 || *pzErr==0 );
++  if( bCancel==0 ){
++    FILE *out = pState->out;
++    int bVerbose = pState->expert.bVerbose;
++
++    rc = sqlite3_expert_analyze(p, pzErr);
++    if( rc==SQLITE_OK ){
++      int nQuery = sqlite3_expert_count(p);
++      int i;
++
++      if( bVerbose ){
++        const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
++        raw_printf(out, "-- Candidates -----------------------------\n");
++        raw_printf(out, "%s\n", zCand);
+       }
++      for(i=0; i<nQuery; i++){
++        const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
++        const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
++        const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
++        if( zIdx==0 ) zIdx = "(no new indexes)\n";
++        if( bVerbose ){
++          raw_printf(out, "-- Query %d --------------------------------\n",i+1);
++          raw_printf(out, "%s\n\n", zSql);
++        }
++        raw_printf(out, "%s\n", zIdx);
++        raw_printf(out, "%s\n", zEQP);
++      }
++    }
++  }
++  sqlite3_expert_destroy(p);
++  pState->expert.pExpert = 0;
++  return rc;
++}
++
++/*
++** Implementation of ".expert" dot command.
++*/
++static int expertDotCommand(
++  ShellState *pState,             /* Current shell tool state */
++  char **azArg,                   /* Array of arguments passed to dot command */
++  int nArg                        /* Number of entries in azArg[] */
++){
++  int rc = SQLITE_OK;
++  char *zErr = 0;
++  int i;
++  int iSample = 0;
++
++  assert( pState->expert.pExpert==0 );
++  memset(&pState->expert, 0, sizeof(ExpertInfo));
++
++  for(i=1; rc==SQLITE_OK && i<nArg; i++){
++    char *z = azArg[i];
++    int n;
++    if( z[0]=='-' && z[1]=='-' ) z++;
++    n = strlen30(z);
++    if( n>=2 && 0==strncmp(z, "-verbose", n) ){
++      pState->expert.bVerbose = 1;
++    }
++    else if( n>=2 && 0==strncmp(z, "-sample", n) ){
++      if( i==(nArg-1) ){
++        raw_printf(stderr, "option requires an argument: %s\n", z);
++        rc = SQLITE_ERROR;
++      }else{
++        iSample = (int)integerValue(azArg[++i]);
++        if( iSample<0 || iSample>100 ){
++          raw_printf(stderr, "value out of range: %s\n", azArg[i]);
++          rc = SQLITE_ERROR;
++        }
++      }
++    }
++    else{
++      raw_printf(stderr, "unknown option: %s\n", z);
++      rc = SQLITE_ERROR;
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
++    if( pState->expert.pExpert==0 ){
++      raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
++      rc = SQLITE_ERROR;
+     }else{
+-      do{
+-        rc = sqlite3_step(pStmt);
+-      } while( rc == SQLITE_ROW );
++      sqlite3_expert_config(
++          pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
++      );
+     }
+   }
++
++  return rc;
+ }
++#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+ 
+ /*
+ ** Execute a statement or set of statements.  Print
+@@ -3615,11 +10450,8 @@
+ ** and callback data argument.
+ */
+ static int shell_exec(
+-  sqlite3 *db,                              /* An open database */
++  ShellState *pArg,                         /* Pointer to ShellState */
+   const char *zSql,                         /* SQL to be evaluated */
+-  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
+-                                            /* (not the same as sqlite3_exec) */
+-  ShellState *pArg,                         /* Pointer to ShellState */
+   char **pzErrMsg                           /* Error msg written here */
+ ){
+   sqlite3_stmt *pStmt = NULL;     /* Statement to execute. */
+@@ -3626,11 +10458,19 @@
+   int rc = SQLITE_OK;             /* Return Code */
+   int rc2;
+   const char *zLeftover;          /* Tail of unprocessed SQL */
++  sqlite3 *db = pArg->db;
+ 
+   if( pzErrMsg ){
+     *pzErrMsg = NULL;
+   }
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( pArg->expert.pExpert ){
++    rc = expertHandleSQL(pArg, zSql, pzErrMsg);
++    return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
++  }
++#endif
++
+   while( zSql[0] && (SQLITE_OK == rc) ){
+     static const char *zStmtSql;
+     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
+@@ -3664,20 +10504,27 @@
+       if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
+         sqlite3_stmt *pExplain;
+         char *zEQP;
++        int triggerEQP = 0;
+         disable_debug_trace_modes();
++        sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
++        if( pArg->autoEQP>=AUTOEQP_trigger ){
++          sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
++        }
+         zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
+         rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+         if( rc==SQLITE_OK ){
+           while( sqlite3_step(pExplain)==SQLITE_ROW ){
+-            raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
+-            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
+-            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
+-            utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
++            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
++            int iEqpId = sqlite3_column_int(pExplain, 0);
++            int iParentId = sqlite3_column_int(pExplain, 1);
++            if( zEQPLine[0]=='-' ) eqp_render(pArg);
++            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
+           }
++          eqp_render(pArg);
+         }
+         sqlite3_finalize(pExplain);
+         sqlite3_free(zEQP);
+-        if( pArg->autoEQP>=2 ){
++        if( pArg->autoEQP>=AUTOEQP_full ){
+           /* Also do an EXPLAIN for ".eqp full" mode */
+           zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
+           rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+@@ -3684,22 +10531,34 @@
+           if( rc==SQLITE_OK ){
+             pArg->cMode = MODE_Explain;
+             explain_data_prepare(pArg, pExplain);
+-            exec_prepared_stmt(pArg, pExplain, xCallback);
++            exec_prepared_stmt(pArg, pExplain);
+             explain_data_delete(pArg);
+           }
+           sqlite3_finalize(pExplain);
+           sqlite3_free(zEQP);
+         }
++        if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
++          sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
++          /* Reprepare pStmt before reactiving trace modes */
++          sqlite3_finalize(pStmt);
++          sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
++          if( pArg ) pArg->pStmt = pStmt;
++        }
+         restore_debug_trace_modes();
+       }
+ 
+       if( pArg ){
+         pArg->cMode = pArg->mode;
+-        if( pArg->autoExplain
+-         && sqlite3_column_count(pStmt)==8
+-         && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
+-        ){
+-          pArg->cMode = MODE_Explain;
++        if( pArg->autoExplain ){
++          if( sqlite3_column_count(pStmt)==8
++           && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
++          ){
++            pArg->cMode = MODE_Explain;
++          }
++          if( sqlite3_column_count(pStmt)==4
++           && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){
++            pArg->cMode = MODE_EQP;
++          }
+         }
+ 
+         /* If the shell is currently in ".explain" mode, gather the extra
+@@ -3709,8 +10568,9 @@
+         }
+       }
+ 
+-      exec_prepared_stmt(pArg, pStmt, xCallback);
++      exec_prepared_stmt(pArg, pStmt);
+       explain_data_delete(pArg);
++      eqp_render(pArg);
+ 
+       /* print usage stats if stats on */
+       if( pArg && pArg->statsOn ){
+@@ -3788,10 +10648,7 @@
+     if( nCol>=nAlloc-2 ){
+       nAlloc = nAlloc*2 + nCol + 10;
+       azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
+-      if( azCol==0 ){
+-        raw_printf(stderr, "Error: out of memory\n");
+-        exit(1);
+-      }
++      if( azCol==0 ) shell_out_of_memory();
+     }
+     azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
+     if( sqlite3_column_int(pStmt, 5) ){
+@@ -3807,6 +10664,7 @@
+     }
+   }
+   sqlite3_finalize(pStmt);
++  if( azCol==0 ) return 0;
+   azCol[0] = 0;
+   azCol[nCol+1] = 0;
+ 
+@@ -3890,7 +10748,7 @@
+   ShellState *p = (ShellState *)pArg;
+ 
+   UNUSED_PARAMETER(azNotUsed);
+-  if( nArg!=3 ) return 1;
++  if( nArg!=3 || azArg==0 ) return 0;
+   zTable = azArg[0];
+   zType = azArg[1];
+   zSql = azArg[2];
+@@ -3971,11 +10829,11 @@
+     savedMode = p->mode;
+     p->zDestTable = sTable.z;
+     p->mode = p->cMode = MODE_Insert;
+-    rc = shell_exec(p->db, sSelect.z, shell_callback, p, 0);
++    rc = shell_exec(p, sSelect.z, 0);
+     if( (rc&0xff)==SQLITE_CORRUPT ){
+       raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
+       toggleSelectOrder(p->db);
+-      shell_exec(p->db, sSelect.z, shell_callback, p, 0);
++      shell_exec(p, sSelect.z, 0);
+       toggleSelectOrder(p->db);
+     }
+     p->zDestTable = savedDestTable;
+@@ -4026,124 +10884,239 @@
+ }
+ 
+ /*
+-** Text of a help message
++** Text of help messages.
++**
++** The help text for each individual command begins with a line that starts
++** with ".".  Subsequent lines are supplimental information.
++**
++** There must be two or more spaces between the end of the command and the
++** start of the description of what that command does.
+ */
+-static char zHelp[] =
++static const char *(azHelp[]) = {
++#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
++  ".archive ...             Manage SQL archives",
++  "   Each command must have exactly one of the following options:",
++  "     -c, --create               Create a new archive",
++  "     -u, --update               Update or add files to an existing archive",
++  "     -t, --list                 List contents of archive",
++  "     -x, --extract              Extract files from archive",
++  "   Optional arguments:",
++  "     -v, --verbose              Print each filename as it is processed",
++  "     -f FILE, --file FILE       Operate on archive FILE (default is current db)",
++  "     -a FILE, --append FILE     Operate on FILE opened using the apndvfs VFS",
++  "     -C DIR, --directory DIR    Change to directory DIR to read/extract files",
++  "     -n, --dryrun               Show the SQL that would have occurred",
++  "   Examples:",
++  "     .ar -cf archive.sar foo bar  # Create archive.sar from files foo and bar",
++  "     .ar -tf archive.sar          # List members of archive.sar",
++  "     .ar -xvf archive.sar         # Verbosely extract files from archive.sar",
++  "   See also:",
++  "      http://sqlite.org/cli.html#sqlar_archive_support",
++#endif
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  ".auth ON|OFF           Show authorizer callbacks\n"
++  ".auth ON|OFF             Show authorizer callbacks",
+ #endif
+-  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
+-  ".bail on|off           Stop after hitting an error.  Default OFF\n"
+-  ".binary on|off         Turn binary output on or off.  Default OFF\n"
+-  ".cd DIRECTORY          Change the working directory to DIRECTORY\n"
+-  ".changes on|off        Show number of rows changed by SQL\n"
+-  ".check GLOB            Fail if output since .testcase does not match\n"
+-  ".clone NEWDB           Clone data into NEWDB from the existing database\n"
+-  ".databases             List names and files of attached databases\n"
+-  ".dbinfo ?DB?           Show status information about the database\n"
+-  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
+-  "                         If TABLE specified, only dump tables matching\n"
+-  "                         LIKE pattern TABLE.\n"
+-  ".echo on|off           Turn command echo on or off\n"
+-  ".eqp on|off|full       Enable or disable automatic EXPLAIN QUERY PLAN\n"
+-  ".exit                  Exit this program\n"
++  ".backup ?DB? FILE        Backup DB (default \"main\") to FILE",
++  "       --append            Use the appendvfs",
++  ".bail on|off             Stop after hitting an error.  Default OFF",
++  ".binary on|off           Turn binary output on or off.  Default OFF",
++  ".cd DIRECTORY            Change the working directory to DIRECTORY",
++  ".changes on|off          Show number of rows changed by SQL",
++  ".check GLOB              Fail if output since .testcase does not match",
++  ".clone NEWDB             Clone data into NEWDB from the existing database",
++  ".databases               List names and files of attached databases",
++  ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
++  ".dbinfo ?DB?             Show status information about the database",
++  ".dump ?TABLE? ...        Render all database content as SQL",
++  "   Options:",
++  "     --preserve-rowids      Include ROWID values in the output",
++  "     --newlines             Allow unescaped newline characters in output",
++  "   TABLE is LIKE pattern for the tables to dump",
++  ".echo on|off             Turn command echo on or off",
++  ".eqp on|off|full         Enable or disable automatic EXPLAIN QUERY PLAN",
++  ".excel                   Display the output of next command in a spreadsheet",
++  ".exit ?CODE?             Exit this program with return-code CODE",
++  ".expert                  EXPERIMENTAL. Suggest indexes for specified queries",
+ /* Because explain mode comes on automatically now, the ".explain" mode
+ ** is removed from the help screen.  It is still supported for legacy, however */
+-/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
+-  ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
+-  ".headers on|off        Turn display of headers on or off\n"
+-  ".help                  Show this message\n"
+-  ".import FILE TABLE     Import data from FILE into TABLE\n"
++/*".explain ?on|off|auto?   Turn EXPLAIN output mode on or off or to automatic",*/
++  ".fullschema ?--indent?   Show schema and the content of sqlite_stat tables",
++  ".headers on|off          Turn display of headers on or off",
++  ".help ?-all? ?PATTERN?   Show help text for PATTERN",
++  ".import FILE TABLE       Import data from FILE into TABLE",
+ #ifndef SQLITE_OMIT_TEST_CONTROL
+-  ".imposter INDEX TABLE  Create imposter table TABLE on index INDEX\n"
++  ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
+ #endif
+-  ".indexes ?TABLE?       Show names of all indexes\n"
+-  "                         If TABLE specified, only show indexes for tables\n"
+-  "                         matching LIKE pattern TABLE.\n"
++  ".indexes ?TABLE?         Show names of indexes",
++  "                           If TABLE is specified, only show indexes for",
++  "                           tables matching TABLE using the LIKE operator.",
+ #ifdef SQLITE_ENABLE_IOTRACE
+-  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
++  ".iotrace FILE            Enable I/O diagnostic logging to FILE",
+ #endif
+-  ".limit ?LIMIT? ?VAL?   Display or change the value of an SQLITE_LIMIT\n"
+-  ".lint OPTIONS          Report potential schema issues. Options:\n"
+-  "                         fkey-indexes     Find missing foreign key indexes\n"
++  ".limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT",
++  ".lint OPTIONS            Report potential schema issues.",
++  "     Options:",
++  "        fkey-indexes     Find missing foreign key indexes",
+ #ifndef SQLITE_OMIT_LOAD_EXTENSION
+-  ".load FILE ?ENTRY?     Load an extension library\n"
++  ".load FILE ?ENTRY?       Load an extension library",
+ #endif
+-  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
+-  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
+-  "                         ascii    Columns/rows delimited by 0x1F and 0x1E\n"
+-  "                         csv      Comma-separated values\n"
+-  "                         column   Left-aligned columns.  (See .width)\n"
+-  "                         html     HTML <table> code\n"
+-  "                         insert   SQL insert statements for TABLE\n"
+-  "                         line     One value per line\n"
+-  "                         list     Values delimited by \"|\"\n"
+-  "                         quote    Escape answers as for SQL\n"
+-  "                         tabs     Tab-separated values\n"
+-  "                         tcl      TCL list elements\n"
+-  ".nullvalue STRING      Use STRING in place of NULL values\n"
+-  ".once FILENAME         Output for the next SQL command only to FILENAME\n"
+-  ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
+-  "                         The --new option starts with an empty file\n"
+-  ".output ?FILENAME?     Send output to FILENAME or stdout\n"
+-  ".print STRING...       Print literal STRING\n"
+-  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
+-  ".quit                  Exit this program\n"
+-  ".read FILENAME         Execute SQL in FILENAME\n"
+-  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
+-  ".save FILE             Write in-memory database into FILE\n"
+-  ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
+-  ".schema ?PATTERN?      Show the CREATE statements matching PATTERN\n"
+-  "                          Add --indent for pretty-printing\n"
+-  ".selftest ?--init?     Run tests defined in the SELFTEST table\n"
+-  ".separator COL ?ROW?   Change the column separator and optionally the row\n"
+-  "                         separator for both the output mode and .import\n"
++  ".log FILE|off            Turn logging on or off.  FILE can be stderr/stdout",
++  ".mode MODE ?TABLE?       Set output mode",
++  "   MODE is one of:",
++  "     ascii    Columns/rows delimited by 0x1F and 0x1E",
++  "     csv      Comma-separated values",
++  "     column   Left-aligned columns.  (See .width)",
++  "     html     HTML <table> code",
++  "     insert   SQL insert statements for TABLE",
++  "     line     One value per line",
++  "     list     Values delimited by \"|\"",
++  "     quote    Escape answers as for SQL",
++  "     tabs     Tab-separated values",
++  "     tcl      TCL list elements",
++  ".nullvalue STRING        Use STRING in place of NULL values",
++  ".once (-e|-x|FILE)       Output for the next SQL command only to FILE",
++  "     If FILE begins with '|' then open as a pipe",
++  "     Other options:",
++  "       -e    Invoke system text editor",
++  "       -x    Open in a spreadsheet",
++  ".open ?OPTIONS? ?FILE?   Close existing database and reopen FILE",
++  "     Options:",
++  "        --append        Use appendvfs to append database to the end of FILE",
++#ifdef SQLITE_ENABLE_DESERIALIZE
++  "        --deserialize   Load into memory useing sqlite3_deserialize()",
++#endif
++  "        --new           Initialize FILE to an empty database",
++  "        --readonly      Open FILE readonly",
++  "        --zip           FILE is a ZIP archive",
++  ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
++  "     If FILE begins with '|' then open it as a pipe.",
++  ".print STRING...         Print literal STRING",
++  ".prompt MAIN CONTINUE    Replace the standard prompts",
++  ".quit                    Exit this program",
++  ".read FILE               Read input from FILE",
++  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
++  ".save FILE               Write in-memory database into FILE",
++  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
++  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
++  "     Options:",
++  "         --indent            Try to pretty-print the schema",
++  ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
++  "    Options:",
++  "       --init               Create a new SELFTEST table",
++  "       -v                   Verbose output",
++  ".separator COL ?ROW?     Change the column and row separators",
+ #if defined(SQLITE_ENABLE_SESSION)
+-  ".session CMD ...       Create or control sessions\n"
++  ".session ?NAME? CMD ...  Create or control sessions",
++  "   Subcommands:",
++  "     attach TABLE             Attach TABLE",
++  "     changeset FILE           Write a changeset into FILE",
++  "     close                    Close one session",
++  "     enable ?BOOLEAN?         Set or query the enable bit",
++  "     filter GLOB...           Reject tables matching GLOBs",
++  "     indirect ?BOOLEAN?       Mark or query the indirect status",
++  "     isempty                  Query whether the session is empty",
++  "     list                     List currently open session names",
++  "     open DB NAME             Open a new session on DB",
++  "     patchset FILE            Write a patchset into FILE",
++  "   If ?NAME? is omitted, the first defined session is used.",
+ #endif
+-  ".sha3sum ?OPTIONS...?  Compute a SHA3 hash of database content\n"
+-  ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
+-  ".show                  Show the current values for various settings\n"
+-  ".stats ?on|off?        Show stats or turn stats on or off\n"
+-  ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
+-  ".tables ?TABLE?        List names of tables\n"
+-  "                         If TABLE specified, only list tables matching\n"
+-  "                         LIKE pattern TABLE.\n"
+-  ".testcase NAME         Begin redirecting output to 'testcase-out.txt'\n"
+-  ".timeout MS            Try opening locked tables for MS milliseconds\n"
+-  ".timer on|off          Turn SQL timer on or off\n"
+-  ".trace FILE|off        Output each SQL statement as it is run\n"
+-  ".vfsinfo ?AUX?         Information about the top-level VFS\n"
+-  ".vfslist               List all available VFSes\n"
+-  ".vfsname ?AUX?         Print the name of the VFS stack\n"
+-  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
+-  "                         Negative values right-justify\n"
+-;
++  ".sha3sum ...             Compute a SHA3 hash of database content",
++  "    Options:",
++  "      --schema              Also hash the sqlite_master table",
++  "      --sha3-224            Use the sha3-224 algorithm",
++  "      --sha3-256            Use the sha3-256 algorithm.  This is the default.",
++  "      --sha3-384            Use the sha3-384 algorithm",
++  "      --sha3-512            Use the sha3-512 algorithm",
++  "    Any other argument is a LIKE pattern for tables to hash",
++#ifndef SQLITE_NOHAVE_SYSTEM
++  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
++#endif
++  ".show                    Show the current values for various settings",
++  ".stats ?on|off?          Show stats or turn stats on or off",
++#ifndef SQLITE_NOHAVE_SYSTEM
++  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
++#endif
++  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
++  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
++  ".timeout MS              Try opening locked tables for MS milliseconds",
++  ".timer on|off            Turn SQL timer on or off",
++  ".trace FILE|off          Output each SQL statement as it is run",
++  ".vfsinfo ?AUX?           Information about the top-level VFS",
++  ".vfslist                 List all available VFSes",
++  ".vfsname ?AUX?           Print the name of the VFS stack",
++  ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
++  "     Negative values right-justify",
++};
+ 
+-#if defined(SQLITE_ENABLE_SESSION)
+ /*
+-** Print help information for the ".sessions" command
++** Output help text.
++**
++** zPattern describes the set of commands for which help text is provided.
++** If zPattern is NULL, then show all commands, but only give a one-line
++** description of each.
++**
++** Return the number of matches.
+ */
+-void session_help(ShellState *p){
+-  raw_printf(p->out,
+-    ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
+-    "If ?NAME? is omitted, the first defined session is used.\n"
+-    "Subcommands:\n"
+-    "   attach TABLE             Attach TABLE\n"
+-    "   changeset FILE           Write a changeset into FILE\n"
+-    "   close                    Close one session\n"
+-    "   enable ?BOOLEAN?         Set or query the enable bit\n"
+-    "   filter GLOB...           Reject tables matching GLOBs\n"
+-    "   indirect ?BOOLEAN?       Mark or query the indirect status\n"
+-    "   isempty                  Query whether the session is empty\n"
+-    "   list                     List currently open session names\n"
+-    "   open DB NAME             Open a new session on DB\n"
+-    "   patchset FILE            Write a patchset into FILE\n"
+-  );
++static int showHelp(FILE *out, const char *zPattern){
++  int i = 0;
++  int j = 0;
++  int n = 0;
++  char *zPat;
++  if( zPattern==0
++   || zPattern[0]=='0'
++   || strcmp(zPattern,"-a")==0
++   || strcmp(zPattern,"-all")==0
++  ){
++    /* Show all commands, but only one line per command */
++    if( zPattern==0 ) zPattern = "";
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( azHelp[i][0]=='.' || zPattern[0] ){
++        utf8_printf(out, "%s\n", azHelp[i]);
++        n++;
++      }
++    }
++  }else{
++    /* Look for commands that for which zPattern is an exact prefix */
++    zPat = sqlite3_mprintf(".%s*", zPattern);
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( sqlite3_strglob(zPat, azHelp[i])==0 ){
++        utf8_printf(out, "%s\n", azHelp[i]);
++        j = i+1;
++        n++;
++      }
++    }
++    sqlite3_free(zPat);
++    if( n ){
++      if( n==1 ){
++        /* when zPattern is a prefix of exactly one command, then include the
++        ** details of that command, which should begin at offset j */
++        while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
++          utf8_printf(out, "%s\n", azHelp[j]);
++          j++;
++        }
++      }
++      return n;
++    }
++    /* Look for commands that contain zPattern anywhere.  Show the complete
++    ** text of all commands that match. */
++    zPat = sqlite3_mprintf("%%%s%%", zPattern);
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( azHelp[i][0]=='.' ) j = i;
++      if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
++        utf8_printf(out, "%s\n", azHelp[j]);
++        while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
++          j++;
++          utf8_printf(out, "%s\n", azHelp[j]);
++        }
++        i = j;
++        n++;
++      }
++    }
++    sqlite3_free(zPat);
++  }
++  return n;
+ }
+-#endif
+ 
+-
+ /* Forward reference */
+ static int process_input(ShellState *p, FILE *in);
+ 
+@@ -4172,7 +11145,7 @@
+   nIn = ftell(in);
+   rewind(in);
+   pBuf = sqlite3_malloc64( nIn+1 );
+-  if( pBuf==0 ) return 0;
++  if( pBuf==0 ){ fclose(in); return 0; }
+   nRead = fread(pBuf, nIn, 1, in);
+   fclose(in);
+   if( nRead!=1 ){
+@@ -4232,18 +11205,105 @@
+ #endif
+ 
+ /*
++** Try to deduce the type of file for zName based on its content.  Return
++** one of the SHELL_OPEN_* constants.
++**
++** If the file does not exist or is empty but its name looks like a ZIP
++** archive and the dfltZip flag is true, then assume it is a ZIP archive.
++** Otherwise, assume an ordinary database regardless of the filename if
++** the type cannot be determined from content.
++*/
++int deduceDatabaseType(const char *zName, int dfltZip){
++  FILE *f = fopen(zName, "rb");
++  size_t n;
++  int rc = SHELL_OPEN_UNSPEC;
++  char zBuf[100];
++  if( f==0 ){
++    if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
++       return SHELL_OPEN_ZIPFILE;
++    }else{
++       return SHELL_OPEN_NORMAL;
++    }
++  }
++  n = fread(zBuf, 16, 1, f);
++  if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
++    fclose(f);
++    return SHELL_OPEN_NORMAL;
++  }
++  fseek(f, -25, SEEK_END);
++  n = fread(zBuf, 25, 1, f);
++  if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
++    rc = SHELL_OPEN_APPENDVFS;
++  }else{
++    fseek(f, -22, SEEK_END);
++    n = fread(zBuf, 22, 1, f);
++    if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
++       && zBuf[3]==0x06 ){
++      rc = SHELL_OPEN_ZIPFILE;
++    }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
++      rc = SHELL_OPEN_ZIPFILE;
++    }
++  }
++  fclose(f);
++  return rc;  
++}
++
++/* Flags for open_db().
++**
++** The default behavior of open_db() is to exit(1) if the database fails to
++** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
++** but still returns without calling exit.
++**
++** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
++** ZIP archive if the file does not exist or is empty and its name matches
++** the *.zip pattern.
++*/
++#define OPEN_DB_KEEPALIVE   0x001   /* Return after error if true */
++#define OPEN_DB_ZIPFILE     0x002   /* Open as ZIP if name matches *.zip */
++
++/*
+ ** Make sure the database is open.  If it is not, then open it.  If
+ ** the database fails to open, print an error message and exit.
+ */
+-static void open_db(ShellState *p, int keepAlive){
++static void open_db(ShellState *p, int openFlags){
+   if( p->db==0 ){
+-    sqlite3_initialize();
+-    sqlite3_open(p->zDbFilename, &p->db);
++    if( p->openMode==SHELL_OPEN_UNSPEC ){
++      if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
++        p->openMode = SHELL_OPEN_NORMAL;
++      }else{
++        p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 
++                             (openFlags & OPEN_DB_ZIPFILE)!=0);
++      }
++    }
++    switch( p->openMode ){
++      case SHELL_OPEN_APPENDVFS: {
++        sqlite3_open_v2(p->zDbFilename, &p->db, 
++           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
++        break;
++      }
++      case SHELL_OPEN_DESERIALIZE: {
++        sqlite3_open(0, &p->db);
++        break;
++      }
++      case SHELL_OPEN_ZIPFILE: {
++        sqlite3_open(":memory:", &p->db);
++        break;
++      }
++      case SHELL_OPEN_READONLY: {
++        sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
++        break;
++      }
++      case SHELL_OPEN_UNSPEC:
++      case SHELL_OPEN_NORMAL: {
++        sqlite3_open(p->zDbFilename, &p->db);
++        break;
++      }
++    }
+     globalDb = p->db;
+     if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
+       utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
+           p->zDbFilename, sqlite3_errmsg(p->db));
+-      if( keepAlive ) return;
++      if( openFlags & OPEN_DB_KEEPALIVE ) return;
+       exit(1);
+     }
+ #ifndef SQLITE_OMIT_LOAD_EXTENSION
+@@ -4252,11 +11312,54 @@
+     sqlite3_fileio_init(p->db, 0, 0);
+     sqlite3_shathree_init(p->db, 0, 0);
+     sqlite3_completion_init(p->db, 0, 0);
+-    sqlite3_create_function(p->db, "shell_add_schema", 2, SQLITE_UTF8, 0,
++#ifdef SQLITE_HAVE_ZLIB
++    sqlite3_zipfile_init(p->db, 0, 0);
++    sqlite3_sqlar_init(p->db, 0, 0);
++#endif
++    sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
+                             shellAddSchemaName, 0, 0);
++    sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
++                            shellModuleSchema, 0, 0);
++    sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
++                            shellPutsFunc, 0, 0);
++#ifndef SQLITE_NOHAVE_SYSTEM
++    sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
++                            editFunc, 0, 0);
++    sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
++                            editFunc, 0, 0);
++#endif
++    if( p->openMode==SHELL_OPEN_ZIPFILE ){
++      char *zSql = sqlite3_mprintf(
++         "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
++      sqlite3_exec(p->db, zSql, 0, 0, 0);
++      sqlite3_free(zSql);
++    }
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
++      int nData = 0;
++      unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
++      int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
++                   SQLITE_DESERIALIZE_RESIZEABLE |
++                   SQLITE_DESERIALIZE_FREEONCLOSE);
++      if( rc ){
++        utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
++      }
++    }
++#endif
+   }
+ }
+ 
++/*
++** Attempt to close the databaes connection.  Report errors.
++*/
++void close_db(sqlite3 *db){
++  int rc = sqlite3_close(db);
++  if( rc ){
++    utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
++        rc, sqlite3_errmsg(db));
++  } 
++}
++
+ #if HAVE_READLINE || HAVE_EDITLINE
+ /*
+ ** Readline completion callbacks
+@@ -4291,7 +11394,7 @@
+ ** Linenoise completion callback
+ */
+ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
+-  int nLine = (int)strlen(zLine);
++  int nLine = strlen30(zLine);
+   int i, iStart;
+   sqlite3_stmt *pStmt = 0;
+   char *zSql;
+@@ -4298,7 +11401,7 @@
+   char zBuf[1000];
+ 
+   if( nLine>sizeof(zBuf)-30 ) return;
+-  if( zLine[0]=='.' ) return;
++  if( zLine[0]=='.' || zLine[0]=='#') return;
+   for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
+   if( i==nLine-1 ) return;
+   iStart = i+1;
+@@ -4382,63 +11485,6 @@
+ }
+ 
+ /*
+-** Return the value of a hexadecimal digit.  Return -1 if the input
+-** is not a hex digit.
+-*/
+-static int hexDigitValue(char c){
+-  if( c>='0' && c<='9' ) return c - '0';
+-  if( c>='a' && c<='f' ) return c - 'a' + 10;
+-  if( c>='A' && c<='F' ) return c - 'A' + 10;
+-  return -1;
+-}
+-
+-/*
+-** Interpret zArg as an integer value, possibly with suffixes.
+-*/
+-static sqlite3_int64 integerValue(const char *zArg){
+-  sqlite3_int64 v = 0;
+-  static const struct { char *zSuffix; int iMult; } aMult[] = {
+-    { "KiB", 1024 },
+-    { "MiB", 1024*1024 },
+-    { "GiB", 1024*1024*1024 },
+-    { "KB",  1000 },
+-    { "MB",  1000000 },
+-    { "GB",  1000000000 },
+-    { "K",   1000 },
+-    { "M",   1000000 },
+-    { "G",   1000000000 },
+-  };
+-  int i;
+-  int isNeg = 0;
+-  if( zArg[0]=='-' ){
+-    isNeg = 1;
+-    zArg++;
+-  }else if( zArg[0]=='+' ){
+-    zArg++;
+-  }
+-  if( zArg[0]=='0' && zArg[1]=='x' ){
+-    int x;
+-    zArg += 2;
+-    while( (x = hexDigitValue(zArg[0]))>=0 ){
+-      v = (v<<4) + x;
+-      zArg++;
+-    }
+-  }else{
+-    while( IsDigit(zArg[0]) ){
+-      v = v*10 + zArg[0] - '0';
+-      zArg++;
+-    }
+-  }
+-  for(i=0; i<ArraySize(aMult); i++){
+-    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
+-      v *= aMult[i].iMult;
+-      break;
+-    }
+-  }
+-  return isNeg? -v : v;
+-}
+-
+-/*
+ ** Interpret zArg as either an integer or a boolean value.  Return 1 or 0
+ ** for TRUE and FALSE.  Return the integer value if appropriate.
+ */
+@@ -4484,7 +11530,7 @@
+ ** recognized and do the right thing.  NULL is returned if the output
+ ** filename is "off".
+ */
+-static FILE *output_file_open(const char *zFile){
++static FILE *output_file_open(const char *zFile, int bTextMode){
+   FILE *f;
+   if( strcmp(zFile,"stdout")==0 ){
+     f = stdout;
+@@ -4493,7 +11539,7 @@
+   }else if( strcmp(zFile, "off")==0 ){
+     f = 0;
+   }else{
+-    f = fopen(zFile, "wb");
++    f = fopen(zFile, bTextMode ? "w" : "wb");
+     if( f==0 ){
+       utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
+     }
+@@ -4501,7 +11547,6 @@
+   return f;
+ }
+ 
+-#if !defined(SQLITE_UNTESTABLE)
+ #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
+ /*
+ ** A routine for handling output from sqlite3_trace().
+@@ -4517,7 +11562,7 @@
+   UNUSED_PARAMETER(pP);
+   if( f ){
+     const char *z = (const char*)pX;
+-    int i = (int)strlen(z);
++    int i = strlen30(z);
+     while( i>0 && z[i-1]==';' ){ i--; }
+     utf8_printf(f, "%.*s;\n", i, z);
+   }
+@@ -4524,7 +11569,6 @@
+   return 0;
+ }
+ #endif
+-#endif
+ 
+ /*
+ ** A no-op routine that runs with the ".breakpoint" doc-command.  This is
+@@ -4557,10 +11601,7 @@
+   if( p->n+1>=p->nAlloc ){
+     p->nAlloc += p->nAlloc + 100;
+     p->z = sqlite3_realloc64(p->z, p->nAlloc);
+-    if( p->z==0 ){
+-      raw_printf(stderr, "out of memory\n");
+-      exit(1);
+-    }
++    if( p->z==0 ) shell_out_of_memory();
+   }
+   p->z[p->n++] = (char)c;
+ }
+@@ -4706,7 +11747,7 @@
+   char *zInsert = 0;
+   int rc;
+   int i, j, n;
+-  int nTable = (int)strlen(zTable);
++  int nTable = strlen30(zTable);
+   int k = 0;
+   int cnt = 0;
+   const int spinRate = 10000;
+@@ -4721,13 +11762,10 @@
+   }
+   n = sqlite3_column_count(pQuery);
+   zInsert = sqlite3_malloc64(200 + nTable + n*3);
+-  if( zInsert==0 ){
+-    raw_printf(stderr, "out of memory\n");
+-    goto end_data_xfer;
+-  }
++  if( zInsert==0 ) shell_out_of_memory();
+   sqlite3_snprintf(200+nTable,zInsert,
+                    "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
+-  i = (int)strlen(zInsert);
++  i = strlen30(zInsert);
+   for(j=1; j<n; j++){
+     memcpy(zInsert+i, ",?", 2);
+     i += 2;
+@@ -4902,11 +11940,15 @@
+     sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
+     sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
+   }
+-  sqlite3_close(newDb);
++  close_db(newDb);
+ }
+ 
+ /*
+-** Change the output file back to stdout
++** Change the output file back to stdout.
++**
++** If the p->doXdgOpen flag is set, that means the output was being
++** redirected to a temporary file named by p->zTempFile.  In that case,
++** launch start/open/xdg-open on that temporary file.
+ */
+ static void output_reset(ShellState *p){
+   if( p->outfile[0]=='|' ){
+@@ -4915,6 +11957,26 @@
+ #endif
+   }else{
+     output_file_close(p->out);
++#ifndef SQLITE_NOHAVE_SYSTEM
++    if( p->doXdgOpen ){
++      const char *zXdgOpenCmd =
++#if defined(_WIN32)
++      "start";
++#elif defined(__APPLE__)
++      "open";
++#else
++      "xdg-open";
++#endif
++      char *zCmd;
++      zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
++      if( system(zCmd) ){
++        utf8_printf(stderr, "Failed: [%s]\n", zCmd);
++      }
++      sqlite3_free(zCmd);
++      outputModePop(p);
++      p->doXdgOpen = 0;
++    }
++#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
+   }
+   p->outfile[0] = 0;
+   p->out = stdout;
+@@ -4976,20 +12038,25 @@
+      { "schema size:",
+        "SELECT total(length(sql)) FROM %s" },
+   };
+-  sqlite3_file *pFile = 0;
+   int i;
++  unsigned iDataVersion;
+   char *zSchemaTab;
+   char *zDb = nArg>=2 ? azArg[1] : "main";
++  sqlite3_stmt *pStmt = 0;
+   unsigned char aHdr[100];
+   open_db(p, 0);
+   if( p->db==0 ) return 1;
+-  sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
+-  if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
+-    return 1;
+-  }
+-  i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
+-  if( i!=SQLITE_OK ){
++  sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
++                     -1, &pStmt, 0);
++  sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
++  if( sqlite3_step(pStmt)==SQLITE_ROW
++   && sqlite3_column_bytes(pStmt,0)>100
++  ){
++    memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
++    sqlite3_finalize(pStmt);
++  }else{
+     raw_printf(stderr, "unable to read database header\n");
++    sqlite3_finalize(pStmt);
+     return 1;
+   }
+   i = get2byteInt(aHdr+16);
+@@ -5025,6 +12092,8 @@
+     utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
+   }
+   sqlite3_free(zSchemaTab);
++  sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
++  utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
+   return 0;
+ }
+ 
+@@ -5038,14 +12107,6 @@
+ }
+ 
+ /*
+-** Print an out-of-memory message to stderr and return 1.
+-*/
+-static int shellNomemError(void){
+-  raw_printf(stderr, "Error: out of memory\n");
+-  return 1;
+-}
+-
+-/*
+ ** Compare the pattern in zGlob[] against the text in z[].  Return TRUE
+ ** if they match and FALSE (0) if they do not match.
+ **
+@@ -5169,8 +12230,43 @@
+   return rc;
+ }
+ 
++/*
++** Try to delete the temporary file (if there is one) and free the
++** memory used to hold the name of the temp file.
++*/
++static void clearTempFile(ShellState *p){
++  if( p->zTempFile==0 ) return;
++  if( p->doXdgOpen ) return;
++  if( shellDeleteFile(p->zTempFile) ) return;
++  sqlite3_free(p->zTempFile);
++  p->zTempFile = 0;
++}
+ 
+ /*
++** Create a new temp file name with the given suffix.
++*/
++static void newTempFile(ShellState *p, const char *zSuffix){
++  clearTempFile(p);
++  sqlite3_free(p->zTempFile);
++  p->zTempFile = 0;
++  if( p->db ){
++    sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
++  }
++  if( p->zTempFile==0 ){
++    sqlite3_uint64 r;
++    sqlite3_randomness(sizeof(r), &r);
++    p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
++  }else{
++    p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
++  }
++  if( p->zTempFile==0 ){
++    raw_printf(stderr, "out of memory\n");
++    exit(1);
++  }
++}
++
++
++/*
+ ** The implementation of SQL scalar function fkey_collate_clause(), used
+ ** by the ".lint fkey-indexes" command. This scalar function is always
+ ** called with four arguments - the parent table name, the parent column name,
+@@ -5246,10 +12342,10 @@
+   **
+   ** 0. The text of an SQL statement similar to:
+   **
+-  **      "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?"
++  **      "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?"
+   **
+-  **    This is the same SELECT that the foreign keys implementation needs
+-  **    to run internally on child tables. If there is an index that can
++  **    This SELECT is similar to the one that the foreign keys implementation
++  **    needs to run internally on child tables. If there is an index that can
+   **    be used to optimize this query, then it can also be used by the FK
+   **    implementation to optimize DELETE or UPDATE statements on the parent
+   **    table.
+@@ -5277,7 +12373,7 @@
+   */
+   const char *zSql =
+   "SELECT "
+-    "     'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
++    "     'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '"
+     "  || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
+     "  || fkey_collate_clause("
+     "       f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
+@@ -5305,7 +12401,7 @@
+   const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
+ 
+   for(i=2; i<nArg; i++){
+-    int n = (int)strlen(azArg[i]);
++    int n = strlen30(azArg[i]);
+     if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
+       bVerbose = 1;
+     }
+@@ -5408,7 +12504,7 @@
+   int nArg                        /* Number of entries in azArg[] */
+ ){
+   int n;
+-  n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
++  n = (nArg>=2 ? strlen30(azArg[1]) : 0);
+   if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
+   return lintFkeyIndexes(pState, azArg, nArg);
+ 
+@@ -5419,8 +12515,741 @@
+   return SQLITE_ERROR;
+ }
+ 
++#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
++/*********************************************************************************
++** The ".archive" or ".ar" command.
++*/
++static void shellPrepare(
++  sqlite3 *db, 
++  int *pRc, 
++  const char *zSql, 
++  sqlite3_stmt **ppStmt
++){
++  *ppStmt = 0;
++  if( *pRc==SQLITE_OK ){
++    int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
++    if( rc!=SQLITE_OK ){
++      raw_printf(stderr, "sql error: %s (%d)\n", 
++          sqlite3_errmsg(db), sqlite3_errcode(db)
++      );
++      *pRc = rc;
++    }
++  }
++}
+ 
++static void shellPreparePrintf(
++  sqlite3 *db, 
++  int *pRc, 
++  sqlite3_stmt **ppStmt,
++  const char *zFmt, 
++  ...
++){
++  *ppStmt = 0;
++  if( *pRc==SQLITE_OK ){
++    va_list ap;
++    char *z;
++    va_start(ap, zFmt);
++    z = sqlite3_vmprintf(zFmt, ap);
++    va_end(ap);
++    if( z==0 ){
++      *pRc = SQLITE_NOMEM;
++    }else{
++      shellPrepare(db, pRc, z, ppStmt);
++      sqlite3_free(z);
++    }
++  }
++}
++
++static void shellFinalize(
++  int *pRc, 
++  sqlite3_stmt *pStmt
++){
++  if( pStmt ){
++    sqlite3 *db = sqlite3_db_handle(pStmt);
++    int rc = sqlite3_finalize(pStmt);
++    if( *pRc==SQLITE_OK ){
++      if( rc!=SQLITE_OK ){
++        raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
++      }
++      *pRc = rc;
++    }
++  }
++}
++
++static void shellReset(
++  int *pRc, 
++  sqlite3_stmt *pStmt
++){
++  int rc = sqlite3_reset(pStmt);
++  if( *pRc==SQLITE_OK ){
++    if( rc!=SQLITE_OK ){
++      sqlite3 *db = sqlite3_db_handle(pStmt);
++      raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
++    }
++    *pRc = rc;
++  }
++}
+ /*
++** Structure representing a single ".ar" command.
++*/
++typedef struct ArCommand ArCommand;
++struct ArCommand {
++  u8 eCmd;                        /* An AR_CMD_* value */
++  u8 bVerbose;                    /* True if --verbose */
++  u8 bZip;                        /* True if the archive is a ZIP */
++  u8 bDryRun;                     /* True if --dry-run */
++  u8 bAppend;                     /* True if --append */
++  u8 fromCmdLine;                 /* Run from -A instead of .archive */
++  int nArg;                       /* Number of command arguments */
++  char *zSrcTable;                /* "sqlar", "zipfile($file)" or "zip" */
++  const char *zFile;              /* --file argument, or NULL */
++  const char *zDir;               /* --directory argument, or NULL */
++  char **azArg;                   /* Array of command arguments */
++  ShellState *p;                  /* Shell state */
++  sqlite3 *db;                    /* Database containing the archive */
++};
++
++/*
++** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
++*/
++static int arUsage(FILE *f){
++  showHelp(f,"archive");
++  return SQLITE_ERROR;
++}
++
++/*
++** Print an error message for the .ar command to stderr and return 
++** SQLITE_ERROR.
++*/
++static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
++  va_list ap;
++  char *z;
++  va_start(ap, zFmt);
++  z = sqlite3_vmprintf(zFmt, ap);
++  va_end(ap);
++  utf8_printf(stderr, "Error: %s\n", z);
++  if( pAr->fromCmdLine ){
++    utf8_printf(stderr, "Use \"-A\" for more help\n");
++  }else{
++    utf8_printf(stderr, "Use \".archive --help\" for more help\n");
++  }
++  sqlite3_free(z);
++  return SQLITE_ERROR;
++}
++
++/*
++** Values for ArCommand.eCmd.
++*/
++#define AR_CMD_CREATE       1
++#define AR_CMD_EXTRACT      2
++#define AR_CMD_LIST         3
++#define AR_CMD_UPDATE       4
++#define AR_CMD_HELP         5
++
++/*
++** Other (non-command) switches.
++*/
++#define AR_SWITCH_VERBOSE     6
++#define AR_SWITCH_FILE        7
++#define AR_SWITCH_DIRECTORY   8
++#define AR_SWITCH_APPEND      9
++#define AR_SWITCH_DRYRUN     10
++
++static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
++  switch( eSwitch ){
++    case AR_CMD_CREATE:
++    case AR_CMD_EXTRACT:
++    case AR_CMD_LIST:
++    case AR_CMD_UPDATE:
++    case AR_CMD_HELP:
++      if( pAr->eCmd ){
++        return arErrorMsg(pAr, "multiple command options");
++      }
++      pAr->eCmd = eSwitch;
++      break;
++
++    case AR_SWITCH_DRYRUN:
++      pAr->bDryRun = 1;
++      break;
++    case AR_SWITCH_VERBOSE:
++      pAr->bVerbose = 1;
++      break;
++    case AR_SWITCH_APPEND:
++      pAr->bAppend = 1;
++      /* Fall thru into --file */
++    case AR_SWITCH_FILE:
++      pAr->zFile = zArg;
++      break;
++    case AR_SWITCH_DIRECTORY:
++      pAr->zDir = zArg;
++      break;
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** Parse the command line for an ".ar" command. The results are written into
++** structure (*pAr). SQLITE_OK is returned if the command line is parsed
++** successfully, otherwise an error message is written to stderr and 
++** SQLITE_ERROR returned.
++*/
++static int arParseCommand(
++  char **azArg,                   /* Array of arguments passed to dot command */
++  int nArg,                       /* Number of entries in azArg[] */
++  ArCommand *pAr                  /* Populate this object */
++){
++  struct ArSwitch {
++    const char *zLong;
++    char cShort;
++    u8 eSwitch;
++    u8 bArg;
++  } aSwitch[] = {
++    { "create",    'c', AR_CMD_CREATE,       0 },
++    { "extract",   'x', AR_CMD_EXTRACT,      0 },
++    { "list",      't', AR_CMD_LIST,         0 },
++    { "update",    'u', AR_CMD_UPDATE,       0 },
++    { "help",      'h', AR_CMD_HELP,         0 },
++    { "verbose",   'v', AR_SWITCH_VERBOSE,   0 },
++    { "file",      'f', AR_SWITCH_FILE,      1 },
++    { "append",    'a', AR_SWITCH_APPEND,    1 },
++    { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
++    { "dryrun",    'n', AR_SWITCH_DRYRUN,    0 },
++  };
++  int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
++  struct ArSwitch *pEnd = &aSwitch[nSwitch];
++
++  if( nArg<=1 ){
++    utf8_printf(stderr, "Wrong number of arguments.  Usage:\n");
++    return arUsage(stderr);
++  }else{
++    char *z = azArg[1];
++    if( z[0]!='-' ){
++      /* Traditional style [tar] invocation */
++      int i;
++      int iArg = 2;
++      for(i=0; z[i]; i++){
++        const char *zArg = 0;
++        struct ArSwitch *pOpt;
++        for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
++          if( z[i]==pOpt->cShort ) break;
++        }
++        if( pOpt==pEnd ){
++          return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
++        }
++        if( pOpt->bArg ){
++          if( iArg>=nArg ){
++            return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
++          }
++          zArg = azArg[iArg++];
++        }
++        if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
++      }
++      pAr->nArg = nArg-iArg;
++      if( pAr->nArg>0 ){
++        pAr->azArg = &azArg[iArg];
++      }
++    }else{
++      /* Non-traditional invocation */
++      int iArg;
++      for(iArg=1; iArg<nArg; iArg++){
++        int n;
++        z = azArg[iArg];
++        if( z[0]!='-' ){
++          /* All remaining command line words are command arguments. */
++          pAr->azArg = &azArg[iArg];
++          pAr->nArg = nArg-iArg;
++          break;
++        }
++        n = strlen30(z);
++
++        if( z[1]!='-' ){
++          int i;
++          /* One or more short options */
++          for(i=1; i<n; i++){
++            const char *zArg = 0;
++            struct ArSwitch *pOpt;
++            for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
++              if( z[i]==pOpt->cShort ) break;
++            }
++            if( pOpt==pEnd ){
++              return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
++            }
++            if( pOpt->bArg ){
++              if( i<(n-1) ){
++                zArg = &z[i+1];
++                i = n;
++              }else{
++                if( iArg>=(nArg-1) ){
++                  return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
++                }
++                zArg = azArg[++iArg];
++              }
++            }
++            if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
++          }
++        }else if( z[2]=='\0' ){
++          /* A -- option, indicating that all remaining command line words
++          ** are command arguments.  */
++          pAr->azArg = &azArg[iArg+1];
++          pAr->nArg = nArg-iArg-1;
++          break;
++        }else{
++          /* A long option */
++          const char *zArg = 0;             /* Argument for option, if any */
++          struct ArSwitch *pMatch = 0;      /* Matching option */
++          struct ArSwitch *pOpt;            /* Iterator */
++          for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
++            const char *zLong = pOpt->zLong;
++            if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
++              if( pMatch ){
++                return arErrorMsg(pAr, "ambiguous option: %s",z);
++              }else{
++                pMatch = pOpt;
++              }
++            }
++          }
++
++          if( pMatch==0 ){
++            return arErrorMsg(pAr, "unrecognized option: %s", z);
++          }
++          if( pMatch->bArg ){
++            if( iArg>=(nArg-1) ){
++              return arErrorMsg(pAr, "option requires an argument: %s", z);
++            }
++            zArg = azArg[++iArg];
++          }
++          if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
++        }
++      }
++    }
++  }
++
++  return SQLITE_OK;
++}
++
++/*
++** This function assumes that all arguments within the ArCommand.azArg[]
++** array refer to archive members, as for the --extract or --list commands. 
++** It checks that each of them are present. If any specified file is not
++** present in the archive, an error is printed to stderr and an error
++** code returned. Otherwise, if all specified arguments are present in
++** the archive, SQLITE_OK is returned.
++**
++** This function strips any trailing '/' characters from each argument.
++** This is consistent with the way the [tar] command seems to work on
++** Linux.
++*/
++static int arCheckEntries(ArCommand *pAr){
++  int rc = SQLITE_OK;
++  if( pAr->nArg ){
++    int i, j;
++    sqlite3_stmt *pTest = 0;
++
++    shellPreparePrintf(pAr->db, &rc, &pTest,
++        "SELECT name FROM %s WHERE name=$name", 
++        pAr->zSrcTable
++    );
++    j = sqlite3_bind_parameter_index(pTest, "$name");
++    for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
++      char *z = pAr->azArg[i];
++      int n = strlen30(z);
++      int bOk = 0;
++      while( n>0 && z[n-1]=='/' ) n--;
++      z[n] = '\0';
++      sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
++      if( SQLITE_ROW==sqlite3_step(pTest) ){
++        bOk = 1;
++      }
++      shellReset(&rc, pTest);
++      if( rc==SQLITE_OK && bOk==0 ){
++        utf8_printf(stderr, "not found in archive: %s\n", z);
++        rc = SQLITE_ERROR;
++      }
++    }
++    shellFinalize(&rc, pTest);
++  }
++  return rc;
++}
++
++/*
++** Format a WHERE clause that can be used against the "sqlar" table to
++** identify all archive members that match the command arguments held
++** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
++** The caller is responsible for eventually calling sqlite3_free() on
++** any non-NULL (*pzWhere) value.
++*/
++static void arWhereClause(
++  int *pRc, 
++  ArCommand *pAr, 
++  char **pzWhere                  /* OUT: New WHERE clause */
++){
++  char *zWhere = 0;
++  if( *pRc==SQLITE_OK ){
++    if( pAr->nArg==0 ){
++      zWhere = sqlite3_mprintf("1");
++    }else{
++      int i;
++      const char *zSep = "";
++      for(i=0; i<pAr->nArg; i++){
++        const char *z = pAr->azArg[i];
++        zWhere = sqlite3_mprintf(
++          "%z%s name = '%q' OR substr(name,1,%d) = '%q/'", 
++          zWhere, zSep, z, strlen30(z)+1, z
++        );
++        if( zWhere==0 ){
++          *pRc = SQLITE_NOMEM;
++          break;
++        }
++        zSep = " OR ";
++      }
++    }
++  }
++  *pzWhere = zWhere;
++}
++
++/*
++** Implementation of .ar "lisT" command. 
++*/
++static int arListCommand(ArCommand *pAr){
++  const char *zSql = "SELECT %s FROM %s WHERE %s"; 
++  const char *azCols[] = {
++    "name",
++    "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
++  };
++
++  char *zWhere = 0;
++  sqlite3_stmt *pSql = 0;
++  int rc;
++
++  rc = arCheckEntries(pAr);
++  arWhereClause(&rc, pAr, &zWhere);
++
++  shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
++                     pAr->zSrcTable, zWhere);
++  if( pAr->bDryRun ){
++    utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
++  }else{
++    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
++      if( pAr->bVerbose ){
++        utf8_printf(pAr->p->out, "%s % 10d  %s  %s\n",
++            sqlite3_column_text(pSql, 0),
++            sqlite3_column_int(pSql, 1), 
++            sqlite3_column_text(pSql, 2),
++            sqlite3_column_text(pSql, 3)
++        );
++      }else{
++        utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
++      }
++    }
++  }
++  shellFinalize(&rc, pSql);
++  sqlite3_free(zWhere);
++  return rc;
++}
++
++
++/*
++** Implementation of .ar "eXtract" command. 
++*/
++static int arExtractCommand(ArCommand *pAr){
++  const char *zSql1 = 
++    "SELECT "
++    " ($dir || name),"
++    " writefile(($dir || name), %s, mode, mtime) "
++    "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
++    " AND name NOT GLOB '*..[/\\]*'";
++
++  const char *azExtraArg[] = { 
++    "sqlar_uncompress(data, sz)",
++    "data"
++  };
++
++  sqlite3_stmt *pSql = 0;
++  int rc = SQLITE_OK;
++  char *zDir = 0;
++  char *zWhere = 0;
++  int i, j;
++
++  /* If arguments are specified, check that they actually exist within
++  ** the archive before proceeding. And formulate a WHERE clause to
++  ** match them.  */
++  rc = arCheckEntries(pAr);
++  arWhereClause(&rc, pAr, &zWhere);
++
++  if( rc==SQLITE_OK ){
++    if( pAr->zDir ){
++      zDir = sqlite3_mprintf("%s/", pAr->zDir);
++    }else{
++      zDir = sqlite3_mprintf("");
++    }
++    if( zDir==0 ) rc = SQLITE_NOMEM;
++  }
++
++  shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, 
++      azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
++  );
++
++  if( rc==SQLITE_OK ){
++    j = sqlite3_bind_parameter_index(pSql, "$dir");
++    sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
++
++    /* Run the SELECT statement twice. The first time, writefile() is called
++    ** for all archive members that should be extracted. The second time,
++    ** only for the directories. This is because the timestamps for
++    ** extracted directories must be reset after they are populated (as
++    ** populating them changes the timestamp).  */
++    for(i=0; i<2; i++){
++      j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
++      sqlite3_bind_int(pSql, j, i);
++      if( pAr->bDryRun ){
++        utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
++      }else{
++        while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
++          if( i==0 && pAr->bVerbose ){
++            utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
++          }
++        }
++      }
++      shellReset(&rc, pSql);
++    }
++    shellFinalize(&rc, pSql);
++  }
++
++  sqlite3_free(zDir);
++  sqlite3_free(zWhere);
++  return rc;
++}
++
++/*
++** Run the SQL statement in zSql.  Or if doing a --dryrun, merely print it out.
++*/
++static int arExecSql(ArCommand *pAr, const char *zSql){
++  int rc;
++  if( pAr->bDryRun ){
++    utf8_printf(pAr->p->out, "%s\n", zSql);
++    rc = SQLITE_OK;
++  }else{
++    char *zErr = 0;
++    rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
++    if( zErr ){
++      utf8_printf(stdout, "ERROR: %s\n", zErr);
++      sqlite3_free(zErr);
++    }
++  }
++  return rc;
++}
++
++
++/*
++** Implementation of .ar "create" and "update" commands.
++**
++** Create the "sqlar" table in the database if it does not already exist.
++** Then add each file in the azFile[] array to the archive. Directories
++** are added recursively. If argument bVerbose is non-zero, a message is
++** printed on stdout for each file archived.
++**
++** The create command is the same as update, except that it drops
++** any existing "sqlar" table before beginning.
++*/
++static int arCreateOrUpdateCommand(
++  ArCommand *pAr,                 /* Command arguments and options */
++  int bUpdate                     /* true for a --create.  false for --update */
++){
++  const char *zCreate = 
++      "CREATE TABLE IF NOT EXISTS sqlar(\n"
++      "  name TEXT PRIMARY KEY,  -- name of the file\n"
++      "  mode INT,               -- access permissions\n"
++      "  mtime INT,              -- last modification time\n"
++      "  sz INT,                 -- original file size\n"
++      "  data BLOB               -- compressed content\n"
++      ")";
++  const char *zDrop = "DROP TABLE IF EXISTS sqlar";
++  const char *zInsertFmt[2] = {
++     "REPLACE INTO %s(name,mode,mtime,sz,data)\n"
++     "  SELECT\n"
++     "    %s,\n"
++     "    mode,\n"
++     "    mtime,\n"
++     "    CASE substr(lsmode(mode),1,1)\n"
++     "      WHEN '-' THEN length(data)\n"
++     "      WHEN 'd' THEN 0\n"
++     "      ELSE -1 END,\n"
++     "    sqlar_compress(data)\n"
++     "  FROM fsdir(%Q,%Q)\n"
++     "  WHERE lsmode(mode) NOT LIKE '?%%';",
++     "REPLACE INTO %s(name,mode,mtime,data)\n"
++     "  SELECT\n"
++     "    %s,\n"
++     "    mode,\n"
++     "    mtime,\n"
++     "    data\n"
++     "  FROM fsdir(%Q,%Q)\n"
++     "  WHERE lsmode(mode) NOT LIKE '?%%';"
++  };
++  int i;                          /* For iterating through azFile[] */
++  int rc;                         /* Return code */
++  const char *zTab = 0;           /* SQL table into which to insert */
++  char *zSql;
++  char zTemp[50];
++
++  arExecSql(pAr, "PRAGMA page_size=512");
++  rc = arExecSql(pAr, "SAVEPOINT ar;");
++  if( rc!=SQLITE_OK ) return rc;
++  zTemp[0] = 0; 
++  if( pAr->bZip ){
++    /* Initialize the zipfile virtual table, if necessary */
++    if( pAr->zFile ){
++      sqlite3_uint64 r;
++      sqlite3_randomness(sizeof(r),&r);
++      sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
++      zTab = zTemp;
++      zSql = sqlite3_mprintf(
++         "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
++         zTab, pAr->zFile
++      );
++      rc = arExecSql(pAr, zSql);
++      sqlite3_free(zSql);
++    }else{
++      zTab = "zip";
++    }
++  }else{
++    /* Initialize the table for an SQLAR */
++    zTab = "sqlar";
++    if( bUpdate==0 ){
++      rc = arExecSql(pAr, zDrop);
++      if( rc!=SQLITE_OK ) goto end_ar_transaction;
++    }
++    rc = arExecSql(pAr, zCreate);
++  }
++  for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
++    char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
++        pAr->bVerbose ? "shell_putsnl(name)" : "name",
++        pAr->azArg[i], pAr->zDir);
++    rc = arExecSql(pAr, zSql2);
++    sqlite3_free(zSql2);
++  }
++end_ar_transaction:
++  if( rc!=SQLITE_OK ){
++    arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
++  }else{
++    rc = arExecSql(pAr, "RELEASE ar;");
++    if( pAr->bZip && pAr->zFile ){
++      zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
++      arExecSql(pAr, zSql);
++      sqlite3_free(zSql);
++    }
++  }
++  return rc;
++}
++
++/*
++** Implementation of ".ar" dot command.
++*/
++static int arDotCommand(
++  ShellState *pState,             /* Current shell tool state */
++  int fromCmdLine,                /* True if -A command-line option, not .ar cmd */
++  char **azArg,                   /* Array of arguments passed to dot command */
++  int nArg                        /* Number of entries in azArg[] */
++){
++  ArCommand cmd;
++  int rc;
++  memset(&cmd, 0, sizeof(cmd));
++  cmd.fromCmdLine = fromCmdLine;
++  rc = arParseCommand(azArg, nArg, &cmd);
++  if( rc==SQLITE_OK ){
++    int eDbType = SHELL_OPEN_UNSPEC;
++    cmd.p = pState;
++    cmd.db = pState->db;
++    if( cmd.zFile ){
++      eDbType = deduceDatabaseType(cmd.zFile, 1);
++    }else{
++      eDbType = pState->openMode;
++    }
++    if( eDbType==SHELL_OPEN_ZIPFILE ){
++      if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
++        if( cmd.zFile==0 ){
++          cmd.zSrcTable = sqlite3_mprintf("zip");
++        }else{
++          cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
++        }
++      }
++      cmd.bZip = 1;
++    }else if( cmd.zFile ){
++      int flags;
++      if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
++      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
++        flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
++      }else{
++        flags = SQLITE_OPEN_READONLY;
++      }
++      cmd.db = 0;
++      if( cmd.bDryRun ){
++        utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
++             eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
++      }
++      rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, 
++             eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
++      if( rc!=SQLITE_OK ){
++        utf8_printf(stderr, "cannot open file: %s (%s)\n", 
++            cmd.zFile, sqlite3_errmsg(cmd.db)
++        );
++        goto end_ar_command;
++      }
++      sqlite3_fileio_init(cmd.db, 0, 0);
++      sqlite3_sqlar_init(cmd.db, 0, 0);
++      sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
++                              shellPutsFunc, 0, 0);
++
++    }
++    if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
++      if( cmd.eCmd!=AR_CMD_CREATE
++       && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
++      ){
++        utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
++        rc = SQLITE_ERROR;
++        goto end_ar_command;
++      }
++      cmd.zSrcTable = sqlite3_mprintf("sqlar");
++    }
++
++    switch( cmd.eCmd ){
++      case AR_CMD_CREATE:
++        rc = arCreateOrUpdateCommand(&cmd, 0);
++        break;
++
++      case AR_CMD_EXTRACT:
++        rc = arExtractCommand(&cmd);
++        break;
++
++      case AR_CMD_LIST:
++        rc = arListCommand(&cmd);
++        break;
++
++      case AR_CMD_HELP:
++        arUsage(pState->out);
++        break;
++
++      default:
++        assert( cmd.eCmd==AR_CMD_UPDATE );
++        rc = arCreateOrUpdateCommand(&cmd, 1);
++        break;
++    }
++  }
++end_ar_command:
++  if( cmd.db!=pState->db ){
++    close_db(cmd.db);
++  }
++  sqlite3_free(cmd.zSrcTable);
++
++  return rc;
++}
++/* End of the ".archive" or ".ar" command logic
++**********************************************************************************/
++#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
++
++
++/*
+ ** If an input line begins with "." then invoke this routine to
+ ** process that line.
+ **
+@@ -5433,6 +13262,12 @@
+   int rc = 0;
+   char *azArg[50];
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( p->expert.pExpert ){
++    expertFinish(p, 1, 0);
++  }
++#endif
++
+   /* Parse the input line into tokens.
+   */
+   while( zLine[h] && nArg<ArraySize(azArg) ){
+@@ -5462,6 +13297,7 @@
+   if( nArg==0 ) return 0; /* no tokens, no error */
+   n = strlen30(azArg[0]);
+   c = azArg[0][0];
++  clearTempFile(p);
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
+@@ -5479,6 +13315,13 @@
+   }else
+ #endif
+ 
++#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
++  if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
++    open_db(p, 0);
++    rc = arDotCommand(p, 0, azArg, nArg);
++  }else
++#endif
++
+   if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
+    || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
+   ){
+@@ -5487,11 +13330,14 @@
+     sqlite3 *pDest;
+     sqlite3_backup *pBackup;
+     int j;
++    const char *zVfs = 0;
+     for(j=1; j<nArg; j++){
+       const char *z = azArg[j];
+       if( z[0]=='-' ){
+-        while( z[0]=='-' ) z++;
+-        /* No options to process at this time */
++        if( z[1]=='-' ) z++;
++        if( strcmp(z, "-append")==0 ){
++          zVfs = "apndvfs";
++        }else
+         {
+           utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
+           return 1;
+@@ -5502,7 +13348,7 @@
+         zDb = zDestFile;
+         zDestFile = azArg[j];
+       }else{
+-        raw_printf(stderr, "too many arguments to .backup\n");
++        raw_printf(stderr, "Usage: .backup ?DB? ?--append? FILENAME\n");
+         return 1;
+       }
+     }
+@@ -5511,10 +13357,11 @@
+       return 1;
+     }
+     if( zDb==0 ) zDb = "main";
+-    rc = sqlite3_open(zDestFile, &pDest);
++    rc = sqlite3_open_v2(zDestFile, &pDest, 
++                  SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
+     if( rc!=SQLITE_OK ){
+       utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
+-      sqlite3_close(pDest);
++      close_db(pDest);
+       return 1;
+     }
+     open_db(p, 0);
+@@ -5521,7 +13368,7 @@
+     pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
+     if( pBackup==0 ){
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+-      sqlite3_close(pDest);
++      close_db(pDest);
+       return 1;
+     }
+     while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
+@@ -5532,7 +13379,7 @@
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+       rc = 1;
+     }
+-    sqlite3_close(pDest);
++    close_db(pDest);
+   }else
+ 
+   if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
+@@ -5609,7 +13456,7 @@
+       utf8_printf(stderr,
+                  "testcase-%s FAILED\n Expected: [%s]\n      Got: [%s]\n",
+                  p->zTestcase, azArg[1], zRes);
+-      rc = 2;
++      rc = 1;
+     }else{
+       utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
+       p->nCheck++;
+@@ -5644,7 +13491,39 @@
+     }
+   }else
+ 
+-  if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
++  if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
++    static const struct DbConfigChoices {
++      const char *zName;
++      int op;
++    } aDbConfig[] = {
++        { "enable_fkey",      SQLITE_DBCONFIG_ENABLE_FKEY            },
++        { "enable_trigger",   SQLITE_DBCONFIG_ENABLE_TRIGGER         },
++        { "fts3_tokenizer",   SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER  },
++        { "load_extension",   SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION  },
++        { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE       },
++        { "enable_qpsg",      SQLITE_DBCONFIG_ENABLE_QPSG            },
++        { "trigger_eqp",      SQLITE_DBCONFIG_TRIGGER_EQP            },
++        { "reset_database",   SQLITE_DBCONFIG_RESET_DATABASE         },
++        { "defensive",        SQLITE_DBCONFIG_DEFENSIVE              },
++    };
++    int ii, v;
++    open_db(p, 0);
++    for(ii=0; ii<ArraySize(aDbConfig); ii++){
++      if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
++      if( nArg>=3 ){
++        sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
++      }
++      sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
++      utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
++      if( nArg>1 ) break;
++    }
++    if( nArg>1 && ii==ArraySize(aDbConfig) ){
++      utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
++      utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
++    }   
++  }else
++
++  if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
+     rc = shell_dbinfo_command(p, nArg, azArg);
+   }else
+ 
+@@ -5652,7 +13531,8 @@
+     const char *zLike = 0;
+     int i;
+     int savedShowHeader = p->showHeader;
+-    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines);
++    int savedShellFlags = p->shellFlgs;
++    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
+     for(i=1; i<nArg; i++){
+       if( azArg[i][0]=='-' ){
+         const char *z = azArg[i]+1;
+@@ -5734,6 +13614,7 @@
+     sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
+     raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
+     p->showHeader = savedShowHeader;
++    p->shellFlgs = savedShellFlags;
+   }else
+ 
+   if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
+@@ -5747,13 +13628,19 @@
+ 
+   if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
+     if( nArg==2 ){
++      p->autoEQPtest = 0;
+       if( strcmp(azArg[1],"full")==0 ){
+-        p->autoEQP = 2;
++        p->autoEQP = AUTOEQP_full;
++      }else if( strcmp(azArg[1],"trigger")==0 ){
++        p->autoEQP = AUTOEQP_trigger;
++      }else if( strcmp(azArg[1],"test")==0 ){
++        p->autoEQP = AUTOEQP_on;
++        p->autoEQPtest = 1;
+       }else{
+-        p->autoEQP = booleanValue(azArg[1]);
++        p->autoEQP = (u8)booleanValue(azArg[1]);
+       }
+     }else{
+-      raw_printf(stderr, "Usage: .eqp on|off|full\n");
++      raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n");
+       rc = 1;
+     }
+   }else
+@@ -5787,6 +13674,13 @@
+     }
+   }else
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
++    open_db(p, 0);
++    expertDotCommand(p, azArg, nArg);
++  }else
++#endif
++
+   if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
+     ShellState data;
+     char *zErrMsg = 0;
+@@ -5830,14 +13724,11 @@
+                    callback, &data, &zErrMsg);
+       data.cMode = data.mode = MODE_Insert;
+       data.zDestTable = "sqlite_stat1";
+-      shell_exec(p->db, "SELECT * FROM sqlite_stat1",
+-                 shell_callback, &data,&zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
+       data.zDestTable = "sqlite_stat3";
+-      shell_exec(p->db, "SELECT * FROM sqlite_stat3",
+-                 shell_callback, &data,&zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
+       data.zDestTable = "sqlite_stat4";
+-      shell_exec(p->db, "SELECT * FROM sqlite_stat4",
+-                 shell_callback, &data, &zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
+       raw_printf(p->out, "ANALYZE sqlite_master;\n");
+     }
+   }else
+@@ -5852,7 +13743,14 @@
+   }else
+ 
+   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
+-    utf8_printf(p->out, "%s", zHelp);
++    if( nArg>=2 ){
++      n = showHelp(p->out, azArg[1]);
++      if( n==0 ){
++        utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
++      }
++    }else{
++      showHelp(p->out, 0);
++    }
+   }else
+ 
+   if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
+@@ -5935,9 +13833,8 @@
+     sCtx.cRowSep = p->rowSeparator[0];
+     zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
+     if( zSql==0 ){
+-      raw_printf(stderr, "Error: out of memory\n");
+       xCloser(sCtx.in);
+-      return 1;
++      shell_out_of_memory();
+     }
+     nByte = strlen30(zSql);
+     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+@@ -5982,9 +13879,8 @@
+     if( nCol==0 ) return 0; /* no columns, no error */
+     zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
+     if( zSql==0 ){
+-      raw_printf(stderr, "Error: out of memory\n");
+       xCloser(sCtx.in);
+-      return 1;
++      shell_out_of_memory();
+     }
+     sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
+     j = strlen30(zSql);
+@@ -6060,12 +13956,17 @@
+     sqlite3_stmt *pStmt;
+     int tnum = 0;
+     int i;
+-    if( nArg!=3 ){
+-      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
++    if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
++      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
++                          "       .imposter off\n");
+       rc = 1;
+       goto meta_command_exit;
+     }
+     open_db(p, 0);
++    if( nArg==2 ){
++      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
++      goto meta_command_exit;
++    }
+     zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
+                            " WHERE name='%q' AND type='index'", azArg[1]);
+     sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+@@ -6241,13 +14142,13 @@
+     }else{
+       const char *zFile = azArg[1];
+       output_file_close(p->pLog);
+-      p->pLog = output_file_open(zFile);
++      p->pLog = output_file_open(zFile, 0);
+     }
+   }else
+ 
+   if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
+     const char *zMode = nArg>=2 ? azArg[1] : "";
+-    int n2 = (int)strlen(zMode);
++    int n2 = strlen30(zMode);
+     int c2 = zMode[0];
+     if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
+       p->mode = MODE_Line;
+@@ -6307,16 +14208,29 @@
+     int newFlag = 0;     /* True to delete file before opening */
+     /* Close the existing database */
+     session_close_all(p);
+-    sqlite3_close(p->db);
++    close_db(p->db);
+     p->db = 0;
+     p->zDbFilename = 0;
+     sqlite3_free(p->zFreeOnClose);
+     p->zFreeOnClose = 0;
++    p->openMode = SHELL_OPEN_UNSPEC;
+     /* Check for command-line arguments */
+     for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
+       const char *z = azArg[iName];
+       if( optionMatch(z,"new") ){
+         newFlag = 1;
++#ifdef SQLITE_HAVE_ZLIB
++      }else if( optionMatch(z, "zip") ){
++        p->openMode = SHELL_OPEN_ZIPFILE;
++#endif
++      }else if( optionMatch(z, "append") ){
++        p->openMode = SHELL_OPEN_APPENDVFS;
++      }else if( optionMatch(z, "readonly") ){
++        p->openMode = SHELL_OPEN_READONLY;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++      }else if( optionMatch(z, "deserialize") ){
++        p->openMode = SHELL_OPEN_DESERIALIZE;
++#endif
+       }else if( z[0]=='-' ){
+         utf8_printf(stderr, "unknown option: %s\n", z);
+         rc = 1;
+@@ -6328,7 +14242,7 @@
+     if( zNewFilename ){
+       if( newFlag ) shellDeleteFile(zNewFilename);
+       p->zDbFilename = zNewFilename;
+-      open_db(p, 1);
++      open_db(p, OPEN_DB_KEEPALIVE);
+       if( p->db==0 ){
+         utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
+         sqlite3_free(zNewFilename);
+@@ -6343,18 +14257,27 @@
+     }
+   }else
+ 
+-  if( c=='o'
+-   && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
++  if( (c=='o'
++        && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
++   || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
+   ){
+     const char *zFile = nArg>=2 ? azArg[1] : "stdout";
++    int bTxtMode = 0;
++    if( azArg[0][0]=='e' ){
++      /* Transform the ".excel" command into ".once -x" */
++      nArg = 2;
++      azArg[0] = "once";
++      zFile = azArg[1] = "-x";
++      n = 4;
++    }
+     if( nArg>2 ){
+-      utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
++      utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
+       rc = 1;
+       goto meta_command_exit;
+     }
+     if( n>1 && strncmp(azArg[0], "once", n)==0 ){
+       if( nArg<2 ){
+-        raw_printf(stderr, "Usage: .once FILE\n");
++        raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
+         rc = 1;
+         goto meta_command_exit;
+       }
+@@ -6363,6 +14286,23 @@
+       p->outCount = 0;
+     }
+     output_reset(p);
++    if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
++#ifndef SQLITE_NOHAVE_SYSTEM
++    if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
++      p->doXdgOpen = 1;
++      outputModePush(p);
++      if( zFile[1]=='x' ){
++        newTempFile(p, "csv");
++        p->mode = MODE_Csv;
++        sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
++        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
++      }else{
++        newTempFile(p, "txt");
++        bTxtMode = 1;
++      }
++      zFile = p->zTempFile;
++    }
++#endif /* SQLITE_NOHAVE_SYSTEM */
+     if( zFile[0]=='|' ){
+ #ifdef SQLITE_OMIT_POPEN
+       raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+@@ -6379,7 +14319,7 @@
+       }
+ #endif
+     }else{
+-      p->out = output_file_open(zFile);
++      p->out = output_file_open(zFile, bTxtMode);
+       if( p->out==0 ){
+         if( strcmp(zFile,"off")!=0 ){
+           utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
+@@ -6452,7 +14392,7 @@
+     rc = sqlite3_open(zSrcFile, &pSrc);
+     if( rc!=SQLITE_OK ){
+       utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
+-      sqlite3_close(pSrc);
++      close_db(pSrc);
+       return 1;
+     }
+     open_db(p, 0);
+@@ -6459,7 +14399,7 @@
+     pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
+     if( pBackup==0 ){
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+-      sqlite3_close(pSrc);
++      close_db(pSrc);
+       return 1;
+     }
+     while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
+@@ -6479,13 +14419,12 @@
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+       rc = 1;
+     }
+-    sqlite3_close(pSrc);
++    close_db(pSrc);
+   }else
+ 
+-
+   if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
+     if( nArg==2 ){
+-      p->scanstatsOn = booleanValue(azArg[1]);
++      p->scanstatsOn = (u8)booleanValue(azArg[1]);
+ #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
+       raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
+ #endif
+@@ -6499,8 +14438,11 @@
+     ShellText sSelect;
+     ShellState data;
+     char *zErrMsg = 0;
+-    const char *zDiv = 0;
++    const char *zDiv = "(";
++    const char *zName = 0;
+     int iSchema = 0;
++    int bDebug = 0;
++    int ii;
+ 
+     open_db(p, 0);
+     memcpy(&data, p, sizeof(data));
+@@ -6507,51 +14449,37 @@
+     data.showHeader = 0;
+     data.cMode = data.mode = MODE_Semi;
+     initText(&sSelect);
+-    if( nArg>=2 && optionMatch(azArg[1], "indent") ){
+-      data.cMode = data.mode = MODE_Pretty;
+-      nArg--;
+-      if( nArg==2 ) azArg[1] = azArg[2];
++    for(ii=1; ii<nArg; ii++){
++      if( optionMatch(azArg[ii],"indent") ){
++        data.cMode = data.mode = MODE_Pretty;
++      }else if( optionMatch(azArg[ii],"debug") ){
++        bDebug = 1;
++      }else if( zName==0 ){
++        zName = azArg[ii];
++      }else{
++        raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
++        rc = 1;
++        goto meta_command_exit;
++      }
+     }
+-    if( nArg==2 && azArg[1][0]!='-' ){
+-      int i;
+-      for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
+-      if( strcmp(azArg[1],"sqlite_master")==0 ){
++    if( zName!=0 ){
++      int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0;
++      if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){
+         char *new_argv[2], *new_colv[2];
+-        new_argv[0] = "CREATE TABLE sqlite_master (\n"
++        new_argv[0] = sqlite3_mprintf(
++                      "CREATE TABLE %s (\n"
+                       "  type text,\n"
+                       "  name text,\n"
+                       "  tbl_name text,\n"
+                       "  rootpage integer,\n"
+                       "  sql text\n"
+-                      ")";
++                      ")", isMaster ? "sqlite_master" : "sqlite_temp_master");
+         new_argv[1] = 0;
+         new_colv[0] = "sql";
+         new_colv[1] = 0;
+         callback(&data, 1, new_argv, new_colv);
+-        rc = SQLITE_OK;
+-      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
+-        char *new_argv[2], *new_colv[2];
+-        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
+-                      "  type text,\n"
+-                      "  name text,\n"
+-                      "  tbl_name text,\n"
+-                      "  rootpage integer,\n"
+-                      "  sql text\n"
+-                      ")";
+-        new_argv[1] = 0;
+-        new_colv[0] = "sql";
+-        new_colv[1] = 0;
+-        callback(&data, 1, new_argv, new_colv);
+-        rc = SQLITE_OK;
+-      }else{
+-        zDiv = "(";
++        sqlite3_free(new_argv[0]);
+       }
+-    }else if( nArg==1 ){
+-      zDiv = "(";
+-    }else{
+-      raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
+-      rc = 1;
+-      goto meta_command_exit;
+     }
+     if( zDiv ){
+       sqlite3_stmt *pStmt = 0;
+@@ -6571,39 +14499,53 @@
+         sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
+         appendText(&sSelect, zDiv, 0);
+         zDiv = " UNION ALL ";
+-        if( strcmp(zDb, "main")!=0 ){
+-          appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
++        appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
++        if( sqlite3_stricmp(zDb, "main")!=0 ){
+           appendText(&sSelect, zDb, '"');
+-          appendText(&sSelect, ") AS sql, type, tbl_name, name, rowid,", 0);
+-          appendText(&sSelect, zScNum, 0);
+-          appendText(&sSelect, " AS snum, ", 0);
+-          appendText(&sSelect, zDb, '\'');
+-          appendText(&sSelect, " AS sname FROM ", 0);
+-          appendText(&sSelect, zDb, '"');
+-          appendText(&sSelect, ".sqlite_master", 0);
+         }else{
+-          appendText(&sSelect, "SELECT sql, type, tbl_name, name, rowid, ", 0);
+-          appendText(&sSelect, zScNum, 0);
+-          appendText(&sSelect, " AS snum, 'main' AS sname FROM sqlite_master",0);
++          appendText(&sSelect, "NULL", 0);
+         }
++        appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
++        appendText(&sSelect, zScNum, 0);
++        appendText(&sSelect, " AS snum, ", 0);
++        appendText(&sSelect, zDb, '\'');
++        appendText(&sSelect, " AS sname FROM ", 0);
++        appendText(&sSelect, zDb, '"');
++        appendText(&sSelect, ".sqlite_master", 0);
+       }
+       sqlite3_finalize(pStmt);
++#ifdef SQLITE_INTROSPECTION_PRAGMAS
++      if( zName ){
++        appendText(&sSelect,
++           " UNION ALL SELECT shell_module_schema(name),"
++           " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0);
++      }
++#endif
+       appendText(&sSelect, ") WHERE ", 0);
+-      if( nArg>1 ){
+-        char *zQarg = sqlite3_mprintf("%Q", azArg[1]);
+-        if( strchr(azArg[1], '.') ){
++      if( zName ){
++        char *zQarg = sqlite3_mprintf("%Q", zName);
++        int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
++                    strchr(zName, '[') != 0;
++        if( strchr(zName, '.') ){
+           appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
+         }else{
+           appendText(&sSelect, "lower(tbl_name)", 0);
+         }
+-        appendText(&sSelect, strchr(azArg[1], '*') ? " GLOB " : " LIKE ", 0);
++        appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
+         appendText(&sSelect, zQarg, 0);
++        if( !bGlob ){
++          appendText(&sSelect, " ESCAPE '\\' ", 0);
++        }
+         appendText(&sSelect, " AND ", 0);
+         sqlite3_free(zQarg);
+       }
+       appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
+                            " ORDER BY snum, rowid", 0);
+-      rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
++      if( bDebug ){
++        utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
++      }else{
++        rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
++      }
+       freeText(&sSelect);
+     }
+     if( zErrMsg ){
+@@ -6816,7 +14758,7 @@
+     }else
+     /* If no command name matches, show a syntax error */
+     session_syntax_error:
+-    session_help(p);
++    showHelp(p->out, "session");
+   }else
+ #endif
+ 
+@@ -6997,7 +14939,7 @@
+           utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
+                       azArg[i], azArg[0]);
+           raw_printf(stderr, "Should be one of: --schema"
+-                             " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n");
++                             " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
+           rc = 1;
+           goto meta_command_exit;
+         }
+@@ -7008,7 +14950,7 @@
+       }else{
+         zLike = z;
+         bSeparate = 1;
+-        if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1;
++        if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
+       }
+     }
+     if( bSchema ){
+@@ -7075,11 +15017,12 @@
+     if( bDebug ){
+       utf8_printf(p->out, "%s\n", zSql);
+     }else{
+-      shell_exec(p->db, zSql, shell_callback, p, 0);
++      shell_exec(p, zSql, 0);
+     }
+     sqlite3_free(zSql);
+   }else
+ 
++#ifndef SQLITE_NOHAVE_SYSTEM
+   if( c=='s'
+    && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
+   ){
+@@ -7099,9 +15042,10 @@
+     sqlite3_free(zCmd);
+     if( x ) raw_printf(stderr, "System command returns %d\n", x);
+   }else
++#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
+ 
+   if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
+-    static const char *azBool[] = { "off", "on", "full", "unk" };
++    static const char *azBool[] = { "off", "on", "trigger", "full"};
+     int i;
+     if( nArg!=1 ){
+       raw_printf(stderr, "Usage: .show\n");
+@@ -7138,7 +15082,7 @@
+ 
+   if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
+     if( nArg==2 ){
+-      p->statsOn = booleanValue(azArg[1]);
++      p->statsOn = (u8)booleanValue(azArg[1]);
+     }else if( nArg==1 ){
+       display_stats(p->db, p, 0);
+     }else{
+@@ -7159,7 +15103,10 @@
+     initText(&s);
+     open_db(p, 0);
+     rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
+-    if( rc ) return shellDatabaseError(p->db);
++    if( rc ){
++      sqlite3_finalize(pStmt);
++      return shellDatabaseError(p->db);
++    }
+ 
+     if( nArg>2 && c=='i' ){
+       /* It is an historical accident that the .indexes command shows an error
+@@ -7167,6 +15114,7 @@
+       ** command does not. */
+       raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
+       rc = 1;
++      sqlite3_finalize(pStmt);
+       goto meta_command_exit;
+     }
+     for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
+@@ -7211,18 +15159,12 @@
+         char **azNew;
+         int n2 = nAlloc*2 + 10;
+         azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
+-        if( azNew==0 ){
+-          rc = shellNomemError();
+-          break;
+-        }
++        if( azNew==0 ) shell_out_of_memory();
+         nAlloc = n2;
+         azResult = azNew;
+       }
+       azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
+-      if( 0==azResult[nRow] ){
+-        rc = shellNomemError();
+-        break;
+-      }
++      if( 0==azResult[nRow] ) shell_out_of_memory();
+       nRow++;
+     }
+     if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
+@@ -7258,7 +15200,7 @@
+   /* Begin redirecting output to the file "testcase-out.txt" */
+   if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
+     output_reset(p);
+-    p->out = output_file_open("testcase-out.txt");
++    p->out = output_file_open("testcase-out.txt", 0);
+     if( p->out==0 ){
+       raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
+     }
+@@ -7270,50 +15212,78 @@
+   }else
+ 
+ #ifndef SQLITE_UNTESTABLE
+-  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
++  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
+     static const struct {
+        const char *zCtrlName;   /* Name of a test-control option */
+        int ctrlCode;            /* Integer code for that option */
++       const char *zUsage;      /* Usage notes */
+     } aCtrl[] = {
+-      { "prng_save",             SQLITE_TESTCTRL_PRNG_SAVE              },
+-      { "prng_restore",          SQLITE_TESTCTRL_PRNG_RESTORE           },
+-      { "prng_reset",            SQLITE_TESTCTRL_PRNG_RESET             },
+-      { "bitvec_test",           SQLITE_TESTCTRL_BITVEC_TEST            },
+-      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
+-      { "benign_malloc_hooks",   SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS    },
+-      { "pending_byte",          SQLITE_TESTCTRL_PENDING_BYTE           },
+-      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
+-      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
+-      { "reserve",               SQLITE_TESTCTRL_RESERVE                },
+-      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
+-      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
+-      { "scratchmalloc",         SQLITE_TESTCTRL_SCRATCHMALLOC          },
+-      { "byteorder",             SQLITE_TESTCTRL_BYTEORDER              },
+-      { "never_corrupt",         SQLITE_TESTCTRL_NEVER_CORRUPT          },
+-      { "imposter",              SQLITE_TESTCTRL_IMPOSTER               },
++      { "always",             SQLITE_TESTCTRL_ALWAYS,        "BOOLEAN"            },
++      { "assert",             SQLITE_TESTCTRL_ASSERT,        "BOOLEAN"            },
++    /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, ""          },*/
++    /*{ "bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST,   ""                },*/
++      { "byteorder",          SQLITE_TESTCTRL_BYTEORDER,     ""                   },
++    /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, ""                }, */
++      { "imposter",           SQLITE_TESTCTRL_IMPOSTER,   "SCHEMA ON/OFF ROOTPAGE"},
++      { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN"       },
++      { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN"           },
++      { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN"            },
++      { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK"       },
++#ifdef YYCOVERAGE
++      { "parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE, ""                 },
++#endif
++      { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,  "OFFSET  "           },
++      { "prng_reset",         SQLITE_TESTCTRL_PRNG_RESET,    ""                   },
++      { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""                   },
++      { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""                   },
++      { "reserve",            SQLITE_TESTCTRL_RESERVE,       "BYTES-OF-RESERVE"   },
+     };
+     int testctrl = -1;
+-    int rc2 = 0;
++    int iCtrl = -1;
++    int rc2 = 0;    /* 0: usage.  1: %d  2: %x  3: no-output */
++    int isOk = 0;
+     int i, n2;
++    const char *zCmd = 0;
++
+     open_db(p, 0);
++    zCmd = nArg>=2 ? azArg[1] : "help";
+ 
++    /* The argument can optionally begin with "-" or "--" */
++    if( zCmd[0]=='-' && zCmd[1] ){
++      zCmd++;
++      if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
++    }
++
++    /* --help lists all test-controls */
++    if( strcmp(zCmd,"help")==0 ){
++      utf8_printf(p->out, "Available test-controls:\n");
++      for(i=0; i<ArraySize(aCtrl); i++){
++        utf8_printf(p->out, "  .testctrl %s %s\n",
++                    aCtrl[i].zCtrlName, aCtrl[i].zUsage);
++      }
++      rc = 1;
++      goto meta_command_exit;
++    }
++
+     /* convert testctrl text option to value. allow any unique prefix
+     ** of the option name, or a numerical value. */
+-    n2 = strlen30(azArg[1]);
++    n2 = strlen30(zCmd);
+     for(i=0; i<ArraySize(aCtrl); i++){
+-      if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
++      if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
+         if( testctrl<0 ){
+           testctrl = aCtrl[i].ctrlCode;
++          iCtrl = i;
+         }else{
+-          utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
+-          testctrl = -1;
+-          break;
++          utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
++                              "Use \".testctrl --help\" for help\n", zCmd);
++          rc = 1;
++          goto meta_command_exit;
+         }
+       }
+     }
+-    if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
+-    if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
+-      utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
++    if( testctrl<0 ){
++      utf8_printf(stderr,"Error: unknown test-control: %s\n"
++                         "Use \".testctrl --help\" for help\n", zCmd);
+     }else{
+       switch(testctrl){
+ 
+@@ -7323,10 +15293,7 @@
+           if( nArg==3 ){
+             int opt = (int)strtol(azArg[2], 0, 0);
+             rc2 = sqlite3_test_control(testctrl, p->db, opt);
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          } else {
+-            utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
+-                    azArg[1]);
++            isOk = 3;
+           }
+           break;
+ 
+@@ -7337,10 +15304,7 @@
+         case SQLITE_TESTCTRL_BYTEORDER:
+           if( nArg==2 ){
+             rc2 = sqlite3_test_control(testctrl);
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          } else {
+-            utf8_printf(stderr,"Error: testctrl %s takes no options\n",
+-                        azArg[1]);
++            isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
+           }
+           break;
+ 
+@@ -7349,10 +15313,7 @@
+           if( nArg==3 ){
+             unsigned int opt = (unsigned int)integerValue(azArg[2]);
+             rc2 = sqlite3_test_control(testctrl, opt);
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          } else {
+-            utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
+-                           " int option\n", azArg[1]);
++            isOk = 3;
+           }
+           break;
+ 
+@@ -7359,31 +15320,23 @@
+         /* sqlite3_test_control(int, int) */
+         case SQLITE_TESTCTRL_ASSERT:
+         case SQLITE_TESTCTRL_ALWAYS:
+-        case SQLITE_TESTCTRL_NEVER_CORRUPT:
++        case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
+           if( nArg==3 ){
+             int opt = booleanValue(azArg[2]);
+             rc2 = sqlite3_test_control(testctrl, opt);
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          } else {
+-            utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
+-                            azArg[1]);
++            isOk = 1;
+           }
+           break;
+ 
+-        /* sqlite3_test_control(int, char *) */
+-#ifdef SQLITE_N_KEYWORD
+-        case SQLITE_TESTCTRL_ISKEYWORD:
++        /* sqlite3_test_control(int, int) */
++        case SQLITE_TESTCTRL_LOCALTIME_FAULT:
++        case SQLITE_TESTCTRL_NEVER_CORRUPT:
+           if( nArg==3 ){
+-            const char *opt = azArg[2];
++            int opt = booleanValue(azArg[2]);
+             rc2 = sqlite3_test_control(testctrl, opt);
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          } else {
+-            utf8_printf(stderr,
+-                        "Error: testctrl %s takes a single char * option\n",
+-                        azArg[1]);
++            isOk = 3;
+           }
+           break;
+-#endif
+ 
+         case SQLITE_TESTCTRL_IMPOSTER:
+           if( nArg==5 ){
+@@ -7391,23 +15344,27 @@
+                           azArg[2],
+                           integerValue(azArg[3]),
+                           integerValue(azArg[4]));
+-            raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
+-          }else{
+-            raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
++            isOk = 3;
+           }
+           break;
+ 
+-        case SQLITE_TESTCTRL_BITVEC_TEST:
+-        case SQLITE_TESTCTRL_FAULT_INSTALL:
+-        case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
+-        case SQLITE_TESTCTRL_SCRATCHMALLOC:
+-        default:
+-          utf8_printf(stderr,
+-                      "Error: CLI support for testctrl %s not implemented\n",
+-                      azArg[1]);
+-          break;
++#ifdef YYCOVERAGE
++        case SQLITE_TESTCTRL_PARSER_COVERAGE:
++          if( nArg==2 ){
++            sqlite3_test_control(testctrl, p->out);
++            isOk = 3;
++          }
++#endif
+       }
+     }
++    if( isOk==0 && iCtrl>=0 ){
++      utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage);
++      rc = 1;
++    }else if( isOk==1 ){
++      raw_printf(p->out, "%d\n", rc2);
++    }else if( isOk==2 ){
++      raw_printf(p->out, "0x%08x\n", rc2);
++    }
+   }else
+ #endif /* !defined(SQLITE_UNTESTABLE) */
+ 
+@@ -7437,7 +15394,7 @@
+       goto meta_command_exit;
+     }
+     output_file_close(p->traceOut);
+-    p->traceOut = output_file_open(azArg[1]);
++    p->traceOut = output_file_open(azArg[1], 0);
+ #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
+     if( p->traceOut==0 ){
+       sqlite3_trace_v2(p->db, 0, 0, 0);
+@@ -7461,8 +15418,7 @@
+         rc = 1;
+         goto meta_command_exit;
+       }
+-      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
+-                                    (int)strlen(azArg[3]));
++      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3]));
+       if( rc ){
+         utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
+         rc = 1;
+@@ -7473,8 +15429,7 @@
+         rc = 1;
+         goto meta_command_exit;
+       }
+-      rc = sqlite3_user_add(p->db, azArg[2],
+-                            azArg[3], (int)strlen(azArg[3]),
++      rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
+                             booleanValue(azArg[4]));
+       if( rc ){
+         raw_printf(stderr, "User-Add failed: %d\n", rc);
+@@ -7486,8 +15441,7 @@
+         rc = 1;
+         goto meta_command_exit;
+       }
+-      rc = sqlite3_user_change(p->db, azArg[2],
+-                              azArg[3], (int)strlen(azArg[3]),
++      rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
+                               booleanValue(azArg[4]));
+       if( rc ){
+         raw_printf(stderr, "User-Edit failed: %d\n", rc);
+@@ -7515,6 +15469,20 @@
+   if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
+     utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
+         sqlite3_libversion(), sqlite3_sourceid());
++#if SQLITE_HAVE_ZLIB
++    utf8_printf(p->out, "zlib version %s\n", zlibVersion());
++#endif
++#define CTIMEOPT_VAL_(opt) #opt
++#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
++#if defined(__clang__) && defined(__clang_major__)
++    utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
++                    CTIMEOPT_VAL(__clang_minor__) "."
++                    CTIMEOPT_VAL(__clang_patchlevel__) "\n");
++#elif defined(_MSC_VER)
++    utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
++#elif defined(__GNUC__) && defined(__VERSION__)
++    utf8_printf(p->out, "gcc-" __VERSION__ "\n");
++#endif
+   }else
+ 
+   if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
+@@ -7641,6 +15609,16 @@
+ }
+ 
+ /*
++** We need a default sqlite3_complete() implementation to use in case
++** the shell is compiled with SQLITE_OMIT_COMPLETE.  The default assumes
++** any arbitrary text is a complete SQL statement.  This is not very
++** user-friendly, but it does seem to work.
++*/
++#ifdef SQLITE_OMIT_COMPLETE
++#define sqlite3_complete(x) 1
++#endif
++
++/*
+ ** Return true if zSql is a complete SQL statement.  Return false if it
+ ** ends in the middle of a string literal or C-style comment.
+ */
+@@ -7655,7 +15633,7 @@
+ }
+ 
+ /*
+-** Run a single line of SQL
++** Run a single line of SQL.  Return the number of errors.
+ */
+ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
+   int rc;
+@@ -7664,7 +15642,7 @@
+   open_db(p, 0);
+   if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
+   BEGIN_TIMER;
+-  rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
++  rc = shell_exec(p, zSql, &zErrMsg);
+   END_TIMER;
+   if( rc || zErrMsg ){
+     char zPrefix[100];
+@@ -7728,13 +15706,15 @@
+       if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+       continue;
+     }
+-    if( zLine && zLine[0]=='.' && nSql==0 ){
++    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
+       if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+-      rc = do_meta_command(zLine, p);
+-      if( rc==2 ){ /* exit requested */
+-        break;
+-      }else if( rc ){
+-        errCnt++;
++      if( zLine[0]=='.' ){
++        rc = do_meta_command(zLine, p);
++        if( rc==2 ){ /* exit requested */
++          break;
++        }else if( rc ){
++          errCnt++;
++        }
+       }
+       continue;
+     }
+@@ -7745,10 +15725,7 @@
+     if( nSql+nLine+2>=nAlloc ){
+       nAlloc = nSql+nLine+100;
+       zSql = realloc(zSql, nAlloc);
+-      if( zSql==0 ){
+-        raw_printf(stderr, "Error: out of memory\n");
+-        exit(1);
+-      }
++      if( zSql==0 ) shell_out_of_memory();
+     }
+     nSqlPrior = nSql;
+     if( nSql==0 ){
+@@ -7770,6 +15747,8 @@
+       if( p->outCount ){
+         output_reset(p);
+         p->outCount = 0;
++      }else{
++        clearTempFile(p);
+       }
+     }else if( nSql && _all_whitespace(zSql) ){
+       if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
+@@ -7777,7 +15756,7 @@
+     }
+   }
+   if( nSql && !_all_whitespace(zSql) ){
+-    runOneSqlLine(p, zSql, in, startline);
++    errCnt += runOneSqlLine(p, zSql, in, startline);
+   }
+   free(zSql);
+   free(zLine);
+@@ -7875,7 +15854,6 @@
+                       " cannot read ~/.sqliterc\n");
+       return;
+     }
+-    sqlite3_initialize();
+     zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
+     sqliterc = zBuf;
+   }
+@@ -7894,6 +15872,10 @@
+ ** Show available command line options
+ */
+ static const char zOptions[] =
++#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
++  "   -A ARGS...           run \".archive ARGS\" and exit\n"
++#endif
++  "   -append              append the database to the end of the file\n"
+   "   -ascii               set output mode to 'ascii'\n"
+   "   -bail                stop after hitting an error\n"
+   "   -batch               force batch I/O\n"
+@@ -7920,8 +15902,11 @@
+   "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
+   "   -pagecache SIZE N    use N slots of SZ bytes each for page cache memory\n"
+   "   -quote               set output mode to 'quote'\n"
+-  "   -scratch SIZE N      use N slots of SZ bytes each for scratch memory\n"
++  "   -readonly            open the database read-only\n"
+   "   -separator SEP       set output column separator. Default: '|'\n"
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  "   -sorterref SIZE      sorter references threshold size\n"
++#endif
+   "   -stats               print memory stats before each finalize\n"
+   "   -version             show SQLite version\n"
+   "   -vfs NAME            use NAME as the default VFS\n"
+@@ -7928,6 +15913,9 @@
+ #ifdef SQLITE_ENABLE_VFSTRACE
+   "   -vfstrace            enable tracing of all VFS calls\n"
+ #endif
++#ifdef SQLITE_HAVE_ZLIB
++  "   -zip                 open the file as a ZIP Archive\n"
++#endif
+ ;
+ static void usage(int showDetail){
+   utf8_printf(stderr,
+@@ -7943,6 +15931,17 @@
+ }
+ 
+ /*
++** Internal check:  Verify that the SQLite is uninitialized.  Print a
++** error message if it is initialized.
++*/
++static void verify_uninitialized(void){
++  if( sqlite3_config(-1)==SQLITE_MISUSE ){
++    utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
++                        " initialization.\n");
++  }
++}
++
++/*
+ ** Initialize the state information in data
+ */
+ static void main_init(ShellState *data) {
+@@ -7953,6 +15952,7 @@
+   memcpy(data->rowSeparator,SEP_Row, 2);
+   data->showHeader = 0;
+   data->shellFlgs = SHFLG_Lookaside;
++  verify_uninitialized();
+   sqlite3_config(SQLITE_CONFIG_URI, 1);
+   sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
+   sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
+@@ -8016,6 +16016,11 @@
+   int readStdin = 1;
+   int nCmd = 0;
+   char **azCmd = 0;
++  const char *zVfs = 0;           /* Value of -vfs command-line option */
++#if !SQLITE_SHELL_IS_UTF8
++  char **argvToFree = 0;
++  int argcToFree = 0;
++#endif
+ 
+   setBinaryMode(stdin, 0);
+   setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+@@ -8022,8 +16027,25 @@
+   stdin_is_interactive = isatty(0);
+   stdout_is_console = isatty(1);
+ 
++#if !defined(_WIN32_WCE)
++  if( getenv("SQLITE_DEBUG_BREAK") ){
++    if( isatty(0) && isatty(2) ){
++      fprintf(stderr,
++          "attach debugger to process %d and press any key to continue.\n",
++          GETPID());
++      fgetc(stdin);
++    }else{
++#if defined(_WIN32) || defined(WIN32)
++      DebugBreak();
++#elif defined(SIGTRAP)
++      raise(SIGTRAP);
++#endif
++    }
++  }
++#endif
++
+ #if USE_SYSTEM_SQLITE+0!=1
+-  if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
++  if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
+     utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
+             sqlite3_sourceid(), SQLITE_SOURCE_ID);
+     exit(1);
+@@ -8030,21 +16052,33 @@
+   }
+ #endif
+   main_init(&data);
++
++  /* On Windows, we must translate command-line arguments into UTF-8.
++  ** The SQLite memory allocator subsystem has to be enabled in order to
++  ** do this.  But we want to run an sqlite3_shutdown() afterwards so that
++  ** subsequent sqlite3_config() calls will work.  So copy all results into
++  ** memory that does not come from the SQLite memory allocator.
++  */
+ #if !SQLITE_SHELL_IS_UTF8
+   sqlite3_initialize();
+-  argv = sqlite3_malloc64(sizeof(argv[0])*argc);
+-  if( argv==0 ){
+-    raw_printf(stderr, "out of memory\n");
+-    exit(1);
+-  }
++  argvToFree = malloc(sizeof(argv[0])*argc*2);
++  argcToFree = argc;
++  argv = argvToFree + argc;
++  if( argv==0 ) shell_out_of_memory();
+   for(i=0; i<argc; i++){
+-    argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
+-    if( argv[i]==0 ){
+-      raw_printf(stderr, "out of memory\n");
+-      exit(1);
+-    }
++    char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
++    int n;
++    if( z==0 ) shell_out_of_memory();
++    n = (int)strlen(z);
++    argv[i] = malloc( n+1 );
++    if( argv[i]==0 ) shell_out_of_memory();
++    memcpy(argv[i], z, n+1);
++    argvToFree[i] = argv[i];
++    sqlite3_free(z);
+   }
++  sqlite3_shutdown();
+ #endif
++
+   assert( argc>=1 && argv && argv[0] );
+   Argv0 = argv[0];
+ 
+@@ -8053,6 +16087,8 @@
+   */
+ #ifdef SIGINT
+   signal(SIGINT, interrupt_handler);
++#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
++  SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
+ #endif
+ 
+ #ifdef SQLITE_SHELL_DBNAME_PROC
+@@ -8072,6 +16108,7 @@
+   ** the size of the alternative malloc heap,
+   ** and the first command to execute.
+   */
++  verify_uninitialized();
+   for(i=1; i<argc; i++){
+     char *z;
+     z = argv[i];
+@@ -8084,10 +16121,7 @@
+         readStdin = 0;
+         nCmd++;
+         azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
+-        if( azCmd==0 ){
+-          raw_printf(stderr, "out of memory\n");
+-          exit(1);
+-        }
++        if( azCmd==0 ) shell_out_of_memory();
+         azCmd[nCmd-1] = z;
+       }
+     }
+@@ -8118,16 +16152,6 @@
+ #else
+       (void)cmdline_option_value(argc, argv, ++i);
+ #endif
+-    }else if( strcmp(z,"-scratch")==0 ){
+-      int n, sz;
+-      sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
+-      if( sz>400000 ) sz = 400000;
+-      if( sz<2500 ) sz = 2500;
+-      n = (int)integerValue(cmdline_option_value(argc,argv,++i));
+-      if( n>10 ) n = 10;
+-      if( n<1 ) n = 1;
+-      sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
+-      data.shellFlgs |= SHFLG_Scratch;
+     }else if( strcmp(z,"-pagecache")==0 ){
+       int n, sz;
+       sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
+@@ -8164,16 +16188,61 @@
+     }else if( strcmp(z,"-mmap")==0 ){
+       sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+       sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    }else if( strcmp(z,"-sorterref")==0 ){
++      sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
++      sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
++#endif
+     }else if( strcmp(z,"-vfs")==0 ){
+-      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
+-      if( pVfs ){
+-        sqlite3_vfs_register(pVfs, 1);
+-      }else{
+-        utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
+-        exit(1);
+-      }
++      zVfs = cmdline_option_value(argc, argv, ++i);
++#ifdef SQLITE_HAVE_ZLIB
++    }else if( strcmp(z,"-zip")==0 ){
++      data.openMode = SHELL_OPEN_ZIPFILE;
++#endif
++    }else if( strcmp(z,"-append")==0 ){
++      data.openMode = SHELL_OPEN_APPENDVFS;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    }else if( strcmp(z,"-deserialize")==0 ){
++      data.openMode = SHELL_OPEN_DESERIALIZE;
++#endif
++    }else if( strcmp(z,"-readonly")==0 ){
++      data.openMode = SHELL_OPEN_READONLY;
++#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
++    }else if( strncmp(z, "-A",2)==0 ){
++      /* All remaining command-line arguments are passed to the ".archive"
++      ** command, so ignore them */
++      break;
++#endif
+     }
+   }
++  verify_uninitialized();
++
++
++#ifdef SQLITE_SHELL_INIT_PROC
++  {
++    /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
++    ** of a C-function that will perform initialization actions on SQLite that
++    ** occur just before or after sqlite3_initialize(). Use this compile-time
++    ** option to embed this shell program in larger applications. */
++    extern void SQLITE_SHELL_INIT_PROC(void);
++    SQLITE_SHELL_INIT_PROC();
++  }
++#else
++  /* All the sqlite3_config() calls have now been made. So it is safe
++  ** to call sqlite3_initialize() and process any command line -vfs option. */
++  sqlite3_initialize();
++#endif
++
++  if( zVfs ){
++    sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
++    if( pVfs ){
++      sqlite3_vfs_register(pVfs, 1);
++    }else{
++      utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
++      exit(1);
++    }
++  }
++
+   if( data.zDbFilename==0 ){
+ #ifndef SQLITE_OMIT_MEMORYDB
+     data.zDbFilename = ":memory:";
+@@ -8184,6 +16253,7 @@
+ #endif
+   }
+   data.out = stdout;
++  sqlite3_appendvfs_init(0,0,0);
+ 
+   /* Go ahead and open the database file if it already exists.  If the
+   ** file does not exist, delay opening it.  This prevents empty database
+@@ -8224,6 +16294,18 @@
+     }else if( strcmp(z,"-csv")==0 ){
+       data.mode = MODE_Csv;
+       memcpy(data.colSeparator,",",2);
++#ifdef SQLITE_HAVE_ZLIB
++    }else if( strcmp(z,"-zip")==0 ){
++      data.openMode = SHELL_OPEN_ZIPFILE;
++#endif
++    }else if( strcmp(z,"-append")==0 ){
++      data.openMode = SHELL_OPEN_APPENDVFS;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    }else if( strcmp(z,"-deserialize")==0 ){
++      data.openMode = SHELL_OPEN_DESERIALIZE;
++#endif
++    }else if( strcmp(z,"-readonly")==0 ){
++      data.openMode = SHELL_OPEN_READONLY;
+     }else if( strcmp(z,"-ascii")==0 ){
+       data.mode = MODE_Ascii;
+       sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
+@@ -8246,9 +16328,9 @@
+     }else if( strcmp(z,"-echo")==0 ){
+       ShellSetFlag(&data, SHFLG_Echo);
+     }else if( strcmp(z,"-eqp")==0 ){
+-      data.autoEQP = 1;
++      data.autoEQP = AUTOEQP_on;
+     }else if( strcmp(z,"-eqpfull")==0 ){
+-      data.autoEQP = 2;
++      data.autoEQP = AUTOEQP_full;
+     }else if( strcmp(z,"-stats")==0 ){
+       data.statsOn = 1;
+     }else if( strcmp(z,"-scanstats")==0 ){
+@@ -8271,8 +16353,6 @@
+       stdin_is_interactive = 0;
+     }else if( strcmp(z,"-heap")==0 ){
+       i++;
+-    }else if( strcmp(z,"-scratch")==0 ){
+-      i+=2;
+     }else if( strcmp(z,"-pagecache")==0 ){
+       i+=2;
+     }else if( strcmp(z,"-lookaside")==0 ){
+@@ -8279,6 +16359,10 @@
+       i+=2;
+     }else if( strcmp(z,"-mmap")==0 ){
+       i++;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    }else if( strcmp(z,"-sorterref")==0 ){
++      i++;
++#endif
+     }else if( strcmp(z,"-vfs")==0 ){
+       i++;
+ #ifdef SQLITE_ENABLE_VFSTRACE
+@@ -8303,7 +16387,7 @@
+         if( rc && bail_on_error ) return rc==2 ? 0 : rc;
+       }else{
+         open_db(&data, 0);
+-        rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
++        rc = shell_exec(&data, z, &zErrMsg);
+         if( zErrMsg!=0 ){
+           utf8_printf(stderr,"Error: %s\n", zErrMsg);
+           if( bail_on_error ) return rc!=0 ? rc : 1;
+@@ -8312,6 +16396,23 @@
+           if( bail_on_error ) return rc;
+         }
+       }
++#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
++    }else if( strncmp(z, "-A", 2)==0 ){
++      if( nCmd>0 ){
++        utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
++                            " with \"%s\"\n", z);
++        return 1;
++      }
++      open_db(&data, OPEN_DB_ZIPFILE);
++      if( z[2] ){
++        argv[i] = &z[2];
++        arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
++      }else{
++        arDotCommand(&data, 1, argv+i, argc-i);
++      }
++      readStdin = 0;
++      break;
++#endif
+     }else{
+       utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
+       raw_printf(stderr,"Use -help for a list of options.\n");
+@@ -8331,7 +16432,7 @@
+         if( rc ) return rc==2 ? 0 : rc;
+       }else{
+         open_db(&data, 0);
+-        rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
++        rc = shell_exec(&data, azCmd[i], &zErrMsg);
+         if( zErrMsg!=0 ){
+           utf8_printf(stderr,"Error: %s\n", zErrMsg);
+           return rc!=0 ? rc : 1;
+@@ -8347,7 +16448,7 @@
+     */
+     if( stdin_is_interactive ){
+       char *zHome;
+-      char *zHistory = 0;
++      char *zHistory;
+       int nHistory;
+       printf(
+         "SQLite version %s %.19s\n" /*extra-version-info*/
+@@ -8360,8 +16461,10 @@
+         printf(".\nUse \".open FILENAME\" to reopen on a "
+                "persistent database.\n");
+       }
+-      zHome = find_home_dir(0);
+-      if( zHome ){
++      zHistory = getenv("SQLITE_HISTORY");
++      if( zHistory ){
++        zHistory = strdup(zHistory);
++      }else if( (zHome = find_home_dir(0))!=0 ){
+         nHistory = strlen30(zHome) + 20;
+         if( (zHistory = malloc(nHistory))!=0 ){
+           sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+@@ -8386,13 +16489,19 @@
+   set_table_name(&data, 0);
+   if( data.db ){
+     session_close_all(&data);
+-    sqlite3_close(data.db);
++    close_db(data.db);
+   }
+   sqlite3_free(data.zFreeOnClose);
+   find_home_dir(1);
++  output_reset(&data);
++  data.doXdgOpen = 0;
++  clearTempFile(&data);
+ #if !SQLITE_SHELL_IS_UTF8
+-  for(i=0; i<argc; i++) sqlite3_free(argv[i]);
+-  sqlite3_free(argv);
++  for(i=0; i<argcToFree; i++) free(argvToFree[i]);
++  free(argvToFree);
+ #endif
++  /* Clear the global data structure so that valgrind will detect memory
++  ** leaks */
++  memset(&data, 0, sizeof(data));
+   return rc;
+ }
+--- contrib/sqlite3/sqlite3.c.orig
++++ contrib/sqlite3/sqlite3.c
+@@ -1,6 +1,6 @@
+ /******************************************************************************
+ ** This file is an amalgamation of many separate C source files from SQLite
+-** version 3.20.0.  By combining all the individual C code files into this
++** version 3.26.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
+@@ -55,6 +55,12 @@
+ #define CTIMEOPT_VAL_(opt) #opt
+ #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+ 
++/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This
++** option requires a separate macro because legal values contain a single
++** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */
++#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2
++#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt)
++
+ /*
+ ** An array of names of all compile-time options.  This array should 
+ ** be sorted A-Z.
+@@ -138,7 +144,7 @@
+   "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
+ #endif
+ #ifdef SQLITE_DEFAULT_LOOKASIDE
+-  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE),
++  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
+ #endif
+ #if SQLITE_DEFAULT_MEMSTATUS
+   "DEFAULT_MEMSTATUS",
+@@ -209,8 +215,11 @@
+ #if SQLITE_ENABLE_ATOMIC_WRITE
+   "ENABLE_ATOMIC_WRITE",
+ #endif
++#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++  "ENABLE_BATCH_ATOMIC_WRITE",
++#endif
+ #if SQLITE_ENABLE_CEROD
+-  "ENABLE_CEROD",
++  "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
+ #endif
+ #if SQLITE_ENABLE_COLUMN_METADATA
+   "ENABLE_COLUMN_METADATA",
+@@ -251,6 +260,9 @@
+ #if SQLITE_ENABLE_FTS5
+   "ENABLE_FTS5",
+ #endif
++#if SQLITE_ENABLE_GEOPOLY
++  "ENABLE_GEOPOLY",
++#endif
+ #if SQLITE_ENABLE_HIDDEN_COLUMNS
+   "ENABLE_HIDDEN_COLUMNS",
+ #endif
+@@ -281,6 +293,9 @@
+ #if SQLITE_ENABLE_MULTIPLEX
+   "ENABLE_MULTIPLEX",
+ #endif
++#if SQLITE_ENABLE_NORMALIZE
++  "ENABLE_NORMALIZE",
++#endif
+ #if SQLITE_ENABLE_NULL_TRIM
+   "ENABLE_NULL_TRIM",
+ #endif
+@@ -308,6 +323,9 @@
+ #if SQLITE_ENABLE_SNAPSHOT
+   "ENABLE_SNAPSHOT",
+ #endif
++#if SQLITE_ENABLE_SORTER_REFERENCES
++  "ENABLE_SORTER_REFERENCES",
++#endif
+ #if SQLITE_ENABLE_SQLLOG
+   "ENABLE_SQLLOG",
+ #endif
+@@ -828,14 +846,6 @@
+ #endif
+ 
+ /*
+-** Make sure that rand_s() is available on Windows systems with MSVC 2005
+-** or higher.
+-*/
+-#if defined(_MSC_VER) && _MSC_VER>=1400
+-#  define _CRT_RAND_S
+-#endif
+-
+-/*
+ ** Include the header file used to customize the compiler options for MSVC.
+ ** This should be done first so that it can successfully prevent spurious
+ ** compiler warnings due to subsequent content in this file and other files
+@@ -1144,15 +1154,17 @@
+ ** 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 a SHA1
+-** or SHA3-256 hash of the entire source tree.
++** or SHA3-256 hash of the entire source tree.  If the source code has
++** been edited in any way since it was last checked in, then the last
++** four hexadecimal digits of the hash may be modified.
+ **
+ ** See also: [sqlite3_libversion()],
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.20.0"
+-#define SQLITE_VERSION_NUMBER 3020000
+-#define SQLITE_SOURCE_ID      "2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8"
++#define SQLITE_VERSION        "3.26.0"
++#define SQLITE_VERSION_NUMBER 3026000
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+@@ -1168,7 +1180,7 @@
+ **
+ ** <blockquote><pre>
+ ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
++** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+ ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+ ** </pre></blockquote>)^
+ **
+@@ -1178,9 +1190,11 @@
+ ** function is provided for use in DLLs since DLL users usually do not have
+ ** direct access to string constants within the DLL.  ^The
+ ** sqlite3_libversion_number() function returns an integer equal to
+-** [SQLITE_VERSION_NUMBER].  ^The sqlite3_sourceid() function returns 
++** [SQLITE_VERSION_NUMBER].  ^(The sqlite3_sourceid() function returns 
+ ** a pointer to a string constant whose value is the same as the 
+-** [SQLITE_SOURCE_ID] C preprocessor macro.
++** [SQLITE_SOURCE_ID] C preprocessor macro.  Except if SQLite is built
++** using an edited copy of [the amalgamation], then the last four characters
++** of the hash might be different from [SQLITE_SOURCE_ID].)^
+ **
+ ** See also: [sqlite_version()] and [sqlite_source_id()].
+ */
+@@ -1461,7 +1475,7 @@
+ #define SQLITE_FULL        13   /* Insertion failed because database is full */
+ #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
+ #define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+-#define SQLITE_EMPTY       16   /* Not used */
++#define SQLITE_EMPTY       16   /* Internal use only */
+ #define SQLITE_SCHEMA      17   /* The database schema changed */
+ #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
+ #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
+@@ -1495,6 +1509,9 @@
+ ** the most recent error can be obtained using
+ ** [sqlite3_extended_errcode()].
+ */
++#define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
++#define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
++#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+ #define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+ #define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+ #define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+@@ -1523,7 +1540,11 @@
+ #define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
+ #define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
+ #define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
++#define SQLITE_IOERR_BEGIN_ATOMIC      (SQLITE_IOERR | (29<<8))
++#define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
++#define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
++#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+ #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+@@ -1530,11 +1551,15 @@
+ #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
+ #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+ #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
++#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+ #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
++#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
+ #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
+ #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+ #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+ #define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
++#define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
++#define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
+ #define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
+ #define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
+ #define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
+@@ -1609,6 +1634,11 @@
+ ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+ ** read-only media and cannot be changed even by processes with
+ ** elevated privileges.
++**
++** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
++** filesystem supports doing multiple write operations atomically when those
++** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
++** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+ */
+ #define SQLITE_IOCAP_ATOMIC                 0x00000001
+ #define SQLITE_IOCAP_ATOMIC512              0x00000002
+@@ -1624,6 +1654,7 @@
+ #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
+ #define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
+ #define SQLITE_IOCAP_IMMUTABLE              0x00002000
++#define SQLITE_IOCAP_BATCH_ATOMIC           0x00004000
+ 
+ /*
+ ** CAPI3REF: File Locking Levels
+@@ -1758,6 +1789,7 @@
+ ** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+ ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+ ** <li> [SQLITE_IOCAP_IMMUTABLE]
++** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
+ ** </ul>
+ **
+ ** The SQLITE_IOCAP_ATOMIC property means that all writes of
+@@ -1895,7 +1927,8 @@
+ ** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
+ ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+ ** persistent [WAL | Write Ahead Log] setting.  By default, the auxiliary
+-** write ahead log and shared memory files used for transaction control
++** write ahead log ([WAL file]) and shared memory
++** files used for transaction control
+ ** are automatically deleted when the latest connection to the database
+ ** closes.  Setting persistent WAL mode causes those files to persist after
+ ** close.  Persisting the files is useful when other processes that do not
+@@ -2041,6 +2074,66 @@
+ ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
+ ** the RBU extension only.  All other VFS should return SQLITE_NOTFOUND for
+ ** this opcode.  
++**
++** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
++** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
++** the file descriptor is placed in "batch write mode", which
++** means all subsequent write operations will be deferred and done
++** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].  Systems
++** that do not support batch atomic writes will return SQLITE_NOTFOUND.
++** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
++** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
++** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
++** no VFS interface calls on the same [sqlite3_file] file descriptor
++** except for calls to the xWrite method and the xFileControl method
++** with [SQLITE_FCNTL_SIZE_HINT].
++**
++** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
++** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
++** operations since the previous successful call to 
++** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
++** This file control returns [SQLITE_OK] if and only if the writes were
++** all performed successfully and have been committed to persistent storage.
++** ^Regardless of whether or not it is successful, this file control takes
++** the file descriptor out of batch write mode so that all subsequent
++** write operations are independent.
++** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
++** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
++**
++** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
++** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
++** operations since the previous successful call to 
++** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
++** ^This file control takes the file descriptor out of batch write mode
++** so that all subsequent write operations are independent.
++** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
++** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
++**
++** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
++** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
++** a file lock using the xLock or xShmLock methods of the VFS to wait
++** for up to M milliseconds before failing, where M is the single 
++** unsigned integer parameter.
++**
++** <li>[[SQLITE_FCNTL_DATA_VERSION]]
++** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
++** a database file.  The argument is a pointer to a 32-bit unsigned integer.
++** The "data version" for the pager is written into the pointer.  The
++** "data version" changes whenever any change occurs to the corresponding
++** database file, either through SQL statements on the same database
++** connection or through transactions committed by separate database
++** connections possibly in other processes. The [sqlite3_total_changes()]
++** interface can be used to find if any database on the connection has changed,
++** but that interface responds to changes on TEMP as well as MAIN and does
++** not provide a mechanism to detect changes to MAIN only.  Also, the
++** [sqlite3_total_changes()] interface responds to internal changes only and
++** omits changes made by other database connections.  The
++** [PRAGMA data_version] command provide a mechanism to detect changes to
++** a single attached database that occur due to other database connections,
++** but omits changes implemented by the database connection on which it is
++** called.  This file control is the only mechanism to detect changes that
++** happen either internally or externally and that are associated with
++** a particular attached database.
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -2072,6 +2165,11 @@
+ #define SQLITE_FCNTL_JOURNAL_POINTER        28
+ #define SQLITE_FCNTL_WIN32_GET_HANDLE       29
+ #define SQLITE_FCNTL_PDB                    30
++#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
++#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
++#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
++#define SQLITE_FCNTL_LOCK_TIMEOUT           34
++#define SQLITE_FCNTL_DATA_VERSION           35
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -2109,12 +2207,18 @@
+ ** in the name of the object stands for "virtual file system".  See
+ ** the [VFS | VFS documentation] for further information.
+ **
+-** The value of the iVersion field is initially 1 but may be larger in
+-** future versions of SQLite.  Additional fields may be appended to this
+-** object when the iVersion value is increased.  Note that the structure
+-** of the sqlite3_vfs object changes in the transaction between
+-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
+-** modified.
++** The VFS interface is sometimes extended by adding new methods onto
++** the end.  Each time such an extension occurs, the iVersion field
++** is incremented.  The iVersion value started out as 1 in
++** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
++** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
++** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6].  Additional fields
++** may be appended to the sqlite3_vfs object and the iVersion value
++** may increase again in future versions of SQLite.
++** Note that the structure
++** of the sqlite3_vfs object changes in the transition from
++** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
++** and yet the iVersion field was not modified.
+ **
+ ** The szOsFile field is the size of the subclassed [sqlite3_file]
+ ** structure used by this VFS.  mxPathname is the maximum length of
+@@ -2642,6 +2746,16 @@
+ ** routines with a wrapper that simulations memory allocation failure or
+ ** tracks memory usage, for example. </dd>
+ **
++** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
++** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
++** type int, interpreted as a boolean, which if true provides a hint to
++** SQLite that it should avoid large memory allocations if possible.
++** SQLite will run faster if it is free to make large memory allocations,
++** but some application might prefer to run slower in exchange for
++** guarantees about memory fragmentation that are possible if large
++** allocations are avoided.  This hint is normally off.
++** </dd>
++**
+ ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
+ ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
+ ** interpreted as a boolean, which enables or disables the collection of
+@@ -2659,25 +2773,7 @@
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
+-** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+-** that SQLite can use for scratch memory.  ^(There are three arguments
+-** to SQLITE_CONFIG_SCRATCH:  A pointer an 8-byte
+-** aligned memory buffer from which the scratch allocations will be
+-** drawn, the size of each scratch allocation (sz),
+-** and the maximum number of scratch allocations (N).)^
+-** The first argument must be a pointer to an 8-byte aligned buffer
+-** of at least sz*N bytes of memory.
+-** ^SQLite will not use more than one scratch buffers per thread.
+-** ^SQLite will never request a scratch buffer that is more than 6
+-** times the database page size.
+-** ^If SQLite needs needs additional
+-** scratch memory beyond what is provided by this configuration option, then 
+-** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+-** ^When the application provides any amount of scratch memory using
+-** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+-** [sqlite3_malloc|heap allocations].
+-** This can help [Robson proof|prevent memory allocation failures] due to heap
+-** fragmentation in low-memory embedded systems.
++** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
+@@ -2713,8 +2809,7 @@
+ ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
+ ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+ ** that SQLite will use for all of its dynamic memory allocation needs
+-** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
+-** [SQLITE_CONFIG_PAGECACHE].
++** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
+ ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
+ ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
+ ** [SQLITE_ERROR] if invoked otherwise.
+@@ -2900,6 +2995,22 @@
+ ** I/O required to support statement rollback.
+ ** The default value for this setting is controlled by the
+ ** [SQLITE_STMTJRNL_SPILL] compile-time option.
++**
++** [[SQLITE_CONFIG_SORTERREF_SIZE]]
++** <dt>SQLITE_CONFIG_SORTERREF_SIZE
++** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
++** of type (int) - the new value of the sorter-reference size threshold.
++** Usually, when SQLite uses an external sort to order records according
++** to an ORDER BY clause, all fields required by the caller are present in the
++** sorted records. However, if SQLite determines based on the declared type
++** of a table column that its values are likely to be very large - larger
++** than the configured sorter-reference size threshold - then a reference
++** is stored in each sorted record and the required column values loaded
++** from the database as records are returned in sorted order. The default
++** value for this option is to never use this optimization. Specifying a 
++** negative value for this option restores the default behaviour.
++** This option is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -2907,7 +3018,7 @@
+ #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
+ #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
+ #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
+-#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
++#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
+ #define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
+ #define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
+ #define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
+@@ -2928,6 +3039,8 @@
+ #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+ #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
++#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
++#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -2943,6 +3056,7 @@
+ ** is invoked.
+ **
+ ** <dl>
++** [[SQLITE_DBCONFIG_LOOKASIDE]]
+ ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+ ** <dd> ^This option takes three additional arguments that determine the 
+ ** [lookaside memory allocator] configuration for the [database connection].
+@@ -2965,6 +3079,7 @@
+ ** memory is in use leaves the configuration unchanged and returns 
+ ** [SQLITE_BUSY].)^</dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
+ ** <dd> ^This option is used to enable or disable the enforcement of
+ ** [foreign key constraints].  There should be two additional arguments.
+@@ -2975,6 +3090,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the FK enforcement setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
+ ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
+ ** There should be two additional arguments.
+@@ -2985,6 +3101,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+ ** <dd> ^This option is used to enable or disable the two-argument
+ ** version of the [fts3_tokenizer()] function which is part of the
+@@ -2998,6 +3115,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the new setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+ ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+ ** interface independently of the [load_extension()] SQL function.
+@@ -3015,7 +3133,7 @@
+ ** be a NULL pointer, in which case the new setting is not reported back.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+ ** <dd> ^This option is used to change the name of the "main" database
+ ** schema.  ^The sole argument is a pointer to a constant UTF8 string
+ ** which will become the new schema name in place of "main".  ^SQLite
+@@ -3024,6 +3142,7 @@
+ ** until after the database connection closes.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] 
+ ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+ ** <dd> Usually, when a database in wal mode is closed or detached from a 
+ ** database handle, SQLite checks if this will mean that there are now no 
+@@ -3030,13 +3149,14 @@
+ ** connections at all to the database. If so, it performs a checkpoint 
+ ** operation before closing the connection. This option may be used to
+ ** override this behaviour. The first parameter passed to this operation
+-** is an integer - non-zero to disable checkpoints-on-close, or zero (the
+-** default) to enable them. The second parameter is a pointer to an integer
++** is an integer - positive to disable checkpoints-on-close, or zero (the
++** default) to enable them, and negative to leave the setting unchanged.
++** The second parameter is a pointer to an integer
+ ** into which is written 0 or 1 to indicate whether checkpoints-on-close
+ ** have been disabled - 0 if they are not disabled, 1 if they are.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+ ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+ ** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+ ** a single SQL query statement will always use the same algorithm regardless
+@@ -3045,8 +3165,57 @@
+ ** slower.  But the QPSG has the advantage of more predictable behavior.  With
+ ** the QPSG active, SQLite will always use the same query plan in the field as
+ ** was used during testing in the lab.
++** The first argument to this setting is an integer which is 0 to disable 
++** the QPSG, positive to enable QPSG, or negative to leave the setting
++** unchanged. The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
++** following this call.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
++** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 
++** include output for any operations performed by trigger programs. This
++** option is used to set or clear (the default) a flag that governs this
++** behavior. The first parameter passed to this operation is an integer -
++** positive to enable output for trigger programs, or zero to disable it,
++** or negative to leave the setting unchanged.
++** The second parameter is a pointer to an integer into which is written 
++** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
++** it is not disabled, 1 if it is.  
++** </dd>
++**
++** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
++** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
++** [VACUUM] in order to reset a database back to an empty database
++** with no schema and no content. The following process works even for
++** a badly corrupted database file:
++** <ol>
++** <li> If the database connection is newly opened, make sure it has read the
++**      database schema by preparing then discarding some query against the
++**      database, or calling sqlite3_table_column_metadata(), ignoring any
++**      errors.  This step is only necessary if the application desires to keep
++**      the database in WAL mode after the reset if it was in WAL mode before
++**      the reset.  
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
++** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
++** </ol>
++** Because resetting a database is destructive and irreversible, the
++** process requires the use of this obscure API and multiple steps to help
++** ensure that it does not happen by accident.
++**
++** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
++** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
++** "defensive" flag for a database connection.  When the defensive
++** flag is enabled, language features that allow ordinary SQL to 
++** deliberately corrupt the database file are disabled.  The disabled
++** features include but are not limited to the following:
++** <ul>
++** <li> The [PRAGMA writable_schema=ON] statement.
++** <li> Writes to the [sqlite_dbpage] virtual table.
++** <li> Direct writes to [shadow tables].
++** </ul>
++** </dd>
+ ** </dl>
+ */
+ #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
+@@ -3057,8 +3226,11 @@
+ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+ #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
++#define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
++#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
++#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
++#define SQLITE_DBCONFIG_MAX                   1010 /* Largest DBCONFIG */
+ 
+-
+ /*
+ ** CAPI3REF: Enable Or Disable Extended Result Codes
+ ** METHOD: sqlite3
+@@ -3185,12 +3357,17 @@
+ ** program, the value returned reflects the number of rows modified by the 
+ ** previous INSERT, UPDATE or DELETE statement within the same trigger.
+ **
+-** See also the [sqlite3_total_changes()] interface, the
+-** [count_changes pragma], and the [changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_total_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** </ul>
+ */
+ SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+@@ -3208,13 +3385,26 @@
+ ** count, but those made as part of REPLACE constraint resolution are
+ ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+ ** are not counted.
++**
++** This the [sqlite3_total_changes(D)] interface only reports the number
++** of rows that changed due to SQL statement run against database
++** connection D.  Any changes by other database connections are ignored.
++** To detect changes against a database file from other database
++** connections use the [PRAGMA data_version] command or the
++** [SQLITE_FCNTL_DATA_VERSION] [file control].
+ ** 
+-** See also the [sqlite3_changes()] interface, the
+-** [count_changes pragma], and the [total_changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
++** </ul>
+ */
+ SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+@@ -3463,16 +3653,16 @@
+ **
+ ** These routines are work-alikes of the "printf()" family of functions
+ ** from the standard C library.
+-** These routines understand most of the common K&R formatting options,
+-** plus some additional non-standard formats, detailed below.
+-** Note that some of the more obscure formatting options from recent
+-** C-library standards are omitted from this implementation.
++** These routines understand most of the common formatting options from
++** the standard library printf() 
++** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
++** See the [built-in printf()] documentation for details.
+ **
+ ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
+-** results into memory obtained from [sqlite3_malloc()].
++** results into memory obtained from [sqlite3_malloc64()].
+ ** The strings returned by these two routines should be
+ ** released by [sqlite3_free()].  ^Both routines return a
+-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
++** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
+ ** memory to hold the resulting string.
+ **
+ ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
+@@ -3496,71 +3686,7 @@
+ **
+ ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
+ **
+-** These routines all implement some additional formatting
+-** options that are useful for constructing SQL statements.
+-** All of the usual printf() formatting options apply.  In addition, there
+-** is are "%q", "%Q", "%w" and "%z" options.
+-**
+-** ^(The %q option works like %s in that it substitutes a nul-terminated
+-** string from the argument list.  But %q also doubles every '\'' character.
+-** %q is designed for use inside a string literal.)^  By doubling each '\''
+-** character it escapes that character and allows it to be inserted into
+-** the string.
+-**
+-** For example, assume the string variable zText contains text as follows:
+-**
+-** <blockquote><pre>
+-**  char *zText = "It's a happy day!";
+-** </pre></blockquote>
+-**
+-** One can use this text in an SQL statement as follows:
+-**
+-** <blockquote><pre>
+-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+-**  sqlite3_exec(db, zSQL, 0, 0, 0);
+-**  sqlite3_free(zSQL);
+-** </pre></blockquote>
+-**
+-** Because the %q format string is used, the '\'' character in zText
+-** is escaped and the SQL generated is as follows:
+-**
+-** <blockquote><pre>
+-**  INSERT INTO table1 VALUES('It''s a happy day!')
+-** </pre></blockquote>
+-**
+-** This is correct.  Had we used %s instead of %q, the generated SQL
+-** would have looked like this:
+-**
+-** <blockquote><pre>
+-**  INSERT INTO table1 VALUES('It's a happy day!');
+-** </pre></blockquote>
+-**
+-** This second example is an SQL syntax error.  As a general rule you should
+-** always use %q instead of %s when inserting text into a string literal.
+-**
+-** ^(The %Q option works like %q except it also adds single quotes around
+-** the outside of the total string.  Additionally, if the parameter in the
+-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
+-** single quotes).)^  So, for example, one could say:
+-**
+-** <blockquote><pre>
+-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+-**  sqlite3_exec(db, zSQL, 0, 0, 0);
+-**  sqlite3_free(zSQL);
+-** </pre></blockquote>
+-**
+-** The code above will render a correct SQL statement in the zSQL
+-** variable even if the zText variable is a NULL pointer.
+-**
+-** ^(The "%w" formatting option is like "%q" except that it expects to
+-** be contained within double-quotes instead of single quotes, and it
+-** escapes the double-quote character instead of the single-quote
+-** character.)^  The "%w" formatting option is intended for safely inserting
+-** table and column names into a constructed SQL statement.
+-**
+-** ^(The "%z" formatting option works like "%s" but with the
+-** addition that after the string has been read and copied into
+-** the result, [sqlite3_free()] is called on the input string.)^
++** See also:  [built-in printf()], [printf() SQL function]
+ */
+ SQLITE_API char *sqlite3_mprintf(const char*,...);
+ SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+@@ -3918,8 +4044,8 @@
+ ** KEYWORDS: SQLITE_TRACE
+ **
+ ** These constants identify classes of events that can be monitored
+-** using the [sqlite3_trace_v2()] tracing logic.  The third argument
+-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
++** using the [sqlite3_trace_v2()] tracing logic.  The M argument
++** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
+ ** the following constants.  ^The first argument to the trace callback
+ ** is one of the following constants.
+ **
+@@ -4128,10 +4254,10 @@
+ ** ^If [URI filename] interpretation is enabled, and the filename argument
+ ** begins with "file:", then the filename is interpreted as a URI. ^URI
+ ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
+-** set in the fourth argument to sqlite3_open_v2(), or if it has
++** set in the third argument to sqlite3_open_v2(), or if it has
+ ** been enabled globally using the [SQLITE_CONFIG_URI] option with the
+ ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
+-** As of SQLite version 3.7.7, URI filename interpretation is turned off
++** URI filename interpretation is turned off
+ ** by default, but future releases of SQLite might enable URI filename
+ ** interpretation by default.  See "[URI filenames]" for additional
+ ** information.
+@@ -4334,13 +4460,24 @@
+ ** [database connection] D failed, then the sqlite3_errcode(D) interface
+ ** returns the numeric [result code] or [extended result code] for that
+ ** API call.
+-** If the most recent API call was successful,
+-** then the return value from sqlite3_errcode() is undefined.
+ ** ^The sqlite3_extended_errcode()
+ ** interface is the same except that it always returns the 
+ ** [extended result code] even when extended result codes are
+ ** disabled.
+ **
++** The values returned by sqlite3_errcode() and/or
++** sqlite3_extended_errcode() might change with each API call.
++** Except, there are some interfaces that are guaranteed to never
++** change the value of the error code.  The error-code preserving
++** interfaces are:
++**
++** <ul>
++** <li> sqlite3_errcode()
++** <li> sqlite3_extended_errcode()
++** <li> sqlite3_errmsg()
++** <li> sqlite3_errmsg16()
++** </ul>
++**
+ ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+ ** text that describes the error, as either UTF-8 or UTF-16 respectively.
+ ** ^(Memory to hold the error message string is managed internally.
+@@ -4530,9 +4667,19 @@
+ ** on this hint by avoiding the use of [lookaside memory] so as not to
+ ** deplete the limited store of lookaside memory. Future versions of
+ ** SQLite may act on this hint differently.
++**
++** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
++** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
++** representation of the SQL statement should be calculated and then
++** associated with the prepared statement, which can be obtained via
++** the [sqlite3_normalized_sql()] interface.)^  The semantics used to
++** normalize a SQL statement are unspecified and subject to change.
++** At a minimum, literal values will be replaced with suitable
++** placeholders.
+ ** </dl>
+ */
+ #define SQLITE_PREPARE_PERSISTENT              0x01
++#define SQLITE_PREPARE_NORMALIZE               0x02
+ 
+ /*
+ ** CAPI3REF: Compiling An SQL Statement
+@@ -4626,6 +4773,7 @@
+ ** or [GLOB] operator or if the parameter is compared to an indexed column
+ ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
+ ** </li>
++** </ol>
+ **
+ ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+ ** the extra prepFlags parameter, which is a bit array consisting of zero or
+@@ -4632,7 +4780,6 @@
+ ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
+ ** sqlite3_prepare_v2() interface works exactly the same as
+ ** sqlite3_prepare_v3() with a zero prepFlags parameter.
+-** </ol>
+ */
+ SQLITE_API int sqlite3_prepare(
+   sqlite3 *db,            /* Database handle */
+@@ -4690,6 +4837,11 @@
+ ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+ ** string containing the SQL text of prepared statement P with
+ ** [bound parameters] expanded.
++** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
++** string containing the normalized SQL text of prepared statement P.  The
++** semantics used to normalize a SQL statement are unspecified and subject
++** to change.  At a minimum, literal values will be replaced with suitable
++** placeholders.
+ **
+ ** ^(For example, if a prepared statement is created using the SQL
+ ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+@@ -4705,8 +4857,9 @@
+ ** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+ ** option causes sqlite3_expanded_sql() to always return NULL.
+ **
+-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
+-** automatically freed when the prepared statement is finalized.
++** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
++** are managed by SQLite and are automatically freed when the prepared
++** statement is finalized.
+ ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+ ** is obtained from [sqlite3_malloc()] and must be free by the application
+ ** by passing it to [sqlite3_free()].
+@@ -4713,6 +4866,7 @@
+ */
+ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -4805,8 +4959,9 @@
+ ** implementation of [application-defined SQL functions] are protected.
+ ** ^The sqlite3_value object returned by
+ ** [sqlite3_column_value()] is unprotected.
+-** Unprotected sqlite3_value objects may only be used with
+-** [sqlite3_result_value()] and [sqlite3_bind_value()].
++** Unprotected sqlite3_value objects may only be used as arguments
++** to [sqlite3_result_value()], [sqlite3_bind_value()], and
++** [sqlite3_value_dup()].
+ ** The [sqlite3_value_blob | sqlite3_value_type()] family of
+ ** interfaces require protected sqlite3_value objects.
+ */
+@@ -5228,7 +5383,7 @@
+ ** other than [SQLITE_ROW] before any subsequent invocation of
+ ** sqlite3_step().  Failure to reset the prepared statement using 
+ ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+-** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1]),
++** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1],
+ ** sqlite3_step() began
+ ** calling [sqlite3_reset()] automatically in this circumstance rather
+ ** than returning [SQLITE_MISUSE].  This is not considered a compatibility
+@@ -5493,11 +5648,25 @@
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+-** ^(If a memory allocation error occurs during the evaluation of any
+-** of these routines, a default value is returned.  The default value
+-** is either the integer 0, the floating point number 0.0, or a NULL
+-** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+-** [SQLITE_NOMEM].)^
++** As long as the input parameters are correct, these routines will only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_column_blob()
++** <li> sqlite3_column_text()
++** <li> sqlite3_column_text16()
++** <li> sqlite3_column_bytes()
++** <li> sqlite3_column_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+ SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+@@ -5574,11 +5743,13 @@
+ **
+ ** ^These functions (collectively known as "function creation routines")
+ ** are used to add SQL functions or aggregates or to redefine the behavior
+-** of existing SQL functions or aggregates.  The only differences between
+-** these routines are the text encoding expected for
+-** the second parameter (the name of the function being created)
+-** and the presence or absence of a destructor callback for
+-** the application data pointer.
++** of existing SQL functions or aggregates. The only differences between
++** the three "sqlite3_create_function*" routines are the text encoding 
++** expected for the second parameter (the name of the function being 
++** created) and the presence or absence of a destructor callback for
++** the application data pointer. Function sqlite3_create_window_function()
++** is similar, but allows the user to supply the extra callback functions
++** needed by [aggregate window functions].
+ **
+ ** ^The first parameter is the [database connection] to which the SQL
+ ** function is to be added.  ^If an application uses more than one database
+@@ -5624,7 +5795,8 @@
+ ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+ ** function can gain access to this pointer using [sqlite3_user_data()].)^
+ **
+-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
++** ^The sixth, seventh and eighth parameters passed to the three
++** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+ ** pointers to C-language functions that implement the SQL function or
+ ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
+ ** callback only; NULL pointers must be passed as the xStep and xFinal
+@@ -5633,16 +5805,25 @@
+ ** SQL function or aggregate, pass NULL pointers for all three function
+ ** callbacks.
+ **
+-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
+-** then it is destructor for the application data pointer. 
+-** The destructor is invoked when the function is deleted, either by being
+-** overloaded or when the database connection closes.)^
+-** ^The destructor is also invoked if the call to
+-** sqlite3_create_function_v2() fails.
+-** ^When the destructor callback of the tenth parameter is invoked, it
+-** is passed a single argument which is a copy of the application data 
+-** pointer which was the fifth parameter to sqlite3_create_function_v2().
++** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
++** and xInverse) passed to sqlite3_create_window_function are pointers to
++** C-language callbacks that implement the new function. xStep and xFinal
++** must both be non-NULL. xValue and xInverse may either both be NULL, in
++** which case a regular aggregate function is created, or must both be 
++** non-NULL, in which case the new function may be used as either an aggregate
++** or aggregate window function. More details regarding the implementation
++** of aggregate window functions are 
++** [user-defined window functions|available here].
+ **
++** ^(If the final parameter to sqlite3_create_function_v2() or
++** sqlite3_create_window_function() is not NULL, then it is destructor for
++** the application data pointer. The destructor is invoked when the function 
++** is deleted, either by being overloaded or when the database connection 
++** closes.)^ ^The destructor is also invoked if the call to 
++** sqlite3_create_function_v2() fails.  ^When the destructor callback is
++** invoked, it is passed a single argument which is a copy of the application
++** data pointer which was the fifth parameter to sqlite3_create_function_v2().
++**
+ ** ^It is permitted to register multiple implementations of the same
+ ** functions with the same name but with either differing numbers of
+ ** arguments or differing preferred text encodings.  ^SQLite will use
+@@ -5694,6 +5875,18 @@
+   void (*xFinal)(sqlite3_context*),
+   void(*xDestroy)(void*)
+ );
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunctionName,
++  int nArg,
++  int eTextRep,
++  void *pApp,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
++);
+ 
+ /*
+ ** CAPI3REF: Text Encodings
+@@ -5764,6 +5957,9 @@
+ ** datatype of the value
+ ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+ ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
++** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
++** against a virtual table.
+ ** </table></blockquote>
+ **
+ ** <b>Details:</b>
+@@ -5812,6 +6008,19 @@
+ ** then the conversion is performed.  Otherwise no conversion occurs.
+ ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
+ **
++** ^Within the [xUpdate] method of a [virtual table], the
++** sqlite3_value_nochange(X) interface returns true if and only if
++** the column corresponding to X is unchanged by the UPDATE operation
++** that the xUpdate method call was invoked to implement and if
++** and the prior [xColumn] method call that was invoked to extracted
++** the value for that column returned without setting a result (probably
++** because it queried [sqlite3_vtab_nochange()] and found that the column
++** was unchanging).  ^Within an [xUpdate] method, any value for which
++** sqlite3_value_nochange(X) is true will in all other respects appear
++** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
++** than within an [xUpdate] method call for an UPDATE statement, then
++** the return value is arbitrary and meaningless.
++**
+ ** Please pay particular attention to the fact that the pointer returned
+ ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
+ ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
+@@ -5820,6 +6029,28 @@
+ **
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
++**
++** As long as the input parameter is correct, these routines can only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_value_blob()
++** <li> sqlite3_value_text()
++** <li> sqlite3_value_text16()
++** <li> sqlite3_value_text16le()
++** <li> sqlite3_value_text16be()
++** <li> sqlite3_value_bytes()
++** <li> sqlite3_value_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+ SQLITE_API double sqlite3_value_double(sqlite3_value*);
+@@ -5834,6 +6065,7 @@
+ SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+ SQLITE_API int sqlite3_value_type(sqlite3_value*);
+ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
++SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+ 
+ /*
+ ** CAPI3REF: Finding The Subtype Of SQL Values
+@@ -6490,6 +6722,41 @@
+ SQLITE_API char *sqlite3_data_directory;
+ 
+ /*
++** CAPI3REF: Win32 Specific Interface
++**
++** These interfaces are available only on Windows.  The
++** [sqlite3_win32_set_directory] interface is used to set the value associated
++** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
++** zValue, depending on the value of the type parameter.  The zValue parameter
++** should be NULL to cause the previous value to be freed via [sqlite3_free];
++** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
++** prior to being used.  The [sqlite3_win32_set_directory] interface returns
++** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
++** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
++** [sqlite3_data_directory] variable is intended to act as a replacement for
++** the current directory on the sub-platforms of Win32 where that concept is
++** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
++** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
++** sqlite3_win32_set_directory interface except the string parameter must be
++** UTF-8 or UTF-16, respectively.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++);
++SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
++SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
++
++/*
++** CAPI3REF: Win32 Directory Types
++**
++** These macros are only available on Windows.  They define the allowed values
++** for the type argument to the [sqlite3_win32_set_directory] interface.
++*/
++#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
++#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
++
++/*
+ ** CAPI3REF: Test For Auto-Commit Mode
+ ** KEYWORDS: {autocommit mode}
+ ** METHOD: sqlite3
+@@ -7089,6 +7356,9 @@
+   int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+   int (*xRelease)(sqlite3_vtab *pVTab, int);
+   int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
++  /* The methods above are in versions 1 and 2 of the sqlite_module object.
++  ** Those below are for version 3 and greater. */
++  int (*xShadowName)(const char*);
+ };
+ 
+ /*
+@@ -7221,6 +7491,10 @@
+ 
+ /*
+ ** CAPI3REF: Virtual Table Scan Flags
++**
++** Virtual table implementations are allowed to set the 
++** [sqlite3_index_info].idxFlags field to some combination of
++** these bits.
+ */
+ #define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
+ 
+@@ -7232,15 +7506,21 @@
+ ** an operator that is part of a constraint term in the wHERE clause of
+ ** a query that uses a [virtual table].
+ */
+-#define SQLITE_INDEX_CONSTRAINT_EQ      2
+-#define SQLITE_INDEX_CONSTRAINT_GT      4
+-#define SQLITE_INDEX_CONSTRAINT_LE      8
+-#define SQLITE_INDEX_CONSTRAINT_LT     16
+-#define SQLITE_INDEX_CONSTRAINT_GE     32
+-#define SQLITE_INDEX_CONSTRAINT_MATCH  64
+-#define SQLITE_INDEX_CONSTRAINT_LIKE   65
+-#define SQLITE_INDEX_CONSTRAINT_GLOB   66
+-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
++#define SQLITE_INDEX_CONSTRAINT_EQ         2
++#define SQLITE_INDEX_CONSTRAINT_GT         4
++#define SQLITE_INDEX_CONSTRAINT_LE         8
++#define SQLITE_INDEX_CONSTRAINT_LT        16
++#define SQLITE_INDEX_CONSTRAINT_GE        32
++#define SQLITE_INDEX_CONSTRAINT_MATCH     64
++#define SQLITE_INDEX_CONSTRAINT_LIKE      65
++#define SQLITE_INDEX_CONSTRAINT_GLOB      66
++#define SQLITE_INDEX_CONSTRAINT_REGEXP    67
++#define SQLITE_INDEX_CONSTRAINT_NE        68
++#define SQLITE_INDEX_CONSTRAINT_ISNOT     69
++#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
++#define SQLITE_INDEX_CONSTRAINT_ISNULL    71
++#define SQLITE_INDEX_CONSTRAINT_IS        72
++#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -7917,6 +8197,7 @@
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+ ** METHOD: sqlite3
++** KEYWORDS: {file control}
+ **
+ ** ^The [sqlite3_file_control()] interface makes a direct call to the
+ ** xFileControl method for the [sqlite3_io_methods] object associated
+@@ -7931,11 +8212,18 @@
+ ** the xFileControl method.  ^The return value of the xFileControl
+ ** method becomes the return value of this routine.
+ **
+-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
++** A few opcodes for [sqlite3_file_control()] are handled directly
++** by the SQLite core and never invoke the 
++** sqlite3_io_methods.xFileControl method.
++** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+ ** a pointer to the underlying [sqlite3_file] object to be written into
+-** the space pointed to by the 4th parameter.  ^The SQLITE_FCNTL_FILE_POINTER
+-** case is a short-circuit path which does not actually invoke the
+-** underlying sqlite3_io_methods.xFileControl method.
++** the space pointed to by the 4th parameter.  The
++** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
++** the [sqlite3_file] object associated with the journal file instead of
++** the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
++** a pointer to the underlying [sqlite3_vfs] object for the file.
++** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
++** from the pager.
+ **
+ ** ^If the second parameter (zDbName) does not match the name of any
+ ** open database file, then SQLITE_ERROR is returned.  ^This error
+@@ -7945,7 +8233,7 @@
+ ** an incorrect zDbName and an SQLITE_ERROR return from the underlying
+ ** xFileControl method.
+ **
+-** See also: [SQLITE_FCNTL_LOCKSTATE]
++** See also: [file control opcodes]
+ */
+ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+ 
+@@ -7991,8 +8279,9 @@
+ #define SQLITE_TESTCTRL_ALWAYS                  13
+ #define SQLITE_TESTCTRL_RESERVE                 14
+ #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
+-#define SQLITE_TESTCTRL_ISKEYWORD               16
+-#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
++#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
++#define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
++#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
+ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+@@ -8002,9 +8291,193 @@
+ #define SQLITE_TESTCTRL_ISINIT                  23
+ #define SQLITE_TESTCTRL_SORTER_MMAP             24
+ #define SQLITE_TESTCTRL_IMPOSTER                25
+-#define SQLITE_TESTCTRL_LAST                    25
++#define SQLITE_TESTCTRL_PARSER_COVERAGE         26
++#define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+ 
+ /*
++** CAPI3REF: SQL Keyword Checking
++**
++** These routines provide access to the set of SQL language keywords 
++** recognized by SQLite.  Applications can uses these routines to determine
++** whether or not a specific identifier needs to be escaped (for example,
++** by enclosing in double-quotes) so as not to confuse the parser.
++**
++** The sqlite3_keyword_count() interface returns the number of distinct
++** keywords understood by SQLite.
++**
++** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
++** makes *Z point to that keyword expressed as UTF8 and writes the number
++** of bytes in the keyword into *L.  The string that *Z points to is not
++** zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
++** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
++** or L are NULL or invalid pointers then calls to
++** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
++**
++** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
++** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
++** if it is and zero if not.
++**
++** The parser used by SQLite is forgiving.  It is often possible to use
++** a keyword as an identifier as long as such use does not result in a
++** parsing ambiguity.  For example, the statement
++** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
++** creates a new table named "BEGIN" with three columns named
++** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
++** using keywords as identifiers.  Common techniques used to avoid keyword
++** name collisions include:
++** <ul>
++** <li> Put all identifier names inside double-quotes.  This is the official
++**      SQL way to escape identifier names.
++** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
++**      but it is what SQL Server does and so lots of programmers use this
++**      technique.
++** <li> Begin every identifier with the letter "Z" as no SQL keywords start
++**      with "Z".
++** <li> Include a digit somewhere in every identifier name.
++** </ul>
++**
++** Note that the number of keywords understood by SQLite can depend on
++** compile-time options.  For example, "VACUUM" is not a keyword if
++** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
++** new keywords may be added to future releases of SQLite.
++*/
++SQLITE_API int sqlite3_keyword_count(void);
++SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
++SQLITE_API int sqlite3_keyword_check(const char*,int);
++
++/*
++** CAPI3REF: Dynamic String Object
++** KEYWORDS: {dynamic string}
++**
++** An instance of the sqlite3_str object contains a dynamically-sized
++** string under construction.
++**
++** The lifecycle of an sqlite3_str object is as follows:
++** <ol>
++** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
++** <li> ^Text is appended to the sqlite3_str object using various
++** methods, such as [sqlite3_str_appendf()].
++** <li> ^The sqlite3_str object is destroyed and the string it created
++** is returned using the [sqlite3_str_finish()] interface.
++** </ol>
++*/
++typedef struct sqlite3_str sqlite3_str;
++
++/*
++** CAPI3REF: Create A New Dynamic String Object
++** CONSTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_new(D)] interface allocates and initializes
++** a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
++** [sqlite3_str_new()] must be freed by a subsequent call to 
++** [sqlite3_str_finish(X)].
++**
++** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
++** valid [sqlite3_str] object, though in the event of an out-of-memory
++** error the returned object might be a special singleton that will
++** silently reject new text, always return SQLITE_NOMEM from 
++** [sqlite3_str_errcode()], always return 0 for 
++** [sqlite3_str_length()], and always return NULL from
++** [sqlite3_str_finish(X)].  It is always safe to use the value
++** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
++** to any of the other [sqlite3_str] methods.
++**
++** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
++** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
++** length of the string contained in the [sqlite3_str] object will be
++** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
++** of [SQLITE_MAX_LENGTH].
++*/
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
++
++/*
++** CAPI3REF: Finalize A Dynamic String
++** DESTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
++** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
++** that contains the constructed string.  The calling application should
++** pass the returned value to [sqlite3_free()] to avoid a memory leak.
++** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
++** errors were encountered during construction of the string.  ^The
++** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
++** string in [sqlite3_str] object X is zero bytes long.
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
++
++/*
++** CAPI3REF: Add Content To A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces add content to an sqlite3_str object previously obtained
++** from [sqlite3_str_new()].
++**
++** ^The [sqlite3_str_appendf(X,F,...)] and 
++** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
++** functionality of SQLite to append formatted text onto the end of 
++** [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
++** onto the end of the [sqlite3_str] object X.  N must be non-negative.
++** S must contain at least N non-zero bytes of content.  To append a
++** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
++** method instead.
++**
++** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
++** zero-terminated string S onto the end of [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
++** single-byte character C onto the end of [sqlite3_str] object X.
++** ^This method can be used, for example, to add whitespace indentation.
++**
++** ^The [sqlite3_str_reset(X)] method resets the string under construction
++** inside [sqlite3_str] object X back to zero bytes in length.  
++**
++** These methods do not return a result code.  ^If an error occurs, that fact
++** is recorded in the [sqlite3_str] object and can be recovered by a
++** subsequent call to [sqlite3_str_errcode(X)].
++*/
++SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
++SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
++SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
++SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
++SQLITE_API void sqlite3_str_reset(sqlite3_str*);
++
++/*
++** CAPI3REF: Status Of A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces return the current status of an [sqlite3_str] object.
++**
++** ^If any prior errors have occurred while constructing the dynamic string
++** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
++** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
++** [SQLITE_NOMEM] following any out-of-memory error, or
++** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
++** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
++**
++** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
++** of the dynamic string under construction in [sqlite3_str] object X.
++** ^The length returned by [sqlite3_str_length(X)] does not include the
++** zero-termination byte.
++**
++** ^The [sqlite3_str_value(X)] method returns a pointer to the current
++** content of the dynamic string under construction in X.  The value
++** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
++** and might be freed or altered by any subsequent method on the same
++** [sqlite3_str] object.  Applications must not used the pointer returned
++** [sqlite3_str_value(X)] after any subsequent method call on the same
++** object.  ^Applications may change the content of the string returned
++** by [sqlite3_str_value(X)] as long as they do not write into any bytes
++** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
++** write any byte after any subsequent sqlite3_str method call.
++*/
++SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
++SQLITE_API int sqlite3_str_length(sqlite3_str*);
++SQLITE_API char *sqlite3_str_value(sqlite3_str*);
++
++/*
+ ** CAPI3REF: SQLite Runtime Status
+ **
+ ** ^These interfaces are used to retrieve runtime status information
+@@ -8051,8 +8524,7 @@
+ ** <dd>This parameter is the current amount of memory checked out
+ ** using [sqlite3_malloc()], either directly or indirectly.  The
+ ** figure includes calls made to [sqlite3_malloc()] by the application
+-** and internal memory usage by the SQLite library.  Scratch memory
+-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
++** and internal memory usage by the SQLite library.  Auxiliary page-cache
+ ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
+ ** this parameter.  The amount returned is the sum of the allocation
+ ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
+@@ -8090,29 +8562,14 @@
+ ** *pHighwater parameter to [sqlite3_status()] is of interest.  
+ ** The value written into the *pCurrent parameter is undefined.</dd>)^
+ **
+-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
+-** <dd>This parameter returns the number of allocations used out of the
+-** [scratch memory allocator] configured using
+-** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
+-** in bytes.  Since a single thread may only have one scratch allocation
+-** outstanding at time, this parameter also reports the number of threads
+-** using scratch memory at the same time.</dd>)^
++** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
++** <dd>No longer used.</dd>
+ **
+ ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
+-** <dd>This parameter returns the number of bytes of scratch memory
+-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
+-** buffer and where forced to overflow to [sqlite3_malloc()].  The values
+-** returned include overflows because the requested allocation was too
+-** larger (that is, because the requested allocation was larger than the
+-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
+-** slots were available.
+-** </dd>)^
++** <dd>No longer used.</dd>
+ **
+-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+-** <dd>This parameter records the largest memory allocation request
+-** handed to [scratch memory allocator].  Only the value returned in the
+-** *pHighwater parameter to [sqlite3_status()] is of interest.  
+-** The value written into the *pCurrent parameter is undefined.</dd>)^
++** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
++** <dd>No longer used.</dd>
+ **
+ ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
+ ** <dd>The *pHighwater parameter records the deepest parser stack. 
+@@ -8125,12 +8582,12 @@
+ #define SQLITE_STATUS_MEMORY_USED          0
+ #define SQLITE_STATUS_PAGECACHE_USED       1
+ #define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
+-#define SQLITE_STATUS_SCRATCH_USED         3
+-#define SQLITE_STATUS_SCRATCH_OVERFLOW     4
++#define SQLITE_STATUS_SCRATCH_USED         3  /* NOT USED */
++#define SQLITE_STATUS_SCRATCH_OVERFLOW     4  /* NOT USED */
+ #define SQLITE_STATUS_MALLOC_SIZE          5
+ #define SQLITE_STATUS_PARSER_STACK         6
+ #define SQLITE_STATUS_PAGECACHE_SIZE       7
+-#define SQLITE_STATUS_SCRATCH_SIZE         8
++#define SQLITE_STATUS_SCRATCH_SIZE         8  /* NOT USED */
+ #define SQLITE_STATUS_MALLOC_COUNT         9
+ 
+ /*
+@@ -8253,6 +8710,15 @@
+ ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
+ ** </dd>
+ **
++** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
++** <dd>This parameter returns the number of dirty cache entries that have
++** been written to disk in the middle of a transaction due to the page
++** cache overflowing. Transactions are more efficient if they are written
++** to disk all at once. When pages spill mid-transaction, that introduces
++** additional overhead. This parameter can be used help identify
++** inefficiencies that can be resolve by increasing the cache size.
++** </dd>
++**
+ ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+ ** <dd>This parameter returns zero for the current value if and only if
+ ** all foreign key constraints (deferred or immediate) have been
+@@ -8272,7 +8738,8 @@
+ #define SQLITE_DBSTATUS_CACHE_WRITE          9
+ #define SQLITE_DBSTATUS_DEFERRED_FKS        10
+ #define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
+-#define SQLITE_DBSTATUS_MAX                 11   /* Largest defined DBSTATUS */
++#define SQLITE_DBSTATUS_CACHE_SPILL         12
++#define SQLITE_DBSTATUS_MAX                 12   /* Largest defined DBSTATUS */
+ 
+ 
+ /*
+@@ -9227,6 +9694,7 @@
+ ** can use to customize and optimize their behavior.
+ **
+ ** <dl>
++** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
+ ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
+ ** <dd>Calls of the form
+ ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
+@@ -9273,6 +9741,40 @@
+ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+ 
+ /*
++** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
++**
++** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
++** method of a [virtual table], then it returns true if and only if the
++** column is being fetched as part of an UPDATE operation during which the
++** column value will not change.  Applications might use this to substitute
++** a return value that is less expensive to compute and that the corresponding
++** [xUpdate] method understands as a "no-change" value.
++**
++** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
++** the column is not changed by the UPDATE statement, then the xColumn
++** method can optionally return without setting a result, without calling
++** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
++** In that case, [sqlite3_value_nochange(X)] will return true for the
++** same column in the [xUpdate] method.
++*/
++SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
++
++/*
++** CAPI3REF: Determine The Collation For a Virtual Table Constraint
++**
++** This function may only be called from within a call to the [xBestIndex]
++** method of a [virtual table]. 
++**
++** The first argument must be the sqlite3_index_info object that is the
++** first parameter to the xBestIndex() method. The second argument must be
++** an index into the aConstraint[] array belonging to the sqlite3_index_info
++** structure passed to xBestIndex. This function returns a pointer to a buffer 
++** containing the name of the collation sequence for the corresponding
++** constraint.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
++
++/*
+ ** CAPI3REF: Conflict resolution modes
+ ** KEYWORDS: {conflict resolution mode}
+ **
+@@ -9542,7 +10044,6 @@
+ /*
+ ** CAPI3REF: Database Snapshot
+ ** KEYWORDS: {snapshot} {sqlite3_snapshot}
+-** EXPERIMENTAL
+ **
+ ** An instance of the snapshot object records the state of a [WAL mode]
+ ** database for some specific point in history.
+@@ -9559,11 +10060,6 @@
+ ** version of the database file so that it is possible to later open a new read
+ ** transaction that sees that historical version of the database rather than
+ ** the most recent version.
+-**
+-** The constructor for this object is [sqlite3_snapshot_get()].  The
+-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+-** to an historical snapshot (if possible).  The destructor for 
+-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+ */
+ typedef struct sqlite3_snapshot {
+   unsigned char hidden[48];
+@@ -9571,7 +10067,7 @@
+ 
+ /*
+ ** CAPI3REF: Record A Database Snapshot
+-** EXPERIMENTAL
++** CONSTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+ ** new [sqlite3_snapshot] object that records the current state of
+@@ -9587,7 +10083,7 @@
+ ** in this case. 
+ **
+ ** <ul>
+-**   <li> The database handle must be in [autocommit mode].
++**   <li> The database handle must not be in [autocommit mode].
+ **
+ **   <li> Schema S of [database connection] D must be a [WAL mode] database.
+ **
+@@ -9610,7 +10106,7 @@
+ ** to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_get()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+   sqlite3 *db,
+@@ -9620,24 +10116,35 @@
+ 
+ /*
+ ** CAPI3REF: Start a read transaction on an historical snapshot
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+-** read transaction for schema S of
+-** [database connection] D such that the read transaction
+-** refers to historical [snapshot] P, rather than the most
+-** recent change to the database.
+-** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+-** or an appropriate [error code] if it fails.
++** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read 
++** transaction or upgrades an existing one for schema S of 
++** [database connection] D such that the read transaction refers to 
++** historical [snapshot] P, rather than the most recent change to the 
++** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK 
++** on success or an appropriate [error code] if it fails.
+ **
+-** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+-** the first operation following the [BEGIN] that takes the schema S
+-** out of [autocommit mode].
+-** ^In other words, schema S must not currently be in
+-** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+-** database connection D must be out of [autocommit mode].
+-** ^A [snapshot] will fail to open if it has been overwritten by a
+-** [checkpoint].
++** ^In order to succeed, the database connection must not be in 
++** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
++** is already a read transaction open on schema S, then the database handle
++** must have no active statements (SELECT statements that have been passed
++** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). 
++** SQLITE_ERROR is returned if either of these conditions is violated, or
++** if schema S does not exist, or if the snapshot object is invalid.
++**
++** ^A call to sqlite3_snapshot_open() will fail to open if the specified
++** snapshot has been overwritten by a [checkpoint]. In this case 
++** SQLITE_ERROR_SNAPSHOT is returned.
++**
++** If there is already a read transaction open when this function is 
++** invoked, then the same read transaction remains open (on the same
++** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
++** is returned. If another error code - for example SQLITE_PROTOCOL or an
++** SQLITE_IOERR error code - is returned, then the final state of the
++** read transaction is undefined. If SQLITE_OK is returned, then the 
++** read transaction is now open on database snapshot P.
++**
+ ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+ ** database connection D does not know that the database file for
+ ** schema S is in [WAL mode].  A database connection might not know
+@@ -9648,7 +10155,7 @@
+ ** database connection in order to make it ready to use snapshots.)
+ **
+ ** The [sqlite3_snapshot_open()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+   sqlite3 *db,
+@@ -9658,7 +10165,7 @@
+ 
+ /*
+ ** CAPI3REF: Destroy a snapshot
+-** EXPERIMENTAL
++** DESTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+ ** The application must eventually free every [sqlite3_snapshot] object
+@@ -9665,13 +10172,13 @@
+ ** using this routine to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_free()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+ 
+ /*
+ ** CAPI3REF: Compare the ages of two snapshot handles.
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+ ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+ ** of two valid snapshot handles. 
+@@ -9690,6 +10197,9 @@
+ ** Otherwise, this API returns a negative value if P1 refers to an older
+ ** snapshot than P2, zero if the two handles refer to the same database
+ ** snapshot, and a positive value if P1 is a newer snapshot than P2.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+   sqlite3_snapshot *p1,
+@@ -9698,27 +10208,152 @@
+ 
+ /*
+ ** CAPI3REF: Recover snapshots from a wal file
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** If all connections disconnect from a database file but do not perform
+-** a checkpoint, the existing wal file is opened along with the database
+-** file the next time the database is opened. At this point it is only
+-** possible to successfully call sqlite3_snapshot_open() to open the most
+-** recent snapshot of the database (the one at the head of the wal file),
+-** even though the wal file may contain other valid snapshots for which
+-** clients have sqlite3_snapshot handles.
++** If a [WAL file] remains on disk after all database connections close
++** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
++** or because the last process to have the database opened exited without
++** calling [sqlite3_close()]) and a new connection is subsequently opened
++** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
++** will only be able to open the last transaction added to the WAL file
++** even though the WAL file contains other valid transactions.
+ **
+-** This function attempts to scan the wal file associated with database zDb
++** This function attempts to scan the WAL file associated with database zDb
+ ** of database handle db and make all valid snapshots available to
+ ** sqlite3_snapshot_open(). It is an error if there is already a read
+-** transaction open on the database, or if the database is not a wal mode
++** transaction open on the database, or if the database is not a WAL mode
+ ** database.
+ **
+ ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+ /*
++** CAPI3REF: Serialize a database
++**
++** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
++** that is a serialization of the S database on [database connection] D.
++** If P is not a NULL pointer, then the size of the database in bytes
++** is written into *P.
++**
++** For an ordinary on-disk database file, the serialization is just a
++** copy of the disk file.  For an in-memory database or a "TEMP" database,
++** the serialization is the same sequence of bytes which would be written
++** to disk if that database where backed up to disk.
++**
++** The usual case is that sqlite3_serialize() copies the serialization of
++** the database into memory obtained from [sqlite3_malloc64()] and returns
++** a pointer to that memory.  The caller is responsible for freeing the
++** returned value to avoid a memory leak.  However, if the F argument
++** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
++** are made, and the sqlite3_serialize() function will return a pointer
++** to the contiguous memory representation of the database that SQLite
++** is currently using for that database, or NULL if the no such contiguous
++** memory representation of the database exists.  A contiguous memory
++** representation of the database will usually only exist if there has
++** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
++** values of D and S.
++** The size of the database is written into *P even if the 
++** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
++** of the database exists.
++**
++** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
++** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
++** allocation error occurs.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_DESERIALIZE] option.
++*/
++SQLITE_API unsigned char *sqlite3_serialize(
++  sqlite3 *db,           /* The database connection */
++  const char *zSchema,   /* Which DB to serialize. ex: "main", "temp", ... */
++  sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
++  unsigned int mFlags    /* Zero or more SQLITE_SERIALIZE_* flags */
++);
++
++/*
++** CAPI3REF: Flags for sqlite3_serialize
++**
++** Zero or more of the following constants can be OR-ed together for
++** the F argument to [sqlite3_serialize(D,S,P,F)].
++**
++** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
++** a pointer to contiguous in-memory database that it is currently using,
++** without making a copy of the database.  If SQLite is not currently using
++** a contiguous in-memory database, then this option causes
++** [sqlite3_serialize()] to return a NULL pointer.  SQLite will only be
++** using a contiguous in-memory database if it has been initialized by a
++** prior call to [sqlite3_deserialize()].
++*/
++#define SQLITE_SERIALIZE_NOCOPY 0x001   /* Do no memory allocations */
++
++/*
++** CAPI3REF: Deserialize a database
++**
++** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the 
++** [database connection] D to disconnect from database S and then
++** reopen S as an in-memory database based on the serialization contained
++** in P.  The serialized database P is N bytes in size.  M is the size of
++** the buffer P, which might be larger than N.  If M is larger than N, and
++** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
++** permitted to add content to the in-memory database as long as the total
++** size does not exceed M bytes.
++**
++** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
++** invoke sqlite3_free() on the serialization buffer when the database
++** connection closes.  If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
++** SQLite will try to increase the buffer size using sqlite3_realloc64()
++** if writes on the database cause it to grow larger than M bytes.
++**
++** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
++** database is currently in a read transaction or is involved in a backup
++** operation.
++**
++** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the 
++** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
++** [sqlite3_free()] is invoked on argument P prior to returning.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_DESERIALIZE] option.
++*/
++SQLITE_API int sqlite3_deserialize(
++  sqlite3 *db,            /* The database connection */
++  const char *zSchema,    /* Which DB to reopen with the deserialization */
++  unsigned char *pData,   /* The serialized database content */
++  sqlite3_int64 szDb,     /* Number bytes in the deserialization */
++  sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
++  unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
++);
++
++/*
++** CAPI3REF: Flags for sqlite3_deserialize()
++**
++** The following are allowed values for 6th argument (the F argument) to
++** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
++**
++** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
++** in the P argument is held in memory obtained from [sqlite3_malloc64()]
++** and that SQLite should take ownership of this memory and automatically
++** free it when it has finished using it.  Without this flag, the caller
++** is responsible for freeing any dynamically allocated memory.
++**
++** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
++** grow the size of the database using calls to [sqlite3_realloc64()].  This
++** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
++** Without this flag, the deserialized database cannot increase in size beyond
++** the number of bytes specified by the M parameter.
++**
++** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
++** should be treated as read-only.
++*/
++#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
++#define SQLITE_DESERIALIZE_RESIZEABLE  2 /* Resize using sqlite3_realloc64() */
++#define SQLITE_DESERIALIZE_READONLY    4 /* Database is read-only */
++
++/*
+ ** Undo the hack that converts floating point types to integer for
+ ** builds on processors without floating point support.
+ */
+@@ -9829,7 +10464,7 @@
+   sqlite3_int64 iRowid;             /* Rowid for current entry */
+   sqlite3_rtree_dbl rParentScore;   /* Score of parent node */
+   int eParentWithin;                /* Visibility of parent node */
+-  int eWithin;                      /* OUT: Visiblity */
++  int eWithin;                      /* OUT: Visibility */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
+   /* The following fields are only available in 3.8.11 and later */
+   sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+@@ -9865,16 +10500,23 @@
+ 
+ /*
+ ** CAPI3REF: Session Object Handle
++**
++** An instance of this object is a [session] that can be used to
++** record changes to a database.
+ */
+ typedef struct sqlite3_session sqlite3_session;
+ 
+ /*
+ ** CAPI3REF: Changeset Iterator Handle
++**
++** An instance of this object acts as a cursor for iterating
++** over the elements of a [changeset] or [patchset].
+ */
+ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+ 
+ /*
+ ** CAPI3REF: Create A New Session Object
++** CONSTRUCTOR: sqlite3_session
+ **
+ ** Create a new session object attached to database handle db. If successful,
+ ** a pointer to the new object is written to *ppSession and SQLITE_OK is
+@@ -9911,6 +10553,7 @@
+ 
+ /*
+ ** CAPI3REF: Delete A Session Object
++** DESTRUCTOR: sqlite3_session
+ **
+ ** Delete a session object previously allocated using 
+ ** [sqlite3session_create()]. Once a session object has been deleted, the
+@@ -9926,6 +10569,7 @@
+ 
+ /*
+ ** CAPI3REF: Enable Or Disable A Session Object
++** METHOD: sqlite3_session
+ **
+ ** Enable or disable the recording of changes by a session object. When
+ ** enabled, a session object records changes made to the database. When
+@@ -9945,6 +10589,7 @@
+ 
+ /*
+ ** CAPI3REF: Set Or Clear the Indirect Change Flag
++** METHOD: sqlite3_session
+ **
+ ** Each change recorded by a session object is marked as either direct or
+ ** indirect. A change is marked as indirect if either:
+@@ -9974,6 +10619,7 @@
+ 
+ /*
+ ** CAPI3REF: Attach A Table To A Session Object
++** METHOD: sqlite3_session
+ **
+ ** If argument zTab is not NULL, then it is the name of a table to attach
+ ** to the session object passed as the first argument. All subsequent changes 
+@@ -9999,6 +10645,35 @@
+ **
+ ** SQLITE_OK is returned if the call completes without error. Or, if an error 
+ ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
++**
++** <h3>Special sqlite_stat1 Handling</h3>
++**
++** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to 
++** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
++**  <pre>
++**  &nbsp;     CREATE TABLE sqlite_stat1(tbl,idx,stat)  
++**  </pre>
++**
++** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are 
++** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes 
++** are recorded for rows for which (idx IS NULL) is true. However, for such
++** rows a zero-length blob (SQL value X'') is stored in the changeset or
++** patchset instead of a NULL value. This allows such changesets to be
++** manipulated by legacy implementations of sqlite3changeset_invert(),
++** concat() and similar.
++**
++** The sqlite3changeset_apply() function automatically converts the 
++** zero-length blob back to a NULL value when updating the sqlite_stat1
++** table. However, if the application calls sqlite3changeset_new(),
++** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset 
++** iterator directly (including on a changeset iterator passed to a
++** conflict-handler callback) then the X'' value is returned. The application
++** must translate X'' to NULL itself if required.
++**
++** Legacy (older than 3.22.0) versions of the sessions module cannot capture
++** changes made to the sqlite_stat1 table. Legacy versions of the
++** sqlite3changeset_apply() function silently ignore any modifications to the
++** sqlite_stat1 table that are part of a changeset or patchset.
+ */
+ SQLITE_API int sqlite3session_attach(
+   sqlite3_session *pSession,      /* Session object */
+@@ -10007,6 +10682,7 @@
+ 
+ /*
+ ** CAPI3REF: Set a table filter on a Session Object.
++** METHOD: sqlite3_session
+ **
+ ** The second argument (xFilter) is the "filter callback". For changes to rows 
+ ** in tables that are not attached to the Session object, the filter is called
+@@ -10025,6 +10701,7 @@
+ 
+ /*
+ ** CAPI3REF: Generate A Changeset From A Session Object
++** METHOD: sqlite3_session
+ **
+ ** Obtain a changeset containing changes to the tables attached to the 
+ ** session object passed as the first argument. If successful, 
+@@ -10134,7 +10811,8 @@
+ );
+ 
+ /*
+-** CAPI3REF: Load The Difference Between Tables Into A Session 
++** CAPI3REF: Load The Difference Between Tables Into A Session
++** METHOD: sqlite3_session
+ **
+ ** If it is not already attached to the session object passed as the first
+ ** argument, this function attaches table zTbl in the same manner as the
+@@ -10199,6 +10877,7 @@
+ 
+ /*
+ ** CAPI3REF: Generate A Patchset From A Session Object
++** METHOD: sqlite3_session
+ **
+ ** The differences between a patchset and a changeset are that:
+ **
+@@ -10227,8 +10906,8 @@
+ */
+ SQLITE_API int sqlite3session_patchset(
+   sqlite3_session *pSession,      /* Session object */
+-  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
+-  void **ppPatchset               /* OUT: Buffer containing changeset */
++  int *pnPatchset,                /* OUT: Size of buffer at *ppPatchset */
++  void **ppPatchset               /* OUT: Buffer containing patchset */
+ );
+ 
+ /*
+@@ -10250,6 +10929,7 @@
+ 
+ /*
+ ** CAPI3REF: Create An Iterator To Traverse A Changeset 
++** CONSTRUCTOR: sqlite3_changeset_iter
+ **
+ ** Create an iterator used to iterate through the contents of a changeset.
+ ** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+@@ -10280,6 +10960,13 @@
+ ** consecutively. There is no chance that the iterator will visit a change 
+ ** the applies to table X, then one for table Y, and then later on visit 
+ ** another change for table X.
++**
++** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
++**
++** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_start(
+   sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+@@ -10286,10 +10973,30 @@
+   int nChangeset,                 /* Size of changeset blob in bytes */
+   void *pChangeset                /* Pointer to blob containing changeset */
+ );
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset,               /* Pointer to blob containing changeset */
++  int flags                       /* SESSION_CHANGESETSTART_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_start_v2
++**
++** The following flags may passed via the 4th parameter to
++** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset while iterating through it. This is equivalent to
++**   inverting a changeset using sqlite3changeset_invert() before applying it.
++**   It is an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETSTART_INVERT        0x0002
+ 
++
+ /*
+ ** CAPI3REF: Advance A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function may only be used with iterators created by function
+ ** [sqlite3changeset_start()]. If it is called on an iterator passed to
+@@ -10314,6 +11021,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -10348,6 +11056,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain The Primary Key Definition Of A Table
++** METHOD: sqlite3_changeset_iter
+ **
+ ** For each modified table, a changeset includes the following:
+ **
+@@ -10379,6 +11088,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain old.* Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -10409,6 +11119,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain new.* Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -10442,6 +11153,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function should only be used with iterator objects passed to a
+ ** conflict-handler callback by [sqlite3changeset_apply()] with either
+@@ -10469,6 +11181,7 @@
+ 
+ /*
+ ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function may only be called with an iterator passed to an
+ ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+@@ -10485,6 +11198,7 @@
+ 
+ /*
+ ** CAPI3REF: Finalize A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function is used to finalize an iterator allocated with
+ ** [sqlite3changeset_start()].
+@@ -10501,6 +11215,7 @@
+ ** to that error is returned by this function. Otherwise, SQLITE_OK is
+ ** returned. This is to allow the following pattern (pseudo-code):
+ **
++** <pre>
+ **   sqlite3changeset_start();
+ **   while( SQLITE_ROW==sqlite3changeset_next() ){
+ **     // Do something with change.
+@@ -10509,6 +11224,7 @@
+ **   if( rc!=SQLITE_OK ){
+ **     // An error has occurred 
+ **   }
++** </pre>
+ */
+ SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+ 
+@@ -10556,6 +11272,7 @@
+ ** sqlite3_changegroup object. Calling it produces similar results as the
+ ** following code fragment:
+ **
++** <pre>
+ **   sqlite3_changegroup *pGrp;
+ **   rc = sqlite3_changegroup_new(&pGrp);
+ **   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+@@ -10566,6 +11283,7 @@
+ **     *ppOut = 0;
+ **     *pnOut = 0;
+ **   }
++** </pre>
+ **
+ ** Refer to the sqlite3_changegroup documentation below for details.
+ */
+@@ -10581,11 +11299,15 @@
+ 
+ /*
+ ** CAPI3REF: Changegroup Handle
++**
++** A changegroup is an object used to combine two or more 
++** [changesets] or [patchsets]
+ */
+ typedef struct sqlite3_changegroup sqlite3_changegroup;
+ 
+ /*
+ ** CAPI3REF: Create A New Changegroup Object
++** CONSTRUCTOR: sqlite3_changegroup
+ **
+ ** An sqlite3_changegroup object is used to combine two or more changesets
+ ** (or patchsets) into a single changeset (or patchset). A single changegroup
+@@ -10623,6 +11345,7 @@
+ 
+ /*
+ ** CAPI3REF: Add A Changeset To A Changegroup
++** METHOD: sqlite3_changegroup
+ **
+ ** Add all changes within the changeset (or patchset) in buffer pData (size
+ ** nData bytes) to the changegroup. 
+@@ -10700,6 +11423,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain A Composite Changeset From A Changegroup
++** METHOD: sqlite3_changegroup
+ **
+ ** Obtain a buffer containing a changeset (or patchset) representing the
+ ** current contents of the changegroup. If the inputs to the changegroup
+@@ -10730,6 +11454,7 @@
+ 
+ /*
+ ** CAPI3REF: Delete A Changegroup Object
++** DESTRUCTOR: sqlite3_changegroup
+ */
+ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+ 
+@@ -10736,19 +11461,18 @@
+ /*
+ ** CAPI3REF: Apply A Changeset To A Database
+ **
+-** Apply a changeset to a database. This function attempts to update the
+-** "main" database attached to handle db with the changes found in the
+-** changeset passed via the second and third arguments.
++** Apply a changeset or patchset to a database. These functions attempt to
++** update the "main" database attached to handle db with the changes found in
++** the changeset passed via the second and third arguments. 
+ **
+-** The fourth argument (xFilter) passed to this function is the "filter
++** The fourth argument (xFilter) passed to these functions is the "filter
+ ** callback". If it is not NULL, then for each table affected by at least one
+ ** change in the changeset, the filter callback is invoked with
+ ** the table name as the second argument, and a copy of the context pointer
+-** passed as the sixth argument to this function as the first. If the "filter
+-** callback" returns zero, then no attempt is made to apply any changes to 
+-** the table. Otherwise, if the return value is non-zero or the xFilter
+-** argument to this function is NULL, all changes related to the table are
+-** attempted.
++** passed as the sixth argument as the first. If the "filter callback"
++** returns zero, then no attempt is made to apply any changes to the table.
++** Otherwise, if the return value is non-zero or the xFilter argument to
++** is NULL, all changes related to the table are attempted.
+ **
+ ** For each table that is not excluded by the filter callback, this function 
+ ** tests that the target database contains a compatible table. A table is 
+@@ -10793,7 +11517,7 @@
+ **
+ ** <dl>
+ ** <dt>DELETE Changes<dd>
+-**   For each DELETE change, this function checks if the target database 
++**   For each DELETE change, the function checks if the target database 
+ **   contains a row with the same primary key value (or values) as the 
+ **   original row values stored in the changeset. If it does, and the values 
+ **   stored in all non-primary key columns also match the values stored in 
+@@ -10838,7 +11562,7 @@
+ **   [SQLITE_CHANGESET_REPLACE].
+ **
+ ** <dt>UPDATE Changes<dd>
+-**   For each UPDATE change, this function checks if the target database 
++**   For each UPDATE change, the function checks if the target database 
+ **   contains a row with the same primary key value (or values) as the 
+ **   original row values stored in the changeset. If it does, and the values 
+ **   stored in all modified non-primary key columns also match the values
+@@ -10869,11 +11593,28 @@
+ ** This can be used to further customize the applications conflict
+ ** resolution strategy.
+ **
+-** All changes made by this function are enclosed in a savepoint transaction.
++** All changes made by these functions are enclosed in a savepoint transaction.
+ ** If any other error (aside from a constraint failure when attempting to
+ ** write to the target database) occurs, then the savepoint transaction is
+ ** rolled back, restoring the target database to its original state, and an 
+ ** SQLite error code returned.
++**
++** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
++** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
++** may set (*ppRebase) to point to a "rebase" that may be used with the 
++** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
++** is set to the size of the buffer in bytes. It is the responsibility of the
++** caller to eventually free any such buffer using sqlite3_free(). The buffer
++** is only allocated and populated if one or more conflicts were encountered
++** while applying the patchset. See comments surrounding the sqlite3_rebaser
++** APIs for further details.
++**
++** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
++**
++** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_apply(
+   sqlite3 *db,                    /* Apply change to "main" db of this handle */
+@@ -10890,7 +11631,48 @@
+   ),
+   void *pCtx                      /* First argument passed to xConflict */
+ );
++SQLITE_API int sqlite3changeset_apply_v2(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase, /* OUT: Rebase data */
++  int flags                       /* SESSION_CHANGESETAPPLY_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_apply_v2
++**
++** The following flags may passed via the 9th parameter to
++** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
++**
++** <dl>
++** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
++**   Usually, the sessions module encloses all operations performed by
++**   a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
++**   SAVEPOINT is committed if the changeset or patchset is successfully
++**   applied, or rolled back if an error occurs. Specifying this flag
++**   causes the sessions module to omit this savepoint. In this case, if the
++**   caller has an open transaction or savepoint when apply_v2() is called, 
++**   it may revert the partially applied changeset by rolling it back.
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset before applying it. This is equivalent to inverting
++**   a changeset using sqlite3changeset_invert() before applying it. It is
++**   an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
++#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
++
+ /* 
+ ** CAPI3REF: Constants Passed To The Conflict Handler
+ **
+@@ -10987,7 +11769,162 @@
+ #define SQLITE_CHANGESET_REPLACE    1
+ #define SQLITE_CHANGESET_ABORT      2
+ 
++/* 
++** CAPI3REF: Rebasing changesets
++** EXPERIMENTAL
++**
++** Suppose there is a site hosting a database in state S0. And that
++** modifications are made that move that database to state S1 and a
++** changeset recorded (the "local" changeset). Then, a changeset based
++** on S0 is received from another site (the "remote" changeset) and 
++** applied to the database. The database is then in state 
++** (S1+"remote"), where the exact state depends on any conflict
++** resolution decisions (OMIT or REPLACE) made while applying "remote".
++** Rebasing a changeset is to update it to take those conflict 
++** resolution decisions into account, so that the same conflicts
++** do not have to be resolved elsewhere in the network. 
++**
++** For example, if both the local and remote changesets contain an
++** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
++**
++**   local:  INSERT INTO t1 VALUES(1, 'v1');
++**   remote: INSERT INTO t1 VALUES(1, 'v2');
++**
++** and the conflict resolution is REPLACE, then the INSERT change is
++** removed from the local changeset (it was overridden). Or, if the
++** conflict resolution was "OMIT", then the local changeset is modified
++** to instead contain:
++**
++**           UPDATE t1 SET b = 'v2' WHERE a=1;
++**
++** Changes within the local changeset are rebased as follows:
++**
++** <dl>
++** <dt>Local INSERT<dd>
++**   This may only conflict with a remote INSERT. If the conflict 
++**   resolution was OMIT, then add an UPDATE change to the rebased
++**   changeset. Or, if the conflict resolution was REPLACE, add
++**   nothing to the rebased changeset.
++**
++** <dt>Local DELETE<dd>
++**   This may conflict with a remote UPDATE or DELETE. In both cases the
++**   only possible resolution is OMIT. If the remote operation was a
++**   DELETE, then add no change to the rebased changeset. If the remote
++**   operation was an UPDATE, then the old.* fields of change are updated
++**   to reflect the new.* values in the UPDATE.
++**
++** <dt>Local UPDATE<dd>
++**   This may conflict with a remote UPDATE or DELETE. If it conflicts
++**   with a DELETE, and the conflict resolution was OMIT, then the update
++**   is changed into an INSERT. Any undefined values in the new.* record
++**   from the update change are filled in using the old.* values from
++**   the conflicting DELETE. Or, if the conflict resolution was REPLACE,
++**   the UPDATE change is simply omitted from the rebased changeset.
++**
++**   If conflict is with a remote UPDATE and the resolution is OMIT, then
++**   the old.* values are rebased using the new.* values in the remote
++**   change. Or, if the resolution is REPLACE, then the change is copied
++**   into the rebased changeset with updates to columns also updated by
++**   the conflicting remote UPDATE removed. If this means no columns would 
++**   be updated, the change is omitted.
++** </dl>
++**
++** A local change may be rebased against multiple remote changes 
++** simultaneously. If a single key is modified by multiple remote 
++** changesets, they are combined as follows before the local changeset
++** is rebased:
++**
++** <ul>
++**    <li> If there has been one or more REPLACE resolutions on a
++**         key, it is rebased according to a REPLACE.
++**
++**    <li> If there have been no REPLACE resolutions on a key, then
++**         the local changeset is rebased according to the most recent
++**         of the OMIT resolutions.
++** </ul>
++**
++** Note that conflict resolutions from multiple remote changesets are 
++** combined on a per-field basis, not per-row. This means that in the 
++** case of multiple remote UPDATE operations, some fields of a single 
++** local change may be rebased for REPLACE while others are rebased for 
++** OMIT.
++**
++** In order to rebase a local changeset, the remote changeset must first
++** be applied to the local database using sqlite3changeset_apply_v2() and
++** the buffer of rebase information captured. Then:
++**
++** <ol>
++**   <li> An sqlite3_rebaser object is created by calling 
++**        sqlite3rebaser_create().
++**   <li> The new object is configured with the rebase buffer obtained from
++**        sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
++**        If the local changeset is to be rebased against multiple remote
++**        changesets, then sqlite3rebaser_configure() should be called
++**        multiple times, in the same order that the multiple
++**        sqlite3changeset_apply_v2() calls were made.
++**   <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
++**   <li> The sqlite3_rebaser object is deleted by calling
++**        sqlite3rebaser_delete().
++** </ol>
++*/
++typedef struct sqlite3_rebaser sqlite3_rebaser;
++
+ /*
++** CAPI3REF: Create a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
++** point to the new object and return SQLITE_OK. Otherwise, if an error
++** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) 
++** to NULL. 
++*/
++SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
++
++/*
++** CAPI3REF: Configure a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Configure the changeset rebaser object to rebase changesets according
++** to the conflict resolutions described by buffer pRebase (size nRebase
++** bytes), which must have been obtained from a previous call to
++** sqlite3changeset_apply_v2().
++*/
++SQLITE_API int sqlite3rebaser_configure(
++  sqlite3_rebaser*, 
++  int nRebase, const void *pRebase
++); 
++
++/*
++** CAPI3REF: Rebase a changeset
++** EXPERIMENTAL
++**
++** Argument pIn must point to a buffer containing a changeset nIn bytes
++** in size. This function allocates and populates a buffer with a copy
++** of the changeset rebased rebased according to the configuration of the
++** rebaser object passed as the first argument. If successful, (*ppOut)
++** is set to point to the new buffer containing the rebased changset and 
++** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
++** responsibility of the caller to eventually free the new buffer using
++** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
++** are set to zero and an SQLite error code returned.
++*/
++SQLITE_API int sqlite3rebaser_rebase(
++  sqlite3_rebaser*,
++  int nIn, const void *pIn, 
++  int *pnOut, void **ppOut 
++);
++
++/*
++** CAPI3REF: Delete a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Delete the changeset rebaser object and all associated resources. There
++** should be one call to this function for each successful invocation
++** of sqlite3rebaser_create().
++*/
++SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); 
++
++/*
+ ** CAPI3REF: Streaming Versions of API functions.
+ **
+ ** The six streaming API xxx_strm() functions serve similar purposes to the 
+@@ -10995,12 +11932,13 @@
+ **
+ ** <table border=1 style="margin-left:8ex;margin-right:8ex">
+ **   <tr><th>Streaming function<th>Non-streaming equivalent</th>
+-**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
+-**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
+-**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
+-**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
+-**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
+-**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
++**   <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] 
++**   <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] 
++**   <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] 
++**   <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] 
++**   <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] 
++**   <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] 
++**   <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] 
+ ** </table>
+ **
+ ** Non-streaming functions that accept changesets (or patchsets) as input
+@@ -11091,6 +12029,23 @@
+   ),
+   void *pCtx                      /* First argument passed to xConflict */
+ );
++SQLITE_API int sqlite3changeset_apply_v2_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase,
++  int flags
++);
+ SQLITE_API int sqlite3changeset_concat_strm(
+   int (*xInputA)(void *pIn, void *pData, int *pnData),
+   void *pInA,
+@@ -11110,6 +12065,12 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ );
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++);
+ SQLITE_API int sqlite3session_changeset_strm(
+   sqlite3_session *pSession,
+   int (*xOutput)(void *pOut, const void *pData, int nData),
+@@ -11128,9 +12089,55 @@
+     int (*xOutput)(void *pOut, const void *pData, int nData), 
+     void *pOut
+ );
++SQLITE_API int sqlite3rebaser_rebase_strm(
++  sqlite3_rebaser *pRebaser,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
+ 
++/*
++** CAPI3REF: Configure global parameters
++**
++** The sqlite3session_config() interface is used to make global configuration
++** changes to the sessions module in order to tune it to the specific needs 
++** of the application.
++**
++** The sqlite3session_config() interface is not threadsafe. If it is invoked
++** while any other thread is inside any other sessions method then the
++** results are undefined. Furthermore, if it is invoked after any sessions
++** related objects have been created, the results are also undefined. 
++**
++** The first argument to the sqlite3session_config() function must be one
++** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The 
++** interpretation of the (void*) value passed as the second parameter and
++** the effect of calling this function depends on the value of the first
++** parameter.
++**
++** <dl>
++** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
++**    By default, the sessions module streaming interfaces attempt to input
++**    and output data in approximately 1 KiB chunks. This operand may be used
++**    to set and query the value of this configuration setting. The pointer
++**    passed as the second argument must point to a value of type (int).
++**    If this value is greater than 0, it is used as the new streaming data
++**    chunk size for both input and output. Before returning, the (int) value
++**    pointed to by pArg is set to the final value of the streaming interface
++**    chunk size.
++** </dl>
++**
++** This function returns SQLITE_OK if successful, or an SQLite error code
++** otherwise.
++*/
++SQLITE_API int sqlite3session_config(int op, void *pArg);
+ 
+ /*
++** CAPI3REF: Values for sqlite3session_config().
++*/
++#define SQLITE_SESSION_CONFIG_STRMSIZE 1
++
++/*
+ ** Make sure we can call this stuff from C++.
+ */
+ #if 0
+@@ -11586,7 +12593,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -11614,7 +12621,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+@@ -12221,6 +13228,21 @@
+ #endif
+ 
+ /*
++** Some conditionals are optimizations only.  In other words, if the
++** conditionals are replaced with a constant 1 (true) or 0 (false) then
++** the correct answer is still obtained, though perhaps not as quickly.
++**
++** The following macros mark these optimizations conditionals.
++*/
++#if defined(SQLITE_MUTATION_TEST)
++# define OK_IF_ALWAYS_TRUE(X)  (1)
++# define OK_IF_ALWAYS_FALSE(X) (0)
++#else
++# define OK_IF_ALWAYS_TRUE(X)  (X)
++# define OK_IF_ALWAYS_FALSE(X) (X)
++#endif
++
++/*
+ ** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is
+ ** defined.  We need to defend against those failures when testing with
+ ** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches
+@@ -12414,144 +13436,153 @@
+ #define TK_AS                              24
+ #define TK_WITHOUT                         25
+ #define TK_COMMA                           26
+-#define TK_ID                              27
+-#define TK_ABORT                           28
+-#define TK_ACTION                          29
+-#define TK_AFTER                           30
+-#define TK_ANALYZE                         31
+-#define TK_ASC                             32
+-#define TK_ATTACH                          33
+-#define TK_BEFORE                          34
+-#define TK_BY                              35
+-#define TK_CASCADE                         36
+-#define TK_CAST                            37
+-#define TK_COLUMNKW                        38
+-#define TK_CONFLICT                        39
+-#define TK_DATABASE                        40
+-#define TK_DESC                            41
+-#define TK_DETACH                          42
+-#define TK_EACH                            43
+-#define TK_FAIL                            44
+-#define TK_FOR                             45
+-#define TK_IGNORE                          46
+-#define TK_INITIALLY                       47
+-#define TK_INSTEAD                         48
+-#define TK_LIKE_KW                         49
+-#define TK_MATCH                           50
+-#define TK_NO                              51
+-#define TK_KEY                             52
+-#define TK_OF                              53
+-#define TK_OFFSET                          54
+-#define TK_PRAGMA                          55
+-#define TK_RAISE                           56
+-#define TK_RECURSIVE                       57
+-#define TK_REPLACE                         58
+-#define TK_RESTRICT                        59
+-#define TK_ROW                             60
+-#define TK_TRIGGER                         61
+-#define TK_VACUUM                          62
+-#define TK_VIEW                            63
+-#define TK_VIRTUAL                         64
+-#define TK_WITH                            65
+-#define TK_REINDEX                         66
+-#define TK_RENAME                          67
+-#define TK_CTIME_KW                        68
+-#define TK_ANY                             69
+-#define TK_OR                              70
+-#define TK_AND                             71
+-#define TK_IS                              72
+-#define TK_BETWEEN                         73
+-#define TK_IN                              74
+-#define TK_ISNULL                          75
+-#define TK_NOTNULL                         76
+-#define TK_NE                              77
+-#define TK_EQ                              78
+-#define TK_GT                              79
+-#define TK_LE                              80
+-#define TK_LT                              81
+-#define TK_GE                              82
+-#define TK_ESCAPE                          83
+-#define TK_BITAND                          84
+-#define TK_BITOR                           85
+-#define TK_LSHIFT                          86
+-#define TK_RSHIFT                          87
+-#define TK_PLUS                            88
+-#define TK_MINUS                           89
+-#define TK_STAR                            90
+-#define TK_SLASH                           91
+-#define TK_REM                             92
+-#define TK_CONCAT                          93
+-#define TK_COLLATE                         94
+-#define TK_BITNOT                          95
+-#define TK_INDEXED                         96
+-#define TK_STRING                          97
+-#define TK_JOIN_KW                         98
+-#define TK_CONSTRAINT                      99
+-#define TK_DEFAULT                        100
+-#define TK_NULL                           101
+-#define TK_PRIMARY                        102
+-#define TK_UNIQUE                         103
+-#define TK_CHECK                          104
+-#define TK_REFERENCES                     105
+-#define TK_AUTOINCR                       106
+-#define TK_ON                             107
+-#define TK_INSERT                         108
+-#define TK_DELETE                         109
+-#define TK_UPDATE                         110
+-#define TK_SET                            111
+-#define TK_DEFERRABLE                     112
+-#define TK_FOREIGN                        113
+-#define TK_DROP                           114
+-#define TK_UNION                          115
+-#define TK_ALL                            116
+-#define TK_EXCEPT                         117
+-#define TK_INTERSECT                      118
+-#define TK_SELECT                         119
+-#define TK_VALUES                         120
+-#define TK_DISTINCT                       121
+-#define TK_DOT                            122
+-#define TK_FROM                           123
+-#define TK_JOIN                           124
+-#define TK_USING                          125
+-#define TK_ORDER                          126
+-#define TK_GROUP                          127
+-#define TK_HAVING                         128
+-#define TK_LIMIT                          129
+-#define TK_WHERE                          130
+-#define TK_INTO                           131
+-#define TK_FLOAT                          132
+-#define TK_BLOB                           133
+-#define TK_INTEGER                        134
+-#define TK_VARIABLE                       135
+-#define TK_CASE                           136
+-#define TK_WHEN                           137
+-#define TK_THEN                           138
+-#define TK_ELSE                           139
+-#define TK_INDEX                          140
+-#define TK_ALTER                          141
+-#define TK_ADD                            142
+-#define TK_TO_TEXT                        143
+-#define TK_TO_BLOB                        144
+-#define TK_TO_NUMERIC                     145
+-#define TK_TO_INT                         146
+-#define TK_TO_REAL                        147
+-#define TK_ISNOT                          148
+-#define TK_END_OF_FILE                    149
+-#define TK_UNCLOSED_STRING                150
+-#define TK_FUNCTION                       151
+-#define TK_COLUMN                         152
+-#define TK_AGG_FUNCTION                   153
+-#define TK_AGG_COLUMN                     154
+-#define TK_UMINUS                         155
+-#define TK_UPLUS                          156
+-#define TK_REGISTER                       157
+-#define TK_VECTOR                         158
+-#define TK_SELECT_COLUMN                  159
+-#define TK_IF_NULL_ROW                    160
+-#define TK_ASTERISK                       161
+-#define TK_SPAN                           162
+-#define TK_SPACE                          163
+-#define TK_ILLEGAL                        164
++#define TK_ABORT                           27
++#define TK_ACTION                          28
++#define TK_AFTER                           29
++#define TK_ANALYZE                         30
++#define TK_ASC                             31
++#define TK_ATTACH                          32
++#define TK_BEFORE                          33
++#define TK_BY                              34
++#define TK_CASCADE                         35
++#define TK_CAST                            36
++#define TK_CONFLICT                        37
++#define TK_DATABASE                        38
++#define TK_DESC                            39
++#define TK_DETACH                          40
++#define TK_EACH                            41
++#define TK_FAIL                            42
++#define TK_OR                              43
++#define TK_AND                             44
++#define TK_IS                              45
++#define TK_MATCH                           46
++#define TK_LIKE_KW                         47
++#define TK_BETWEEN                         48
++#define TK_IN                              49
++#define TK_ISNULL                          50
++#define TK_NOTNULL                         51
++#define TK_NE                              52
++#define TK_EQ                              53
++#define TK_GT                              54
++#define TK_LE                              55
++#define TK_LT                              56
++#define TK_GE                              57
++#define TK_ESCAPE                          58
++#define TK_ID                              59
++#define TK_COLUMNKW                        60
++#define TK_DO                              61
++#define TK_FOR                             62
++#define TK_IGNORE                          63
++#define TK_INITIALLY                       64
++#define TK_INSTEAD                         65
++#define TK_NO                              66
++#define TK_KEY                             67
++#define TK_OF                              68
++#define TK_OFFSET                          69
++#define TK_PRAGMA                          70
++#define TK_RAISE                           71
++#define TK_RECURSIVE                       72
++#define TK_REPLACE                         73
++#define TK_RESTRICT                        74
++#define TK_ROW                             75
++#define TK_ROWS                            76
++#define TK_TRIGGER                         77
++#define TK_VACUUM                          78
++#define TK_VIEW                            79
++#define TK_VIRTUAL                         80
++#define TK_WITH                            81
++#define TK_CURRENT                         82
++#define TK_FOLLOWING                       83
++#define TK_PARTITION                       84
++#define TK_PRECEDING                       85
++#define TK_RANGE                           86
++#define TK_UNBOUNDED                       87
++#define TK_REINDEX                         88
++#define TK_RENAME                          89
++#define TK_CTIME_KW                        90
++#define TK_ANY                             91
++#define TK_BITAND                          92
++#define TK_BITOR                           93
++#define TK_LSHIFT                          94
++#define TK_RSHIFT                          95
++#define TK_PLUS                            96
++#define TK_MINUS                           97
++#define TK_STAR                            98
++#define TK_SLASH                           99
++#define TK_REM                            100
++#define TK_CONCAT                         101
++#define TK_COLLATE                        102
++#define TK_BITNOT                         103
++#define TK_ON                             104
++#define TK_INDEXED                        105
++#define TK_STRING                         106
++#define TK_JOIN_KW                        107
++#define TK_CONSTRAINT                     108
++#define TK_DEFAULT                        109
++#define TK_NULL                           110
++#define TK_PRIMARY                        111
++#define TK_UNIQUE                         112
++#define TK_CHECK                          113
++#define TK_REFERENCES                     114
++#define TK_AUTOINCR                       115
++#define TK_INSERT                         116
++#define TK_DELETE                         117
++#define TK_UPDATE                         118
++#define TK_SET                            119
++#define TK_DEFERRABLE                     120
++#define TK_FOREIGN                        121
++#define TK_DROP                           122
++#define TK_UNION                          123
++#define TK_ALL                            124
++#define TK_EXCEPT                         125
++#define TK_INTERSECT                      126
++#define TK_SELECT                         127
++#define TK_VALUES                         128
++#define TK_DISTINCT                       129
++#define TK_DOT                            130
++#define TK_FROM                           131
++#define TK_JOIN                           132
++#define TK_USING                          133
++#define TK_ORDER                          134
++#define TK_GROUP                          135
++#define TK_HAVING                         136
++#define TK_LIMIT                          137
++#define TK_WHERE                          138
++#define TK_INTO                           139
++#define TK_NOTHING                        140
++#define TK_FLOAT                          141
++#define TK_BLOB                           142
++#define TK_INTEGER                        143
++#define TK_VARIABLE                       144
++#define TK_CASE                           145
++#define TK_WHEN                           146
++#define TK_THEN                           147
++#define TK_ELSE                           148
++#define TK_INDEX                          149
++#define TK_ALTER                          150
++#define TK_ADD                            151
++#define TK_WINDOW                         152
++#define TK_OVER                           153
++#define TK_FILTER                         154
++#define TK_TRUEFALSE                      155
++#define TK_ISNOT                          156
++#define TK_FUNCTION                       157
++#define TK_COLUMN                         158
++#define TK_AGG_FUNCTION                   159
++#define TK_AGG_COLUMN                     160
++#define TK_UMINUS                         161
++#define TK_UPLUS                          162
++#define TK_TRUTH                          163
++#define TK_REGISTER                       164
++#define TK_VECTOR                         165
++#define TK_SELECT_COLUMN                  166
++#define TK_IF_NULL_ROW                    167
++#define TK_ASTERISK                       168
++#define TK_SPAN                           169
++#define TK_END_OF_FILE                    170
++#define TK_UNCLOSED_STRING                171
++#define TK_SPACE                          172
++#define TK_ILLEGAL                        173
+ 
+ /* The token codes above must all fit in 8 bits */
+ #define TKFLG_MASK           0xff  
+@@ -12672,6 +13703,22 @@
+ #endif
+ 
+ /*
++** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option.
++*/
++#ifndef SQLITE_DEFAULT_SORTERREF_SIZE
++# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff
++#endif
++
++/*
++** The compile-time options SQLITE_MMAP_READWRITE and 
++** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
++** You must choose one or the other (or neither) but not both.
++*/
++#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++#endif
++
++/*
+ ** GCC does not define the offsetof() macro so we'll have to do it
+ ** ourselves.
+ */
+@@ -12809,7 +13856,8 @@
+ # if defined(__SIZEOF_POINTER__)
+ #   define SQLITE_PTRSIZE __SIZEOF_POINTER__
+ # elif defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+-       defined(_M_ARM)   || defined(__arm__)    || defined(__x86)
++       defined(_M_ARM)   || defined(__arm__)    || defined(__x86)   ||    \
++      (defined(__TOS_AIX__) && !defined(__64BIT__))
+ #   define SQLITE_PTRSIZE 4
+ # else
+ #   define SQLITE_PTRSIZE 8
+@@ -12850,7 +13898,7 @@
+ # if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+      defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
+      defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
+-     defined(__arm__)
++     defined(__arm__)  || defined(_M_ARM64)
+ #   define SQLITE_BYTEORDER    1234
+ # elif defined(sparc)    || defined(__ppc__)
+ #   define SQLITE_BYTEORDER    4321
+@@ -12969,7 +14017,7 @@
+ ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
+ ** the Select query generator tracing logic is turned on.
+ */
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
++#if defined(SQLITE_ENABLE_SELECTTRACE)
+ # define SELECTTRACE_ENABLED 1
+ #else
+ # define SELECTTRACE_ENABLED 0
+@@ -12986,9 +14034,10 @@
+ */
+ typedef struct BusyHandler BusyHandler;
+ struct BusyHandler {
+-  int (*xFunc)(void *,int);  /* The busy callback */
+-  void *pArg;                /* First arg to busy callback */
+-  int nBusy;                 /* Incremented with each busy call */
++  int (*xBusyHandler)(void *,int);  /* The busy callback */
++  void *pBusyArg;                   /* First arg to busy callback */
++  int nBusy;                        /* Incremented with each busy call */
++  u8 bExtraFileArg;                 /* Include sqlite3_file as callback arg */
+ };
+ 
+ /*
+@@ -13088,7 +14137,6 @@
+ typedef struct Schema Schema;
+ typedef struct Expr Expr;
+ typedef struct ExprList ExprList;
+-typedef struct ExprSpan ExprSpan;
+ typedef struct FKey FKey;
+ typedef struct FuncDestructor FuncDestructor;
+ typedef struct FuncDef FuncDef;
+@@ -13105,6 +14153,7 @@
+ typedef struct Parse Parse;
+ typedef struct PreUpdate PreUpdate;
+ typedef struct PrintfArguments PrintfArguments;
++typedef struct RenameToken RenameToken;
+ typedef struct RowSet RowSet;
+ typedef struct Savepoint Savepoint;
+ typedef struct Select Select;
+@@ -13111,7 +14160,7 @@
+ typedef struct SQLiteThread SQLiteThread;
+ typedef struct SelectDest SelectDest;
+ typedef struct SrcList SrcList;
+-typedef struct StrAccum StrAccum;
++typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
+ typedef struct Table Table;
+ typedef struct TableLock TableLock;
+ typedef struct Token Token;
+@@ -13120,12 +14169,40 @@
+ typedef struct TriggerPrg TriggerPrg;
+ typedef struct TriggerStep TriggerStep;
+ typedef struct UnpackedRecord UnpackedRecord;
++typedef struct Upsert Upsert;
+ typedef struct VTable VTable;
+ typedef struct VtabCtx VtabCtx;
+ typedef struct Walker Walker;
+ typedef struct WhereInfo WhereInfo;
++typedef struct Window Window;
+ typedef struct With With;
+ 
++
++/*
++** The bitmask datatype defined below is used for various optimizations.
++**
++** Changing this from a 64-bit to a 32-bit type limits the number of
++** tables in a join to 32 instead of 64.  But it also reduces the size
++** of the library by 738 bytes on ix86.
++*/
++#ifdef SQLITE_BITMASK_TYPE
++  typedef SQLITE_BITMASK_TYPE Bitmask;
++#else
++  typedef u64 Bitmask;
++#endif
++
++/*
++** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
++*/
++#define BMS  ((int)(sizeof(Bitmask)*8))
++
++/*
++** A bit in a Bitmask
++*/
++#define MASKBIT(n)   (((Bitmask)1)<<(n))
++#define MASKBIT32(n) (((unsigned int)1)<<(n))
++#define ALLBITS      ((Bitmask)-1)
++
+ /* A VList object records a mapping between parameters/variables/wildcards
+ ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
+ ** variable number associated with that parameter.  See the format description
+@@ -13221,7 +14298,7 @@
+ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
+ SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
+ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
+-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
++SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*);
+ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
+ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
+ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
+@@ -13373,6 +14450,7 @@
+   struct KeyInfo*,                     /* First argument to compare function */
+   BtCursor *pCursor                    /* Space to write cursor structure */
+ );
++SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
+ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
+ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
+ SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
+@@ -13401,14 +14479,29 @@
+ ** entry in either an index or table btree.
+ **
+ ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
+-** an arbitrary key and no data.  These btrees have pKey,nKey set to their
+-** key and pData,nData,nZero set to zero.
++** an arbitrary key and no data.  These btrees have pKey,nKey set to the
++** key and the pData,nData,nZero fields are uninitialized.  The aMem,nMem
++** fields give an array of Mem objects that are a decomposition of the key.
++** The nMem field might be zero, indicating that no decomposition is available.
+ **
+ ** Table btrees (used for rowid tables) contain an integer rowid used as
+ ** the key and passed in the nKey field.  The pKey field is zero.  
+ ** pData,nData hold the content of the new entry.  nZero extra zero bytes
+ ** are appended to the end of the content when constructing the entry.
++** The aMem,nMem fields are uninitialized for table btrees.
+ **
++** Field usage summary:
++**
++**               Table BTrees                   Index Btrees
++**
++**   pKey        always NULL                    encoded key
++**   nKey        the ROWID                      length of pKey
++**   pData       data                           not used
++**   aMem        not used                       decomposed key value
++**   nMem        not used                       entries in aMem
++**   nData       length of pData                not used
++**   nZero       extra zeros after pData        not used
++**
+ ** This object is used to pass information into sqlite3BtreeInsert().  The
+ ** same information used to be passed as five separate parameters.  But placing
+ ** the information into this object helps to keep the interface more 
+@@ -13418,7 +14511,7 @@
+ struct BtreePayload {
+   const void *pKey;       /* Key content for indexes.  NULL for tables */
+   sqlite3_int64 nKey;     /* Size of pKey for indexes.  PRIMARY KEY for tabs */
+-  const void *pData;      /* Data for tables.  NULL for indexes */
++  const void *pData;      /* Data for tables. */
+   sqlite3_value *aMem;    /* First of nMem value in the unpacked pKey */
+   u16 nMem;               /* Number of aMem[] value.  Might be zero */
+   int nData;              /* Size of pData.  0 if none. */
+@@ -13428,11 +14521,17 @@
+ SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
+                        int flags, int seekResult);
+ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*);
++#endif
+ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
+ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
+ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
+ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
+ SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
++SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
++#endif
+ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
+ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
+ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+@@ -13592,7 +14691,8 @@
+   u64 cycles;              /* Total time spent executing this instruction */
+ #endif
+ #ifdef SQLITE_VDBE_COVERAGE
+-  int iSrcLine;            /* Source-code line that generated this opcode */
++  u32 iSrcLine;            /* Source-code line that generated this opcode
++                           ** with flags in the upper 8 bits */
+ #endif
+ };
+ typedef struct VdbeOp VdbeOp;
+@@ -13646,6 +14746,7 @@
+ #define P4_INT64      (-14) /* P4 is a 64-bit signed integer */
+ #define P4_INTARRAY   (-15) /* P4 is a vector of 32-bit integers */
+ #define P4_FUNCCTX    (-16) /* P4 is a pointer to an sqlite3_context object */
++#define P4_DYNBLOB    (-17) /* Pointer to memory from sqliteMalloc() */
+ 
+ /* Error message codes for OP_Halt */
+ #define P5_ConstraintNotNull 1
+@@ -13691,171 +14792,177 @@
+ #define OP_Savepoint       0
+ #define OP_AutoCommit      1
+ #define OP_Transaction     2
+-#define OP_SorterNext      3
+-#define OP_PrevIfOpen      4
+-#define OP_NextIfOpen      5
+-#define OP_Prev            6
+-#define OP_Next            7
+-#define OP_Checkpoint      8
+-#define OP_JournalMode     9
+-#define OP_Vacuum         10
+-#define OP_VFilter        11 /* synopsis: iplan=r[P3] zplan='P4'           */
+-#define OP_VUpdate        12 /* synopsis: data=r[P3@P2]                    */
+-#define OP_Goto           13
+-#define OP_Gosub          14
+-#define OP_InitCoroutine  15
+-#define OP_Yield          16
+-#define OP_MustBeInt      17
+-#define OP_Jump           18
++#define OP_SorterNext      3 /* jump                                       */
++#define OP_Prev            4 /* jump                                       */
++#define OP_Next            5 /* jump                                       */
++#define OP_Checkpoint      6
++#define OP_JournalMode     7
++#define OP_Vacuum          8
++#define OP_VFilter         9 /* jump, synopsis: iplan=r[P3] zplan='P4'     */
++#define OP_VUpdate        10 /* synopsis: data=r[P3@P2]                    */
++#define OP_Goto           11 /* jump                                       */
++#define OP_Gosub          12 /* jump                                       */
++#define OP_InitCoroutine  13 /* jump                                       */
++#define OP_Yield          14 /* jump                                       */
++#define OP_MustBeInt      15 /* jump                                       */
++#define OP_Jump           16 /* jump                                       */
++#define OP_Once           17 /* jump                                       */
++#define OP_If             18 /* jump                                       */
+ #define OP_Not            19 /* same as TK_NOT, synopsis: r[P2]= !r[P1]    */
+-#define OP_Once           20
+-#define OP_If             21
+-#define OP_IfNot          22
+-#define OP_IfNullRow      23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
+-#define OP_SeekLT         24 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekLE         25 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekGE         26 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekGT         27 /* synopsis: key=r[P3@P4]                     */
+-#define OP_NoConflict     28 /* synopsis: key=r[P3@P4]                     */
+-#define OP_NotFound       29 /* synopsis: key=r[P3@P4]                     */
+-#define OP_Found          30 /* synopsis: key=r[P3@P4]                     */
+-#define OP_SeekRowid      31 /* synopsis: intkey=r[P3]                     */
+-#define OP_NotExists      32 /* synopsis: intkey=r[P3]                     */
+-#define OP_Last           33
+-#define OP_IfSmaller      34
+-#define OP_SorterSort     35
+-#define OP_Sort           36
+-#define OP_Rewind         37
+-#define OP_IdxLE          38 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxGT          39 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxLT          40 /* synopsis: key=r[P3@P4]                     */
+-#define OP_IdxGE          41 /* synopsis: key=r[P3@P4]                     */
+-#define OP_RowSetRead     42 /* synopsis: r[P3]=rowset(P1)                 */
+-#define OP_RowSetTest     43 /* synopsis: if r[P3] in rowset(P1) goto P2   */
+-#define OP_Program        44
+-#define OP_FkIfZero       45 /* synopsis: if fkctr[P1]==0 goto P2          */
+-#define OP_IfPos          46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+-#define OP_IfNotZero      47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+-#define OP_DecrJumpZero   48 /* synopsis: if (--r[P1])==0 goto P2          */
+-#define OP_IncrVacuum     49
+-#define OP_VNext          50
+-#define OP_Init           51 /* synopsis: Start at P2                      */
+-#define OP_Return         52
+-#define OP_EndCoroutine   53
+-#define OP_HaltIfNull     54 /* synopsis: if r[P3]=null halt               */
+-#define OP_Halt           55
+-#define OP_Integer        56 /* synopsis: r[P2]=P1                         */
+-#define OP_Int64          57 /* synopsis: r[P2]=P4                         */
+-#define OP_String         58 /* synopsis: r[P2]='P4' (len=P1)              */
+-#define OP_Null           59 /* synopsis: r[P2..P3]=NULL                   */
+-#define OP_SoftNull       60 /* synopsis: r[P1]=NULL                       */
+-#define OP_Blob           61 /* synopsis: r[P2]=P4 (len=P1)                */
+-#define OP_Variable       62 /* synopsis: r[P2]=parameter(P1,P4)           */
+-#define OP_Move           63 /* synopsis: r[P2@P3]=r[P1@P3]                */
+-#define OP_Copy           64 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+-#define OP_SCopy          65 /* synopsis: r[P2]=r[P1]                      */
+-#define OP_IntCopy        66 /* synopsis: r[P2]=r[P1]                      */
+-#define OP_ResultRow      67 /* synopsis: output=r[P1@P2]                  */
+-#define OP_CollSeq        68
+-#define OP_AddImm         69 /* synopsis: r[P1]=r[P1]+P2                   */
+-#define OP_Or             70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+-#define OP_And            71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+-#define OP_RealAffinity   72
+-#define OP_Cast           73 /* synopsis: affinity(r[P1])                  */
+-#define OP_Permutation    74
+-#define OP_IsNull         75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+-#define OP_NotNull        76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+-#define OP_Ne             77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1]   */
+-#define OP_Eq             78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1]   */
+-#define OP_Gt             79 /* same as TK_GT, synopsis: IF r[P3]>r[P1]    */
+-#define OP_Le             80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1]   */
+-#define OP_Lt             81 /* same as TK_LT, synopsis: IF r[P3]<r[P1]    */
+-#define OP_Ge             82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1]   */
+-#define OP_ElseNotEq      83 /* same as TK_ESCAPE                          */
+-#define OP_BitAnd         84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+-#define OP_BitOr          85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+-#define OP_ShiftLeft      86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+-#define OP_ShiftRight     87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+-#define OP_Add            88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+-#define OP_Subtract       89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+-#define OP_Multiply       90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+-#define OP_Divide         91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+-#define OP_Remainder      92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+-#define OP_Concat         93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+-#define OP_Compare        94 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
+-#define OP_BitNot         95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+-#define OP_Column         96 /* synopsis: r[P3]=PX                         */
+-#define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
+-#define OP_Affinity       98 /* synopsis: affinity(r[P1@P2])               */
+-#define OP_MakeRecord     99 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+-#define OP_Count         100 /* synopsis: r[P2]=count()                    */
+-#define OP_ReadCookie    101
+-#define OP_SetCookie     102
+-#define OP_ReopenIdx     103 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenRead      104 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenWrite     105 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenDup       106
+-#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2                       */
+-#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2                       */
+-#define OP_SorterOpen    109
+-#define OP_SequenceTest  110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+-#define OP_OpenPseudo    111 /* synopsis: P3 columns in r[P2]              */
+-#define OP_Close         112
+-#define OP_ColumnsUsed   113
+-#define OP_Sequence      114 /* synopsis: r[P2]=cursor[P1].ctr++           */
+-#define OP_NewRowid      115 /* synopsis: r[P2]=rowid                      */
+-#define OP_Insert        116 /* synopsis: intkey=r[P3] data=r[P2]          */
+-#define OP_InsertInt     117 /* synopsis: intkey=P3 data=r[P2]             */
+-#define OP_Delete        118
+-#define OP_ResetCount    119
+-#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+-#define OP_SorterData    121 /* synopsis: r[P2]=data                       */
+-#define OP_RowData       122 /* synopsis: r[P2]=data                       */
+-#define OP_Rowid         123 /* synopsis: r[P2]=rowid                      */
+-#define OP_NullRow       124
+-#define OP_SorterInsert  125 /* synopsis: key=r[P2]                        */
+-#define OP_IdxInsert     126 /* synopsis: key=r[P2]                        */
+-#define OP_IdxDelete     127 /* synopsis: key=r[P2@P3]                     */
+-#define OP_DeferredSeek  128 /* synopsis: Move P3 to P1.rowid if needed    */
+-#define OP_IdxRowid      129 /* synopsis: r[P2]=rowid                      */
+-#define OP_Destroy       130
+-#define OP_Clear         131
+-#define OP_Real          132 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
+-#define OP_ResetSorter   133
+-#define OP_CreateIndex   134 /* synopsis: r[P2]=root iDb=P1                */
+-#define OP_CreateTable   135 /* synopsis: r[P2]=root iDb=P1                */
+-#define OP_SqlExec       136
+-#define OP_ParseSchema   137
+-#define OP_LoadAnalysis  138
+-#define OP_DropTable     139
+-#define OP_DropIndex     140
+-#define OP_DropTrigger   141
+-#define OP_IntegrityCk   142
+-#define OP_RowSetAdd     143 /* synopsis: rowset(P1)=r[P2]                 */
+-#define OP_Param         144
+-#define OP_FkCounter     145 /* synopsis: fkctr[P1]+=P2                    */
+-#define OP_MemMax        146 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+-#define OP_OffsetLimit   147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+-#define OP_AggStep0      148 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+-#define OP_AggStep       149 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+-#define OP_AggFinal      150 /* synopsis: accum=r[P1] N=P2                 */
+-#define OP_Expire        151
+-#define OP_TableLock     152 /* synopsis: iDb=P1 root=P2 write=P3          */
+-#define OP_VBegin        153
+-#define OP_VCreate       154
+-#define OP_VDestroy      155
+-#define OP_VOpen         156
+-#define OP_VColumn       157 /* synopsis: r[P3]=vcolumn(P2)                */
+-#define OP_VRename       158
+-#define OP_Pagecount     159
+-#define OP_MaxPgcnt      160
+-#define OP_PureFunc0     161
+-#define OP_Function0     162 /* synopsis: r[P3]=func(r[P2@P5])             */
+-#define OP_PureFunc      163
+-#define OP_Function      164 /* synopsis: r[P3]=func(r[P2@P5])             */
+-#define OP_CursorHint    165
+-#define OP_Noop          166
+-#define OP_Explain       167
++#define OP_IfNot          20 /* jump                                       */
++#define OP_IfNullRow      21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
++#define OP_SeekLT         22 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekLE         23 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekGE         24 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekGT         25 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IfNoHope       26 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_NoConflict     27 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_NotFound       28 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_Found          29 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekRowid      30 /* jump, synopsis: intkey=r[P3]               */
++#define OP_NotExists      31 /* jump, synopsis: intkey=r[P3]               */
++#define OP_Last           32 /* jump                                       */
++#define OP_IfSmaller      33 /* jump                                       */
++#define OP_SorterSort     34 /* jump                                       */
++#define OP_Sort           35 /* jump                                       */
++#define OP_Rewind         36 /* jump                                       */
++#define OP_IdxLE          37 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxGT          38 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxLT          39 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxGE          40 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_RowSetRead     41 /* jump, synopsis: r[P3]=rowset(P1)           */
++#define OP_RowSetTest     42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
++#define OP_Or             43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
++#define OP_And            44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
++#define OP_Program        45 /* jump                                       */
++#define OP_FkIfZero       46 /* jump, synopsis: if fkctr[P1]==0 goto P2    */
++#define OP_IfPos          47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
++#define OP_IfNotZero      48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
++#define OP_DecrJumpZero   49 /* jump, synopsis: if (--r[P1])==0 goto P2    */
++#define OP_IsNull         50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
++#define OP_NotNull        51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
++#define OP_Ne             52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
++#define OP_Eq             53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
++#define OP_Gt             54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
++#define OP_Le             55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
++#define OP_Lt             56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
++#define OP_Ge             57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
++#define OP_ElseNotEq      58 /* jump, same as TK_ESCAPE                    */
++#define OP_IncrVacuum     59 /* jump                                       */
++#define OP_VNext          60 /* jump                                       */
++#define OP_Init           61 /* jump, synopsis: Start at P2                */
++#define OP_PureFunc0      62
++#define OP_Function0      63 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_PureFunc       64
++#define OP_Function       65 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_Return         66
++#define OP_EndCoroutine   67
++#define OP_HaltIfNull     68 /* synopsis: if r[P3]=null halt               */
++#define OP_Halt           69
++#define OP_Integer        70 /* synopsis: r[P2]=P1                         */
++#define OP_Int64          71 /* synopsis: r[P2]=P4                         */
++#define OP_String         72 /* synopsis: r[P2]='P4' (len=P1)              */
++#define OP_Null           73 /* synopsis: r[P2..P3]=NULL                   */
++#define OP_SoftNull       74 /* synopsis: r[P1]=NULL                       */
++#define OP_Blob           75 /* synopsis: r[P2]=P4 (len=P1)                */
++#define OP_Variable       76 /* synopsis: r[P2]=parameter(P1,P4)           */
++#define OP_Move           77 /* synopsis: r[P2@P3]=r[P1@P3]                */
++#define OP_Copy           78 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
++#define OP_SCopy          79 /* synopsis: r[P2]=r[P1]                      */
++#define OP_IntCopy        80 /* synopsis: r[P2]=r[P1]                      */
++#define OP_ResultRow      81 /* synopsis: output=r[P1@P2]                  */
++#define OP_CollSeq        82
++#define OP_AddImm         83 /* synopsis: r[P1]=r[P1]+P2                   */
++#define OP_RealAffinity   84
++#define OP_Cast           85 /* synopsis: affinity(r[P1])                  */
++#define OP_Permutation    86
++#define OP_Compare        87 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
++#define OP_IsTrue         88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
++#define OP_Offset         89 /* synopsis: r[P3] = sqlite_offset(P1)        */
++#define OP_Column         90 /* synopsis: r[P3]=PX                         */
++#define OP_Affinity       91 /* synopsis: affinity(r[P1@P2])               */
++#define OP_BitAnd         92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
++#define OP_BitOr          93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
++#define OP_ShiftLeft      94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
++#define OP_ShiftRight     95 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
++#define OP_Add            96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
++#define OP_Subtract       97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
++#define OP_Multiply       98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
++#define OP_Divide         99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
++#define OP_Remainder     100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
++#define OP_Concat        101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
++#define OP_MakeRecord    102 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
++#define OP_BitNot        103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
++#define OP_Count         104 /* synopsis: r[P2]=count()                    */
++#define OP_ReadCookie    105
++#define OP_String8       106 /* same as TK_STRING, synopsis: r[P2]='P4'    */
++#define OP_SetCookie     107
++#define OP_ReopenIdx     108 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenRead      109 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenWrite     110 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenDup       111
++#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2                       */
++#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2                       */
++#define OP_SorterOpen    114
++#define OP_SequenceTest  115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
++#define OP_OpenPseudo    116 /* synopsis: P3 columns in r[P2]              */
++#define OP_Close         117
++#define OP_ColumnsUsed   118
++#define OP_SeekHit       119 /* synopsis: seekHit=P2                       */
++#define OP_Sequence      120 /* synopsis: r[P2]=cursor[P1].ctr++           */
++#define OP_NewRowid      121 /* synopsis: r[P2]=rowid                      */
++#define OP_Insert        122 /* synopsis: intkey=r[P3] data=r[P2]          */
++#define OP_InsertInt     123 /* synopsis: intkey=P3 data=r[P2]             */
++#define OP_Delete        124
++#define OP_ResetCount    125
++#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
++#define OP_SorterData    127 /* synopsis: r[P2]=data                       */
++#define OP_RowData       128 /* synopsis: r[P2]=data                       */
++#define OP_Rowid         129 /* synopsis: r[P2]=rowid                      */
++#define OP_NullRow       130
++#define OP_SeekEnd       131
++#define OP_SorterInsert  132 /* synopsis: key=r[P2]                        */
++#define OP_IdxInsert     133 /* synopsis: key=r[P2]                        */
++#define OP_IdxDelete     134 /* synopsis: key=r[P2@P3]                     */
++#define OP_DeferredSeek  135 /* synopsis: Move P3 to P1.rowid if needed    */
++#define OP_IdxRowid      136 /* synopsis: r[P2]=rowid                      */
++#define OP_Destroy       137
++#define OP_Clear         138
++#define OP_ResetSorter   139
++#define OP_CreateBtree   140 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
++#define OP_Real          141 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
++#define OP_SqlExec       142
++#define OP_ParseSchema   143
++#define OP_LoadAnalysis  144
++#define OP_DropTable     145
++#define OP_DropIndex     146
++#define OP_DropTrigger   147
++#define OP_IntegrityCk   148
++#define OP_RowSetAdd     149 /* synopsis: rowset(P1)=r[P2]                 */
++#define OP_Param         150
++#define OP_FkCounter     151 /* synopsis: fkctr[P1]+=P2                    */
++#define OP_MemMax        152 /* synopsis: r[P1]=max(r[P1],r[P2])           */
++#define OP_OffsetLimit   153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
++#define OP_AggInverse    154 /* synopsis: accum=r[P3] inverse(r[P2@P5])    */
++#define OP_AggStep       155 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggStep1      156 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggValue      157 /* synopsis: r[P3]=value N=P2                 */
++#define OP_AggFinal      158 /* synopsis: accum=r[P1] N=P2                 */
++#define OP_Expire        159
++#define OP_TableLock     160 /* synopsis: iDb=P1 root=P2 write=P3          */
++#define OP_VBegin        161
++#define OP_VCreate       162
++#define OP_VDestroy      163
++#define OP_VOpen         164
++#define OP_VColumn       165 /* synopsis: r[P3]=vcolumn(P2)                */
++#define OP_VRename       166
++#define OP_Pagecount     167
++#define OP_MaxPgcnt      168
++#define OP_Trace         169
++#define OP_CursorHint    170
++#define OP_Noop          171
++#define OP_Explain       172
++#define OP_Abortable     173
+ 
+ /* Properties such as "out2" or "jump" that are specified in
+ ** comments following the "case" for each opcode in the vdbe.c
+@@ -13868,28 +14975,28 @@
+ #define OPFLG_OUT2        0x10  /* out2:  P2 is an output */
+ #define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
+ #define OPFLG_INITIALIZER {\
+-/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
+-/*   8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
+-/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
++/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
++/*   8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
++/*  16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\
+ /*  24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
+-/*  32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+-/*  40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\
+-/*  48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\
+-/*  56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
+-/*  64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x02, 0x26, 0x26,\
+-/*  72 */ 0x02, 0x02, 0x00, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
+-/*  80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\
+-/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
+-/*  96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+-/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
+-/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
+-/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
+-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\
+-/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
+-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+-/* 160 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-}
++/*  32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
++/*  40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\
++/*  48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
++/*  56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\
++/*  64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
++/*  72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
++/*  80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
++/*  88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\
++/*  96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
++/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\
++/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
++/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
++/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
++/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,}
+ 
+ /* The sqlite3P2Values() routine is able to run faster if it knows
+ ** the value of the largest JUMP opcode.  The smaller the maximum
+@@ -13897,7 +15004,7 @@
+ ** generated this include file strives to group all JUMP opcodes
+ ** together near the beginning of the list.
+ */
+-#define SQLITE_MX_JUMP_OPCODE  83  /* Maximum JUMP opcode */
++#define SQLITE_MX_JUMP_OPCODE  61  /* Maximum JUMP opcode */
+ 
+ /************** End of opcodes.h *********************************************/
+ /************** Continuing where we left off in vdbe.h ***********************/
+@@ -13931,7 +15038,24 @@
+ # define sqlite3VdbeVerifyNoMallocRequired(A,B)
+ # define sqlite3VdbeVerifyNoResultRow(A)
+ #endif
+-SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
++#if defined(SQLITE_DEBUG)
++SQLITE_PRIVATE   void sqlite3VdbeVerifyAbortable(Vdbe *p, int);
++#else
++# define sqlite3VdbeVerifyAbortable(A,B)
++#endif
++SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
++#ifndef SQLITE_OMIT_EXPLAIN
++SQLITE_PRIVATE   void sqlite3VdbeExplain(Parse*,u8,const char*,...);
++SQLITE_PRIVATE   void sqlite3VdbeExplainPop(Parse*);
++SQLITE_PRIVATE   int sqlite3VdbeExplainParent(Parse*);
++# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
++# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
++# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
++#else
++# define ExplainQueryPlan(P)
++# define ExplainQueryPlanPop(P)
++# define ExplainQueryPlanParent(P) 0
++#endif
+ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
+ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
+@@ -13975,6 +15099,7 @@
+ SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
+ #endif
+ SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
++SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*);
+ 
+ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
+ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+@@ -14030,17 +15155,43 @@
+ **
+ **    VdbeCoverageNeverTaken(v)        // Previous branch is never taken
+ **
++**    VdbeCoverageNeverNull(v)         // Previous three-way branch is only
++**                                     // taken on the first two ways.  The
++**                                     // NULL option is not possible
++**
++**    VdbeCoverageEqNe(v)              // Previous OP_Jump is only interested
++**                                     // in distingishing equal and not-equal.
++**
+ ** Every VDBE branch operation must be tagged with one of the macros above.
+ ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
+ ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
+ ** routine in vdbe.c, alerting the developer to the missed tag.
++**
++** During testing, the test application will invoke
++** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback
++** routine that is invoked as each bytecode branch is taken.  The callback
++** contains the sqlite3.c source line number ov the VdbeCoverage macro and
++** flags to indicate whether or not the branch was taken.  The test application
++** is responsible for keeping track of this and reporting byte-code branches
++** that are never taken.
++**
++** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the
++** vdbe.c source file for additional information.
+ */
+ #ifdef SQLITE_VDBE_COVERAGE
+ SQLITE_PRIVATE   void sqlite3VdbeSetLineNumber(Vdbe*,int);
+ # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
+ # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
+-# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
+-# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
++# define VdbeCoverageAlwaysTaken(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000);
++# define VdbeCoverageNeverTaken(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000);
++# define VdbeCoverageNeverNull(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
++# define VdbeCoverageNeverNullIf(v,x) \
++         if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
++# define VdbeCoverageEqNe(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000);
+ # define VDBE_OFFSET_LINENO(x) (__LINE__+x)
+ #else
+ # define VdbeCoverage(v)
+@@ -14047,6 +15198,9 @@
+ # define VdbeCoverageIf(v,x)
+ # define VdbeCoverageAlwaysTaken(v)
+ # define VdbeCoverageNeverTaken(v)
++# define VdbeCoverageNeverNull(v)
++# define VdbeCoverageNeverNullIf(v,x)
++# define VdbeCoverageEqNe(v)
+ # define VDBE_OFFSET_LINENO(x) 0
+ #endif
+ 
+@@ -14056,6 +15210,10 @@
+ # define sqlite3VdbeScanStatus(a,b,c,d,e)
+ #endif
+ 
++#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
++SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*);
++#endif
++
+ #endif /* SQLITE_VDBE_H */
+ 
+ /************** End of vdbe.h ************************************************/
+@@ -14190,7 +15348,7 @@
+ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
+ 
+ /* Functions used to configure a Pager object. */
+-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
++SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
+ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
+ #ifdef SQLITE_HAS_CODEC
+ SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
+@@ -14215,6 +15373,7 @@
+ SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
+ SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
+ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*);
++SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*);
+ 
+ /* Operations on page references. */
+ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
+@@ -14242,18 +15401,19 @@
+ SQLITE_PRIVATE   int sqlite3PagerWalCallback(Pager *pPager);
+ SQLITE_PRIVATE   int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
+ SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
+-# ifdef SQLITE_DIRECT_OVERFLOW_READ
+-SQLITE_PRIVATE   int sqlite3PagerUseWal(Pager *pPager, Pgno);
+-# endif
+ # ifdef SQLITE_ENABLE_SNAPSHOT
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotRecover(Pager *pPager);
++SQLITE_PRIVATE   int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE   void sqlite3PagerSnapshotUnlock(Pager *pPager);
+ # endif
+-#else
+-# define sqlite3PagerUseWal(x,y) 0
+ #endif
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++SQLITE_PRIVATE   int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
++#endif
++
+ #ifdef SQLITE_ENABLE_ZIPVFS
+ SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
+ #endif
+@@ -14275,6 +15435,11 @@
+ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
+ SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
+ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
++#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
++SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
++#else
++# define sqlite3PagerResetLockTimeout(X)
++#endif
+ 
+ /* Functions used to truncate the database file. */
+ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
+@@ -14351,6 +15516,8 @@
+   i16 nRef;                      /* Number of users of this page */
+   PgHdr *pDirtyNext;             /* Next element in list of dirty pages */
+   PgHdr *pDirtyPrev;             /* Previous element in list of dirty pages */
++                          /* NB: pDirtyNext and pDirtyPrev are undefined if the
++                          ** PgHdr object is not dirty */
+ };
+ 
+ /* Bit values for PgHdr.flags */
+@@ -14489,6 +15656,10 @@
+ /* Number of dirty pages as a percentage of the configured cache size */
+ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
++#endif
++
+ #endif /* _PCACHE_H_ */
+ 
+ /************** End of pcache.h **********************************************/
+@@ -14732,10 +15903,12 @@
+ #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
+ SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
+ SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
++#ifndef SQLITE_OMIT_WAL
+ SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
+ SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
+ SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id);
+ SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int);
++#endif /* SQLITE_OMIT_WAL */
+ SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
+ SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
+ 
+@@ -14944,6 +16117,7 @@
+ #define DB_SchemaLoaded    0x0001  /* The schema has been loaded */
+ #define DB_UnresetViews    0x0002  /* Some views have defined column names */
+ #define DB_Empty           0x0004  /* The file is empty (length 0 bytes) */
++#define DB_ResetWanted     0x0008  /* Reset the schema when nSchemaLock==0 */
+ 
+ /*
+ ** The number of different kinds of things that can be limited
+@@ -14975,9 +16149,9 @@
+   u32 bDisable;           /* Only operate the lookaside when zero */
+   u16 sz;                 /* Size of each buffer in bytes */
+   u8 bMalloced;           /* True if pStart obtained from sqlite3_malloc() */
+-  int nOut;               /* Number of buffers currently checked out */
+-  int mxOut;              /* Highwater mark for nOut */
+-  int anStat[3];          /* 0: hits.  1: size misses.  2: full misses */
++  u32 nSlot;              /* Number of lookaside slots allocated */
++  u32 anStat[3];          /* 0: hits.  1: size misses.  2: full misses */
++  LookasideSlot *pInit;   /* List of buffers not previously used */
+   LookasideSlot *pFree;   /* List of available buffers */
+   void *pStart;           /* First byte of available memory space */
+   void *pEnd;             /* First byte past end of available space */
+@@ -14991,12 +16165,14 @@
+ ** functions use a regular table table from hash.h.)
+ **
+ ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
+-** Collisions are on the FuncDef.u.pHash chain.
++** Collisions are on the FuncDef.u.pHash chain.  Use the SQLITE_FUNC_HASH()
++** macro to compute a hash on the function name.
+ */
+ #define SQLITE_FUNC_HASH_SZ 23
+ struct FuncDefHash {
+   FuncDef *a[SQLITE_FUNC_HASH_SZ];       /* Hash table for functions */
+ };
++#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
+ 
+ #ifdef SQLITE_USER_AUTHENTICATION
+ /*
+@@ -15056,9 +16232,11 @@
+   sqlite3_mutex *mutex;         /* Connection mutex */
+   Db *aDb;                      /* All backends */
+   int nDb;                      /* Number of backends currently in use */
+-  int flags;                    /* Miscellaneous flags. See below */
++  u32 mDbFlags;                 /* flags recording internal state */
++  u64 flags;                    /* flags settable by pragmas. See below */
+   i64 lastRowid;                /* ROWID of most recent insert (see above) */
+   i64 szMmap;                   /* Default mmap_size setting */
++  u32 nSchemaLock;              /* Do not reset the schema when non-zero */
+   unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
+   int errCode;                  /* Most recent error code (SQLITE_*) */
+   int errMask;                  /* & result codes with this before returning */
+@@ -15075,7 +16253,7 @@
+   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 noSharedCache;             /* 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 */
+@@ -15087,8 +16265,9 @@
+     int newTnum;                /* Rootpage of table being initialized */
+     u8 iDb;                     /* Which db file is being initialized */
+     u8 busy;                    /* TRUE if currently initializing */
+-    u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
+-    u8 imposterTable;           /* Building an imposter table */
++    unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
++    unsigned imposterTable : 1; /* Building an imposter table */
++    unsigned reopenMemdb : 1;   /* ATTACH is really a reopen using MemDB */
+   } init;
+   int nVdbeActive;              /* Number of VDBEs currently running */
+   int nVdbeRead;                /* Number of active VDBEs that read or write */
+@@ -15141,7 +16320,7 @@
+   Hash aModule;                 /* populated by sqlite3_create_module() */
+   VtabCtx *pVtabCtx;            /* Context for active vtab connect/create */
+   VTable **aVTrans;             /* Virtual tables with open transactions */
+-  VTable *pDisconnect;    /* Disconnect these in next sqlite3_prepare() */
++  VTable *pDisconnect;          /* Disconnect these in next sqlite3_prepare() */
+ #endif
+   Hash aFunc;                   /* Hash table of connection functions */
+   Hash aCollSeq;                /* All collating sequences */
+@@ -15210,27 +16389,36 @@
+ #define SQLITE_ForeignKeys    0x00004000  /* Enforce foreign key constraints  */
+ #define SQLITE_AutoIndex      0x00008000  /* Enable automatic indexes */
+ #define SQLITE_LoadExtension  0x00010000  /* Enable load_extension */
+-#define SQLITE_EnableTrigger  0x00020000  /* True to enable triggers */
+-#define SQLITE_DeferFKs       0x00040000  /* Defer all FK constraints */
+-#define SQLITE_QueryOnly      0x00080000  /* Disable database changes */
+-#define SQLITE_CellSizeCk     0x00100000  /* Check btree cell sizes on load */
+-#define SQLITE_Fts3Tokenizer  0x00200000  /* Enable fts3_tokenizer(2) */
+-#define SQLITE_EnableQPSG     0x00400000  /* Query Planner Stability Guarantee */
+-/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
+-** could be factored out into a separate bit vector of the sqlite3 object. */
+-#define SQLITE_InternChanges  0x00800000  /* Uncommitted Hash table changes */
+-#define SQLITE_LoadExtFunc    0x01000000  /* Enable load_extension() SQL func */
+-#define SQLITE_PreferBuiltin  0x02000000  /* Preference to built-in funcs */
+-#define SQLITE_Vacuum         0x04000000  /* Currently in a VACUUM */
++#define SQLITE_LoadExtFunc    0x00020000  /* Enable load_extension() SQL func */
++#define SQLITE_EnableTrigger  0x00040000  /* True to enable triggers */
++#define SQLITE_DeferFKs       0x00080000  /* Defer all FK constraints */
++#define SQLITE_QueryOnly      0x00100000  /* Disable database changes */
++#define SQLITE_CellSizeCk     0x00200000  /* Check btree cell sizes on load */
++#define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
++#define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
++#define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
++#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
++#define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */
++#define SQLITE_NoSchemaError  0x08000000  /* Do not report schema parse errors*/
++#define SQLITE_Defensive      0x10000000  /* Input SQL is likely hostile */
++
+ /* Flags used only if debugging */
++#define HI(X)  ((u64)(X)<<32)
+ #ifdef SQLITE_DEBUG
+-#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
+-#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
+-#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
+-#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */
+-#define SQLITE_VdbeEQP        0x80000000  /* Debug EXPLAIN QUERY PLAN */
++#define SQLITE_SqlTrace       HI(0x0001)  /* Debug print SQL as it executes */
++#define SQLITE_VdbeListing    HI(0x0002)  /* Debug listings of VDBE progs */
++#define SQLITE_VdbeTrace      HI(0x0004)  /* True to trace VDBE execution */
++#define SQLITE_VdbeAddopTrace HI(0x0008)  /* Trace sqlite3VdbeAddOp() calls */
++#define SQLITE_VdbeEQP        HI(0x0010)  /* Debug EXPLAIN QUERY PLAN */
+ #endif
+ 
++/*
++** Allowed values for sqlite3.mDbFlags
++*/
++#define DBFLAG_SchemaChange   0x0001  /* Uncommitted Hash table changes */
++#define DBFLAG_PreferBuiltin  0x0002  /* Preference to built-in funcs */
++#define DBFLAG_Vacuum         0x0004  /* Currently in a VACUUM */
++#define DBFLAG_SchemaKnownOk  0x0008  /* Schema is known to be valid */
+ 
+ /*
+ ** Bits of the sqlite3.dbOptFlags field that are used by the
+@@ -15238,19 +16426,22 @@
+ ** selectively disable various optimizations.
+ */
+ #define SQLITE_QueryFlattener 0x0001   /* Query flattening */
+-#define SQLITE_ColumnCache    0x0002   /* Column cache */
++                          /*  0x0002   available for reuse */
+ #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
+ #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
+-/*                not used    0x0010   // Was: SQLITE_IdxRealAsInt */
+-#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
+-#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
+-#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
+-#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
+-#define SQLITE_Transitive     0x0200   /* Transitive constraints */
+-#define SQLITE_OmitNoopJoin   0x0400   /* Omit unused tables in joins */
++#define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
++#define SQLITE_CoverIdxScan   0x0020   /* Covering index scans */
++#define SQLITE_OrderByIdxJoin 0x0040   /* ORDER BY of joins via index */
++#define SQLITE_Transitive     0x0080   /* Transitive constraints */
++#define SQLITE_OmitNoopJoin   0x0100   /* Omit unused tables in joins */
++#define SQLITE_CountOfView    0x0200   /* The count-of-view optimization */
++#define SQLITE_CursorHints    0x0400   /* Add OP_CursorHint opcodes */
+ #define SQLITE_Stat34         0x0800   /* Use STAT3 or STAT4 data */
+-#define SQLITE_CountOfView    0x1000   /* The count-of-view optimization */
+-#define SQLITE_CursorHints    0x2000   /* Add OP_CursorHint opcodes */
++   /* TH3 expects the Stat34  ^^^^^^ value to be 0x0800.  Don't change it */
++#define SQLITE_PushDown       0x1000   /* The push-down optimization */
++#define SQLITE_SimplifyJoin   0x2000   /* Convert LEFT JOIN to JOIN */
++#define SQLITE_SkipScan       0x4000   /* Skip-scans */
++#define SQLITE_PropagateConst 0x8000   /* The constant propagation opt */
+ #define SQLITE_AllOpts        0xffff   /* All optimizations */
+ 
+ /*
+@@ -15289,11 +16480,13 @@
+ */
+ struct FuncDef {
+   i8 nArg;             /* Number of arguments.  -1 means unlimited */
+-  u16 funcFlags;       /* Some combination of SQLITE_FUNC_* */
++  u32 funcFlags;       /* Some combination of SQLITE_FUNC_* */
+   void *pUserData;     /* User data parameter */
+   FuncDef *pNext;      /* Next function with same name */
+   void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
+   void (*xFinalize)(sqlite3_context*);                  /* Agg finalizer */
++  void (*xValue)(sqlite3_context*);                     /* Current agg value */
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
+   const char *zName;   /* SQL name of the function. */
+   union {
+     FuncDef *pHash;      /* Next with a different name but the same hash */
+@@ -15349,6 +16542,10 @@
+ #define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
+                                     ** single query - might change over time */
+ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
++#define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
++#define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
++#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
++#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
+ 
+ /*
+ ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
+@@ -15383,6 +16580,12 @@
+ **     are interpreted in the same way as the first 4 parameters to
+ **     FUNCTION().
+ **
++**   WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse)
++**     Used to create an aggregate function definition implemented by
++**     the C functions xStep and xFinal. The first four parameters
++**     are interpreted in the same way as the first 4 parameters to
++**     FUNCTION().
++**
+ **   LIKEFUNC(zName, nArg, pArg, flags)
+ **     Used to create a scalar function definition of a function zName
+ **     that accepts nArg arguments and is implemented by a call to C
+@@ -15393,32 +16596,39 @@
+ */
+ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
+-   0, 0, xFunc, 0, #zName, {0} }
++   0, 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
+-   (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} }
++   (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
+   {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   pArg, 0, xFunc, 0, #zName, }
++   pArg, 0, xFunc, 0, 0, 0, #zName, }
+ #define LIKEFUNC(zName, nArg, arg, flags) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
+-   (void *)arg, 0, likeFunc, 0, #zName, {0} }
+-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
++   (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
++#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
+ #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
+-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
++#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
++  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
++#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
++  {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
++   0, 0, xFunc, 0, 0, 0, #zName, {0} }
+ 
++
+ /*
+ ** All current savepoints are stored in a linked list starting at
+ ** sqlite3.pSavepoint. The first element in the list is the most recently
+@@ -15473,6 +16683,8 @@
+ #define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
+ #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
+ #define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
++#define COLFLAG_UNIQUE   0x0008    /* Column def contains "UNIQUE" or "PK" */
++#define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
+ 
+ /*
+ ** A "Collating Sequence" is defined by an instance of the following
+@@ -15600,6 +16812,9 @@
+ struct Table {
+   char *zName;         /* Name of the table or view */
+   Column *aCol;        /* Information about each column */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  Hash *pColHash;      /* All columns indexed by name */
++#endif
+   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 */
+@@ -15650,6 +16865,7 @@
+ #define TF_StatsUsed       0x0100    /* Query planner decisions affected by
+                                      ** Index.aiRowLogEst[] values */
+ #define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */
++#define TF_Shadow          0x0400    /* True for a shadow table */
+ 
+ /*
+ ** Test to see whether or not a table is a virtual table.  This is
+@@ -15760,15 +16976,14 @@
+ #define OE_Fail     3   /* Stop the operation but leave all prior changes */
+ #define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
+ #define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */
++#define OE_Update   6   /* Process as a DO UPDATE in an upsert */
++#define OE_Restrict 7   /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
++#define OE_SetNull  8   /* Set the foreign key value to NULL */
++#define OE_SetDflt  9   /* Set the foreign key value to its default */
++#define OE_Cascade  10  /* Cascade the changes */
++#define OE_Default  11  /* Do whatever the default action is */
+ 
+-#define OE_Restrict 6   /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+-#define OE_SetNull  7   /* Set the foreign key value to NULL */
+-#define OE_SetDflt  8   /* Set the foreign key value to its default */
+-#define OE_Cascade  9   /* Cascade the changes */
+ 
+-#define OE_Default  10  /* Do whatever the default action is */
+-
+-
+ /*
+ ** An instance of the following structure is passed as the first
+ ** argument to sqlite3VdbeKeyCompare and is used to control the
+@@ -15781,8 +16996,8 @@
+ struct KeyInfo {
+   u32 nRef;           /* Number of references to this KeyInfo object */
+   u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
+-  u16 nField;         /* Number of key columns in the index */
+-  u16 nXField;        /* Number of columns beyond the key columns */
++  u16 nKeyField;      /* Number of key columns in the index */
++  u16 nAllField;      /* Total columns, including key plus others */
+   sqlite3 *db;        /* The database connection */
+   u8 *aSortOrder;     /* Sort order for each column. */
+   CollSeq *aColl[1];  /* Collating sequence for each term of the key */
+@@ -15829,8 +17044,8 @@
+   u16 nField;         /* Number of entries in apMem[] */
+   i8 default_rc;      /* Comparison result if keys are equal */
+   u8 errCode;         /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
+-  i8 r1;              /* Value to return if (lhs > rhs) */
+-  i8 r2;              /* Value to return if (rhs < lhs) */
++  i8 r1;              /* Value to return if (lhs < rhs) */
++  i8 r2;              /* Value to return if (lhs > rhs) */
+   u8 eqSeen;          /* True if an equality comparison has been seen */
+ };
+ 
+@@ -15893,6 +17108,7 @@
+   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 */
++  unsigned bNoQuery:1;     /* Do not use this index to optimize queries */
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   int nSample;             /* Number of elements in aSample[] */
+   int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
+@@ -15901,6 +17117,7 @@
+   tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
+   tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
+ #endif
++  Bitmask colNotIdxed;     /* 0 for unindexed columns in pTab */
+ };
+ 
+ /*
+@@ -15936,12 +17153,20 @@
+ };
+ 
+ /*
++** Possible values to use within the flags argument to sqlite3GetToken().
++*/
++#define SQLITE_TOKEN_QUOTED    0x1 /* Token is a quoted identifier. */
++#define SQLITE_TOKEN_KEYWORD   0x2 /* Token is a keyword. */
++
++/*
+ ** Each token coming out of the lexer is an instance of
+ ** this structure.  Tokens are also used as part of an expression.
+ **
+-** Note if Token.z==0 then Token.dyn and Token.n are undefined and
+-** may contain random values.  Do not make any assumptions about Token.dyn
+-** and Token.n when Token.z==0.
++** The memory that "z" points to is owned by other objects.  Take care
++** that the owner of the "z" string does not deallocate the string before
++** the Token goes out of scope!  Very often, the "z" points to some place
++** in the middle of the Parse.zSql text.  But it might also point to a
++** static string.
+ */
+ struct Token {
+   const char *z;     /* Text of the token.  Not NULL-terminated! */
+@@ -16114,7 +17339,11 @@
+                          ** TK_COLUMN: the value of p5 for OP_Column
+                          ** TK_AGG_FUNCTION: nesting depth */
+   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
+-  Table *pTab;           /* Table for TK_COLUMN expressions. */
++  union {
++    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
++                           ** for a column of an index on an expression */
++    Window *pWin;          /* TK_FUNCTION: Window definition for the func */
++  } y;
+ };
+ 
+ /*
+@@ -16122,8 +17351,8 @@
+ */
+ #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
+ #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
+-                  /* 0x000004 // available for use */
+-                  /* 0x000008 // available for use */
++#define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
++#define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */
+ #define EP_Distinct  0x000010 /* Aggregate function with DISTINCT keyword */
+ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+@@ -16144,11 +17373,13 @@
+ #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
+ #define EP_Alias     0x400000 /* Is an alias for a result set column */
+ #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
++#define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
+ 
+ /*
+-** Combinations of two or more EP_* flags
++** The EP_Propagate mask is a set of properties that automatically propagate
++** upwards into parent nodes.
+ */
+-#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
++#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
+ 
+ /*
+ ** These macros can be used to test, set, or clear bits in the
+@@ -16202,7 +17433,6 @@
+ */
+ struct ExprList {
+   int nExpr;             /* Number of expressions on the list */
+-  int nAlloc;            /* Number of a[] slots allocated */
+   struct ExprList_item { /* For each expression in the list */
+     Expr *pExpr;            /* The parse tree for this expression */
+     char *zName;            /* Token associated with this expression */
+@@ -16211,6 +17441,7 @@
+     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 */
++    unsigned bSorterRef :1; /* Defer evaluation until after sorting */
+     union {
+       struct {
+         u16 iOrderByCol;      /* For ORDER BY, column number in result set */
+@@ -16222,17 +17453,6 @@
+ };
+ 
+ /*
+-** An instance of this structure is used by the parser to record both
+-** the parse tree for an expression and the span of input text for an
+-** expression.
+-*/
+-struct ExprSpan {
+-  Expr *pExpr;          /* The expression parse tree */
+-  const char *zStart;   /* First character of input text */
+-  const char *zEnd;     /* One character past the end of input text */
+-};
+-
+-/*
+ ** An instance of this structure can hold a simple list of identifiers,
+ ** such as the list "a,b,c" in the following statements:
+ **
+@@ -16256,31 +17476,6 @@
+ };
+ 
+ /*
+-** The bitmask datatype defined below is used for various optimizations.
+-**
+-** Changing this from a 64-bit to a 32-bit type limits the number of
+-** tables in a join to 32 instead of 64.  But it also reduces the size
+-** of the library by 738 bytes on ix86.
+-*/
+-#ifdef SQLITE_BITMASK_TYPE
+-  typedef SQLITE_BITMASK_TYPE Bitmask;
+-#else
+-  typedef u64 Bitmask;
+-#endif
+-
+-/*
+-** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
+-*/
+-#define BMS  ((int)(sizeof(Bitmask)*8))
+-
+-/*
+-** A bit in a Bitmask
+-*/
+-#define MASKBIT(n)   (((Bitmask)1)<<(n))
+-#define MASKBIT32(n) (((unsigned int)1)<<(n))
+-#define ALLBITS      ((Bitmask)-1)
+-
+-/*
+ ** The following structure describes the FROM clause of a SELECT statement.
+ ** Each table or subquery in the FROM clause is a separate element of
+ ** the SrcList.a[] array.
+@@ -16321,9 +17516,6 @@
+       unsigned viaCoroutine :1;  /* Implemented as a co-routine */
+       unsigned isRecursive :1;   /* True for recursive reference in WITH */
+     } fg;
+-#ifndef SQLITE_OMIT_EXPLAIN
+-    u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
+-#endif
+     int iCursor;      /* The VDBE cursor number used to access this table */
+     Expr *pOn;        /* The ON clause of a join */
+     IdList *pUsing;   /* The USING clause of a join */
+@@ -16405,12 +17597,16 @@
+ struct NameContext {
+   Parse *pParse;       /* The parser */
+   SrcList *pSrcList;   /* One or more tables used to resolve names */
+-  ExprList *pEList;    /* Optional list of result-set columns */
+-  AggInfo *pAggInfo;   /* Information about aggregates at this level */
++  union {
++    ExprList *pEList;    /* Optional list of result-set columns */
++    AggInfo *pAggInfo;   /* Information about aggregates at this level */
++    Upsert *pUpsert;     /* ON CONFLICT clause information from an upsert */
++  } uNC;
+   NameContext *pNext;  /* Next outer name context.  NULL for outermost */
+   int nRef;            /* Number of names resolved by this context */
+   int nErr;            /* Number of errors encountered while resolving names */
+   u16 ncFlags;         /* Zero or more NC_* flags defined below */
++  Select *pWinSelect;  /* SELECT statement for any window functions */
+ };
+ 
+ /*
+@@ -16428,17 +17624,49 @@
+ #define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
+ #define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
+ #define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
++#define NC_UEList    0x0080  /* True if uNC.pEList is used */
++#define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
++#define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
+ #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
++#define NC_Complex   0x2000  /* True if a function or subquery seen */
++#define NC_AllowWin  0x4000  /* Window functions are allowed here */
+ 
+ /*
++** An instance of the following object describes a single ON CONFLICT
++** clause in an upsert.
++**
++** The pUpsertTarget field is only set if the ON CONFLICT clause includes
++** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
++** conflict-target clause.)  The pUpsertTargetWhere is the optional
++** WHERE clause used to identify partial unique indexes.
++**
++** pUpsertSet is the list of column=expr terms of the UPDATE statement. 
++** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING.  The
++** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
++** WHERE clause is omitted.
++*/
++struct Upsert {
++  ExprList *pUpsertTarget;  /* Optional description of conflicting index */
++  Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */
++  ExprList *pUpsertSet;     /* The SET clause from an ON CONFLICT UPDATE */
++  Expr *pUpsertWhere;       /* WHERE clause for the ON CONFLICT UPDATE */
++  /* The fields above comprise the parse tree for the upsert clause.
++  ** The fields below are used to transfer information from the INSERT
++  ** processing down into the UPDATE processing while generating code.
++  ** Upsert owns the memory allocated above, but not the memory below. */
++  Index *pUpsertIdx;        /* Constraint that pUpsertTarget identifies */
++  SrcList *pUpsertSrc;      /* Table to be updated */
++  int regData;              /* First register holding array of VALUES */
++  int iDataCur;             /* Index of the data cursor */
++  int iIdxCur;              /* Index of the first index cursor */
++};
++
++/*
+ ** An instance of the following structure contains all information
+ ** needed to generate code for a single SELECT statement.
+ **
+-** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
+-** If there is a LIMIT clause, the parser sets nLimit to the value of the
+-** limit and nOffset to the value of the offset (or 0 if there is not
+-** offset).  But later on, nLimit and nOffset become the memory locations
+-** in the VDBE that record the limit and offset counters.
++** See the header comment on the computeLimitRegisters() routine for a
++** detailed description of the meaning of the iLimit and iOffset fields.
+ **
+ ** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
+ ** These addresses must be stored so that we can go back and fill in
+@@ -16456,9 +17684,7 @@
+   LogEst nSelectRow;     /* Estimated number of result rows */
+   u32 selFlags;          /* Various SF_* values */
+   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+-#if SELECTTRACE_ENABLED
+-  char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
+-#endif
++  u32 selId;             /* Unique identifier number for this SELECT */
+   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
+   SrcList *pSrc;         /* The FROM clause */
+   Expr *pWhere;          /* The WHERE clause */
+@@ -16468,8 +17694,11 @@
+   Select *pPrior;        /* Prior select in a compound select statement */
+   Select *pNext;         /* Next select to the left in a compound */
+   Expr *pLimit;          /* LIMIT expression. NULL means not used. */
+-  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
+   With *pWith;           /* WITH clause attached to this select. Or NULL. */
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  Window *pWin;          /* List of window functions */
++  Window *pWinDefn;      /* List of named window definitions */
++#endif
+ };
+ 
+ /*
+@@ -16499,8 +17728,8 @@
+ #define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
+ #define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
+ #define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
++#define SF_ComplexResult  0x40000  /* Result contains subquery or function */
+ 
+-
+ /*
+ ** The results of a SELECT can be distributed in several ways, as defined
+ ** by one of the following macros.  The "SRT" prefix means "SELECT Result
+@@ -16614,13 +17843,6 @@
+ };
+ 
+ /*
+-** Size of the column cache
+-*/
+-#ifndef SQLITE_N_COLCACHE
+-# define SQLITE_N_COLCACHE 10
+-#endif
+-
+-/*
+ ** At least one instance of the following structure is created for each
+ ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
+ ** statement. All such objects are stored in the linked list headed at
+@@ -16695,7 +17917,6 @@
+   u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
+   u8 okConstFactor;    /* OK to factor out constants */
+   u8 disableLookaside; /* Number of times lookaside has been disabled */
+-  u8 nColCache;        /* Number of entries in aColCache[] */
+   int nRangeReg;       /* Size of the temporary register block */
+   int iRangeReg;       /* First register in temporary register block */
+   int nErr;            /* Number of errors seen */
+@@ -16703,10 +17924,8 @@
+   int nMem;            /* Number of memory cells used so far */
+   int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
+   int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
+-  int iSelfTab;        /* Table for associated with an index on expr, or negative
++  int iSelfTab;        /* Table associated with an index on expr, or negative
+                        ** of the base register during check-constraint eval */
+-  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
+-  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
+   int nLabel;          /* Number of labels used */
+   int *aLabel;         /* Space to hold the labels */
+   ExprList *pConstExpr;/* Constant expressions */
+@@ -16716,10 +17935,7 @@
+   int regRowid;        /* Register holding rowid of CREATE TABLE entry */
+   int regRoot;         /* Register holding root page number for new objects */
+   int nMaxArg;         /* Max args passed to user function by sub-program */
+-#if SELECTTRACE_ENABLED
+-  int nSelect;         /* Number of SELECT statements seen */
+-  int nSelectIndent;   /* How far to indent SELECTTRACE() output */
+-#endif
++  int nSelect;         /* Number of SELECT stmts. Counter for Select.selId */
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+   int nTableLock;        /* Number of locks in aTableLock */
+   TableLock *aTableLock; /* Required table locks for shared-cache mode */
+@@ -16727,7 +17943,7 @@
+   AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
+   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
+   Table *pTriggerTab;  /* Table triggers are being coded for */
+-  int addrCrTab;       /* Address of OP_CreateTable opcode on CREATE TABLE */
++  int addrCrTab;       /* Address of OP_CreateBtree opcode on CREATE TABLE */
+   u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
+   u32 oldmask;         /* Mask of old.* columns referenced */
+   u32 newmask;         /* Mask of new.* columns referenced */
+@@ -16739,17 +17955,9 @@
+   ** Fields above must be initialized to zero.  The fields that follow,
+   ** down to the beginning of the recursive section, do not need to be
+   ** initialized as they will be set before being used.  The boundary is
+-  ** determined by offsetof(Parse,aColCache).
++  ** determined by offsetof(Parse,aTempReg).
+   **************************************************************************/
+ 
+-  struct yColCache {
+-    int iTable;           /* Table cursor number */
+-    i16 iColumn;          /* Table column number */
+-    u8 tempReg;           /* iReg is a temp register that needs to be freed */
+-    int iLevel;           /* Nesting level */
+-    int iReg;             /* Reg with value of this column. 0 means none. */
+-    int lru;              /* Least recently used entry has the smallest value */
+-  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
+   int aTempReg[8];        /* Holding area for temporary registers */
+   Token sNameToken;       /* Token with unqualified schema object name */
+ 
+@@ -16764,19 +17972,21 @@
+   ynVar nVar;               /* Number of '?' variables seen in the SQL so far */
+   u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
+   u8 explain;               /* True if the EXPLAIN flag is found on the query */
++#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE))
++  u8 eParseMode;            /* PARSE_MODE_XXX constant */
++#endif
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
+   int nVtabLock;            /* Number of virtual tables to lock */
+ #endif
+   int nHeight;              /* Expression tree height of current sub-select */
+ #ifndef SQLITE_OMIT_EXPLAIN
+-  int iSelectId;            /* ID of current select for EXPLAIN output */
+-  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
++  int addrExplain;          /* Address of current OP_Explain opcode */
+ #endif
+   VList *pVList;            /* Mapping between variable names and numbers */
+   Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
+   const char *zTail;        /* All SQL text past the last semicolon parsed */
+   Table *pNewTable;         /* A table being constructed by CREATE TABLE */
++  Index *pNewIndex;         /* An index being constructed by CREATE INDEX */
+   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
+   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+@@ -16787,12 +17997,20 @@
+   TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
+   With *pWith;              /* Current WITH clause, or NULL */
+   With *pWithToFree;        /* Free this WITH object at the end of the parse */
++#ifndef SQLITE_OMIT_ALTERTABLE
++  RenameToken *pRename;     /* Tokens subject to renaming by ALTER TABLE */
++#endif
+ };
+ 
++#define PARSE_MODE_NORMAL        0
++#define PARSE_MODE_DECLARE_VTAB  1
++#define PARSE_MODE_RENAME_COLUMN 2
++#define PARSE_MODE_RENAME_TABLE  3
++
+ /*
+ ** Sizes and pointers of various parts of the Parse object.
+ */
+-#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
++#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
+ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken)    /* Recursive part */
+ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
+ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */
+@@ -16803,9 +18021,21 @@
+ #ifdef SQLITE_OMIT_VIRTUALTABLE
+   #define IN_DECLARE_VTAB 0
+ #else
+-  #define IN_DECLARE_VTAB (pParse->declareVtab)
++  #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB)
+ #endif
+ 
++#if defined(SQLITE_OMIT_ALTERTABLE)
++  #define IN_RENAME_OBJECT 0
++#else
++  #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN)
++#endif
++
++#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)
++  #define IN_SPECIAL_PARSE 0
++#else
++  #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL)
++#endif
++
+ /*
+ ** An instance of the following structure can be declared on a stack and used
+ ** to save the Parse.zAuthContext value so that it can be restored later.
+@@ -16829,6 +18059,7 @@
+ */
+ #define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
+                                      /* Also used in P2 (not P5) of OP_Delete */
++#define OPFLAG_NOCHNG        0x01    /* OP_VColumn nochange for UPDATE */
+ #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
+ #define OPFLAG_LASTROWID     0x20    /* Set to update db->lastRowid */
+ #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
+@@ -16844,6 +18075,7 @@
+ #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
+ #define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete/Insert: save cursor pos */
+ #define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
++#define OPFLAG_NOCHNG_MAGIC  0x6d    /* OP_MakeRecord: serialtype 10 is ok */
+ 
+ /*
+  * Each trigger present in the database schema is stored as an instance of
+@@ -16929,8 +18161,10 @@
+   Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
+   char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
+   Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
+-  ExprList *pExprList; /* SET clause for UPDATE. */
++  ExprList *pExprList; /* SET clause for UPDATE */
+   IdList *pIdList;     /* Column names for INSERT */
++  Upsert *pUpsert;     /* Upsert clauses on an INSERT */
++  char *zSpan;         /* Original SQL text of this command */
+   TriggerStep *pNext;  /* Next in the link-list */
+   TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
+ };
+@@ -16954,18 +18188,15 @@
+ ** An objected used to accumulate the text of a string where we
+ ** do not necessarily know how big the string will be in the end.
+ */
+-struct StrAccum {
++struct sqlite3_str {
+   sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
+-  char *zBase;         /* A base allocation.  Not from malloc. */
+   char *zText;         /* The string collected so far */
+-  u32  nChar;          /* Length of the string so far */
+   u32  nAlloc;         /* Amount of space allocated in zText */
+   u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
+-  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
++  u32  nChar;          /* Length of the string so far */
++  u8   accError;       /* SQLITE_NOMEM or SQLITE_TOOBIG */
+   u8   printfFlags;    /* SQLITE_PRINTF flags below */
+ };
+-#define STRACCUM_NOMEM   1
+-#define STRACCUM_TOOBIG  2
+ #define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
+ #define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
+ #define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
+@@ -16982,9 +18213,15 @@
+   char **pzErrMsg;    /* Error message stored here */
+   int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
+   int rc;             /* Result code stored here */
++  u32 mInitFlags;     /* Flags controlling error messages */
+ } InitData;
+ 
+ /*
++** Allowed values for mInitFlags
++*/
++#define INITFLAG_AlterTable   0x0001  /* This is a reparse after ALTER TABLE */
++
++/*
+ ** Structure containing global configuration data for the SQLite library.
+ **
+ ** This structure also contains some state information.
+@@ -16995,6 +18232,7 @@
+   int bFullMutex;                   /* True to enable full mutexing */
+   int bOpenUri;                     /* True to interpret filenames as URIs */
+   int bUseCis;                      /* Use covering indices for full-scans */
++  int bSmallMalloc;                 /* Avoid large memory allocations if true */
+   int mxStrlen;                     /* Maximum string length */
+   int neverCorrupt;                 /* Database is always well-formed */
+   int szLookaside;                  /* Default lookaside buffer size */
+@@ -17008,9 +18246,6 @@
+   int mnReq, mxReq;                 /* Min and max heap requests sizes */
+   sqlite3_int64 szMmap;             /* mmap() space per open file */
+   sqlite3_int64 mxMmap;             /* Maximum value for szMmap */
+-  void *pScratch;                   /* Scratch memory */
+-  int szScratch;                    /* Size of each scratch buffer */
+-  int nScratch;                     /* Number of scratch buffers */
+   void *pPage;                      /* Page cache memory */
+   int szPage;                       /* Size of each page in pPage[] */
+   int nPage;                        /* Number of pages in pPage[] */
+@@ -17036,7 +18271,7 @@
+   /* The following callback (if not NULL) is invoked on every VDBE branch
+   ** operation.  Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
+   */
+-  void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx);  /* Callback */
++  void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx);  /* Callback */
+   void *pVdbeBranchArg;                                     /* 1st argument */
+ #endif
+ #ifndef SQLITE_UNTESTABLE
+@@ -17043,7 +18278,9 @@
+   int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
+ #endif
+   int bLocaltimeFault;              /* True to fail localtime() calls */
++  int bInternalFunctions;           /* Internal SQL functions are visible */
+   int iOnceResetThreshold;          /* When to reset OP_Once counters */
++  u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
+ };
+ 
+ /*
+@@ -17083,9 +18320,12 @@
+     struct CCurHint *pCCurHint;               /* Used by codeCursorHint() */
+     int *aiCol;                               /* array of column indexes */
+     struct IdxCover *pIdxCover;               /* Check for index coverage */
+-    struct IdxExprTrans *pIdxTrans;           /* Convert indexed expr to column */
++    struct IdxExprTrans *pIdxTrans;           /* Convert idxed expr to column */
+     ExprList *pGroupBy;                       /* GROUP BY clause */
+-    struct HavingToWhereCtx *pHavingCtx;      /* HAVING to WHERE clause ctx */
++    Select *pSelect;                          /* HAVING to WHERE clause ctx */
++    struct WindowRewrite *pRewrite;           /* Window rewrite context */
++    struct WhereConst *pConst;                /* WHERE clause constants */
++    struct RenameCtx *pRename;                /* RENAME COLUMN context */
+   } u;
+ };
+ 
+@@ -17097,6 +18337,7 @@
+ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
+ SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
+ SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
++SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
+ #endif
+@@ -17136,6 +18377,68 @@
+ #endif /* SQLITE_DEBUG */
+ 
+ /*
++** This object is used in varioius ways, all related to window functions
++**
++**   (1) A single instance of this structure is attached to the
++**       the Expr.pWin field for each window function in an expression tree.
++**       This object holds the information contained in the OVER clause,
++**       plus additional fields used during code generation.
++**
++**   (2) All window functions in a single SELECT form a linked-list
++**       attached to Select.pWin.  The Window.pFunc and Window.pExpr
++**       fields point back to the expression that is the window function.
++**
++**   (3) The terms of the WINDOW clause of a SELECT are instances of this
++**       object on a linked list attached to Select.pWinDefn.
++**
++** The uses (1) and (2) are really the same Window object that just happens
++** to be accessible in two different ways.  Use (3) is are separate objects.
++*/
++struct Window {
++  char *zName;            /* Name of window (may be NULL) */
++  ExprList *pPartition;   /* PARTITION BY clause */
++  ExprList *pOrderBy;     /* ORDER BY clause */
++  u8 eType;               /* TK_RANGE or TK_ROWS */
++  u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
++  u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
++  Expr *pStart;           /* Expression for "<expr> PRECEDING" */
++  Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
++  Window *pNextWin;       /* Next window function belonging to this SELECT */
++  Expr *pFilter;          /* The FILTER expression */
++  FuncDef *pFunc;         /* The function */
++  int iEphCsr;            /* Partition buffer or Peer buffer */
++  int regAccum;
++  int regResult;
++  int csrApp;             /* Function cursor (used by min/max) */
++  int regApp;             /* Function register (also used by min/max) */
++  int regPart;            /* First in a set of registers holding PARTITION BY
++                          ** and ORDER BY values for the window */
++  Expr *pOwner;           /* Expression object this window is attached to */
++  int nBufferCol;         /* Number of columns in buffer table */
++  int iArgCol;            /* Offset of first argument for this function */
++};
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
++SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p);
++SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
++SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
++SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*);
++SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
++SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
++SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*);
++SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
++SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
++SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
++SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
++SQLITE_PRIVATE void sqlite3WindowFunctions(void);
++#else
++# define sqlite3WindowDelete(a,b)
++# define sqlite3WindowFunctions()
++# define sqlite3WindowAttach(a,b,c)
++#endif
++
++/*
+ ** Assuming zIn points to the first byte of a UTF-8 character,
+ ** advance zIn to point to the first byte of the next UTF-8 character.
+ */
+@@ -17152,6 +18455,7 @@
+ ** using sqlite3_log().  The routines also provide a convenient place
+ ** to set a debugger breakpoint.
+ */
++SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType);
+ SQLITE_PRIVATE int sqlite3CorruptError(int);
+ SQLITE_PRIVATE int sqlite3MisuseError(int);
+ SQLITE_PRIVATE int sqlite3CantopenError(int);
+@@ -17221,9 +18525,7 @@
+ # define sqlite3Tolower(x)   tolower((unsigned char)(x))
+ # define sqlite3Isquote(x)   ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
+ #endif
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
+-#endif
+ 
+ /*
+ ** Internal function prototypes
+@@ -17230,6 +18532,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
+ SQLITE_PRIVATE int sqlite3Strlen30(const char*);
++#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
+ SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
+ #define sqlite3StrNICmp sqlite3_strnicmp
+ 
+@@ -17242,6 +18545,7 @@
+ SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
+ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
+ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
++SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
+ SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
+ SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
+ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
+@@ -17249,8 +18553,6 @@
+ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
+ SQLITE_PRIVATE int sqlite3MallocSize(void*);
+ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
+-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
+-SQLITE_PRIVATE void sqlite3ScratchFree(void*);
+ SQLITE_PRIVATE void *sqlite3PageMalloc(int);
+ SQLITE_PRIVATE void sqlite3PageFree(void*);
+ SQLITE_PRIVATE void sqlite3MemSetDefault(void);
+@@ -17306,11 +18608,18 @@
+ SQLITE_PRIVATE void sqlite3StatusUp(int, int);
+ SQLITE_PRIVATE void sqlite3StatusDown(int, int);
+ SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
++SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*);
+ 
+ /* Access to mutexes used by sqlite3_status() */
+ SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
+ SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
+ 
++#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
++SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
++#else
++# define sqlite3MutexWarnOnContention(x)
++#endif
++
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+ SQLITE_PRIVATE   int sqlite3IsNaN(double);
+ #else
+@@ -17327,8 +18636,6 @@
+   sqlite3_value **apArg;   /* The argument values */
+ };
+ 
+-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list);
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
+ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
+ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
+ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+@@ -17342,9 +18649,14 @@
+ SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
+ SQLITE_PRIVATE   void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
+ SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
++SQLITE_PRIVATE   void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
+ SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
+ SQLITE_PRIVATE   void sqlite3TreeViewWith(TreeView*, const With*, u8);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE   void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
++SQLITE_PRIVATE   void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
+ #endif
++#endif
+ 
+ 
+ SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
+@@ -17368,7 +18680,7 @@
+ SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
+ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
+ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
+-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
++SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
+ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
+ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+@@ -17375,11 +18687,12 @@
+ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
+ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
+ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
+-SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
++SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
+ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
+ SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
+ SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
+ SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
++SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
+ SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
+@@ -17405,7 +18718,7 @@
+ SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
+ SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
+ SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
+-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
++SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
+ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
+ SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
+ SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
+@@ -17429,8 +18742,9 @@
+ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
+ #endif
+ 
+-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
+-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
++SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*);
++SQLITE_PRIVATE void sqlite3RowSetDelete(void*);
++SQLITE_PRIVATE void sqlite3RowSetClear(void*);
+ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
+ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
+ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
+@@ -17449,6 +18763,7 @@
+ SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
+ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
+ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
++SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
+ #ifndef SQLITE_OMIT_AUTOINCREMENT
+ SQLITE_PRIVATE   void sqlite3AutoincrementBegin(Parse *pParse);
+ SQLITE_PRIVATE   void sqlite3AutoincrementEnd(Parse *pParse);
+@@ -17456,9 +18771,9 @@
+ # define sqlite3AutoincrementBegin(X)
+ # define sqlite3AutoincrementEnd(X)
+ #endif
+-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
++SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
+ SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
+-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
++SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
+ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
+ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
+ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
+@@ -17477,22 +18792,23 @@
+ SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
+ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
+ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
+-                         Expr*,ExprList*,u32,Expr*,Expr*);
++                         Expr*,ExprList*,u32,Expr*);
+ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
+ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
+ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
+ SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
+ #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
+-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
++SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
+ #endif
+-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
+-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
++SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
++SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
++                   Upsert*);
+ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
+ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
+ SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
+-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*);
++SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+@@ -17502,15 +18818,8 @@
+ #define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */
+ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
+ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
+-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
+@@ -17541,6 +18850,7 @@
+ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
+ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
+ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
++SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
+ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
+ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
+ SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
+@@ -17558,6 +18868,8 @@
+ SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
+ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
+ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
++SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
++SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
+ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
+ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
+ SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
+@@ -17570,13 +18882,17 @@
+ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
+ SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
+ SQLITE_PRIVATE int sqlite3IsRowid(const char*);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
++#endif
+ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
+     Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
+ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
+ SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
+ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
++SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
+ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+-                                     u8,u8,int,int*,int*);
++                                     u8,u8,int,int*,int*,Upsert*);
+ #ifdef SQLITE_ENABLE_NULL_TRIM
+ SQLITE_PRIVATE   void sqlite3SetMakeRecordP5(Vdbe*,Table*);
+ #else
+@@ -17595,10 +18911,8 @@
+ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
+ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
+ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+-#if SELECTTRACE_ENABLED
+-SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
+-#else
+-# define sqlite3SelectSetName(A,B)
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
+ #endif
+ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+@@ -17610,7 +18924,7 @@
+ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
+ 
+ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
++SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
+ #endif
+ 
+ #ifndef SQLITE_OMIT_TRIGGER
+@@ -17626,11 +18940,15 @@
+ SQLITE_PRIVATE   void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
+   void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
+ SQLITE_PRIVATE   void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
+-                                        Select*,u8);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
++                                        const char*,const char*);
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
++                                        Select*,u8,Upsert*,
++                                        const char*,const char*);
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8,
++                                        const char*,const char*);
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
++                                        const char*,const char*);
+ SQLITE_PRIVATE   void sqlite3DeleteTrigger(sqlite3*, Trigger*);
+ SQLITE_PRIVATE   void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
+ SQLITE_PRIVATE   u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
+@@ -17737,15 +19055,23 @@
+ SQLITE_PRIVATE const char *sqlite3ErrName(int);
+ #endif
+ 
++#ifdef SQLITE_ENABLE_DESERIALIZE
++SQLITE_PRIVATE int sqlite3MemdbInit(void);
++#endif
++
+ SQLITE_PRIVATE const char *sqlite3ErrStr(int);
+ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
+ SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
++SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*);
+ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
+ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
++SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
++SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
+ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
+ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
+ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
+ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
++SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
+ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
+ SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
+ SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
+@@ -17783,13 +19109,20 @@
+ SQLITE_PRIVATE int sqlite3PendingByte;
+ #endif
+ #endif
++#ifdef VDBE_PROFILE
++SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt;
++#endif
+ SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int);
+ SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
+ SQLITE_PRIVATE void sqlite3AlterFunctions(void);
+ SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
++SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
+ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
++#endif
+ SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
+-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
++SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
+ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
+ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
+@@ -17802,10 +19135,14 @@
+ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
+ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
+ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
++SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*);
++SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
++SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
++SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
+ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
+-SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*);
++SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
+ SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
+-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
++SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
+ SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
+ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
+ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
+@@ -17820,14 +19157,20 @@
+ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
+ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
+ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
++SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
++
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+ #endif
+ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+   void (*)(sqlite3_context*,int,sqlite3_value **),
+-  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*,int,sqlite3_value **), 
++  void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*,int,sqlite3_value **), 
+   FuncDestructor *pDestructor
+ );
++SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
+ SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
+ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
+ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
+@@ -17834,11 +19177,7 @@
+ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
+ 
+ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
+-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
+-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
+-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
+ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
+-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
+ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
+ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
+ 
+@@ -17865,10 +19204,11 @@
+ ** The interface to the LEMON-generated parser
+ */
+ #ifndef SQLITE_AMALGAMATION
+-SQLITE_PRIVATE   void *sqlite3ParserAlloc(void*(*)(u64));
++SQLITE_PRIVATE   void *sqlite3ParserAlloc(void*(*)(u64), Parse*);
+ SQLITE_PRIVATE   void sqlite3ParserFree(void*, void(*)(void*));
+ #endif
+-SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
++SQLITE_PRIVATE void sqlite3Parser(void*, int, Token);
++SQLITE_PRIVATE int sqlite3ParserFallback(int);
+ #ifdef YYTRACKMAXSTACKDEPTH
+ SQLITE_PRIVATE   int sqlite3ParserStackPeak(void*);
+ #endif
+@@ -17934,11 +19274,13 @@
+ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
+ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
+ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
+-SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
+ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
+ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
+ SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
++#endif
+ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
+ SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
+ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
+@@ -17956,7 +19298,19 @@
+ #define sqlite3WithPush(x,y,z)
+ #define sqlite3WithDelete(x,y)
+ #endif
++#ifndef SQLITE_OMIT_UPSERT
++SQLITE_PRIVATE   Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*);
++SQLITE_PRIVATE   void sqlite3UpsertDelete(sqlite3*,Upsert*);
++SQLITE_PRIVATE   Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
++SQLITE_PRIVATE   int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
++SQLITE_PRIVATE   void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
++#else
++#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0)
++#define sqlite3UpsertDelete(x,y)
++#define sqlite3UpsertDup(x,y)       ((Upsert*)0)
++#endif
+ 
++
+ /* Declarations for functions in fkey.c. All of these are replaced by
+ ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
+ ** key functionality is available. If OMIT_TRIGGER is defined but
+@@ -18025,7 +19379,8 @@
+ 
+ SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
+ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
++ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ SQLITE_PRIVATE   int sqlite3JournalCreate(sqlite3_file *);
+ #endif
+ 
+@@ -18057,6 +19412,9 @@
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE   void sqlite3ParserTrace(FILE*, char *);
+ #endif
++#if defined(YYCOVERAGE)
++SQLITE_PRIVATE   int sqlite3ParserCoverage(FILE*);
++#endif
+ 
+ /*
+ ** If the SQLITE_ENABLE IOTRACE exists then the global variable
+@@ -18111,8 +19469,7 @@
+ #endif
+ #define MEMTYPE_HEAP       0x01  /* General heap allocations */
+ #define MEMTYPE_LOOKASIDE  0x02  /* Heap that might have been lookaside */
+-#define MEMTYPE_SCRATCH    0x04  /* Scratch allocations */
+-#define MEMTYPE_PCACHE     0x08  /* Page cache allocations */
++#define MEMTYPE_PCACHE     0x04  /* Page cache allocations */
+ 
+ /*
+ ** Threading interface
+@@ -18122,6 +19479,9 @@
+ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
+ #endif
+ 
++#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
++SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*);
++#endif
+ #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
+ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
+ #endif
+@@ -18341,6 +19701,7 @@
+    SQLITE_THREADSAFE==1,      /* bFullMutex */
+    SQLITE_USE_URI,            /* bOpenUri */
+    SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
++   0,                         /* bSmallMalloc */
+    0x7ffffffe,                /* mxStrlen */
+    0,                         /* neverCorrupt */
+    SQLITE_DEFAULT_LOOKASIDE,  /* szLookaside, nLookaside */
+@@ -18353,9 +19714,6 @@
+    0, 0,                      /* mnHeap, mxHeap */
+    SQLITE_DEFAULT_MMAP_SIZE,  /* szMmap */
+    SQLITE_MAX_MMAP_SIZE,      /* mxMmap */
+-   (void*)0,                  /* pScratch */
+-   0,                         /* szScratch */
+-   0,                         /* nScratch */
+    (void*)0,                  /* pPage */
+    0,                         /* szPage */
+    SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */
+@@ -18384,7 +19742,9 @@
+    0,                         /* xTestCallback */
+ #endif
+    0,                         /* bLocaltimeFault */
+-   0x7ffffffe                 /* iOnceResetThreshold */
++   0,                         /* bInternalFunctions */
++   0x7ffffffe,                /* iOnceResetThreshold */
++   SQLITE_DEFAULT_SORTERREF_SIZE   /* szSorterRef */
+ };
+ 
+ /*
+@@ -18402,6 +19762,13 @@
+    { "1", 1 }
+ };
+ 
++#ifdef VDBE_PROFILE
++/*
++** The following performance counter can be used in place of
++** sqlite3Hwtime() for profiling.  This is a no-op on standard builds.
++*/
++SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0;
++#endif
+ 
+ /*
+ ** The value of the "pending" byte must be 0x40000000 (1 byte past the
+@@ -18546,6 +19913,7 @@
+   Bool isEphemeral:1;     /* True for an ephemeral table */
+   Bool useRandomRowid:1;  /* Generate new record numbers semi-randomly */
+   Bool isOrdered:1;       /* True if the table is not BTREE_UNORDERED */
++  Bool seekHit:1;         /* See the OP_SeekHit and OP_IfNoHope opcodes */
+   Btree *pBtx;            /* Separate file holding temporary table */
+   i64 seqCount;           /* Sequence counter */
+   int *aAltMap;           /* Mapping from table to index column numbers */
+@@ -18557,8 +19925,9 @@
+   u32 cacheStatus;        /* Cache is valid if this matches Vdbe.cacheCtr */
+   int seekResult;         /* Result of previous sqlite3BtreeMoveto() or 0
+                           ** if there have been no prior seeks on the cursor. */
+-  /* NB: seekResult does not distinguish between "no seeks have ever occurred
+-  ** on this cursor" and "the most recent seek was an exact match". */
++  /* seekResult does not distinguish between "no seeks have ever occurred
++  ** on this cursor" and "the most recent seek was an exact match".
++  ** For CURTYPE_PSEUDO, seekResult is the register holding the record */
+ 
+   /* When a new VdbeCursor is allocated, only the fields above are zeroed.
+   ** The fields that follow are uninitialized, and must be individually
+@@ -18565,10 +19934,9 @@
+   ** initialized prior to first use. */
+   VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
+   union {
+-    BtCursor *pCursor;          /* CURTYPE_BTREE.  Btree cursor */
+-    sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB.   Vtab cursor */
+-    int pseudoTableReg;         /* CURTYPE_PSEUDO. Reg holding content. */
+-    VdbeSorter *pSorter;        /* CURTYPE_SORTER. Sorter object */
++    BtCursor *pCursor;          /* CURTYPE_BTREE or _PSEUDO.  Btree cursor */
++    sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB.              Vtab cursor */
++    VdbeSorter *pSorter;        /* CURTYPE_SORTER.            Sorter object */
+   } uc;
+   KeyInfo *pKeyInfo;      /* Info about index keys needed by index cursors */
+   u32 iHdrOffset;         /* Offset to next unparsed byte of the header */
+@@ -18629,6 +19997,9 @@
+   void *token;            /* Copy of SubProgram.token */
+   i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
+   AuxData *pAuxData;      /* Linked list of auxdata allocations */
++#if SQLITE_DEBUG
++  u32 iFrameMagic;        /* magic number for sanity checking */
++#endif
+   int nCursor;            /* Number of entries in apCsr */
+   int pc;                 /* Program Counter in parent (calling) frame */
+   int nOp;                /* Size of aOp array */
+@@ -18639,6 +20010,13 @@
+   int nDbChange;          /* Value of db->nChange */
+ };
+ 
++/* Magic number for sanity checking on VdbeFrame objects */
++#define SQLITE_FRAME_MAGIC 0x879fb71e
++
++/*
++** Return a pointer to the array of registers allocated for use
++** by a VdbeFrame.
++*/
+ #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
+ 
+ /*
+@@ -18653,8 +20031,6 @@
+     int nZero;          /* Extra zero bytes when MEM_Zero and MEM_Blob set */
+     const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
+     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+-    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
+-    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
+   } u;
+   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
+@@ -18669,7 +20045,7 @@
+   void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
+ #ifdef SQLITE_DEBUG
+   Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
+-  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
++  u16 mScopyFlags;    /* flags value immediately after the shallow copy */
+ #endif
+ };
+ 
+@@ -18698,8 +20074,8 @@
+ #define MEM_Real      0x0008   /* Value is a real number */
+ #define MEM_Blob      0x0010   /* Value is a BLOB */
+ #define MEM_AffMask   0x001f   /* Mask of affinity bits */
+-#define MEM_RowSet    0x0020   /* Value is a RowSet object */
+-#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
++/* Available          0x0020   */
++/* Available          0x0040   */
+ #define MEM_Undefined 0x0080   /* Value is undefined */
+ #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
+ #define MEM_TypeMask  0xc1ff   /* Mask of type bits */
+@@ -18726,7 +20102,7 @@
+ ** that needs to be deallocated to avoid a leak.
+ */
+ #define VdbeMemDynamic(X)  \
+-  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
++  (((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
+ 
+ /*
+ ** Clear any existing type flags from a Mem and replace them with f
+@@ -18778,7 +20154,6 @@
+   int iOp;                /* Instruction number of OP_Function */
+   int isError;            /* Error code returned by the function. */
+   u8 skipFlag;            /* Skip accumulator loading if true */
+-  u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
+   u8 argc;                /* Number of arguments */
+   sqlite3_value *argv[1]; /* Argument set */
+ };
+@@ -18841,14 +20216,15 @@
+   int nOp;                /* Number of instructions in the program */
+ #ifdef SQLITE_DEBUG
+   int rcApp;              /* errcode set by sqlite3_result_error_code() */
++  u32 nWrite;             /* Number of write operations that have occurred */
+ #endif
+   u16 nResColumn;         /* Number of columns in one row of the result set */
+   u8 errorAction;         /* Recovery action to do in case of an error */
+   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
+   u8 prepFlags;           /* SQLITE_PREPARE_* flags */
+-  bft expired:1;          /* True if the VM needs to be recompiled */
++  bft expired:2;          /* 1: recompile VM immediately  2: when convenient */
++  bft explain:2;          /* True if EXPLAIN present on SQL command */
+   bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
+-  bft explain:2;          /* True if EXPLAIN present on SQL command */
+   bft changeCntOn:1;      /* True to update the change-counter */
+   bft runOnlyOnce:1;      /* Automatically expire on reset */
+   bft usesStmtJournal:1;  /* True if uses a statement journal */
+@@ -18858,6 +20234,9 @@
+   yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
+   u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
+   char *zSql;             /* Text of the SQL statement that generated this */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  char *zNormSql;         /* Normalization of the associated SQL statement */
++#endif
+   void *pFree;            /* Free this when deleting the vdbe */
+   VdbeFrame *pFrame;      /* Parent frame */
+   VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
+@@ -18909,9 +20288,6 @@
+ void sqliteVdbePopStack(Vdbe*,int);
+ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
+ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
+-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
+-#endif
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
+ SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+@@ -18923,7 +20299,9 @@
+ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
+ SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
++#ifndef SQLITE_OMIT_EXPLAIN
+ SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
++#endif
+ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
+ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
+ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
+@@ -18942,12 +20320,16 @@
+ SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
+-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
++#endif
++SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
+ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
+ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
+ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
+@@ -18955,11 +20337,20 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
+ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
++#endif
++#ifndef SQLITE_OMIT_EXPLAIN
+ SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
++#endif
+ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
+ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
+-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
++#endif
++SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*);      /* Destructor on Mem */
++SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
+ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
+@@ -18975,6 +20366,14 @@
+ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
+ 
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE   void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*);
++SQLITE_PRIVATE   void sqlite3VdbeAssertAbortable(Vdbe*);
++#else
++# define sqlite3VdbeIncrWriteCounter(V,C)
++# define sqlite3VdbeAssertAbortable(V)
++#endif
++
+ #if !defined(SQLITE_OMIT_SHARED_CACHE) 
+ SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
+ #else
+@@ -19126,7 +20525,6 @@
+                                            : sqlite3MallocMutex()) );
+   assert( op==SQLITE_STATUS_MALLOC_SIZE
+           || op==SQLITE_STATUS_PAGECACHE_SIZE
+-          || op==SQLITE_STATUS_SCRATCH_SIZE
+           || op==SQLITE_STATUS_PARSER_STACK );
+   if( newValue>wsdStat.mxValue[op] ){
+     wsdStat.mxValue[op] = newValue;
+@@ -19176,6 +20574,28 @@
+ }
+ 
+ /*
++** Return the number of LookasideSlot elements on the linked list
++*/
++static u32 countLookasideSlots(LookasideSlot *p){
++  u32 cnt = 0;
++  while( p ){
++    p = p->pNext;
++    cnt++;
++  }
++  return cnt;
++}
++
++/*
++** Count the number of slots of lookaside memory that are outstanding
++*/
++SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
++  u32 nInit = countLookasideSlots(db->lookaside.pInit);
++  u32 nFree = countLookasideSlots(db->lookaside.pFree);
++  if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
++  return db->lookaside.nSlot - (nInit+nFree);
++}
++
++/*
+ ** Query status information for a single database connection
+ */
+ SQLITE_API int sqlite3_db_status(
+@@ -19194,10 +20614,15 @@
+   sqlite3_mutex_enter(db->mutex);
+   switch( op ){
+     case SQLITE_DBSTATUS_LOOKASIDE_USED: {
+-      *pCurrent = db->lookaside.nOut;
+-      *pHighwater = db->lookaside.mxOut;
++      *pCurrent = sqlite3LookasideUsed(db, pHighwater);
+       if( resetFlag ){
+-        db->lookaside.mxOut = db->lookaside.nOut;
++        LookasideSlot *p = db->lookaside.pFree;
++        if( p ){
++          while( p->pNext ) p = p->pNext;
++          p->pNext = db->lookaside.pInit;
++          db->lookaside.pInit = db->lookaside.pFree;
++          db->lookaside.pFree = 0;
++        }
+       }
+       break;
+     }
+@@ -19315,6 +20740,9 @@
+     ** pagers the database handle is connected to. *pHighwater is always set 
+     ** to zero.
+     */
++    case SQLITE_DBSTATUS_CACHE_SPILL:
++      op = SQLITE_DBSTATUS_CACHE_WRITE+1;
++      /* Fall through into the next case */
+     case SQLITE_DBSTATUS_CACHE_HIT:
+     case SQLITE_DBSTATUS_CACHE_MISS:
+     case SQLITE_DBSTATUS_CACHE_WRITE:{
+@@ -19397,7 +20825,7 @@
+ **
+ **      Jean Meeus
+ **      Astronomical Algorithms, 2nd Edition, 1998
+-**      ISBM 0-943396-61-1
++**      ISBN 0-943396-61-1
+ **      Willmann-Bell, Inc
+ **      Richmond, Virginia (USA)
+ */
+@@ -20708,7 +22136,7 @@
+ }
+ SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
+   DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xSync(id, flags);
++  return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
+ }
+ SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
+   DO_OS_MALLOC_TEST(id);
+@@ -20735,8 +22163,11 @@
+ ** routine has no return value since the return value would be meaningless.
+ */
+ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
++  if( id->pMethods==0 ) return SQLITE_NOTFOUND;
+ #ifdef SQLITE_TEST
+-  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
++  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
++   && op!=SQLITE_FCNTL_LOCK_TIMEOUT
++  ){
+     /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+     ** is using a regular VFS, it is called after the corresponding
+     ** transaction has been committed. Injecting a fault at this point
+@@ -20753,7 +22184,7 @@
+   return id->pMethods->xFileControl(id, op, pArg);
+ }
+ SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
+-  (void)id->pMethods->xFileControl(id, op, pArg);
++  if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg);
+ }
+ 
+ SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
+@@ -20763,6 +22194,7 @@
+ SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
+   return id->pMethods->xDeviceCharacteristics(id);
+ }
++#ifndef SQLITE_OMIT_WAL
+ SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
+   return id->pMethods->xShmLock(id, offset, n, flags);
+ }
+@@ -20782,6 +22214,7 @@
+   DO_OS_MALLOC_TEST(id);
+   return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
+ }
++#endif /* SQLITE_OMIT_WAL */
+ 
+ #if SQLITE_MAX_MMAP_SIZE>0
+ /* The real implementation of xFetch and xUnfetch */
+@@ -21015,9 +22448,12 @@
+ ** Unregister a VFS so that it is no longer accessible.
+ */
+ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+-#if SQLITE_THREADSAFE
+-  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
++  MUTEX_LOGIC(sqlite3_mutex *mutex;)
++#ifndef SQLITE_OMIT_AUTOINIT
++  int rc = sqlite3_initialize();
++  if( rc ) return rc;
+ #endif
++  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+   sqlite3_mutex_enter(mutex);
+   vfsUnlink(pVfs);
+   sqlite3_mutex_leave(mutex);
+@@ -23300,7 +24736,194 @@
+ 
+ 
+ #ifndef SQLITE_MUTEX_OMIT
++
++#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ /*
++** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
++** the implementation of a wrapper around the system default mutex
++** implementation (sqlite3DefaultMutex()). 
++**
++** Most calls are passed directly through to the underlying default
++** mutex implementation. Except, if a mutex is configured by calling
++** sqlite3MutexWarnOnContention() on it, then if contention is ever
++** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
++**
++** This type of mutex is used as the database handle mutex when testing
++** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
++*/
++
++/* 
++** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
++** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
++** allocated by the system mutex implementation. Variable iType is usually set
++** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
++** or one of the static mutex identifiers. Or, if this is a recursive mutex
++** that has been configured using sqlite3MutexWarnOnContention(), it is
++** set to SQLITE_MUTEX_WARNONCONTENTION.
++*/
++typedef struct CheckMutex CheckMutex;
++struct CheckMutex {
++  int iType;
++  sqlite3_mutex *mutex;
++};
++
++#define SQLITE_MUTEX_WARNONCONTENTION  (-1)
++
++/* 
++** Pointer to real mutex methods object used by the CheckMutex
++** implementation. Set by checkMutexInit(). 
++*/
++static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
++
++#ifdef SQLITE_DEBUG
++static int checkMutexHeld(sqlite3_mutex *p){
++  return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
++}
++static int checkMutexNotheld(sqlite3_mutex *p){
++  return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
++}
++#endif
++
++/*
++** Initialize and deinitialize the mutex subsystem.
++*/
++static int checkMutexInit(void){ 
++  pGlobalMutexMethods = sqlite3DefaultMutex();
++  return SQLITE_OK; 
++}
++static int checkMutexEnd(void){ 
++  pGlobalMutexMethods = 0;
++  return SQLITE_OK; 
++}
++
++/*
++** Allocate a mutex.
++*/
++static sqlite3_mutex *checkMutexAlloc(int iType){
++  static CheckMutex staticMutexes[] = {
++    {2, 0}, {3, 0}, {4, 0}, {5, 0},
++    {6, 0}, {7, 0}, {8, 0}, {9, 0},
++    {10, 0}, {11, 0}, {12, 0}, {13, 0}
++  };
++  CheckMutex *p = 0;
++
++  assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
++  if( iType<2 ){
++    p = sqlite3MallocZero(sizeof(CheckMutex));
++    if( p==0 ) return 0;
++    p->iType = iType;
++  }else{
++#ifdef SQLITE_ENABLE_API_ARMOR
++    if( iType-2>=ArraySize(staticMutexes) ){
++      (void)SQLITE_MISUSE_BKPT;
++      return 0;
++    }
++#endif
++    p = &staticMutexes[iType-2];
++  }
++
++  if( p->mutex==0 ){
++    p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
++    if( p->mutex==0 ){
++      if( iType<2 ){
++        sqlite3_free(p);
++      }
++      p = 0;
++    }
++  }
++
++  return (sqlite3_mutex*)p;
++}
++
++/*
++** Free a mutex.
++*/
++static void checkMutexFree(sqlite3_mutex *p){
++  assert( SQLITE_MUTEX_RECURSIVE<2 );
++  assert( SQLITE_MUTEX_FAST<2 );
++  assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
++
++#if SQLITE_ENABLE_API_ARMOR
++  if( ((CheckMutex*)p)->iType<2 )
++#endif
++  {
++    CheckMutex *pCheck = (CheckMutex*)p;
++    pGlobalMutexMethods->xMutexFree(pCheck->mutex);
++    sqlite3_free(pCheck);
++  }
++#ifdef SQLITE_ENABLE_API_ARMOR
++  else{
++    (void)SQLITE_MISUSE_BKPT;
++  }
++#endif
++}
++
++/*
++** Enter the mutex.
++*/
++static void checkMutexEnter(sqlite3_mutex *p){
++  CheckMutex *pCheck = (CheckMutex*)p;
++  if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
++    if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
++      return;
++    }
++    sqlite3_log(SQLITE_MISUSE, 
++        "illegal multi-threaded access to database connection"
++    );
++  }
++  pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
++}
++
++/*
++** Enter the mutex (do not block).
++*/
++static int checkMutexTry(sqlite3_mutex *p){
++  CheckMutex *pCheck = (CheckMutex*)p;
++  return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
++}
++
++/*
++** Leave the mutex.
++*/
++static void checkMutexLeave(sqlite3_mutex *p){
++  CheckMutex *pCheck = (CheckMutex*)p;
++  pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
++}
++
++sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
++  static const sqlite3_mutex_methods sMutex = {
++    checkMutexInit,
++    checkMutexEnd,
++    checkMutexAlloc,
++    checkMutexFree,
++    checkMutexEnter,
++    checkMutexTry,
++    checkMutexLeave,
++#ifdef SQLITE_DEBUG
++    checkMutexHeld,
++    checkMutexNotheld
++#else
++    0,
++    0
++#endif
++  };
++  return &sMutex;
++}
++
++/*
++** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
++** one on which there should be no contention.
++*/
++SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
++  if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
++    CheckMutex *pCheck = (CheckMutex*)p;
++    assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
++    pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
++  }
++}
++#endif   /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
++
++/*
+ ** Initialize the mutex system.
+ */
+ SQLITE_PRIVATE int sqlite3MutexInit(void){ 
+@@ -23315,7 +24938,11 @@
+     sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
+ 
+     if( sqlite3GlobalConfig.bCoreMutex ){
++#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
++      pFrom = multiThreadedCheckMutex();
++#else
+       pFrom = sqlite3DefaultMutex();
++#endif
+     }else{
+       pFrom = sqlite3NoopMutex();
+     }
+@@ -23714,11 +25341,12 @@
+ #endif
+ };
+ #if SQLITE_MUTEX_NREF
+-#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}
++# define SQLITE3_MUTEX_INITIALIZER(id) \
++     {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
+ #elif defined(SQLITE_ENABLE_API_ARMOR)
+-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
++# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
+ #else
+-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
++#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
+ #endif
+ 
+ /*
+@@ -23815,18 +25443,18 @@
+ */
+ static sqlite3_mutex *pthreadMutexAlloc(int iType){
+   static sqlite3_mutex staticMutexes[] = {
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER,
+-    SQLITE3_MUTEX_INITIALIZER
++    SQLITE3_MUTEX_INITIALIZER(2),
++    SQLITE3_MUTEX_INITIALIZER(3),
++    SQLITE3_MUTEX_INITIALIZER(4),
++    SQLITE3_MUTEX_INITIALIZER(5),
++    SQLITE3_MUTEX_INITIALIZER(6),
++    SQLITE3_MUTEX_INITIALIZER(7),
++    SQLITE3_MUTEX_INITIALIZER(8),
++    SQLITE3_MUTEX_INITIALIZER(9),
++    SQLITE3_MUTEX_INITIALIZER(10),
++    SQLITE3_MUTEX_INITIALIZER(11),
++    SQLITE3_MUTEX_INITIALIZER(12),
++    SQLITE3_MUTEX_INITIALIZER(13)
+   };
+   sqlite3_mutex *p;
+   switch( iType ){
+@@ -23845,6 +25473,9 @@
+         pthread_mutex_init(&p->mutex, &recursiveAttr);
+         pthread_mutexattr_destroy(&recursiveAttr);
+ #endif
++#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
++        p->id = SQLITE_MUTEX_RECURSIVE;
++#endif
+       }
+       break;
+     }
+@@ -23852,6 +25483,9 @@
+       p = sqlite3MallocZero( sizeof(*p) );
+       if( p ){
+         pthread_mutex_init(&p->mutex, 0);
++#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
++        p->id = SQLITE_MUTEX_FAST;
++#endif
+       }
+       break;
+     }
+@@ -23867,7 +25501,7 @@
+     }
+   }
+ #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
+-  if( p ) p->id = iType;
++  assert( p==0 || p->id==iType );
+ #endif
+   return p;
+ }
+@@ -24384,7 +26018,7 @@
+ #ifdef SQLITE_DEBUG
+   volatile int nRef;         /* Number of enterances */
+   volatile DWORD owner;      /* Thread holding this mutex */
+-  volatile int trace;        /* True to trace changes */
++  volatile LONG trace;       /* True to trace changes */
+ #endif
+ };
+ 
+@@ -24396,10 +26030,10 @@
+ #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
+ 
+ #ifdef SQLITE_DEBUG
+-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
++#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
+                                     0L, (DWORD)0, 0 }
+ #else
+-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
++#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
+ #endif
+ 
+ #ifdef SQLITE_DEBUG
+@@ -24442,18 +26076,18 @@
+ ** Initialize and deinitialize the mutex subsystem.
+ */
+ static sqlite3_mutex winMutex_staticMutexes[] = {
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER,
+-  SQLITE3_MUTEX_INITIALIZER
++  SQLITE3_MUTEX_INITIALIZER(2),
++  SQLITE3_MUTEX_INITIALIZER(3),
++  SQLITE3_MUTEX_INITIALIZER(4),
++  SQLITE3_MUTEX_INITIALIZER(5),
++  SQLITE3_MUTEX_INITIALIZER(6),
++  SQLITE3_MUTEX_INITIALIZER(7),
++  SQLITE3_MUTEX_INITIALIZER(8),
++  SQLITE3_MUTEX_INITIALIZER(9),
++  SQLITE3_MUTEX_INITIALIZER(10),
++  SQLITE3_MUTEX_INITIALIZER(11),
++  SQLITE3_MUTEX_INITIALIZER(12),
++  SQLITE3_MUTEX_INITIALIZER(13)
+ };
+ 
+ static int winMutex_isInit = 0;
+@@ -24583,15 +26217,15 @@
+       }
+ #endif
+       p = &winMutex_staticMutexes[iType-2];
+-      p->id = iType;
+ #ifdef SQLITE_DEBUG
+ #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
+-      p->trace = 1;
++      InterlockedCompareExchange(&p->trace, 1, 0);
+ #endif
+ #endif
+       break;
+     }
+   }
++  assert( p==0 || p->id==iType );
+   return p;
+ }
+ 
+@@ -24779,14 +26413,6 @@
+ }
+ 
+ /*
+-** An instance of the following object records the location of
+-** each unused scratch buffer.
+-*/
+-typedef struct ScratchFreeslot {
+-  struct ScratchFreeslot *pNext;   /* Next unused scratch buffer */
+-} ScratchFreeslot;
+-
+-/*
+ ** State information local to the memory allocation subsystem.
+ */
+ static SQLITE_WSD struct Mem0Global {
+@@ -24794,21 +26420,11 @@
+   sqlite3_int64 alarmThreshold; /* The soft heap limit */
+ 
+   /*
+-  ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
+-  ** (so that a range test can be used to determine if an allocation
+-  ** being freed came from pScratch) and a pointer to the list of
+-  ** unused scratch allocations.
+-  */
+-  void *pScratchEnd;
+-  ScratchFreeslot *pScratchFree;
+-  u32 nScratchFree;
+-
+-  /*
+   ** True if heap is nearly "full" where "full" is defined by the
+   ** sqlite3_soft_heap_limit() setting.
+   */
+   int nearlyFull;
+-} mem0 = { 0, 0, 0, 0, 0, 0 };
++} mem0 = { 0, 0, 0 };
+ 
+ #define mem0 GLOBAL(struct Mem0Global, mem0)
+ 
+@@ -24878,28 +26494,6 @@
+   }
+   memset(&mem0, 0, sizeof(mem0));
+   mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+-  if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
+-      && sqlite3GlobalConfig.nScratch>0 ){
+-    int i, n, sz;
+-    ScratchFreeslot *pSlot;
+-    sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
+-    sqlite3GlobalConfig.szScratch = sz;
+-    pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
+-    n = sqlite3GlobalConfig.nScratch;
+-    mem0.pScratchFree = pSlot;
+-    mem0.nScratchFree = n;
+-    for(i=0; i<n-1; i++){
+-      pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
+-      pSlot = pSlot->pNext;
+-    }
+-    pSlot->pNext = 0;
+-    mem0.pScratchEnd = (void*)&pSlot[1];
+-  }else{
+-    mem0.pScratchEnd = 0;
+-    sqlite3GlobalConfig.pScratch = 0;
+-    sqlite3GlobalConfig.szScratch = 0;
+-    sqlite3GlobalConfig.nScratch = 0;
+-  }
+   if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
+       || sqlite3GlobalConfig.nPage<=0 ){
+     sqlite3GlobalConfig.pPage = 0;
+@@ -25051,105 +26645,6 @@
+ }
+ 
+ /*
+-** Each thread may only have a single outstanding allocation from
+-** xScratchMalloc().  We verify this constraint in the single-threaded
+-** case by setting scratchAllocOut to 1 when an allocation
+-** is outstanding clearing it when the allocation is freed.
+-*/
+-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+-static int scratchAllocOut = 0;
+-#endif
+-
+-
+-/*
+-** Allocate memory that is to be used and released right away.
+-** This routine is similar to alloca() in that it is not intended
+-** for situations where the memory might be held long-term.  This
+-** routine is intended to get memory to old large transient data
+-** structures that would not normally fit on the stack of an
+-** embedded processor.
+-*/
+-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
+-  void *p;
+-  assert( n>0 );
+-
+-  sqlite3_mutex_enter(mem0.mutex);
+-  sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
+-  if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
+-    p = mem0.pScratchFree;
+-    mem0.pScratchFree = mem0.pScratchFree->pNext;
+-    mem0.nScratchFree--;
+-    sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
+-    sqlite3_mutex_leave(mem0.mutex);
+-  }else{
+-    sqlite3_mutex_leave(mem0.mutex);
+-    p = sqlite3Malloc(n);
+-    if( sqlite3GlobalConfig.bMemstat && p ){
+-      sqlite3_mutex_enter(mem0.mutex);
+-      sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
+-      sqlite3_mutex_leave(mem0.mutex);
+-    }
+-    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
+-  }
+-  assert( sqlite3_mutex_notheld(mem0.mutex) );
+-
+-
+-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+-  /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
+-  ** buffers per thread.
+-  **
+-  ** This can only be checked in single-threaded mode.
+-  */
+-  assert( scratchAllocOut==0 );
+-  if( p ) scratchAllocOut++;
+-#endif
+-
+-  return p;
+-}
+-SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
+-  if( p ){
+-
+-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+-    /* Verify that no more than two scratch allocation per thread
+-    ** is outstanding at one time.  (This is only checked in the
+-    ** single-threaded case since checking in the multi-threaded case
+-    ** would be much more complicated.) */
+-    assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
+-    scratchAllocOut--;
+-#endif
+-
+-    if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){
+-      /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
+-      ScratchFreeslot *pSlot;
+-      pSlot = (ScratchFreeslot*)p;
+-      sqlite3_mutex_enter(mem0.mutex);
+-      pSlot->pNext = mem0.pScratchFree;
+-      mem0.pScratchFree = pSlot;
+-      mem0.nScratchFree++;
+-      assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
+-      sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1);
+-      sqlite3_mutex_leave(mem0.mutex);
+-    }else{
+-      /* Release memory back to the heap */
+-      assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
+-      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
+-      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+-      if( sqlite3GlobalConfig.bMemstat ){
+-        int iSize = sqlite3MallocSize(p);
+-        sqlite3_mutex_enter(mem0.mutex);
+-        sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
+-        sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
+-        sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
+-        sqlite3GlobalConfig.m.xFree(p);
+-        sqlite3_mutex_leave(mem0.mutex);
+-      }else{
+-        sqlite3GlobalConfig.m.xFree(p);
+-      }
+-    }
+-  }
+-}
+-
+-/*
+ ** TRUE if p is a lookaside memory allocation from db
+ */
+ #ifndef SQLITE_OMIT_LOOKASIDE
+@@ -25239,7 +26734,6 @@
+ #endif
+       pBuf->pNext = db->lookaside.pFree;
+       db->lookaside.pFree = pBuf;
+-      db->lookaside.nOut--;
+       return;
+     }
+   }
+@@ -25400,16 +26894,16 @@
+     assert( db->mallocFailed==0 );
+     if( n>db->lookaside.sz ){
+       db->lookaside.anStat[1]++;
+-    }else if( (pBuf = db->lookaside.pFree)==0 ){
+-      db->lookaside.anStat[2]++;
+-    }else{
++    }else if( (pBuf = db->lookaside.pFree)!=0 ){
+       db->lookaside.pFree = pBuf->pNext;
+-      db->lookaside.nOut++;
+       db->lookaside.anStat[0]++;
+-      if( db->lookaside.nOut>db->lookaside.mxOut ){
+-        db->lookaside.mxOut = db->lookaside.nOut;
+-      }
+       return (void*)pBuf;
++    }else if( (pBuf = db->lookaside.pInit)!=0 ){
++      db->lookaside.pInit = pBuf->pNext;
++      db->lookaside.anStat[0]++;
++      return (void*)pBuf;
++    }else{
++      db->lookaside.anStat[2]++;
+     }
+   }else if( db->mallocFailed ){
+     return 0;
+@@ -25514,6 +27008,19 @@
+ }
+ 
+ /*
++** The text between zStart and zEnd represents a phrase within a larger
++** SQL statement.  Make a copy of this phrase in space obtained form
++** sqlite3DbMalloc().  Omit leading and trailing whitespace.
++*/
++SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
++  int n;
++  while( sqlite3Isspace(zStart[0]) ) zStart++;
++  n = (int)(zEnd - zStart);
++  while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
++  return sqlite3DbStrNDup(db, zStart, n);
++}
++
++/*
+ ** Free any prior content in *pz and replace it with a copy of zNew.
+ */
+ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
+@@ -25725,7 +27232,7 @@
+ ** Set the StrAccum object to an error mode.
+ */
+ static void setStrAccumError(StrAccum *p, u8 eError){
+-  assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
++  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
+   p->accError = eError;
+   p->nAlloc = 0;
+ }
+@@ -25759,8 +27266,8 @@
+ /*
+ ** Render a string given by "fmt" into the StrAccum object.
+ */
+-SQLITE_PRIVATE void sqlite3VXPrintf(
+-  StrAccum *pAccum,          /* Accumulate results here */
++SQLITE_API void sqlite3_str_vappendf(
++  sqlite3_str *pAccum,       /* Accumulate results here */
+   const char *fmt,           /* Format string */
+   va_list ap                 /* arguments */
+ ){
+@@ -25797,6 +27304,11 @@
+   PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
+   char buf[etBUFSIZE];       /* Conversion buffer */
+ 
++  /* pAccum never starts out with an empty buffer that was obtained from 
++  ** malloc().  This precondition is required by the mprintf("%z...")
++  ** optimization. */
++  assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
++
+   bufpt = 0;
+   if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
+     pArgList = va_arg(ap, PrintfArguments*);
+@@ -25812,11 +27324,11 @@
+ #else
+       do{ fmt++; }while( *fmt && *fmt != '%' );
+ #endif
+-      sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
++      sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
+       if( *fmt==0 ) break;
+     }
+     if( (c=(*++fmt))==0 ){
+-      sqlite3StrAccumAppend(pAccum, "%", 1);
++      sqlite3_str_append(pAccum, "%", 1);
+       break;
+     }
+     /* Find out what flags are present */
+@@ -25994,7 +27506,7 @@
+           u64 n = (u64)precision + 10 + precision/3;
+           zOut = zExtra = sqlite3Malloc( n );
+           if( zOut==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+           nOut = (int)n;
+@@ -26119,7 +27631,7 @@
+           bufpt = zExtra 
+               = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
+           if( bufpt==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+         }
+@@ -26215,22 +27727,52 @@
+       case etCHARX:
+         if( bArgList ){
+           bufpt = getTextArg(pArgList);
+-          c = bufpt ? bufpt[0] : 0;
++          length = 1;
++          if( bufpt ){
++            buf[0] = c = *(bufpt++);
++            if( (c&0xc0)==0xc0 ){
++              while( length<4 && (bufpt[0]&0xc0)==0x80 ){
++                buf[length++] = *(bufpt++);
++              }
++            }
++          }else{
++            buf[0] = 0;
++          }
+         }else{
+-          c = va_arg(ap,int);
++          unsigned int ch = va_arg(ap,unsigned int);
++          if( ch<0x00080 ){
++            buf[0] = ch & 0xff;
++            length = 1;
++          }else if( ch<0x00800 ){
++            buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
++            buf[1] = 0x80 + (u8)(ch & 0x3f);
++            length = 2;
++          }else if( ch<0x10000 ){
++            buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
++            buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
++            buf[2] = 0x80 + (u8)(ch & 0x3f);
++            length = 3;
++          }else{
++            buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
++            buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
++            buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
++            buf[3] = 0x80 + (u8)(ch & 0x3f);
++            length = 4;
++          }
+         }
+         if( precision>1 ){
+           width -= precision-1;
+           if( width>1 && !flag_leftjustify ){
+-            sqlite3AppendChar(pAccum, width-1, ' ');
++            sqlite3_str_appendchar(pAccum, width-1, ' ');
+             width = 0;
+           }
+-          sqlite3AppendChar(pAccum, precision-1, c);
++          while( precision-- > 1 ){
++            sqlite3_str_append(pAccum, buf, length);
++          }
+         }
+-        length = 1;
+-        buf[0] = c;
+         bufpt = buf;
+-        break;
++        flag_altform2 = 1;
++        goto adjust_width_for_utf8;
+       case etSTRING:
+       case etDYNSTRING:
+         if( bArgList ){
+@@ -26242,17 +27784,50 @@
+         if( bufpt==0 ){
+           bufpt = "";
+         }else if( xtype==etDYNSTRING ){
++          if( pAccum->nChar==0
++           && pAccum->mxAlloc
++           && width==0
++           && precision<0
++           && pAccum->accError==0
++          ){
++            /* Special optimization for sqlite3_mprintf("%z..."):
++            ** Extend an existing memory allocation rather than creating
++            ** a new one. */
++            assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
++            pAccum->zText = bufpt;
++            pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
++            pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
++            pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
++            length = 0;
++            break;
++          }
+           zExtra = bufpt;
+         }
+         if( precision>=0 ){
+-          for(length=0; length<precision && bufpt[length]; length++){}
++          if( flag_altform2 ){
++            /* Set length to the number of bytes needed in order to display
++            ** precision characters */
++            unsigned char *z = (unsigned char*)bufpt;
++            while( precision-- > 0 && z[0] ){
++              SQLITE_SKIP_UTF8(z);
++            }
++            length = (int)(z - (unsigned char*)bufpt);
++          }else{
++            for(length=0; length<precision && bufpt[length]; length++){}
++          }
+         }else{
+-          length = sqlite3Strlen30(bufpt);
++          length = 0x7fffffff & (int)strlen(bufpt);
+         }
++      adjust_width_for_utf8:
++        if( flag_altform2 && width>0 ){
++          /* Adjust width to account for extra bytes in UTF-8 characters */
++          int ii = length - 1;
++          while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
++        }
+         break;
+-      case etSQLESCAPE:           /* Escape ' characters */
+-      case etSQLESCAPE2:          /* Escape ' and enclose in '...' */
+-      case etSQLESCAPE3: {        /* Escape " characters */
++      case etSQLESCAPE:           /* %q: Escape ' characters */
++      case etSQLESCAPE2:          /* %Q: Escape ' and enclose in '...' */
++      case etSQLESCAPE3: {        /* %w: Escape " characters */
+         int i, j, k, n, isnull;
+         int needQuote;
+         char ch;
+@@ -26266,9 +27841,17 @@
+         }
+         isnull = escarg==0;
+         if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
++        /* For %q, %Q, and %w, the precision is the number of byte (or
++        ** characters if the ! flags is present) to use from the input.
++        ** Because of the extra quoting characters inserted, the number
++        ** of output characters may be larger than the precision.
++        */
+         k = precision;
+         for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
+           if( ch==q )  n++;
++          if( flag_altform2 && (ch&0xc0)==0xc0 ){
++            while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
++          }
+         }
+         needQuote = !isnull && xtype==etSQLESCAPE2;
+         n += i + 3;
+@@ -26275,7 +27858,7 @@
+         if( n>etBUFSIZE ){
+           bufpt = zExtra = sqlite3Malloc( n );
+           if( bufpt==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+         }else{
+@@ -26291,10 +27874,7 @@
+         if( needQuote ) bufpt[j++] = q;
+         bufpt[j] = 0;
+         length = j;
+-        /* The precision in %q and %Q means how many input characters to
+-        ** consume, not the length of the output...
+-        ** if( precision>=0 && precision<length ) length = precision; */
+-        break;
++        goto adjust_width_for_utf8;
+       }
+       case etTOKEN: {
+         Token *pToken;
+@@ -26302,7 +27882,7 @@
+         pToken = va_arg(ap, Token*);
+         assert( bArgList==0 );
+         if( pToken && pToken->n ){
+-          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
++          sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
+         }
+         length = width = 0;
+         break;
+@@ -26318,10 +27898,10 @@
+         assert( bArgList==0 );
+         assert( k>=0 && k<pSrc->nSrc );
+         if( pItem->zDatabase ){
+-          sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
+-          sqlite3StrAccumAppend(pAccum, ".", 1);
++          sqlite3_str_appendall(pAccum, pItem->zDatabase);
++          sqlite3_str_append(pAccum, ".", 1);
+         }
+-        sqlite3StrAccumAppendAll(pAccum, pItem->zName);
++        sqlite3_str_appendall(pAccum, pItem->zName);
+         length = width = 0;
+         break;
+       }
+@@ -26333,15 +27913,18 @@
+     /*
+     ** The text of the conversion is pointed to by "bufpt" and is
+     ** "length" characters long.  The field width is "width".  Do
+-    ** the output.
++    ** the output.  Both length and width are in bytes, not characters,
++    ** at this point.  If the "!" flag was present on string conversions
++    ** indicating that width and precision should be expressed in characters,
++    ** then the values have been translated prior to reaching this point.
+     */
+     width -= length;
+     if( width>0 ){
+-      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+-      sqlite3StrAccumAppend(pAccum, bufpt, length);
+-      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
++      if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
++      sqlite3_str_append(pAccum, bufpt, length);
++      if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
+     }else{
+-      sqlite3StrAccumAppend(pAccum, bufpt, length);
++      sqlite3_str_append(pAccum, bufpt, length);
+     }
+ 
+     if( zExtra ){
+@@ -26362,18 +27945,17 @@
+   char *zNew;
+   assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+   if( p->accError ){
+-    testcase(p->accError==STRACCUM_TOOBIG);
+-    testcase(p->accError==STRACCUM_NOMEM);
++    testcase(p->accError==SQLITE_TOOBIG);
++    testcase(p->accError==SQLITE_NOMEM);
+     return 0;
+   }
+   if( p->mxAlloc==0 ){
+     N = p->nAlloc - p->nChar - 1;
+-    setStrAccumError(p, STRACCUM_TOOBIG);
++    setStrAccumError(p, SQLITE_TOOBIG);
+     return N;
+   }else{
+     char *zOld = isMalloced(p) ? p->zText : 0;
+     i64 szNew = p->nChar;
+-    assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
+     szNew += N + 1;
+     if( szNew+p->nChar<=p->mxAlloc ){
+       /* Force exponential buffer size growth as long as it does not overflow,
+@@ -26381,8 +27963,8 @@
+       szNew += p->nChar;
+     }
+     if( szNew > p->mxAlloc ){
+-      sqlite3StrAccumReset(p);
+-      setStrAccumError(p, STRACCUM_TOOBIG);
++      sqlite3_str_reset(p);
++      setStrAccumError(p, SQLITE_TOOBIG);
+       return 0;
+     }else{
+       p->nAlloc = (int)szNew;
+@@ -26399,8 +27981,8 @@
+       p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
+       p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+     }else{
+-      sqlite3StrAccumReset(p);
+-      setStrAccumError(p, STRACCUM_NOMEM);
++      sqlite3_str_reset(p);
++      setStrAccumError(p, SQLITE_NOMEM);
+       return 0;
+     }
+   }
+@@ -26410,12 +27992,11 @@
+ /*
+ ** Append N copies of character c to the given string buffer.
+ */
+-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
+   testcase( p->nChar + (i64)N > 0x7fffffff );
+   if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+     return;
+   }
+-  assert( (p->zText==p->zBase)==!isMalloced(p) );
+   while( (N--)>0 ) p->zText[p->nChar++] = c;
+ }
+ 
+@@ -26423,9 +28004,9 @@
+ ** The StrAccum "p" is not large enough to accept N new bytes of z[].
+ ** So enlarge if first, then do the append.
+ **
+-** This is a helper routine to sqlite3StrAccumAppend() that does special-case
++** This is a helper routine to sqlite3_str_append() that does special-case
+ ** work (enlarging the buffer) using tail recursion, so that the
+-** sqlite3StrAccumAppend() routine can use fast calling semantics.
++** sqlite3_str_append() routine can use fast calling semantics.
+ */
+ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
+   N = sqlite3StrAccumEnlarge(p, N);
+@@ -26433,7 +28014,6 @@
+     memcpy(&p->zText[p->nChar], z, N);
+     p->nChar += N;
+   }
+-  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
+ }
+ 
+ /*
+@@ -26440,7 +28020,7 @@
+ ** Append N bytes of text from z to the StrAccum object.  Increase the
+ ** size of the memory allocation for StrAccum if necessary.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
++SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
+   assert( z!=0 || N==0 );
+   assert( p->zText!=0 || p->nChar==0 || p->accError );
+   assert( N>=0 );
+@@ -26457,8 +28037,8 @@
+ /*
+ ** Append the complete text of zero-terminated string z[] to the p string.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
+-  sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
++SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){
++  sqlite3_str_append(p, z, sqlite3Strlen30(z));
+ }
+ 
+ 
+@@ -26468,19 +28048,20 @@
+ ** pointer if any kind of error was encountered.
+ */
+ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
++  char *zText;
+   assert( p->mxAlloc>0 && !isMalloced(p) );
+-  p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+-  if( p->zText ){
+-    memcpy(p->zText, p->zBase, p->nChar+1);
++  zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
++  if( zText ){
++    memcpy(zText, p->zText, p->nChar+1);
+     p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+   }else{
+-    setStrAccumError(p, STRACCUM_NOMEM);
++    setStrAccumError(p, SQLITE_NOMEM);
+   }
+-  return p->zText;
++  p->zText = zText;
++  return zText;
+ }
+ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
+   if( p->zText ){
+-    assert( (p->zText==p->zBase)==!isMalloced(p) );
+     p->zText[p->nChar] = 0;
+     if( p->mxAlloc>0 && !isMalloced(p) ){
+       return strAccumFinishRealloc(p);
+@@ -26490,14 +28071,55 @@
+ }
+ 
+ /*
++** This singleton is an sqlite3_str object that is returned if
++** sqlite3_malloc() fails to provide space for a real one.  This
++** sqlite3_str object accepts no new text and always returns
++** an SQLITE_NOMEM error.
++*/
++static sqlite3_str sqlite3OomStr = {
++   0, 0, 0, 0, 0, SQLITE_NOMEM, 0
++};
++
++/* Finalize a string created using sqlite3_str_new().
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){
++  char *z;
++  if( p!=0 && p!=&sqlite3OomStr ){
++    z = sqlite3StrAccumFinish(p);
++    sqlite3_free(p);
++  }else{
++    z = 0;
++  }
++  return z;
++}
++
++/* Return any error code associated with p */
++SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){
++  return p ? p->accError : SQLITE_NOMEM;
++}
++
++/* Return the current length of p in bytes */
++SQLITE_API int sqlite3_str_length(sqlite3_str *p){
++  return p ? p->nChar : 0;
++}
++
++/* Return the current value for p */
++SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
++  if( p==0 || p->nChar==0 ) return 0;
++  p->zText[p->nChar] = 0;
++  return p->zText;
++}
++
++/*
+ ** Reset an StrAccum string.  Reclaim all malloced memory.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
+-  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
++SQLITE_API void sqlite3_str_reset(StrAccum *p){
+   if( isMalloced(p) ){
+     sqlite3DbFree(p->db, p->zText);
+     p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
+   }
++  p->nAlloc = 0;
++  p->nChar = 0;
+   p->zText = 0;
+ }
+ 
+@@ -26516,15 +28138,27 @@
+ **        allocations will ever occur.
+ */
+ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
+-  p->zText = p->zBase = zBase;
++  p->zText = zBase;
+   p->db = db;
+-  p->nChar = 0;
+   p->nAlloc = n;
+   p->mxAlloc = mx;
++  p->nChar = 0;
+   p->accError = 0;
+   p->printfFlags = 0;
+ }
+ 
++/* Allocate and initialize a new dynamic string object */
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){
++  sqlite3_str *p = sqlite3_malloc64(sizeof(*p));
++  if( p ){
++    sqlite3StrAccumInit(p, 0, 0, 0,
++            db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
++  }else{
++    p = &sqlite3OomStr;
++  }
++  return p;
++}
++
+ /*
+ ** Print into memory obtained from sqliteMalloc().  Use the internal
+ ** %-conversion extensions.
+@@ -26537,9 +28171,9 @@
+   sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
+                       db->aLimit[SQLITE_LIMIT_LENGTH]);
+   acc.printfFlags = SQLITE_PRINTF_INTERNAL;
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+-  if( acc.accError==STRACCUM_NOMEM ){
++  if( acc.accError==SQLITE_NOMEM ){
+     sqlite3OomFault(db);
+   }
+   return z;
+@@ -26577,7 +28211,7 @@
+   if( sqlite3_initialize() ) return 0;
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+   return z;
+ }
+@@ -26622,7 +28256,7 @@
+   }
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   zBuf[acc.nChar] = 0;
+   return zBuf;
+ }
+@@ -26644,7 +28278,7 @@
+ ** allocate memory because it might be called while the memory allocator
+ ** mutex is held.
+ **
+-** sqlite3VXPrintf() might ask for *temporary* memory allocations for
++** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
+ ** certain format characters (%q) or for very large precisions or widths.
+ ** Care must be taken that any sqlite3_log() calls that occur while the
+ ** memory mutex is held do not use these mechanisms.
+@@ -26654,7 +28288,7 @@
+   char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
+ 
+   sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
+                            sqlite3StrAccumFinish(&acc));
+ }
+@@ -26683,23 +28317,30 @@
+   char zBuf[500];
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+   va_start(ap,zFormat);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   va_end(ap);
+   sqlite3StrAccumFinish(&acc);
++#ifdef SQLITE_OS_TRACE_PROC
++  {
++    extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
++    SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
++  }
++#else
+   fprintf(stdout,"%s", zBuf);
+   fflush(stdout);
++#endif
+ }
+ #endif
+ 
+ 
+ /*
+-** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
++** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
+ ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
+ */
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
++SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
+   va_list ap;
+   va_start(ap,zFormat);
+-  sqlite3VXPrintf(p, zFormat, ap);
++  sqlite3_str_vappendf(p, zFormat, ap);
+   va_end(ap);
+ }
+ 
+@@ -26765,15 +28406,17 @@
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+   if( p ){
+     for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+-      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
++      sqlite3_str_append(&acc, p->bLine[i] ? "|   " : "    ", 4);
+     }
+-    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
++    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+   }
+-  va_start(ap, zFormat);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
+-  va_end(ap);
+-  assert( acc.nChar>0 );
+-  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
++  if( zFormat!=0 ){
++    va_start(ap, zFormat);
++    sqlite3_str_vappendf(&acc, zFormat, ap);
++    va_end(ap);
++    assert( acc.nChar>0 );
++    sqlite3_str_append(&acc, "\n", 1);
++  }
+   sqlite3StrAccumFinish(&acc);
+   fprintf(stdout,"%s", zBuf);
+   fflush(stdout);
+@@ -26806,17 +28449,17 @@
+       char zLine[1000];
+       const struct Cte *pCte = &pWith->a[i];
+       sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+-      sqlite3XPrintf(&x, "%s", pCte->zName);
++      sqlite3_str_appendf(&x, "%s", pCte->zName);
+       if( pCte->pCols && pCte->pCols->nExpr>0 ){
+         char cSep = '(';
+         int j;
+         for(j=0; j<pCte->pCols->nExpr; j++){
+-          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
++          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
+           cSep = ',';
+         }
+-        sqlite3XPrintf(&x, ")");
++        sqlite3_str_appendf(&x, ")");
+       }
+-      sqlite3XPrintf(&x, " AS");
++      sqlite3_str_appendf(&x, " AS");
+       sqlite3StrAccumFinish(&x);
+       sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
+       sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
+@@ -26826,6 +28469,42 @@
+   }
+ }
+ 
++/*
++** Generate a human-readable description of a SrcList object.
++*/
++SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
++  int i;
++  for(i=0; i<pSrc->nSrc; i++){
++    const struct SrcList_item *pItem = &pSrc->a[i];
++    StrAccum x;
++    char zLine[100];
++    sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
++    sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
++    if( pItem->zDatabase ){
++      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
++    }else if( pItem->zName ){
++      sqlite3_str_appendf(&x, " %s", pItem->zName);
++    }
++    if( pItem->pTab ){
++      sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
++    }
++    if( pItem->zAlias ){
++      sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
++    }
++    if( pItem->fg.jointype & JT_LEFT ){
++      sqlite3_str_appendf(&x, " LEFT-JOIN");
++    }
++    sqlite3StrAccumFinish(&x);
++    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); 
++    if( pItem->pSelect ){
++      sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
++    }
++    if( pItem->fg.isTabFunc ){
++      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
++    }
++    sqlite3TreeViewPop(pView);
++  }
++}
+ 
+ /*
+ ** Generate a human-readable description of a Select object.
+@@ -26844,9 +28523,11 @@
+     sqlite3TreeViewPush(pView, 1);
+   }
+   do{
+-    sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
++    sqlite3TreeViewLine(pView,
++      "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
+       ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+-      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
++      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
++      p->selId, p, p->selFlags,
+       (int)p->nSelectRow
+     );
+     if( cnt++ ) sqlite3TreeViewPop(pView);
+@@ -26860,43 +28541,27 @@
+       if( p->pHaving ) n++;
+       if( p->pOrderBy ) n++;
+       if( p->pLimit ) n++;
+-      if( p->pOffset ) n++;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( p->pWin ) n++;
++      if( p->pWinDefn ) n++;
++#endif
+     }
+     sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( p->pWin ){
++      Window *pX;
++      pView = sqlite3TreeViewPush(pView, (n--)>0);
++      sqlite3TreeViewLine(pView, "window-functions");
++      for(pX=p->pWin; pX; pX=pX->pNextWin){
++        sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
++      }
++      sqlite3TreeViewPop(pView);
++    }
++#endif
+     if( p->pSrc && p->pSrc->nSrc ){
+-      int i;
+       pView = sqlite3TreeViewPush(pView, (n--)>0);
+       sqlite3TreeViewLine(pView, "FROM");
+-      for(i=0; i<p->pSrc->nSrc; i++){
+-        struct SrcList_item *pItem = &p->pSrc->a[i];
+-        StrAccum x;
+-        char zLine[100];
+-        sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+-        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
+-        if( pItem->zDatabase ){
+-          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
+-        }else if( pItem->zName ){
+-          sqlite3XPrintf(&x, " %s", pItem->zName);
+-        }
+-        if( pItem->pTab ){
+-          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
+-        }
+-        if( pItem->zAlias ){
+-          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
+-        }
+-        if( pItem->fg.jointype & JT_LEFT ){
+-          sqlite3XPrintf(&x, " LEFT-JOIN");
+-        }
+-        sqlite3StrAccumFinish(&x);
+-        sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
+-        if( pItem->pSelect ){
+-          sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+-        }
+-        if( pItem->fg.isTabFunc ){
+-          sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+-        }
+-        sqlite3TreeViewPop(pView);
+-      }
++      sqlite3TreeViewSrcList(pView, p->pSrc);
+       sqlite3TreeViewPop(pView);
+     }
+     if( p->pWhere ){
+@@ -26912,19 +28577,29 @@
+       sqlite3TreeViewExpr(pView, p->pHaving, 0);
+       sqlite3TreeViewPop(pView);
+     }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( p->pWinDefn ){
++      Window *pX;
++      sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
++      for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
++        sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
++      }
++      sqlite3TreeViewPop(pView);
++    }
++#endif
+     if( p->pOrderBy ){
+       sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+     }
+     if( p->pLimit ){
+       sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+-      sqlite3TreeViewExpr(pView, p->pLimit, 0);
++      sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
++      if( p->pLimit->pRight ){
++        sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
++        sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
++        sqlite3TreeViewPop(pView);
++      }
+       sqlite3TreeViewPop(pView);
+     }
+-    if( p->pOffset ){
+-      sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+-      sqlite3TreeViewExpr(pView, p->pOffset, 0);
+-      sqlite3TreeViewPop(pView);
+-    }
+     if( p->pPrior ){
+       const char *zOp = "UNION";
+       switch( p->op ){
+@@ -26939,7 +28614,84 @@
+   sqlite3TreeViewPop(pView);
+ }
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
+ /*
++** Generate a description of starting or stopping bounds
++*/
++SQLITE_PRIVATE void sqlite3TreeViewBound(
++  TreeView *pView,        /* View context */
++  u8 eBound,              /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
++  Expr *pExpr,            /* Value for PRECEDING or FOLLOWING */
++  u8 moreToFollow         /* True if more to follow */
++){
++  switch( eBound ){
++    case TK_UNBOUNDED: {
++      sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_CURRENT: {
++      sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_PRECEDING: {
++      sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
++      sqlite3TreeViewExpr(pView, pExpr, 0);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_FOLLOWING: {
++      sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
++      sqlite3TreeViewExpr(pView, pExpr, 0);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++  }
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Generate a human-readable explanation for a Window object
++*/
++SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
++  pView = sqlite3TreeViewPush(pView, more);
++  if( pWin->zName ){
++    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
++  }else{
++    sqlite3TreeViewLine(pView, "OVER");
++  }
++  if( pWin->pPartition ){
++    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
++  }
++  if( pWin->pOrderBy ){
++    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
++  }
++  if( pWin->eType ){
++    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
++    sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
++    sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
++    sqlite3TreeViewPop(pView);
++  }
++  sqlite3TreeViewPop(pView);
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Generate a human-readable explanation for a Window Function object
++*/
++SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
++  pView = sqlite3TreeViewPush(pView, more);
++  sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
++                       pWin->pFunc->zName, pWin->pFunc->nArg);
++  sqlite3TreeViewWindow(pView, pWin, 0);
++  sqlite3TreeViewPop(pView);
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** Generate a human-readable explanation of an expression tree.
+ */
+ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
+@@ -26976,6 +28728,9 @@
+         sqlite3TreeViewLine(pView, "{%d:%d}%s",
+                              pExpr->iTable, pExpr->iColumn, zFlgs);
+       }
++      if( ExprHasProperty(pExpr, EP_FixedCol) ){
++        sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      }
+       break;
+     }
+     case TK_INTEGER: {
+@@ -27000,6 +28755,11 @@
+       sqlite3TreeViewLine(pView,"NULL");
+       break;
+     }
++    case TK_TRUEFALSE: {
++      sqlite3TreeViewLine(pView,
++         sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE");
++      break;
++    }
+ #ifndef SQLITE_OMIT_BLOB_LITERAL
+     case TK_BLOB: {
+       sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
+@@ -27056,6 +28816,19 @@
+     case TK_ISNULL:  zUniOp = "ISNULL"; break;
+     case TK_NOTNULL: zUniOp = "NOTNULL"; break;
+ 
++    case TK_TRUTH: {
++      int x;
++      const char *azOp[] = {
++         "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE"
++      };
++      assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
++      assert( pExpr->pRight );
++      assert( pExpr->pRight->op==TK_TRUEFALSE );
++      x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
++      zUniOp = azOp[x];
++      break;
++    }
++
+     case TK_SPAN: {
+       sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
+       sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+@@ -27071,10 +28844,17 @@
+     case TK_AGG_FUNCTION:
+     case TK_FUNCTION: {
+       ExprList *pFarg;       /* List of function arguments */
++      Window *pWin;
+       if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+         pFarg = 0;
++        pWin = 0;
+       }else{
+         pFarg = pExpr->x.pList;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        pWin = pExpr->y.pWin;
++#else
++        pWin = 0;
++#endif 
+       }
+       if( pExpr->op==TK_AGG_FUNCTION ){
+         sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
+@@ -27083,8 +28863,13 @@
+         sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
+       }
+       if( pFarg ){
+-        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
++        sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
+       }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( pWin ){
++        sqlite3TreeViewWindow(pView, pWin, 0);
++      }
++#endif
+       break;
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+@@ -27215,12 +29000,25 @@
+     sqlite3TreeViewLine(pView, "%s", zLabel);
+     for(i=0; i<pList->nExpr; i++){
+       int j = pList->a[i].u.x.iOrderByCol;
+-      if( j ){
+-        sqlite3TreeViewPush(pView, 0);
+-        sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
++      char *zName = pList->a[i].zName;
++      int moreToFollow = i<pList->nExpr - 1;
++      if( j || zName ){
++        sqlite3TreeViewPush(pView, moreToFollow);
++        moreToFollow = 0;
++        sqlite3TreeViewLine(pView, 0);
++        if( zName ){
++          fprintf(stdout, "AS %s ", zName);
++        }
++        if( j ){
++          fprintf(stdout, "iOrderByCol=%d", j);
++        }
++        fprintf(stdout, "\n");
++        fflush(stdout);
+       }
+-      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
+-      if( j ) sqlite3TreeViewPop(pView);
++      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
++      if( j || zName ){
++        sqlite3TreeViewPop(pView);
++      }
+     }
+   }
+ }
+@@ -28511,6 +30309,45 @@
+ }
+ 
+ /*
++** Compute 10 to the E-th power.  Examples:  E==1 results in 10.
++** E==2 results in 100.  E==50 results in 1.0e50.
++**
++** This routine only works for values of E between 1 and 341.
++*/
++static LONGDOUBLE_TYPE sqlite3Pow10(int E){
++#if defined(_MSC_VER)
++  static const LONGDOUBLE_TYPE x[] = {
++    1.0e+001,
++    1.0e+002,
++    1.0e+004,
++    1.0e+008,
++    1.0e+016,
++    1.0e+032,
++    1.0e+064,
++    1.0e+128,
++    1.0e+256
++  };
++  LONGDOUBLE_TYPE r = 1.0;
++  int i;
++  assert( E>=0 && E<=307 );
++  for(i=0; E!=0; i++, E >>=1){
++    if( E & 1 ) r *= x[i];
++  }
++  return r;
++#else
++  LONGDOUBLE_TYPE x = 10.0;
++  LONGDOUBLE_TYPE r = 1.0;
++  while(1){
++    if( E & 1 ) r *= x;
++    E >>= 1;
++    if( E==0 ) break;
++    x *= x;
++  }
++  return r; 
++#endif
++}
++
++/*
+ ** The string z[] is an text representation of a real number.
+ ** Convert this string to a double and write it into *pResult.
+ **
+@@ -28577,12 +30414,12 @@
+   /* copy max significant digits to significand */
+   while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+     s = s*10 + (*z - '0');
+-    z+=incr, nDigits++;
++    z+=incr; nDigits++;
+   }
+ 
+   /* skip non-significant significand digits
+   ** (increase exponent by d to shift decimal left) */
+-  while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
++  while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
+   if( z>=zEnd ) goto do_atof_calc;
+ 
+   /* if decimal point is present */
+@@ -28595,7 +30432,7 @@
+         s = s*10 + (*z - '0');
+         d--;
+       }
+-      z+=incr, nDigits++;
++      z+=incr; nDigits++;
+     }
+   }
+   if( z>=zEnd ) goto do_atof_calc;
+@@ -28665,11 +30502,10 @@
+     if( e==0 ){                                         /*OPTIMIZATION-IF-TRUE*/
+       result = (double)s;
+     }else{
+-      LONGDOUBLE_TYPE scale = 1.0;
+       /* attempt to handle extremely small/large numbers better */
+       if( e>307 ){                                      /*OPTIMIZATION-IF-TRUE*/
+         if( e<342 ){                                    /*OPTIMIZATION-IF-TRUE*/
+-          while( e%308 ) { scale *= 1.0e+1; e -= 1; }
++          LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
+           if( esign<0 ){
+             result = s / scale;
+             result /= 1.0e+308;
+@@ -28681,14 +30517,15 @@
+           if( esign<0 ){
+             result = 0.0*s;
+           }else{
++#ifdef INFINITY
++            result = INFINITY*s;
++#else
+             result = 1e308*1e308*s;  /* Infinity */
++#endif
+           }
+         }
+       }else{
+-        /* 1.0e+22 is the largest power of 10 than can be 
+-        ** represented exactly. */
+-        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
+-        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
++        LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
+         if( esign<0 ){
+           result = s / scale;
+         }else{
+@@ -28743,17 +30580,13 @@
+ ** Convert zNum to a 64-bit signed integer.  zNum must be decimal. This
+ ** routine does *not* accept hexadecimal notation.
+ **
+-** If the zNum value is representable as a 64-bit twos-complement 
+-** integer, then write that value into *pNum and return 0.
++** Returns:
+ **
+-** If zNum is exactly 9223372036854775808, return 2.  This special
+-** case is broken out because while 9223372036854775808 cannot be a 
+-** signed 64-bit integer, its negative -9223372036854775808 can be.
++**     0    Successful transformation.  Fits in a 64-bit signed integer.
++**     1    Excess non-space text after the integer value
++**     2    Integer too large for a 64-bit signed integer or is malformed
++**     3    Special case of 9223372036854775808
+ **
+-** If zNum is too big for a 64-bit integer and is not
+-** 9223372036854775808  or if zNum contains any non-numeric text,
+-** then return 1.
+-**
+ ** length is the number of bytes in the string (bytes, not characters).
+ ** The string is not necessarily zero-terminated.  The encoding is
+ ** given by enc.
+@@ -28765,6 +30598,7 @@
+   int i;
+   int c = 0;
+   int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
++  int rc;          /* Baseline return code */
+   const char *zStart;
+   const char *zEnd = zNum + length;
+   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
+@@ -28792,7 +30626,14 @@
+   for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
+     u = u*10 + c - '0';
+   }
++  testcase( i==18*incr );
++  testcase( i==19*incr );
++  testcase( i==20*incr );
+   if( u>LARGEST_INT64 ){
++    /* This test and assignment is needed only to suppress UB warnings
++    ** from clang and -fsanitize=undefined.  This test and assignment make
++    ** the code a little larger and slower, and no harm comes from omitting
++    ** them, but we must appaise the undefined-behavior pharisees. */
+     *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
+   }else if( neg ){
+     *pNum = -(i64)u;
+@@ -28799,36 +30640,43 @@
+   }else{
+     *pNum = (i64)u;
+   }
+-  testcase( i==18 );
+-  testcase( i==19 );
+-  testcase( i==20 );
+-  if( &zNum[i]<zEnd              /* Extra bytes at the end */
+-   || (i==0 && zStart==zNum)     /* No digits */
+-   || i>19*incr                  /* Too many digits */
++  rc = 0;
++  if( (i==0 && zStart==zNum)     /* No digits */
+    || nonNum                     /* UTF16 with high-order bytes non-zero */
+   ){
+-    /* zNum is empty or contains non-numeric text or is longer
+-    ** than 19 digits (thus guaranteeing that it is too large) */
+-    return 1;
+-  }else if( i<19*incr ){
++    rc = 1;
++  }else if( &zNum[i]<zEnd ){     /* Extra bytes at the end */
++    int jj = i;
++    do{
++      if( !sqlite3Isspace(zNum[jj]) ){
++        rc = 1;          /* Extra non-space text after the integer */
++        break;
++      }
++      jj += incr;
++    }while( &zNum[jj]<zEnd );
++  }
++  if( i<19*incr ){
+     /* Less than 19 digits, so we know that it fits in 64 bits */
+     assert( u<=LARGEST_INT64 );
+-    return 0;
++    return rc;
+   }else{
+     /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
+-    c = compare2pow63(zNum, incr);
++    c = i>19*incr ? 1 : compare2pow63(zNum, incr);
+     if( c<0 ){
+       /* zNum is less than 9223372036854775808 so it fits */
+       assert( u<=LARGEST_INT64 );
+-      return 0;
+-    }else if( c>0 ){
+-      /* zNum is greater than 9223372036854775808 so it overflows */
+-      return 1;
++      return rc;
+     }else{
+-      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
+-      ** special case 2 overflow if positive */
+-      assert( u-1==LARGEST_INT64 );
+-      return neg ? 0 : 2;
++      *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
++      if( c>0 ){
++        /* zNum is greater than 9223372036854775808 so it overflows */
++        return 2;
++      }else{
++        /* zNum is exactly 9223372036854775808.  Fits if negative.  The
++        ** special case 2 overflow if positive */
++        assert( u-1==LARGEST_INT64 );
++        return neg ? rc : 3;
++      }
+     }
+   }
+ }
+@@ -28841,8 +30689,9 @@
+ ** Returns:
+ **
+ **     0    Successful transformation.  Fits in a 64-bit signed integer.
+-**     1    Integer too large for a 64-bit signed integer or is malformed
+-**     2    Special case of 9223372036854775808
++**     1    Excess text after the integer value
++**     2    Integer too large for a 64-bit signed integer or is malformed
++**     3    Special case of 9223372036854775808
+ */
+ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
+ #ifndef SQLITE_OMIT_HEX_INTEGER
+@@ -28856,7 +30705,7 @@
+       u = u*16 + sqlite3HexToInt(z[k]);
+     }
+     memcpy(pOut, &u, 8);
+-    return (z[k]==0 && k-i<=16) ? 0 : 1;
++    return (z[k]==0 && k-i<=16) ? 0 : 2;
+   }else
+ #endif /* SQLITE_OMIT_HEX_INTEGER */
+   {
+@@ -29466,7 +31315,7 @@
+ ** overflow, leave *pA unchanged and return 1.
+ */
+ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
+-#if GCC_VERSION>=5004000
++#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+   return __builtin_add_overflow(*pA, iB, pA);
+ #else
+   i64 iA = *pA;
+@@ -29486,7 +31335,7 @@
+ #endif
+ }
+ SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
+-#if GCC_VERSION>=5004000
++#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+   return __builtin_sub_overflow(*pA, iB, pA);
+ #else
+   testcase( iB==SMALLEST_INT64+1 );
+@@ -29501,7 +31350,7 @@
+ #endif
+ }
+ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
+-#if GCC_VERSION>=5004000
++#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
+   return __builtin_mul_overflow(*pA, iB, pA);
+ #else
+   i64 iA = *pA;
+@@ -29603,8 +31452,14 @@
+     if( x<2 ) return 0;
+     while( x<8 ){  y -= 10; x <<= 1; }
+   }else{
++#if GCC_VERSION>=5004000
++    int i = 60 - __builtin_clzll(x);
++    y += i*10;
++    x >>= i;
++#else
+     while( x>255 ){ y += 40; x >>= 4; }  /*OPTIMIZATION-IF-TRUE*/
+     while( x>15 ){  y += 10; x >>= 1; }
++#endif
+   }
+   return a[x&7] + y - 10;
+ }
+@@ -29824,6 +31679,20 @@
+   }
+   return h;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++static unsigned int strHashN(const char *z, int n){
++  unsigned int h = 0;
++  int i;
++  for(i=0; i<n; i++){
++    /* Knuth multiplicative hashing.  (Sorting & Searching, p. 510).
++    ** 0x9e3779b1 is 2654435761 which is the closest prime number to
++    ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
++    h += sqlite3UpperToLower[z[i]];
++    h *= 0x9e3779b1;
++  }
++  return h;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ 
+ /* Link pNew element into the hash table pH.  If pEntry!=0 then also
+@@ -29935,7 +31804,41 @@
+   }
+   return &nullElement;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++static HashElem *findElementWithHashN(
++  const Hash *pH,     /* The pH to be searched */
++  const char *pKey,   /* The key we are searching for */
++  int nKey,           /* Number of key bytes to use */
++  unsigned int *pHash /* Write the hash value here */
++){
++  HashElem *elem;                /* Used to loop thru the element list */
++  int count;                     /* Number of elements left to test */
++  unsigned int h;                /* The computed hash */
++  static HashElem nullElement = { 0, 0, 0, 0 };
+ 
++  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
++    struct _ht *pEntry;
++    h = strHashN(pKey, nKey) % pH->htsize;
++    pEntry = &pH->ht[h];
++    elem = pEntry->chain;
++    count = pEntry->count;
++  }else{
++    h = 0;
++    elem = pH->first;
++    count = pH->count;
++  }
++  if( pHash ) *pHash = h;
++  while( count-- ){
++    assert( elem!=0 );
++    if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
++      return elem;
++    }
++    elem = elem->next;
++  }
++  return &nullElement;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
+ /* Remove a single entry from the hash table given a pointer to that
+ ** element and a hash on the element's key.
+ */
+@@ -29979,6 +31882,14 @@
+   assert( pKey!=0 );
+   return findElementWithHash(pH, pKey, 0)->data;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
++  assert( pH!=0 );
++  assert( pKey!=0 );
++  assert( nKey>=0 );
++  return findElementWithHashN(pH, pKey, nKey, 0)->data;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ /* Insert an element into the hash table pH.  The key is pKey
+ ** and the data is "data".
+@@ -30046,170 +31957,176 @@
+     /*   1 */ "AutoCommit"       OpHelp(""),
+     /*   2 */ "Transaction"      OpHelp(""),
+     /*   3 */ "SorterNext"       OpHelp(""),
+-    /*   4 */ "PrevIfOpen"       OpHelp(""),
+-    /*   5 */ "NextIfOpen"       OpHelp(""),
+-    /*   6 */ "Prev"             OpHelp(""),
+-    /*   7 */ "Next"             OpHelp(""),
+-    /*   8 */ "Checkpoint"       OpHelp(""),
+-    /*   9 */ "JournalMode"      OpHelp(""),
+-    /*  10 */ "Vacuum"           OpHelp(""),
+-    /*  11 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
+-    /*  12 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
+-    /*  13 */ "Goto"             OpHelp(""),
+-    /*  14 */ "Gosub"            OpHelp(""),
+-    /*  15 */ "InitCoroutine"    OpHelp(""),
+-    /*  16 */ "Yield"            OpHelp(""),
+-    /*  17 */ "MustBeInt"        OpHelp(""),
+-    /*  18 */ "Jump"             OpHelp(""),
++    /*   4 */ "Prev"             OpHelp(""),
++    /*   5 */ "Next"             OpHelp(""),
++    /*   6 */ "Checkpoint"       OpHelp(""),
++    /*   7 */ "JournalMode"      OpHelp(""),
++    /*   8 */ "Vacuum"           OpHelp(""),
++    /*   9 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
++    /*  10 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
++    /*  11 */ "Goto"             OpHelp(""),
++    /*  12 */ "Gosub"            OpHelp(""),
++    /*  13 */ "InitCoroutine"    OpHelp(""),
++    /*  14 */ "Yield"            OpHelp(""),
++    /*  15 */ "MustBeInt"        OpHelp(""),
++    /*  16 */ "Jump"             OpHelp(""),
++    /*  17 */ "Once"             OpHelp(""),
++    /*  18 */ "If"               OpHelp(""),
+     /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
+-    /*  20 */ "Once"             OpHelp(""),
+-    /*  21 */ "If"               OpHelp(""),
+-    /*  22 */ "IfNot"            OpHelp(""),
+-    /*  23 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
+-    /*  24 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
+-    /*  25 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
+-    /*  26 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
+-    /*  27 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
+-    /*  28 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
+-    /*  29 */ "NotFound"         OpHelp("key=r[P3@P4]"),
+-    /*  30 */ "Found"            OpHelp("key=r[P3@P4]"),
+-    /*  31 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
+-    /*  32 */ "NotExists"        OpHelp("intkey=r[P3]"),
+-    /*  33 */ "Last"             OpHelp(""),
+-    /*  34 */ "IfSmaller"        OpHelp(""),
+-    /*  35 */ "SorterSort"       OpHelp(""),
+-    /*  36 */ "Sort"             OpHelp(""),
+-    /*  37 */ "Rewind"           OpHelp(""),
+-    /*  38 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
+-    /*  39 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
+-    /*  40 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
+-    /*  41 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
+-    /*  42 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
+-    /*  43 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+-    /*  44 */ "Program"          OpHelp(""),
+-    /*  45 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+-    /*  46 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+-    /*  47 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+-    /*  48 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+-    /*  49 */ "IncrVacuum"       OpHelp(""),
+-    /*  50 */ "VNext"            OpHelp(""),
+-    /*  51 */ "Init"             OpHelp("Start at P2"),
+-    /*  52 */ "Return"           OpHelp(""),
+-    /*  53 */ "EndCoroutine"     OpHelp(""),
+-    /*  54 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
+-    /*  55 */ "Halt"             OpHelp(""),
+-    /*  56 */ "Integer"          OpHelp("r[P2]=P1"),
+-    /*  57 */ "Int64"            OpHelp("r[P2]=P4"),
+-    /*  58 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
+-    /*  59 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+-    /*  60 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+-    /*  61 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+-    /*  62 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+-    /*  63 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+-    /*  64 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+-    /*  65 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+-    /*  66 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
+-    /*  67 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+-    /*  68 */ "CollSeq"          OpHelp(""),
+-    /*  69 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+-    /*  70 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
+-    /*  71 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
+-    /*  72 */ "RealAffinity"     OpHelp(""),
+-    /*  73 */ "Cast"             OpHelp("affinity(r[P1])"),
+-    /*  74 */ "Permutation"      OpHelp(""),
+-    /*  75 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
+-    /*  76 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
+-    /*  77 */ "Ne"               OpHelp("IF r[P3]!=r[P1]"),
+-    /*  78 */ "Eq"               OpHelp("IF r[P3]==r[P1]"),
+-    /*  79 */ "Gt"               OpHelp("IF r[P3]>r[P1]"),
+-    /*  80 */ "Le"               OpHelp("IF r[P3]<=r[P1]"),
+-    /*  81 */ "Lt"               OpHelp("IF r[P3]<r[P1]"),
+-    /*  82 */ "Ge"               OpHelp("IF r[P3]>=r[P1]"),
+-    /*  83 */ "ElseNotEq"        OpHelp(""),
+-    /*  84 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
+-    /*  85 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
+-    /*  86 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
+-    /*  87 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
+-    /*  88 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
+-    /*  89 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
+-    /*  90 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
+-    /*  91 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
+-    /*  92 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
+-    /*  93 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
+-    /*  94 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
+-    /*  95 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
+-    /*  96 */ "Column"           OpHelp("r[P3]=PX"),
+-    /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
+-    /*  98 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+-    /*  99 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+-    /* 100 */ "Count"            OpHelp("r[P2]=count()"),
+-    /* 101 */ "ReadCookie"       OpHelp(""),
+-    /* 102 */ "SetCookie"        OpHelp(""),
+-    /* 103 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+-    /* 104 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+-    /* 105 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+-    /* 106 */ "OpenDup"          OpHelp(""),
+-    /* 107 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
+-    /* 108 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+-    /* 109 */ "SorterOpen"       OpHelp(""),
+-    /* 110 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+-    /* 111 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+-    /* 112 */ "Close"            OpHelp(""),
+-    /* 113 */ "ColumnsUsed"      OpHelp(""),
+-    /* 114 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+-    /* 115 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+-    /* 116 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
+-    /* 117 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
+-    /* 118 */ "Delete"           OpHelp(""),
+-    /* 119 */ "ResetCount"       OpHelp(""),
+-    /* 120 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+-    /* 121 */ "SorterData"       OpHelp("r[P2]=data"),
+-    /* 122 */ "RowData"          OpHelp("r[P2]=data"),
+-    /* 123 */ "Rowid"            OpHelp("r[P2]=rowid"),
+-    /* 124 */ "NullRow"          OpHelp(""),
+-    /* 125 */ "SorterInsert"     OpHelp("key=r[P2]"),
+-    /* 126 */ "IdxInsert"        OpHelp("key=r[P2]"),
+-    /* 127 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+-    /* 128 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
+-    /* 129 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+-    /* 130 */ "Destroy"          OpHelp(""),
+-    /* 131 */ "Clear"            OpHelp(""),
+-    /* 132 */ "Real"             OpHelp("r[P2]=P4"),
+-    /* 133 */ "ResetSorter"      OpHelp(""),
+-    /* 134 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
+-    /* 135 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
+-    /* 136 */ "SqlExec"          OpHelp(""),
+-    /* 137 */ "ParseSchema"      OpHelp(""),
+-    /* 138 */ "LoadAnalysis"     OpHelp(""),
+-    /* 139 */ "DropTable"        OpHelp(""),
+-    /* 140 */ "DropIndex"        OpHelp(""),
+-    /* 141 */ "DropTrigger"      OpHelp(""),
+-    /* 142 */ "IntegrityCk"      OpHelp(""),
+-    /* 143 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+-    /* 144 */ "Param"            OpHelp(""),
+-    /* 145 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+-    /* 146 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+-    /* 147 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+-    /* 148 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
+-    /* 149 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+-    /* 150 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+-    /* 151 */ "Expire"           OpHelp(""),
+-    /* 152 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+-    /* 153 */ "VBegin"           OpHelp(""),
+-    /* 154 */ "VCreate"          OpHelp(""),
+-    /* 155 */ "VDestroy"         OpHelp(""),
+-    /* 156 */ "VOpen"            OpHelp(""),
+-    /* 157 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+-    /* 158 */ "VRename"          OpHelp(""),
+-    /* 159 */ "Pagecount"        OpHelp(""),
+-    /* 160 */ "MaxPgcnt"         OpHelp(""),
+-    /* 161 */ "PureFunc0"        OpHelp(""),
+-    /* 162 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
+-    /* 163 */ "PureFunc"         OpHelp(""),
+-    /* 164 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
+-    /* 165 */ "CursorHint"       OpHelp(""),
+-    /* 166 */ "Noop"             OpHelp(""),
+-    /* 167 */ "Explain"          OpHelp(""),
++    /*  20 */ "IfNot"            OpHelp(""),
++    /*  21 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
++    /*  22 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
++    /*  23 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
++    /*  24 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
++    /*  25 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
++    /*  26 */ "IfNoHope"         OpHelp("key=r[P3@P4]"),
++    /*  27 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
++    /*  28 */ "NotFound"         OpHelp("key=r[P3@P4]"),
++    /*  29 */ "Found"            OpHelp("key=r[P3@P4]"),
++    /*  30 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
++    /*  31 */ "NotExists"        OpHelp("intkey=r[P3]"),
++    /*  32 */ "Last"             OpHelp(""),
++    /*  33 */ "IfSmaller"        OpHelp(""),
++    /*  34 */ "SorterSort"       OpHelp(""),
++    /*  35 */ "Sort"             OpHelp(""),
++    /*  36 */ "Rewind"           OpHelp(""),
++    /*  37 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
++    /*  38 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
++    /*  39 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
++    /*  40 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
++    /*  41 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
++    /*  42 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
++    /*  43 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
++    /*  44 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
++    /*  45 */ "Program"          OpHelp(""),
++    /*  46 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
++    /*  47 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
++    /*  48 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
++    /*  49 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
++    /*  50 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
++    /*  51 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
++    /*  52 */ "Ne"               OpHelp("IF r[P3]!=r[P1]"),
++    /*  53 */ "Eq"               OpHelp("IF r[P3]==r[P1]"),
++    /*  54 */ "Gt"               OpHelp("IF r[P3]>r[P1]"),
++    /*  55 */ "Le"               OpHelp("IF r[P3]<=r[P1]"),
++    /*  56 */ "Lt"               OpHelp("IF r[P3]<r[P1]"),
++    /*  57 */ "Ge"               OpHelp("IF r[P3]>=r[P1]"),
++    /*  58 */ "ElseNotEq"        OpHelp(""),
++    /*  59 */ "IncrVacuum"       OpHelp(""),
++    /*  60 */ "VNext"            OpHelp(""),
++    /*  61 */ "Init"             OpHelp("Start at P2"),
++    /*  62 */ "PureFunc0"        OpHelp(""),
++    /*  63 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
++    /*  64 */ "PureFunc"         OpHelp(""),
++    /*  65 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
++    /*  66 */ "Return"           OpHelp(""),
++    /*  67 */ "EndCoroutine"     OpHelp(""),
++    /*  68 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
++    /*  69 */ "Halt"             OpHelp(""),
++    /*  70 */ "Integer"          OpHelp("r[P2]=P1"),
++    /*  71 */ "Int64"            OpHelp("r[P2]=P4"),
++    /*  72 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
++    /*  73 */ "Null"             OpHelp("r[P2..P3]=NULL"),
++    /*  74 */ "SoftNull"         OpHelp("r[P1]=NULL"),
++    /*  75 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
++    /*  76 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
++    /*  77 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
++    /*  78 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
++    /*  79 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
++    /*  80 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
++    /*  81 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
++    /*  82 */ "CollSeq"          OpHelp(""),
++    /*  83 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
++    /*  84 */ "RealAffinity"     OpHelp(""),
++    /*  85 */ "Cast"             OpHelp("affinity(r[P1])"),
++    /*  86 */ "Permutation"      OpHelp(""),
++    /*  87 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
++    /*  88 */ "IsTrue"           OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
++    /*  89 */ "Offset"           OpHelp("r[P3] = sqlite_offset(P1)"),
++    /*  90 */ "Column"           OpHelp("r[P3]=PX"),
++    /*  91 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
++    /*  92 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
++    /*  93 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
++    /*  94 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
++    /*  95 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
++    /*  96 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
++    /*  97 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
++    /*  98 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
++    /*  99 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
++    /* 100 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
++    /* 101 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
++    /* 102 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
++    /* 103 */ "BitNot"           OpHelp("r[P2]= ~r[P1]"),
++    /* 104 */ "Count"            OpHelp("r[P2]=count()"),
++    /* 105 */ "ReadCookie"       OpHelp(""),
++    /* 106 */ "String8"          OpHelp("r[P2]='P4'"),
++    /* 107 */ "SetCookie"        OpHelp(""),
++    /* 108 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
++    /* 109 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
++    /* 110 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
++    /* 111 */ "OpenDup"          OpHelp(""),
++    /* 112 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
++    /* 113 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
++    /* 114 */ "SorterOpen"       OpHelp(""),
++    /* 115 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
++    /* 116 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
++    /* 117 */ "Close"            OpHelp(""),
++    /* 118 */ "ColumnsUsed"      OpHelp(""),
++    /* 119 */ "SeekHit"          OpHelp("seekHit=P2"),
++    /* 120 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
++    /* 121 */ "NewRowid"         OpHelp("r[P2]=rowid"),
++    /* 122 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
++    /* 123 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
++    /* 124 */ "Delete"           OpHelp(""),
++    /* 125 */ "ResetCount"       OpHelp(""),
++    /* 126 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
++    /* 127 */ "SorterData"       OpHelp("r[P2]=data"),
++    /* 128 */ "RowData"          OpHelp("r[P2]=data"),
++    /* 129 */ "Rowid"            OpHelp("r[P2]=rowid"),
++    /* 130 */ "NullRow"          OpHelp(""),
++    /* 131 */ "SeekEnd"          OpHelp(""),
++    /* 132 */ "SorterInsert"     OpHelp("key=r[P2]"),
++    /* 133 */ "IdxInsert"        OpHelp("key=r[P2]"),
++    /* 134 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
++    /* 135 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
++    /* 136 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
++    /* 137 */ "Destroy"          OpHelp(""),
++    /* 138 */ "Clear"            OpHelp(""),
++    /* 139 */ "ResetSorter"      OpHelp(""),
++    /* 140 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
++    /* 141 */ "Real"             OpHelp("r[P2]=P4"),
++    /* 142 */ "SqlExec"          OpHelp(""),
++    /* 143 */ "ParseSchema"      OpHelp(""),
++    /* 144 */ "LoadAnalysis"     OpHelp(""),
++    /* 145 */ "DropTable"        OpHelp(""),
++    /* 146 */ "DropIndex"        OpHelp(""),
++    /* 147 */ "DropTrigger"      OpHelp(""),
++    /* 148 */ "IntegrityCk"      OpHelp(""),
++    /* 149 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
++    /* 150 */ "Param"            OpHelp(""),
++    /* 151 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
++    /* 152 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
++    /* 153 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
++    /* 154 */ "AggInverse"       OpHelp("accum=r[P3] inverse(r[P2@P5])"),
++    /* 155 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 156 */ "AggStep1"         OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 157 */ "AggValue"         OpHelp("r[P3]=value N=P2"),
++    /* 158 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
++    /* 159 */ "Expire"           OpHelp(""),
++    /* 160 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
++    /* 161 */ "VBegin"           OpHelp(""),
++    /* 162 */ "VCreate"          OpHelp(""),
++    /* 163 */ "VDestroy"         OpHelp(""),
++    /* 164 */ "VOpen"            OpHelp(""),
++    /* 165 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
++    /* 166 */ "VRename"          OpHelp(""),
++    /* 167 */ "Pagecount"        OpHelp(""),
++    /* 168 */ "MaxPgcnt"         OpHelp(""),
++    /* 169 */ "Trace"            OpHelp(""),
++    /* 170 */ "CursorHint"       OpHelp(""),
++    /* 171 */ "Noop"             OpHelp(""),
++    /* 172 */ "Explain"          OpHelp(""),
++    /* 173 */ "Abortable"        OpHelp(""),
+   };
+   return azName[i];
+ }
+@@ -30309,6 +32226,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
++#include <sys/ioctl.h>
+ #include <unistd.h>
+ /* #include <time.h> */
+ #include <sys/time.h>
+@@ -30318,7 +32236,7 @@
+ #endif
+ 
+ #if SQLITE_ENABLE_LOCKING_STYLE
+-# include <sys/ioctl.h>
++/* # include <sys/ioctl.h> */
+ # include <sys/file.h>
+ # include <sys/param.h>
+ #endif /* SQLITE_ENABLE_LOCKING_STYLE */
+@@ -30354,12 +32272,10 @@
+ #define SQLITE_FSFLAGS_IS_MSDOS     0x1
+ 
+ /*
+-** If we are to be thread-safe, include the pthreads header and define
+-** the SQLITE_UNIX_THREADS macro.
++** If we are to be thread-safe, include the pthreads header.
+ */
+ #if SQLITE_THREADSAFE
+ /* # include <pthread.h> */
+-# define SQLITE_UNIX_THREADS 1
+ #endif
+ 
+ /*
+@@ -30428,7 +32344,7 @@
+   unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
+   int lastErrno;                      /* The unix errno from last I/O error */
+   void *lockingContext;               /* Locking style specific state */
+-  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
++  UnixUnusedFd *pPreallocatedUnused;  /* Pre-allocated UnixUnusedFd */
+   const char *zPath;                  /* Name of the file */
+   unixShm *pShm;                      /* Shared memory segment information */
+   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
+@@ -30439,10 +32355,8 @@
+   sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
+   void *pMapRegion;                   /* Memory mapped region */
+ #endif
+-#ifdef __QNXNTO__
+   int sectorSize;                     /* Device sector size */
+   int deviceCharacteristics;          /* Precomputed device characteristics */
+-#endif
+ #if SQLITE_ENABLE_LOCKING_STYLE
+   int openFlags;                      /* The flags specified at open() */
+ #endif
+@@ -30449,6 +32363,9 @@
+ #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
+   unsigned fsFlags;                   /* cached details from statfs() */
+ #endif
++#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
++  unsigned iBusyTimeout;              /* Wait this many millisec on locks */
++#endif
+ #if OS_VXWORKS
+   struct vxworksFileId *pId;          /* Unique file ID */
+ #endif
+@@ -30745,7 +32662,21 @@
+ # define lseek lseek64
+ #endif
+ 
++#ifdef __linux__
+ /*
++** Linux-specific IOCTL magic numbers used for controlling F2FS
++*/
++#define F2FS_IOCTL_MAGIC        0xf5
++#define F2FS_IOC_START_ATOMIC_WRITE     _IO(F2FS_IOCTL_MAGIC, 1)
++#define F2FS_IOC_COMMIT_ATOMIC_WRITE    _IO(F2FS_IOCTL_MAGIC, 2)
++#define F2FS_IOC_START_VOLATILE_WRITE   _IO(F2FS_IOCTL_MAGIC, 3)
++#define F2FS_IOC_ABORT_VOLATILE_WRITE   _IO(F2FS_IOCTL_MAGIC, 5)
++#define F2FS_IOC_GET_FEATURES           _IOR(F2FS_IOCTL_MAGIC, 12, u32)
++#define F2FS_FEATURE_ATOMIC_WRITE 0x0004
++#endif /* __linux__ */
++
++
++/*
+ ** Different Unix systems declare open() in different ways.  Same use
+ ** open(const char*,int,mode_t).  Others use open(const char*,int,...).
+ ** The difference is important when using a pointer to the function.
+@@ -30872,7 +32803,11 @@
+ #endif
+ #define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
+ 
++#if defined(HAVE_FCHOWN)
+   { "geteuid",      (sqlite3_syscall_ptr)geteuid,         0 },
++#else
++  { "geteuid",      (sqlite3_syscall_ptr)0,               0 },
++#endif
+ #define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)
+ 
+ #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+@@ -30887,7 +32822,7 @@
+ #else
+   { "munmap",       (sqlite3_syscall_ptr)0,               0 },
+ #endif
+-#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
++#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent)
+ 
+ #if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
+   { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
+@@ -30917,6 +32852,17 @@
+ #endif
+ #define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+ 
++#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++# ifdef __ANDROID__
++  { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
++# else
++  { "ioctl",         (sqlite3_syscall_ptr)ioctl,          0 },
++# endif
++#else
++  { "ioctl",         (sqlite3_syscall_ptr)0,              0 },
++#endif
++#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
++
+ }; /* End of the overrideable system calls */
+ 
+ 
+@@ -31092,16 +33038,30 @@
+ **   unixEnterMutex()
+ **     assert( unixMutexHeld() );
+ **   unixEnterLeave()
++**
++** To prevent deadlock, the global unixBigLock must must be acquired
++** before the unixInodeInfo.pLockMutex mutex, if both are held.  It is
++** OK to get the pLockMutex without holding unixBigLock first, but if
++** that happens, the unixBigLock mutex must not be acquired until after
++** pLockMutex is released.
++**
++**      OK:     enter(unixBigLock),  enter(pLockInfo)
++**      OK:     enter(unixBigLock)
++**      OK:     enter(pLockInfo)
++**   ERROR:     enter(pLockInfo), enter(unixBigLock)
+ */
++static sqlite3_mutex *unixBigLock = 0;
+ static void unixEnterMutex(void){
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  assert( sqlite3_mutex_notheld(unixBigLock) );  /* Not a recursive mutex */
++  sqlite3_mutex_enter(unixBigLock);
+ }
+ static void unixLeaveMutex(void){
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  assert( sqlite3_mutex_held(unixBigLock) );
++  sqlite3_mutex_leave(unixBigLock);
+ }
+ #ifdef SQLITE_DEBUG
+ static int unixMutexHeld(void) {
+-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  return sqlite3_mutex_held(unixBigLock);
+ }
+ #endif
+ 
+@@ -31491,22 +33451,39 @@
+ 
+ /*
+ ** An instance of the following structure is allocated for each open
+-** inode.  Or, on LinuxThreads, there is one of these structures for
+-** each inode opened by each thread.
++** inode.
+ **
+ ** A single inode can have multiple file descriptors, so each unixFile
+ ** structure contains a pointer to an instance of this object and this
+ ** object keeps a count of the number of unixFile pointing to it.
++**
++** Mutex rules:
++**
++**  (1) Only the pLockMutex mutex must be held in order to read or write
++**      any of the locking fields:
++**          nShared, nLock, eFileLock, bProcessLock, pUnused
++**
++**  (2) When nRef>0, then the following fields are unchanging and can
++**      be read (but not written) without holding any mutex:
++**          fileId, pLockMutex
++**
++**  (3) With the exceptions above, all the fields may only be read
++**      or written while holding the global unixBigLock mutex.
++**
++** Deadlock prevention:  The global unixBigLock mutex may not
++** be acquired while holding the pLockMutex mutex.  If both unixBigLock
++** and pLockMutex are needed, then unixBigLock must be acquired first.
+ */
+ struct unixInodeInfo {
+   struct unixFileId fileId;       /* The lookup key */
+-  int nShared;                    /* Number of SHARED locks held */
+-  unsigned char eFileLock;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+-  unsigned char bProcessLock;     /* An exclusive process lock is held */
++  sqlite3_mutex *pLockMutex;      /* Hold this mutex for... */
++  int nShared;                      /* Number of SHARED locks held */
++  int nLock;                        /* Number of outstanding file locks */
++  unsigned char eFileLock;          /* One of SHARED_LOCK, RESERVED_LOCK etc. */
++  unsigned char bProcessLock;       /* An exclusive process lock is held */
++  UnixUnusedFd *pUnused;            /* Unused file descriptors to close */
+   int nRef;                       /* Number of pointers to this structure */
+   unixShmNode *pShmNode;          /* Shared memory associated with this inode */
+-  int nLock;                      /* Number of outstanding file locks */
+-  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
+   unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
+   unixInodeInfo *pPrev;           /*    .... doubly linked */
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -31520,10 +33497,28 @@
+ 
+ /*
+ ** A lists of all unixInodeInfo objects.
++**
++** Must hold unixBigLock in order to read or write this variable.
+ */
+-static unixInodeInfo *inodeList = 0;
++static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
++** This routine is used only within assert() to help verify correct mutex
++** usage.
++*/
++int unixFileMutexHeld(unixFile *pFile){
++  assert( pFile->pInode );
++  return sqlite3_mutex_held(pFile->pInode->pLockMutex);
++}
++int unixFileMutexNotheld(unixFile *pFile){
++  assert( pFile->pInode );
++  return sqlite3_mutex_notheld(pFile->pInode->pLockMutex);
++}
++#endif
++
++/*
+ **
+ ** This function - unixLogErrorAtLine(), is only ever called via the macro
+ ** unixLogError().
+@@ -31627,6 +33622,7 @@
+   unixInodeInfo *pInode = pFile->pInode;
+   UnixUnusedFd *p;
+   UnixUnusedFd *pNext;
++  assert( unixFileMutexHeld(pFile) );
+   for(p=pInode->pUnused; p; p=pNext){
+     pNext = p->pNext;
+     robust_close(pFile, p->fd, __LINE__);
+@@ -31638,17 +33634,20 @@
+ /*
+ ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
+ **
+-** The mutex entered using the unixEnterMutex() function must be held
+-** when this function is called.
++** The global mutex must be held when this routine is called, but the mutex
++** on the inode being deleted must NOT be held.
+ */
+ static void releaseInodeInfo(unixFile *pFile){
+   unixInodeInfo *pInode = pFile->pInode;
+   assert( unixMutexHeld() );
++  assert( unixFileMutexNotheld(pFile) );
+   if( ALWAYS(pInode) ){
+     pInode->nRef--;
+     if( pInode->nRef==0 ){
+       assert( pInode->pShmNode==0 );
++      sqlite3_mutex_enter(pInode->pLockMutex);
+       closePendingFds(pFile);
++      sqlite3_mutex_leave(pInode->pLockMutex);
+       if( pInode->pPrev ){
+         assert( pInode->pPrev->pNext==pInode );
+         pInode->pPrev->pNext = pInode->pNext;
+@@ -31660,6 +33659,7 @@
+         assert( pInode->pNext->pPrev==pInode );
+         pInode->pNext->pPrev = pInode->pPrev;
+       }
++      sqlite3_mutex_free(pInode->pLockMutex);
+       sqlite3_free(pInode);
+     }
+   }
+@@ -31670,8 +33670,7 @@
+ ** describes that file descriptor.  Create a new one if necessary.  The
+ ** return value might be uninitialized if an error occurs.
+ **
+-** The mutex entered using the unixEnterMutex() function must be held
+-** when this function is called.
++** The global mutex must held when calling this routine.
+ **
+ ** Return an appropriate error code.
+ */
+@@ -31732,6 +33731,7 @@
+ #else
+   fileId.ino = (u64)statbuf.st_ino;
+ #endif
++  assert( unixMutexHeld() );
+   pInode = inodeList;
+   while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
+     pInode = pInode->pNext;
+@@ -31743,7 +33743,15 @@
+     }
+     memset(pInode, 0, sizeof(*pInode));
+     memcpy(&pInode->fileId, &fileId, sizeof(fileId));
++    if( sqlite3GlobalConfig.bCoreMutex ){
++      pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pInode->pLockMutex==0 ){
++        sqlite3_free(pInode);
++        return SQLITE_NOMEM_BKPT;
++      }
++    }
+     pInode->nRef = 1;
++    assert( unixMutexHeld() );
+     pInode->pNext = inodeList;
+     pInode->pPrev = 0;
+     if( inodeList ) inodeList->pPrev = pInode;
+@@ -31821,7 +33829,7 @@
+ 
+   assert( pFile );
+   assert( pFile->eFileLock<=SHARED_LOCK );
+-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
++  sqlite3_mutex_enter(pFile->pInode->pLockMutex);
+ 
+   /* Check if a thread in this process holds such a lock */
+   if( pFile->pInode->eFileLock>SHARED_LOCK ){
+@@ -31846,7 +33854,7 @@
+   }
+ #endif
+   
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pFile->pInode->pLockMutex);
+   OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
+ 
+   *pResOut = reserved;
+@@ -31854,6 +33862,43 @@
+ }
+ 
+ /*
++** Set a posix-advisory-lock.
++**
++** There are two versions of this routine.  If compiled with
++** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
++** which is a pointer to a unixFile.  If the unixFile->iBusyTimeout
++** value is set, then it is the number of milliseconds to wait before
++** failing the lock.  The iBusyTimeout value is always reset back to
++** zero on each call.
++**
++** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking
++** attempt to set the lock.
++*/
++#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
++# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
++#else
++static int osSetPosixAdvisoryLock(
++  int h,                /* The file descriptor on which to take the lock */
++  struct flock *pLock,  /* The description of the lock */
++  unixFile *pFile       /* Structure holding timeout value */
++){
++  int rc = osFcntl(h,F_SETLK,pLock);
++  while( rc<0 && pFile->iBusyTimeout>0 ){
++    /* On systems that support some kind of blocking file lock with a timeout,
++    ** make appropriate changes here to invoke that blocking file lock.  On
++    ** generic posix, however, there is no such API.  So we simply try the
++    ** lock once every millisecond until either the timeout expires, or until
++    ** the lock is obtained. */
++    usleep(1000);
++    rc = osFcntl(h,F_SETLK,pLock);
++    pFile->iBusyTimeout--;
++  }
++  return rc;
++}
++#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
++
++
++/*
+ ** Attempt to set a system-lock on the file pFile.  The lock is 
+ ** described by pLock.
+ **
+@@ -31875,8 +33920,8 @@
+ static int unixFileLock(unixFile *pFile, struct flock *pLock){
+   int rc;
+   unixInodeInfo *pInode = pFile->pInode;
+-  assert( unixMutexHeld() );
+   assert( pInode!=0 );
++  assert( sqlite3_mutex_held(pInode->pLockMutex) );
+   if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
+     if( pInode->bProcessLock==0 ){
+       struct flock lock;
+@@ -31885,7 +33930,7 @@
+       lock.l_start = SHARED_FIRST;
+       lock.l_len = SHARED_SIZE;
+       lock.l_type = F_WRLCK;
+-      rc = osFcntl(pFile->h, F_SETLK, &lock);
++      rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
+       if( rc<0 ) return rc;
+       pInode->bProcessLock = 1;
+       pInode->nLock++;
+@@ -31893,7 +33938,7 @@
+       rc = 0;
+     }
+   }else{
+-    rc = osFcntl(pFile->h, F_SETLK, pLock);
++    rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
+   }
+   return rc;
+ }
+@@ -31995,8 +34040,8 @@
+ 
+   /* This mutex is needed because pFile->pInode is shared across threads
+   */
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+ 
+   /* If some thread using this PID has a lock via a different unixFile*
+   ** handle that precludes the requested lock, return BUSY.
+@@ -32139,7 +34184,7 @@
+   }
+ 
+ end_lock:
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   OSTRACE(("LOCK    %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), 
+       rc==SQLITE_OK ? "ok" : "failed"));
+   return rc;
+@@ -32151,11 +34196,12 @@
+ */
+ static void setPendingFd(unixFile *pFile){
+   unixInodeInfo *pInode = pFile->pInode;
+-  UnixUnusedFd *p = pFile->pUnused;
++  UnixUnusedFd *p = pFile->pPreallocatedUnused;
++  assert( unixFileMutexHeld(pFile) );
+   p->pNext = pInode->pUnused;
+   pInode->pUnused = p;
+   pFile->h = -1;
+-  pFile->pUnused = 0;
++  pFile->pPreallocatedUnused = 0;
+ }
+ 
+ /*
+@@ -32186,8 +34232,8 @@
+   if( pFile->eFileLock<=eFileLock ){
+     return SQLITE_OK;
+   }
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+   assert( pInode->nShared!=0 );
+   if( pFile->eFileLock>SHARED_LOCK ){
+     assert( pInode->eFileLock==pFile->eFileLock );
+@@ -32313,14 +34359,14 @@
+     */
+     pInode->nLock--;
+     assert( pInode->nLock>=0 );
+-    if( pInode->nLock==0 ){
+-      closePendingFds(pFile);
+-    }
++    if( pInode->nLock==0 ) closePendingFds(pFile);
+   }
+ 
+ end_unlock:
+-  unixLeaveMutex();
+-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
++  sqlite3_mutex_leave(pInode->pLockMutex);
++  if( rc==SQLITE_OK ){
++    pFile->eFileLock = eFileLock;
++  }
+   return rc;
+ }
+ 
+@@ -32380,7 +34426,7 @@
+ #endif
+   OSTRACE(("CLOSE   %-3d\n", pFile->h));
+   OpenCounter(-1);
+-  sqlite3_free(pFile->pUnused);
++  sqlite3_free(pFile->pPreallocatedUnused);
+   memset(pFile, 0, sizeof(unixFile));
+   return SQLITE_OK;
+ }
+@@ -32391,8 +34437,12 @@
+ static int unixClose(sqlite3_file *id){
+   int rc = SQLITE_OK;
+   unixFile *pFile = (unixFile *)id;
++  unixInodeInfo *pInode = pFile->pInode;
++
++  assert( pInode!=0 );
+   verifyDbFile(pFile);
+   unixUnlock(id, NO_LOCK);
++  assert( unixFileMutexNotheld(pFile) );
+   unixEnterMutex();
+ 
+   /* unixFile.pInode is always valid here. Otherwise, a different close
+@@ -32399,7 +34449,8 @@
+   ** routine (e.g. nolockClose()) would be called instead.
+   */
+   assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
+-  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
++  sqlite3_mutex_enter(pInode->pLockMutex);
++  if( pInode->nLock ){
+     /* If there are outstanding locks, do not actually close the file just
+     ** yet because that would clear those locks.  Instead, add the file
+     ** descriptor to pInode->pUnused list.  It will be automatically closed 
+@@ -32407,6 +34458,7 @@
+     */
+     setPendingFd(pFile);
+   }
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   releaseInodeInfo(pFile);
+   rc = closeUnixFile(id);
+   unixLeaveMutex();
+@@ -32717,7 +34769,7 @@
+   OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
+ 
+ #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+-  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
++  if( (rc & 0xff) == SQLITE_IOERR ){
+     rc = SQLITE_OK;
+     reserved=1;
+   }
+@@ -32784,7 +34836,7 @@
+   OSTRACE(("LOCK    %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), 
+            rc==SQLITE_OK ? "ok" : "failed"));
+ #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+-  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
++  if( (rc & 0xff) == SQLITE_IOERR ){
+     rc = SQLITE_BUSY;
+   }
+ #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
+@@ -33004,6 +35056,7 @@
+     unixFile *pFile = (unixFile*)id;
+     semXUnlock(id, NO_LOCK);
+     assert( pFile );
++    assert( unixFileMutexNotheld(pFile) );
+     unixEnterMutex();
+     releaseInodeInfo(pFile);
+     unixLeaveMutex();
+@@ -33118,8 +35171,7 @@
+     *pResOut = 1;
+     return SQLITE_OK;
+   }
+-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+-  
++  sqlite3_mutex_enter(pFile->pInode->pLockMutex);
+   /* Check if a thread in this process holds such a lock */
+   if( pFile->pInode->eFileLock>SHARED_LOCK ){
+     reserved = 1;
+@@ -33143,7 +35195,7 @@
+     }
+   }
+   
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pFile->pInode->pLockMutex);
+   OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
+   
+   *pResOut = reserved;
+@@ -33206,8 +35258,8 @@
+   
+   /* This mutex is needed because pFile->pInode is shared across threads
+   */
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+ 
+   /* If some thread using this PID has a lock via a different unixFile*
+   ** handle that precludes the requested lock, return BUSY.
+@@ -33321,7 +35373,7 @@
+           /* Can't reestablish the shared lock.  Sqlite can't deal, this is
+           ** a critical I/O error
+           */
+-          rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : 
++          rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : 
+                SQLITE_IOERR_LOCK;
+           goto afp_end_lock;
+         } 
+@@ -33343,7 +35395,7 @@
+   }
+   
+ afp_end_lock:
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   OSTRACE(("LOCK    %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), 
+          rc==SQLITE_OK ? "ok" : "failed"));
+   return rc;
+@@ -33375,8 +35427,8 @@
+   if( pFile->eFileLock<=eFileLock ){
+     return SQLITE_OK;
+   }
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+   assert( pInode->nShared!=0 );
+   if( pFile->eFileLock>SHARED_LOCK ){
+     assert( pInode->eFileLock==pFile->eFileLock );
+@@ -33445,14 +35497,14 @@
+     if( rc==SQLITE_OK ){
+       pInode->nLock--;
+       assert( pInode->nLock>=0 );
+-      if( pInode->nLock==0 ){
+-        closePendingFds(pFile);
+-      }
++      if( pInode->nLock==0 ) closePendingFds(pFile);
+     }
+   }
+   
+-  unixLeaveMutex();
+-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
++  sqlite3_mutex_leave(pInode->pLockMutex);
++  if( rc==SQLITE_OK ){
++    pFile->eFileLock = eFileLock;
++  }
+   return rc;
+ }
+ 
+@@ -33464,14 +35516,20 @@
+   unixFile *pFile = (unixFile*)id;
+   assert( id!=0 );
+   afpUnlock(id, NO_LOCK);
++  assert( unixFileMutexNotheld(pFile) );
+   unixEnterMutex();
+-  if( pFile->pInode && pFile->pInode->nLock ){
+-    /* If there are outstanding locks, do not actually close the file just
+-    ** yet because that would clear those locks.  Instead, add the file
+-    ** descriptor to pInode->aPending.  It will be automatically closed when
+-    ** the last lock is cleared.
+-    */
+-    setPendingFd(pFile);
++  if( pFile->pInode ){
++    unixInodeInfo *pInode = pFile->pInode;
++    sqlite3_mutex_enter(pInode->pLockMutex);
++    if( pInode->nLock ){
++      /* If there are outstanding locks, do not actually close the file just
++      ** yet because that would clear those locks.  Instead, add the file
++      ** descriptor to pInode->aPending.  It will be automatically closed when
++      ** the last lock is cleared.
++      */
++      setPendingFd(pFile);
++    }
++    sqlite3_mutex_leave(pInode->pLockMutex);
+   }
+   releaseInodeInfo(pFile);
+   sqlite3_free(pFile->lockingContext);
+@@ -33601,7 +35659,7 @@
+   /* If this is a database file (not a journal, master-journal or temp
+   ** file), the bytes in the locking range should never be read or written. */
+ #if 0
+-  assert( pFile->pUnused==0
++  assert( pFile->pPreallocatedUnused==0
+        || offset>=PENDING_BYTE+512
+        || offset+amt<=PENDING_BYTE 
+   );
+@@ -33714,7 +35772,7 @@
+   /* If this is a database file (not a journal, master-journal or temp
+   ** file), the bytes in the locking range should never be read or written. */
+ #if 0
+-  assert( pFile->pUnused==0
++  assert( pFile->pPreallocatedUnused==0
+        || offset>=PENDING_BYTE+512
+        || offset+amt<=PENDING_BYTE 
+   );
+@@ -34126,7 +36184,7 @@
+       do{
+         err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
+       }while( err==EINTR );
+-      if( err ) return SQLITE_IOERR_WRITE;
++      if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE;
+ #else
+       /* If the OS does not have posix_fallocate(), fake it. Write a 
+       ** single byte to the last byte in each block that falls entirely
+@@ -34194,6 +36252,21 @@
+ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
+   unixFile *pFile = (unixFile*)id;
+   switch( op ){
++#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++    case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: {
++      int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE);
++      return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK;
++    }
++    case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: {
++      int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE);
++      return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
++    }
++    case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
++      int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
++      return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
++    }
++#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
++
+     case SQLITE_FCNTL_LOCKSTATE: {
+       *(int*)pArg = pFile->eFileLock;
+       return SQLITE_OK;
+@@ -34237,6 +36310,12 @@
+       *(int*)pArg = fileHasMoved(pFile);
+       return SQLITE_OK;
+     }
++#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
++    case SQLITE_FCNTL_LOCK_TIMEOUT: {
++      pFile->iBusyTimeout = *(int*)pArg;
++      return SQLITE_OK;
++    }
++#endif
+ #if SQLITE_MAX_MMAP_SIZE>0
+     case SQLITE_FCNTL_MMAP_SIZE: {
+       i64 newLimit = *(i64*)pArg;
+@@ -34244,6 +36323,14 @@
+       if( newLimit>sqlite3GlobalConfig.mxMmap ){
+         newLimit = sqlite3GlobalConfig.mxMmap;
+       }
++
++      /* The value of newLimit may be eventually cast to (size_t) and passed
++      ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a
++      ** 64-bit type. */
++      if( newLimit>0 && sizeof(size_t)<8 ){
++        newLimit = (newLimit & 0x7FFFFFFF);
++      }
++
+       *(i64*)pArg = pFile->mmapSizeMax;
+       if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+         pFile->mmapSizeMax = newLimit;
+@@ -34277,30 +36364,41 @@
+ }
+ 
+ /*
+-** Return the sector size in bytes of the underlying block device for
+-** the specified file. This is almost always 512 bytes, but may be
+-** larger for some devices.
++** If pFd->sectorSize is non-zero when this function is called, it is a
++** no-op. Otherwise, the values of pFd->sectorSize and 
++** pFd->deviceCharacteristics are set according to the file-system 
++** characteristics. 
+ **
+-** SQLite code assumes this function cannot fail. It also assumes that
+-** if two files are created in the same file-system directory (i.e.
+-** a database and its journal file) that the sector size will be the
+-** same for both.
++** There are two versions of this function. One for QNX and one for all
++** other systems.
+ */
+-#ifndef __QNXNTO__ 
+-static int unixSectorSize(sqlite3_file *NotUsed){
+-  UNUSED_PARAMETER(NotUsed);
+-  return SQLITE_DEFAULT_SECTOR_SIZE;
++#ifndef __QNXNTO__
++static void setDeviceCharacteristics(unixFile *pFd){
++  assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 );
++  if( pFd->sectorSize==0 ){
++#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++    int res;
++    u32 f = 0;
++
++    /* Check for support for F2FS atomic batch writes. */
++    res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f);
++    if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){
++      pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC;
++    }
++#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
++
++    /* Set the POWERSAFE_OVERWRITE flag if requested. */
++    if( pFd->ctrlFlags & UNIXFILE_PSOW ){
++      pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
++    }
++
++    pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
++  }
+ }
+-#endif
+-
+-/*
+-** The following version of unixSectorSize() is optimized for QNX.
+-*/
+-#ifdef __QNXNTO__
++#else
+ #include <sys/dcmd_blk.h>
+ #include <sys/statvfs.h>
+-static int unixSectorSize(sqlite3_file *id){
+-  unixFile *pFile = (unixFile*)id;
++static void setDeviceCharacteristics(unixFile *pFile){
+   if( pFile->sectorSize == 0 ){
+     struct statvfs fsInfo;
+        
+@@ -34308,7 +36406,7 @@
+     pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
+     pFile->deviceCharacteristics = 0;
+     if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
+-      return pFile->sectorSize;
++      return;
+     }
+ 
+     if( !strcmp(fsInfo.f_basetype, "tmp") ) {
+@@ -34369,11 +36467,26 @@
+     pFile->deviceCharacteristics = 0;
+     pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
+   }
+-  return pFile->sectorSize;
+ }
+-#endif /* __QNXNTO__ */
++#endif
+ 
+ /*
++** Return the sector size in bytes of the underlying block device for
++** the specified file. This is almost always 512 bytes, but may be
++** larger for some devices.
++**
++** SQLite code assumes this function cannot fail. It also assumes that
++** if two files are created in the same file-system directory (i.e.
++** a database and its journal file) that the sector size will be the
++** same for both.
++*/
++static int unixSectorSize(sqlite3_file *id){
++  unixFile *pFd = (unixFile*)id;
++  setDeviceCharacteristics(pFd);
++  return pFd->sectorSize;
++}
++
++/*
+ ** Return the device characteristics for the file.
+ **
+ ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
+@@ -34387,16 +36500,9 @@
+ ** available to turn it off and URI query parameter available to turn it off.
+ */
+ static int unixDeviceCharacteristics(sqlite3_file *id){
+-  unixFile *p = (unixFile*)id;
+-  int rc = 0;
+-#ifdef __QNXNTO__
+-  if( p->sectorSize==0 ) unixSectorSize(id);
+-  rc = p->deviceCharacteristics;
+-#endif
+-  if( p->ctrlFlags & UNIXFILE_PSOW ){
+-    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
+-  }
+-  return rc;
++  unixFile *pFd = (unixFile*)id;
++  setDeviceCharacteristics(pFd);
++  return pFd->deviceCharacteristics;
+ }
+ 
+ #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+@@ -34443,21 +36549,22 @@
+ **
+ ** The following fields are read-only after the object is created:
+ ** 
+-**      fid
++**      hShm
+ **      zFilename
+ **
+-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
++** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
+ ** unixMutexHeld() is true when reading or writing any other field
+ ** in this structure.
+ */
+ struct unixShmNode {
+   unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
+-  sqlite3_mutex *mutex;      /* Mutex to access this object */
++  sqlite3_mutex *pShmMutex;  /* Mutex to access this object */
+   char *zFilename;           /* Name of the mmapped file */
+-  int h;                     /* Open file descriptor */
++  int hShm;                  /* Open file descriptor */
+   int szRegion;              /* Size of shared-memory regions */
+   u16 nRegion;               /* Size of array apRegion */
+   u8 isReadonly;             /* True if read-only */
++  u8 isUnlocked;             /* True if no DMS lock held */
+   char **apRegion;           /* Array of mapped shared-memory regions */
+   int nRef;                  /* Number of unixShm objects pointing to this */
+   unixShm *pFirst;           /* All unixShm objects pointing to this */
+@@ -34475,16 +36582,16 @@
+ ** The following fields are initialized when this object is created and
+ ** are read-only thereafter:
+ **
+-**    unixShm.pFile
++**    unixShm.pShmNode
+ **    unixShm.id
+ **
+-** All other fields are read/write.  The unixShm.pFile->mutex must be held
+-** while accessing any read/write fields.
++** All other fields are read/write.  The unixShm.pShmNode->pShmMutex must
++** be held while accessing any read/write fields.
+ */
+ struct unixShm {
+   unixShmNode *pShmNode;     /* The underlying unixShmNode object */
+   unixShm *pNext;            /* Next unixShm with the same unixShmNode */
+-  u8 hasMutex;               /* True if holding the unixShmNode mutex */
++  u8 hasMutex;               /* True if holding the unixShmNode->pShmMutex */
+   u8 id;                     /* Id of this connection within its unixShmNode */
+   u16 sharedMask;            /* Mask of shared locks held */
+   u16 exclMask;              /* Mask of exclusive locks held */
+@@ -34514,7 +36621,8 @@
+ 
+   /* Access to the unixShmNode object is serialized by the caller */
+   pShmNode = pFile->pInode->pShmNode;
+-  assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
++  assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
++  assert( pShmNode->nRef>0 || unixMutexHeld() );
+ 
+   /* Shared locks never span more than one byte */
+   assert( n==1 || lockType!=F_RDLCK );
+@@ -34522,15 +36630,13 @@
+   /* Locks are within range */
+   assert( n>=1 && n<=SQLITE_SHM_NLOCK );
+ 
+-  if( pShmNode->h>=0 ){
++  if( pShmNode->hShm>=0 ){
+     /* Initialize the locking parameters */
+-    memset(&f, 0, sizeof(f));
+     f.l_type = lockType;
+     f.l_whence = SEEK_SET;
+     f.l_start = ofst;
+     f.l_len = n;
+-
+-    rc = osFcntl(pShmNode->h, F_SETLK, &f);
++    rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
+     rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
+   }
+ 
+@@ -34602,9 +36708,9 @@
+     int nShmPerMap = unixShmRegionPerMap();
+     int i;
+     assert( p->pInode==pFd->pInode );
+-    sqlite3_mutex_free(p->mutex);
++    sqlite3_mutex_free(p->pShmMutex);
+     for(i=0; i<p->nRegion; i+=nShmPerMap){
+-      if( p->h>=0 ){
++      if( p->hShm>=0 ){
+         osMunmap(p->apRegion[i], p->szRegion);
+       }else{
+         sqlite3_free(p->apRegion[i]);
+@@ -34611,9 +36717,9 @@
+       }
+     }
+     sqlite3_free(p->apRegion);
+-    if( p->h>=0 ){
+-      robust_close(pFd, p->h, __LINE__);
+-      p->h = -1;
++    if( p->hShm>=0 ){
++      robust_close(pFd, p->hShm, __LINE__);
++      p->hShm = -1;
+     }
+     p->pInode->pShmNode = 0;
+     sqlite3_free(p);
+@@ -34621,6 +36727,69 @@
+ }
+ 
+ /*
++** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
++** take it now. Return SQLITE_OK if successful, or an SQLite error
++** code otherwise.
++**
++** If the DMS cannot be locked because this is a readonly_shm=1 
++** connection and no other process already holds a lock, return
++** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
++*/
++static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
++  struct flock lock;
++  int rc = SQLITE_OK;
++
++  /* Use F_GETLK to determine the locks other processes are holding
++  ** on the DMS byte. If it indicates that another process is holding
++  ** a SHARED lock, then this process may also take a SHARED lock
++  ** and proceed with opening the *-shm file. 
++  **
++  ** Or, if no other process is holding any lock, then this process
++  ** is the first to open it. In this case take an EXCLUSIVE lock on the
++  ** DMS byte and truncate the *-shm file to zero bytes in size. Then
++  ** downgrade to a SHARED lock on the DMS byte.
++  **
++  ** If another process is holding an EXCLUSIVE lock on the DMS byte,
++  ** return SQLITE_BUSY to the caller (it will try again). An earlier
++  ** version of this code attempted the SHARED lock at this point. But
++  ** this introduced a subtle race condition: if the process holding
++  ** EXCLUSIVE failed just before truncating the *-shm file, then this
++  ** process might open and use the *-shm file without truncating it.
++  ** And if the *-shm file has been corrupted by a power failure or
++  ** system crash, the database itself may also become corrupt.  */
++  lock.l_whence = SEEK_SET;
++  lock.l_start = UNIX_SHM_DMS;
++  lock.l_len = 1;
++  lock.l_type = F_WRLCK;
++  if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
++    rc = SQLITE_IOERR_LOCK;
++  }else if( lock.l_type==F_UNLCK ){
++    if( pShmNode->isReadonly ){
++      pShmNode->isUnlocked = 1;
++      rc = SQLITE_READONLY_CANTINIT;
++    }else{
++      rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
++      /* The first connection to attach must truncate the -shm file.  We
++      ** truncate to 3 bytes (an arbitrary small number, less than the
++      ** -shm header size) rather than 0 as a system debugging aid, to
++      ** help detect if a -shm file truncation is legitimate or is the work
++      ** or a rogue process. */
++      if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
++        rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
++      }
++    }
++  }else if( lock.l_type==F_WRLCK ){
++    rc = SQLITE_BUSY;
++  }
++
++  if( rc==SQLITE_OK ){
++    assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
++    rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
++  }
++  return rc;
++}
++
++/*
+ ** Open a shared-memory area associated with open database file pDbFd.  
+ ** This particular implementation uses mmapped files.
+ **
+@@ -34658,9 +36827,9 @@
+ static int unixOpenSharedMemory(unixFile *pDbFd){
+   struct unixShm *p = 0;          /* The connection to be opened */
+   struct unixShmNode *pShmNode;   /* The underlying mmapped file */
+-  int rc;                         /* Result code */
++  int rc = SQLITE_OK;             /* Result code */
+   unixInodeInfo *pInode;          /* The inode of fd */
+-  char *zShmFilename;             /* Name of the file used for SHM */
++  char *zShm;             /* Name of the file used for SHM */
+   int nShmFilename;               /* Size of the SHM filename in bytes */
+ 
+   /* Allocate space for the new unixShm object. */
+@@ -34672,6 +36841,7 @@
+   /* Check to see if a unixShmNode object already exists. Reuse an existing
+   ** one if present. Create a new one if necessary.
+   */
++  assert( unixFileMutexNotheld(pDbFd) );
+   unixEnterMutex();
+   pInode = pDbFd->pInode;
+   pShmNode = pInode->pShmNode;
+@@ -34701,21 +36871,21 @@
+       goto shm_open_err;
+     }
+     memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
+-    zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
++    zShm = pShmNode->zFilename = (char*)&pShmNode[1];
+ #ifdef SQLITE_SHM_DIRECTORY
+-    sqlite3_snprintf(nShmFilename, zShmFilename, 
++    sqlite3_snprintf(nShmFilename, zShm, 
+                      SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
+                      (u32)sStat.st_ino, (u32)sStat.st_dev);
+ #else
+-    sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
+-    sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
++    sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
++    sqlite3FileSuffix3(pDbFd->zPath, zShm);
+ #endif
+-    pShmNode->h = -1;
++    pShmNode->hShm = -1;
+     pDbFd->pInode->pShmNode = pShmNode;
+     pShmNode->pInode = pDbFd->pInode;
+     if( sqlite3GlobalConfig.bCoreMutex ){
+-      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+-      if( pShmNode->mutex==0 ){
++      pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pShmNode->pShmMutex==0 ){
+         rc = SQLITE_NOMEM_BKPT;
+         goto shm_open_err;
+       }
+@@ -34722,36 +36892,26 @@
+     }
+ 
+     if( pInode->bProcessLock==0 ){
+-      int openFlags = O_RDWR | O_CREAT;
+-      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+-        openFlags = O_RDONLY;
++      if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
++        pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
++      }
++      if( pShmNode->hShm<0 ){
++        pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
++        if( pShmNode->hShm<0 ){
++          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
++          goto shm_open_err;
++        }
+         pShmNode->isReadonly = 1;
+       }
+-      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
+-      if( pShmNode->h<0 ){
+-        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
+-        goto shm_open_err;
+-      }
+ 
+       /* If this process is running as root, make sure that the SHM file
+       ** is owned by the same user that owns the original database.  Otherwise,
+       ** the original owner will not be able to connect.
+       */
+-      robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
+-  
+-      /* Check to see if another process is holding the dead-man switch.
+-      ** If not, truncate the file to zero length. 
+-      */
+-      rc = SQLITE_OK;
+-      if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
+-        if( robust_ftruncate(pShmNode->h, 0) ){
+-          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
+-        }
+-      }
+-      if( rc==SQLITE_OK ){
+-        rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+-      }
+-      if( rc ) goto shm_open_err;
++      robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
++
++      rc = unixLockSharedMemory(pDbFd, pShmNode);
++      if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
+     }
+   }
+ 
+@@ -34768,14 +36928,14 @@
+   ** the cover of the unixEnterMutex() mutex and the pointer from the
+   ** new (struct unixShm) object to the pShmNode has been set. All that is
+   ** left to do is to link the new object into the linked list starting
+-  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
+-  ** mutex.
++  ** at pShmNode->pFirst. This must be done while holding the
++  ** pShmNode->pShmMutex.
+   */
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   p->pNext = pShmNode->pFirst;
+   pShmNode->pFirst = p;
+-  sqlite3_mutex_leave(pShmNode->mutex);
+-  return SQLITE_OK;
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
++  return rc;
+ 
+   /* Jump here on any error */
+ shm_open_err:
+@@ -34826,11 +36986,16 @@
+ 
+   p = pDbFd->pShm;
+   pShmNode = p->pShmNode;
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
++  if( pShmNode->isUnlocked ){
++    rc = unixLockSharedMemory(pDbFd, pShmNode);
++    if( rc!=SQLITE_OK ) goto shmpage_out;
++    pShmNode->isUnlocked = 0;
++  }
+   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
+   assert( pShmNode->pInode==pDbFd->pInode );
+-  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
+-  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
++  assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
++  assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
+ 
+   /* Minimum number of regions required to be mapped. */
+   nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
+@@ -34842,12 +37007,12 @@
+ 
+     pShmNode->szRegion = szRegion;
+ 
+-    if( pShmNode->h>=0 ){
++    if( pShmNode->hShm>=0 ){
+       /* The requested region is not mapped into this processes address space.
+       ** Check to see if it has been allocated (i.e. if the wal-index file is
+       ** large enough to contain the requested region).
+       */
+-      if( osFstat(pShmNode->h, &sStat) ){
++      if( osFstat(pShmNode->hShm, &sStat) ){
+         rc = SQLITE_IOERR_SHMSIZE;
+         goto shmpage_out;
+       }
+@@ -34875,7 +37040,7 @@
+           assert( (nByte % pgsz)==0 );
+           for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
+             int x = 0;
+-            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
++            if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
+               const char *zFile = pShmNode->zFilename;
+               rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
+               goto shmpage_out;
+@@ -34898,10 +37063,10 @@
+       int nMap = szRegion*nShmPerMap;
+       int i;
+       void *pMem;
+-      if( pShmNode->h>=0 ){
++      if( pShmNode->hShm>=0 ){
+         pMem = osMmap(0, nMap,
+             pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
+-            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
++            MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
+         );
+         if( pMem==MAP_FAILED ){
+           rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
+@@ -34908,12 +37073,12 @@
+           goto shmpage_out;
+         }
+       }else{
+-        pMem = sqlite3_malloc64(szRegion);
++        pMem = sqlite3_malloc64(nMap);
+         if( pMem==0 ){
+           rc = SQLITE_NOMEM_BKPT;
+           goto shmpage_out;
+         }
+-        memset(pMem, 0, szRegion);
++        memset(pMem, 0, nMap);
+       }
+ 
+       for(i=0; i<nShmPerMap; i++){
+@@ -34930,7 +37095,7 @@
+     *pp = 0;
+   }
+   if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+   return rc;
+ }
+ 
+@@ -34964,12 +37129,12 @@
+        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
+        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
+   assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
+-  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
+-  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
++  assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
++  assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
+ 
+   mask = (1<<(ofst+n)) - (1<<ofst);
+   assert( n>1 || mask==(1<<ofst) );
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   if( flags & SQLITE_SHM_UNLOCK ){
+     u16 allMask = 0; /* Mask of locks held by siblings */
+ 
+@@ -35042,7 +37207,7 @@
+       }
+     }
+   }
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+   OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
+            p->id, osGetpid(0), p->sharedMask, p->exclMask));
+   return rc;
+@@ -35059,6 +37224,9 @@
+ ){
+   UNUSED_PARAMETER(fd);
+   sqlite3MemoryBarrier();         /* compiler-defined memory barrier */
++  assert( fd->pMethods->xLock==nolockLock 
++       || unixFileMutexNotheld((unixFile*)fd) 
++  );
+   unixEnterMutex();               /* Also mutex, for redundancy */
+   unixLeaveMutex();
+ }
+@@ -35089,7 +37257,7 @@
+ 
+   /* Remove connection p from the set of connections associated
+   ** with pShmNode */
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
+   *pp = p->pNext;
+ 
+@@ -35096,15 +37264,16 @@
+   /* Free the connection p */
+   sqlite3_free(p);
+   pDbFd->pShm = 0;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+ 
+   /* If pShmNode->nRef has reached 0, then close the underlying
+   ** shared-memory file, too */
++  assert( unixFileMutexNotheld(pDbFd) );
+   unixEnterMutex();
+   assert( pShmNode->nRef>0 );
+   pShmNode->nRef--;
+   if( pShmNode->nRef==0 ){
+-    if( deleteFlag && pShmNode->h>=0 ){
++    if( deleteFlag && pShmNode->hShm>=0 ){
+       osUnlink(pShmNode->zFilename);
+     }
+     unixShmPurge(pDbFd);
+@@ -35426,7 +37595,7 @@
+ IOMETHODS(
+   nolockIoFinder,           /* Finder function name */
+   nolockIoMethods,          /* sqlite3_io_methods object name */
+-  3,                        /* shared memory is disabled */
++  3,                        /* shared memory and mmap are enabled */
+   nolockClose,              /* xClose method */
+   nolockLock,               /* xLock method */
+   nolockUnlock,             /* xUnlock method */
+@@ -35654,17 +37823,6 @@
+ 
+   assert( pNew->pInode==NULL );
+ 
+-  /* Usually the path zFilename should not be a relative pathname. The
+-  ** exception is when opening the proxy "conch" file in builds that
+-  ** include the special Apple locking styles.
+-  */
+-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
+-  assert( zFilename==0 || zFilename[0]=='/' 
+-    || pVfs->pAppData==(void*)&autolockIoFinder );
+-#else
+-  assert( zFilename==0 || zFilename[0]=='/' );
+-#endif
+-
+   /* No locking occurs in temporary files */
+   assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
+ 
+@@ -35923,6 +38081,8 @@
+ #if !OS_VXWORKS
+   struct stat sStat;                   /* Results of stat() call */
+ 
++  unixEnterMutex();
++
+   /* A stat() call may fail for various reasons. If this happens, it is
+   ** almost certain that an open() call on the same path will also fail.
+   ** For this reason, if an error occurs in the stat() call here, it is
+@@ -35931,10 +38091,9 @@
+   **
+   ** Even if a subsequent open() call does succeed, the consequences of
+   ** not searching for a reusable file descriptor are not dire.  */
+-  if( 0==osStat(zPath, &sStat) ){
++  if( inodeList!=0 && 0==osStat(zPath, &sStat) ){
+     unixInodeInfo *pInode;
+ 
+-    unixEnterMutex();
+     pInode = inodeList;
+     while( pInode && (pInode->fileId.dev!=sStat.st_dev
+                      || pInode->fileId.ino!=(u64)sStat.st_ino) ){
+@@ -35942,14 +38101,17 @@
+     }
+     if( pInode ){
+       UnixUnusedFd **pp;
++      assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
++      sqlite3_mutex_enter(pInode->pLockMutex);
+       for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
+       pUnused = *pp;
+       if( pUnused ){
+         *pp = pUnused->pNext;
+       }
++      sqlite3_mutex_leave(pInode->pLockMutex);
+     }
+-    unixLeaveMutex();
+   }
++  unixLeaveMutex();
+ #endif    /* if !OS_VXWORKS */
+   return pUnused;
+ }
+@@ -36025,16 +38187,11 @@
+     */
+     nDb = sqlite3Strlen30(zPath) - 1; 
+     while( zPath[nDb]!='-' ){
+-#ifndef SQLITE_ENABLE_8_3_NAMES
+-      /* In the normal case (8+3 filenames disabled) the journal filename
+-      ** is guaranteed to contain a '-' character. */
+-      assert( nDb>0 );
+-      assert( sqlite3Isalnum(zPath[nDb]) );
+-#else
+-      /* If 8+3 names are possible, then the journal file might not contain
+-      ** a '-' character.  So check for that case and return early. */
++      /* In normal operation, the journal file name will always contain
++      ** a '-' character.  However in 8+3 filename mode, or if a corrupt
++      ** rollback journal specifies a master journal with a goofy name, then
++      ** the '-' might be missing. */
+       if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
+-#endif
+       nDb--;
+     }
+     memcpy(zDb, zPath, nDb);
+@@ -36109,7 +38266,7 @@
+   ** a file-descriptor on the directory too. The first time unixSync()
+   ** is called the directory file descriptor will be fsync()ed and close()d.
+   */
+-  int syncDir = (isCreate && (
++  int isNewJrnl = (isCreate && (
+         eType==SQLITE_OPEN_MASTER_JOURNAL 
+      || eType==SQLITE_OPEN_MAIN_JOURNAL 
+      || eType==SQLITE_OPEN_WAL
+@@ -36156,7 +38313,6 @@
+     randomnessPid = osGetpid(0);
+     sqlite3_randomness(0,0);
+   }
+-
+   memset(p, 0, sizeof(unixFile));
+ 
+   if( eType==SQLITE_OPEN_MAIN_DB ){
+@@ -36170,7 +38326,7 @@
+         return SQLITE_NOMEM_BKPT;
+       }
+     }
+-    p->pUnused = pUnused;
++    p->pPreallocatedUnused = pUnused;
+ 
+     /* Database filenames are double-zero terminated if they are not
+     ** URIs with parameters.  Hence, they can always be passed into
+@@ -36179,7 +38335,7 @@
+ 
+   }else if( !zName ){
+     /* If zName is NULL, the upper layer is requesting a temp file. */
+-    assert(isDelete && !syncDir);
++    assert(isDelete && !isNewJrnl);
+     rc = unixGetTempname(pVfs->mxPathname, zTmpname);
+     if( rc!=SQLITE_OK ){
+       return rc;
+@@ -36207,7 +38363,7 @@
+     gid_t gid;                    /* Groupid for the file */
+     rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
+     if( rc!=SQLITE_OK ){
+-      assert( !p->pUnused );
++      assert( !p->pPreallocatedUnused );
+       assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
+       return rc;
+     }
+@@ -36214,17 +38370,24 @@
+     fd = robust_open(zName, openFlags, openMode);
+     OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
+     assert( !isExclusive || (openFlags & O_CREAT)!=0 );
+-    if( fd<0 && errno!=EISDIR && isReadWrite ){
+-      /* Failed to open the file for read/write access. Try read-only. */
+-      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+-      openFlags &= ~(O_RDWR|O_CREAT);
+-      flags |= SQLITE_OPEN_READONLY;
+-      openFlags |= O_RDONLY;
+-      isReadonly = 1;
+-      fd = robust_open(zName, openFlags, openMode);
++    if( fd<0 ){
++      if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
++        /* If unable to create a journal because the directory is not
++        ** writable, change the error code to indicate that. */
++        rc = SQLITE_READONLY_DIRECTORY;
++      }else if( errno!=EISDIR && isReadWrite ){
++        /* Failed to open the file for read/write access. Try read-only. */
++        flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
++        openFlags &= ~(O_RDWR|O_CREAT);
++        flags |= SQLITE_OPEN_READONLY;
++        openFlags |= O_RDONLY;
++        isReadonly = 1;
++        fd = robust_open(zName, openFlags, openMode);
++      }
+     }
+     if( fd<0 ){
+-      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
++      int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
++      if( rc==SQLITE_OK ) rc = rc2;
+       goto open_finished;
+     }
+ 
+@@ -36241,9 +38404,9 @@
+     *pOutFlags = flags;
+   }
+ 
+-  if( p->pUnused ){
+-    p->pUnused->fd = fd;
+-    p->pUnused->flags = flags;
++  if( p->pPreallocatedUnused ){
++    p->pPreallocatedUnused->fd = fd;
++    p->pPreallocatedUnused->flags = flags;
+   }
+ 
+   if( isDelete ){
+@@ -36284,7 +38447,7 @@
+   if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
+   noLock = eType!=SQLITE_OPEN_MAIN_DB;
+   if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
+-  if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
++  if( isNewJrnl )               ctrlFlags |= UNIXFILE_DIRSYNC;
+   if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
+ 
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -36320,11 +38483,14 @@
+   }
+ #endif
+   
++  assert( zPath==0 || zPath[0]=='/' 
++      || eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL 
++  );
+   rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
+ 
+ open_finished:
+   if( rc!=SQLITE_OK ){
+-    sqlite3_free(p->pUnused);
++    sqlite3_free(p->pPreallocatedUnused);
+   }
+   return rc;
+ }
+@@ -37065,7 +39231,7 @@
+   dummyVfs.zName = "dummy";
+   pUnused->fd = fd;
+   pUnused->flags = openFlags;
+-  pNew->pUnused = pUnused;
++  pNew->pPreallocatedUnused = pUnused;
+   
+   rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
+   if( rc==SQLITE_OK ){
+@@ -38015,12 +40181,13 @@
+ 
+   /* Double-check that the aSyscall[] array has been constructed
+   ** correctly.  See ticket [bb3a86e890c8e96ab] */
+-  assert( ArraySize(aSyscall)==28 );
++  assert( ArraySize(aSyscall)==29 );
+ 
+   /* Register all VFSes defined in the aVfs[] array */
+   for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+     sqlite3_vfs_register(&aVfs[i], i==0);
+   }
++  unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
+   return SQLITE_OK; 
+ }
+ 
+@@ -38032,6 +40199,7 @@
+ ** This routine is a no-op for unix.
+ */
+ SQLITE_API int sqlite3_os_end(void){ 
++  unixBigLock = 0;
+   return SQLITE_OK; 
+ }
+  
+@@ -38523,8 +40691,7 @@
+   int nFetchOut;                /* Number of outstanding xFetch references */
+   HANDLE hMap;                  /* Handle for accessing memory mapping */
+   void *pMapRegion;             /* Area memory mapped */
+-  sqlite3_int64 mmapSize;       /* Usable size of mapped region */
+-  sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
++  sqlite3_int64 mmapSize;       /* Size of mapped region */
+   sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
+ #endif
+ };
+@@ -38555,22 +40722,6 @@
+ #endif
+ 
+ /*
+- * The value used with sqlite3_win32_set_directory() to specify that
+- * the data directory should be changed.
+- */
+-#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
+-#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
+-#endif
+-
+-/*
+- * The value used with sqlite3_win32_set_directory() to specify that
+- * the temporary directory should be changed.
+- */
+-#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
+-#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
+-#endif
+-
+-/*
+  * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
+  * various Win32 API heap functions instead of our own.
+  */
+@@ -40166,13 +42317,13 @@
+ }
+ 
+ /*
+-** This function sets the data directory or the temporary directory based on
+-** the provided arguments.  The type argument must be 1 in order to set the
+-** data directory or 2 in order to set the temporary directory.  The zValue
+-** argument is the name of the directory to use.  The return value will be
+-** SQLITE_OK if successful.
++** This function is the same as sqlite3_win32_set_directory (below); however,
++** it accepts a UTF-8 string.
+ */
+-SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
++SQLITE_API int sqlite3_win32_set_directory8(
++  unsigned long type, /* Identifier for directory being set or reset */
++  const char *zValue  /* New value for directory being set or reset */
++){
+   char **ppDirectory = 0;
+ #ifndef SQLITE_OMIT_AUTOINIT
+   int rc = sqlite3_initialize();
+@@ -40188,15 +42339,15 @@
+   );
+   assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
+   if( ppDirectory ){
+-    char *zValueUtf8 = 0;
++    char *zCopy = 0;
+     if( zValue && zValue[0] ){
+-      zValueUtf8 = winUnicodeToUtf8(zValue);
+-      if ( zValueUtf8==0 ){
++      zCopy = sqlite3_mprintf("%s", zValue);
++      if ( zCopy==0 ){
+         return SQLITE_NOMEM_BKPT;
+       }
+     }
+     sqlite3_free(*ppDirectory);
+-    *ppDirectory = zValueUtf8;
++    *ppDirectory = zCopy;
+     return SQLITE_OK;
+   }
+   return SQLITE_ERROR;
+@@ -40203,6 +42354,39 @@
+ }
+ 
+ /*
++** This function is the same as sqlite3_win32_set_directory (below); however,
++** it accepts a UTF-16 string.
++*/
++SQLITE_API int sqlite3_win32_set_directory16(
++  unsigned long type, /* Identifier for directory being set or reset */
++  const void *zValue  /* New value for directory being set or reset */
++){
++  int rc;
++  char *zUtf8 = 0;
++  if( zValue ){
++    zUtf8 = sqlite3_win32_unicode_to_utf8(zValue);
++    if( zUtf8==0 ) return SQLITE_NOMEM_BKPT;
++  }
++  rc = sqlite3_win32_set_directory8(type, zUtf8);
++  if( zUtf8 ) sqlite3_free(zUtf8);
++  return rc;
++}
++
++/*
++** This function sets the data directory or the temporary directory based on
++** the provided arguments.  The type argument must be 1 in order to set the
++** data directory or 2 in order to set the temporary directory.  The zValue
++** argument is the name of the directory to use.  The return value will be
++** SQLITE_OK if successful.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++){
++  return sqlite3_win32_set_directory16(type, zValue);
++}
++
++/*
+ ** The return value of winGetLastErrorMsg
+ ** is zero if the error message fits in the buffer, or non-zero
+ ** otherwise (if the message was truncated).
+@@ -41126,6 +43310,29 @@
+   winFile *pFile = (winFile*)id;  /* File handle object */
+   int rc = SQLITE_OK;             /* Return code for this function */
+   DWORD lastErrno;
++#if SQLITE_MAX_MMAP_SIZE>0
++  sqlite3_int64 oldMmapSize;
++  if( pFile->nFetchOut>0 ){
++    /* File truncation is a no-op if there are outstanding memory mapped
++    ** pages.  This is because truncating the file means temporarily unmapping
++    ** the file, and that might delete memory out from under existing cursors.
++    **
++    ** This can result in incremental vacuum not truncating the file,
++    ** if there is an active read cursor when the incremental vacuum occurs.
++    ** No real harm comes of this - the database file is not corrupted,
++    ** though some folks might complain that the file is bigger than it
++    ** needs to be.
++    **
++    ** The only feasible work-around is to defer the truncation until after
++    ** all references to memory-mapped content are closed.  That is doable,
++    ** but involves adding a few branches in the common write code path which
++    ** could slow down normal operations slightly.  Hence, we have decided for
++    ** now to simply make trancations a no-op if there are pending reads.  We
++    ** can maybe revisit this decision in the future.
++    */
++    return SQLITE_OK;
++  }
++#endif
+ 
+   assert( pFile );
+   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
+@@ -41141,6 +43348,15 @@
+     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
+   }
+ 
++#if SQLITE_MAX_MMAP_SIZE>0
++  if( pFile->pMapRegion ){
++    oldMmapSize = pFile->mmapSize;
++  }else{
++    oldMmapSize = 0;
++  }
++  winUnmapfile(pFile);
++#endif
++
+   /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
+   if( winSeekFile(pFile, nByte) ){
+     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
+@@ -41153,12 +43369,12 @@
+   }
+ 
+ #if SQLITE_MAX_MMAP_SIZE>0
+-  /* If the file was truncated to a size smaller than the currently
+-  ** mapped region, reduce the effective mapping size as well. SQLite will
+-  ** use read() and write() to access data beyond this point from now on.
+-  */
+-  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
+-    pFile->mmapSize = nByte;
++  if( rc==SQLITE_OK && oldMmapSize>0 ){
++    if( oldMmapSize>nByte ){
++      winMapfile(pFile, -1);
++    }else{
++      winMapfile(pFile, oldMmapSize);
++    }
+   }
+ #endif
+ 
+@@ -41798,6 +44014,14 @@
+       if( newLimit>sqlite3GlobalConfig.mxMmap ){
+         newLimit = sqlite3GlobalConfig.mxMmap;
+       }
++
++      /* The value of newLimit may be eventually cast to (SIZE_T) and passed
++      ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at
++      ** least a 64-bit type. */
++      if( newLimit>0 && sizeof(SIZE_T)<8 ){
++        newLimit = (newLimit & 0x7FFFFFFF);
++      }
++
+       *(i64*)pArg = pFile->mmapSizeMax;
+       if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+         pFile->mmapSizeMax = newLimit;
+@@ -41862,15 +44086,16 @@
+ **     assert( winShmMutexHeld() );
+ **   winShmLeaveMutex()
+ */
++static sqlite3_mutex *winBigLock = 0;
+ static void winShmEnterMutex(void){
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  sqlite3_mutex_enter(winBigLock);
+ }
+ static void winShmLeaveMutex(void){
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  sqlite3_mutex_leave(winBigLock);
+ }
+ #ifndef NDEBUG
+ static int winShmMutexHeld(void) {
+-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1));
++  return sqlite3_mutex_held(winBigLock);
+ }
+ #endif
+ 
+@@ -41904,6 +44129,9 @@
+ 
+   int szRegion;              /* Size of shared-memory regions */
+   int nRegion;               /* Size of array apRegion */
++  u8 isReadonly;             /* True if read-only */
++  u8 isUnlocked;             /* True if no DMS lock held */
++
+   struct ShmRegion {
+     HANDLE hMap;             /* File handle from CreateFileMapping */
+     void *pMap;
+@@ -41970,7 +44198,7 @@
+   int rc = 0;           /* Result code form Lock/UnlockFileEx() */
+ 
+   /* Access to the winShmNode object is serialized by the caller */
+-  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
++  assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) );
+ 
+   OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
+            pFile->hFile.h, lockType, ofst, nByte));
+@@ -42052,6 +44280,37 @@
+ }
+ 
+ /*
++** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
++** take it now. Return SQLITE_OK if successful, or an SQLite error
++** code otherwise.
++**
++** If the DMS cannot be locked because this is a readonly_shm=1
++** connection and no other process already holds a lock, return
++** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
++*/
++static int winLockSharedMemory(winShmNode *pShmNode){
++  int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
++
++  if( rc==SQLITE_OK ){
++    if( pShmNode->isReadonly ){
++      pShmNode->isUnlocked = 1;
++      winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
++      return SQLITE_READONLY_CANTINIT;
++    }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
++      winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
++      return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
++                         "winLockSharedMemory", pShmNode->zFilename);
++    }
++  }
++
++  if( rc==SQLITE_OK ){
++    winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
++  }
++
++  return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
++}
++
++/*
+ ** Open the shared-memory area associated with database file pDbFd.
+ **
+ ** When opening a new shared-memory file, if no other instances of that
+@@ -42060,9 +44319,9 @@
+ */
+ static int winOpenSharedMemory(winFile *pDbFd){
+   struct winShm *p;                  /* The connection to be opened */
+-  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
+-  int rc;                            /* Result code */
+-  struct winShmNode *pNew;           /* Newly allocated winShmNode */
++  winShmNode *pShmNode = 0;          /* The underlying mmapped file */
++  int rc = SQLITE_OK;                /* Result code */
++  winShmNode *pNew;                  /* Newly allocated winShmNode */
+   int nName;                         /* Size of zName in bytes */
+ 
+   assert( pDbFd->pShm==0 );    /* Not previously opened */
+@@ -42095,6 +44354,9 @@
+   if( pShmNode ){
+     sqlite3_free(pNew);
+   }else{
++    int inFlags = SQLITE_OPEN_WAL;
++    int outFlags = 0;
++
+     pShmNode = pNew;
+     pNew = 0;
+     ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
+@@ -42109,30 +44371,23 @@
+       }
+     }
+ 
+-    rc = winOpen(pDbFd->pVfs,
+-                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
+-                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
+-                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+-                 0);
+-    if( SQLITE_OK!=rc ){
++    if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
++      inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
++    }else{
++      inFlags |= SQLITE_OPEN_READONLY;
++    }
++    rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
++                 (sqlite3_file*)&pShmNode->hFile,
++                 inFlags, &outFlags);
++    if( rc!=SQLITE_OK ){
++      rc = winLogError(rc, osGetLastError(), "winOpenShm",
++                       pShmNode->zFilename);
+       goto shm_open_err;
+     }
++    if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
+ 
+-    /* Check to see if another process is holding the dead-man switch.
+-    ** If not, truncate the file to zero length.
+-    */
+-    if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
+-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
+-      if( rc!=SQLITE_OK ){
+-        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+-                         "winOpenShm", pDbFd->zPath);
+-      }
+-    }
+-    if( rc==SQLITE_OK ){
+-      winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+-      rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
+-    }
+-    if( rc ) goto shm_open_err;
++    rc = winLockSharedMemory(pShmNode);
++    if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
+   }
+ 
+   /* Make the new connection a child of the winShmNode */
+@@ -42155,7 +44410,7 @@
+   p->pNext = pShmNode->pFirst;
+   pShmNode->pFirst = p;
+   sqlite3_mutex_leave(pShmNode->mutex);
+-  return SQLITE_OK;
++  return rc;
+ 
+   /* Jump here on any error */
+ shm_open_err:
+@@ -42359,6 +44614,8 @@
+   winFile *pDbFd = (winFile*)fd;
+   winShm *pShm = pDbFd->pShm;
+   winShmNode *pShmNode;
++  DWORD protect = PAGE_READWRITE;
++  DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
+   int rc = SQLITE_OK;
+ 
+   if( !pShm ){
+@@ -42369,6 +44626,11 @@
+   pShmNode = pShm->pShmNode;
+ 
+   sqlite3_mutex_enter(pShmNode->mutex);
++  if( pShmNode->isUnlocked ){
++    rc = winLockSharedMemory(pShmNode);
++    if( rc!=SQLITE_OK ) goto shmpage_out;
++    pShmNode->isUnlocked = 0;
++  }
+   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
+ 
+   if( pShmNode->nRegion<=iRegion ){
+@@ -42415,6 +44677,11 @@
+     }
+     pShmNode->aRegion = apNew;
+ 
++    if( pShmNode->isReadonly ){
++      protect = PAGE_READONLY;
++      flags = FILE_MAP_READ;
++    }
++
+     while( pShmNode->nRegion<=iRegion ){
+       HANDLE hMap = NULL;         /* file-mapping handle */
+       void *pMap = 0;             /* Mapped memory region */
+@@ -42421,15 +44688,15 @@
+ 
+ #if SQLITE_OS_WINRT
+       hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, nByte, NULL
++          NULL, protect, nByte, NULL
+       );
+ #elif defined(SQLITE_WIN32_HAS_WIDE)
+       hMap = osCreateFileMappingW(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, 0, nByte, NULL
++          NULL, protect, 0, nByte, NULL
+       );
+ #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
+       hMap = osCreateFileMappingA(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, 0, nByte, NULL
++          NULL, protect, 0, nByte, NULL
+       );
+ #endif
+       OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
+@@ -42439,11 +44706,11 @@
+         int iOffset = pShmNode->nRegion*szRegion;
+         int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
+ #if SQLITE_OS_WINRT
+-        pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
++        pMap = osMapViewOfFileFromApp(hMap, flags,
+             iOffset - iOffsetShift, szRegion + iOffsetShift
+         );
+ #else
+-        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
++        pMap = osMapViewOfFile(hMap, flags,
+             0, iOffset - iOffsetShift, szRegion + iOffsetShift
+         );
+ #endif
+@@ -42474,6 +44741,7 @@
+   }else{
+     *pp = 0;
+   }
++  if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
+   sqlite3_mutex_leave(pShmNode->mutex);
+   return rc;
+ }
+@@ -42492,9 +44760,9 @@
+ static int winUnmapfile(winFile *pFile){
+   assert( pFile!=0 );
+   OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
+-           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
++           "mmapSize=%lld, mmapSizeMax=%lld\n",
+            osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
+-           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
++           pFile->mmapSize, pFile->mmapSizeMax));
+   if( pFile->pMapRegion ){
+     if( !osUnmapViewOfFile(pFile->pMapRegion) ){
+       pFile->lastErrno = osGetLastError();
+@@ -42506,7 +44774,6 @@
+     }
+     pFile->pMapRegion = 0;
+     pFile->mmapSize = 0;
+-    pFile->mmapSizeActual = 0;
+   }
+   if( pFile->hMap!=NULL ){
+     if( !osCloseHandle(pFile->hMap) ){
+@@ -42617,7 +44884,6 @@
+     }
+     pFd->pMapRegion = pNew;
+     pFd->mmapSize = nMap;
+-    pFd->mmapSizeActual = nMap;
+   }
+ 
+   OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+@@ -43110,6 +45376,14 @@
+   return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
+ }
+ 
++/* forward reference */
++static int winAccess(
++  sqlite3_vfs *pVfs,         /* Not used on win32 */
++  const char *zFilename,     /* Name of file to check */
++  int flags,                 /* Type of test to make on this file */
++  int *pResOut               /* OUT: Result */
++);
++
+ /*
+ ** Open a file.
+ */
+@@ -43286,37 +45560,58 @@
+     extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
+     extendedParameters.lpSecurityAttributes = NULL;
+     extendedParameters.hTemplateFile = NULL;
+-    while( (h = osCreateFile2((LPCWSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode,
+-                              dwCreationDisposition,
+-                              &extendedParameters))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
++    do{
++      h = osCreateFile2((LPCWSTR)zConverted,
++                        dwDesiredAccess,
++                        dwShareMode,
++                        dwCreationDisposition,
++                        &extendedParameters);
++      if( h!=INVALID_HANDLE_VALUE ) break;
++      if( isReadWrite ){
++        int rc2, isRO = 0;
++        sqlite3BeginBenignMalloc();
++        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
++        sqlite3EndBenignMalloc();
++        if( rc2==SQLITE_OK && isRO ) break;
++      }
++    }while( winRetryIoerr(&cnt, &lastErrno) );
+ #else
+-    while( (h = osCreateFileW((LPCWSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode, NULL,
+-                              dwCreationDisposition,
+-                              dwFlagsAndAttributes,
+-                              NULL))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
++    do{
++      h = osCreateFileW((LPCWSTR)zConverted,
++                        dwDesiredAccess,
++                        dwShareMode, NULL,
++                        dwCreationDisposition,
++                        dwFlagsAndAttributes,
++                        NULL);
++      if( h!=INVALID_HANDLE_VALUE ) break;
++      if( isReadWrite ){
++        int rc2, isRO = 0;
++        sqlite3BeginBenignMalloc();
++        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
++        sqlite3EndBenignMalloc();
++        if( rc2==SQLITE_OK && isRO ) break;
++      }
++    }while( winRetryIoerr(&cnt, &lastErrno) );
+ #endif
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+   else{
+-    while( (h = osCreateFileA((LPCSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode, NULL,
+-                              dwCreationDisposition,
+-                              dwFlagsAndAttributes,
+-                              NULL))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
++    do{
++      h = osCreateFileA((LPCSTR)zConverted,
++                        dwDesiredAccess,
++                        dwShareMode, NULL,
++                        dwCreationDisposition,
++                        dwFlagsAndAttributes,
++                        NULL);
++      if( h!=INVALID_HANDLE_VALUE ) break;
++      if( isReadWrite ){
++        int rc2, isRO = 0;
++        sqlite3BeginBenignMalloc();
++        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
++        sqlite3EndBenignMalloc();
++        if( rc2==SQLITE_OK && isRO ) break;
++      }
++    }while( winRetryIoerr(&cnt, &lastErrno) );
+   }
+ #endif
+   winLogIoerr(cnt, __LINE__);
+@@ -43325,8 +45620,6 @@
+            dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
+ 
+   if( h==INVALID_HANDLE_VALUE ){
+-    pFile->lastErrno = lastErrno;
+-    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
+     sqlite3_free(zConverted);
+     sqlite3_free(zTmpname);
+     if( isReadWrite && !isExclusive ){
+@@ -43335,6 +45628,8 @@
+                      ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
+          pOutFlags);
+     }else{
++      pFile->lastErrno = lastErrno;
++      winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
+       return SQLITE_CANTOPEN_BKPT;
+     }
+   }
+@@ -43390,7 +45685,6 @@
+   pFile->hMap = NULL;
+   pFile->pMapRegion = 0;
+   pFile->mmapSize = 0;
+-  pFile->mmapSizeActual = 0;
+   pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+ #endif
+ 
+@@ -43927,9 +46221,6 @@
+   EntropyGatherer e;
+   UNUSED_PARAMETER(pVfs);
+   memset(zBuf, 0, nBuf);
+-#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE
+-  rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
+-#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
+   e.a = (unsigned char*)zBuf;
+   e.na = nBuf;
+   e.nXor = 0;
+@@ -44224,6 +46515,10 @@
+   sqlite3_vfs_register(&winLongPathNolockVfs, 0);
+ #endif
+ 
++#ifndef SQLITE_OMIT_WAL
++  winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
++#endif
++
+   return SQLITE_OK;
+ }
+ 
+@@ -44234,6 +46529,11 @@
+     sleepObj = NULL;
+   }
+ #endif
++
++#ifndef SQLITE_OMIT_WAL
++  winBigLock = 0;
++#endif
++
+   return SQLITE_OK;
+ }
+ 
+@@ -44240,6 +46540,598 @@
+ #endif /* SQLITE_OS_WIN */
+ 
+ /************** End of os_win.c **********************************************/
++/************** Begin file memdb.c *******************************************/
++/*
++** 2016-09-07
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file implements an in-memory VFS. A database is held as a contiguous
++** block of memory.
++**
++** This file also implements interface sqlite3_serialize() and
++** sqlite3_deserialize().
++*/
++/* #include "sqliteInt.h" */
++#ifdef SQLITE_ENABLE_DESERIALIZE
++
++/*
++** Forward declaration of objects used by this utility
++*/
++typedef struct sqlite3_vfs MemVfs;
++typedef struct MemFile MemFile;
++
++/* Access to a lower-level VFS that (might) implement dynamic loading,
++** access to randomness, etc.
++*/
++#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
++
++/* An open file */
++struct MemFile {
++  sqlite3_file base;              /* IO methods */
++  sqlite3_int64 sz;               /* Size of the file */
++  sqlite3_int64 szMax;            /* Space allocated to aData */
++  unsigned char *aData;           /* content of the file */
++  int nMmap;                      /* Number of memory mapped pages */
++  unsigned mFlags;                /* Flags */
++  int eLock;                      /* Most recent lock against this file */
++};
++
++/*
++** Methods for MemFile
++*/
++static int memdbClose(sqlite3_file*);
++static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
++static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
++static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
++static int memdbSync(sqlite3_file*, int flags);
++static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
++static int memdbLock(sqlite3_file*, int);
++/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
++static int memdbFileControl(sqlite3_file*, int op, void *pArg);
++/* static int memdbSectorSize(sqlite3_file*); // not used */
++static int memdbDeviceCharacteristics(sqlite3_file*);
++static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
++static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
++
++/*
++** Methods for MemVfs
++*/
++static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
++/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */
++static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *);
++static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
++static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename);
++static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
++static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
++static void memdbDlClose(sqlite3_vfs*, void*);
++static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut);
++static int memdbSleep(sqlite3_vfs*, int microseconds);
++/* static int memdbCurrentTime(sqlite3_vfs*, double*); */
++static int memdbGetLastError(sqlite3_vfs*, int, char *);
++static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
++
++static sqlite3_vfs memdb_vfs = {
++  2,                           /* iVersion */
++  0,                           /* szOsFile (set when registered) */
++  1024,                        /* mxPathname */
++  0,                           /* pNext */
++  "memdb",                     /* zName */
++  0,                           /* pAppData (set when registered) */ 
++  memdbOpen,                   /* xOpen */
++  0, /* memdbDelete, */        /* xDelete */
++  memdbAccess,                 /* xAccess */
++  memdbFullPathname,           /* xFullPathname */
++  memdbDlOpen,                 /* xDlOpen */
++  memdbDlError,                /* xDlError */
++  memdbDlSym,                  /* xDlSym */
++  memdbDlClose,                /* xDlClose */
++  memdbRandomness,             /* xRandomness */
++  memdbSleep,                  /* xSleep */
++  0, /* memdbCurrentTime, */   /* xCurrentTime */
++  memdbGetLastError,           /* xGetLastError */
++  memdbCurrentTimeInt64        /* xCurrentTimeInt64 */
++};
++
++static const sqlite3_io_methods memdb_io_methods = {
++  3,                              /* iVersion */
++  memdbClose,                      /* xClose */
++  memdbRead,                       /* xRead */
++  memdbWrite,                      /* xWrite */
++  memdbTruncate,                   /* xTruncate */
++  memdbSync,                       /* xSync */
++  memdbFileSize,                   /* xFileSize */
++  memdbLock,                       /* xLock */
++  memdbLock,                       /* xUnlock - same as xLock in this case */ 
++  0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
++  memdbFileControl,                /* xFileControl */
++  0, /* memdbSectorSize,*/         /* xSectorSize */
++  memdbDeviceCharacteristics,      /* xDeviceCharacteristics */
++  0,                               /* xShmMap */
++  0,                               /* xShmLock */
++  0,                               /* xShmBarrier */
++  0,                               /* xShmUnmap */
++  memdbFetch,                      /* xFetch */
++  memdbUnfetch                     /* xUnfetch */
++};
++
++
++
++/*
++** Close an memdb-file.
++**
++** The pData pointer is owned by the application, so there is nothing
++** to free.
++*/
++static int memdbClose(sqlite3_file *pFile){
++  MemFile *p = (MemFile *)pFile;
++  if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
++  return SQLITE_OK;
++}
++
++/*
++** Read data from an memdb-file.
++*/
++static int memdbRead(
++  sqlite3_file *pFile, 
++  void *zBuf, 
++  int iAmt, 
++  sqlite_int64 iOfst
++){
++  MemFile *p = (MemFile *)pFile;
++  if( iOfst+iAmt>p->sz ){
++    memset(zBuf, 0, iAmt);
++    if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
++    return SQLITE_IOERR_SHORT_READ;
++  }
++  memcpy(zBuf, p->aData+iOfst, iAmt);
++  return SQLITE_OK;
++}
++
++/*
++** Try to enlarge the memory allocation to hold at least sz bytes
++*/
++static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
++  unsigned char *pNew;
++  if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
++    return SQLITE_FULL;
++  }
++  pNew = sqlite3_realloc64(p->aData, newSz);
++  if( pNew==0 ) return SQLITE_NOMEM;
++  p->aData = pNew;
++  p->szMax = newSz;
++  return SQLITE_OK;
++}
++
++/*
++** Write data to an memdb-file.
++*/
++static int memdbWrite(
++  sqlite3_file *pFile,
++  const void *z,
++  int iAmt,
++  sqlite_int64 iOfst
++){
++  MemFile *p = (MemFile *)pFile;
++  if( iOfst+iAmt>p->sz ){
++    int rc;
++    if( iOfst+iAmt>p->szMax
++     && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
++    ){
++      return rc;
++    }
++    if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz);
++    p->sz = iOfst+iAmt;
++  }
++  memcpy(p->aData+iOfst, z, iAmt);
++  return SQLITE_OK;
++}
++
++/*
++** Truncate an memdb-file.
++**
++** In rollback mode (which is always the case for memdb, as it does not
++** support WAL mode) the truncate() method is only used to reduce
++** the size of a file, never to increase the size.
++*/
++static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
++  MemFile *p = (MemFile *)pFile;
++  if( NEVER(size>p->sz) ) return SQLITE_FULL;
++  p->sz = size; 
++  return SQLITE_OK;
++}
++
++/*
++** Sync an memdb-file.
++*/
++static int memdbSync(sqlite3_file *pFile, int flags){
++  return SQLITE_OK;
++}
++
++/*
++** Return the current file-size of an memdb-file.
++*/
++static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
++  MemFile *p = (MemFile *)pFile;
++  *pSize = p->sz;
++  return SQLITE_OK;
++}
++
++/*
++** Lock an memdb-file.
++*/
++static int memdbLock(sqlite3_file *pFile, int eLock){
++  MemFile *p = (MemFile *)pFile;
++  p->eLock = eLock;
++  return SQLITE_OK;
++}
++
++#if 0 /* Never used because memdbAccess() always returns false */
++/*
++** Check if another file-handle holds a RESERVED lock on an memdb-file.
++*/
++static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){
++  *pResOut = 0;
++  return SQLITE_OK;
++}
++#endif
++
++/*
++** File control method. For custom operations on an memdb-file.
++*/
++static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
++  MemFile *p = (MemFile *)pFile;
++  int rc = SQLITE_NOTFOUND;
++  if( op==SQLITE_FCNTL_VFSNAME ){
++    *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
++    rc = SQLITE_OK;
++  }
++  return rc;
++}
++
++#if 0  /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */
++/*
++** Return the sector-size in bytes for an memdb-file.
++*/
++static int memdbSectorSize(sqlite3_file *pFile){
++  return 1024;
++}
++#endif
++
++/*
++** Return the device characteristic flags supported by an memdb-file.
++*/
++static int memdbDeviceCharacteristics(sqlite3_file *pFile){
++  return SQLITE_IOCAP_ATOMIC | 
++         SQLITE_IOCAP_POWERSAFE_OVERWRITE |
++         SQLITE_IOCAP_SAFE_APPEND |
++         SQLITE_IOCAP_SEQUENTIAL;
++}
++
++/* Fetch a page of a memory-mapped file */
++static int memdbFetch(
++  sqlite3_file *pFile,
++  sqlite3_int64 iOfst,
++  int iAmt,
++  void **pp
++){
++  MemFile *p = (MemFile *)pFile;
++  p->nMmap++;
++  *pp = (void*)(p->aData + iOfst);
++  return SQLITE_OK;
++}
++
++/* Release a memory-mapped page */
++static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
++  MemFile *p = (MemFile *)pFile;
++  p->nMmap--;
++  return SQLITE_OK;
++}
++
++/*
++** Open an mem file handle.
++*/
++static int memdbOpen(
++  sqlite3_vfs *pVfs,
++  const char *zName,
++  sqlite3_file *pFile,
++  int flags,
++  int *pOutFlags
++){
++  MemFile *p = (MemFile*)pFile;
++  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
++    return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags);
++  }
++  memset(p, 0, sizeof(*p));
++  p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
++  assert( pOutFlags!=0 );  /* True because flags==SQLITE_OPEN_MAIN_DB */
++  *pOutFlags = flags | SQLITE_OPEN_MEMORY;
++  p->base.pMethods = &memdb_io_methods;
++  return SQLITE_OK;
++}
++
++#if 0 /* Only used to delete rollback journals, master journals, and WAL
++      ** files, none of which exist in memdb.  So this routine is never used */
++/*
++** Delete the file located at zPath. If the dirSync argument is true,
++** ensure the file-system modifications are synced to disk before
++** returning.
++*/
++static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
++  return SQLITE_IOERR_DELETE;
++}
++#endif
++
++/*
++** Test for access permissions. Return true if the requested permission
++** is available, or false otherwise.
++**
++** With memdb, no files ever exist on disk.  So always return false.
++*/
++static int memdbAccess(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int flags, 
++  int *pResOut
++){
++  *pResOut = 0;
++  return SQLITE_OK;
++}
++
++/*
++** Populate buffer zOut with the full canonical pathname corresponding
++** to the pathname in zPath. zOut is guaranteed to point to a buffer
++** of at least (INST_MAX_PATHNAME+1) bytes.
++*/
++static int memdbFullPathname(
++  sqlite3_vfs *pVfs, 
++  const char *zPath, 
++  int nOut, 
++  char *zOut
++){
++  sqlite3_snprintf(nOut, zOut, "%s", zPath);
++  return SQLITE_OK;
++}
++
++/*
++** Open the dynamic library located at zPath and return a handle.
++*/
++static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){
++  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
++}
++
++/*
++** Populate the buffer zErrMsg (size nByte bytes) with a human readable
++** utf-8 string describing the most recent error encountered associated 
++** with dynamic libraries.
++*/
++static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
++  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
++}
++
++/*
++** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
++*/
++static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
++  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
++}
++
++/*
++** Close the dynamic library handle pHandle.
++*/
++static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){
++  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
++}
++
++/*
++** Populate the buffer pointed to by zBufOut with nByte bytes of 
++** random data.
++*/
++static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
++  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
++}
++
++/*
++** Sleep for nMicro microseconds. Return the number of microseconds 
++** actually slept.
++*/
++static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){
++  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
++}
++
++#if 0  /* Never used.  Modern cores only call xCurrentTimeInt64() */
++/*
++** Return the current time as a Julian Day number in *pTimeOut.
++*/
++static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
++  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
++}
++#endif
++
++static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){
++  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
++}
++static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
++  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
++}
++
++/*
++** Translate a database connection pointer and schema name into a
++** MemFile pointer.
++*/
++static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
++  MemFile *p = 0;
++  int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p);
++  if( rc ) return 0;
++  if( p->base.pMethods!=&memdb_io_methods ) return 0;
++  return p;
++}
++
++/*
++** Return the serialization of a database
++*/
++SQLITE_API unsigned char *sqlite3_serialize(
++  sqlite3 *db,              /* The database connection */
++  const char *zSchema,      /* Which database within the connection */
++  sqlite3_int64 *piSize,    /* Write size here, if not NULL */
++  unsigned int mFlags       /* Maybe SQLITE_SERIALIZE_NOCOPY */
++){
++  MemFile *p;
++  int iDb;
++  Btree *pBt;
++  sqlite3_int64 sz;
++  int szPage = 0;
++  sqlite3_stmt *pStmt = 0;
++  unsigned char *pOut;
++  char *zSql;
++  int rc;
++
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++
++  if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
++  p = memdbFromDbSchema(db, zSchema);
++  iDb = sqlite3FindDbName(db, zSchema);
++  if( piSize ) *piSize = -1;
++  if( iDb<0 ) return 0;
++  if( p ){
++    if( piSize ) *piSize = p->sz;
++    if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
++      pOut = p->aData;
++    }else{
++      pOut = sqlite3_malloc64( p->sz );
++      if( pOut ) memcpy(pOut, p->aData, p->sz);
++    }
++    return pOut;
++  }
++  pBt = db->aDb[iDb].pBt;
++  if( pBt==0 ) return 0;
++  szPage = sqlite3BtreeGetPageSize(pBt);
++  zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
++  rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
++  sqlite3_free(zSql);
++  if( rc ) return 0;
++  rc = sqlite3_step(pStmt);
++  if( rc!=SQLITE_ROW ){
++    pOut = 0;
++  }else{
++    sz = sqlite3_column_int64(pStmt, 0)*szPage;
++    if( piSize ) *piSize = sz;
++    if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
++      pOut = 0;
++    }else{
++      pOut = sqlite3_malloc64( sz );
++      if( pOut ){
++        int nPage = sqlite3_column_int(pStmt, 0);
++        Pager *pPager = sqlite3BtreePager(pBt);
++        int pgno;
++        for(pgno=1; pgno<=nPage; pgno++){
++          DbPage *pPage = 0;
++          unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
++          rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
++          if( rc==SQLITE_OK ){
++            memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
++          }else{
++            memset(pTo, 0, szPage);
++          }
++          sqlite3PagerUnref(pPage);       
++        }
++      }
++    }
++  }
++  sqlite3_finalize(pStmt);
++  return pOut;
++}
++
++/* Convert zSchema to a MemDB and initialize its content.
++*/
++SQLITE_API int sqlite3_deserialize(
++  sqlite3 *db,            /* The database connection */
++  const char *zSchema,    /* Which DB to reopen with the deserialization */
++  unsigned char *pData,   /* The serialized database content */
++  sqlite3_int64 szDb,     /* Number bytes in the deserialization */
++  sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
++  unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
++){
++  MemFile *p;
++  char *zSql;
++  sqlite3_stmt *pStmt = 0;
++  int rc;
++  int iDb;
++
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) ){
++    return SQLITE_MISUSE_BKPT;
++  }
++  if( szDb<0 ) return SQLITE_MISUSE_BKPT;
++  if( szBuf<0 ) return SQLITE_MISUSE_BKPT;
++#endif
++
++  sqlite3_mutex_enter(db->mutex);
++  if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
++  iDb = sqlite3FindDbName(db, zSchema);
++  if( iDb<0 ){
++    rc = SQLITE_ERROR;
++    goto end_deserialize;
++  }    
++  zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
++  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
++  sqlite3_free(zSql);
++  if( rc ) goto end_deserialize;
++  db->init.iDb = (u8)iDb;
++  db->init.reopenMemdb = 1;
++  rc = sqlite3_step(pStmt);
++  db->init.reopenMemdb = 0;
++  if( rc!=SQLITE_DONE ){
++    rc = SQLITE_ERROR;
++    goto end_deserialize;
++  }
++  p = memdbFromDbSchema(db, zSchema);
++  if( p==0 ){
++    rc = SQLITE_ERROR;
++  }else{
++    p->aData = pData;
++    p->sz = szDb;
++    p->szMax = szBuf;
++    p->mFlags = mFlags;
++    rc = SQLITE_OK;
++  }
++
++end_deserialize:
++  sqlite3_finalize(pStmt);
++  sqlite3_mutex_leave(db->mutex);
++  return rc;
++}
++
++/* 
++** This routine is called when the extension is loaded.
++** Register the new VFS.
++*/
++SQLITE_PRIVATE int sqlite3MemdbInit(void){
++  sqlite3_vfs *pLower = sqlite3_vfs_find(0);
++  int sz = pLower->szOsFile;
++  memdb_vfs.pAppData = pLower;
++  /* In all known configurations of SQLite, the size of a default
++  ** sqlite3_file is greater than the size of a memdb sqlite3_file.
++  ** Should that ever change, remove the following NEVER() */
++  if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
++  memdb_vfs.szOsFile = sz;
++  return sqlite3_vfs_register(&memdb_vfs, 0);
++}
++#endif /* SQLITE_ENABLE_DESERIALIZE */
++
++/************** End of memdb.c ***********************************************/
+ /************** Begin file bitvec.c ******************************************/
+ /*
+ ** 2008 February 16
+@@ -44689,7 +47581,7 @@
+ **   The PCache.pSynced variable is used to optimize searching for a dirty
+ **   page to eject from the cache mid-transaction. It is better to eject
+ **   a page that does not require a journal sync than one that does. 
+-**   Therefore, pSynced is maintained to that it *almost* always points
++**   Therefore, pSynced is maintained so that it *almost* always points
+ **   to either the oldest page in the pDirty/pDirtyTail list that has a
+ **   clear PGHDR_NEED_SYNC flag or to a page that is older than this one
+ **   (so that the right page to eject can be found by following pDirtyPrev
+@@ -44848,12 +47740,9 @@
+         p->eCreate = 2;
+       }
+     }
+-    pPage->pDirtyNext = 0;
+-    pPage->pDirtyPrev = 0;
+   }
+   if( addRemove & PCACHE_DIRTYLIST_ADD ){
+-    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
+-  
++    pPage->pDirtyPrev = 0;
+     pPage->pDirtyNext = p->pDirty;
+     if( pPage->pDirtyNext ){
+       assert( pPage->pDirtyNext->pDirtyPrev==0 );
+@@ -45091,7 +47980,7 @@
+       sqlite3_log(SQLITE_FULL, 
+                   "spill page %d making room for %d - cache used: %d/%d",
+                   pPg->pgno, pgno,
+-                  sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
++                  sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache),
+                 numberOfCachePages(pCache));
+ #endif
+       pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno));
+@@ -45170,11 +48059,7 @@
+   if( (--p->nRef)==0 ){
+     if( p->flags&PGHDR_CLEAN ){
+       pcacheUnpin(p);
+-    }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/
+-      /* Move the page to the head of the dirty list. If p->pDirtyPrev==0,
+-      ** then page p is already at the head of the dirty list and the
+-      ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE
+-      ** tag above.  */
++    }else{
+       pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
+     }
+   }
+@@ -45230,16 +48115,15 @@
+ */
+ SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
+   assert( sqlite3PcachePageSanity(p) );
+-  if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){
+-    assert( (p->flags & PGHDR_CLEAN)==0 );
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+-    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+-    p->flags |= PGHDR_CLEAN;
+-    pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
+-    assert( sqlite3PcachePageSanity(p) );
+-    if( p->nRef==0 ){
+-      pcacheUnpin(p);
+-    }
++  assert( (p->flags & PGHDR_DIRTY)!=0 );
++  assert( (p->flags & PGHDR_CLEAN)==0 );
++  pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
++  p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
++  p->flags |= PGHDR_CLEAN;
++  pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
++  assert( sqlite3PcachePageSanity(p) );
++  if( p->nRef==0 ){
++    pcacheUnpin(p);
+   }
+ }
+ 
+@@ -45521,6 +48405,15 @@
+   return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
+ }
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++/* 
++** Return true if there are one or more dirty pages in the cache. Else false.
++*/
++SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
++  return (pCache->pDirty!=0);
++}
++#endif
++
+ #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
+ /*
+ ** For all dirty pages currently in the cache, invoke the specified
+@@ -45635,7 +48528,6 @@
+ struct PgHdr1 {
+   sqlite3_pcache_page page;      /* Base class. Must be first. pBuf & pExtra */
+   unsigned int iKey;             /* Key value (page number) */
+-  u8 isPinned;                   /* Page in use, not on the LRU list */
+   u8 isBulkLocal;                /* This page from bulk local storage */
+   u8 isAnchor;                   /* This is the PGroup.lru element */
+   PgHdr1 *pNext;                 /* Next in hash table chain */
+@@ -45644,6 +48536,13 @@
+   PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
+ };
+ 
++/*
++** A page is pinned if it is not on the LRU list.  To be "pinned" means
++** that the page is in active use and must not be deallocated.
++*/
++#define PAGE_IS_PINNED(p)    ((p)->pLruNext==0)
++#define PAGE_IS_UNPINNED(p)  ((p)->pLruNext!=0)
++
+ /* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
+ ** of one or more PCaches that are able to recycle each other's unpinned
+ ** pages when they are under memory pressure.  A PGroup is an instance of
+@@ -45671,7 +48570,7 @@
+   unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
+   unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
+   unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
+-  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
++  unsigned int nPurgeable;       /* Number of purgeable pages allocated */
+   PgHdr1 lru;                    /* The beginning and end of the LRU list */
+ };
+ 
+@@ -45685,11 +48584,13 @@
+ */
+ struct PCache1 {
+   /* Cache configuration parameters. Page size (szPage) and the purgeable
+-  ** flag (bPurgeable) are set when the cache is created. nMax may be 
++  ** flag (bPurgeable) and the pnPurgeable pointer are all set when the
++  ** cache is created and are never changed thereafter. nMax may be 
+   ** modified at any time by a call to the pcache1Cachesize() method.
+   ** The PGroup mutex must be held when accessing nMax.
+   */
+   PGroup *pGroup;                     /* PGroup this cache belongs to */
++  unsigned int *pnPurgeable;          /* Pointer to pGroup->nPurgeable */
+   int szPage;                         /* Size of database content section */
+   int szExtra;                        /* sizeof(MemPage)+sizeof(PgHdr) */
+   int szAlloc;                        /* Total size of one pcache line */
+@@ -45784,6 +48685,7 @@
+   if( pcache1.isInit ){
+     PgFreeslot *p;
+     if( pBuf==0 ) sz = n = 0;
++    if( n==0 ) sz = 0;
+     sz = ROUNDDOWN8(sz);
+     pcache1.szSlot = sz;
+     pcache1.nSlot = pcache1.nFreeSlot = n;
+@@ -45976,9 +48878,7 @@
+     p->isBulkLocal = 0;
+     p->isAnchor = 0;
+   }
+-  if( pCache->bPurgeable ){
+-    pCache->pGroup->nCurrentPage++;
+-  }
++  (*pCache->pnPurgeable)++;
+   return p;
+ }
+ 
+@@ -45999,9 +48899,7 @@
+     sqlite3_free(p);
+ #endif
+   }
+-  if( pCache->bPurgeable ){
+-    pCache->pGroup->nCurrentPage--;
+-  }
++  (*pCache->pnPurgeable)--;
+ }
+ 
+ /*
+@@ -46096,22 +48994,18 @@
+ ** The PGroup mutex must be held when this function is called.
+ */
+ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
+-  PCache1 *pCache;
+-
+   assert( pPage!=0 );
+-  assert( pPage->isPinned==0 );
+-  pCache = pPage->pCache;
++  assert( PAGE_IS_UNPINNED(pPage) );
+   assert( pPage->pLruNext );
+   assert( pPage->pLruPrev );
+-  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
++  assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) );
+   pPage->pLruPrev->pLruNext = pPage->pLruNext;
+   pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+   pPage->pLruNext = 0;
+   pPage->pLruPrev = 0;
+-  pPage->isPinned = 1;
+   assert( pPage->isAnchor==0 );
+-  assert( pCache->pGroup->lru.isAnchor==1 );
+-  pCache->nRecyclable--;
++  assert( pPage->pCache->pGroup->lru.isAnchor==1 );
++  pPage->pCache->nRecyclable--;
+   return pPage;
+ }
+ 
+@@ -46145,11 +49039,11 @@
+   PGroup *pGroup = pCache->pGroup;
+   PgHdr1 *p;
+   assert( sqlite3_mutex_held(pGroup->mutex) );
+-  while( pGroup->nCurrentPage>pGroup->nMaxPage
++  while( pGroup->nPurgeable>pGroup->nMaxPage
+       && (p=pGroup->lru.pLruPrev)->isAnchor==0
+   ){
+     assert( p->pCache->pGroup==pGroup );
+-    assert( p->isPinned==0 );
++    assert( PAGE_IS_UNPINNED(p) );
+     pcache1PinPage(p);
+     pcache1RemoveFromHash(p, 1);
+   }
+@@ -46198,7 +49092,7 @@
+       if( pPage->iKey>=iLimit ){
+         pCache->nPage--;
+         *pp = pPage->pNext;
+-        if( !pPage->isPinned ) pcache1PinPage(pPage);
++        if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage);
+         pcache1FreePage(pPage);
+       }else{
+         pp = &pPage->pNext;
+@@ -46316,6 +49210,10 @@
+       pCache->nMin = 10;
+       pGroup->nMinPage += pCache->nMin;
+       pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
++      pCache->pnPurgeable = &pGroup->nPurgeable;
++    }else{
++      static unsigned int dummyCurrentPage;
++      pCache->pnPurgeable = &dummyCurrentPage;
+     }
+     pcache1LeaveMutex(pGroup);
+     if( pCache->nHash==0 ){
+@@ -46417,7 +49315,7 @@
+   ){
+     PCache1 *pOther;
+     pPage = pGroup->lru.pLruPrev;
+-    assert( pPage->isPinned==0 );
++    assert( PAGE_IS_UNPINNED(pPage) );
+     pcache1RemoveFromHash(pPage, 0);
+     pcache1PinPage(pPage);
+     pOther = pPage->pCache;
+@@ -46425,7 +49323,7 @@
+       pcache1FreePage(pPage);
+       pPage = 0;
+     }else{
+-      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
++      pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable);
+     }
+   }
+ 
+@@ -46444,7 +49342,6 @@
+     pPage->pCache = pCache;
+     pPage->pLruPrev = 0;
+     pPage->pLruNext = 0;
+-    pPage->isPinned = 1;
+     *(void **)pPage->page.pExtra = 0;
+     pCache->apHash[h] = pPage;
+     if( iKey>pCache->iMaxKey ){
+@@ -46530,7 +49427,7 @@
+   ** Otherwise (page not in hash and createFlag!=0) continue with
+   ** subsequent steps to try to create the page. */
+   if( pPage ){
+-    if( !pPage->isPinned ){
++    if( PAGE_IS_UNPINNED(pPage) ){
+       return pcache1PinPage(pPage);
+     }else{
+       return pPage;
+@@ -46605,9 +49502,9 @@
+   ** part of the PGroup LRU list.
+   */
+   assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+-  assert( pPage->isPinned==1 );
++  assert( PAGE_IS_PINNED(pPage) );
+ 
+-  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
++  if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
+     pcache1RemoveFromHash(pPage, 1);
+   }else{
+     /* Add the page to the PGroup LRU list. */
+@@ -46616,7 +49513,6 @@
+     (pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
+     *ppFirst = pPage;
+     pCache->nRecyclable++;
+-    pPage->isPinned = 0;
+   }
+ 
+   pcache1LeaveMutex(pCache->pGroup);
+@@ -46760,7 +49656,7 @@
+ #ifdef SQLITE_PCACHE_SEPARATE_HEADER
+       nFree += sqlite3MemSize(p);
+ #endif
+-      assert( p->isPinned==0 );
++      assert( PAGE_IS_UNPINNED(p) );
+       pcache1PinPage(p);
+       pcache1RemoveFromHash(p, 1);
+     }
+@@ -46784,10 +49680,10 @@
+   PgHdr1 *p;
+   int nRecyclable = 0;
+   for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
+-    assert( p->isPinned==0 );
++    assert( PAGE_IS_UNPINNED(p) );
+     nRecyclable++;
+   }
+-  *pnCurrent = pcache1.grp.nCurrentPage;
++  *pnCurrent = pcache1.grp.nPurgeable;
+   *pnMax = (int)pcache1.grp.nMaxPage;
+   *pnMin = (int)pcache1.grp.nMinPage;
+   *pnRecyclable = nRecyclable;
+@@ -46922,30 +49818,23 @@
+ #define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
+ 
+ /*
+-** Turn bulk memory into a RowSet object.  N bytes of memory
+-** are available at pSpace.  The db pointer is used as a memory context
+-** for any subsequent allocations that need to occur.
+-** Return a pointer to the new RowSet object.
+-**
+-** It must be the case that N is sufficient to make a Rowset.  If not
+-** an assertion fault occurs.
+-** 
+-** If N is larger than the minimum, use the surplus as an initial
+-** allocation of entries available to be filled.
++** Allocate a RowSet object.  Return NULL if a memory allocation
++** error occurs.
+ */
+-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
+-  RowSet *p;
+-  assert( N >= ROUND8(sizeof(*p)) );
+-  p = pSpace;
+-  p->pChunk = 0;
+-  p->db = db;
+-  p->pEntry = 0;
+-  p->pLast = 0;
+-  p->pForest = 0;
+-  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+-  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
+-  p->rsFlags = ROWSET_SORTED;
+-  p->iBatch = 0;
++SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){
++  RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p));
++  if( p ){
++    int N = sqlite3DbMallocSize(db, p);
++    p->pChunk = 0;
++    p->db = db;
++    p->pEntry = 0;
++    p->pLast = 0;
++    p->pForest = 0;
++    p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
++    p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
++    p->rsFlags = ROWSET_SORTED;
++    p->iBatch = 0;
++  }
+   return p;
+ }
+ 
+@@ -46954,7 +49843,8 @@
+ ** the RowSet has allocated over its lifetime.  This routine is
+ ** the destructor for the RowSet.
+ */
+-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
++SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){
++  RowSet *p = (RowSet*)pArg;
+   struct RowSetChunk *pChunk, *pNextChunk;
+   for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
+     pNextChunk = pChunk->pNextChunk;
+@@ -46969,6 +49859,16 @@
+ }
+ 
+ /*
++** Deallocate all chunks from a RowSet.  This frees all memory that
++** the RowSet has allocated over its lifetime.  This routine is
++** the destructor for the RowSet.
++*/
++SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){
++  sqlite3RowSetClear(pArg);
++  sqlite3DbFree(((RowSet*)pArg)->db, pArg);
++}
++
++/*
+ ** Allocate a new RowSetEntry object that is associated with the
+ ** given RowSet.  Return a pointer to the new and completely uninitialized
+ ** objected.
+@@ -47342,11 +50242,11 @@
+ 
+ /* #include "sqliteInt.h" */
+ 
+-/* Additional values that can be added to the sync_flags argument of
+-** sqlite3WalFrames():
++/* Macros for extracting appropriate sync flags for either transaction
++** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)):
+ */
+-#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
+-#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
++#define WAL_SYNC_FLAGS(X)   ((X)&0x03)
++#define CKPT_SYNC_FLAGS(X)  (((X)>>2)&0x03)
+ 
+ #ifdef SQLITE_OMIT_WAL
+ # define sqlite3WalOpen(x,y,z)                   0
+@@ -47455,6 +50355,8 @@
+ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
+ SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
+ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
++SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal);
+ #endif
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -47579,8 +50481,8 @@
+ ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
+ ** struct as its argument.
+ */
+-#define PAGERID(p) ((int)(p->fd))
+-#define FILEHANDLEID(fd) ((int)fd)
++#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd))
++#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd))
+ 
+ /*
+ ** The Pager.eState variable stores the current 'state' of a pager. A
+@@ -48067,6 +50969,18 @@
+ **   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
+ **   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
+ **   sub-codes.
++**
++** syncFlags, walSyncFlags
++**
++**   syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03).
++**   syncFlags is used for rollback mode.  walSyncFlags is used for WAL mode
++**   and contains the flags used to sync the checkpoint operations in the
++**   lower two bits, and sync flags used for transaction commits in the WAL
++**   file in bits 0x04 and 0x08.  In other words, to get the correct sync flags
++**   for checkpoint operations, use (walSyncFlags&0x03) and to get the correct
++**   sync flags for transaction commit, use ((walSyncFlags>>2)&0x03).  Note
++**   that with synchronous=NORMAL in WAL mode, transaction commit is not synced
++**   meaning that the 0x04 and 0x08 bits are both zero.
+ */
+ struct Pager {
+   sqlite3_vfs *pVfs;          /* OS functions to use for IO */
+@@ -48076,9 +50990,8 @@
+   u8 noSync;                  /* Do not sync the journal if true */
+   u8 fullSync;                /* Do extra syncs of the journal for robustness */
+   u8 extraSync;               /* sync directory after journal delete */
+-  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
+-  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
+   u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
++  u8 walSyncFlags;            /* See description above */
+   u8 tempFile;                /* zFilename is a temporary or immutable file */
+   u8 noLock;                  /* Do not lock (except in WAL mode) */
+   u8 readOnly;                /* True for a read-only database */
+@@ -48139,7 +51052,7 @@
+   char *zJournal;             /* Name of the journal file */
+   int (*xBusyHandler)(void*); /* Function to call when busy */
+   void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
+-  int aStat[3];               /* Total cache hits, misses and writes */
++  int aStat[4];               /* Total cache hits, misses, writes, spills */
+ #ifdef SQLITE_TEST
+   int nRead;                  /* Database pages read */
+ #endif
+@@ -48167,6 +51080,7 @@
+ #define PAGER_STAT_HIT   0
+ #define PAGER_STAT_MISS  1
+ #define PAGER_STAT_WRITE 2
++#define PAGER_STAT_SPILL 3
+ 
+ /*
+ ** The following global variables hold counters used for
+@@ -48264,19 +51178,30 @@
+ */
+ #define isOpen(pFd) ((pFd)->pMethods!=0)
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
+ /*
+-** Return true if this pager uses a write-ahead log to read page pgno.
+-** Return false if the pager reads pgno directly from the database.
++** Return true if page pgno can be read directly from the database file
++** by the b-tree layer. This is the case if:
++**
++**   * the database file is open,
++**   * there are no dirty pages in the cache, and
++**   * the desired page is not currently in the wal file.
+ */
+-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
+-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
+-  u32 iRead = 0;
+-  int rc;
+-  if( pPager->pWal==0 ) return 0;
+-  rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+-  return rc || iRead;
++SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
++  if( pPager->fd->pMethods==0 ) return 0;
++  if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
++#ifndef SQLITE_OMIT_WAL
++  if( pPager->pWal ){
++    u32 iRead = 0;
++    int rc;
++    rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
++    return (rc==SQLITE_OK && iRead==0);
++  }
++#endif
++  return 1;
+ }
+ #endif
++
+ #ifndef SQLITE_OMIT_WAL
+ # define pagerUseWal(x) ((x)->pWal!=0)
+ #else
+@@ -48398,6 +51323,7 @@
+       assert( isOpen(p->jfd) 
+            || p->journalMode==PAGER_JOURNALMODE_OFF 
+            || p->journalMode==PAGER_JOURNALMODE_WAL 
++           || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+       );
+       assert( pPager->dbOrigSize<=pPager->dbHintSize );
+       break;
+@@ -48409,6 +51335,7 @@
+       assert( isOpen(p->jfd) 
+            || p->journalMode==PAGER_JOURNALMODE_OFF 
+            || p->journalMode==PAGER_JOURNALMODE_WAL 
++           || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+       );
+       break;
+ 
+@@ -48434,8 +51361,12 @@
+ ** to "print *pPager" in gdb:
+ **
+ ** (gdb) printf "%s", print_pager_state(pPager)
++**
++** This routine has external linkage in order to suppress compiler warnings
++** about an unused function.  It is enclosed within SQLITE_DEBUG and so does
++** not appear in normal builds.
+ */
+-static char *print_pager_state(Pager *p){
++char *print_pager_state(Pager *p){
+   static char zRet[1024];
+ 
+   sqlite3_snprintf(1024, zRet,
+@@ -48619,8 +51550,9 @@
+ }
+ 
+ /*
+-** This function determines whether or not the atomic-write optimization
+-** can be used with this pager. The optimization can be used if:
++** This function determines whether or not the atomic-write or
++** atomic-batch-write optimizations can be used with this pager. The
++** atomic-write optimization can be used if:
+ **
+ **  (a) the value returned by OsDeviceCharacteristics() indicates that
+ **      a database page may be written atomically, and
+@@ -48627,27 +51559,39 @@
+ **  (b) the value returned by OsSectorSize() is less than or equal
+ **      to the page size.
+ **
+-** The optimization is also always enabled for temporary files. It is
+-** an error to call this function if pPager is opened on an in-memory
+-** database.
++** If it can be used, then the value returned is the size of the journal 
++** file when it contains rollback data for exactly one page.
+ **
+-** If the optimization cannot be used, 0 is returned. If it can be used,
+-** then the value returned is the size of the journal file when it
+-** contains rollback data for exactly one page.
++** The atomic-batch-write optimization can be used if OsDeviceCharacteristics()
++** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is
++** returned in this case.
++**
++** If neither optimization can be used, 0 is returned.
+ */
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ static int jrnlBufferSize(Pager *pPager){
+   assert( !MEMDB );
+-  if( !pPager->tempFile ){
+-    int dc;                           /* Device characteristics */
+-    int nSector;                      /* Sector size */
+-    int szPage;                       /* Page size */
+ 
+-    assert( isOpen(pPager->fd) );
+-    dc = sqlite3OsDeviceCharacteristics(pPager->fd);
+-    nSector = pPager->sectorSize;
+-    szPage = pPager->pageSize;
++#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
++ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++  int dc;                           /* Device characteristics */
+ 
++  assert( isOpen(pPager->fd) );
++  dc = sqlite3OsDeviceCharacteristics(pPager->fd);
++#else
++  UNUSED_PARAMETER(pPager);
++#endif
++
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++  if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){
++    return -1;
++  }
++#endif
++
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++  {
++    int nSector = pPager->sectorSize;
++    int szPage = pPager->pageSize;
++
+     assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
+     assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
+     if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
+@@ -48656,11 +51600,11 @@
+   }
+ 
+   return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
+-}
+-#else
+-# define jrnlBufferSize(x) 0
+ #endif
+ 
++  return 0;
++}
++
+ /*
+ ** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
+ ** on the cache using a hash function.  This is used for testing
+@@ -48742,6 +51686,7 @@
+    || szJ<16
+    || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
+    || len>=nMaster 
++   || len>szJ-16
+    || len==0 
+    || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
+    || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
+@@ -49187,7 +52132,6 @@
+ ** Return the pPager->iDataVersion value
+ */
+ SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
+-  assert( pPager->eState>PAGER_OPEN );
+   return pPager->iDataVersion;
+ }
+ 
+@@ -49463,7 +52407,9 @@
+   }
+ 
+   releaseAllSavepoints(pPager);
+-  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
++  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 
++      || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
++  );
+   if( isOpen(pPager->jfd) ){
+     assert( !pagerUseWal(pPager) );
+ 
+@@ -49551,7 +52497,7 @@
+     rc = pager_truncate(pPager, pPager->dbSize);
+   }
+ 
+-  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
++  if( rc==SQLITE_OK && bCommit ){
+     rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
+     if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+   }
+@@ -50231,6 +53177,7 @@
+   char *zMaster = 0;       /* Name of master journal file if any */
+   int needPagerReset;      /* True to reset page prior to first page rollback */
+   int nPlayback = 0;       /* Total number of pages restored from journal */
++  u32 savedPageSize = pPager->pageSize;
+ 
+   /* Figure out how many records are in the journal.  Abort early if
+   ** the journal is empty.
+@@ -50360,6 +53307,9 @@
+   assert( 0 );
+ 
+ end_playback:
++  if( rc==SQLITE_OK ){
++    rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
++  }
+   /* Following a rollback, the database file should be back in its original
+   ** state prior to the start of the transaction, so invoke the
+   ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
+@@ -50366,9 +53316,7 @@
+   ** assertion that the transaction counter was modified.
+   */
+ #ifdef SQLITE_DEBUG
+-  if( pPager->fd->pMethods ){
+-    sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
+-  }
++  sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
+ #endif
+ 
+   /* If this playback is happening automatically as a result of an IO or 
+@@ -50418,7 +53366,8 @@
+ 
+ 
+ /*
+-** Read the content for page pPg out of the database file and into 
++** Read the content for page pPg out of the database file (or out of
++** the WAL if that is where the most recent copy if found) into 
+ ** pPg->pData. A shared lock or greater must be held on the database
+ ** file before this function is called.
+ **
+@@ -50428,30 +53377,33 @@
+ ** If an IO error occurs, then the IO error is returned to the caller.
+ ** Otherwise, SQLITE_OK is returned.
+ */
+-static int readDbPage(PgHdr *pPg, u32 iFrame){
++static int readDbPage(PgHdr *pPg){
+   Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
+-  Pgno pgno = pPg->pgno;       /* Page number to read */
+   int rc = SQLITE_OK;          /* Return code */
+-  int pgsz = pPager->pageSize; /* Number of bytes to read */
+ 
++#ifndef SQLITE_OMIT_WAL
++  u32 iFrame = 0;              /* Frame of WAL containing pgno */
++
+   assert( pPager->eState>=PAGER_READER && !MEMDB );
+   assert( isOpen(pPager->fd) );
+ 
+-#ifndef SQLITE_OMIT_WAL
++  if( pagerUseWal(pPager) ){
++    rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
++    if( rc ) return rc;
++  }
+   if( iFrame ){
+-    /* Try to pull the page from the write-ahead log. */
+-    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
++    rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData);
+   }else
+ #endif
+   {
+-    i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
+-    rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
++    i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize;
++    rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
+     if( rc==SQLITE_IOERR_SHORT_READ ){
+       rc = SQLITE_OK;
+     }
+   }
+ 
+-  if( pgno==1 ){
++  if( pPg->pgno==1 ){
+     if( rc ){
+       /* If the read is unsuccessful, set the dbFileVers[] to something
+       ** that will never be a valid file version.  dbFileVers[] is a copy
+@@ -50471,13 +53423,13 @@
+       memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
+     }
+   }
+-  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
++  CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT);
+ 
+   PAGER_INCR(sqlite3_pager_readdb_count);
+   PAGER_INCR(pPager->nRead);
+-  IOTRACE(("PGIN %p %d\n", pPager, pgno));
++  IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
+   PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
+-               PAGERID(pPager), pgno, pager_pagehash(pPg)));
++               PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
+ 
+   return rc;
+ }
+@@ -50528,12 +53480,8 @@
+     if( sqlite3PcachePageRefcount(pPg)==1 ){
+       sqlite3PcacheDrop(pPg);
+     }else{
+-      u32 iFrame = 0;
+-      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
++      rc = readDbPage(pPg);
+       if( rc==SQLITE_OK ){
+-        rc = readDbPage(pPg, iFrame);
+-      }
+-      if( rc==SQLITE_OK ){
+         pPager->xReiniter(pPg);
+       }
+       sqlite3PagerUnrefNotNull(pPg);
+@@ -51038,21 +53986,18 @@
+   }
+   if( pPager->noSync ){
+     pPager->syncFlags = 0;
+-    pPager->ckptSyncFlags = 0;
+   }else if( pgFlags & PAGER_FULLFSYNC ){
+     pPager->syncFlags = SQLITE_SYNC_FULL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
+-  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
+-    pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
+   }else{
+     pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
+   }
+-  pPager->walSyncFlags = pPager->syncFlags;
++  pPager->walSyncFlags = (pPager->syncFlags<<2);
+   if( pPager->fullSync ){
+-    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
++    pPager->walSyncFlags |= pPager->syncFlags;
+   }
++  if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){
++    pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2);
++  }
+   if( pgFlags & PAGER_CACHESPILL ){
+     pPager->doNotSpill &= ~SPILLFLAG_OFF;
+   }else{
+@@ -51124,20 +54069,18 @@
+ ** retried. If it returns zero, then the SQLITE_BUSY error is
+ ** returned to the caller of the pager API function.
+ */
+-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
++SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(
+   Pager *pPager,                       /* Pager object */
+   int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
+   void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
+ ){
++  void **ap;
+   pPager->xBusyHandler = xBusyHandler;
+   pPager->pBusyHandlerArg = pBusyHandlerArg;
+-
+-  if( isOpen(pPager->fd) ){
+-    void **ap = (void **)&pPager->xBusyHandler;
+-    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
+-    assert( ap[1]==pBusyHandlerArg );
+-    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
+-  }
++  ap = (void **)&pPager->xBusyHandler;
++  assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
++  assert( ap[1]==pBusyHandlerArg );
++  sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
+ }
+ 
+ /*
+@@ -51523,7 +54466,31 @@
+   }
+ }
+ 
++/* Verify that the database file has not be deleted or renamed out from
++** under the pager.  Return SQLITE_OK if the database is still where it ought
++** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
++** code from sqlite3OsAccess()) if the database has gone missing.
++*/
++static int databaseIsUnmoved(Pager *pPager){
++  int bHasMoved = 0;
++  int rc;
+ 
++  if( pPager->tempFile ) return SQLITE_OK;
++  if( pPager->dbSize==0 ) return SQLITE_OK;
++  assert( pPager->zFilename && pPager->zFilename[0] );
++  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
++  if( rc==SQLITE_NOTFOUND ){
++    /* If the HAS_MOVED file-control is unimplemented, assume that the file
++    ** has not been moved.  That is the historical behavior of SQLite: prior to
++    ** version 3.8.3, it never checked */
++    rc = SQLITE_OK;
++  }else if( rc==SQLITE_OK && bHasMoved ){
++    rc = SQLITE_READONLY_DBMOVED;
++  }
++  return rc;
++}
++
++
+ /*
+ ** Shutdown the page cache.  Free all memory and close all files.
+ **
+@@ -51539,8 +54506,7 @@
+ ** to the caller.
+ */
+ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
+-  u8 *pTmp = (u8 *)pPager->pTmpSpace;
+-
++  u8 *pTmp = (u8*)pPager->pTmpSpace;
+   assert( db || pagerUseWal(pPager)==0 );
+   assert( assert_pager_state(pPager) );
+   disable_simulated_io_errors();
+@@ -51549,11 +54515,17 @@
+   /* pPager->errCode = 0; */
+   pPager->exclusiveMode = 0;
+ #ifndef SQLITE_OMIT_WAL
+-  assert( db || pPager->pWal==0 );
+-  sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize,
+-      (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
+-  );
+-  pPager->pWal = 0;
++  {
++    u8 *a = 0;
++    assert( db || pPager->pWal==0 );
++    if( db && 0==(db->flags & SQLITE_NoCkptOnClose) 
++     && SQLITE_OK==databaseIsUnmoved(pPager)
++    ){
++      a = pTmp;
++    }
++    sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
++    pPager->pWal = 0;
++  }
+ #endif
+   pager_reset(pPager);
+   if( MEMDB ){
+@@ -52010,6 +54982,7 @@
+     return SQLITE_OK;
+   }
+ 
++  pPager->aStat[PAGER_STAT_SPILL]++;
+   pPg->pDirty = 0;
+   if( pagerUseWal(pPager) ){
+     /* Write a single frame for this page to the log. */
+@@ -52018,6 +54991,13 @@
+       rc = pagerWalFrames(pPager, pPg, 0, 0);
+     }
+   }else{
++    
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++    if( pPager->tempFile==0 ){
++      rc = sqlite3JournalCreate(pPager->jfd);
++      if( rc!=SQLITE_OK ) return pager_error(pPager, rc);
++    }
++#endif
+   
+     /* Sync the journal file if required. */
+     if( pPg->flags&PGHDR_NEED_SYNC 
+@@ -52108,6 +55088,11 @@
+   int rc = SQLITE_OK;      /* Return code */
+   int tempFile = 0;        /* True for temp files (incl. in-memory files) */
+   int memDb = 0;           /* True if this is an in-memory file */
++#ifdef SQLITE_ENABLE_DESERIALIZE
++  int memJM = 0;           /* Memory journal mode */
++#else
++# define memJM 0
++#endif
+   int readOnly = 0;        /* True if this is a read-only file */
+   int journalFileSize;     /* Bytes to allocate for each journal fd */
+   char *zPathname = 0;     /* Full path to database file */
+@@ -52235,7 +55220,10 @@
+     int fout = 0;                    /* VFS flags returned by xOpen() */
+     rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
+     assert( !memDb );
+-    readOnly = (fout&SQLITE_OPEN_READONLY);
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
++#endif
++    readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
+ 
+     /* If the file was successfully opened for read/write access,
+     ** choose a default page size in case we have to create the
+@@ -52351,13 +55339,11 @@
+     assert( pPager->extraSync==0 );
+     assert( pPager->syncFlags==0 );
+     assert( pPager->walSyncFlags==0 );
+-    assert( pPager->ckptSyncFlags==0 );
+   }else{
+     pPager->fullSync = 1;
+     pPager->extraSync = 0;
+     pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
++    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
+   }
+   /* pPager->pFirst = 0; */
+   /* pPager->pFirstSynced = 0; */
+@@ -52368,7 +55354,7 @@
+   setSectorSize(pPager);
+   if( !useJournal ){
+     pPager->journalMode = PAGER_JOURNALMODE_OFF;
+-  }else if( memDb ){
++  }else if( memDb || memJM ){
+     pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
+   }
+   /* pPager->xBusyHandler = 0; */
+@@ -52383,31 +55369,7 @@
+ }
+ 
+ 
+-/* Verify that the database file has not be deleted or renamed out from
+-** under the pager.  Return SQLITE_OK if the database is still were it ought
+-** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
+-** code from sqlite3OsAccess()) if the database has gone missing.
+-*/
+-static int databaseIsUnmoved(Pager *pPager){
+-  int bHasMoved = 0;
+-  int rc;
+ 
+-  if( pPager->tempFile ) return SQLITE_OK;
+-  if( pPager->dbSize==0 ) return SQLITE_OK;
+-  assert( pPager->zFilename && pPager->zFilename[0] );
+-  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+-  if( rc==SQLITE_NOTFOUND ){
+-    /* If the HAS_MOVED file-control is unimplemented, assume that the file
+-    ** has not been moved.  That is the historical behavior of SQLite: prior to
+-    ** version 3.8.3, it never checked */
+-    rc = SQLITE_OK;
+-  }else if( rc==SQLITE_OK && bHasMoved ){
+-    rc = SQLITE_READONLY_DBMOVED;
+-  }
+-  return rc;
+-}
+-
+-
+ /*
+ ** This function is called after transitioning from PAGER_UNLOCK to
+ ** PAGER_SHARED state. It tests if there is a hot journal present in
+@@ -52777,7 +55739,8 @@
+ ** nothing to rollback, so this routine is a no-op.
+ */ 
+ static void pagerUnlockIfUnused(Pager *pPager){
+-  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
++  if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
++    assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
+     pagerUnlockAndRollback(pPager);
+   }
+ }
+@@ -52918,14 +55881,9 @@
+       memset(pPg->pData, 0, pPager->pageSize);
+       IOTRACE(("ZERO %p %d\n", pPager, pgno));
+     }else{
+-      u32 iFrame = 0;                 /* Frame to read from WAL file */
+-      if( pagerUseWal(pPager) ){
+-        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+-        if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-      }
+       assert( pPg->pPager==pPager );
+       pPager->aStat[PAGER_STAT_MISS]++;
+-      rc = readDbPage(pPg, iFrame);
++      rc = readDbPage(pPg);
+       if( rc!=SQLITE_OK ){
+         goto pager_acquire_err;
+       }
+@@ -52999,7 +55957,7 @@
+       }
+       if( pPg==0 ){
+         rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+-     }else{
++      }else{
+         sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+       }
+       if( pPg ){
+@@ -53068,25 +56026,40 @@
+ /*
+ ** Release a page reference.
+ **
+-** If the number of references to the page drop to zero, then the
+-** page is added to the LRU list.  When all references to all pages
+-** are released, a rollback occurs and the lock on the database is
+-** removed.
++** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
++** used if we know that the page being released is not the last page.
++** The btree layer always holds page1 open until the end, so these first
++** to routines can be used to release any page other than BtShared.pPage1.
++**
++** Use sqlite3PagerUnrefPageOne() to release page1.  This latter routine
++** checks the total number of outstanding pages and if the number of
++** pages reaches zero it drops the database lock.
+ */
+ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
+-  Pager *pPager;
++  TESTONLY( Pager *pPager = pPg->pPager; )
+   assert( pPg!=0 );
+-  pPager = pPg->pPager;
+   if( pPg->flags & PGHDR_MMAP ){
++    assert( pPg->pgno!=1 );  /* Page1 is never memory mapped */
+     pagerReleaseMapPage(pPg);
+   }else{
+     sqlite3PcacheRelease(pPg);
+   }
+-  pagerUnlockIfUnused(pPager);
++  /* Do not use this routine to release the last reference to page1 */
++  assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
+ }
+ SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
+   if( pPg ) sqlite3PagerUnrefNotNull(pPg);
+ }
++SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
++  Pager *pPager;
++  assert( pPg!=0 );
++  assert( pPg->pgno==1 );
++  assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
++  pPager = pPg->pPager;
++  sqlite3PagerResetLockTimeout(pPager);
++  sqlite3PcacheRelease(pPg);
++  pagerUnlockIfUnused(pPager);
++}
+ 
+ /*
+ ** This function is called at the start of every write transaction.
+@@ -53679,12 +56652,9 @@
+ */
+ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
+   int rc = SQLITE_OK;
+-
+-  if( isOpen(pPager->fd) ){
+-    void *pArg = (void*)zMaster;
+-    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
+-    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+-  }
++  void *pArg = (void*)zMaster;
++  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
++  if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+   if( rc==SQLITE_OK && !pPager->noSync ){
+     assert( !MEMDB );
+     rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
+@@ -53779,9 +56749,10 @@
+     ** backup in progress needs to be restarted.  */
+     sqlite3BackupRestart(pPager->pBackup);
+   }else{
++    PgHdr *pList;
+     if( pagerUseWal(pPager) ){
+-      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
+       PgHdr *pPageOne = 0;
++      pList = sqlite3PcacheDirtyList(pPager->pPCache);
+       if( pList==0 ){
+         /* Must have at least one page for the WAL commit flag.
+         ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
+@@ -53798,6 +56769,21 @@
+         sqlite3PcacheCleanAll(pPager->pPCache);
+       }
+     }else{
++      /* The bBatch boolean is true if the batch-atomic-write commit method
++      ** should be used.  No rollback journal is created if batch-atomic-write
++      ** is enabled.
++      */
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++      sqlite3_file *fd = pPager->fd;
++      int bBatch = zMaster==0    /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
++        && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
++        && !pPager->noSync
++        && sqlite3JournalIsInMemory(pPager->jfd);
++#else
++#     define bBatch 0
++#endif
++
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+       /* The following block updates the change-counter. Exactly how it
+       ** does this depends on whether or not the atomic-update optimization
+       ** was enabled at compile time, and if this transaction meets the 
+@@ -53821,33 +56807,41 @@
+       ** in 'direct' mode. In this case the journal file will never be
+       ** created for this transaction.
+       */
+-  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-      PgHdr *pPg;
+-      assert( isOpen(pPager->jfd) 
+-           || pPager->journalMode==PAGER_JOURNALMODE_OFF 
+-           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
+-      );
+-      if( !zMaster && isOpen(pPager->jfd) 
+-       && pPager->journalOff==jrnlBufferSize(pPager) 
+-       && pPager->dbSize>=pPager->dbOrigSize
+-       && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
+-      ){
+-        /* Update the db file change counter via the direct-write method. The 
+-        ** following call will modify the in-memory representation of page 1 
+-        ** to include the updated change counter and then write page 1 
+-        ** directly to the database file. Because of the atomic-write 
+-        ** property of the host file-system, this is safe.
+-        */
+-        rc = pager_incr_changecounter(pPager, 1);
+-      }else{
+-        rc = sqlite3JournalCreate(pPager->jfd);
+-        if( rc==SQLITE_OK ){
+-          rc = pager_incr_changecounter(pPager, 0);
++      if( bBatch==0 ){
++        PgHdr *pPg;
++        assert( isOpen(pPager->jfd) 
++            || pPager->journalMode==PAGER_JOURNALMODE_OFF 
++            || pPager->journalMode==PAGER_JOURNALMODE_WAL 
++            );
++        if( !zMaster && isOpen(pPager->jfd) 
++         && pPager->journalOff==jrnlBufferSize(pPager) 
++         && pPager->dbSize>=pPager->dbOrigSize
++         && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
++        ){
++          /* Update the db file change counter via the direct-write method. The 
++          ** following call will modify the in-memory representation of page 1 
++          ** to include the updated change counter and then write page 1 
++          ** directly to the database file. Because of the atomic-write 
++          ** property of the host file-system, this is safe.
++          */
++          rc = pager_incr_changecounter(pPager, 1);
++        }else{
++          rc = sqlite3JournalCreate(pPager->jfd);
++          if( rc==SQLITE_OK ){
++            rc = pager_incr_changecounter(pPager, 0);
++          }
+         }
+       }
+-  #else
++#else  /* SQLITE_ENABLE_ATOMIC_WRITE */
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++      if( zMaster ){
++        rc = sqlite3JournalCreate(pPager->jfd);
++        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++        assert( bBatch==0 );
++      }
++#endif
+       rc = pager_incr_changecounter(pPager, 0);
+-  #endif
++#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */
+       if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+   
+       /* Write the master journal name into the journal file. If a master 
+@@ -53870,8 +56864,37 @@
+       */
+       rc = syncJournal(pPager, 0);
+       if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-  
+-      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
++
++      pList = sqlite3PcacheDirtyList(pPager->pPCache);
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++      if( bBatch ){
++        rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
++        if( rc==SQLITE_OK ){
++          rc = pager_write_pagelist(pPager, pList);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
++          }
++          if( rc!=SQLITE_OK ){
++            sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
++          }
++        }
++
++        if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){
++          rc = sqlite3JournalCreate(pPager->jfd);
++          if( rc!=SQLITE_OK ){
++            sqlite3OsClose(pPager->jfd);
++            goto commit_phase_one_exit;
++          }
++          bBatch = 0;
++        }else{
++          sqlite3OsClose(pPager->jfd);
++        }
++      }
++#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
++
++      if( bBatch==0 ){
++        rc = pager_write_pagelist(pPager, pList);
++      }
+       if( rc!=SQLITE_OK ){
+         assert( rc!=SQLITE_IOERR_BLOCKED );
+         goto commit_phase_one_exit;
+@@ -54092,8 +57115,12 @@
+ #endif
+ 
+ /*
+-** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
+-** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
++** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE,
++** or _WRITE+1.  The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation
++** of SQLITE_DBSTATUS_CACHE_SPILL.  The _SPILL case is not contiguous because
++** it was added later.
++**
++** Before returning, *pnVal is incremented by the
+ ** current cache hit or miss count, according to the value of eStat. If the 
+ ** reset parameter is non-zero, the cache hit or miss count is zeroed before 
+ ** returning.
+@@ -54103,15 +57130,18 @@
+   assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
+        || eStat==SQLITE_DBSTATUS_CACHE_MISS
+        || eStat==SQLITE_DBSTATUS_CACHE_WRITE
++       || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1
+   );
+ 
+   assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
+   assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
+-  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
++  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1
++           && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 );
+ 
+-  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
++  eStat -= SQLITE_DBSTATUS_CACHE_HIT;
++  *pnVal += pPager->aStat[eStat];
+   if( reset ){
+-    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
++    pPager->aStat[eStat] = 0;
+   }
+ }
+ 
+@@ -54315,7 +57345,17 @@
+   return pPager->fd;
+ }
+ 
++#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ /*
++** Reset the lock timeout for pager.
++*/
++SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
++  int x = 0;
++  sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
++}
++#endif
++
++/*
+ ** Return the file handle for the journal file (if it exists).
+ ** This will be either the rollback journal or the WAL file.
+ */
+@@ -54345,7 +57385,11 @@
+   void (*xCodecFree)(void*),
+   void *pCodec
+ ){
+-  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
++  if( pPager->xCodecFree ){
++    pPager->xCodecFree(pPager->pCodec);
++  }else{
++    pager_reset(pPager);
++  }
+   pPager->xCodec = pPager->memDb ? 0 : xCodec;
+   pPager->xCodecSizeChng = xCodecSizeChng;
+   pPager->xCodecFree = xCodecFree;
+@@ -54606,13 +57650,6 @@
+ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
+   u8 eOld = pPager->journalMode;    /* Prior journalmode */
+ 
+-#ifdef SQLITE_DEBUG
+-  /* The print_pager_state() routine is intended to be used by the debugger
+-  ** only.  We invoke it once here to suppress a compiler warning. */
+-  print_pager_state(pPager);
+-#endif
+-
+-
+   /* The eMode parameter is always valid */
+   assert(      eMode==PAGER_JOURNALMODE_DELETE
+             || eMode==PAGER_JOURNALMODE_TRUNCATE
+@@ -54772,9 +57809,10 @@
+     rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
+         (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
+         pPager->pBusyHandlerArg,
+-        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
++        pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
+         pnLog, pnCkpt
+     );
++    sqlite3PagerResetLockTimeout(pPager);
+   }
+   return rc;
+ }
+@@ -54929,7 +57967,7 @@
+   if( rc==SQLITE_OK && pPager->pWal ){
+     rc = pagerExclusiveLock(pPager);
+     if( rc==SQLITE_OK ){
+-      rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
++      rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags,
+                            pPager->pageSize, (u8*)pPager->pTmpSpace);
+       pPager->pWal = 0;
+       pagerFixMaplimit(pPager);
+@@ -54980,6 +58018,38 @@
+   }
+   return rc;
+ }
++
++/*
++** The caller currently has a read transaction open on the database.
++** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise,
++** this function takes a SHARED lock on the CHECKPOINTER slot and then
++** checks if the snapshot passed as the second argument is still 
++** available. If so, SQLITE_OK is returned.
++**
++** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
++** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
++** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
++** lock is released before returning.
++*/
++SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){
++  int rc;
++  if( pPager->pWal ){
++    rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot);
++  }else{
++    rc = SQLITE_ERROR;
++  }
++  return rc;
++}
++
++/*
++** Release a lock obtained by an earlier successful call to
++** sqlite3PagerSnapshotCheck().
++*/
++SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
++  assert( pPager->pWal );
++  return sqlite3WalSnapshotUnlock(pPager->pWal);
++}
++
+ #endif /* SQLITE_ENABLE_SNAPSHOT */
+ #endif /* !SQLITE_OMIT_WAL */
+ 
+@@ -55135,6 +58205,10 @@
+ ** on a network filesystem.  All users of the database must be able to
+ ** share memory.
+ **
++** In the default unix and windows implementation, the wal-index is a mmapped
++** file whose name is the database name with a "-shm" suffix added.  For that
++** reason, the wal-index is sometimes called the "shm" file.
++**
+ ** The wal-index is transient.  After a crash, the wal-index can (and should
+ ** be) reconstructed from the original WAL file.  In fact, the VFS is required
+ ** to either truncate or zero the header of the wal-index when the last
+@@ -55258,6 +58332,18 @@
+ #endif
+ 
+ /*
++** WAL mode depends on atomic aligned 32-bit loads and stores in a few
++** places.  The following macros try to make this explicit.
++*/
++#if GCC_VESRION>=5004000
++# define AtomicLoad(PTR)       __atomic_load_n((PTR),__ATOMIC_RELAXED)
++# define AtomicStore(PTR,VAL)  __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
++#else
++# define AtomicLoad(PTR)       (*(PTR))
++# define AtomicStore(PTR,VAL)  (*(PTR) = (VAL))
++#endif
++
++/*
+ ** The maximum (and only) versions of the wal and wal-index formats
+ ** that may be interpreted by this version of SQLite.
+ **
+@@ -55274,9 +58360,18 @@
+ #define WALINDEX_MAX_VERSION 3007000
+ 
+ /*
+-** Indices of various locking bytes.   WAL_NREADER is the number
++** Index numbers for various locking bytes.   WAL_NREADER is the number
+ ** of available reader locks and should be at least 3.  The default
+ ** is SQLITE_SHM_NLOCK==8 and  WAL_NREADER==5.
++**
++** Technically, the various VFSes are free to implement these locks however
++** they see fit.  However, compatibility is encouraged so that VFSes can
++** interoperate.  The standard implemention used on both unix and windows
++** is for the index number to indicate a byte offset into the
++** WalCkptInfo.aLock[] array in the wal-index header.  In other words, all
++** locks are on the shm file.  The WALINDEX_LOCK_OFFSET constant (which
++** should be 120) is the location in the shm file for the first locking
++** byte.
+ */
+ #define WAL_WRITE_LOCK         0
+ #define WAL_ALL_BUT_WRITE      1
+@@ -55400,7 +58495,6 @@
+ #define WAL_FRAME_HDRSIZE 24
+ 
+ /* Size of write ahead log header, including checksum. */
+-/* #define WAL_HDRSIZE 24 */
+ #define WAL_HDRSIZE 32
+ 
+ /* WAL magic value. Either this value, or the same value with the least
+@@ -55446,6 +58540,7 @@
+   u8 truncateOnCommit;       /* True to truncate WAL file on commit */
+   u8 syncHeader;             /* Fsync the WAL header if true */
+   u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
++  u8 bShmUnreliable;         /* SHM content is read-only and unreliable */
+   WalIndexHdr hdr;           /* Wal-index header for current transaction */
+   u32 minFrame;              /* Ignore wal frames before this one */
+   u32 iReCksum;              /* On commit, recalculate checksums from here */
+@@ -55535,11 +58630,20 @@
+ ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
+ ** numbered from zero.
+ **
++** If the wal-index is currently smaller the iPage pages then the size
++** of the wal-index might be increased, but only if it is safe to do
++** so.  It is safe to enlarge the wal-index if pWal->writeLock is true
++** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
++**
+ ** If this call is successful, *ppPage is set to point to the wal-index
+ ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
+ ** then an SQLite error code is returned and *ppPage is set to 0.
+ */
+-static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
++static SQLITE_NOINLINE int walIndexPageRealloc(
++  Wal *pWal,               /* The WAL context */
++  int iPage,               /* The page we seek */
++  volatile u32 **ppPage    /* Write the page pointer here */
++){
+   int rc = SQLITE_OK;
+ 
+   /* Enlarge the pWal->apWiData[] array if required */
+@@ -55558,16 +58662,19 @@
+   }
+ 
+   /* Request a pointer to the required page from the VFS */
+-  if( pWal->apWiData[iPage]==0 ){
+-    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
+-      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
+-      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
+-    }else{
+-      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
+-          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
+-      );
++  assert( pWal->apWiData[iPage]==0 );
++  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
++    pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
++    if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
++  }else{
++    rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
++        pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
++    );
++    assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
++    testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
++    if( (rc&0xff)==SQLITE_READONLY ){
++      pWal->readOnly |= WAL_SHM_RDONLY;
+       if( rc==SQLITE_READONLY ){
+-        pWal->readOnly |= WAL_SHM_RDONLY;
+         rc = SQLITE_OK;
+       }
+     }
+@@ -55577,6 +58684,16 @@
+   assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
+   return rc;
+ }
++static int walIndexPage(
++  Wal *pWal,               /* The WAL context */
++  int iPage,               /* The page we seek */
++  volatile u32 **ppPage    /* Write the page pointer here */
++){
++  if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
++    return walIndexPageRealloc(pWal, iPage, ppPage);
++  }
++  return SQLITE_OK;
++}
+ 
+ /*
+ ** Return a pointer to the WalCkptInfo structure in the wal-index.
+@@ -55848,48 +58965,51 @@
+   return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
+ }
+ 
++/*
++** An instance of the WalHashLoc object is used to describe the location
++** of a page hash table in the wal-index.  This becomes the return value
++** from walHashGet().
++*/
++typedef struct WalHashLoc WalHashLoc;
++struct WalHashLoc {
++  volatile ht_slot *aHash;  /* Start of the wal-index hash table */
++  volatile u32 *aPgno;      /* aPgno[1] is the page of first frame indexed */
++  u32 iZero;                /* One less than the frame number of first indexed*/
++};
++
+ /* 
+ ** Return pointers to the hash table and page number array stored on
+ ** page iHash of the wal-index. The wal-index is broken into 32KB pages
+ ** numbered starting from 0.
+ **
+-** Set output variable *paHash to point to the start of the hash table
+-** in the wal-index file. Set *piZero to one less than the frame 
++** Set output variable pLoc->aHash to point to the start of the hash table
++** in the wal-index file. Set pLoc->iZero to one less than the frame 
+ ** number of the first frame indexed by this hash table. If a
+ ** slot in the hash table is set to N, it refers to frame number 
+-** (*piZero+N) in the log.
++** (pLoc->iZero+N) in the log.
+ **
+-** Finally, set *paPgno so that *paPgno[1] is the page number of the
+-** first frame indexed by the hash table, frame (*piZero+1).
++** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
++** first frame indexed by the hash table, frame (pLoc->iZero+1).
+ */
+ static int walHashGet(
+   Wal *pWal,                      /* WAL handle */
+   int iHash,                      /* Find the iHash'th table */
+-  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
+-  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
+-  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
++  WalHashLoc *pLoc                /* OUT: Hash table location */
+ ){
+   int rc;                         /* Return code */
+-  volatile u32 *aPgno;
+ 
+-  rc = walIndexPage(pWal, iHash, &aPgno);
++  rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
+   assert( rc==SQLITE_OK || iHash>0 );
+ 
+   if( rc==SQLITE_OK ){
+-    u32 iZero;
+-    volatile ht_slot *aHash;
+-
+-    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
++    pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
+     if( iHash==0 ){
+-      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
+-      iZero = 0;
++      pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
++      pLoc->iZero = 0;
+     }else{
+-      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
++      pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
+     }
+-  
+-    *paPgno = &aPgno[-1];
+-    *paHash = aHash;
+-    *piZero = iZero;
++    pLoc->aPgno = &pLoc->aPgno[-1];
+   }
+   return rc;
+ }
+@@ -55935,9 +59055,7 @@
+ ** actually needed.
+ */
+ static void walCleanupHash(Wal *pWal){
+-  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
+-  volatile u32 *aPgno = 0;        /* Page number array for hash table */
+-  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
++  WalHashLoc sLoc;                /* Hash table location */
+   int iLimit = 0;                 /* Zero values greater than this */
+   int nByte;                      /* Number of bytes to zero in aPgno[] */
+   int i;                          /* Used to iterate through aHash[] */
+@@ -55955,16 +59073,16 @@
+   */
+   assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
+   assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
+-  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
++  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+ 
+   /* Zero all hash-table entries that correspond to frame numbers greater
+   ** than pWal->hdr.mxFrame.
+   */
+-  iLimit = pWal->hdr.mxFrame - iZero;
++  iLimit = pWal->hdr.mxFrame - sLoc.iZero;
+   assert( iLimit>0 );
+   for(i=0; i<HASHTABLE_NSLOT; i++){
+-    if( aHash[i]>iLimit ){
+-      aHash[i] = 0;
++    if( sLoc.aHash[i]>iLimit ){
++      sLoc.aHash[i] = 0;
+     }
+   }
+   
+@@ -55971,8 +59089,8 @@
+   /* Zero the entries in the aPgno array that correspond to frames with
+   ** frame numbers greater than pWal->hdr.mxFrame. 
+   */
+-  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
+-  memset((void *)&aPgno[iLimit+1], 0, nByte);
++  nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
++  memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
+ 
+ #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+   /* Verify that the every entry in the mapping region is still reachable
+@@ -55982,10 +59100,10 @@
+     int j;           /* Loop counter */
+     int iKey;        /* Hash key */
+     for(j=1; j<=iLimit; j++){
+-      for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){
+-        if( aHash[iKey]==j ) break;
++      for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
++        if( sLoc.aHash[iKey]==j ) break;
+       }
+-      assert( aHash[iKey]==j );
++      assert( sLoc.aHash[iKey]==j );
+     }
+   }
+ #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
+@@ -55998,11 +59116,9 @@
+ */
+ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
+   int rc;                         /* Return code */
+-  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
+-  volatile u32 *aPgno = 0;        /* Page number array */
+-  volatile ht_slot *aHash = 0;    /* Hash table */
++  WalHashLoc sLoc;                /* Wal-index hash table location */
+ 
+-  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
++  rc = walHashGet(pWal, walFramePage(iFrame), &sLoc);
+ 
+   /* Assuming the wal-index file was successfully mapped, populate the
+   ** page number array and hash table entry.
+@@ -56012,7 +59128,7 @@
+     int idx;                      /* Value to write to hash-table slot */
+     int nCollide;                 /* Number of hash collisions */
+ 
+-    idx = iFrame - iZero;
++    idx = iFrame - sLoc.iZero;
+     assert( idx <= HASHTABLE_NSLOT/2 + 1 );
+     
+     /* If this is the first entry to be added to this hash-table, zero the
+@@ -56019,8 +59135,9 @@
+     ** entire hash table and aPgno[] array before proceeding. 
+     */
+     if( idx==1 ){
+-      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
+-      memset((void*)&aPgno[1], 0, nByte);
++      int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
++                               - (u8 *)&sLoc.aPgno[1]);
++      memset((void*)&sLoc.aPgno[1], 0, nByte);
+     }
+ 
+     /* If the entry in aPgno[] is already set, then the previous writer
+@@ -56029,18 +59146,18 @@
+     ** Remove the remnants of that writers uncommitted transaction from 
+     ** the hash-table before writing any new entries.
+     */
+-    if( aPgno[idx] ){
++    if( sLoc.aPgno[idx] ){
+       walCleanupHash(pWal);
+-      assert( !aPgno[idx] );
++      assert( !sLoc.aPgno[idx] );
+     }
+ 
+     /* Write the aPgno[] array entry and the hash-table slot. */
+     nCollide = idx;
+-    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
++    for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
+       if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
+     }
+-    aPgno[idx] = iPage;
+-    aHash[iKey] = (ht_slot)idx;
++    sLoc.aPgno[idx] = iPage;
++    sLoc.aHash[iKey] = (ht_slot)idx;
+ 
+ #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+     /* Verify that the number of entries in the hash table exactly equals
+@@ -56049,7 +59166,7 @@
+     {
+       int i;           /* Loop counter */
+       int nEntry = 0;  /* Number of entries in the hash table */
+-      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
++      for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; }
+       assert( nEntry==idx );
+     }
+ 
+@@ -56061,10 +59178,12 @@
+     if( (idx&0x3ff)==0 ){
+       int i;           /* Loop counter */
+       for(i=1; i<=idx; i++){
+-        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
+-          if( aHash[iKey]==i ) break;
++        for(iKey=walHash(sLoc.aPgno[i]);
++            sLoc.aHash[iKey];
++            iKey=walNextHash(iKey)){
++          if( sLoc.aHash[iKey]==i ) break;
+         }
+-        assert( aHash[iKey]==i );
++        assert( sLoc.aHash[iKey]==i );
+       }
+     }
+ #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
+@@ -56090,7 +59209,6 @@
+   i64 nSize;                      /* Size of log file */
+   u32 aFrameCksum[2] = {0, 0};
+   int iLock;                      /* Lock offset to lock for checkpoint */
+-  int nLock;                      /* Number of locks to hold */
+ 
+   /* Obtain an exclusive lock on all byte in the locking range not already
+   ** locked by the caller. The caller is guaranteed to have locked the
+@@ -56103,11 +59221,17 @@
+   assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
+   assert( pWal->writeLock );
+   iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
+-  nLock = SQLITE_SHM_NLOCK - iLock;
+-  rc = walLockExclusive(pWal, iLock, nLock);
++  rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
++  if( rc==SQLITE_OK ){
++    rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
++    if( rc!=SQLITE_OK ){
++      walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
++    }
++  }
+   if( rc ){
+     return rc;
+   }
++
+   WALTRACE(("WAL%p: recovery begin...\n", pWal));
+ 
+   memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
+@@ -56245,7 +59369,8 @@
+ 
+ recovery_error:
+   WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
+-  walUnlockExclusive(pWal, iLock, nLock);
++  walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
++  walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+   return rc;
+ }
+ 
+@@ -56253,13 +59378,14 @@
+ ** Close an open wal-index.
+ */
+ static void walIndexClose(Wal *pWal, int isDelete){
+-  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
++  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){
+     int i;
+     for(i=0; i<pWal->nWiData; i++){
+       sqlite3_free((void *)pWal->apWiData[i]);
+       pWal->apWiData[i] = 0;
+     }
+-  }else{
++  }
++  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
+     sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
+   }
+ }
+@@ -56546,8 +59672,9 @@
+ 
+ /*
+ ** Construct a WalInterator object that can be used to loop over all 
+-** pages in the WAL in ascending order. The caller must hold the checkpoint
+-** lock.
++** pages in the WAL following frame nBackfill in ascending order. Frames
++** nBackfill or earlier may be included - excluding them is an optimization
++** only. The caller must hold the checkpoint lock.
+ **
+ ** On success, make *pp point to the newly allocated WalInterator object
+ ** return SQLITE_OK. Otherwise, return an error code. If this routine
+@@ -56556,7 +59683,7 @@
+ ** The calling routine should invoke walIteratorFree() to destroy the
+ ** WalIterator object when it has finished with it.
+ */
+-static int walIteratorInit(Wal *pWal, WalIterator **pp){
++static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
+   WalIterator *p;                 /* Return value */
+   int nSegment;                   /* Number of segments to merge */
+   u32 iLast;                      /* Last frame in log */
+@@ -56593,34 +59720,32 @@
+     rc = SQLITE_NOMEM_BKPT;
+   }
+ 
+-  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
+-    volatile ht_slot *aHash;
+-    u32 iZero;
+-    volatile u32 *aPgno;
++  for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
++    WalHashLoc sLoc;
+ 
+-    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
++    rc = walHashGet(pWal, i, &sLoc);
+     if( rc==SQLITE_OK ){
+       int j;                      /* Counter variable */
+       int nEntry;                 /* Number of entries in this segment */
+       ht_slot *aIndex;            /* Sorted index for this segment */
+ 
+-      aPgno++;
++      sLoc.aPgno++;
+       if( (i+1)==nSegment ){
+-        nEntry = (int)(iLast - iZero);
++        nEntry = (int)(iLast - sLoc.iZero);
+       }else{
+-        nEntry = (int)((u32*)aHash - (u32*)aPgno);
++        nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
+       }
+-      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
+-      iZero++;
++      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero];
++      sLoc.iZero++;
+   
+       for(j=0; j<nEntry; j++){
+         aIndex[j] = (ht_slot)j;
+       }
+-      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
+-      p->aSegment[i].iZero = iZero;
++      walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry);
++      p->aSegment[i].iZero = sLoc.iZero;
+       p->aSegment[i].nEntry = nEntry;
+       p->aSegment[i].aIndex = aIndex;
+-      p->aSegment[i].aPgno = (u32 *)aPgno;
++      p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
+     }
+   }
+   sqlite3_free(aTmp);
+@@ -56627,6 +59752,7 @@
+ 
+   if( rc!=SQLITE_OK ){
+     walIteratorFree(p);
++    p = 0;
+   }
+   *pp = p;
+   return rc;
+@@ -56749,13 +59875,6 @@
+   pInfo = walCkptInfo(pWal);
+   if( pInfo->nBackfill<pWal->hdr.mxFrame ){
+ 
+-    /* Allocate the iterator */
+-    rc = walIteratorInit(pWal, &pIter);
+-    if( rc!=SQLITE_OK ){
+-      return rc;
+-    }
+-    assert( pIter );
+-
+     /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+     ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+     assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
+@@ -56792,18 +59911,21 @@
+       }
+     }
+ 
+-    if( pInfo->nBackfill<mxSafeFrame
++    /* Allocate the iterator */
++    if( pInfo->nBackfill<mxSafeFrame ){
++      rc = walIteratorInit(pWal, pInfo->nBackfill, &pIter);
++      assert( rc==SQLITE_OK || pIter==0 );
++    }
++
++    if( pIter
+      && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+     ){
+-      i64 nSize;                    /* Current size of database file */
+       u32 nBackfill = pInfo->nBackfill;
+ 
+       pInfo->nBackfillAttempted = mxSafeFrame;
+ 
+       /* Sync the WAL to disk */
+-      if( sync_flags ){
+-        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
+-      }
++      rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
+ 
+       /* If the database may grow as a result of this checkpoint, hint
+       ** about the eventual size of the db file to the VFS layer.
+@@ -56810,6 +59932,7 @@
+       */
+       if( rc==SQLITE_OK ){
+         i64 nReq = ((i64)mxPage * szPage);
++        i64 nSize;                    /* Current size of database file */
+         rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
+         if( rc==SQLITE_OK && nSize<nReq ){
+           sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+@@ -56844,8 +59967,8 @@
+           i64 szDb = pWal->hdr.nPage*(i64)szPage;
+           testcase( IS_BIG_INT(szDb) );
+           rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
+-          if( rc==SQLITE_OK && sync_flags ){
+-            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
+           }
+         }
+         if( rc==SQLITE_OK ){
+@@ -57055,6 +60178,12 @@
+ }
+ 
+ /*
++** This is the value that walTryBeginRead returns when it needs to
++** be retried.
++*/
++#define WAL_RETRY  (-1)
++
++/*
+ ** Read the wal-index header from the wal-index and into pWal->hdr.
+ ** If the wal-header appears to be corrupt, try to reconstruct the
+ ** wal-index from the WAL before returning.
+@@ -57077,9 +60206,29 @@
+   assert( pChanged );
+   rc = walIndexPage(pWal, 0, &page0);
+   if( rc!=SQLITE_OK ){
+-    return rc;
+-  };
+-  assert( page0 || pWal->writeLock==0 );
++    assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */
++    if( rc==SQLITE_READONLY_CANTINIT ){
++      /* The SQLITE_READONLY_CANTINIT return means that the shared-memory
++      ** was openable but is not writable, and this thread is unable to
++      ** confirm that another write-capable connection has the shared-memory
++      ** open, and hence the content of the shared-memory is unreliable,
++      ** since the shared-memory might be inconsistent with the WAL file
++      ** and there is no writer on hand to fix it. */
++      assert( page0==0 );
++      assert( pWal->writeLock==0 );
++      assert( pWal->readOnly & WAL_SHM_RDONLY );
++      pWal->bShmUnreliable = 1;
++      pWal->exclusiveMode = WAL_HEAPMEMORY_MODE;
++      *pChanged = 1;
++    }else{
++      return rc; /* Any other non-OK return is just an error */
++    }
++  }else{
++    /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
++    ** is zero, which prevents the SHM from growing */
++    testcase( page0!=0 );
++  }
++  assert( page0!=0 || pWal->writeLock==0 );
+ 
+   /* If the first page of the wal-index has been mapped, try to read the
+   ** wal-index header immediately, without holding any lock. This usually
+@@ -57093,7 +60242,7 @@
+   */
+   assert( badHdr==0 || pWal->writeLock==0 );
+   if( badHdr ){
+-    if( pWal->readOnly & WAL_SHM_RDONLY ){
++    if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
+       if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
+         walUnlockShared(pWal, WAL_WRITE_LOCK);
+         rc = SQLITE_READONLY_RECOVERY;
+@@ -57123,16 +60272,194 @@
+   if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
+     rc = SQLITE_CANTOPEN_BKPT;
+   }
++  if( pWal->bShmUnreliable ){
++    if( rc!=SQLITE_OK ){
++      walIndexClose(pWal, 0);
++      pWal->bShmUnreliable = 0;
++      assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
++      /* walIndexRecover() might have returned SHORT_READ if a concurrent
++      ** writer truncated the WAL out from under it.  If that happens, it
++      ** indicates that a writer has fixed the SHM file for us, so retry */
++      if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
++    }
++    pWal->exclusiveMode = WAL_NORMAL_MODE;
++  }
+ 
+   return rc;
+ }
+ 
+ /*
+-** This is the value that walTryBeginRead returns when it needs to
+-** be retried.
++** Open a transaction in a connection where the shared-memory is read-only
++** and where we cannot verify that there is a separate write-capable connection
++** on hand to keep the shared-memory up-to-date with the WAL file.
++**
++** This can happen, for example, when the shared-memory is implemented by
++** memory-mapping a *-shm file, where a prior writer has shut down and
++** left the *-shm file on disk, and now the present connection is trying
++** to use that database but lacks write permission on the *-shm file.
++** Other scenarios are also possible, depending on the VFS implementation.
++**
++** Precondition:
++**
++**    The *-wal file has been read and an appropriate wal-index has been
++**    constructed in pWal->apWiData[] using heap memory instead of shared
++**    memory. 
++**
++** If this function returns SQLITE_OK, then the read transaction has
++** been successfully opened. In this case output variable (*pChanged) 
++** is set to true before returning if the caller should discard the
++** contents of the page cache before proceeding. Or, if it returns 
++** WAL_RETRY, then the heap memory wal-index has been discarded and 
++** the caller should retry opening the read transaction from the 
++** beginning (including attempting to map the *-shm file). 
++**
++** If an error occurs, an SQLite error code is returned.
+ */
+-#define WAL_RETRY  (-1)
++static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
++  i64 szWal;                      /* Size of wal file on disk in bytes */
++  i64 iOffset;                    /* Current offset when reading wal file */
++  u8 aBuf[WAL_HDRSIZE];           /* Buffer to load WAL header into */
++  u8 *aFrame = 0;                 /* Malloc'd buffer to load entire frame */
++  int szFrame;                    /* Number of bytes in buffer aFrame[] */
++  u8 *aData;                      /* Pointer to data part of aFrame buffer */
++  volatile void *pDummy;          /* Dummy argument for xShmMap */
++  int rc;                         /* Return code */
++  u32 aSaveCksum[2];              /* Saved copy of pWal->hdr.aFrameCksum */
+ 
++  assert( pWal->bShmUnreliable );
++  assert( pWal->readOnly & WAL_SHM_RDONLY );
++  assert( pWal->nWiData>0 && pWal->apWiData[0] );
++
++  /* Take WAL_READ_LOCK(0). This has the effect of preventing any
++  ** writers from running a checkpoint, but does not stop them
++  ** from running recovery.  */
++  rc = walLockShared(pWal, WAL_READ_LOCK(0));
++  if( rc!=SQLITE_OK ){
++    if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
++    goto begin_unreliable_shm_out;
++  }
++  pWal->readLock = 0;
++
++  /* Check to see if a separate writer has attached to the shared-memory area,
++  ** thus making the shared-memory "reliable" again.  Do this by invoking
++  ** the xShmMap() routine of the VFS and looking to see if the return
++  ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
++  **
++  ** If the shared-memory is now "reliable" return WAL_RETRY, which will
++  ** cause the heap-memory WAL-index to be discarded and the actual
++  ** shared memory to be used in its place.
++  **
++  ** This step is important because, even though this connection is holding
++  ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
++  ** have already checkpointed the WAL file and, while the current
++  ** is active, wrap the WAL and start overwriting frames that this
++  ** process wants to use.
++  **
++  ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
++  ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
++  ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
++  ** even if some external agent does a "chmod" to make the shared-memory
++  ** writable by us, until sqlite3OsShmUnmap() has been called.
++  ** This is a requirement on the VFS implementation.
++   */
++  rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
++  assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
++  if( rc!=SQLITE_READONLY_CANTINIT ){
++    rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
++    goto begin_unreliable_shm_out;
++  }
++
++  /* We reach this point only if the real shared-memory is still unreliable.
++  ** Assume the in-memory WAL-index substitute is correct and load it
++  ** into pWal->hdr.
++  */
++  memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));
++
++  /* Make sure some writer hasn't come in and changed the WAL file out
++  ** from under us, then disconnected, while we were not looking.
++  */
++  rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
++  if( rc!=SQLITE_OK ){
++    goto begin_unreliable_shm_out;
++  }
++  if( szWal<WAL_HDRSIZE ){
++    /* If the wal file is too small to contain a wal-header and the
++    ** wal-index header has mxFrame==0, then it must be safe to proceed
++    ** reading the database file only. However, the page cache cannot
++    ** be trusted, as a read/write connection may have connected, written
++    ** the db, run a checkpoint, truncated the wal file and disconnected
++    ** since this client's last read transaction.  */
++    *pChanged = 1;
++    rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
++    goto begin_unreliable_shm_out;
++  }
++
++  /* Check the salt keys at the start of the wal file still match. */
++  rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
++  if( rc!=SQLITE_OK ){
++    goto begin_unreliable_shm_out;
++  }
++  if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
++    /* Some writer has wrapped the WAL file while we were not looking.
++    ** Return WAL_RETRY which will cause the in-memory WAL-index to be
++    ** rebuilt. */
++    rc = WAL_RETRY;
++    goto begin_unreliable_shm_out;
++  }
++
++  /* Allocate a buffer to read frames into */
++  szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
++  aFrame = (u8 *)sqlite3_malloc64(szFrame);
++  if( aFrame==0 ){
++    rc = SQLITE_NOMEM_BKPT;
++    goto begin_unreliable_shm_out;
++  }
++  aData = &aFrame[WAL_FRAME_HDRSIZE];
++
++  /* Check to see if a complete transaction has been appended to the
++  ** wal file since the heap-memory wal-index was created. If so, the
++  ** heap-memory wal-index is discarded and WAL_RETRY returned to
++  ** the caller.  */
++  aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
++  aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
++  for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); 
++      iOffset+szFrame<=szWal; 
++      iOffset+=szFrame
++  ){
++    u32 pgno;                   /* Database page number for frame */
++    u32 nTruncate;              /* dbsize field from frame header */
++
++    /* Read and decode the next log frame. */
++    rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
++    if( rc!=SQLITE_OK ) break;
++    if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;
++
++    /* If nTruncate is non-zero, then a complete transaction has been
++    ** appended to this wal file. Set rc to WAL_RETRY and break out of
++    ** the loop.  */
++    if( nTruncate ){
++      rc = WAL_RETRY;
++      break;
++    }
++  }
++  pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
++  pWal->hdr.aFrameCksum[1] = aSaveCksum[1];
++
++ begin_unreliable_shm_out:
++  sqlite3_free(aFrame);
++  if( rc!=SQLITE_OK ){
++    int i;
++    for(i=0; i<pWal->nWiData; i++){
++      sqlite3_free((void*)pWal->apWiData[i]);
++      pWal->apWiData[i] = 0;
++    }
++    pWal->bShmUnreliable = 0;
++    sqlite3WalEndReadTransaction(pWal);
++    *pChanged = 1;
++  }
++  return rc;
++}
++
+ /*
+ ** Attempt to start a read transaction.  This might fail due to a race or
+ ** other transient condition.  When that happens, it returns WAL_RETRY to
+@@ -57147,7 +60474,7 @@
+ ** checkpointed.  If useWal==0 then this routine calls walIndexReadHdr() 
+ ** to make a copy of the wal-index header into pWal->hdr.  If the 
+ ** wal-index header has changed, *pChanged is set to 1 (as an indication 
+-** to the caller that the local paget cache is obsolete and needs to be 
++** to the caller that the local page cache is obsolete and needs to be 
+ ** flushed.)  When useWal==1, the wal-index header is assumed to already
+ ** be loaded and the pChanged parameter is unused.
+ **
+@@ -57193,6 +60520,9 @@
+ 
+   assert( pWal->readLock<0 );     /* Not currently locked */
+ 
++  /* useWal may only be set for read/write connections */
++  assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
++
+   /* Take steps to avoid spinning forever if there is a protocol error.
+   **
+   ** Circumstances that cause a RETRY should only last for the briefest
+@@ -57221,7 +60551,10 @@
+   }
+ 
+   if( !useWal ){
+-    rc = walIndexReadHdr(pWal, pChanged);
++    assert( rc==SQLITE_OK );
++    if( pWal->bShmUnreliable==0 ){
++      rc = walIndexReadHdr(pWal, pChanged);
++    }
+     if( rc==SQLITE_BUSY ){
+       /* If there is not a recovery running in another thread or process
+       ** then convert BUSY errors to WAL_RETRY.  If recovery is known to
+@@ -57250,13 +60583,17 @@
+     if( rc!=SQLITE_OK ){
+       return rc;
+     }
++    else if( pWal->bShmUnreliable ){
++      return walBeginShmUnreliable(pWal, pChanged);
++    }
+   }
+ 
++  assert( pWal->nWiData>0 );
++  assert( pWal->apWiData[0]!=0 );
+   pInfo = walCkptInfo(pWal);
+-  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame 
++  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
+ #ifdef SQLITE_ENABLE_SNAPSHOT
+-   && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
+-     || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
++   && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
+ #endif
+   ){
+     /* The WAL has been completely backfilled (or it is empty).
+@@ -57303,7 +60640,7 @@
+   }
+ #endif
+   for(i=1; i<WAL_NREADER; i++){
+-    u32 thisMark = pInfo->aReadMark[i];
++    u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
+     if( mxReadMark<=thisMark && thisMark<=mxFrame ){
+       assert( thisMark!=READMARK_NOT_USED );
+       mxReadMark = thisMark;
+@@ -57316,7 +60653,7 @@
+     for(i=1; i<WAL_NREADER; i++){
+       rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
+       if( rc==SQLITE_OK ){
+-        mxReadMark = pInfo->aReadMark[i] = mxFrame;
++        mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
+         mxI = i;
+         walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+         break;
+@@ -57327,7 +60664,7 @@
+   }
+   if( mxI==0 ){
+     assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
+-    return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
++    return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
+   }
+ 
+   rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
+@@ -57368,9 +60705,9 @@
+   ** we can guarantee that the checkpointer that set nBackfill could not
+   ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
+   */
+-  pWal->minFrame = pInfo->nBackfill+1;
++  pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
+   walShmBarrier(pWal);
+-  if( pInfo->aReadMark[mxI]!=mxReadMark
++  if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
+    || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
+   ){
+     walUnlockShared(pWal, WAL_READ_LOCK(mxI));
+@@ -57421,16 +60758,14 @@
+       }else{
+         u32 i = pInfo->nBackfillAttempted;
+         for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
+-          volatile ht_slot *dummy;
+-          volatile u32 *aPgno;      /* Array of page numbers */
+-          u32 iZero;                /* Frame corresponding to aPgno[0] */
++          WalHashLoc sLoc;          /* Hash table location */
+           u32 pgno;                 /* Page number in db file */
+           i64 iDbOff;               /* Offset of db file entry */
+           i64 iWalOff;              /* Offset of wal file entry */
+ 
+-          rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
++          rc = walHashGet(pWal, walFramePage(i), &sLoc);
+           if( rc!=SQLITE_OK ) break;
+-          pgno = aPgno[i-iZero];
++          pgno = sLoc.aPgno[i-sLoc.iZero];
+           iDbOff = (i64)(pgno-1) * szPage;
+ 
+           if( iDbOff+szPage<=szDb ){
+@@ -57471,7 +60806,7 @@
+ **
+ ** If the database contents have changes since the previous read
+ ** transaction, then *pChanged is set to 1 before returning.  The
+-** Pager layer will use this to know that is cache is stale and
++** Pager layer will use this to know that its cache is stale and
+ ** needs to be flushed.
+ */
+ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
+@@ -57533,7 +60868,7 @@
+         /* Check that the wal file has not been wrapped. Assuming that it has
+         ** not, also check that no checkpointer has attempted to checkpoint any
+         ** frames beyond pSnapshot->mxFrame. If either of these conditions are
+-        ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
++        ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
+         ** with *pSnapshot and set *pChanged as appropriate for opening the
+         ** snapshot.  */
+         if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+@@ -57543,11 +60878,12 @@
+           memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
+           *pChanged = bChanged;
+         }else{
+-          rc = SQLITE_BUSY_SNAPSHOT;
++          rc = SQLITE_ERROR_SNAPSHOT;
+         }
+ 
+         /* Release the shared CKPT lock obtained above. */
+         walUnlockShared(pWal, WAL_CKPT_LOCK);
++        pWal->minFrame = 1;
+       }
+ 
+ 
+@@ -57599,7 +60935,7 @@
+   ** then the WAL is ignored by the reader so return early, as if the 
+   ** WAL were empty.
+   */
+-  if( iLast==0 || pWal->readLock==0 ){
++  if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){
+     *piRead = 0;
+     return SQLITE_OK;
+   }
+@@ -57630,22 +60966,21 @@
+   **     table after the current read-transaction had started.
+   */
+   iMinHash = walFramePage(pWal->minFrame);
+-  for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
+-    volatile ht_slot *aHash;      /* Pointer to hash table */
+-    volatile u32 *aPgno;          /* Pointer to array of page numbers */
+-    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
++  for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
++    WalHashLoc sLoc;              /* Hash table location */
+     int iKey;                     /* Hash slot index */
+     int nCollide;                 /* Number of hash collisions remaining */
+     int rc;                       /* Error code */
+ 
+-    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
++    rc = walHashGet(pWal, iHash, &sLoc);
+     if( rc!=SQLITE_OK ){
+       return rc;
+     }
+     nCollide = HASHTABLE_NSLOT;
+-    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
+-      u32 iFrame = aHash[iKey] + iZero;
+-      if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
++    for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
++      u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
++      if( iFrame<=iLast && iFrame>=pWal->minFrame
++       && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
+         assert( iFrame>iRead || CORRUPT_DB );
+         iRead = iFrame;
+       }
+@@ -57653,6 +60988,7 @@
+         return SQLITE_CORRUPT_BKPT;
+       }
+     }
++    if( iRead ) break;
+   }
+ 
+ #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+@@ -57662,8 +60998,8 @@
+   {
+     u32 iRead2 = 0;
+     u32 iTest;
+-    assert( pWal->minFrame>0 );
+-    for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
++    assert( pWal->bShmUnreliable || pWal->minFrame>0 );
++    for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){
+       if( walFramePgno(pWal, iTest)==pgno ){
+         iRead2 = iTest;
+         break;
+@@ -57951,8 +61287,8 @@
+     iOffset += iFirstAmt;
+     iAmt -= iFirstAmt;
+     pContent = (void*)(iFirstAmt + (char*)pContent);
+-    assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
+-    rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
++    assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 );
++    rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags));
+     if( iAmt==0 || rc ) return rc;
+   }
+   rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
+@@ -58122,10 +61458,10 @@
+     ** an out-of-order write following a WAL restart could result in
+     ** database corruption.  See the ticket:
+     **
+-    **     http://localhost:591/sqlite/info/ff5be73dee
++    **     https://sqlite.org/src/info/ff5be73dee
+     */
+-    if( pWal->syncHeader && sync_flags ){
+-      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
++    if( pWal->syncHeader ){
++      rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
+       if( rc ) return rc;
+     }
+   }
+@@ -58200,7 +61536,7 @@
+   ** sector boundary is synced; the part of the last frame that extends
+   ** past the sector boundary is written after the sync.
+   */
+-  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
++  if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){
+     int bSync = 1;
+     if( pWal->padToSectorBoundary ){
+       int sectorSize = sqlite3SectorSize(pWal->pWalFd);
+@@ -58216,7 +61552,7 @@
+     }
+     if( bSync ){
+       assert( rc==SQLITE_OK );
+-      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
++      rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags));
+     }
+   }
+ 
+@@ -58439,24 +61775,24 @@
+   assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
+ 
+   if( op==0 ){
+-    if( pWal->exclusiveMode ){
+-      pWal->exclusiveMode = 0;
++    if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){
++      pWal->exclusiveMode = WAL_NORMAL_MODE;
+       if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
+-        pWal->exclusiveMode = 1;
++        pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
+       }
+-      rc = pWal->exclusiveMode==0;
++      rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
+     }else{
+       /* Already in locking_mode=NORMAL */
+       rc = 0;
+     }
+   }else if( op>0 ){
+-    assert( pWal->exclusiveMode==0 );
++    assert( pWal->exclusiveMode==WAL_NORMAL_MODE );
+     assert( pWal->readLock>=0 );
+     walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
+-    pWal->exclusiveMode = 1;
++    pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
+     rc = 1;
+   }else{
+-    rc = pWal->exclusiveMode==0;
++    rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
+   }
+   return rc;
+ }
+@@ -58519,6 +61855,43 @@
+   if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
+   return 0;
+ }
++
++/*
++** The caller currently has a read transaction open on the database.
++** This function takes a SHARED lock on the CHECKPOINTER slot and then
++** checks if the snapshot passed as the second argument is still 
++** available. If so, SQLITE_OK is returned.
++**
++** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
++** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
++** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
++** lock is released before returning.
++*/
++SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){
++  int rc;
++  rc = walLockShared(pWal, WAL_CKPT_LOCK);
++  if( rc==SQLITE_OK ){
++    WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot;
++    if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
++     || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted
++    ){
++      rc = SQLITE_ERROR_SNAPSHOT;
++      walUnlockShared(pWal, WAL_CKPT_LOCK);
++    }
++  }
++  return rc;
++}
++
++/*
++** Release a lock obtained by an earlier successful call to
++** sqlite3WalSnapshotCheck().
++*/
++SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){
++  assert( pWal );
++  walUnlockShared(pWal, WAL_CKPT_LOCK);
++}
++
++
+ #endif /* SQLITE_ENABLE_SNAPSHOT */
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -59063,30 +62436,31 @@
+ **    eState==FAULT:                   Cursor fault with skipNext as error code.
+ */
+ struct BtCursor {
++  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
++  u8 curFlags;              /* zero or more BTCF_* flags defined below */
++  u8 curPagerFlags;         /* Flags to send to sqlite3PagerGet() */
++  u8 hints;                 /* As configured by CursorSetHints() */
++  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
++                   ** Error code if eState==CURSOR_FAULT */
+   Btree *pBtree;            /* The Btree to which this cursor belongs */
++  Pgno *aOverflow;          /* Cache of overflow page locations */
++  void *pKey;               /* Saved key that was cursor last known position */
++  /* All fields above are zeroed when the cursor is allocated.  See
++  ** sqlite3BtreeCursorZero().  Fields that follow must be manually
++  ** initialized. */
++#define BTCURSOR_FIRST_UNINIT pBt   /* Name of first uninitialized field */
+   BtShared *pBt;            /* The BtShared this cursor points to */
+   BtCursor *pNext;          /* Forms a linked list of all cursors */
+-  Pgno *aOverflow;          /* Cache of overflow page locations */
+   CellInfo info;            /* A parse of the cell we are pointing at */
+   i64 nKey;                 /* Size of pKey, or last integer key */
+-  void *pKey;               /* Saved key that was cursor last known position */
+   Pgno pgnoRoot;            /* The root page of this tree */
+-  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
+-  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
+-                   ** Error code if eState==CURSOR_FAULT */
+-  u8 curFlags;              /* zero or more BTCF_* flags defined below */
+-  u8 curPagerFlags;         /* Flags to send to sqlite3PagerGet() */
+-  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
+-  u8 hints;                 /* As configured by CursorSetHints() */
+-  /* All fields above are zeroed when the cursor is allocated.  See
+-  ** sqlite3BtreeCursorZero().  Fields that follow must be manually
+-  ** initialized. */
+   i8 iPage;                 /* Index of current page in apPage */
+   u8 curIntKey;             /* Value of apPage[0]->intKey */
+   u16 ix;                   /* Current index for apPage[iPage] */
+   u16 aiIdx[BTCURSOR_MAX_DEPTH-1];     /* Current index in apPage[i] */
+   struct KeyInfo *pKeyInfo;            /* Arg passed to comparison function */
+-  MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
++  MemPage *pPage;                        /* Current page */
++  MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */
+ };
+ 
+ /*
+@@ -59129,8 +62503,8 @@
+ **   Do nothing else with this cursor.  Any attempt to use the cursor
+ **   should return the error code stored in BtCursor.skipNext
+ */
+-#define CURSOR_INVALID           0
+-#define CURSOR_VALID             1
++#define CURSOR_VALID             0
++#define CURSOR_INVALID           1
+ #define CURSOR_SKIPNEXT          2
+ #define CURSOR_REQUIRESEEK       3
+ #define CURSOR_FAULT             4
+@@ -59447,10 +62821,10 @@
+       skipOk = 0;
+     }
+   }
+-  db->skipBtreeMutex = skipOk;
++  db->noSharedCache = skipOk;
+ }
+ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
+-  if( db->skipBtreeMutex==0 ) btreeEnterAll(db);
++  if( db->noSharedCache==0 ) btreeEnterAll(db);
+ }
+ static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
+   int i;
+@@ -59462,7 +62836,7 @@
+   }
+ }
+ SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
+-  if( db->skipBtreeMutex==0 ) btreeLeaveAll(db);
++  if( db->noSharedCache==0 ) btreeLeaveAll(db);
+ }
+ 
+ #ifndef NDEBUG
+@@ -59675,6 +63049,34 @@
+   #define hasReadConflicts(a, b) 0
+ #endif
+ 
++/*
++** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
++** (MemPage*) as an argument. The (MemPage*) must not be NULL.
++**
++** If SQLITE_DEBUG is not defined, then this macro is equivalent to
++** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
++** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
++** with the page number and filename associated with the (MemPage*).
++*/
++#ifdef SQLITE_DEBUG
++int corruptPageError(int lineno, MemPage *p){
++  char *zMsg;
++  sqlite3BeginBenignMalloc();
++  zMsg = sqlite3_mprintf("database corruption page %d of %s",
++      (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
++  );
++  sqlite3EndBenignMalloc();
++  if( zMsg ){
++    sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
++  }
++  sqlite3_free(zMsg);
++  return SQLITE_CORRUPT_BKPT;
++}
++# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
++#else
++# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
++#endif
++
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+ 
+ #ifdef SQLITE_DEBUG
+@@ -60002,7 +63404,9 @@
+ 
+ #endif /* SQLITE_OMIT_SHARED_CACHE */
+ 
+-static void releasePage(MemPage *pPage);  /* Forward reference */
++static void releasePage(MemPage *pPage);         /* Forward reference */
++static void releasePageOne(MemPage *pPage);      /* Forward reference */
++static void releasePageNotNull(MemPage *pPage);  /* Forward reference */
+ 
+ /*
+ ***** This routine is used inside of assert() only ****
+@@ -60161,11 +63565,13 @@
+ */
+ static void btreeReleaseAllCursorPages(BtCursor *pCur){
+   int i;
+-  for(i=0; i<=pCur->iPage; i++){
+-    releasePage(pCur->apPage[i]);
+-    pCur->apPage[i] = 0;
++  if( pCur->iPage>=0 ){
++    for(i=0; i<pCur->iPage; i++){
++      releasePageNotNull(pCur->apPage[i]);
++    }
++    releasePageNotNull(pCur->pPage);
++    pCur->iPage = -1;
+   }
+-  pCur->iPage = -1;
+ }
+ 
+ /*
+@@ -60294,7 +63700,7 @@
+           return rc;
+         }
+       }else{
+-        testcase( p->iPage>0 );
++        testcase( p->iPage>=0 );
+         btreeReleaseAllCursorPages(p);
+       }
+     }
+@@ -60334,7 +63740,7 @@
+     if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
+     sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
+     if( pIdxKey->nField==0 ){
+-      rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
++      rc = SQLITE_CORRUPT_BKPT;
+       goto moveto_done;
+     }
+   }else{
+@@ -60395,10 +63801,25 @@
+ ** back to where it ought to be if this routine returns true.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
+-  return pCur->eState!=CURSOR_VALID;
++  assert( EIGHT_BYTE_ALIGNMENT(pCur)
++       || pCur==sqlite3BtreeFakeValidCursor() );
++  assert( offsetof(BtCursor, eState)==0 );
++  assert( sizeof(pCur->eState)==1 );
++  return CURSOR_VALID != *(u8*)pCur;
+ }
+ 
+ /*
++** Return a pointer to a fake BtCursor object that will always answer
++** false to the sqlite3BtreeCursorHasMoved() routine above.  The fake
++** cursor returned must not be used with any other Btree interface.
++*/
++SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){
++  static u8 fakeCursor = CURSOR_VALID;
++  assert( offsetof(BtCursor, eState)==0 );
++  return (BtCursor*)&fakeCursor;
++}
++
++/*
+ ** This routine restores a cursor back to its original position after it
+ ** has been moved by some outside activity (such as a btree rebalance or
+ ** a row having been deleted out from under the cursor).  
+@@ -60947,8 +64368,11 @@
+         int sz2 = 0;
+         int sz = get2byte(&data[iFree+2]);
+         int top = get2byte(&data[hdr+5]);
++        if( top>=iFree ){
++          return SQLITE_CORRUPT_PAGE(pPage);
++        }
+         if( iFree2 ){
+-          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++          assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
+           sz2 = get2byte(&data[iFree2+2]);
+           assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+           memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
+@@ -60979,13 +64403,13 @@
+     ** if PRAGMA cell_size_check=ON.
+     */
+     if( pc<iCellFirst || pc>iCellLast ){
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+     assert( pc>=iCellFirst && pc<=iCellLast );
+     size = pPage->xCellSize(pPage, &src[pc]);
+     cbrk -= size;
+     if( cbrk<iCellFirst || pc+size>usableSize ){
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+     assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
+     testcase( cbrk+size==usableSize );
+@@ -61005,7 +64429,7 @@
+ 
+  defragment_out:
+   if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   assert( cbrk>=iCellFirst );
+   put2byte(&data[hdr+5], cbrk);
+@@ -61037,16 +64461,10 @@
+   int pc = get2byte(&aData[iAddr]);
+   int x;
+   int usableSize = pPg->pBt->usableSize;
++  int size;            /* Size of the free slot */
+ 
+   assert( pc>0 );
+-  do{
+-    int size;            /* Size of the free slot */
+-    /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+-    ** increasing offset. */
+-    if( pc>usableSize-4 || pc<iAddr+4 ){
+-      *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
+-      return 0;
+-    }
++  while( pc<=usableSize-4 ){
+     /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
+     ** freeblock form a big-endian integer which is the size of the freeblock
+     ** in bytes, including the 4-byte header. */
+@@ -61054,8 +64472,8 @@
+     if( (x = size - nByte)>=0 ){
+       testcase( x==4 );
+       testcase( x==3 );
+-      if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
+-        *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
++      if( size+pc > usableSize ){
++        *pRc = SQLITE_CORRUPT_PAGE(pPg);
+         return 0;
+       }else if( x<4 ){
+         /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
+@@ -61075,7 +64493,11 @@
+     }
+     iAddr = pc;
+     pc = get2byte(&aData[pc]);
+-  }while( pc );
++    if( pc<iAddr+size ) break;
++  }
++  if( pc ){
++    *pRc = SQLITE_CORRUPT_PAGE(pPg);
++  }
+ 
+   return 0;
+ }
+@@ -61122,7 +64544,7 @@
+     if( top==0 && pPage->pBt->usableSize==65536 ){
+       top = 65536;
+     }else{
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+   }
+ 
+@@ -61189,7 +64611,7 @@
+   u8 hdr;                               /* Page header size.  0 or 100 */
+   u8 nFrag = 0;                         /* Reduction in fragmentation */
+   u16 iOrigSize = iSize;                /* Original value of iSize */
+-  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
++  u16 x;                                /* Offset to cell content area */
+   u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
+   unsigned char *data = pPage->aData;   /* Page content */
+ 
+@@ -61199,14 +64621,8 @@
+   assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+   assert( iSize>=4 );   /* Minimum cell size is 4 */
+-  assert( iStart<=iLast );
++  assert( iStart<=pPage->pBt->usableSize-4 );
+ 
+-  /* Overwrite deleted information with zeros when the secure_delete
+-  ** option is enabled */
+-  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
+-    memset(&data[iStart], 0, iSize);
+-  }
+-
+   /* The list of freeblocks must be in ascending order.  Find the 
+   ** spot on the list where iStart should be inserted.
+   */
+@@ -61218,11 +64634,13 @@
+     while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
+       if( iFreeBlk<iPtr+4 ){
+         if( iFreeBlk==0 ) break;
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+       iPtr = iFreeBlk;
+     }
+-    if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    if( iFreeBlk>pPage->pBt->usableSize-4 ){
++      return SQLITE_CORRUPT_PAGE(pPage);
++    }
+     assert( iFreeBlk>iPtr || iFreeBlk==0 );
+   
+     /* At this point:
+@@ -61233,10 +64651,10 @@
+     */
+     if( iFreeBlk && iEnd+3>=iFreeBlk ){
+       nFrag = iFreeBlk - iEnd;
+-      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
+       iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
+       if( iEnd > pPage->pBt->usableSize ){
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+       iSize = iEnd - iStart;
+       iFreeBlk = get2byte(&data[iFreeBlk]);
+@@ -61249,28 +64667,34 @@
+     if( iPtr>hdr+1 ){
+       int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
+       if( iPtrEnd+3>=iStart ){
+-        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage);
+         nFrag += iStart - iPtrEnd;
+         iSize = iEnd - iPtr;
+         iStart = iPtr;
+       }
+     }
+-    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
+     data[hdr+7] -= nFrag;
+   }
+-  if( iStart==get2byte(&data[hdr+5]) ){
++  x = get2byte(&data[hdr+5]);
++  if( iStart<=x ){
+     /* The new freeblock is at the beginning of the cell content area,
+     ** so just extend the cell content area rather than create another
+     ** freelist entry */
+-    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
+     put2byte(&data[hdr+1], iFreeBlk);
+     put2byte(&data[hdr+5], iEnd);
+   }else{
+     /* Insert the new freeblock into the freelist */
+     put2byte(&data[iPtr], iStart);
+-    put2byte(&data[iStart], iFreeBlk);
+-    put2byte(&data[iStart+2], iSize);
+   }
++  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
++    /* Overwrite deleted information with zeros when the secure_delete
++    ** option is enabled */
++    memset(&data[iStart], 0, iSize);
++  }
++  put2byte(&data[iStart], iFreeBlk);
++  put2byte(&data[iStart+2], iSize);
+   pPage->nFree += iOrigSize;
+   return SQLITE_OK;
+ }
+@@ -61330,7 +64754,7 @@
+   }else{
+     /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
+     ** an error. */
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   pPage->max1bytePayload = pBt->max1bytePayload;
+   return SQLITE_OK;
+@@ -61371,7 +64795,7 @@
+   /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+   ** the b-tree page type. */
+   if( decodeFlags(pPage, data[hdr]) ){
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
+   pPage->maskPage = (u16)(pBt->pageSize - 1);
+@@ -61390,7 +64814,7 @@
+   pPage->nCell = get2byte(&data[hdr+3]);
+   if( pPage->nCell>MX_CELL(pBt) ){
+     /* To many cells for a single page.  The page must be corrupt */
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   testcase( pPage->nCell==MX_CELL(pBt) );
+   /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
+@@ -61418,12 +64842,12 @@
+       testcase( pc==iCellFirst );
+       testcase( pc==iCellLast );
+       if( pc<iCellFirst || pc>iCellLast ){
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+       sz = pPage->xCellSize(pPage, &data[pc]);
+       testcase( pc+sz==usableSize );
+       if( pc+sz>usableSize ){
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+     }
+     if( !pPage->leaf ) iCellLast++;
+@@ -61441,12 +64865,12 @@
+       /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
+       ** always be at least one cell before the first freeblock.
+       */
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno); 
++      return SQLITE_CORRUPT_PAGE(pPage); 
+     }
+     while( 1 ){
+       if( pc>iCellLast ){
+         /* Freeblock off the end of the page */
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+       next = get2byte(&data[pc]);
+       size = get2byte(&data[pc+2]);
+@@ -61456,11 +64880,11 @@
+     }
+     if( next>0 ){
+       /* Freeblock not in ascending order */
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+     if( pc+size>(unsigned int)usableSize ){
+       /* Last freeblock extends past page end */
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+   }
+ 
+@@ -61472,7 +64896,7 @@
+   ** area, according to the page header, lies within the page.
+   */
+   if( nFree>usableSize ){
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   pPage->nFree = (u16)(nFree - iCellFirst);
+   pPage->isInit = 1;
+@@ -61585,7 +65009,7 @@
+ }
+ SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){
+   assert( sqlite3BtreeHoldsMutex(p) );
+-  assert( ((p->pBt->nPage)&0x8000000)==0 );
++  assert( ((p->pBt->nPage)&0x80000000)==0 );
+   return btreePagecount(p->pBt);
+ }
+ 
+@@ -61612,7 +65036,7 @@
+   int rc;
+   DbPage *pDbPage;
+   assert( sqlite3_mutex_held(pBt->mutex) );
+-  assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] );
++  assert( pCur==0 || ppPage==&pCur->pPage );
+   assert( pCur==0 || bReadOnly==pCur->curPagerFlags );
+   assert( pCur==0 || pCur->iPage>0 );
+ 
+@@ -61646,7 +65070,10 @@
+   return SQLITE_OK;
+ 
+ getAndInitPage_error:
+-  if( pCur ) pCur->iPage--;
++  if( pCur ){
++    pCur->iPage--;
++    pCur->pPage = pCur->apPage[pCur->iPage];
++  }
+   testcase( pgno==0 );
+   assert( pgno!=0 || rc==SQLITE_CORRUPT );
+   return rc;
+@@ -61655,6 +65082,8 @@
+ /*
+ ** Release a MemPage.  This should be called once for each prior
+ ** call to btreeGetPage.
++**
++** Page1 is a special case and must be released using releasePageOne().
+ */
+ static void releasePageNotNull(MemPage *pPage){
+   assert( pPage->aData );
+@@ -61668,6 +65097,16 @@
+ static void releasePage(MemPage *pPage){
+   if( pPage ) releasePageNotNull(pPage);
+ }
++static void releasePageOne(MemPage *pPage){
++  assert( pPage!=0 );
++  assert( pPage->aData );
++  assert( pPage->pBt );
++  assert( pPage->pDbPage!=0 );
++  assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
++  assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
++  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
++  sqlite3PagerUnrefPageOne(pPage->pDbPage);
++}
+ 
+ /*
+ ** Get an unused page.
+@@ -61733,7 +65172,8 @@
+   BtShared *pBt = (BtShared*)pArg;
+   assert( pBt->db );
+   assert( sqlite3_mutex_held(pBt->db->mutex) );
+-  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
++  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
++                                  sqlite3PagerFile(pBt->pPager));
+ }
+ 
+ /*
+@@ -61911,7 +65351,7 @@
+     }
+     pBt->openFlags = (u8)flags;
+     pBt->db = db;
+-    sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
++    sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
+     p->pBt = pBt;
+   
+     pBt->pCursor = 0;
+@@ -62452,7 +65892,8 @@
+ ** set to the value passed to this function as the second parameter,
+ ** set it so.
+ */
+-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
++#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \
++    && !defined(SQLITE_OMIT_WAL)
+ static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
+   sqlite3 *db;
+   Db *pDb;
+@@ -62472,6 +65913,10 @@
+ # define setDefaultSyncFlag(pBt,safety_level)
+ #endif
+ 
++/* Forward declaration */
++static int newDatabase(BtShared*);
++
++
+ /*
+ ** Get a reference to pPage1 of the database file.  This will
+ ** also acquire a readlock on that file.
+@@ -62503,6 +65948,9 @@
+   if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
+     nPage = nPageFile;
+   }
++  if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
++    nPage = 0;
++  }
+   if( nPage>0 ){
+     u32 pageSize;
+     u32 usableSize;
+@@ -62546,7 +65994,7 @@
+       }else{
+         setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
+         if( isOpen==0 ){
+-          releasePage(pPage1);
++          releasePageOne(pPage1);
+           return SQLITE_OK;
+         }
+       }
+@@ -62593,7 +66041,7 @@
+       ** zero and return SQLITE_OK. The caller will call this function
+       ** again with the correct page-size.
+       */
+-      releasePage(pPage1);
++      releasePageOne(pPage1);
+       pBt->usableSize = usableSize;
+       pBt->pageSize = pageSize;
+       freeTempSpace(pBt);
+@@ -62601,7 +66049,7 @@
+                                    pageSize-usableSize);
+       return rc;
+     }
+-    if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
++    if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
+       rc = SQLITE_CORRUPT_BKPT;
+       goto page1_init_failed;
+     }
+@@ -62647,7 +66095,7 @@
+   return SQLITE_OK;
+ 
+ page1_init_failed:
+-  releasePage(pPage1);
++  releasePageOne(pPage1);
+   pBt->pPage1 = 0;
+   return rc;
+ }
+@@ -62692,7 +66140,7 @@
+     assert( pPage1->aData );
+     assert( sqlite3PagerRefcount(pBt->pPager)==1 );
+     pBt->pPage1 = 0;
+-    releasePageNotNull(pPage1);
++    releasePageOne(pPage1);
+   }
+ }
+ 
+@@ -62789,7 +66237,7 @@
+ ** when A already has a read lock, we encourage A to give up and let B
+ ** proceed.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
++SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
+   BtShared *pBt = p->pBt;
+   int rc = SQLITE_OK;
+ 
+@@ -62805,6 +66253,12 @@
+   }
+   assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
+ 
++  if( (p->db->flags & SQLITE_ResetDatabase) 
++   && sqlite3PagerIsreadonly(pBt->pPager)==0 
++  ){
++    pBt->btsFlags &= ~BTS_READ_ONLY;
++  }
++
+   /* Write transactions are not possible on a read-only database */
+   if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
+     rc = SQLITE_READONLY;
+@@ -62864,6 +66318,11 @@
+         rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
+         if( rc==SQLITE_OK ){
+           rc = newDatabase(pBt);
++        }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
++          /* if there was no transaction opened when this function was
++          ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
++          ** code to SQLITE_BUSY. */
++          rc = SQLITE_BUSY;
+         }
+       }
+     }
+@@ -62873,6 +66332,7 @@
+     }
+   }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
+           btreeInvokeBusyHandler(pBt) );
++  sqlite3PagerResetLockTimeout(pBt->pPager);
+ 
+   if( rc==SQLITE_OK ){
+     if( p->inTrans==TRANS_NONE ){
+@@ -62914,14 +66374,18 @@
+     }
+   }
+ 
+-
+ trans_begun:
+-  if( rc==SQLITE_OK && wrflag ){
+-    /* This call makes sure that the pager has the correct number of
+-    ** open savepoints. If the second parameter is greater than 0 and
+-    ** the sub-journal is not already open, then it will be opened here.
+-    */
+-    rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
++  if( rc==SQLITE_OK ){
++    if( pSchemaVersion ){
++      *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
++    }
++    if( wrflag ){
++      /* This call makes sure that the pager has the correct number of
++      ** open savepoints. If the second parameter is greater than 0 and
++      ** the sub-journal is not already open, then it will be opened here.
++      */
++      rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
++    }
+   }
+ 
+   btreeIntegrity(p);
+@@ -62987,7 +66451,7 @@
+   if( eType==PTRMAP_OVERFLOW2 ){
+     /* The pointer is always the first 4 bytes of the page in this case.  */
+     if( get4byte(pPage->aData)!=iFrom ){
+-      return SQLITE_CORRUPT_PGNO(pPage->pgno);
++      return SQLITE_CORRUPT_PAGE(pPage);
+     }
+     put4byte(pPage->aData, iTo);
+   }else{
+@@ -63006,7 +66470,7 @@
+         pPage->xParseCell(pPage, pCell, &info);
+         if( info.nLocal<info.nPayload ){
+           if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
+-            return SQLITE_CORRUPT_PGNO(pPage->pgno);
++            return SQLITE_CORRUPT_PAGE(pPage);
+           }
+           if( iFrom==get4byte(pCell+info.nSize-4) ){
+             put4byte(pCell+info.nSize-4, iTo);
+@@ -63024,7 +66488,7 @@
+     if( i==nCell ){
+       if( eType!=PTRMAP_BTREE || 
+           get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
+-        return SQLITE_CORRUPT_PGNO(pPage->pgno);
++        return SQLITE_CORRUPT_PAGE(pPage);
+       }
+       put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
+     }
+@@ -63059,6 +66523,7 @@
+       eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
+   assert( sqlite3_mutex_held(pBt->mutex) );
+   assert( pDbPage->pBt==pBt );
++  if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
+ 
+   /* Move page iDbPage from its current location to page number iFreePage */
+   TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
+@@ -63544,7 +67009,6 @@
+   if( pBtree ){
+     sqlite3BtreeEnter(pBtree);
+     for(p=pBtree->pBt->pCursor; p; p=p->pNext){
+-      int i;
+       if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
+         if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+           rc = saveCursorPosition(p);
+@@ -63558,10 +67022,7 @@
+         p->eState = CURSOR_FAULT;
+         p->skipNext = errCode;
+       }
+-      for(i=0; i<=p->iPage; i++){
+-        releasePage(p->apPage[i]);
+-        p->apPage[i] = 0;
+-      }
++      btreeReleaseAllCursorPages(p);
+     }
+     sqlite3BtreeLeave(pBtree);
+   }
+@@ -63618,7 +67079,7 @@
+       if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
+       testcase( pBt->nPage!=nPage );
+       pBt->nPage = nPage;
+-      releasePage(pPage1);
++      releasePageOne(pPage1);
+     }
+     assert( countValidCursors(pBt, 1)==0 );
+     pBt->inTransaction = TRANS_READ;
+@@ -63850,7 +67311,7 @@
+ ** of run-time by skipping the initialization of those elements.
+ */
+ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
+-  memset(p, 0, offsetof(BtCursor, iPage));
++  memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT));
+ }
+ 
+ /*
+@@ -63860,10 +67321,8 @@
+ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
+   Btree *pBtree = pCur->pBtree;
+   if( pBtree ){
+-    int i;
+     BtShared *pBt = pCur->pBt;
+     sqlite3BtreeEnter(pBtree);
+-    sqlite3BtreeClearCursor(pCur);
+     assert( pBt->pCursor!=0 );
+     if( pBt->pCursor==pCur ){
+       pBt->pCursor = pCur->pNext;
+@@ -63877,12 +67336,10 @@
+         pPrev = pPrev->pNext;
+       }while( ALWAYS(pPrev) );
+     }
+-    for(i=0; i<=pCur->iPage; i++){
+-      releasePage(pCur->apPage[i]);
+-    }
++    btreeReleaseAllCursorPages(pCur);
+     unlockBtreeIfUnused(pBt);
+     sqlite3_free(pCur->aOverflow);
+-    /* sqlite3_free(pCur); */
++    sqlite3_free(pCur->pKey);
+     sqlite3BtreeLeave(pBtree);
+   }
+   return SQLITE_OK;
+@@ -63897,12 +67354,19 @@
+ ** Using this cache reduces the number of calls to btreeParseCell().
+ */
+ #ifndef NDEBUG
++  static int cellInfoEqual(CellInfo *a, CellInfo *b){
++    if( a->nKey!=b->nKey ) return 0;
++    if( a->pPayload!=b->pPayload ) return 0;
++    if( a->nPayload!=b->nPayload ) return 0;
++    if( a->nLocal!=b->nLocal ) return 0;
++    if( a->nSize!=b->nSize ) return 0;
++    return 1;
++  }
+   static void assertCellInfo(BtCursor *pCur){
+     CellInfo info;
+-    int iPage = pCur->iPage;
+     memset(&info, 0, sizeof(info));
+-    btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
+-    assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
++    btreeParseCell(pCur->pPage, pCur->ix, &info);
++    assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
+   }
+ #else
+   #define assertCellInfo(x)
+@@ -63909,9 +67373,8 @@
+ #endif
+ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
+   if( pCur->info.nSize==0 ){
+-    int iPage = pCur->iPage;
+     pCur->curFlags |= BTCF_ValidNKey;
+-    btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
++    btreeParseCell(pCur->pPage,pCur->ix,&pCur->info);
+   }else{
+     assertCellInfo(pCur);
+   }
+@@ -63946,7 +67409,21 @@
+   return pCur->info.nKey;
+ }
+ 
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ /*
++** Return the offset into the database file for the start of the
++** payload to which the cursor is pointing.
++*/
++SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
++  assert( cursorHoldsMutex(pCur) );
++  assert( pCur->eState==CURSOR_VALID );
++  getCellInfo(pCur);
++  return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
++         (i64)(pCur->info.pPayload - pCur->pPage->aData);
++}
++#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
++
++/*
+ ** Return the number of bytes of payload for the entry that pCur is
+ ** currently pointing to.  For table btrees, this will be the amount
+ ** of data.  For index btrees, this will be the size of the key.
+@@ -64109,7 +67586,7 @@
+   unsigned char *aPayload;
+   int rc = SQLITE_OK;
+   int iIdx = 0;
+-  MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
++  MemPage *pPage = pCur->pPage;               /* Btree page of current entry */
+   BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
+ #ifdef SQLITE_DIRECT_OVERFLOW_READ
+   unsigned char * const pBufStart = pBuf;     /* Start of original out buffer */
+@@ -64132,7 +67609,7 @@
+     **    &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
+     ** but is recast into its current form to avoid integer overflow problems
+     */
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+ 
+   /* Check if data must be read/written to/from the btree page itself. */
+@@ -64165,7 +67642,9 @@
+     */
+     if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
+       int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
+-      if( nOvfl>pCur->nOvflAlloc ){
++      if( pCur->aOverflow==0
++       || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
++      ){
+         Pgno *aNew = (Pgno*)sqlite3Realloc(
+             pCur->aOverflow, nOvfl*2*sizeof(Pgno)
+         );
+@@ -64172,7 +67651,6 @@
+         if( aNew==0 ){
+           return SQLITE_NOMEM_BKPT;
+         }else{
+-          pCur->nOvflAlloc = nOvfl*2;
+           pCur->aOverflow = aNew;
+         }
+       }
+@@ -64217,9 +67695,6 @@
+         /* Need to read this page properly. It contains some of the
+         ** range of data that is being read (eOp==0) or written (eOp!=0).
+         */
+-#ifdef SQLITE_DIRECT_OVERFLOW_READ
+-        sqlite3_file *fd;      /* File from which to do direct overflow read */
+-#endif
+         int a = amt;
+         if( a + offset > ovflSize ){
+           a = ovflSize - offset;
+@@ -64230,7 +67705,7 @@
+         **
+         **   1) this is a read operation, and 
+         **   2) data is required from the start of this overflow page, and
+-        **   3) there is no open write-transaction, and
++        **   3) there are no dirty pages in the page-cache
+         **   4) the database is file-backed, and
+         **   5) the page is not in the WAL file
+         **   6) at least 4 bytes have already been read into the output buffer 
+@@ -64241,11 +67716,10 @@
+         */
+         if( eOp==0                                             /* (1) */
+          && offset==0                                          /* (2) */
+-         && pBt->inTransaction==TRANS_READ                     /* (3) */
+-         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (4) */
+-         && 0==sqlite3PagerUseWal(pBt->pPager, nextPage)       /* (5) */
++         && sqlite3PagerDirectReadOk(pBt->pPager, nextPage)    /* (3,4,5) */
+          && &pBuf[-4]>=pBufStart                               /* (6) */
+         ){
++          sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
+           u8 aSave[4];
+           u8 *aWrite = &pBuf[-4];
+           assert( aWrite>=pBufStart );                         /* due to (6) */
+@@ -64280,7 +67754,7 @@
+ 
+   if( rc==SQLITE_OK && amt>0 ){
+     /* Overflow chain ends prematurely */
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   return rc;
+ }
+@@ -64305,8 +67779,8 @@
+ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+   assert( cursorHoldsMutex(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+-  assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
+-  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++  assert( pCur->iPage>=0 && pCur->pPage );
++  assert( pCur->ix<pCur->pPage->nCell );
+   return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
+ }
+ 
+@@ -64363,18 +67837,23 @@
+   BtCursor *pCur,      /* Cursor pointing to entry to read from */
+   u32 *pAmt            /* Write the number of available bytes here */
+ ){
+-  u32 amt;
+-  assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
++  int amt;
++  assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
+   assert( pCur->eState==CURSOR_VALID );
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+   assert( cursorOwnsBtShared(pCur) );
+-  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++  assert( pCur->ix<pCur->pPage->nCell );
+   assert( pCur->info.nSize>0 );
+-  assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
+-  assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
+-  amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
+-  if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
+-  *pAmt = amt;
++  assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
++  assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
++  amt = pCur->info.nLocal;
++  if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
++    /* There is too little space on the page for the expected amount
++    ** of local content. Database must be corrupt. */
++    assert( CORRUPT_DB );
++    amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
++  }
++  *pAmt = (u32)amt;
+   return (void*)pCur->info.pPayload;
+ }
+ 
+@@ -64419,10 +67898,11 @@
+   }
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+-  pCur->aiIdx[pCur->iPage++] = pCur->ix;
++  pCur->aiIdx[pCur->iPage] = pCur->ix;
++  pCur->apPage[pCur->iPage] = pCur->pPage;
+   pCur->ix = 0;
+-  return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
+-                        pCur, pCur->curPagerFlags);
++  pCur->iPage++;
++  return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags);
+ }
+ 
+ #ifdef SQLITE_DEBUG
+@@ -64456,20 +67936,23 @@
+ ** the largest cell index.
+ */
+ static void moveToParent(BtCursor *pCur){
++  MemPage *pLeaf;
+   assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+   assert( pCur->iPage>0 );
+-  assert( pCur->apPage[pCur->iPage] );
++  assert( pCur->pPage );
+   assertParentIndex(
+     pCur->apPage[pCur->iPage-1], 
+     pCur->aiIdx[pCur->iPage-1], 
+-    pCur->apPage[pCur->iPage]->pgno
++    pCur->pPage->pgno
+   );
+   testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+   pCur->ix = pCur->aiIdx[pCur->iPage-1];
+-  releasePageNotNull(pCur->apPage[pCur->iPage--]);
++  pLeaf = pCur->pPage;
++  pCur->pPage = pCur->apPage[--pCur->iPage];
++  releasePageNotNull(pLeaf);
+ }
+ 
+ /*
+@@ -64481,9 +67964,9 @@
+ ** single child page. This can only happen with the table rooted at page 1.
+ **
+ ** If the b-tree structure is empty, the cursor state is set to 
+-** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
+-** cell located on the root (or virtual root) page and the cursor state
+-** is set to CURSOR_VALID.
++** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise,
++** the cursor is set to point to the first cell located on the root
++** (or virtual root) page and the cursor state is set to CURSOR_VALID.
+ **
+ ** If this function returns successfully, it may be assumed that the
+ ** page-header flags indicate that the [virtual] root-page is the expected 
+@@ -64501,37 +67984,40 @@
+   assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
+   assert( CURSOR_VALID   < CURSOR_REQUIRESEEK );
+   assert( CURSOR_FAULT   > CURSOR_REQUIRESEEK );
+-  if( pCur->eState>=CURSOR_REQUIRESEEK ){
+-    if( pCur->eState==CURSOR_FAULT ){
+-      assert( pCur->skipNext!=SQLITE_OK );
+-      return pCur->skipNext;
+-    }
+-    sqlite3BtreeClearCursor(pCur);
+-  }
++  assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 );
++  assert( pCur->pgnoRoot>0 || pCur->iPage<0 );
+ 
+   if( pCur->iPage>=0 ){
+     if( pCur->iPage ){
+-      do{
+-        assert( pCur->apPage[pCur->iPage]!=0 );
+-        releasePageNotNull(pCur->apPage[pCur->iPage--]);
+-      }while( pCur->iPage);
++      releasePageNotNull(pCur->pPage);
++      while( --pCur->iPage ){
++        releasePageNotNull(pCur->apPage[pCur->iPage]);
++      }
++      pCur->pPage = pCur->apPage[0];
+       goto skip_init;
+     }
+   }else if( pCur->pgnoRoot==0 ){
+     pCur->eState = CURSOR_INVALID;
+-    return SQLITE_OK;
++    return SQLITE_EMPTY;
+   }else{
+     assert( pCur->iPage==(-1) );
+-    rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
++    if( pCur->eState>=CURSOR_REQUIRESEEK ){
++      if( pCur->eState==CURSOR_FAULT ){
++        assert( pCur->skipNext!=SQLITE_OK );
++        return pCur->skipNext;
++      }
++      sqlite3BtreeClearCursor(pCur);
++    }
++    rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage,
+                         0, pCur->curPagerFlags);
+     if( rc!=SQLITE_OK ){
+       pCur->eState = CURSOR_INVALID;
+-       return rc;
++      return rc;
+     }
+     pCur->iPage = 0;
+-    pCur->curIntKey = pCur->apPage[0]->intKey;
++    pCur->curIntKey = pCur->pPage->intKey;
+   }
+-  pRoot = pCur->apPage[0];
++  pRoot = pCur->pPage;
+   assert( pRoot->pgno==pCur->pgnoRoot );
+ 
+   /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
+@@ -64546,7 +68032,7 @@
+   ** (or the freelist).  */
+   assert( pRoot->intKey==1 || pRoot->intKey==0 );
+   if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
+-    return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
++    return SQLITE_CORRUPT_PAGE(pCur->pPage);
+   }
+ 
+ skip_init:  
+@@ -64554,7 +68040,7 @@
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
+ 
+-  pRoot = pCur->apPage[0];
++  pRoot = pCur->pPage;
+   if( pRoot->nCell>0 ){
+     pCur->eState = CURSOR_VALID;
+   }else if( !pRoot->leaf ){
+@@ -64565,6 +68051,7 @@
+     rc = moveToChild(pCur, subpage);
+   }else{
+     pCur->eState = CURSOR_INVALID;
++    rc = SQLITE_EMPTY;
+   }
+   return rc;
+ }
+@@ -64583,7 +68070,7 @@
+ 
+   assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+-  while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
++  while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
+     assert( pCur->ix<pPage->nCell );
+     pgno = get4byte(findCell(pPage, pCur->ix));
+     rc = moveToChild(pCur, pgno);
+@@ -64608,7 +68095,7 @@
+ 
+   assert( cursorOwnsBtShared(pCur) );
+   assert( pCur->eState==CURSOR_VALID );
+-  while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
++  while( !(pPage = pCur->pPage)->leaf ){
+     pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+     pCur->ix = pPage->nCell;
+     rc = moveToChild(pCur, pgno);
+@@ -64631,18 +68118,34 @@
+   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+   rc = moveToRoot(pCur);
+   if( rc==SQLITE_OK ){
+-    if( pCur->eState==CURSOR_INVALID ){
+-      assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
+-      *pRes = 1;
+-    }else{
+-      assert( pCur->apPage[pCur->iPage]->nCell>0 );
+-      *pRes = 0;
+-      rc = moveToLeftmost(pCur);
+-    }
++    assert( pCur->pPage->nCell>0 );
++    *pRes = 0;
++    rc = moveToLeftmost(pCur);
++  }else if( rc==SQLITE_EMPTY ){
++    assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
++    *pRes = 1;
++    rc = SQLITE_OK;
+   }
+   return rc;
+ }
+ 
++/*
++** This function is a no-op if cursor pCur does not point to a valid row.
++** Otherwise, if pCur is valid, configure it so that the next call to
++** sqlite3BtreeNext() is a no-op.
++*/
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){
++  /* We believe that the cursor must always be in the valid state when
++  ** this routine is called, but the proof is difficult, so we add an
++  ** ALWaYS() test just in case we are wrong. */
++  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
++    pCur->eState = CURSOR_SKIPNEXT;
++    pCur->skipNext = 1;
++  }
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
+ /* Move the cursor to the last entry in the table.  Return SQLITE_OK
+ ** on success.  Set *pRes to 0 if the cursor actually points to something
+ ** or set *pRes to 1 if the table is empty.
+@@ -64662,8 +68165,8 @@
+     for(ii=0; ii<pCur->iPage; ii++){
+       assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
+     }
+-    assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
+-    assert( pCur->apPage[pCur->iPage]->leaf );
++    assert( pCur->ix==pCur->pPage->nCell-1 );
++    assert( pCur->pPage->leaf );
+ #endif
+     return SQLITE_OK;
+   }
+@@ -64670,20 +68173,18 @@
+ 
+   rc = moveToRoot(pCur);
+   if( rc==SQLITE_OK ){
+-    if( CURSOR_INVALID==pCur->eState ){
+-      assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
+-      *pRes = 1;
++    assert( pCur->eState==CURSOR_VALID );
++    *pRes = 0;
++    rc = moveToRightmost(pCur);
++    if( rc==SQLITE_OK ){
++      pCur->curFlags |= BTCF_AtLast;
+     }else{
+-      assert( pCur->eState==CURSOR_VALID );
+-      *pRes = 0;
+-      rc = moveToRightmost(pCur);
+-      if( rc==SQLITE_OK ){
+-        pCur->curFlags |= BTCF_AtLast;
+-      }else{
+-        pCur->curFlags &= ~BTCF_AtLast;
+-      }
+-   
++      pCur->curFlags &= ~BTCF_AtLast;
+     }
++  }else if( rc==SQLITE_EMPTY ){
++    assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
++    *pRes = 1;
++    rc = SQLITE_OK;
+   }
+   return rc;
+ }
+@@ -64782,22 +68283,23 @@
+ 
+   rc = moveToRoot(pCur);
+   if( rc ){
++    if( rc==SQLITE_EMPTY ){
++      assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
++      *pRes = -1;
++      return SQLITE_OK;
++    }
+     return rc;
+   }
+-  assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] );
+-  assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit );
+-  assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 );
+-  if( pCur->eState==CURSOR_INVALID ){
+-    *pRes = -1;
+-    assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
+-    return SQLITE_OK;
+-  }
+-  assert( pCur->apPage[0]->intKey==pCur->curIntKey );
++  assert( pCur->pPage );
++  assert( pCur->pPage->isInit );
++  assert( pCur->eState==CURSOR_VALID );
++  assert( pCur->pPage->nCell > 0 );
++  assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
+   assert( pCur->curIntKey || pIdxKey );
+   for(;;){
+     int lwr, upr, idx, c;
+     Pgno chldPg;
+-    MemPage *pPage = pCur->apPage[pCur->iPage];
++    MemPage *pPage = pCur->pPage;
+     u8 *pCell;                          /* Pointer to current cell in pPage */
+ 
+     /* pPage->nCell must be greater than zero. If this is the root-page
+@@ -64820,7 +68322,7 @@
+         if( pPage->intKeyLeaf ){
+           while( 0x80 <= *(pCell++) ){
+             if( pCell>=pPage->aDataEnd ){
+-              return SQLITE_CORRUPT_PGNO(pPage->pgno);
++              return SQLITE_CORRUPT_PAGE(pPage);
+             }
+           }
+         }
+@@ -64894,7 +68396,7 @@
+           testcase( nCell==1 );  /* Invalid key size:  0x80 0x80 0x01 */
+           testcase( nCell==2 );  /* Minimum legal index key size */
+           if( nCell<2 ){
+-            rc = SQLITE_CORRUPT_PGNO(pPage->pgno);
++            rc = SQLITE_CORRUPT_PAGE(pPage);
+             goto moveto_finish;
+           }
+           pCellKey = sqlite3Malloc( nCell+18 );
+@@ -64925,7 +68427,7 @@
+           *pRes = 0;
+           rc = SQLITE_OK;
+           pCur->ix = (u16)idx;
+-          if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
++          if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT;
+           goto moveto_finish;
+         }
+         if( lwr>upr ) break;
+@@ -64936,7 +68438,7 @@
+     assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
+     assert( pPage->isInit );
+     if( pPage->leaf ){
+-      assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++      assert( pCur->ix<pCur->pPage->nCell );
+       pCur->ix = (u16)idx;
+       *pRes = c;
+       rc = SQLITE_OK;
+@@ -64990,9 +68492,10 @@
+   ** 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;
++  if( NEVER(pCur->pPage->leaf==0) ) return -1;
+ 
+-  for(n=1, i=0; i<=pCur->iPage; i++){
++  n = pCur->pPage->nCell;
++  for(i=0; i<pCur->iPage; i++){
+     n *= pCur->apPage[i]->nCell;
+   }
+   return n;
+@@ -65045,9 +68548,18 @@
+     }
+   }
+ 
+-  pPage = pCur->apPage[pCur->iPage];
++  pPage = pCur->pPage;
+   idx = ++pCur->ix;
+-  assert( pPage->isInit );
++  if( !pPage->isInit ){
++    /* The only known way for this to happen is for there to be a
++    ** recursive SQL function that does a DELETE operation as part of a
++    ** SELECT which deletes content out from under an active cursor
++    ** in a corrupt database file where the table being DELETE-ed from
++    ** has pages in common with the table being queried.  See TH3
++    ** module cov1/btree78.test testcase 220 (2018-06-08) for an
++    ** example. */
++    return SQLITE_CORRUPT_BKPT;
++  }
+ 
+   /* If the database file is corrupt, it is possible for the value of idx 
+   ** to be invalid here. This can only occur if a second cursor modifies
+@@ -65068,7 +68580,7 @@
+         return SQLITE_DONE;
+       }
+       moveToParent(pCur);
+-      pPage = pCur->apPage[pCur->iPage];
++      pPage = pCur->pPage;
+     }while( pCur->ix>=pPage->nCell );
+     if( pPage->intKey ){
+       return sqlite3BtreeNext(pCur, 0);
+@@ -65091,7 +68603,7 @@
+   pCur->info.nSize = 0;
+   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+   if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
+-  pPage = pCur->apPage[pCur->iPage];
++  pPage = pCur->pPage;
+   if( (++pCur->ix)>=pPage->nCell ){
+     pCur->ix--;
+     return btreeNext(pCur);
+@@ -65150,7 +68662,7 @@
+     }
+   }
+ 
+-  pPage = pCur->apPage[pCur->iPage];
++  pPage = pCur->pPage;
+   assert( pPage->isInit );
+   if( !pPage->leaf ){
+     int idx = pCur->ix;
+@@ -65169,7 +68681,7 @@
+     assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
+ 
+     pCur->ix--;
+-    pPage = pCur->apPage[pCur->iPage];
++    pPage = pCur->pPage;
+     if( pPage->intKey && !pPage->leaf ){
+       rc = sqlite3BtreePrevious(pCur, 0);
+     }else{
+@@ -65187,7 +68699,7 @@
+   pCur->info.nSize = 0;
+   if( pCur->eState!=CURSOR_VALID
+    || pCur->ix==0
+-   || pCur->apPage[pCur->iPage]->leaf==0
++   || pCur->pPage->leaf==0
+   ){
+     return btreePrevious(pCur);
+   }
+@@ -65674,9 +69186,8 @@
+ }
+ 
+ /*
+-** Free any overflow pages associated with the given Cell.  Write the
+-** local Cell size (the number of bytes on the original page, omitting
+-** overflow) into *pnSize.
++** Free any overflow pages associated with the given Cell.  Store
++** size information about the cell in pInfo.
+ */
+ static int clearCell(
+   MemPage *pPage,          /* The page that contains the Cell */
+@@ -65683,7 +69194,7 @@
+   unsigned char *pCell,    /* First byte of the Cell */
+   CellInfo *pInfo          /* Size information about the cell */
+ ){
+-  BtShared *pBt = pPage->pBt;
++  BtShared *pBt;
+   Pgno ovflPgno;
+   int rc;
+   int nOvfl;
+@@ -65694,11 +69205,14 @@
+   if( pInfo->nLocal==pInfo->nPayload ){
+     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
+   }
+-  if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
++  testcase( pCell + pInfo->nSize == pPage->aDataEnd );
++  testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
++  if( pCell + pInfo->nSize > pPage->aDataEnd ){
+     /* Cell extends past end of page */
+-    return SQLITE_CORRUPT_PGNO(pPage->pgno);
++    return SQLITE_CORRUPT_PAGE(pPage);
+   }
+   ovflPgno = get4byte(pCell + pInfo->nSize - 4);
++  pBt = pPage->pBt;
+   assert( pBt->usableSize > 4 );
+   ovflPageSize = pBt->usableSize - 4;
+   nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
+@@ -65766,14 +69280,13 @@
+ ){
+   int nPayload;
+   const u8 *pSrc;
+-  int nSrc, n, rc;
++  int nSrc, n, rc, mn;
+   int spaceLeft;
+-  MemPage *pOvfl = 0;
+-  MemPage *pToRelease = 0;
++  MemPage *pToRelease;
+   unsigned char *pPrior;
+   unsigned char *pPayload;
+-  BtShared *pBt = pPage->pBt;
+-  Pgno pgnoOvfl = 0;
++  BtShared *pBt;
++  Pgno pgnoOvfl;
+   int nHeader;
+ 
+   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+@@ -65780,7 +69293,7 @@
+ 
+   /* pPage is not necessarily writeable since pCell might be auxiliary
+   ** buffer space that is separate from the pPage buffer area */
+-  assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
++  assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize]
+             || sqlite3PagerIswriteable(pPage->pDbPage) );
+ 
+   /* Fill in the header. */
+@@ -65800,26 +69313,37 @@
+   }
+   
+   /* Fill in the payload */
++  pPayload = &pCell[nHeader];
+   if( nPayload<=pPage->maxLocal ){
++    /* This is the common case where everything fits on the btree page
++    ** and no overflow pages are required. */
+     n = nHeader + nPayload;
+     testcase( n==3 );
+     testcase( n==4 );
+     if( n<4 ) n = 4;
+     *pnSize = n;
+-    spaceLeft = nPayload;
+-    pPrior = pCell;
+-  }else{
+-    int mn = pPage->minLocal;
+-    n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
+-    testcase( n==pPage->maxLocal );
+-    testcase( n==pPage->maxLocal+1 );
+-    if( n > pPage->maxLocal ) n = mn;
+-    spaceLeft = n;
+-    *pnSize = n + nHeader + 4;
+-    pPrior = &pCell[nHeader+n];
++    assert( nSrc<=nPayload );
++    testcase( nSrc<nPayload );
++    memcpy(pPayload, pSrc, nSrc);
++    memset(pPayload+nSrc, 0, nPayload-nSrc);
++    return SQLITE_OK;
+   }
+-  pPayload = &pCell[nHeader];
+ 
++  /* If we reach this point, it means that some of the content will need
++  ** to spill onto overflow pages.
++  */
++  mn = pPage->minLocal;
++  n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
++  testcase( n==pPage->maxLocal );
++  testcase( n==pPage->maxLocal+1 );
++  if( n > pPage->maxLocal ) n = mn;
++  spaceLeft = n;
++  *pnSize = n + nHeader + 4;
++  pPrior = &pCell[nHeader+n];
++  pToRelease = 0;
++  pgnoOvfl = 0;
++  pBt = pPage->pBt;
++
+   /* At this point variables should be set as follows:
+   **
+   **   nPayload           Total payload size in bytes
+@@ -65844,8 +69368,35 @@
+ #endif
+ 
+   /* Write the payload into the local Cell and any extra into overflow pages */
+-  while( nPayload>0 ){
++  while( 1 ){
++    n = nPayload;
++    if( n>spaceLeft ) n = spaceLeft;
++
++    /* If pToRelease is not zero than pPayload points into the data area
++    ** of pToRelease.  Make sure pToRelease is still writeable. */
++    assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
++
++    /* If pPayload is part of the data area of pPage, then make sure pPage
++    ** is still writeable */
++    assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
++            || sqlite3PagerIswriteable(pPage->pDbPage) );
++
++    if( nSrc>=n ){
++      memcpy(pPayload, pSrc, n);
++    }else if( nSrc>0 ){
++      n = nSrc;
++      memcpy(pPayload, pSrc, n);
++    }else{
++      memset(pPayload, 0, n);
++    }
++    nPayload -= n;
++    if( nPayload<=0 ) break;
++    pPayload += n;
++    pSrc += n;
++    nSrc -= n;
++    spaceLeft -= n;
+     if( spaceLeft==0 ){
++      MemPage *pOvfl = 0;
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+       Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
+       if( pBt->autoVacuum ){
+@@ -65898,30 +69449,6 @@
+       pPayload = &pOvfl->aData[4];
+       spaceLeft = pBt->usableSize - 4;
+     }
+-    n = nPayload;
+-    if( n>spaceLeft ) n = spaceLeft;
+-
+-    /* If pToRelease is not zero than pPayload points into the data area
+-    ** of pToRelease.  Make sure pToRelease is still writeable. */
+-    assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
+-
+-    /* If pPayload is part of the data area of pPage, then make sure pPage
+-    ** is still writeable */
+-    assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
+-            || sqlite3PagerIswriteable(pPage->pDbPage) );
+-
+-    if( nSrc>0 ){
+-      if( n>nSrc ) n = nSrc;
+-      assert( pSrc );
+-      memcpy(pPayload, pSrc, n);
+-    }else{
+-      memset(pPayload, 0, n);
+-    }
+-    nPayload -= n;
+-    pPayload += n;
+-    pSrc += n;
+-    nSrc -= n;
+-    spaceLeft -= n;
+   }
+   releasePage(pToRelease);
+   return SQLITE_OK;
+@@ -65953,7 +69480,7 @@
+   hdr = pPage->hdrOffset;
+   testcase( pc==get2byte(&data[hdr+5]) );
+   testcase( pc+sz==pPage->pBt->usableSize );
+-  if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
++  if( pc+sz > pPage->pBt->usableSize ){
+     *pRC = SQLITE_CORRUPT_BKPT;
+     return;
+   }
+@@ -66820,10 +70347,8 @@
+      + nMaxCells*sizeof(u16)                       /* b.szCell */
+      + pBt->pageSize;                              /* aSpace1 */
+ 
+-  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
+-  ** that is more than 6 times the database page size. */
+   assert( szScratch<=6*(int)pBt->pageSize );
+-  b.apCell = sqlite3ScratchMalloc( szScratch ); 
++  b.apCell = sqlite3StackAllocRaw(0, szScratch );
+   if( b.apCell==0 ){
+     rc = SQLITE_NOMEM_BKPT;
+     goto balance_cleanup;
+@@ -66868,7 +70393,7 @@
+     }
+ 
+     /* Load b.apCell[] with pointers to all cells in pOld.  If pOld
+-    ** constains overflow cells, include them in the b.apCell[] array
++    ** contains overflow cells, include them in the b.apCell[] array
+     ** in the correct spot.
+     **
+     ** Note that when there are multiple overflow cells, it is always the
+@@ -67401,7 +70926,7 @@
+   ** Cleanup before returning.
+   */
+ balance_cleanup:
+-  sqlite3ScratchFree(b.apCell);
++  sqlite3StackFree(0, b.apCell);
+   for(i=0; i<nOld; i++){
+     releasePage(apOld[i]);
+   }
+@@ -67500,7 +71025,7 @@
+ 
+   do {
+     int iPage = pCur->iPage;
+-    MemPage *pPage = pCur->apPage[iPage];
++    MemPage *pPage = pCur->pPage;
+ 
+     if( iPage==0 ){
+       if( pPage->nOverflow ){
+@@ -67516,7 +71041,9 @@
+           pCur->iPage = 1;
+           pCur->ix = 0;
+           pCur->aiIdx[0] = 0;
+-          assert( pCur->apPage[1]->nOverflow );
++          pCur->apPage[0] = pPage;
++          pCur->pPage = pCur->apPage[1];
++          assert( pCur->pPage->nOverflow );
+         }
+       }else{
+         break;
+@@ -67596,6 +71123,7 @@
+       releasePage(pPage);
+       pCur->iPage--;
+       assert( pCur->iPage>=0 );
++      pCur->pPage = pCur->apPage[pCur->iPage];
+     }
+   }while( rc==SQLITE_OK );
+ 
+@@ -67605,8 +71133,96 @@
+   return rc;
+ }
+ 
++/* Overwrite content from pX into pDest.  Only do the write if the
++** content is different from what is already there.
++*/
++static int btreeOverwriteContent(
++  MemPage *pPage,           /* MemPage on which writing will occur */
++  u8 *pDest,                /* Pointer to the place to start writing */
++  const BtreePayload *pX,   /* Source of data to write */
++  int iOffset,              /* Offset of first byte to write */
++  int iAmt                  /* Number of bytes to be written */
++){
++  int nData = pX->nData - iOffset;
++  if( nData<=0 ){
++    /* Overwritting with zeros */
++    int i;
++    for(i=0; i<iAmt && pDest[i]==0; i++){}
++    if( i<iAmt ){
++      int rc = sqlite3PagerWrite(pPage->pDbPage);
++      if( rc ) return rc;
++      memset(pDest + i, 0, iAmt - i);
++    }
++  }else{
++    if( nData<iAmt ){
++      /* Mixed read data and zeros at the end.  Make a recursive call
++      ** to write the zeros then fall through to write the real data */
++      int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData,
++                                 iAmt-nData);
++      if( rc ) return rc;
++      iAmt = nData;
++    }
++    if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
++      int rc = sqlite3PagerWrite(pPage->pDbPage);
++      if( rc ) return rc;
++      memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
++    }
++  }
++  return SQLITE_OK;
++}
+ 
+ /*
++** Overwrite the cell that cursor pCur is pointing to with fresh content
++** contained in pX.
++*/
++static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
++  int iOffset;                        /* Next byte of pX->pData to write */
++  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
++  int rc;                             /* Return code */
++  MemPage *pPage = pCur->pPage;       /* Page being written */
++  BtShared *pBt;                      /* Btree */
++  Pgno ovflPgno;                      /* Next overflow page to write */
++  u32 ovflPageSize;                   /* Size to write on overflow page */
++
++  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
++    return SQLITE_CORRUPT_BKPT;
++  }
++  /* Overwrite the local portion first */
++  rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
++                             0, pCur->info.nLocal);
++  if( rc ) return rc;
++  if( pCur->info.nLocal==nTotal ) return SQLITE_OK;
++
++  /* Now overwrite the overflow pages */
++  iOffset = pCur->info.nLocal;
++  assert( nTotal>=0 );
++  assert( iOffset>=0 );
++  ovflPgno = get4byte(pCur->info.pPayload + iOffset);
++  pBt = pPage->pBt;
++  ovflPageSize = pBt->usableSize - 4;
++  do{
++    rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
++    if( rc ) return rc;
++    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){
++      rc = SQLITE_CORRUPT_BKPT;
++    }else{
++      if( iOffset+ovflPageSize<(u32)nTotal ){
++        ovflPgno = get4byte(pPage->aData);
++      }else{
++        ovflPageSize = nTotal - iOffset;
++      }
++      rc = btreeOverwriteContent(pPage, pPage->aData+4, pX,
++                                 iOffset, ovflPageSize);
++    }
++    sqlite3PagerUnref(pPage->pDbPage);
++    if( rc ) return rc;
++    iOffset += ovflPageSize;
++  }while( iOffset<nTotal );
++  return SQLITE_OK;    
++}
++
++
++/*
+ ** Insert a new record into the BTree.  The content of the new record
+ ** is described by the pX object.  The pCur cursor is used only to
+ ** define what table the record should be inserted into, and is left
+@@ -67695,39 +71311,90 @@
+     invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
+ 
+     /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
+-    ** to a row with the same key as the new entry being inserted.  */
+-    assert( (flags & BTREE_SAVEPOSITION)==0 || 
+-            ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
++    ** to a row with the same key as the new entry being inserted.
++    */
++#ifdef SQLITE_DEBUG
++    if( flags & BTREE_SAVEPOSITION ){
++      assert( pCur->curFlags & BTCF_ValidNKey );
++      assert( pX->nKey==pCur->info.nKey );
++      assert( pCur->info.nSize!=0 );
++      assert( loc==0 );
++    }
++#endif
+ 
+-    /* If the cursor is currently on the last row and we are appending a
+-    ** new row onto the end, set the "loc" to avoid an unnecessary
+-    ** btreeMoveto() call */
++    /* On the other hand, BTREE_SAVEPOSITION==0 does not imply
++    ** that the cursor is not pointing to a row to be overwritten.
++    ** So do a complete check.
++    */
+     if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
+-      loc = 0;
++      /* The cursor is pointing to the entry that is to be
++      ** overwritten */
++      assert( pX->nData>=0 && pX->nZero>=0 );
++      if( pCur->info.nSize!=0
++       && pCur->info.nPayload==(u32)pX->nData+pX->nZero
++      ){
++        /* New entry is the same size as the old.  Do an overwrite */
++        return btreeOverwriteCell(pCur, pX);
++      }
++      assert( loc==0 );
+     }else if( loc==0 ){
++      /* The cursor is *not* pointing to the cell to be overwritten, nor
++      ** to an adjacent cell.  Move the cursor so that it is pointing either
++      ** to the cell to be overwritten or an adjacent cell.
++      */
+       rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
+       if( rc ) return rc;
+     }
+-  }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
+-    if( pX->nMem ){
+-      UnpackedRecord r;
+-      r.pKeyInfo = pCur->pKeyInfo;
+-      r.aMem = pX->aMem;
+-      r.nField = pX->nMem;
+-      r.default_rc = 0;
+-      r.errCode = 0;
+-      r.r1 = 0;
+-      r.r2 = 0;
+-      r.eqSeen = 0;
+-      rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
+-    }else{
+-      rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
++  }else{
++    /* This is an index or a WITHOUT ROWID table */
++
++    /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
++    ** to a row with the same key as the new entry being inserted.
++    */
++    assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 );
++
++    /* If the cursor is not already pointing either to the cell to be
++    ** overwritten, or if a new cell is being inserted, if the cursor is
++    ** not pointing to an immediately adjacent cell, then move the cursor
++    ** so that it does.
++    */
++    if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
++      if( pX->nMem ){
++        UnpackedRecord r;
++        r.pKeyInfo = pCur->pKeyInfo;
++        r.aMem = pX->aMem;
++        r.nField = pX->nMem;
++        r.default_rc = 0;
++        r.errCode = 0;
++        r.r1 = 0;
++        r.r2 = 0;
++        r.eqSeen = 0;
++        rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
++      }else{
++        rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
++      }
++      if( rc ) return rc;
+     }
+-    if( rc ) return rc;
++
++    /* If the cursor is currently pointing to an entry to be overwritten
++    ** and the new content is the same as as the old, then use the
++    ** overwrite optimization.
++    */
++    if( loc==0 ){
++      getCellInfo(pCur);
++      if( pCur->info.nKey==pX->nKey ){
++        BtreePayload x2;
++        x2.pData = pX->pKey;
++        x2.nData = pX->nKey;
++        x2.nZero = 0;
++        return btreeOverwriteCell(pCur, &x2);
++      }
++    }
++
+   }
+   assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
+ 
+-  pPage = pCur->apPage[pCur->iPage];
++  pPage = pCur->pPage;
+   assert( pPage->intKey || pX->nKey>=0 );
+   assert( pPage->leaf || !pPage->intKey );
+ 
+@@ -67814,10 +71481,10 @@
+     ** fails. Internal data structure corruption will result otherwise. 
+     ** Also, set the cursor state to invalid. This stops saveCursorPosition()
+     ** from trying to save the current position of the cursor.  */
+-    pCur->apPage[pCur->iPage]->nOverflow = 0;
++    pCur->pPage->nOverflow = 0;
+     pCur->eState = CURSOR_INVALID;
+     if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
+-      rc = moveToRoot(pCur);
++      btreeReleaseAllCursorPages(pCur);
+       if( pCur->pKeyInfo ){
+         assert( pCur->pKey==0 );
+         pCur->pKey = sqlite3Malloc( pX->nKey );
+@@ -67831,7 +71498,7 @@
+       pCur->nKey = pX->nKey;
+     }
+   }
+-  assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
++  assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );
+ 
+ end_insert:
+   return rc;
+@@ -67872,13 +71539,13 @@
+   assert( pCur->curFlags & BTCF_WriteFlag );
+   assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
+   assert( !hasReadConflicts(p, pCur->pgnoRoot) );
+-  assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
++  assert( pCur->ix<pCur->pPage->nCell );
+   assert( pCur->eState==CURSOR_VALID );
+   assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
+ 
+   iCellDepth = pCur->iPage;
+   iCellIdx = pCur->ix;
+-  pPage = pCur->apPage[iCellDepth];
++  pPage = pCur->pPage;
+   pCell = findCell(pPage, iCellIdx);
+ 
+   /* If the bPreserve flag is set to true, then the cursor position must
+@@ -67944,11 +71611,16 @@
+   ** node. The cell from the leaf node needs to be moved to the internal
+   ** node to replace the deleted cell.  */
+   if( !pPage->leaf ){
+-    MemPage *pLeaf = pCur->apPage[pCur->iPage];
++    MemPage *pLeaf = pCur->pPage;
+     int nCell;
+-    Pgno n = pCur->apPage[iCellDepth+1]->pgno;
++    Pgno n;
+     unsigned char *pTmp;
+ 
++    if( iCellDepth<pCur->iPage-1 ){
++      n = pCur->apPage[iCellDepth+1]->pgno;
++    }else{
++      n = pCur->pPage->pgno;
++    }
+     pCell = findCell(pLeaf, pLeaf->nCell-1);
+     if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
+     nCell = pLeaf->xCellSize(pLeaf, pCell);
+@@ -67980,9 +71652,12 @@
+   ** well.  */
+   rc = balance(pCur);
+   if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
++    releasePageNotNull(pCur->pPage);
++    pCur->iPage--;
+     while( pCur->iPage>iCellDepth ){
+       releasePage(pCur->apPage[pCur->iPage--]);
+     }
++    pCur->pPage = pCur->apPage[pCur->iPage];
+     rc = balance(pCur);
+   }
+ 
+@@ -67989,7 +71664,7 @@
+   if( rc==SQLITE_OK ){
+     if( bSkipnext ){
+       assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
+-      assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
++      assert( pPage==pCur->pPage || CORRUPT_DB );
+       assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
+       pCur->eState = CURSOR_SKIPNEXT;
+       if( iCellIdx>=pPage->nCell ){
+@@ -68001,8 +71676,10 @@
+     }else{
+       rc = moveToRoot(pCur);
+       if( bPreserve ){
++        btreeReleaseAllCursorPages(pCur);
+         pCur->eState = CURSOR_REQUIRESEEK;
+       }
++      if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
+     }
+   }
+   return rc;
+@@ -68467,11 +72144,11 @@
+   i64 nEntry = 0;                      /* Value to return in *pnEntry */
+   int rc;                              /* Return code */
+ 
+-  if( pCur->pgnoRoot==0 ){
++  rc = moveToRoot(pCur);
++  if( rc==SQLITE_EMPTY ){
+     *pnEntry = 0;
+     return SQLITE_OK;
+   }
+-  rc = moveToRoot(pCur);
+ 
+   /* Unless an error occurs, the following loop runs one iteration for each
+   ** page in the B-Tree structure (not including overflow pages). 
+@@ -68484,7 +72161,7 @@
+     ** this page contains countable entries. Increment the entry counter
+     ** accordingly.
+     */
+-    pPage = pCur->apPage[pCur->iPage];
++    pPage = pCur->pPage;
+     if( pPage->leaf || !pPage->intKey ){
+       nEntry += pPage->nCell;
+     }
+@@ -68507,10 +72184,10 @@
+           return moveToRoot(pCur);
+         }
+         moveToParent(pCur);
+-      }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
++      }while ( pCur->ix>=pCur->pPage->nCell );
+ 
+       pCur->ix++;
+-      pPage = pCur->apPage[pCur->iPage];
++      pPage = pCur->pPage;
+     }
+ 
+     /* Descend to the child node of the cell that the cursor currently 
+@@ -68552,14 +72229,14 @@
+   pCheck->nErr++;
+   va_start(ap, zFormat);
+   if( pCheck->errMsg.nChar ){
+-    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
++    sqlite3_str_append(&pCheck->errMsg, "\n", 1);
+   }
+   if( pCheck->zPfx ){
+-    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
++    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
+   }
+-  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
++  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
+   va_end(ap);
+-  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
++  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
+     pCheck->mallocFailed = 1;
+   }
+ }
+@@ -68594,8 +72271,7 @@
+ ** Also check that the page number is in bounds.
+ */
+ static int checkRef(IntegrityCk *pCheck, Pgno iPage){
+-  if( iPage==0 ) return 1;
+-  if( iPage>pCheck->nPage ){
++  if( iPage>pCheck->nPage || iPage==0 ){
+     checkAppendMsg(pCheck, "invalid page number %d", iPage);
+     return 1;
+   }
+@@ -68650,17 +72326,12 @@
+ ){
+   int i;
+   int expected = N;
+-  int iFirst = iPage;
+-  while( N-- > 0 && pCheck->mxErr ){
++  int nErrAtStart = pCheck->nErr;
++  while( iPage!=0 && pCheck->mxErr ){
+     DbPage *pOvflPage;
+     unsigned char *pOvflData;
+-    if( iPage<1 ){
+-      checkAppendMsg(pCheck,
+-         "%d of %d pages missing from overflow list starting at %d",
+-          N+1, expected, iFirst);
+-      break;
+-    }
+     if( checkRef(pCheck, iPage) ) break;
++    N--;
+     if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
+       checkAppendMsg(pCheck, "failed to get page %d", iPage);
+       break;
+@@ -68704,11 +72375,13 @@
+ #endif
+     iPage = get4byte(pOvflData);
+     sqlite3PagerUnref(pOvflPage);
+-
+-    if( isFreeList && N<(iPage!=0) ){
+-      checkAppendMsg(pCheck, "free-page count in header is too small");
+-    }
+   }
++  if( N && nErrAtStart==pCheck->nErr ){
++    checkAppendMsg(pCheck,
++      "%s is %d but should be %d",
++      isFreeList ? "size" : "overflow list length",
++      expected-N, expected);
++  }
+ }
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+ 
+@@ -69101,6 +72774,24 @@
+ 
+   /* Check all the tables.
+   */
++#ifndef SQLITE_OMIT_AUTOVACUUM
++  if( pBt->autoVacuum ){
++    int mx = 0;
++    int mxInHdr;
++    for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
++    mxInHdr = get4byte(&pBt->pPage1->aData[52]);
++    if( mx!=mxInHdr ){
++      checkAppendMsg(&sCheck,
++        "max rootpage (%d) disagrees with header (%d)",
++        mx, mxInHdr
++      );
++    }
++  }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
++    checkAppendMsg(&sCheck,
++      "incremental_vacuum enabled with a max rootpage of zero"
++    );
++  }
++#endif
+   testcase( pBt->db->flags & SQLITE_CellSizeCk );
+   pBt->db->flags &= ~SQLITE_CellSizeCk;
+   for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
+@@ -69143,11 +72834,11 @@
+   sqlite3PageFree(sCheck.heap);
+   sqlite3_free(sCheck.aPgRef);
+   if( sCheck.mallocFailed ){
+-    sqlite3StrAccumReset(&sCheck.errMsg);
++    sqlite3_str_reset(&sCheck.errMsg);
+     sCheck.nErr++;
+   }
+   *pnErr = sCheck.nErr;
+-  if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
++  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
+   /* Make sure this analysis did not leave any unref() pages. */
+   assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
+   sqlite3BtreeLeave(p);
+@@ -69351,7 +73042,7 @@
+               && pCsr->pBt->inTransaction==TRANS_WRITE );
+   assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
+   assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
+-  assert( pCsr->apPage[pCsr->iPage]->intKey );
++  assert( pCsr->pPage->intKey );
+ 
+   return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
+ }
+@@ -69382,11 +73073,11 @@
+   pBt->btsFlags &= ~BTS_NO_WAL;
+   if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;
+ 
+-  rc = sqlite3BtreeBeginTrans(pBtree, 0);
++  rc = sqlite3BtreeBeginTrans(pBtree, 0, 0);
+   if( rc==SQLITE_OK ){
+     u8 *aData = pBt->pPage1->aData;
+     if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
+-      rc = sqlite3BtreeBeginTrans(pBtree, 2);
++      rc = sqlite3BtreeBeginTrans(pBtree, 2, 0);
+       if( rc==SQLITE_OK ){
+         rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+         if( rc==SQLITE_OK ){
+@@ -69826,7 +73517,7 @@
+     ** before this function exits.
+     */
+     if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
+-      rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
++      rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
+       bCloseTrans = 1;
+     }
+ 
+@@ -69842,10 +73533,10 @@
+ 
+     /* Lock the destination database, if it is not locked already. */
+     if( SQLITE_OK==rc && p->bDestLocked==0
+-     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
++     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
++                                                (int*)&p->iDestSchema)) 
+     ){
+       p->bDestLocked = 1;
+-      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
+     }
+ 
+     /* Do not allow backup if the destination database is in WAL mode
+@@ -70289,8 +73980,7 @@
+ 
+   if( p->flags & MEM_Null ){
+     /* Cannot be both MEM_Null and some other type */
+-    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
+-                         |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
++    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
+ 
+     /* If MEM_Null is set, then either the value is a pure NULL (the usual
+     ** case) or it is a pointer set using sqlite3_bind_pointer() or
+@@ -70340,6 +74030,51 @@
+ }
+ #endif
+ 
++#ifdef SQLITE_DEBUG
++/*
++** Check that string value of pMem agrees with its integer or real value.
++**
++** A single int or real value always converts to the same strings.  But
++** many different strings can be converted into the same int or real.
++** If a table contains a numeric value and an index is based on the
++** corresponding string value, then it is important that the string be
++** derived from the numeric value, not the other way around, to ensure
++** that the index and table are consistent.  See ticket
++** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for
++** an example.
++**
++** This routine looks at pMem to verify that if it has both a numeric
++** representation and a string representation then the string rep has
++** been derived from the numeric and not the other way around.  It returns
++** true if everything is ok and false if there is a problem.
++**
++** This routine is for use inside of assert() statements only.
++*/
++SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
++  char zBuf[100];
++  char *z;
++  int i, j, incr;
++  if( (p->flags & MEM_Str)==0 ) return 1;
++  if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
++  if( p->flags & MEM_Int ){
++    sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
++  }else{
++    sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
++  }
++  z = p->z;
++  i = j = 0;
++  incr = 1;
++  if( p->enc!=SQLITE_UTF8 ){
++    incr = 2;
++    if( p->enc==SQLITE_UTF16BE ) z++;
++  }
++  while( zBuf[j] ){
++    if( zBuf[j++]!=z[i] ) return 0;
++    i += incr;
++  }
++  return 1;
++}
++#endif /* SQLITE_DEBUG */
+ 
+ /*
+ ** If pMem is an object with a valid string representation, this routine
+@@ -70358,7 +74093,7 @@
+ #ifndef SQLITE_OMIT_UTF16
+   int rc;
+ #endif
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
+            || desiredEnc==SQLITE_UTF16BE );
+   if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
+@@ -70391,7 +74126,7 @@
+ */
+ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+   assert( sqlite3VdbeCheckMemInvariants(pMem) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   testcase( pMem->db==0 );
+ 
+   /* If the bPreserve flag is set to true, then the memory cell must already
+@@ -70402,7 +74137,7 @@
+   assert( pMem->szMalloc==0
+        || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
+   if( n<32 ) n = 32;
+-  if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
++  if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
+     pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
+     bPreserve = 0;
+   }else{
+@@ -70418,7 +74153,8 @@
+     pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+   }
+ 
+-  if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
++  if( bPreserve && pMem->z ){
++    assert( pMem->z!=pMem->zMalloc );
+     memcpy(pMem->zMalloc, pMem->z, pMem->n);
+   }
+   if( (pMem->flags&MEM_Dyn)!=0 ){
+@@ -70457,6 +74193,20 @@
+ }
+ 
+ /*
++** It is already known that pMem contains an unterminated string.
++** Add the zero terminator.
++*/
++static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
++  if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
++    return SQLITE_NOMEM_BKPT;
++  }
++  pMem->z[pMem->n] = 0;
++  pMem->z[pMem->n+1] = 0;
++  pMem->flags |= MEM_Term;
++  return SQLITE_OK;
++}
++
++/*
+ ** Change pMem so that its MEM_Str or MEM_Blob value is stored in
+ ** MEM.zMalloc, where it can be safely written.
+ **
+@@ -70464,16 +74214,12 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
+     if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
+     if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
+-      if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
+-        return SQLITE_NOMEM_BKPT;
+-      }
+-      pMem->z[pMem->n] = 0;
+-      pMem->z[pMem->n+1] = 0;
+-      pMem->flags |= MEM_Term;
++      int rc = vdbeMemAddTerminator(pMem);
++      if( rc ) return rc;
+     }
+   }
+   pMem->flags &= ~MEM_Ephem;
+@@ -70493,7 +74239,7 @@
+   int nByte;
+   assert( pMem->flags & MEM_Zero );
+   assert( pMem->flags&MEM_Blob );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ 
+   /* Set nByte to the number of bytes required to store the expanded blob. */
+@@ -70513,20 +74259,6 @@
+ #endif
+ 
+ /*
+-** It is already known that pMem contains an unterminated string.
+-** Add the zero terminator.
+-*/
+-static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
+-  if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+-    return SQLITE_NOMEM_BKPT;
+-  }
+-  pMem->z[pMem->n] = 0;
+-  pMem->z[pMem->n+1] = 0;
+-  pMem->flags |= MEM_Term;
+-  return SQLITE_OK;
+-}
+-
+-/*
+ ** Make sure the given Mem is \u0000 terminated.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
+@@ -70562,7 +74294,7 @@
+   assert( !(fg&MEM_Zero) );
+   assert( !(fg&(MEM_Str|MEM_Blob)) );
+   assert( fg&(MEM_Int|MEM_Real) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+ 
+@@ -70583,7 +74315,8 @@
+     assert( fg & MEM_Real );
+     sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
+   }
+-  pMem->n = sqlite3Strlen30(pMem->z);
++  assert( pMem->z!=0 );
++  pMem->n = sqlite3Strlen30NN(pMem->z);
+   pMem->enc = SQLITE_UTF8;
+   pMem->flags |= MEM_Str|MEM_Term;
+   if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
+@@ -70600,29 +74333,56 @@
+ ** otherwise.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
+-  int rc = SQLITE_OK;
+-  if( ALWAYS(pFunc && pFunc->xFinalize) ){
+-    sqlite3_context ctx;
+-    Mem t;
+-    assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
+-    assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-    memset(&ctx, 0, sizeof(ctx));
+-    memset(&t, 0, sizeof(t));
+-    t.flags = MEM_Null;
+-    t.db = pMem->db;
+-    ctx.pOut = &t;
+-    ctx.pMem = pMem;
+-    ctx.pFunc = pFunc;
+-    pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
+-    assert( (pMem->flags & MEM_Dyn)==0 );
+-    if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+-    memcpy(pMem, &t, sizeof(t));
+-    rc = ctx.isError;
+-  }
+-  return rc;
++  sqlite3_context ctx;
++  Mem t;
++  assert( pFunc!=0 );
++  assert( pFunc->xFinalize!=0 );
++  assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
++  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
++  memset(&ctx, 0, sizeof(ctx));
++  memset(&t, 0, sizeof(t));
++  t.flags = MEM_Null;
++  t.db = pMem->db;
++  ctx.pOut = &t;
++  ctx.pMem = pMem;
++  ctx.pFunc = pFunc;
++  pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
++  assert( (pMem->flags & MEM_Dyn)==0 );
++  if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
++  memcpy(pMem, &t, sizeof(t));
++  return ctx.isError;
+ }
+ 
+ /*
++** Memory cell pAccum contains the context of an aggregate function.
++** This routine calls the xValue method for that function and stores
++** the results in memory cell pMem.
++**
++** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
++** otherwise.
++*/
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
++  sqlite3_context ctx;
++  Mem t;
++  assert( pFunc!=0 );
++  assert( pFunc->xValue!=0 );
++  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
++  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
++  memset(&ctx, 0, sizeof(ctx));
++  memset(&t, 0, sizeof(t));
++  t.flags = MEM_Null;
++  t.db = pAccum->db;
++  sqlite3VdbeMemSetNull(pOut);
++  ctx.pOut = pOut;
++  ctx.pMem = pAccum;
++  ctx.pFunc = pFunc;
++  pFunc->xValue(&ctx);
++  return ctx.isError;
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** If the memory cell contains a value that must be freed by
+ ** invoking the external callback in Mem.xDel, then this routine
+ ** will free that value.  It also sets Mem.flags to MEM_Null.
+@@ -70640,15 +74400,8 @@
+     testcase( p->flags & MEM_Dyn );
+   }
+   if( p->flags&MEM_Dyn ){
+-    assert( (p->flags&MEM_RowSet)==0 );
+     assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
+     p->xDel((void *)p->z);
+-  }else if( p->flags&MEM_RowSet ){
+-    sqlite3RowSetClear(p->u.pRowSet);
+-  }else if( p->flags&MEM_Frame ){
+-    VdbeFrame *pFrame = p->u.pFrame;
+-    pFrame->pParent = pFrame->v->pDelFrame;
+-    pFrame->v->pDelFrame = pFrame;
+   }
+   p->flags = MEM_Null;
+ }
+@@ -70780,6 +74533,16 @@
+ }
+ 
+ /*
++** Return 1 if pMem represents true, and return 0 if pMem represents false.
++** Return the value ifNull if pMem is NULL.  
++*/
++SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
++  if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
++  if( pMem->flags & MEM_Null ) return ifNull;
++  return sqlite3VdbeRealValue(pMem)!=0.0;
++}
++
++/*
+ ** The MEM structure is already a MEM_Real.  Try to also make it a
+ ** MEM_Int if we can.
+ */
+@@ -70786,7 +74549,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
+   i64 ix;
+   assert( pMem->flags & MEM_Real );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+@@ -70813,7 +74576,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+   pMem->u.i = sqlite3VdbeIntValue(pMem);
+@@ -70834,6 +74597,18 @@
+   return SQLITE_OK;
+ }
+ 
++/* Compare a floating point value to an integer.  Return true if the two
++** values are the same within the precision of the floating point value.
++**
++** For some versions of GCC on 32-bit machines, if you do the more obvious
++** comparison of "r1==(double)i" you sometimes get an answer of false even
++** though the r1 and (double)i values are bit-for-bit the same.
++*/
++static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
++  double r2 = (double)i;
++  return memcmp(&r1, &r2, sizeof(r1))==0;
++}
++
+ /*
+ ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
+ ** Invalidate any prior representations.
+@@ -70844,14 +74619,21 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
+   if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
++    int rc;
+     assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
+     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-    if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
++    rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
++    if( rc==0 ){
+       MemSetTypeFlag(pMem, MEM_Int);
+     }else{
+-      pMem->u.r = sqlite3VdbeRealValue(pMem);
+-      MemSetTypeFlag(pMem, MEM_Real);
+-      sqlite3VdbeIntegerAffinity(pMem);
++      i64 i = pMem->u.i;
++      sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
++      if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
++        pMem->u.i = i;
++        MemSetTypeFlag(pMem, MEM_Int);
++      }else{
++        MemSetTypeFlag(pMem, MEM_Real);
++      }
+     }
+   }
+   assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
+@@ -70978,7 +74760,7 @@
+ }
+ 
+ /* A no-op destructor */
+-static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
++SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
+ 
+ /*
+ ** Set the value stored in *pMem should already be a NULL.
+@@ -71012,26 +74794,36 @@
+ }
+ #endif
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Return true if the Mem holds a RowSet object.  This routine is intended
++** for use inside of assert() statements.
++*/
++SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){
++  return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn)
++         && pMem->xDel==sqlite3RowSetDelete;
++}
++#endif
++
++/*
+ ** Delete any previous value and set the value of pMem to be an
+ ** empty boolean index.
++**
++** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
++** error occurs.
+ */
+-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
++SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){
+   sqlite3 *db = pMem->db;
++  RowSet *p;
+   assert( db!=0 );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   sqlite3VdbeMemRelease(pMem);
+-  pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
+-  if( db->mallocFailed ){
+-    pMem->flags = MEM_Null;
+-    pMem->szMalloc = 0;
+-  }else{
+-    assert( pMem->zMalloc );
+-    pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
+-    pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
+-    assert( pMem->u.pRowSet!=0 );
+-    pMem->flags = MEM_RowSet;
+-  }
++  p = sqlite3RowSetInit(db);
++  if( p==0 ) return SQLITE_NOMEM;
++  pMem->z = (char*)p;
++  pMem->flags = MEM_Blob|MEM_Dyn;
++  pMem->xDel = sqlite3RowSetDelete;
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -71064,7 +74856,21 @@
+   Mem *pX;
+   for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
+     if( pX->pScopyFrom==pMem ){
+-      pX->flags |= MEM_Undefined;
++      /* If pX is marked as a shallow copy of pMem, then verify that
++      ** no significant changes have been made to pX since the OP_SCopy.
++      ** A significant change would indicated a missed call to this
++      ** function for pX.  Minor changes, such as adding or removing a
++      ** dual type, are allowed, as long as the underlying value is the
++      ** same. */
++      u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
++      assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
++      assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
++      assert( (mFlags&MEM_Str)==0  || (pMem->n==pX->n && pMem->z==pX->z) );
++      assert( (mFlags&MEM_Blob)==0  || sqlite3BlobCompare(pMem,pX)==0 );
++      
++      /* pMem is the register that is changing.  But also mark pX as
++      ** undefined so that we can quickly detect the shallow-copy error */
++      pX->flags = MEM_Undefined;
+       pX->pScopyFrom = 0;
+     }
+   }
+@@ -71085,7 +74891,7 @@
+   sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
+ }
+ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
+-  assert( (pFrom->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pFrom) );
+   assert( pTo->db==pFrom->db );
+   if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+@@ -71103,7 +74909,7 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
+   int rc = SQLITE_OK;
+ 
+-  assert( (pFrom->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pFrom) );
+   if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+   pTo->flags &= ~MEM_Dyn;
+@@ -71161,7 +74967,7 @@
+   u16 flags = 0;      /* New value for pMem->flags */
+ 
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+ 
+   /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
+   if( !z ){
+@@ -71178,7 +74984,7 @@
+   if( nByte<0 ){
+     assert( enc!=0 );
+     if( enc==SQLITE_UTF8 ){
+-      nByte = sqlite3Strlen30(z);
++      nByte = 0x7fffffff & (int)strlen(z);
+       if( nByte>iLimit ) nByte = iLimit+1;
+     }else{
+       for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
+@@ -71256,12 +75062,11 @@
+ ){
+   int rc;
+   pMem->flags = MEM_Null;
+-  if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
++  if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
+     rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
+     if( rc==SQLITE_OK ){
+-      pMem->z[amt] = 0;
+-      pMem->z[amt+1] = 0;
+-      pMem->flags = MEM_Blob|MEM_Term;
++      pMem->z[amt] = 0;   /* Overrun area used when reading malformed records */
++      pMem->flags = MEM_Blob;
+       pMem->n = (int)amt;
+     }else{
+       sqlite3VdbeMemRelease(pMem);
+@@ -71284,7 +75089,7 @@
+ 
+   /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
+   ** that both the BtShared and database handle mutexes are held. */
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
+   assert( zData!=0 );
+ 
+@@ -71308,7 +75113,7 @@
+   assert( pVal!=0 );
+   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
+   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+-  assert( (pVal->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pVal) );
+   assert( (pVal->flags & (MEM_Null))==0 );
+   if( pVal->flags & (MEM_Blob|MEM_Str) ){
+     if( ExpandBlob(pVal) ) return 0;
+@@ -71330,6 +75135,7 @@
+   assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
+               || pVal->db->mallocFailed );
+   if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
++    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+     return pVal->z;
+   }else{
+     return 0;
+@@ -71350,8 +75156,9 @@
+   if( !pVal ) return 0;
+   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
+   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+-  assert( (pVal->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pVal) );
+   if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
++    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+     return pVal->z;
+   }
+   if( pVal->flags&MEM_Null ){
+@@ -71410,7 +75217,7 @@
+       if( pRec ){
+         pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
+         if( pRec->pKeyInfo ){
+-          assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
++          assert( pRec->pKeyInfo->nAllField==nCol );
+           assert( pRec->pKeyInfo->enc==ENC(db) );
+           pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
+           for(i=0; i<nCol; i++){
+@@ -71567,7 +75374,11 @@
+ 
+   assert( pExpr!=0 );
+   while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
++#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
++  if( op==TK_REGISTER ) op = pExpr->op2;
++#else
+   if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
++#endif
+ 
+   /* Compressed expressions only appear when parsing the DEFAULT clause
+   ** on a table column definition, and hence only when pCtx==0.  This
+@@ -71651,18 +75462,25 @@
+                          0, SQLITE_DYNAMIC);
+   }
+ #endif
+-
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   else if( op==TK_FUNCTION && pCtx!=0 ){
+     rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
+   }
+ #endif
++  else if( op==TK_TRUEFALSE ){
++     pVal = valueNew(db, pCtx);
++     pVal->flags = MEM_Int;
++     pVal->u.i = pExpr->u.zToken[4]==0;
++  }
+ 
+   *ppVal = pVal;
+   return rc;
+ 
+ no_mem:
+-  sqlite3OomFault(db);
++#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
++  if( pCtx==0 || pCtx->pParse->nErr==0 )
++#endif
++    sqlite3OomFault(db);
+   sqlite3DbFree(db, zVal);
+   assert( *ppVal==0 );
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+@@ -71905,11 +75723,11 @@
+   int iCol,                       /* Column to extract */
+   sqlite3_value **ppVal           /* OUT: Extracted value */
+ ){
+-  u32 t;                          /* a column type code */
++  u32 t = 0;                      /* a column type code */
+   int nHdr;                       /* Size of the header in the record */
+   int iHdr;                       /* Next unread header byte */
+   int iField;                     /* Next unread data byte */
+-  int szField;                    /* Size of the current data field */
++  int szField = 0;                /* Size of the current data field */
+   int i;                          /* Column index */
+   u8 *a = (u8*)pRec;              /* Typecast byte array */
+   Mem *pMem = *ppVal;             /* Write result into this Mem object */
+@@ -71946,7 +75764,7 @@
+ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
+   if( pRec ){
+     int i;
+-    int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
++    int nCol = pRec->pKeyInfo->nAllField;
+     Mem *aMem = pRec->aMem;
+     sqlite3 *db = aMem[0].db;
+     for(i=0; i<nCol; i++){
+@@ -72042,10 +75860,12 @@
+   db->pVdbe = p;
+   p->magic = VDBE_MAGIC_INIT;
+   p->pParse = pParse;
++  pParse->pVdbe = p;
+   assert( pParse->aLabel==0 );
+   assert( pParse->nLabel==0 );
+   assert( pParse->nOpAlloc==0 );
+   assert( pParse->szOpAlloc==0 );
++  sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
+   return p;
+ }
+ 
+@@ -72071,6 +75891,13 @@
+   }
+   assert( p->zSql==0 );
+   p->zSql = sqlite3DbStrNDup(p->db, z, n);
++#ifdef SQLITE_ENABLE_NORMALIZE
++  assert( p->zNormSql==0 );
++  if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
++    sqlite3Normalize(p, p->zSql, n, prepFlags);
++    assert( p->zNormSql!=0 || p->db->mallocFailed );
++  }
++#endif
+ }
+ 
+ /*
+@@ -72092,6 +75919,11 @@
+   zTmp = pA->zSql;
+   pA->zSql = pB->zSql;
+   pB->zSql = zTmp;
++#ifdef SQLITE_ENABLE_NORMALIZE
++  zTmp = pA->zNormSql;
++  pA->zNormSql = pB->zNormSql;
++  pB->zNormSql = zTmp;
++#endif
+   pB->expmask = pA->expmask;
+   pB->prepFlags = pA->prepFlags;
+   memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
+@@ -72200,14 +76032,6 @@
+ #endif
+ #ifdef SQLITE_DEBUG
+   if( p->db->flags & SQLITE_VdbeAddopTrace ){
+-    int jj, kk;
+-    Parse *pParse = p->pParse;
+-    for(jj=kk=0; jj<pParse->nColCache; jj++){
+-      struct yColCache *x = pParse->aColCache + jj;
+-      printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+-      kk++;
+-    }
+-    if( kk ) printf("\n");
+     sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+     test_addop_breakpoint();
+   }
+@@ -72310,7 +76134,50 @@
+   return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
+ }
+ 
++#ifndef SQLITE_OMIT_EXPLAIN
+ /*
++** Return the address of the current EXPLAIN QUERY PLAN baseline.
++** 0 means "none".
++*/
++SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
++  VdbeOp *pOp;
++  if( pParse->addrExplain==0 ) return 0;
++  pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
++  return pOp->p2;
++}
++
++/*
++** Add a new OP_Explain opcode.
++**
++** If the bPush flag is true, then make this opcode the parent for
++** subsequent Explains until sqlite3VdbeExplainPop() is called.
++*/
++SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
++  if( pParse->explain==2 ){
++    char *zMsg;
++    Vdbe *v;
++    va_list ap;
++    int iThis;
++    va_start(ap, zFmt);
++    zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
++    va_end(ap);
++    v = pParse->pVdbe;
++    iThis = v->nOp;
++    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
++                      zMsg, P4_DYNAMIC);
++    if( bPush) pParse->addrExplain = iThis;
++  }
++}
++
++/*
++** Pop the EXPLAIN QUERY PLAN stack one level.
++*/
++SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
++  pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
++}
++#endif /* SQLITE_OMIT_EXPLAIN */
++
++/*
+ ** Add an OP_ParseSchema opcode.  This routine is broken out from
+ ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
+ ** as having been used.
+@@ -72399,6 +76266,12 @@
+   assert( j<p->nLabel );
+   assert( j>=0 );
+   if( p->aLabel ){
++#ifdef SQLITE_DEBUG
++    if( p->db->flags & SQLITE_VdbeAddopTrace ){
++      printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
++    }
++#endif
++    assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
+     p->aLabel[j] = v->nOp;
+   }
+ }
+@@ -72499,7 +76372,8 @@
+ **   *  OP_VUpdate
+ **   *  OP_VRename
+ **   *  OP_FkCounter with P2==0 (immediate foreign key constraint)
+-**   *  OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...)
++**   *  OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine 
++**      (for CREATE TABLE AS SELECT ...)
+ **
+ ** Then check that the value of Parse.mayAbort is true if an
+ ** ABORT may be thrown, or false otherwise. Return true if it does
+@@ -72527,7 +76401,7 @@
+       hasAbort = 1;
+       break;
+     }
+-    if( opcode==OP_CreateTable ) hasCreateTable = 1;
++    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
+     if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
+ #ifndef SQLITE_OMIT_FOREIGN_KEY
+     if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
+@@ -72547,7 +76421,33 @@
+ }
+ #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Increment the nWrite counter in the VDBE if the cursor is not an
++** ephemeral cursor, or if the cursor argument is NULL.
++*/
++SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){
++  if( pC==0
++   || (pC->eCurType!=CURTYPE_SORTER
++       && pC->eCurType!=CURTYPE_PSEUDO
++       && !pC->isEphemeral)
++  ){
++    p->nWrite++;
++  }
++}
++#endif
++
++#ifdef SQLITE_DEBUG
++/*
++** Assert if an Abort at this point in time might result in a corrupt
++** database.
++*/
++SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){
++  assert( p->nWrite==0 || p->usesStmtJournal );
++}
++#endif
++
++/*
+ ** This routine is called after all opcodes have been inserted.  It loops
+ ** through all the opcodes and fixes up some details.
+ **
+@@ -72606,6 +76506,25 @@
+           p->bIsReader = 1;
+           break;
+         }
++        case OP_Next:
++        case OP_SorterNext: {
++          pOp->p4.xAdvance = sqlite3BtreeNext;
++          pOp->p4type = P4_ADVANCE;
++          /* The code generator never codes any of these opcodes as a jump
++          ** to a label.  They are always coded as a jump backwards to a 
++          ** known address */
++          assert( pOp->p2>=0 );
++          break;
++        }
++        case OP_Prev: {
++          pOp->p4.xAdvance = sqlite3BtreePrevious;
++          pOp->p4type = P4_ADVANCE;
++          /* The code generator never codes any of these opcodes as a jump
++          ** to a label.  They are always coded as a jump backwards to a 
++          ** known address */
++          assert( pOp->p2>=0 );
++          break;
++        }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+         case OP_VUpdate: {
+           if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+@@ -72617,27 +76536,25 @@
+           assert( pOp[-1].opcode==OP_Integer );
+           n = pOp[-1].p1;
+           if( n>nMaxArgs ) nMaxArgs = n;
+-          break;
++          /* Fall through into the default case */
+         }
+ #endif
+-        case OP_Next:
+-        case OP_NextIfOpen:
+-        case OP_SorterNext: {
+-          pOp->p4.xAdvance = sqlite3BtreeNext;
+-          pOp->p4type = P4_ADVANCE;
++        default: {
++          if( pOp->p2<0 ){
++            /* The mkopcodeh.tcl script has so arranged things that the only
++            ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
++            ** have non-negative values for P2. */
++            assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
++            assert( ADDR(pOp->p2)<pParse->nLabel );
++            pOp->p2 = aLabel[ADDR(pOp->p2)];
++          }
+           break;
+         }
+-        case OP_Prev:
+-        case OP_PrevIfOpen: {
+-          pOp->p4.xAdvance = sqlite3BtreePrevious;
+-          pOp->p4type = P4_ADVANCE;
+-          break;
+-        }
+       }
+-      if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
+-        assert( ADDR(pOp->p2)<pParse->nLabel );
+-        pOp->p2 = aLabel[ADDR(pOp->p2)];
+-      }
++      /* The mkopcodeh.tcl script has so arranged things that the only
++      ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
++      ** have non-negative values for P2. */
++      assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
+     }
+     if( pOp==p->aOp ) break;
+     pOp--;
+@@ -72688,6 +76605,17 @@
+ #endif
+ 
+ /*
++** Generate code (a single OP_Abortable opcode) that will
++** verify that the VDBE program can safely call Abort in the current
++** context.
++*/
++#if defined(SQLITE_DEBUG)
++SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){
++  if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable);
++}
++#endif
++
++/*
+ ** This function returns a pointer to the array of opcodes associated with
+ ** the Vdbe passed as the first argument. It is the callers responsibility
+ ** to arrange for the returned array to be eventually freed using the 
+@@ -72853,6 +76781,7 @@
+     case P4_REAL:
+     case P4_INT64:
+     case P4_DYNAMIC:
++    case P4_DYNBLOB:
+     case P4_INTARRAY: {
+       sqlite3DbFree(db, p4);
+       break;
+@@ -73230,23 +77159,23 @@
+   const char *zOp = 0;
+   switch( pExpr->op ){
+     case TK_STRING:
+-      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
++      sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
+       break;
+     case TK_INTEGER:
+-      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
++      sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
+       break;
+     case TK_NULL:
+-      sqlite3XPrintf(p, "NULL");
++      sqlite3_str_appendf(p, "NULL");
+       break;
+     case TK_REGISTER: {
+-      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
++      sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
+       break;
+     }
+     case TK_COLUMN: {
+       if( pExpr->iColumn<0 ){
+-        sqlite3XPrintf(p, "rowid");
++        sqlite3_str_appendf(p, "rowid");
+       }else{
+-        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
++        sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
+       }
+       break;
+     }
+@@ -73278,18 +77207,18 @@
+     case TK_NOTNULL: zOp = "NOTNULL"; break;
+ 
+     default:
+-      sqlite3XPrintf(p, "%s", "expr");
++      sqlite3_str_appendf(p, "%s", "expr");
+       break;
+   }
+ 
+   if( zOp ){
+-    sqlite3XPrintf(p, "%s(", zOp);
++    sqlite3_str_appendf(p, "%s(", zOp);
+     displayP4Expr(p, pExpr->pLeft);
+     if( pExpr->pRight ){
+-      sqlite3StrAccumAppend(p, ",", 1);
++      sqlite3_str_append(p, ",", 1);
+       displayP4Expr(p, pExpr->pRight);
+     }
+-    sqlite3StrAccumAppend(p, ")", 1);
++    sqlite3_str_append(p, ")", 1);
+   }
+ }
+ #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
+@@ -73310,14 +77239,15 @@
+       int j;
+       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
+       assert( pKeyInfo->aSortOrder!=0 );
+-      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
+-      for(j=0; j<pKeyInfo->nField; j++){
++      sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
++      for(j=0; j<pKeyInfo->nKeyField; j++){
+         CollSeq *pColl = pKeyInfo->aColl[j];
+         const char *zColl = pColl ? pColl->zName : "";
+         if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
+-        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
++        sqlite3_str_appendf(&x, ",%s%s", 
++               pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
+       }
+-      sqlite3StrAccumAppend(&x, ")", 1);
++      sqlite3_str_append(&x, ")", 1);
+       break;
+     }
+ #ifdef SQLITE_ENABLE_CURSOR_HINTS
+@@ -73328,31 +77258,31 @@
+ #endif
+     case P4_COLLSEQ: {
+       CollSeq *pColl = pOp->p4.pColl;
+-      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
++      sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
+       break;
+     }
+     case P4_FUNCDEF: {
+       FuncDef *pDef = pOp->p4.pFunc;
+-      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
++      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+       break;
+     }
+ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+     case P4_FUNCCTX: {
+       FuncDef *pDef = pOp->p4.pCtx->pFunc;
+-      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
++      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+       break;
+     }
+ #endif
+     case P4_INT64: {
+-      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
++      sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
+       break;
+     }
+     case P4_INT32: {
+-      sqlite3XPrintf(&x, "%d", pOp->p4.i);
++      sqlite3_str_appendf(&x, "%d", pOp->p4.i);
+       break;
+     }
+     case P4_REAL: {
+-      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
++      sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
+       break;
+     }
+     case P4_MEM: {
+@@ -73360,9 +77290,9 @@
+       if( pMem->flags & MEM_Str ){
+         zP4 = pMem->z;
+       }else if( pMem->flags & MEM_Int ){
+-        sqlite3XPrintf(&x, "%lld", pMem->u.i);
++        sqlite3_str_appendf(&x, "%lld", pMem->u.i);
+       }else if( pMem->flags & MEM_Real ){
+-        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
++        sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
+       }else if( pMem->flags & MEM_Null ){
+         zP4 = "NULL";
+       }else{
+@@ -73374,7 +77304,7 @@
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     case P4_VTAB: {
+       sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
+-      sqlite3XPrintf(&x, "vtab:%p", pVtab);
++      sqlite3_str_appendf(&x, "vtab:%p", pVtab);
+       break;
+     }
+ #endif
+@@ -73383,23 +77313,24 @@
+       int *ai = pOp->p4.ai;
+       int n = ai[0];   /* The first element of an INTARRAY is always the
+                        ** count of the number of elements to follow */
+-      for(i=1; i<n; i++){
+-        sqlite3XPrintf(&x, ",%d", ai[i]);
++      for(i=1; i<=n; i++){
++        sqlite3_str_appendf(&x, ",%d", ai[i]);
+       }
+       zTemp[0] = '[';
+-      sqlite3StrAccumAppend(&x, "]", 1);
++      sqlite3_str_append(&x, "]", 1);
+       break;
+     }
+     case P4_SUBPROGRAM: {
+-      sqlite3XPrintf(&x, "program");
++      sqlite3_str_appendf(&x, "program");
+       break;
+     }
++    case P4_DYNBLOB:
+     case P4_ADVANCE: {
+       zTemp[0] = 0;
+       break;
+     }
+     case P4_TABLE: {
+-      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
++      sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
+       break;
+     }
+     default: {
+@@ -73500,7 +77431,7 @@
+ /*
+ ** Print a single opcode.  This routine is used for debugging only.
+ */
+-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
++SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
+   char *zP4;
+   char zPtr[50];
+   char zCom[100];
+@@ -73569,9 +77500,8 @@
+       */
+       testcase( p->flags & MEM_Agg );
+       testcase( p->flags & MEM_Dyn );
+-      testcase( p->flags & MEM_Frame );
+-      testcase( p->flags & MEM_RowSet );
+-      if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
++      testcase( p->xDel==sqlite3VdbeFrameMemDel );
++      if( p->flags&(MEM_Agg|MEM_Dyn) ){
+         sqlite3VdbeMemRelease(p);
+       }else if( p->szMalloc ){
+         sqlite3DbFreeNN(db, p->zMalloc);
+@@ -73583,7 +77513,36 @@
+   }
+ }
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Verify that pFrame is a valid VdbeFrame pointer.  Return true if it is
++** and false if something is wrong.
++**
++** This routine is intended for use inside of assert() statements only.
++*/
++SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
++  if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
++  return 1;
++}
++#endif
++
++
++/*
++** This is a destructor on a Mem object (which is really an sqlite3_value)
++** that deletes the Frame object that is attached to it as a blob.
++**
++** This routine does not delete the Frame right away.  It merely adds the
++** frame to a list of frames to be deleted when the Vdbe halts.
++*/
++SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
++  VdbeFrame *pFrame = (VdbeFrame*)pArg;
++  assert( sqlite3VdbeFrameIsValid(pFrame) );
++  pFrame->pParent = pFrame->v->pDelFrame;
++  pFrame->v->pDelFrame = pFrame;
++}
++
++
++/*
+ ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
+ ** allocated by the OP_Program opcode in sqlite3VdbeExec().
+ */
+@@ -73591,6 +77550,7 @@
+   int i;
+   Mem *aMem = VdbeFrameMem(p);
+   VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
++  assert( sqlite3VdbeFrameIsValid(p) );
+   for(i=0; i<p->nChildCsr; i++){
+     sqlite3VdbeFreeCursor(p->v, apCsr[i]);
+   }
+@@ -73611,6 +77571,9 @@
+ ** p->explain==2, only OP_Explain instructions are listed and these
+ ** are shown in a different format.  p->explain==2 is used to implement
+ ** EXPLAIN QUERY PLAN.
++** 2018-04-24:  In p->explain==2 mode, the OP_Init opcodes of triggers
++** are also shown, so that the boundaries between the main program and
++** each trigger are clear.
+ **
+ ** When p->explain==1, first the main program is listed, then each of
+ ** the trigger subprograms are listed one by one.
+@@ -73626,6 +77589,8 @@
+   int i;                               /* Loop counter */
+   int rc = SQLITE_OK;                  /* Return code */
+   Mem *pMem = &p->aMem[1];             /* First Mem of result set */
++  int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
++  Op *pOp = 0;
+ 
+   assert( p->explain );
+   assert( p->magic==VDBE_MAGIC_RUN );
+@@ -73638,7 +77603,7 @@
+   releaseMemArray(pMem, 8);
+   p->pResultSet = 0;
+ 
+-  if( p->rc==SQLITE_NOMEM_BKPT ){
++  if( p->rc==SQLITE_NOMEM ){
+     /* This happens if a malloc() inside a call to sqlite3_column_text() or
+     ** sqlite3_column_text16() failed.  */
+     sqlite3OomFault(db);
+@@ -73653,7 +77618,7 @@
+   ** encountered, but p->pc will eventually catch up to nRow.
+   */
+   nRow = p->nOp;
+-  if( p->explain==1 ){
++  if( bListSubprogs ){
+     /* The first 8 memory cells are used for the result set.  So we will
+     ** commandeer the 9th cell to use as storage for an array of pointers
+     ** to trigger subprograms.  The VDBE is guaranteed to have at least 9
+@@ -73671,19 +77636,13 @@
+     }
+   }
+ 
+-  do{
++  while(1){  /* Loop exits via break */
+     i = p->pc++;
+-  }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
+-  if( i>=nRow ){
+-    p->rc = SQLITE_OK;
+-    rc = SQLITE_DONE;
+-  }else if( db->u1.isInterrupted ){
+-    p->rc = SQLITE_INTERRUPT;
+-    rc = SQLITE_ERROR;
+-    sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
+-  }else{
+-    char *zP4;
+-    Op *pOp;
++    if( i>=nRow ){
++      p->rc = SQLITE_OK;
++      rc = SQLITE_DONE;
++      break;
++    }
+     if( i<p->nOp ){
+       /* The output line number is small enough that we are still in the
+       ** main program. */
+@@ -73698,94 +77657,113 @@
+       }
+       pOp = &apSub[j]->aOp[i];
+     }
+-    if( p->explain==1 ){
+-      pMem->flags = MEM_Int;
+-      pMem->u.i = i;                                /* Program counter */
+-      pMem++;
+-  
+-      pMem->flags = MEM_Static|MEM_Str|MEM_Term;
+-      pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
+-      assert( pMem->z!=0 );
+-      pMem->n = sqlite3Strlen30(pMem->z);
+-      pMem->enc = SQLITE_UTF8;
+-      pMem++;
+ 
+-      /* When an OP_Program opcode is encounter (the only opcode that has
+-      ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
+-      ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
+-      ** has not already been seen.
+-      */
+-      if( pOp->p4type==P4_SUBPROGRAM ){
+-        int nByte = (nSub+1)*sizeof(SubProgram*);
+-        int j;
+-        for(j=0; j<nSub; j++){
+-          if( apSub[j]==pOp->p4.pProgram ) break;
++    /* When an OP_Program opcode is encounter (the only opcode that has
++    ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
++    ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
++    ** has not already been seen.
++    */
++    if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
++      int nByte = (nSub+1)*sizeof(SubProgram*);
++      int j;
++      for(j=0; j<nSub; j++){
++        if( apSub[j]==pOp->p4.pProgram ) break;
++      }
++      if( j==nSub ){
++        p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
++        if( p->rc!=SQLITE_OK ){
++          rc = SQLITE_ERROR;
++          break;
+         }
+-        if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){
+-          apSub = (SubProgram **)pSub->z;
+-          apSub[nSub++] = pOp->p4.pProgram;
+-          pSub->flags |= MEM_Blob;
+-          pSub->n = nSub*sizeof(SubProgram*);
+-        }
++        apSub = (SubProgram **)pSub->z;
++        apSub[nSub++] = pOp->p4.pProgram;
++        pSub->flags |= MEM_Blob;
++        pSub->n = nSub*sizeof(SubProgram*);
++        nRow += pOp->p4.pProgram->nOp;
+       }
+     }
++    if( p->explain<2 ) break;
++    if( pOp->opcode==OP_Explain ) break;
++    if( pOp->opcode==OP_Init && p->pc>1 ) break;
++  }
+ 
+-    pMem->flags = MEM_Int;
+-    pMem->u.i = pOp->p1;                          /* P1 */
+-    pMem++;
++  if( rc==SQLITE_OK ){
++    if( db->u1.isInterrupted ){
++      p->rc = SQLITE_INTERRUPT;
++      rc = SQLITE_ERROR;
++      sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
++    }else{
++      char *zP4;
++      if( p->explain==1 ){
++        pMem->flags = MEM_Int;
++        pMem->u.i = i;                                /* Program counter */
++        pMem++;
++    
++        pMem->flags = MEM_Static|MEM_Str|MEM_Term;
++        pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
++        assert( pMem->z!=0 );
++        pMem->n = sqlite3Strlen30(pMem->z);
++        pMem->enc = SQLITE_UTF8;
++        pMem++;
++      }
+ 
+-    pMem->flags = MEM_Int;
+-    pMem->u.i = pOp->p2;                          /* P2 */
+-    pMem++;
++      pMem->flags = MEM_Int;
++      pMem->u.i = pOp->p1;                          /* P1 */
++      pMem++;
+ 
+-    pMem->flags = MEM_Int;
+-    pMem->u.i = pOp->p3;                          /* P3 */
+-    pMem++;
++      pMem->flags = MEM_Int;
++      pMem->u.i = pOp->p2;                          /* P2 */
++      pMem++;
+ 
+-    if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
+-      assert( p->db->mallocFailed );
+-      return SQLITE_ERROR;
+-    }
+-    pMem->flags = MEM_Str|MEM_Term;
+-    zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
+-    if( zP4!=pMem->z ){
+-      pMem->n = 0;
+-      sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
+-    }else{
+-      assert( pMem->z!=0 );
+-      pMem->n = sqlite3Strlen30(pMem->z);
+-      pMem->enc = SQLITE_UTF8;
+-    }
+-    pMem++;
++      pMem->flags = MEM_Int;
++      pMem->u.i = pOp->p3;                          /* P3 */
++      pMem++;
+ 
+-    if( p->explain==1 ){
+-      if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
++      if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
+         assert( p->db->mallocFailed );
+         return SQLITE_ERROR;
+       }
+       pMem->flags = MEM_Str|MEM_Term;
+-      pMem->n = 2;
+-      sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5);   /* P5 */
+-      pMem->enc = SQLITE_UTF8;
++      zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
++      if( zP4!=pMem->z ){
++        pMem->n = 0;
++        sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
++      }else{
++        assert( pMem->z!=0 );
++        pMem->n = sqlite3Strlen30(pMem->z);
++        pMem->enc = SQLITE_UTF8;
++      }
+       pMem++;
+-  
++
++      if( p->explain==1 ){
++        if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
++          assert( p->db->mallocFailed );
++          return SQLITE_ERROR;
++        }
++        pMem->flags = MEM_Str|MEM_Term;
++        pMem->n = 2;
++        sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5);   /* P5 */
++        pMem->enc = SQLITE_UTF8;
++        pMem++;
++    
+ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+-      if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
+-        assert( p->db->mallocFailed );
+-        return SQLITE_ERROR;
+-      }
+-      pMem->flags = MEM_Str|MEM_Term;
+-      pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+-      pMem->enc = SQLITE_UTF8;
++        if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
++          assert( p->db->mallocFailed );
++          return SQLITE_ERROR;
++        }
++        pMem->flags = MEM_Str|MEM_Term;
++        pMem->n = displayComment(pOp, zP4, pMem->z, 500);
++        pMem->enc = SQLITE_UTF8;
+ #else
+-      pMem->flags = MEM_Null;                       /* Comment */
++        pMem->flags = MEM_Null;                       /* Comment */
+ #endif
++      }
++
++      p->nResColumn = 8 - 4*(p->explain-1);
++      p->pResultSet = &p->aMem[1];
++      p->rc = SQLITE_OK;
++      rc = SQLITE_ROW;
+     }
+-
+-    p->nResColumn = 8 - 4*(p->explain-1);
+-    p->pResultSet = &p->aMem[1];
+-    p->rc = SQLITE_OK;
+-    rc = SQLITE_ROW;
+   }
+   return rc;
+ }
+@@ -74148,27 +78126,6 @@
+ }
+ 
+ /*
+-** Clean up the VM after a single run.
+-*/
+-static void Cleanup(Vdbe *p){
+-  sqlite3 *db = p->db;
+-
+-#ifdef SQLITE_DEBUG
+-  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
+-  ** Vdbe.aMem[] arrays have already been cleaned up.  */
+-  int i;
+-  if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
+-  if( p->aMem ){
+-    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
+-  }
+-#endif
+-
+-  sqlite3DbFree(db, p->zErrMsg);
+-  p->zErrMsg = 0;
+-  p->pResultSet = 0;
+-}
+-
+-/*
+ ** Set the number of result columns that will be returned by this SQL
+ ** statement. This is now set at compile time, rather than during
+ ** execution of the vdbe program so that sqlite3_column_count() can
+@@ -74276,6 +78233,7 @@
+       pPager = sqlite3BtreePager(pBt);
+       if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+        && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
++       && sqlite3PagerIsMemdb(pPager)==0
+       ){ 
+         assert( i!=1 );
+         nTrans++;
+@@ -74876,6 +78834,10 @@
+ ** VDBE_MAGIC_INIT.
+ */
+ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
++#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
++  int i;
++#endif
++
+   sqlite3 *db;
+   db = p->db;
+ 
+@@ -74885,7 +78847,7 @@
+   */
+   sqlite3VdbeHalt(p);
+ 
+-  /* If the VDBE has be run even partially, then transfer the error code
++  /* If the VDBE has been run even partially, then transfer the error code
+   ** and error message from the VDBE into the main database structure.  But
+   ** if the VDBE has just been set to run but has not actually executed any
+   ** instructions yet, leave the main database error information unchanged.
+@@ -74893,8 +78855,6 @@
+   if( p->pc>=0 ){
+     vdbeInvokeSqllog(p);
+     sqlite3VdbeTransferError(p);
+-    sqlite3DbFree(db, p->zErrMsg);
+-    p->zErrMsg = 0;
+     if( p->runOnlyOnce ) p->expired = 1;
+   }else if( p->rc && p->expired ){
+     /* The expired flag was set on the VDBE before the first call
+@@ -74902,13 +78862,24 @@
+     ** called), set the database error in this case as well.
+     */
+     sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
+-    sqlite3DbFree(db, p->zErrMsg);
+-    p->zErrMsg = 0;
+   }
+ 
+-  /* Reclaim all memory used by the VDBE
++  /* Reset register contents and reclaim error message memory.
+   */
+-  Cleanup(p);
++#ifdef SQLITE_DEBUG
++  /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
++  ** Vdbe.aMem[] arrays have already been cleaned up.  */
++  if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
++  if( p->aMem ){
++    for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
++  }
++#endif
++  sqlite3DbFree(db, p->zErrMsg);
++  p->zErrMsg = 0;
++  p->pResultSet = 0;
++#ifdef SQLITE_DEBUG
++  p->nWrite = 0;
++#endif
+ 
+   /* Save profiling information from this VDBE run.
+   */
+@@ -74916,7 +78887,6 @@
+   {
+     FILE *out = fopen("vdbe_profile.out", "a");
+     if( out ){
+-      int i;
+       fprintf(out, "---- ");
+       for(i=0; i<p->nOp; i++){
+         fprintf(out, "%02x", p->aOp[i].opcode);
+@@ -75025,6 +78995,9 @@
+   vdbeFreeOpArray(db, p->aOp, p->nOp);
+   sqlite3DbFree(db, p->aColName);
+   sqlite3DbFree(db, p->zSql);
++#ifdef SQLITE_ENABLE_NORMALIZE
++  sqlite3DbFree(db, p->zNormSql);
++#endif
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+   {
+     int i;
+@@ -75042,7 +79015,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
+   sqlite3 *db;
+ 
+-  if( NEVER(p==0) ) return;
++  assert( p!=0 );
+   db = p->db;
+   assert( sqlite3_mutex_held(db->mutex) );
+   sqlite3VdbeClearObject(db, p);
+@@ -75129,20 +79102,19 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
+   VdbeCursor *p = *pp;
+-  if( p->eCurType==CURTYPE_BTREE ){
+-    if( p->deferredMoveto ){
+-      int iMap;
+-      if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
+-        *pp = p->pAltCursor;
+-        *piCol = iMap - 1;
+-        return SQLITE_OK;
+-      }
+-      return handleDeferredMoveto(p);
++  assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
++  if( p->deferredMoveto ){
++    int iMap;
++    if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
++      *pp = p->pAltCursor;
++      *piCol = iMap - 1;
++      return SQLITE_OK;
+     }
+-    if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+-      return handleMovedCursor(p);
+-    }
++    return handleDeferredMoveto(p);
+   }
++  if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
++    return handleMovedCursor(p);
++  }
+   return SQLITE_OK;
+ }
+ 
+@@ -75439,7 +79411,13 @@
+   Mem *pMem                     /* Memory cell to write value into */
+ ){
+   switch( serial_type ){
+-    case 10:   /* Reserved for future use */
++    case 10: { /* Internal use only: NULL with virtual table
++               ** UPDATE no-change flag set */
++      pMem->flags = MEM_Null|MEM_Zero;
++      pMem->n = 0;
++      pMem->u.nZero = 0;
++      break;
++    }
+     case 11:   /* Reserved for future use */
+     case 0: {  /* Null */
+       /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
+@@ -75537,13 +79515,13 @@
+ ){
+   UnpackedRecord *p;              /* Unpacked record to return */
+   int nByte;                      /* Number of bytes required for *p */
+-  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
++  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
+   p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
+   if( !p ) return 0;
+   p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
+   assert( pKeyInfo->aSortOrder!=0 );
+   p->pKeyInfo = pKeyInfo;
+-  p->nField = pKeyInfo->nField + 1;
++  p->nField = pKeyInfo->nKeyField + 1;
+   return p;
+ }
+ 
+@@ -75583,7 +79561,7 @@
+     pMem++;
+     if( (++u)>=p->nField ) break;
+   }
+-  assert( u<=pKeyInfo->nField + 1 );
++  assert( u<=pKeyInfo->nKeyField + 1 );
+   p->nField = u;
+ }
+ 
+@@ -75632,9 +79610,9 @@
+   idx1 = getVarint32(aKey1, szHdr1);
+   if( szHdr1>98307 ) return SQLITE_CORRUPT;
+   d1 = szHdr1;
+-  assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
++  assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
+   assert( pKeyInfo->aSortOrder!=0 );
+-  assert( pKeyInfo->nField>0 );
++  assert( pKeyInfo->nKeyField>0 );
+   assert( idx1<=szHdr1 || CORRUPT_DB );
+   do{
+     u32 serial_type1;
+@@ -75696,12 +79674,12 @@
+ /*
+ ** 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.
++** limit given by pKeyInfo->nAllField.
+ **
+ ** 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
+-** that the KeyInfo.nField or KeyInfo.nXField values were computed
++** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed
+ ** incorrectly.
+ */
+ static void vdbeAssertFieldCountWithinLimits(
+@@ -75722,7 +79700,7 @@
+     idx += getVarint32(aKey+idx, notUsed);
+     nField++;
+   }
+-  assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
++  assert( nField <= pKeyInfo->nAllField );
+ }
+ #else
+ # define vdbeAssertFieldCountWithinLimits(A,B,C)
+@@ -75784,7 +79762,7 @@
+ ** is less than, equal to, or greater than the second, respectively.
+ ** If one blob is a prefix of the other, then the shorter is the lessor.
+ */
+-static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
++SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+   int c;
+   int n1 = pB1->n;
+   int n2 = pB2->n;
+@@ -75827,13 +79805,10 @@
+     i64 y;
+     double s;
+     if( r<-9223372036854775808.0 ) return +1;
+-    if( r>9223372036854775807.0 ) return -1;
++    if( r>=9223372036854775808.0 ) return -1;
+     y = (i64)r;
+     if( i<y ) return -1;
+-    if( i>y ){
+-      if( y==SMALLEST_INT64 && r>0.0 ) return -1;
+-      return +1;
+-    }
++    if( i>y ) return +1;
+     s = (double)i;
+     if( s<r ) return -1;
+     if( s>r ) return +1;
+@@ -75857,7 +79832,7 @@
+   f1 = pMem1->flags;
+   f2 = pMem2->flags;
+   combined_flags = f1|f2;
+-  assert( (combined_flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) );
+  
+   /* If one value is NULL, it is less than the other. If both values
+   ** are NULL, return 0.
+@@ -76002,7 +79977,7 @@
+   u32 idx1;                       /* Offset of first type in header */
+   int rc = 0;                     /* Return value */
+   Mem *pRhs = pPKey2->aMem;       /* Next field of pPKey2 to compare */
+-  KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
++  KeyInfo *pKeyInfo;
+   const unsigned char *aKey1 = (const unsigned char *)pKey1;
+   Mem mem1;
+ 
+@@ -76027,10 +80002,10 @@
+   }
+ 
+   VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
+-  assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField 
++  assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField 
+        || CORRUPT_DB );
+   assert( pPKey2->pKeyInfo->aSortOrder!=0 );
+-  assert( pPKey2->pKeyInfo->nField>0 );
++  assert( pPKey2->pKeyInfo->nKeyField>0 );
+   assert( idx1<=szHdr1 || CORRUPT_DB );
+   do{
+     u32 serial_type;
+@@ -76097,7 +80072,7 @@
+         if( (d1+mem1.n) > (unsigned)nKey1 ){
+           pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+           return 0;                /* Corruption */
+-        }else if( pKeyInfo->aColl[i] ){
++        }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
+           mem1.enc = pKeyInfo->enc;
+           mem1.db = pKeyInfo->db;
+           mem1.flags = MEM_Str;
+@@ -76148,7 +80123,7 @@
+     }
+ 
+     if( rc!=0 ){
+-      if( pKeyInfo->aSortOrder[i] ){
++      if( pPKey2->pKeyInfo->aSortOrder[i] ){
+         rc = -rc;
+       }
+       assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
+@@ -76157,10 +80132,11 @@
+     }
+ 
+     i++;
++    if( i==pPKey2->nField ) break;
+     pRhs++;
+     d1 += sqlite3VdbeSerialTypeLen(serial_type);
+     idx1 += sqlite3VarintLen(serial_type);
+-  }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
++  }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 );
+ 
+   /* No memory allocation is ever used on mem1.  Prove this using
+   ** the following assert().  If the assert() fails, it indicates a
+@@ -76172,7 +80148,7 @@
+   ** value.  */
+   assert( CORRUPT_DB 
+        || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) 
+-       || pKeyInfo->db->mallocFailed
++       || pPKey2->pKeyInfo->db->mallocFailed
+   );
+   pPKey2->eqSeen = 1;
+   return pPKey2->default_rc;
+@@ -76363,7 +80339,7 @@
+   ** The easiest way to enforce this limit is to consider only records with
+   ** 13 fields or less. If the first field is an integer, the maximum legal
+   ** header size is (12*5 + 1 + 1) bytes.  */
+-  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
++  if( p->pKeyInfo->nAllField<=13 ){
+     int flags = p->aMem[0].flags;
+     if( p->pKeyInfo->aSortOrder[0] ){
+       p->r1 = 1;
+@@ -76423,7 +80399,9 @@
+   (void)getVarint32((u8*)m.z, szHdr);
+   testcase( szHdr==3 );
+   testcase( szHdr==m.n );
+-  if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
++  testcase( szHdr>0x7fffffff );
++  assert( m.n>=0 );
++  if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
+     goto idx_rowid_corruption;
+   }
+ 
+@@ -76498,7 +80476,7 @@
+   if( rc ){
+     return rc;
+   }
+-  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
++  *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
+   sqlite3VdbeMemRelease(&m);
+   return SQLITE_OK;
+ }
+@@ -76530,11 +80508,19 @@
+ ** programs obsolete.  Removing user-defined functions or collating
+ ** sequences, or changing an authorization function are the types of
+ ** things that make prepared statements obsolete.
++**
++** If iCode is 1, then expiration is advisory.  The statement should
++** be reprepared before being restarted, but if it is already running
++** it is allowed to run to completion.
++**
++** Internally, this function just sets the Vdbe.expired flag on all
++** prepared statements.  The flag is set to 1 for an immediate expiration
++** and set to 2 for an advisory expiration.
+ */
+-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){
++SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){
+   Vdbe *p;
+   for(p = db->pVdbe; p; p=p->pNext){
+-    p->expired = 1;
++    p->expired = iCode+1;
+   }
+ }
+ 
+@@ -76698,7 +80684,7 @@
+   preupdate.iNewReg = iReg;
+   preupdate.keyinfo.db = db;
+   preupdate.keyinfo.enc = ENC(db);
+-  preupdate.keyinfo.nField = pTab->nCol;
++  preupdate.keyinfo.nKeyField = pTab->nCol;
+   preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
+   preupdate.iKey1 = iKey1;
+   preupdate.iKey2 = iKey2;
+@@ -76708,8 +80694,8 @@
+   db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
+   db->pPreUpdate = 0;
+   sqlite3DbFree(db, preupdate.aRecord);
+-  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
+-  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
++  vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked);
++  vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked);
+   if( preupdate.aNew ){
+     int i;
+     for(i=0; i<pCsr->nField; i++){
+@@ -76992,6 +80978,11 @@
+   return aType[pVal->flags&MEM_AffMask];
+ }
+ 
++/* Return true if a parameter to xUpdate represents an unchanged column */
++SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
++  return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
++}
++
+ /* Make a copy of an sqlite3_value object
+ */
+ SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
+@@ -77091,7 +81082,6 @@
+ SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_ERROR;
+-  pCtx->fErrorOrAux = 1;
+   sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
+ }
+ #ifndef SQLITE_OMIT_UTF16
+@@ -77098,7 +81088,6 @@
+ SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_ERROR;
+-  pCtx->fErrorOrAux = 1;
+   sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
+ }
+ #endif
+@@ -77122,7 +81111,8 @@
+ ){
+   Mem *pOut = pCtx->pOut;
+   assert( sqlite3_mutex_held(pOut->db->mutex) );
+-  sqlite3VdbeMemSetNull(pOut);
++  sqlite3VdbeMemRelease(pOut);
++  pOut->flags = MEM_Null;
+   sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
+ }
+ SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
+@@ -77203,8 +81193,7 @@
+   return SQLITE_OK;
+ }
+ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+-  pCtx->isError = errCode;
+-  pCtx->fErrorOrAux = 1;
++  pCtx->isError = errCode ? errCode : -1;
+ #ifdef SQLITE_DEBUG
+   if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
+ #endif
+@@ -77218,7 +81207,6 @@
+ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   pCtx->isError = SQLITE_TOOBIG;
+-  pCtx->fErrorOrAux = 1;
+   sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 
+                        SQLITE_UTF8, SQLITE_STATIC);
+ }
+@@ -77228,7 +81216,6 @@
+   assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+   sqlite3VdbeMemSetNull(pCtx->pOut);
+   pCtx->isError = SQLITE_NOMEM_BKPT;
+-  pCtx->fErrorOrAux = 1;
+   sqlite3OomFault(pCtx->pOut->db);
+ }
+ 
+@@ -77247,7 +81234,7 @@
+       sqlite3BtreeEnter(pBt);
+       nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+       sqlite3BtreeLeave(pBt);
+-      if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
++      if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
+         rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
+       }
+     }
+@@ -77357,7 +81344,7 @@
+   if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
+ #endif
+ 
+-  if( rc==SQLITE_DONE ){
++  if( rc==SQLITE_DONE && db->autoCommit ){
+     assert( p->rc==SQLITE_OK );
+     p->rc = doWalCallbacks(db);
+     if( p->rc!=SQLITE_OK ){
+@@ -77401,7 +81388,6 @@
+ */
+ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
+   int rc = SQLITE_OK;      /* Result from sqlite3Step() */
+-  int rc2 = SQLITE_OK;     /* Result from sqlite3Reprepare() */
+   Vdbe *v = (Vdbe*)pStmt;  /* the prepared statement */
+   int cnt = 0;             /* Counter to prevent infinite loop of reprepares */
+   sqlite3 *db;             /* The database connection */
+@@ -77415,32 +81401,31 @@
+   while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
+          && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
+     int savedPc = v->pc;
+-    rc2 = rc = sqlite3Reprepare(v);
+-    if( rc!=SQLITE_OK) break;
++    rc = sqlite3Reprepare(v);
++    if( rc!=SQLITE_OK ){
++      /* This case occurs after failing to recompile an sql statement. 
++      ** The error message from the SQL compiler has already been loaded 
++      ** into the database handle. This block copies the error message 
++      ** from the database handle into the statement and sets the statement
++      ** program counter to 0 to ensure that when the statement is 
++      ** finalized or reset the parser error message is available via
++      ** sqlite3_errmsg() and sqlite3_errcode().
++      */
++      const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
++      sqlite3DbFree(db, v->zErrMsg);
++      if( !db->mallocFailed ){
++        v->zErrMsg = sqlite3DbStrDup(db, zErr);
++        v->rc = rc = sqlite3ApiExit(db, rc);
++      } else {
++        v->zErrMsg = 0;
++        v->rc = rc = SQLITE_NOMEM_BKPT;
++      }
++      break;
++    }
+     sqlite3_reset(pStmt);
+     if( savedPc>=0 ) v->doingRerun = 1;
+     assert( v->expired==0 );
+   }
+-  if( rc2!=SQLITE_OK ){
+-    /* This case occurs after failing to recompile an sql statement. 
+-    ** The error message from the SQL compiler has already been loaded 
+-    ** into the database handle. This block copies the error message 
+-    ** from the database handle into the statement and sets the statement
+-    ** program counter to 0 to ensure that when the statement is 
+-    ** finalized or reset the parser error message is available via
+-    ** sqlite3_errmsg() and sqlite3_errcode().
+-    */
+-    const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
+-    sqlite3DbFree(db, v->zErrMsg);
+-    if( !db->mallocFailed ){
+-      v->zErrMsg = sqlite3DbStrDup(db, zErr);
+-      v->rc = rc2;
+-    } else {
+-      v->zErrMsg = 0;
+-      v->rc = rc = SQLITE_NOMEM_BKPT;
+-    }
+-  }
+-  rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+   return rc;
+ }
+@@ -77471,6 +81456,25 @@
+ }
+ 
+ /*
++** If this routine is invoked from within an xColumn method of a virtual
++** table, then it returns true if and only if the the call is during an
++** UPDATE operation and the value of the column will not be modified
++** by the UPDATE.
++**
++** If this routine is called from any context other than within the
++** xColumn method of a virtual table, then the return value is meaningless
++** and arbitrary.
++**
++** Virtual table implements might use this routine to optimize their
++** performance by substituting a NULL result, or some other light-weight
++** value, as a signal to the xUpdate routine that the column is unchanged.
++*/
++SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
++  assert( p );
++  return sqlite3_value_nochange(p->pOut);
++}
++
++/*
+ ** Return the current time for a statement.  If the current time
+ ** is requested more than once within the same run of a single prepared
+ ** statement, the exact same time is returned for each invocation regardless
+@@ -77494,28 +81498,6 @@
+ }
+ 
+ /*
+-** The following is the implementation of an SQL function that always
+-** fails with an error message stating that the function is used in the
+-** wrong context.  The sqlite3_overload_function() API might construct
+-** SQL function that use this routine so that the functions will exist
+-** for name resolution but are actually overloaded by the xFindFunction
+-** method of virtual tables.
+-*/
+-SQLITE_PRIVATE void sqlite3InvalidFunction(
+-  sqlite3_context *context,  /* The function calling context */
+-  int NotUsed,               /* Number of arguments to the function */
+-  sqlite3_value **NotUsed2   /* Value of each argument */
+-){
+-  const char *zName = context->pFunc->zName;
+-  char *zErr;
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  zErr = sqlite3_mprintf(
+-      "unable to use function %s in the requested context", zName);
+-  sqlite3_result_error(context, zErr, -1);
+-  sqlite3_free(zErr);
+-}
+-
+-/*
+ ** Create a new aggregate context for p and return a pointer to
+ ** its pMem->z element.
+ */
+@@ -77618,10 +81600,7 @@
+     pAuxData->iAuxArg = iArg;
+     pAuxData->pNextAux = pVdbe->pAuxData;
+     pVdbe->pAuxData = pAuxData;
+-    if( pCtx->fErrorOrAux==0 ){
+-      pCtx->isError = 0;
+-      pCtx->fErrorOrAux = 1;
+-    }
++    if( pCtx->isError==0 ) pCtx->isError = -1;
+   }else if( pAuxData->xDeleteAux ){
+     pAuxData->xDeleteAux(pAuxData->pAux);
+   }
+@@ -77701,7 +81680,7 @@
+         /* .xDel       = */ (void(*)(void*))0,
+ #ifdef SQLITE_DEBUG
+         /* .pScopyFrom = */ (Mem*)0,
+-        /* .pFiller    = */ (void*)0,
++        /* .mScopyFlags= */ 0,
+ #endif
+       };
+   return &nullMem;
+@@ -78377,7 +82356,9 @@
+   Vdbe *pVdbe = (Vdbe*)pStmt;
+   u32 v;
+ #ifdef SQLITE_ENABLE_API_ARMOR
+-  if( !pStmt ){
++  if( !pStmt 
++   || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter)))
++  ){
+     (void)SQLITE_MISUSE_BKPT;
+     return 0;
+   }
+@@ -78431,6 +82412,16 @@
+ #endif
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
++/*
++** Return the normalized SQL associated with a prepared statement.
++*/
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
++  Vdbe *p = (Vdbe *)pStmt;
++  return p ? p->zNormSql : 0;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ /*
+ ** Allocate and populate an UnpackedRecord structure based on the serialized
+@@ -78446,7 +82437,7 @@
+ 
+   pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
+   if( pRet ){
+-    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
++    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
+     sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
+   }
+   return pRet;
+@@ -78519,7 +82510,7 @@
+ */
+ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
+   PreUpdate *p = db->pPreUpdate;
+-  return (p ? p->keyinfo.nField : 0);
++  return (p ? p->keyinfo.nKeyField : 0);
+ }
+ #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+ 
+@@ -78772,7 +82763,7 @@
+   Mem *pVar;               /* Value of a host parameter */
+   StrAccum out;            /* Accumulate the output here */
+ #ifndef SQLITE_OMIT_UTF16
+-  Mem utf8;                /* Used to convert UTF16 parameters into UTF8 for display */
++  Mem utf8;                /* Used to convert UTF16 into UTF8 for display */
+ #endif
+   char zBase[100];         /* Initial working space */
+ 
+@@ -78783,17 +82774,17 @@
+     while( *zRawSql ){
+       const char *zStart = zRawSql;
+       while( *(zRawSql++)!='\n' && *zRawSql );
+-      sqlite3StrAccumAppend(&out, "-- ", 3);
++      sqlite3_str_append(&out, "-- ", 3);
+       assert( (zRawSql - zStart) > 0 );
+-      sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
++      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
+     }
+   }else if( p->nVar==0 ){
+-    sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
++    sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
+   }else{
+     while( zRawSql[0] ){
+       n = findNextHostParameter(zRawSql, &nToken);
+       assert( n>0 );
+-      sqlite3StrAccumAppend(&out, zRawSql, n);
++      sqlite3_str_append(&out, zRawSql, n);
+       zRawSql += n;
+       assert( zRawSql[0] || nToken==0 );
+       if( nToken==0 ) break;
+@@ -78819,11 +82810,11 @@
+       assert( idx>0 && idx<=p->nVar );
+       pVar = &p->aVar[idx-1];
+       if( pVar->flags & MEM_Null ){
+-        sqlite3StrAccumAppend(&out, "NULL", 4);
++        sqlite3_str_append(&out, "NULL", 4);
+       }else if( pVar->flags & MEM_Int ){
+-        sqlite3XPrintf(&out, "%lld", pVar->u.i);
++        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
+       }else if( pVar->flags & MEM_Real ){
+-        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
++        sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
+       }else if( pVar->flags & MEM_Str ){
+         int nOut;  /* Number of bytes of the string text to include in output */
+ #ifndef SQLITE_OMIT_UTF16
+@@ -78833,7 +82824,7 @@
+           utf8.db = db;
+           sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
+           if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
+-            out.accError = STRACCUM_NOMEM;
++            out.accError = SQLITE_NOMEM;
+             out.nAlloc = 0;
+           }
+           pVar = &utf8;
+@@ -78846,10 +82837,10 @@
+           while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
+         }
+ #endif    
+-        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
++        sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+ #ifndef SQLITE_OMIT_UTF16
+@@ -78856,28 +82847,28 @@
+         if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
+ #endif
+       }else if( pVar->flags & MEM_Zero ){
+-        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
++        sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
+       }else{
+         int nOut;  /* Number of bytes of the blob to include in output */
+         assert( pVar->flags & MEM_Blob );
+-        sqlite3StrAccumAppend(&out, "x'", 2);
++        sqlite3_str_append(&out, "x'", 2);
+         nOut = pVar->n;
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
+ #endif
+         for(i=0; i<nOut; i++){
+-          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
++          sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
+         }
+-        sqlite3StrAccumAppend(&out, "'", 1);
++        sqlite3_str_append(&out, "'", 1);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+       }
+     }
+   }
+-  if( out.accError ) sqlite3StrAccumReset(&out);
++  if( out.accError ) sqlite3_str_reset(&out);
+   return sqlite3StrAccumFinish(&out);
+ }
+ 
+@@ -79009,32 +83000,56 @@
+ ** feature is used for test suite validation only and does not appear an
+ ** production builds.
+ **
+-** M is an integer, 2 or 3, that indices how many different ways the
+-** branch can go.  It is usually 2.  "I" is the direction the branch
+-** goes.  0 means falls through.  1 means branch is taken.  2 means the
+-** second alternative branch is taken.
++** M is an integer between 2 and 4.  2 indicates a ordinary two-way
++** branch (I=0 means fall through and I=1 means taken).  3 indicates
++** a 3-way branch where the third way is when one of the operands is
++** NULL.  4 indicates the OP_Jump instruction which has three destinations
++** depending on whether the first operand is less than, equal to, or greater
++** than the second. 
+ **
+ ** iSrcLine is the source code line (from the __LINE__ macro) that
+-** generated the VDBE instruction.  This instrumentation assumes that all
+-** source code is in a single file (the amalgamation).  Special values 1
+-** and 2 for the iSrcLine parameter mean that this particular branch is
+-** always taken or never taken, respectively.
++** generated the VDBE instruction combined with flag bits.  The source
++** code line number is in the lower 24 bits of iSrcLine and the upper
++** 8 bytes are flags.  The lower three bits of the flags indicate
++** values for I that should never occur.  For example, if the branch is
++** always taken, the flags should be 0x05 since the fall-through and
++** alternate branch are never taken.  If a branch is never taken then
++** flags should be 0x06 since only the fall-through approach is allowed.
++**
++** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
++** interested in equal or not-equal.  In other words, I==0 and I==2
++** should be treated the same.
++**
++** Since only a line number is retained, not the filename, this macro
++** only works for amalgamation builds.  But that is ok, since these macros
++** should be no-ops except for special builds used to measure test coverage.
+ */
+ #if !defined(SQLITE_VDBE_COVERAGE)
+ # define VdbeBranchTaken(I,M)
+ #else
+ # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
+-  static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
+-    if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
+-      M = iSrcLine;
+-      /* Assert the truth of VdbeCoverageAlwaysTaken() and 
+-      ** VdbeCoverageNeverTaken() */
+-      assert( (M & I)==I );
+-    }else{
+-      if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
+-      sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
+-                                      iSrcLine,I,M);
++  static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){
++    u8 mNever;
++    assert( I<=2 );  /* 0: fall through,  1: taken,  2: alternate taken */
++    assert( M<=4 );  /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */
++    assert( I<M );   /* I can only be 2 if M is 3 or 4 */
++    /* Transform I from a integer [0,1,2] into a bitmask of [1,2,4] */
++    I = 1<<I;
++    /* The upper 8 bits of iSrcLine are flags.  The lower three bits of
++    ** the flags indicate directions that the branch can never go.  If
++    ** a branch really does go in one of those directions, assert right
++    ** away. */
++    mNever = iSrcLine >> 24;
++    assert( (I & mNever)==0 );
++    if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
++    I |= mNever;
++    if( M==2 ) I |= 0x04;
++    if( M==4 ){
++      I |= 0x08;
++      if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
+     }
++    sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
++                                    iSrcLine&0xffffff, I, M);
+   }
+ #endif
+ 
+@@ -79151,6 +83166,11 @@
+     pRec->flags |= MEM_Real;
+     if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
+   }
++  /* TEXT->NUMERIC is many->one.  Hence, it is important to invalidate the
++  ** string representation after computing a numeric equivalent, because the
++  ** string representation might not be the canonical representation for the
++  ** numeric value.  Ticket [343634942dd54ab57b7024] 2018-01-31. */
++  pRec->flags &= ~MEM_Str;
+ }
+ 
+ /*
+@@ -79241,7 +83261,7 @@
+   if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
+     return 0;
+   }
+-  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
++  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
+     return MEM_Int;
+   }
+   return MEM_Real;
+@@ -79351,7 +83371,7 @@
+   if( p->flags & MEM_Undefined ){
+     printf(" undefined");
+   }else if( p->flags & MEM_Null ){
+-    printf(" NULL");
++    printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
+   }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
+     printf(" si:%lld", p->u.i);
+   }else if( p->flags & MEM_Int ){
+@@ -79360,7 +83380,7 @@
+   }else if( p->flags & MEM_Real ){
+     printf(" r:%g", p->u.r);
+ #endif
+-  }else if( p->flags & MEM_RowSet ){
++  }else if( sqlite3VdbeMemIsRowSet(p) ){
+     printf(" (rowset)");
+   }else{
+     char zBuf[200];
+@@ -79619,7 +83639,7 @@
+ 
+     assert( pOp>=aOp && pOp<&aOp[p->nOp]);
+ #ifdef VDBE_PROFILE
+-    start = sqlite3Hwtime();
++    start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
+ #endif
+     nVmStep++;
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+@@ -79886,6 +83906,9 @@
+ */
+ case OP_HaltIfNull: {      /* in3 */
+   pIn3 = &aMem[pOp->p3];
++#ifdef SQLITE_DEBUG
++  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
++#endif
+   if( (pIn3->flags & MEM_Null)==0 ) break;
+   /* Fall through into OP_Halt */
+ }
+@@ -79925,6 +83948,9 @@
+   int pcx;
+ 
+   pcx = (int)(pOp - aOp);
++#ifdef SQLITE_DEBUG
++  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
++#endif
+   if( pOp->p1==SQLITE_OK && p->pFrame ){
+     /* Halt the sub-program. Return control to the parent frame. */
+     pFrame = p->pFrame;
+@@ -80108,6 +84134,9 @@
+   assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+   pOut->n = 0;
++#ifdef SQLITE_DEBUG
++  pOut->uTemp = 0;
++#endif
+   while( cnt>0 ){
+     pOut++;
+     memAboutToChange(p, pOut);
+@@ -80229,6 +84258,7 @@
+   pOut = &aMem[pOp->p2];
+   assert( pOut!=pIn1 );
+   while( 1 ){
++    memAboutToChange(p, pOut);
+     sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
+     Deephemeralize(pOut);
+ #ifdef SQLITE_DEBUG
+@@ -80261,7 +84291,8 @@
+   assert( pOut!=pIn1 );
+   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
+ #ifdef SQLITE_DEBUG
+-  if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
++  pOut->pScopyFrom = pIn1;
++  pOut->mScopyFlags = pIn1->flags;
+ #endif
+   break;
+ }
+@@ -80895,7 +84926,12 @@
+       if( (flags1 | flags3)&MEM_Str ){
+         if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+           applyNumericAffinity(pIn1,0);
+-          testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
++          assert( flags3==pIn3->flags );
++          /* testcase( flags3!=pIn3->flags );
++          ** this used to be possible with pIn1==pIn3, but not since
++          ** the column cache was removed.  The following assignment
++          ** is essentially a no-op.  But, it provides defense-in-depth
++          ** in case our analysis is incorrect, so it is left in. */
+           flags3 = pIn3->flags;
+         }
+         if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+@@ -80931,13 +84967,23 @@
+     res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+   }
+ compare_op:
+-  switch( pOp->opcode ){
+-    case OP_Eq:    res2 = res==0;     break;
+-    case OP_Ne:    res2 = res;        break;
+-    case OP_Lt:    res2 = res<0;      break;
+-    case OP_Le:    res2 = res<=0;     break;
+-    case OP_Gt:    res2 = res>0;      break;
+-    default:       res2 = res>=0;     break;
++  /* At this point, res is negative, zero, or positive if reg[P1] is
++  ** less than, equal to, or greater than reg[P3], respectively.  Compute
++  ** the answer to this operator in res2, depending on what the comparison
++  ** operator actually is.  The next block of code depends on the fact
++  ** that the 6 comparison operators are consecutive integers in this
++  ** order:  NE, EQ, GT, LE, LT, GE */
++  assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 );
++  assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 );
++  if( res<0 ){                        /* ne, eq, gt, le, lt, ge */
++    static const unsigned char aLTb[] = { 1,  0,  0,  1,  1,  0 };
++    res2 = aLTb[pOp->opcode - OP_Ne];
++  }else if( res==0 ){
++    static const unsigned char aEQb[] = { 0,  1,  0,  1,  0,  1 };
++    res2 = aEQb[pOp->opcode - OP_Ne];
++  }else{
++    static const unsigned char aGTb[] = { 1,  0,  1,  0,  0,  1 };
++    res2 = aGTb[pOp->opcode - OP_Ne];
+   }
+ 
+   /* Undo any changes made by applyAffinity() to the input registers. */
+@@ -80949,7 +84995,6 @@
+   if( pOp->p5 & SQLITE_STOREP2 ){
+     pOut = &aMem[pOp->p2];
+     iCompare = res;
+-    res2 = res2!=0;  /* For this path res2 must be exactly 0 or 1 */
+     if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){
+       /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1
+       ** and prevents OP_Ne from overwriting NULL with 0.  This flag
+@@ -81080,7 +85125,7 @@
+     assert( memIsValid(&aMem[p2+idx]) );
+     REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
+     REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
+-    assert( i<pKeyInfo->nField );
++    assert( i<pKeyInfo->nKeyField );
+     pColl = pKeyInfo->aColl[i];
+     bRev = pKeyInfo->aSortOrder[i];
+     iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
+@@ -81100,11 +85145,11 @@
+ */
+ case OP_Jump: {             /* jump */
+   if( iCompare<0 ){
+-    VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
++    VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
+   }else if( iCompare==0 ){
+-    VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
++    VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
+   }else{
+-    VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
++    VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1];
+   }
+   break;
+ }
+@@ -81134,18 +85179,8 @@
+   int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+   int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ 
+-  pIn1 = &aMem[pOp->p1];
+-  if( pIn1->flags & MEM_Null ){
+-    v1 = 2;
+-  }else{
+-    v1 = sqlite3VdbeIntValue(pIn1)!=0;
+-  }
+-  pIn2 = &aMem[pOp->p2];
+-  if( pIn2->flags & MEM_Null ){
+-    v2 = 2;
+-  }else{
+-    v2 = sqlite3VdbeIntValue(pIn2)!=0;
+-  }
++  v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2);
++  v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2);
+   if( pOp->opcode==OP_And ){
+     static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
+     v1 = and_logic[v1*3+v2];
+@@ -81163,6 +85198,35 @@
+   break;
+ }
+ 
++/* Opcode: IsTrue P1 P2 P3 P4 *
++** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4
++**
++** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and
++** IS NOT FALSE operators.
++**
++** Interpret the value in register P1 as a boolean value.  Store that
++** boolean (a 0 or 1) in register P2.  Or if the value in register P1 is 
++** NULL, then the P3 is stored in register P2.  Invert the answer if P4
++** is 1.
++**
++** The logic is summarized like this:
++**
++** <ul> 
++** <li> If P3==0 and P4==0  then  r[P2] := r[P1] IS TRUE
++** <li> If P3==1 and P4==1  then  r[P2] := r[P1] IS FALSE
++** <li> If P3==0 and P4==1  then  r[P2] := r[P1] IS NOT TRUE
++** <li> If P3==1 and P4==0  then  r[P2] := r[P1] IS NOT FALSE
++** </ul>
++*/
++case OP_IsTrue: {               /* in1, out2 */
++  assert( pOp->p4type==P4_INT32 );
++  assert( pOp->p4.i==0 || pOp->p4.i==1 );
++  assert( pOp->p3==0 || pOp->p3==1 );
++  sqlite3VdbeMemSetInt64(&aMem[pOp->p2],
++      sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i);
++  break;
++}
++
+ /* Opcode: Not P1 P2 * * *
+ ** Synopsis: r[P2]= !r[P1]
+ **
+@@ -81173,16 +85237,16 @@
+ case OP_Not: {                /* same as TK_NOT, in1, out2 */
+   pIn1 = &aMem[pOp->p1];
+   pOut = &aMem[pOp->p2];
+-  sqlite3VdbeMemSetNull(pOut);
+   if( (pIn1->flags & MEM_Null)==0 ){
+-    pOut->flags = MEM_Int;
+-    pOut->u.i = !sqlite3VdbeIntValue(pIn1);
++    sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0));
++  }else{
++    sqlite3VdbeMemSetNull(pOut);
+   }
+   break;
+ }
+ 
+ /* Opcode: BitNot P1 P2 * * *
+-** Synopsis: r[P1]= ~r[P1]
++** Synopsis: r[P2]= ~r[P1]
+ **
+ ** Interpret the content of register P1 as an integer.  Store the
+ ** ones-complement of the P1 value into register P2.  If P1 holds
+@@ -81243,6 +85307,14 @@
+ ** 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.
+ */
++case OP_If:  {               /* jump, in1 */
++  int c;
++  c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3);
++  VdbeBranchTaken(c!=0, 2);
++  if( c ) goto jump_to_p2;
++  break;
++}
++
+ /* Opcode: IfNot P1 P2 P3 * *
+ **
+ ** Jump to P2 if the value in register P1 is False.  The value
+@@ -81249,24 +85321,11 @@
+ ** is considered false if it has a numeric value of zero.  If the value
+ ** in P1 is NULL then take the jump if and only if P3 is non-zero.
+ */
+-case OP_If:                 /* jump, in1 */
+ case OP_IfNot: {            /* jump, in1 */
+   int c;
+-  pIn1 = &aMem[pOp->p1];
+-  if( pIn1->flags & MEM_Null ){
+-    c = pOp->p3;
+-  }else{
+-#ifdef SQLITE_OMIT_FLOATING_POINT
+-    c = sqlite3VdbeIntValue(pIn1)!=0;
+-#else
+-    c = sqlite3VdbeRealValue(pIn1)!=0.0;
+-#endif
+-    if( pOp->opcode==OP_IfNot ) c = !c;
+-  }
++  c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3);
+   VdbeBranchTaken(c!=0, 2);
+-  if( c ){
+-    goto jump_to_p2;
+-  }
++  if( c ) goto jump_to_p2;
+   break;
+ }
+ 
+@@ -81316,6 +85375,36 @@
+   break;
+ }
+ 
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
++/* Opcode: Offset P1 P2 P3 * *
++** Synopsis: r[P3] = sqlite_offset(P1)
++**
++** Store in register r[P3] the byte offset into the database file that is the
++** start of the payload for the record at which that cursor P1 is currently
++** pointing.
++**
++** P2 is the column number for the argument to the sqlite_offset() function.
++** This opcode does not use P2 itself, but the P2 value is used by the
++** code generator.  The P1, P2, and P3 operands to this opcode are the
++** same as for OP_Column.
++**
++** This opcode is only available if SQLite is compiled with the
++** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
++*/
++case OP_Offset: {          /* out3 */
++  VdbeCursor *pC;    /* The VDBE cursor */
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  pOut = &p->aMem[pOp->p3];
++  if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
++    sqlite3VdbeMemSetNull(pOut);
++  }else{
++    sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
++  }
++  break;
++}
++#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
++
+ /* Opcode: Column P1 P2 P3 P4 P5
+ ** Synopsis: r[P3]=PX
+ **
+@@ -81353,9 +85442,7 @@
+   const u8 *zData;   /* Part of the record being decoded */
+   const u8 *zHdr;    /* Next unparsed byte of the header */
+   const u8 *zEndHdr; /* Pointer to first byte after the header */
+-  u32 offset;        /* Offset into the data */
+   u64 offset64;      /* 64-bit offset */
+-  u32 avail;         /* Number of bytes of available data */
+   u32 t;             /* A type code from the record header */
+   Mem *pReg;         /* PseudoTable input register */
+ 
+@@ -81382,11 +85469,13 @@
+   if( pC->cacheStatus!=p->cacheCtr ){                /*OPTIMIZATION-IF-FALSE*/
+     if( pC->nullRow ){
+       if( pC->eCurType==CURTYPE_PSEUDO ){
+-        assert( pC->uc.pseudoTableReg>0 );
+-        pReg = &aMem[pC->uc.pseudoTableReg];
++        /* For the special case of as pseudo-cursor, the seekResult field
++        ** identifies the register that holds the record */
++        assert( pC->seekResult>0 );
++        pReg = &aMem[pC->seekResult];
+         assert( pReg->flags & MEM_Blob );
+         assert( memIsValid(pReg) );
+-        pC->payloadSize = pC->szRow = avail = pReg->n;
++        pC->payloadSize = pC->szRow = pReg->n;
+         pC->aRow = (u8*)pReg->z;
+       }else{
+         sqlite3VdbeMemSetNull(pDest);
+@@ -81398,23 +85487,19 @@
+       assert( pCrsr );
+       assert( sqlite3BtreeCursorIsValid(pCrsr) );
+       pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
+-      pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail);
+-      assert( avail<=65536 );  /* Maximum page size is 64KiB */
+-      if( pC->payloadSize <= (u32)avail ){
+-        pC->szRow = pC->payloadSize;
+-      }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
++      pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
++      assert( pC->szRow<=pC->payloadSize );
++      assert( pC->szRow<=65536 );  /* Maximum page size is 64KiB */
++      if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+         goto too_big;
+-      }else{
+-        pC->szRow = avail;
+       }
+     }
+     pC->cacheStatus = p->cacheCtr;
+-    pC->iHdrOffset = getVarint32(pC->aRow, offset);
++    pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
+     pC->nHdrParsed = 0;
+-    aOffset[0] = offset;
+ 
+ 
+-    if( avail<offset ){      /*OPTIMIZATION-IF-FALSE*/
++    if( pC->szRow<aOffset[0] ){      /*OPTIMIZATION-IF-FALSE*/
+       /* pC->aRow does not have to hold the entire row, but it does at least
+       ** need to cover the header of the record.  If pC->aRow does not contain
+       ** the complete header, then set it to zero, forcing the header to be
+@@ -81431,17 +85516,26 @@
+       ** 3-byte type for each of the maximum of 32768 columns plus three
+       ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
+       */
+-      if( offset > 98307 || offset > pC->payloadSize ){
+-        rc = SQLITE_CORRUPT_BKPT;
+-        goto abort_due_to_error;
++      if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
++        goto op_column_corrupt;
+       }
+-    }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/
+-      /* The following goto is an optimization.  It can be omitted and
+-      ** everything will still work.  But OP_Column is measurably faster
+-      ** by skipping the subsequent conditional, which is always true.
++    }else{
++      /* This is an optimization.  By skipping over the first few tests
++      ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
++      ** measurable performance gain.
++      **
++      ** This branch is taken even if aOffset[0]==0.  Such a record is never
++      ** generated by SQLite, and could be considered corruption, but we
++      ** accept it for historical reasons.  When aOffset[0]==0, the code this
++      ** branch jumps to reads past the end of the record, but never more
++      ** than a few bytes.  Even if the record occurs at the end of the page
++      ** content area, the "page header" comes after the page content and so
++      ** this overread is harmless.  Similar overreads can occur for a corrupt
++      ** database file.
+       */
+       zData = pC->aRow;
+       assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
++      testcase( aOffset[0]==0 );
+       goto op_column_read_header;
+     }
+   }
+@@ -81470,6 +85564,7 @@
+       offset64 = aOffset[i];
+       zHdr = zData + pC->iHdrOffset;
+       zEndHdr = zData + aOffset[0];
++      testcase( zHdr>=zEndHdr );
+       do{
+         if( (t = zHdr[0])<0x80 ){
+           zHdr++;
+@@ -81490,9 +85585,13 @@
+       if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
+        || (offset64 > pC->payloadSize)
+       ){
+-        if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+-        rc = SQLITE_CORRUPT_BKPT;
+-        goto abort_due_to_error;
++        if( aOffset[0]==0 ){
++          i = 0;
++          zHdr = zEndHdr;
++        }else{
++          if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
++          goto op_column_corrupt;
++        }
+       }
+ 
+       pC->nHdrParsed = i;
+@@ -81586,6 +85685,15 @@
+   UPDATE_MAX_BLOBSIZE(pDest);
+   REGISTER_TRACE(pOp->p3, pDest);
+   break;
++
++op_column_corrupt:
++  if( aOp[0].p3>0 ){
++    pOp = &aOp[aOp[0].p3-1];
++    break;
++  }else{
++    rc = SQLITE_CORRUPT_BKPT;
++    goto abort_due_to_error;
++  }
+ }
+ 
+ /* Opcode: Affinity P1 P2 * P4 *
+@@ -81710,9 +85818,18 @@
+   pRec = pLast;
+   do{
+     assert( memIsValid(pRec) );
+-    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
++    serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
+     if( pRec->flags & MEM_Zero ){
+-      if( nData ){
++      if( serial_type==0 ){
++        /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
++        ** table methods that never invoke sqlite3_result_xxxxx() while
++        ** computing an unchanging column value in an UPDATE statement.
++        ** Give such values a special internal-use-only serial-type of 10
++        ** so that they can be passed through to xUpdate and have
++        ** a true sqlite3_value_nochange(). */
++        assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
++        serial_type = 10;
++      }else if( nData ){
+         if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
+       }else{
+         nZero += pRec->u.nZero;
+@@ -81723,6 +85840,7 @@
+     testcase( serial_type==127 );
+     testcase( serial_type==128 );
+     nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
++    pRec->uTemp = serial_type;
+     if( pRec==pData0 ) break;
+     pRec--;
+   }while(1);
+@@ -81743,9 +85861,6 @@
+     if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
+   }
+   nByte = nHdr+nData;
+-  if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-    goto too_big;
+-  }
+ 
+   /* Make sure the output register has a buffer large enough to store 
+   ** the new record. The output register (pOp->p3) is not allowed to
+@@ -81752,8 +85867,19 @@
+   ** be one of the input registers (because the following call to
+   ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
+   */
+-  if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
+-    goto no_mem;
++  if( nByte+nZero<=pOut->szMalloc ){
++    /* The output register is already large enough to hold the record.
++    ** No error checks or buffer enlargement is required */
++    pOut->z = pOut->zMalloc;
++  }else{
++    /* Need to make sure that the output is not too big and then enlarge
++    ** the output register to hold the full result */
++    if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
++      goto too_big;
++    }
++    if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
++      goto no_mem;
++    }
+   }
+   zNewRecord = (u8 *)pOut->z;
+ 
+@@ -81926,7 +86052,7 @@
+         int isSchemaChange;
+         iSavepoint = db->nSavepoint - iSavepoint - 1;
+         if( p1==SAVEPOINT_ROLLBACK ){
+-          isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
++          isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
+           for(ii=0; ii<db->nDb; ii++){
+             rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
+                                        SQLITE_ABORT_ROLLBACK,
+@@ -81943,9 +86069,9 @@
+           }
+         }
+         if( isSchemaChange ){
+-          sqlite3ExpirePreparedStatements(db);
++          sqlite3ExpirePreparedStatements(db, 0);
+           sqlite3ResetAllSchemasOfConnection(db);
+-          db->flags = (db->flags | SQLITE_InternChanges);
++          db->mDbFlags |= DBFLAG_SchemaChange;
+         }
+       }
+   
+@@ -82085,8 +86211,7 @@
+ */
+ case OP_Transaction: {
+   Btree *pBt;
+-  int iMeta;
+-  int iGen;
++  int iMeta = 0;
+ 
+   assert( p->bIsReader );
+   assert( p->readOnly==0 || pOp->p2==0 );
+@@ -82099,7 +86224,7 @@
+   pBt = db->aDb[pOp->p1].pBt;
+ 
+   if( pBt ){
+-    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
++    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
+     testcase( rc==SQLITE_BUSY_SNAPSHOT );
+     testcase( rc==SQLITE_BUSY_RECOVERY );
+     if( rc!=SQLITE_OK ){
+@@ -82132,19 +86257,17 @@
+       p->nStmtDefCons = db->nDeferredCons;
+       p->nStmtDefImmCons = db->nDeferredImmCons;
+     }
+-
+-    /* Gather the schema version number for checking:
++  }
++  assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
++  if( pOp->p5
++   && (iMeta!=pOp->p3
++      || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
++  ){
++    /*
+     ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
+     ** version is checked to ensure that the schema has not changed since the
+     ** SQL statement was prepared.
+     */
+-    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+-    iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+-  }else{
+-    iGen = iMeta = 0;
+-  }
+-  assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
+-  if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){
+     sqlite3DbFree(db, p->zErrMsg);
+     p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
+     /* If the schema-cookie from the database file matches the cookie 
+@@ -82213,6 +86336,8 @@
+ */
+ case OP_SetCookie: {
+   Db *pDb;
++
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   assert( pOp->p2<SQLITE_N_BTREE_META );
+   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+   assert( DbMaskTest(p->btreeMask, pOp->p1) );
+@@ -82225,7 +86350,7 @@
+   if( pOp->p2==BTREE_SCHEMA_VERSION ){
+     /* When the schema cookie changes, record the new cookie internally */
+     pDb->pSchema->schema_cookie = pOp->p3;
+-    db->flags |= SQLITE_InternChanges;
++    db->mDbFlags |= DBFLAG_SchemaChange;
+   }else if( pOp->p2==BTREE_FILE_FORMAT ){
+     /* Record changes in the file format */
+     pDb->pSchema->file_format = pOp->p3;
+@@ -82233,7 +86358,7 @@
+   if( pOp->p1==1 ){
+     /* Invalidate all prepared statements whenever the TEMP database
+     ** schema is changed.  Ticket #1644 */
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+     p->expired = 0;
+   }
+   if( rc ) goto abort_due_to_error;
+@@ -82251,23 +86376,20 @@
+ ** values need not be contiguous but all P1 values should be small integers.
+ ** It is an error for P1 to be negative.
+ **
+-** If P5!=0 then use the content of register P2 as the root page, not
+-** the value of P2 itself.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** </ul>
+ **
+-** There will be a read lock on the database whenever there is an
+-** open cursor.  If the database was unlocked prior to this instruction
+-** then a read lock is acquired as part of this instruction.  A read
+-** lock allows other processes to read the database but prohibits
+-** any other process from modifying the database.  The read lock is
+-** released when all cursors are closed.  If this instruction attempts
+-** to get a read lock but fails, the script terminates with an
+-** SQLITE_BUSY error code.
+-**
+ ** The P4 value may be either an integer (P4_INT32) or a pointer to
+ ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
+-** structure, then said structure defines the content and collating 
+-** sequence of the index being opened. Otherwise, if P4 is an integer 
+-** value, it is set to the number of columns in the table.
++** object, then table being opened must be an [index b-tree] where the
++** KeyInfo object defines the content and collating 
++** sequence of that index b-tree. Otherwise, if P4 is an integer 
++** value, then the table being opened must be a [table b-tree] with a
++** number of columns no less than the value of P4.
+ **
+ ** See also: OpenWrite, ReopenIdx
+ */
+@@ -82274,36 +86396,58 @@
+ /* Opcode: ReopenIdx P1 P2 P3 P4 P5
+ ** Synopsis: root=P2 iDb=P3
+ **
+-** The ReopenIdx opcode works exactly like ReadOpen except that it first
+-** checks to see if the cursor on P1 is already open with a root page
+-** number of P2 and if it is this opcode becomes a no-op.  In other words,
++** The ReopenIdx opcode works like OP_OpenRead except that it first
++** checks to see if the cursor on P1 is already open on the same
++** b-tree and if it is this opcode becomes a no-op.  In other words,
+ ** if the cursor is already open, do not reopen it.
+ **
+-** The ReopenIdx opcode may only be used with P5==0 and with P4 being
+-** a P4_KEYINFO object.  Furthermore, the P3 value must be the same as
+-** every other ReopenIdx or OpenRead for the same cursor number.
++** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ
++** and with P4 being a P4_KEYINFO object.  Furthermore, the P3 value must
++** be the same as every other ReopenIdx or OpenRead for the same cursor
++** number.
+ **
+-** See the OpenRead opcode documentation for additional information.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** </ul>
++**
++** See also: OP_OpenRead, OP_OpenWrite
+ */
+ /* Opcode: OpenWrite P1 P2 P3 P4 P5
+ ** Synopsis: root=P2 iDb=P3
+ **
+ ** Open a read/write cursor named P1 on the table or index whose root
+-** page is P2.  Or if P5!=0 use the content of register P2 to find the
+-** root page.
++** page is P2 (or whose root page is held in register P2 if the
++** OPFLAG_P2ISREG bit is set in P5 - see below).
+ **
+ ** The P4 value may be either an integer (P4_INT32) or a pointer to
+ ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
+-** structure, then said structure defines the content and collating 
+-** sequence of the index being opened. Otherwise, if P4 is an integer 
+-** value, it is set to the number of columns in the table, or to the
+-** largest index of any column of the table that is actually used.
++** object, then table being opened must be an [index b-tree] where the
++** KeyInfo object defines the content and collating 
++** sequence of that index b-tree. Otherwise, if P4 is an integer 
++** value, then the table being opened must be a [table b-tree] with a
++** number of columns no less than the value of P4.
+ **
+-** This instruction works just like OpenRead except that it opens the cursor
+-** in read/write mode.  For a given table, there can be one or more read-only
+-** cursors or a single read/write cursor but not both.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** <li>  <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
++**       and subsequently delete entries in an index btree.  This is a
++**       hint to the storage engine that the storage engine is allowed to
++**       ignore.  The hint is not used by the official SQLite b*tree storage
++**       engine, but is used by COMDB2.
++** <li>  <b>0x10 OPFLAG_P2ISREG</b>: Use the content of register P2
++**       as the root page, not the value of P2 itself.
++** </ul>
+ **
+-** See also OpenRead.
++** This instruction works like OpenRead except that it opens the cursor
++** in read/write mode.
++**
++** See also: OP_OpenRead, OP_ReopenIdx
+ */
+ case OP_ReopenIdx: {
+   int nField;
+@@ -82332,7 +86476,7 @@
+   assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
+           || p->readOnly==0 );
+ 
+-  if( p->expired ){
++  if( p->expired==1 ){
+     rc = SQLITE_ABORT_ROLLBACK;
+     goto abort_due_to_error;
+   }
+@@ -82359,12 +86503,13 @@
+   if( pOp->p5 & OPFLAG_P2ISREG ){
+     assert( p2>0 );
+     assert( p2<=(p->nMem+1 - p->nCursor) );
++    assert( pOp->opcode==OP_OpenWrite );
+     pIn2 = &aMem[p2];
+     assert( memIsValid(pIn2) );
+     assert( (pIn2->flags & MEM_Int)!=0 );
+     sqlite3VdbeMemIntegerify(pIn2);
+     p2 = (int)pIn2->u.i;
+-    /* The p2 value always comes from a prior OP_CreateTable opcode and
++    /* The p2 value always comes from a prior OP_CreateBtree opcode and
+     ** that opcode will always set the p2 value to 2 or more or else fail.
+     ** If there were a failure, the prepared statement would have halted
+     ** before reaching this instruction. */
+@@ -82374,7 +86519,7 @@
+     pKeyInfo = pOp->p4.pKeyInfo;
+     assert( pKeyInfo->enc==ENC(db) );
+     assert( pKeyInfo->db==db );
+-    nField = pKeyInfo->nField+pKeyInfo->nXField;
++    nField = pKeyInfo->nAllField;
+   }else if( pOp->p4type==P4_INT32 ){
+     nField = pOp->p4.i;
+   }
+@@ -82487,7 +86632,7 @@
+   rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
+                         BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1);
++    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
+   }
+   if( rc==SQLITE_OK ){
+     /* If a transient index is required, create it by calling
+@@ -82585,8 +86730,13 @@
+   pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
+   if( pCx==0 ) goto no_mem;
+   pCx->nullRow = 1;
+-  pCx->uc.pseudoTableReg = pOp->p2;
++  pCx->seekResult = pOp->p2;
+   pCx->isTable = 1;
++  /* Give this pseudo-cursor a fake BtCursor pointer so that pCx
++  ** can be safely passed to sqlite3VdbeCursorMoveto().  This avoids a test
++  ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto()
++  ** which is a performance optimization */
++  pCx->uc.pCursor = sqlite3BtreeFakeValidCursor();
+   assert( pOp->p5==0 );
+   break;
+ }
+@@ -82709,10 +86859,10 @@
+ **
+ ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
+ */
+-case OP_SeekLT:         /* jump, in3 */
+-case OP_SeekLE:         /* jump, in3 */
+-case OP_SeekGE:         /* jump, in3 */
+-case OP_SeekGT: {       /* jump, in3 */
++case OP_SeekLT:         /* jump, in3, group */
++case OP_SeekLE:         /* jump, in3, group */
++case OP_SeekGE:         /* jump, in3, group */
++case OP_SeekGT: {       /* jump, in3, group */
+   int res;           /* Comparison result */
+   int oc;            /* Opcode */
+   VdbeCursor *pC;    /* The cursor to seek */
+@@ -82890,6 +87040,25 @@
+   break;
+ }
+ 
++/* Opcode: SeekHit P1 P2 * * *
++** Synopsis: seekHit=P2
++**
++** Set the seekHit flag on cursor P1 to the value in P2.
++** The seekHit flag is used by the IfNoHope opcode.
++**
++** P1 must be a valid b-tree cursor.  P2 must be a boolean value,
++** either 0 or 1.
++*/
++case OP_SeekHit: {
++  VdbeCursor *pC;
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  assert( pC!=0 );
++  assert( pOp->p2==0 || pOp->p2==1 );
++  pC->seekHit = pOp->p2 & 1;
++  break;
++}
++
+ /* Opcode: Found P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -82924,8 +87093,35 @@
+ ** advanced in either direction.  In other words, the Next and Prev
+ ** opcodes do not work after this operation.
+ **
+-** See also: Found, NotExists, NoConflict
++** See also: Found, NotExists, NoConflict, IfNoHope
+ */
++/* Opcode: IfNoHope P1 P2 P3 P4 *
++** Synopsis: key=r[P3@P4]
++**
++** Register P3 is the first of P4 registers that form an unpacked
++** record.
++**
++** Cursor P1 is on an index btree.  If the seekHit flag is set on P1, then
++** this opcode is a no-op.  But if the seekHit flag of P1 is clear, then
++** check to see if there is any entry in P1 that matches the
++** prefix identified by P3 and P4.  If no entry matches the prefix,
++** jump to P2.  Otherwise fall through.
++**
++** This opcode behaves like OP_NotFound if the seekHit
++** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
++**
++** This opcode is used in IN clause processing for a multi-column key.
++** If an IN clause is attached to an element of the key other than the
++** left-most element, and if there are no matches on the most recent
++** seek over the whole key, then it might be that one of the key element
++** to the left is prohibiting a match, and hence there is "no hope" of
++** any match regardless of how many IN clause elements are checked.
++** In such a case, we abandon the IN clause search early, using this
++** opcode.  The opcode name comes from the fact that the
++** jump is taken if there is "no hope" of achieving a match.
++**
++** See also: NotFound, SeekHit
++*/
+ /* Opcode: NoConflict P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -82949,6 +87145,14 @@
+ **
+ ** See also: NotFound, Found, NotExists
+ */
++case OP_IfNoHope: {     /* jump, in3 */
++  VdbeCursor *pC;
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  assert( pC!=0 );
++  if( pC->seekHit ) break;
++  /* Fall through into OP_NotFound */
++}
+ case OP_NoConflict:     /* jump, in3 */
+ case OP_NotFound:       /* jump, in3 */
+ case OP_Found: {        /* jump, in3 */
+@@ -83086,18 +87290,26 @@
+ 
+   pIn3 = &aMem[pOp->p3];
+   if( (pIn3->flags & MEM_Int)==0 ){
++    /* Make sure pIn3->u.i contains a valid integer representation of
++    ** the key value, but do not change the datatype of the register, as
++    ** other parts of the perpared statement might be depending on the
++    ** current datatype. */
++    u16 origFlags = pIn3->flags;
++    int isNotInt;
+     applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
+-    if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
++    isNotInt = (pIn3->flags & MEM_Int)==0;
++    pIn3->flags = origFlags;
++    if( isNotInt ) goto jump_to_p2;
+   }
+   /* Fall through into OP_NotExists */
+ case OP_NotExists:          /* jump, in3 */
+   pIn3 = &aMem[pOp->p3];
+-  assert( pIn3->flags & MEM_Int );
++  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+ #ifdef SQLITE_DEBUG
+-  pC->seekOp = 0;
++  pC->seekOp = OP_SeekRowid;
+ #endif
+   assert( pC->isTable );
+   assert( pC->eCurType==CURTYPE_BTREE );
+@@ -83172,6 +87384,7 @@
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
++  assert( pC->isTable );
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pC->uc.pCursor!=0 );
+   {
+@@ -83328,10 +87541,8 @@
+   int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
+   const char *zDb;  /* database name - used by the update hook */
+   Table *pTab;      /* Table structure - used by update and pre-update hooks */
+-  int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
+   BtreePayload x;   /* Payload to be inserted */
+ 
+-  op = 0;
+   pData = &aMem[pOp->p2];
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   assert( memIsValid(pData) );
+@@ -83342,6 +87553,7 @@
+   assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
+   assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
+   REGISTER_TRACE(pOp->p2, pData);
++  sqlite3VdbeIncrWriteCounter(p, pC);
+ 
+   if( pOp->opcode==OP_Insert ){
+     pKey = &aMem[pOp->p3];
+@@ -83359,19 +87571,21 @@
+     zDb = db->aDb[pC->iDb].zDbSName;
+     pTab = pOp->p4.pTab;
+     assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
+-    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+   }else{
+-    pTab = 0; /* Not needed.  Silence a compiler warning. */
++    pTab = 0;
+     zDb = 0;  /* Not needed.  Silence a compiler warning. */
+   }
+ 
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+   /* Invoke the pre-update hook, if any */
+-  if( db->xPreUpdateCallback 
+-   && pOp->p4type==P4_TABLE
+-   && !(pOp->p5 & OPFLAG_ISUPDATE)
+-  ){
+-    sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
++  if( pTab ){
++    if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
++      sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
++    }
++    if( db->xUpdateCallback==0 || pTab->aCol==0 ){
++      /* Prevent post-update hook from running in cases when it should not */
++      pTab = 0;
++    }
+   }
+   if( pOp->p5 & OPFLAG_ISNOOP ) break;
+ #endif
+@@ -83378,14 +87592,9 @@
+ 
+   if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+   if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+-  if( pData->flags & MEM_Null ){
+-    x.pData = 0;
+-    x.nData = 0;
+-  }else{
+-    assert( pData->flags & (MEM_Blob|MEM_Str) );
+-    x.pData = pData->z;
+-    x.nData = pData->n;
+-  }
++  assert( pData->flags & (MEM_Blob|MEM_Str) );
++  x.pData = pData->z;
++  x.nData = pData->n;
+   seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
+   if( pData->flags & MEM_Zero ){
+     x.nZero = pData->u.nZero;
+@@ -83401,8 +87610,12 @@
+ 
+   /* Invoke the update-hook if required. */
+   if( rc ) goto abort_due_to_error;
+-  if( db->xUpdateCallback && op ){
+-    db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
++  if( pTab ){
++    assert( db->xUpdateCallback!=0 );
++    assert( pTab->aCol!=0 );
++    db->xUpdateCallback(db->pUpdateArg,
++           (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
++           zDb, pTab->zName, x.nKey);
+   }
+   break;
+ }
+@@ -83455,6 +87668,7 @@
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pC->uc.pCursor!=0 );
+   assert( pC->deferredMoveto==0 );
++  sqlite3VdbeIncrWriteCounter(p, pC);
+ 
+ #ifdef SQLITE_DEBUG
+   if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
+@@ -83623,10 +87837,10 @@
+ ** If the P1 cursor must be pointing to a valid row (not a NULL row)
+ ** of a real table, not a pseudo-table.
+ **
+-** If P3!=0 then this opcode is allowed to make an ephermeral pointer
++** If P3!=0 then this opcode is allowed to make an ephemeral pointer
+ ** into the database page.  That means that the content of the output
+ ** register will be invalidated as soon as the cursor moves - including
+-** moves caused by other cursors that "save" the the current cursors
++** moves caused by other cursors that "save" the current cursors
+ ** position in order that they can write to the same table.  If P3==0
+ ** then a copy of the data is made into memory.  P3!=0 is faster, but
+ ** P3==0 is safer.
+@@ -83749,11 +87963,24 @@
+     assert( pC->uc.pCursor!=0 );
+     sqlite3BtreeClearCursor(pC->uc.pCursor);
+   }
++#ifdef SQLITE_DEBUG
++  if( pC->seekOp==0 ) pC->seekOp = OP_NullRow;
++#endif
+   break;
+ }
+ 
+-/* Opcode: Last P1 P2 P3 * *
++/* Opcode: SeekEnd P1 * * * *
+ **
++** Position cursor P1 at the end of the btree for the purpose of
++** appending a new entry onto the btree.
++**
++** It is assumed that the cursor is used only for appending and so
++** if the cursor is valid, then the cursor must already be pointing
++** at the end of the btree and so no changes are made to
++** the cursor.
++*/
++/* Opcode: Last P1 P2 * * *
++**
+ ** The next use of the Rowid or Column or Prev instruction for P1 
+ ** will refer to the last entry in the database table or index.
+ ** If the table or index is empty and P2>0, then jump immediately to P2.
+@@ -83763,14 +87990,8 @@
+ ** This opcode leaves the cursor configured to move in reverse order,
+ ** from the end toward the beginning.  In other words, the cursor is
+ ** configured to use Prev, not Next.
+-**
+-** If P3 is -1, then the cursor is positioned at the end of the btree
+-** for the purpose of appending a new entry onto the btree.  In that
+-** case P2 must be 0.  It is assumed that the cursor is used only for
+-** appending and so if the cursor is valid, then the cursor must already
+-** be pointing at the end of the btree and so no changes are made to
+-** the cursor.
+ */
++case OP_SeekEnd:
+ case OP_Last: {        /* jump */
+   VdbeCursor *pC;
+   BtCursor *pCrsr;
+@@ -83783,23 +88004,25 @@
+   pCrsr = pC->uc.pCursor;
+   res = 0;
+   assert( pCrsr!=0 );
+-  pC->seekResult = pOp->p3;
+ #ifdef SQLITE_DEBUG
+-  pC->seekOp = OP_Last;
++  pC->seekOp = pOp->opcode;
+ #endif
+-  if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){
+-    rc = sqlite3BtreeLast(pCrsr, &res);
+-    pC->nullRow = (u8)res;
+-    pC->deferredMoveto = 0;
+-    pC->cacheStatus = CACHE_STALE;
+-    if( rc ) goto abort_due_to_error;
+-    if( pOp->p2>0 ){
+-      VdbeBranchTaken(res!=0,2);
+-      if( res ) goto jump_to_p2;
++  if( pOp->opcode==OP_SeekEnd ){
++    assert( pOp->p2==0 );
++    pC->seekResult = -1;
++    if( sqlite3BtreeCursorIsValidNN(pCrsr) ){
++      break;
+     }
+-  }else{
+-    assert( pOp->p2==0 );
+   }
++  rc = sqlite3BtreeLast(pCrsr, &res);
++  pC->nullRow = (u8)res;
++  pC->deferredMoveto = 0;
++  pC->cacheStatus = CACHE_STALE;
++  if( rc ) goto abort_due_to_error;
++  if( pOp->p2>0 ){
++    VdbeBranchTaken(res!=0,2);
++    if( res ) goto jump_to_p2;
++  }
+   break;
+ }
+ 
+@@ -83861,7 +88084,7 @@
+   p->aCounter[SQLITE_STMTSTATUS_SORT]++;
+   /* Fall through into OP_Rewind */
+ }
+-/* Opcode: Rewind P1 P2 * * *
++/* Opcode: Rewind P1 P2 * * P5
+ **
+ ** The next use of the Rowid or Column or Next instruction for P1 
+ ** will refer to the first entry in the database table or index.
+@@ -83869,6 +88092,10 @@
+ ** If the table or index is not empty, fall through to the following 
+ ** instruction.
+ **
++** If P5 is non-zero and the table is not empty, then the "skip-next"
++** flag is set on the cursor so that the next OP_Next instruction 
++** executed on it is a no-op.
++**
+ ** This opcode leaves the cursor configured to move in forward order,
+ ** from the beginning toward the end.  In other words, the cursor is
+ ** configured to use Next, not Prev.
+@@ -83893,6 +88120,9 @@
+     pCrsr = pC->uc.pCursor;
+     assert( pCrsr );
+     rc = sqlite3BtreeFirst(pCrsr, &res);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
++#endif
+     pC->deferredMoveto = 0;
+     pC->cacheStatus = CACHE_STALE;
+   }
+@@ -83929,13 +88159,8 @@
+ ** If P5 is positive and the jump is taken, then event counter
+ ** number P5-1 in the prepared statement is incremented.
+ **
+-** See also: Prev, NextIfOpen
++** See also: Prev
+ */
+-/* Opcode: NextIfOpen P1 P2 P3 P4 P5
+-**
+-** This opcode works just like Next except that if cursor P1 is not
+-** open it behaves a no-op.
+-*/
+ /* Opcode: Prev P1 P2 P3 P4 P5
+ **
+ ** Back up cursor P1 so that it points to the previous key/data pair in its
+@@ -83962,11 +88187,6 @@
+ ** If P5 is positive and the jump is taken, then event counter
+ ** number P5-1 in the prepared statement is incremented.
+ */
+-/* Opcode: PrevIfOpen P1 P2 P3 P4 P5
+-**
+-** This opcode works just like Prev except that if cursor P1 is not
+-** open it behaves a no-op.
+-*/
+ /* Opcode: SorterNext P1 P2 * * P5
+ **
+ ** This opcode works just like OP_Next except that P1 must be a
+@@ -83981,10 +88201,6 @@
+   assert( isSorter(pC) );
+   rc = sqlite3VdbeSorterNext(db, pC);
+   goto next_tail;
+-case OP_PrevIfOpen:    /* jump */
+-case OP_NextIfOpen:    /* jump */
+-  if( p->apCsr[pOp->p1]==0 ) break;
+-  /* Fall through */
+ case OP_Prev:          /* jump */
+ case OP_Next:          /* jump */
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+@@ -83995,17 +88211,17 @@
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
+   assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+-  assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
+-  assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
+ 
+-  /* The Next opcode is only used after SeekGT, SeekGE, and Rewind.
++  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
+   ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
+-  assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen
++  assert( pOp->opcode!=OP_Next
+        || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
+-       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found);
+-  assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen
++       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
++       || pC->seekOp==OP_NullRow);
++  assert( pOp->opcode!=OP_Prev
+        || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
+-       || pC->seekOp==OP_Last );
++       || pC->seekOp==OP_Last 
++       || pC->seekOp==OP_NullRow);
+ 
+   rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
+ next_tail:
+@@ -84067,6 +88283,7 @@
+ 
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
++  sqlite3VdbeIncrWriteCounter(p, pC);
+   assert( pC!=0 );
+   assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
+   pIn2 = &aMem[pOp->p2];
+@@ -84113,6 +88330,7 @@
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+   assert( pC->eCurType==CURTYPE_BTREE );
++  sqlite3VdbeIncrWriteCounter(p, pC);
+   pCrsr = pC->uc.pCursor;
+   assert( pCrsr!=0 );
+   assert( pOp->p5==0 );
+@@ -84286,7 +88504,13 @@
+   }
+   r.aMem = &aMem[pOp->p3];
+ #ifdef SQLITE_DEBUG
+-  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
++  {
++    int i;
++    for(i=0; i<r.nField; i++){
++      assert( memIsValid(&r.aMem[i]) );
++      REGISTER_TRACE(pOp->p3+i, &aMem[pOp->p3+i]);
++    }
++  }
+ #endif
+   res = 0;  /* Not needed.  Only used to silence a warning. */
+   rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
+@@ -84335,6 +88559,7 @@
+   int iMoved;
+   int iDb;
+ 
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   assert( p->readOnly==0 );
+   assert( pOp->p1>1 );
+   pOut = out2Prerelease(p, pOp);
+@@ -84384,6 +88609,7 @@
+ case OP_Clear: {
+   int nChange;
+  
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   nChange = 0;
+   assert( p->readOnly==0 );
+   assert( DbMaskTest(p->btreeMask, pOp->p2) );
+@@ -84427,50 +88653,29 @@
+   break;
+ }
+ 
+-/* Opcode: CreateTable P1 P2 * * *
+-** Synopsis: r[P2]=root iDb=P1
++/* Opcode: CreateBtree P1 P2 P3 * *
++** Synopsis: r[P2]=root iDb=P1 flags=P3
+ **
+-** Allocate a new table in the main database file if P1==0 or in the
+-** auxiliary database file if P1==1 or in an attached database if
+-** P1>1.  Write the root page number of the new table into
+-** register P2
+-**
+-** The difference between a table and an index is this:  A table must
+-** have a 4-byte integer key and can have arbitrary data.  An index
+-** has an arbitrary key but no data.
+-**
+-** See also: CreateIndex
++** Allocate a new b-tree in the main database file if P1==0 or in the
++** TEMP database file if P1==1 or in an attached database if
++** P1>1.  The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
++** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table.
++** The root page number of the new b-tree is stored in register P2.
+ */
+-/* Opcode: CreateIndex P1 P2 * * *
+-** Synopsis: r[P2]=root iDb=P1
+-**
+-** Allocate a new index in the main database file if P1==0 or in the
+-** auxiliary database file if P1==1 or in an attached database if
+-** P1>1.  Write the root page number of the new table into
+-** register P2.
+-**
+-** See documentation on OP_CreateTable for additional information.
+-*/
+-case OP_CreateIndex:            /* out2 */
+-case OP_CreateTable: {          /* out2 */
++case OP_CreateBtree: {          /* out2 */
+   int pgno;
+-  int flags;
+   Db *pDb;
+ 
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   pOut = out2Prerelease(p, pOp);
+   pgno = 0;
++  assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
+   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+   assert( DbMaskTest(p->btreeMask, pOp->p1) );
+   assert( p->readOnly==0 );
+   pDb = &db->aDb[pOp->p1];
+   assert( pDb->pBt!=0 );
+-  if( pOp->opcode==OP_CreateTable ){
+-    /* flags = BTREE_INTKEY; */
+-    flags = BTREE_INTKEY;
+-  }else{
+-    flags = BTREE_BLOBKEY;
+-  }
+-  rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
++  rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3);
+   if( rc ) goto abort_due_to_error;
+   pOut->u.i = pgno;
+   break;
+@@ -84481,6 +88686,7 @@
+ ** Run the SQL statement or statements specified in the P4 string.
+ */
+ case OP_SqlExec: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   db->nSqlExec++;
+   rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
+   db->nSqlExec--;
+@@ -84491,7 +88697,8 @@
+ /* Opcode: ParseSchema P1 * * P4 *
+ **
+ ** Read and parse all entries from the SQLITE_MASTER table of database P1
+-** that match the WHERE clause P4. 
++** that match the WHERE clause P4.  If P4 is a NULL pointer, then the
++** entire schema for P1 is reparsed.
+ **
+ ** This opcode invokes the parser to create a new virtual machine,
+ ** then runs the new virtual machine.  It is thus a re-entrant opcode.
+@@ -84515,11 +88722,22 @@
+   iDb = pOp->p1;
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
+-  /* Used to be a conditional */ {
++
++#ifndef SQLITE_OMIT_ALTERTABLE
++  if( pOp->p4.z==0 ){
++    sqlite3SchemaClear(db->aDb[iDb].pSchema);
++    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
++    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
++    db->mDbFlags |= DBFLAG_SchemaChange;
++    p->expired = 0;
++  }else
++#endif
++  {
+     zMaster = MASTER_NAME;
+     initData.db = db;
+-    initData.iDb = pOp->p1;
++    initData.iDb = iDb;
+     initData.pzErrMsg = &p->zErrMsg;
++    initData.mInitFlags = 0;
+     zSql = sqlite3MPrintf(db,
+        "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
+        db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
+@@ -84570,6 +88788,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropTable: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -84583,6 +88802,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropIndex: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -84596,6 +88816,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropTrigger: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -84632,7 +88853,7 @@
+   nRoot = pOp->p2;
+   aRoot = pOp->p4.ai;
+   assert( nRoot>0 );
+-  assert( aRoot[nRoot]==0 );
++  assert( aRoot[0]==nRoot );
+   assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pnErr = &aMem[pOp->p3];
+   assert( (pnErr->flags & MEM_Int)!=0 );
+@@ -84640,7 +88861,7 @@
+   pIn1 = &aMem[pOp->p1];
+   assert( pOp->p5<db->nDb );
+   assert( DbMaskTest(p->btreeMask, pOp->p5) );
+-  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
++  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
+                                  (int)pnErr->u.i+1, &nErr);
+   sqlite3VdbeMemSetNull(pIn1);
+   if( nErr==0 ){
+@@ -84669,11 +88890,11 @@
+   pIn1 = &aMem[pOp->p1];
+   pIn2 = &aMem[pOp->p2];
+   assert( (pIn2->flags & MEM_Int)!=0 );
+-  if( (pIn1->flags & MEM_RowSet)==0 ){
+-    sqlite3VdbeMemSetRowSet(pIn1);
+-    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
++  if( (pIn1->flags & MEM_Blob)==0 ){
++    if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
+   }
+-  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
++  assert( sqlite3VdbeMemIsRowSet(pIn1) );
++  sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i);
+   break;
+ }
+ 
+@@ -84689,8 +88910,9 @@
+   i64 val;
+ 
+   pIn1 = &aMem[pOp->p1];
+-  if( (pIn1->flags & MEM_RowSet)==0 
+-   || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
++  assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) );
++  if( (pIn1->flags & MEM_Blob)==0 
++   || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0
+   ){
+     /* The boolean index is empty */
+     sqlite3VdbeMemSetNull(pIn1);
+@@ -84739,20 +88961,19 @@
+   /* If there is anything other than a rowset object in memory cell P1,
+   ** delete it now and initialize P1 with an empty rowset
+   */
+-  if( (pIn1->flags & MEM_RowSet)==0 ){
+-    sqlite3VdbeMemSetRowSet(pIn1);
+-    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
++  if( (pIn1->flags & MEM_Blob)==0 ){
++    if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
+   }
+-
++  assert( sqlite3VdbeMemIsRowSet(pIn1) );
+   assert( pOp->p4type==P4_INT32 );
+   assert( iSet==-1 || iSet>=0 );
+   if( iSet ){
+-    exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
++    exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i);
+     VdbeBranchTaken(exists!=0,2);
+     if( exists ) goto jump_to_p2;
+   }
+   if( iSet>=0 ){
+-    sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
++    sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i);
+   }
+   break;
+ }
+@@ -84816,7 +89037,7 @@
+   ** of the current program, and the memory required at runtime to execute
+   ** the trigger program. If this trigger has been fired before, then pRt 
+   ** is already allocated. Otherwise, it must be initialized.  */
+-  if( (pRt->flags&MEM_Frame)==0 ){
++  if( (pRt->flags&MEM_Blob)==0 ){
+     /* SubProgram.nMem is set to the number of memory cells used by the 
+     ** program stored in SubProgram.aOp. As well as these, one memory
+     ** cell is required for each cursor used by the program. Set local
+@@ -84834,8 +89055,10 @@
+       goto no_mem;
+     }
+     sqlite3VdbeMemRelease(pRt);
+-    pRt->flags = MEM_Frame;
+-    pRt->u.pFrame = pFrame;
++    pRt->flags = MEM_Blob|MEM_Dyn;
++    pRt->z = (char*)pFrame;
++    pRt->n = nByte;
++    pRt->xDel = sqlite3VdbeFrameMemDel;
+ 
+     pFrame->v = p;
+     pFrame->nChildMem = nMem;
+@@ -84851,6 +89074,9 @@
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+     pFrame->anExec = p->anExec;
+ #endif
++#ifdef SQLITE_DEBUG
++    pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
++#endif
+ 
+     pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
+     for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
+@@ -84858,7 +89084,8 @@
+       pMem->db = db;
+     }
+   }else{
+-    pFrame = pRt->u.pFrame;
++    pFrame = (VdbeFrame*)pRt->z;
++    assert( pRt->xDel==sqlite3VdbeFrameMemDel );
+     assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem 
+         || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
+     assert( pProgram->nCsr==pFrame->nChildCsr );
+@@ -85087,24 +89314,35 @@
+ }
+ 
+ 
+-/* Opcode: AggStep0 * P2 P3 P4 P5
++/* Opcode: AggStep * P2 P3 P4 P5
+ ** Synopsis: accum=r[P3] step(r[P2@P5])
+ **
+-** Execute the step function for an aggregate.  The
+-** function has P5 arguments.   P4 is a pointer to the FuncDef
+-** structure that specifies the function.  Register P3 is the
++** Execute the xStep function for an aggregate.
++** The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
+ ** accumulator.
+ **
+ ** The P5 arguments are taken from register P2 and its
+ ** successors.
+ */
+-/* Opcode: AggStep * P2 P3 P4 P5
++/* Opcode: AggInverse * P2 P3 P4 P5
++** Synopsis: accum=r[P3] inverse(r[P2@P5])
++**
++** Execute the xInverse function for an aggregate.
++** The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
++** accumulator.
++**
++** The P5 arguments are taken from register P2 and its
++** successors.
++*/
++/* Opcode: AggStep1 P1 P2 P3 P4 P5
+ ** Synopsis: accum=r[P3] step(r[P2@P5])
+ **
+-** Execute the step function for an aggregate.  The
+-** function has P5 arguments.   P4 is a pointer to an sqlite3_context
+-** object that is used to run the function.  Register P3 is
+-** as the accumulator.
++** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
++** aggregate.  The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
++** accumulator.
+ **
+ ** The P5 arguments are taken from register P2 and its
+ ** successors.
+@@ -85115,7 +89353,8 @@
+ ** sqlite3_context only happens once, instead of on each call to the
+ ** step function.
+ */
+-case OP_AggStep0: {
++case OP_AggInverse:
++case OP_AggStep: {
+   int n;
+   sqlite3_context *pCtx;
+ 
+@@ -85124,28 +89363,47 @@
+   assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+   assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
+   assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+-  pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
++  pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
++               (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
+   if( pCtx==0 ) goto no_mem;
+   pCtx->pMem = 0;
++  pCtx->pOut = (Mem*)&(pCtx->argv[n]);
++  sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
+   pCtx->pFunc = pOp->p4.pFunc;
+   pCtx->iOp = (int)(pOp - aOp);
+   pCtx->pVdbe = p;
++  pCtx->skipFlag = 0;
++  pCtx->isError = 0;
+   pCtx->argc = n;
+   pOp->p4type = P4_FUNCCTX;
+   pOp->p4.pCtx = pCtx;
+-  pOp->opcode = OP_AggStep;
++
++  /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
++  assert( pOp->p1==(pOp->opcode==OP_AggInverse) );
++
++  pOp->opcode = OP_AggStep1;
+   /* Fall through into OP_AggStep */
+ }
+-case OP_AggStep: {
++case OP_AggStep1: {
+   int i;
+   sqlite3_context *pCtx;
+   Mem *pMem;
+-  Mem t;
+ 
+   assert( pOp->p4type==P4_FUNCCTX );
+   pCtx = pOp->p4.pCtx;
+   pMem = &aMem[pOp->p3];
+ 
++#ifdef SQLITE_DEBUG
++  if( pOp->p1 ){
++    /* This is an OP_AggInverse call.  Verify that xStep has always
++    ** been called at least once prior to any xInverse call. */
++    assert( pMem->uTemp==0x1122e0e3 );
++  }else{
++    /* This is an OP_AggStep call.  Mark it as such. */
++    pMem->uTemp = 0x1122e0e3;
++  }
++#endif
++
+   /* If this function is inside of a trigger, the register array in aMem[]
+   ** might change from one evaluation to the next.  The next block of code
+   ** checks to see if the register array has changed, and if so it
+@@ -85163,26 +89421,34 @@
+ #endif
+ 
+   pMem->n++;
+-  sqlite3VdbeMemInit(&t, db, MEM_Null);
+-  pCtx->pOut = &t;
+-  pCtx->fErrorOrAux = 0;
+-  pCtx->skipFlag = 0;
++  assert( pCtx->pOut->flags==MEM_Null );
++  assert( pCtx->isError==0 );
++  assert( pCtx->skipFlag==0 );
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pOp->p1 ){
++    (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
++  }else
++#endif
+   (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
+-  if( pCtx->fErrorOrAux ){
+-    if( pCtx->isError ){
+-      sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
++
++  if( pCtx->isError ){
++    if( pCtx->isError>0 ){
++      sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+       rc = pCtx->isError;
+     }
+-    sqlite3VdbeMemRelease(&t);
++    if( pCtx->skipFlag ){
++      assert( pOp[-1].opcode==OP_CollSeq );
++      i = pOp[-1].p1;
++      if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
++      pCtx->skipFlag = 0;
++    }
++    sqlite3VdbeMemRelease(pCtx->pOut);
++    pCtx->pOut->flags = MEM_Null;
++    pCtx->isError = 0;
+     if( rc ) goto abort_due_to_error;
+-  }else{
+-    assert( t.flags==MEM_Null );
+   }
+-  if( pCtx->skipFlag ){
+-    assert( pOp[-1].opcode==OP_CollSeq );
+-    i = pOp[-1].p1;
+-    if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
+-  }
++  assert( pCtx->pOut->flags==MEM_Null );
++  assert( pCtx->skipFlag==0 );
+   break;
+ }
+ 
+@@ -85189,22 +89455,46 @@
+ /* Opcode: AggFinal P1 P2 * P4 *
+ ** Synopsis: accum=r[P1] N=P2
+ **
+-** Execute the finalizer function for an aggregate.  P1 is
+-** the memory location that is the accumulator for the aggregate.
++** P1 is the memory location that is the accumulator for an aggregate
++** or window function.  Execute the finalizer function 
++** for an aggregate and store the result in P1.
+ **
+ ** P2 is the number of arguments that the step function takes and
+ ** P4 is a pointer to the FuncDef for this function.  The P2
+ ** argument is not used by this opcode.  It is only there to disambiguate
+ ** functions that can take varying numbers of arguments.  The
+-** P4 argument is only needed for the degenerate case where
++** P4 argument is only needed for the case where
+ ** the step function was not previously called.
+ */
++/* Opcode: AggValue * P2 P3 P4 *
++** Synopsis: r[P3]=value N=P2
++**
++** Invoke the xValue() function and store the result in register P3.
++**
++** P2 is the number of arguments that the step function takes and
++** P4 is a pointer to the FuncDef for this function.  The P2
++** argument is not used by this opcode.  It is only there to disambiguate
++** functions that can take varying numbers of arguments.  The
++** P4 argument is only needed for the case where
++** the step function was not previously called.
++*/
++case OP_AggValue:
+ case OP_AggFinal: {
+   Mem *pMem;
+   assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
++  assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
+   pMem = &aMem[pOp->p1];
+   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+-  rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pOp->p3 ){
++    rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
++    pMem = &aMem[pOp->p3];
++  }else
++#endif
++  {
++    rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
++  }
++  
+   if( rc ){
+     sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
+     goto abort_due_to_error;
+@@ -85399,7 +89689,7 @@
+ }
+ #endif
+ 
+-/* Opcode: Expire P1 * * * *
++/* Opcode: Expire P1 P2 * * *
+ **
+ ** Cause precompiled statements to expire.  When an expired statement
+ ** is executed using sqlite3_step() it will either automatically
+@@ -85408,12 +89698,19 @@
+ ** 
+ ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
+ ** then only the currently executing statement is expired.
++**
++** If P2 is 0, then SQL statements are expired immediately.  If P2 is 1,
++** then running SQL statements are allowed to continue to run to completion.
++** The P2==1 case occurs when a CREATE INDEX or similar schema change happens
++** that might help the statement run faster but which does not affect the
++** correctness of operation.
+ */
+ case OP_Expire: {
++  assert( pOp->p2==0 || pOp->p2==1 );
+   if( !pOp->p1 ){
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, pOp->p2);
+   }else{
+-    p->expired = 1;
++    p->expired = pOp->p2+1;
+   }
+   break;
+ }
+@@ -85627,12 +89924,19 @@
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-/* Opcode: VColumn P1 P2 P3 * *
++/* Opcode: VColumn P1 P2 P3 * P5
+ ** Synopsis: r[P3]=vcolumn(P2)
+ **
+-** Store the value of the P2-th column of
+-** the row of the virtual-table that the 
+-** P1 cursor is pointing to into register P3.
++** Store in register P3 the value of the P2-th column of
++** the current row of the virtual-table of cursor P1.
++**
++** If the VColumn opcode is being used to fetch the value of
++** an unchanging column during an UPDATE operation, then the P5
++** value is OPFLAG_NOCHNG.  This will cause the sqlite3_vtab_nochange()
++** function to return true inside the xColumn method of the virtual
++** table implementation.  The P5 column might also contain other
++** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
++** unused by OP_VColumn.
+ */
+ case OP_VColumn: {
+   sqlite3_vtab *pVtab;
+@@ -85654,10 +89958,18 @@
+   assert( pModule->xColumn );
+   memset(&sContext, 0, sizeof(sContext));
+   sContext.pOut = pDest;
+-  MemSetTypeFlag(pDest, MEM_Null);
++  testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
++  if( pOp->p5 & OPFLAG_NOCHNG ){
++    sqlite3VdbeMemSetNull(pDest);
++    pDest->flags = MEM_Null|MEM_Zero;
++    pDest->u.nZero = 0;
++  }else{
++    MemSetTypeFlag(pDest, MEM_Null);
++  }
+   rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
+   sqlite3VtabImportErrmsg(p, pVtab);
+-  if( sContext.isError ){
++  if( sContext.isError>0 ){
++    sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest));
+     rc = sContext.isError;
+   }
+   sqlite3VdbeChangeEncoding(pDest, encoding);
+@@ -85724,7 +90036,10 @@
+ case OP_VRename: {
+   sqlite3_vtab *pVtab;
+   Mem *pName;
+-
++  int isLegacy;
++  
++  isLegacy = (db->flags & SQLITE_LegacyAlter);
++  db->flags |= SQLITE_LegacyAlter;
+   pVtab = pOp->p4.pVtab->pVtab;
+   pName = &aMem[pOp->p1];
+   assert( pVtab->pModule->xRename );
+@@ -85738,6 +90053,7 @@
+   rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
+   if( rc ) goto abort_due_to_error;
+   rc = pVtab->pModule->xRename(pVtab, pName->z);
++  if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter;
+   sqlite3VtabImportErrmsg(p, pVtab);
+   p->expired = 0;
+   if( rc ) goto abort_due_to_error;
+@@ -85786,6 +90102,8 @@
+        || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
+   );
+   assert( p->readOnly==0 );
++  if( db->mallocFailed ) goto no_mem;
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   pVtab = pOp->p4.pVtab->pVtab;
+   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+     rc = SQLITE_LOCKED;
+@@ -85906,8 +90224,8 @@
+ **
+ ** See also: Function0, AggStep, AggFinal
+ */
+-case OP_PureFunc0:
+-case OP_Function0: {
++case OP_PureFunc0:              /* group */
++case OP_Function0: {            /* group */
+   int n;
+   sqlite3_context *pCtx;
+ 
+@@ -85922,6 +90240,7 @@
+   pCtx->pFunc = pOp->p4.pFunc;
+   pCtx->iOp = (int)(pOp - aOp);
+   pCtx->pVdbe = p;
++  pCtx->isError = 0;
+   pCtx->argc = n;
+   pOp->p4type = P4_FUNCCTX;
+   pOp->p4.pCtx = pCtx;
+@@ -85930,8 +90249,8 @@
+   pOp->opcode += 2;
+   /* Fall through into OP_Function */
+ }
+-case OP_PureFunc:
+-case OP_Function: {
++case OP_PureFunc:              /* group */
++case OP_Function: {            /* group */
+   int i;
+   sqlite3_context *pCtx;
+ 
+@@ -85956,16 +90275,17 @@
+   }
+ #endif
+   MemSetTypeFlag(pOut, MEM_Null);
+-  pCtx->fErrorOrAux = 0;
++  assert( pCtx->isError==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 ){
++  if( pCtx->isError ){
++    if( pCtx->isError>0 ){
+       sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
+       rc = pCtx->isError;
+     }
+     sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
++    pCtx->isError = 0;
+     if( rc ) goto abort_due_to_error;
+   }
+ 
+@@ -85980,8 +90300,14 @@
+   break;
+ }
+ 
+-
+-/* Opcode: Init P1 P2 * P4 *
++/* Opcode: Trace P1 P2 * P4 *
++**
++** Write P4 on the statement trace output if statement tracing is
++** enabled.
++**
++** Operand P1 must be 0x7fffffff and P2 must positive.
++*/
++/* Opcode: Init P1 P2 P3 P4 *
+ ** Synopsis: Start at P2
+ **
+ ** Programs contain a single instance of this opcode as the very first
+@@ -85995,10 +90321,16 @@
+ **
+ ** Increment the value of P1 so that OP_Once opcodes will jump the
+ ** first time they are evaluated for this run.
++**
++** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
++** error is encountered.
+ */
++case OP_Trace:
+ case OP_Init: {          /* jump */
++  int i;
++#ifndef SQLITE_OMIT_TRACE
+   char *zTrace;
+-  int i;
++#endif
+ 
+   /* If the P4 argument is not NULL, then it must be an SQL comment string.
+   ** The "--" string is broken up to prevent false-positives with srcck1.c.
+@@ -86010,8 +90342,10 @@
+   ** sqlite3_expanded_sql(P) otherwise.
+   */
+   assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
+-  assert( pOp==p->aOp );  /* Always instruction 0 */
+ 
++  /* OP_Init is always instruction 0 */
++  assert( pOp==p->aOp || pOp->opcode==OP_Trace );
++
+ #ifndef SQLITE_OMIT_TRACE
+   if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
+    && !p->doingRerun
+@@ -86053,6 +90387,7 @@
+ #endif /* SQLITE_OMIT_TRACE */
+   assert( pOp->p2>0 );
+   if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
++    if( pOp->opcode==OP_Trace ) break;
+     for(i=1; i<p->nOp; i++){
+       if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
+     }
+@@ -86086,6 +90421,22 @@
+ }
+ #endif /* SQLITE_ENABLE_CURSOR_HINTS */
+ 
++#ifdef SQLITE_DEBUG
++/* Opcode:  Abortable   * * * * *
++**
++** Verify that an Abort can happen.  Assert if an Abort at this point
++** might cause database corruption.  This opcode only appears in debugging
++** builds.
++**
++** An Abort is safe if either there have been no writes, or if there is
++** an active statement journal.
++*/
++case OP_Abortable: {
++  sqlite3VdbeAssertAbortable(p);
++  break;
++}
++#endif
++
+ /* Opcode: Noop * * * * *
+ **
+ ** Do nothing.  This instruction is often useful as a jump
+@@ -86097,8 +90448,9 @@
+ ** This opcode records information from the optimizer.  It is the
+ ** the same as a no-op.  This opcodesnever appears in a real VM program.
+ */
+-default: {          /* This is really OP_Noop and OP_Explain */
++default: {          /* This is really OP_Noop, OP_Explain */
+   assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
++
+   break;
+ }
+ 
+@@ -86112,7 +90464,7 @@
+ 
+ #ifdef VDBE_PROFILE
+     {
+-      u64 endTime = sqlite3Hwtime();
++      u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
+       if( endTime>start ) pOrigOp->cycles += endTime - start;
+       pOrigOp->cnt++;
+     }
+@@ -86269,11 +90621,12 @@
+   v->aMem[1].u.i = iRow;
+ 
+   /* If the statement has been run before (and is paused at the OP_ResultRow)
+-  ** then back it up to the point where it does the OP_SeekRowid.  This could
++  ** then back it up to the point where it does the OP_NotExists.  This could
+   ** have been down with an extra OP_Goto, but simply setting the program
+   ** counter is faster. */
+-  if( v->pc>3 ){
+-    v->pc = 3;
++  if( v->pc>4 ){
++    v->pc = 4;
++    assert( v->aOp[v->pc].opcode==OP_NotExists );
+     rc = sqlite3VdbeExec(v);
+   }else{
+     rc = sqlite3_step(p->pStmt);
+@@ -86335,8 +90688,8 @@
+   int rc = SQLITE_OK;
+   char *zErr = 0;
+   Table *pTab;
+-  Parse *pParse = 0;
+   Incrblob *pBlob = 0;
++  Parse sParse;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( ppBlob==0 ){
+@@ -86354,37 +90707,34 @@
+   sqlite3_mutex_enter(db->mutex);
+ 
+   pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
+-  if( !pBlob ) goto blob_open_out;
+-  pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
+-  if( !pParse ) goto blob_open_out;
+-
+   do {
+-    memset(pParse, 0, sizeof(Parse));
+-    pParse->db = db;
++    memset(&sParse, 0, sizeof(Parse));
++    if( !pBlob ) goto blob_open_out;
++    sParse.db = db;
+     sqlite3DbFree(db, zErr);
+     zErr = 0;
+ 
+     sqlite3BtreeEnterAll(db);
+-    pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
++    pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
+     if( pTab && IsVirtual(pTab) ){
+       pTab = 0;
+-      sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
++      sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
+     }
+     if( pTab && !HasRowid(pTab) ){
+       pTab = 0;
+-      sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable);
++      sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
+     }
+ #ifndef SQLITE_OMIT_VIEW
+     if( pTab && pTab->pSelect ){
+       pTab = 0;
+-      sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
++      sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
+     }
+ #endif
+     if( !pTab ){
+-      if( pParse->zErrMsg ){
++      if( sParse.zErrMsg ){
+         sqlite3DbFree(db, zErr);
+-        zErr = pParse->zErrMsg;
+-        pParse->zErrMsg = 0;
++        zErr = sParse.zErrMsg;
++        sParse.zErrMsg = 0;
+       }
+       rc = SQLITE_ERROR;
+       sqlite3BtreeLeaveAll(db);
+@@ -86448,7 +90798,7 @@
+       }
+     }
+ 
+-    pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
++    pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse);
+     assert( pBlob->pStmt || db->mallocFailed );
+     if( pBlob->pStmt ){
+       
+@@ -86484,7 +90834,8 @@
+       sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, 
+                            pTab->pSchema->schema_cookie,
+                            pTab->pSchema->iGeneration);
+-      sqlite3VdbeChangeP5(v, 1);     
++      sqlite3VdbeChangeP5(v, 1);
++      assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed );
+       aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
+ 
+       /* Make sure a mutex is held on the table to be accessed */
+@@ -86499,7 +90850,7 @@
+         aOp[0].p1 = iDb;
+         aOp[0].p2 = pTab->tnum;
+         aOp[0].p3 = wrFlag;
+-        sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
++        sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
+       }
+       if( db->mallocFailed==0 ){
+ #endif
+@@ -86521,10 +90872,10 @@
+         aOp[1].p4.i = pTab->nCol+1;
+         aOp[3].p2 = pTab->nCol;
+ 
+-        pParse->nVar = 0;
+-        pParse->nMem = 1;
+-        pParse->nTab = 1;
+-        sqlite3VdbeMakeReady(v, pParse);
++        sParse.nVar = 0;
++        sParse.nMem = 1;
++        sParse.nTab = 1;
++        sqlite3VdbeMakeReady(v, &sParse);
+       }
+     }
+    
+@@ -86546,8 +90897,7 @@
+   }
+   sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
+   sqlite3DbFree(db, zErr);
+-  sqlite3ParserReset(pParse);
+-  sqlite3StackFree(db, pParse);
++  sqlite3ParserReset(&sParse);
+   rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+   return rc;
+@@ -87541,7 +91891,7 @@
+   }
+ 
+   if( res==0 ){
+-    if( pTask->pSorter->pKeyInfo->nField>1 ){
++    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
+       res = vdbeSorterCompareTail(
+           pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+       );
+@@ -87610,7 +91960,7 @@
+   }
+ 
+   if( res==0 ){
+-    if( pTask->pSorter->pKeyInfo->nField>1 ){
++    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
+       res = vdbeSorterCompareTail(
+           pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+       );
+@@ -87625,7 +91975,7 @@
+ /*
+ ** Initialize the temporary index cursor just opened as a sorter cursor.
+ **
+-** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
++** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
+ ** to determine the number of fields that should be compared from the
+ ** records being sorted. However, if the value passed as argument nField
+ ** is non-zero and the sorter is able to guarantee a stable sort, nField
+@@ -87678,7 +92028,7 @@
+ 
+   assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
+   assert( pCsr->eCurType==CURTYPE_SORTER );
+-  szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
++  szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
+   sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
+ 
+   pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
+@@ -87690,8 +92040,7 @@
+     memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
+     pKeyInfo->db = 0;
+     if( nField && nWorker==0 ){
+-      pKeyInfo->nXField += (pKeyInfo->nField - nField);
+-      pKeyInfo->nField = nField;
++      pKeyInfo->nKeyField = nField;
+     }
+     pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+     pSorter->nTask = nWorker + 1;
+@@ -87719,11 +92068,9 @@
+       mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
+       pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
+ 
+-      /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
+-      ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
+-      ** large heap allocations.
+-      */
+-      if( sqlite3GlobalConfig.pScratch==0 ){
++      /* Avoid large memory allocations if the application has requested
++      ** SQLITE_CONFIG_SMALL_MALLOC. */
++      if( sqlite3GlobalConfig.bSmallMalloc==0 ){
+         assert( pSorter->iMemory==0 );
+         pSorter->nMemory = pgsz;
+         pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
+@@ -87731,7 +92078,7 @@
+       }
+     }
+ 
+-    if( (pKeyInfo->nField+pKeyInfo->nXField)<13 
++    if( pKeyInfo->nAllField<13 
+      && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
+     ){
+       pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
+@@ -88046,7 +92393,7 @@
+   if( pTask->pUnpacked==0 ){
+     pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
+     if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
+-    pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
++    pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField;
+     pTask->pUnpacked->errCode = 0;
+   }
+   return SQLITE_OK;
+@@ -88828,8 +93175,12 @@
+ ){
+   int rc = SQLITE_OK;             /* Return code */
+   int i;                          /* For looping over PmaReader objects */
+-  int nTree = pMerger->nTree;
++  int nTree;                      /* Number of subtrees to merge */
+ 
++  /* Failure to allocate the merge would have been detected prior to
++  ** invoking this routine */
++  assert( pMerger!=0 );
++
+   /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+   assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+ 
+@@ -88837,6 +93188,7 @@
+   assert( pMerger->pTask==0 );
+   pMerger->pTask = pTask;
+ 
++  nTree = pMerger->nTree;
+   for(i=0; i<nTree; i++){
+     if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
+       /* PmaReaders should be normally initialized in order, as if they are
+@@ -89570,7 +93922,8 @@
+   int iChunkOffset;
+   FileChunk *pChunk;
+ 
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
++ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+   if( (iAmt+iOfst)>p->endpoint.iOffset ){
+     return SQLITE_IOERR_SHORT_READ;
+   }
+@@ -89689,7 +94042,8 @@
+     ** atomic-write optimization. In this case the first 28 bytes of the
+     ** journal file may be written as part of committing the transaction. */ 
+     assert( iOfst==p->endpoint.iOffset || iOfst==0 );
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
++ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+     if( iOfst==0 && p->pFirst ){
+       assert( p->nChunkSize>iAmt );
+       memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
+@@ -89858,17 +94212,31 @@
+   sqlite3JournalOpen(0, 0, pJfd, 0, -1);
+ }
+ 
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
++ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ /*
+ ** If the argument p points to a MemJournal structure that is not an 
+ ** in-memory-only journal file (i.e. is one that was opened with a +ve
+-** nSpill parameter), and the underlying file has not yet been created, 
+-** create it now.
++** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying 
++** file has not yet been created, create it now.
+ */
+-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
++SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){
+   int rc = SQLITE_OK;
+-  if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){
+-    rc = memjrnlCreateFile((MemJournal*)p);
++  MemJournal *p = (MemJournal*)pJfd;
++  if( p->pMethod==&MemJournalMethods && (
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++     p->nSpill>0
++#else
++     /* While this appears to not be possible without ATOMIC_WRITE, the
++     ** paths are complex, so it seems prudent to leave the test in as
++     ** a NEVER(), in case our analysis is subtly flawed. */
++     NEVER(p->nSpill>0)
++#endif
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
++     || (p->flags & SQLITE_OPEN_MAIN_JOURNAL)
++#endif
++  )){
++    rc = memjrnlCreateFile(p);
+   }
+   return rc;
+ }
+@@ -89935,18 +94303,30 @@
+   int rc;
+   testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
+   testcase( ExprHasProperty(pExpr, EP_Reduced) );
+-  rc = pWalker->xExprCallback(pWalker, pExpr);
+-  if( rc ) return rc & WRC_Abort;
+-  if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+-    if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
+-    assert( pExpr->x.pList==0 || pExpr->pRight==0 );
+-    if( pExpr->pRight ){
+-      if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
+-    }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+-      if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
+-    }else if( pExpr->x.pList ){
+-      if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
++  while(1){
++    rc = pWalker->xExprCallback(pWalker, pExpr);
++    if( rc ) return rc & WRC_Abort;
++    if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
++      if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
++       assert( pExpr->x.pList==0 || pExpr->pRight==0 );
++      if( pExpr->pRight ){
++        pExpr = pExpr->pRight;
++        continue;
++      }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
++        if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
++      }else if( pExpr->x.pList ){
++        if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
++      }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(pExpr, EP_WinFunc) ){
++        Window *pWin = pExpr->y.pWin;
++        if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
++        if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
++        if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
++      }
++#endif
+     }
++    break;
+   }
+   return WRC_Continue;
+ }
+@@ -89982,7 +94362,6 @@
+   if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
+   if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
+   if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
+-  if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
+   return WRC_Continue;
+ }
+ 
+@@ -89999,17 +94378,16 @@
+   struct SrcList_item *pItem;
+ 
+   pSrc = p->pSrc;
+-  if( ALWAYS(pSrc) ){
+-    for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+-      if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+-        return WRC_Abort;
+-      }
+-      if( pItem->fg.isTabFunc
+-       && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+-      ){
+-        return WRC_Abort;
+-      }
++  assert( pSrc!=0 );
++  for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
++    if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
++      return WRC_Abort;
+     }
++    if( pItem->fg.isTabFunc
++     && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
++    ){
++      return WRC_Abort;
++    }
+   }
+   return WRC_Continue;
+ } 
+@@ -90130,29 +94508,31 @@
+   assert( pOrig!=0 );
+   db = pParse->db;
+   pDup = sqlite3ExprDup(db, pOrig, 0);
+-  if( pDup==0 ) return;
+-  if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
+-  if( pExpr->op==TK_COLLATE ){
+-    pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
+-  }
+-  ExprSetProperty(pDup, EP_Alias);
++  if( pDup!=0 ){
++    if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
++    if( pExpr->op==TK_COLLATE ){
++      pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
++    }
++    ExprSetProperty(pDup, EP_Alias);
+ 
+-  /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
+-  ** prevents ExprDelete() from deleting the Expr structure itself,
+-  ** allowing it to be repopulated by the memcpy() on the following line.
+-  ** The pExpr->u.zToken might point into memory that will be freed by the
+-  ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
+-  ** make a copy of the token before doing the sqlite3DbFree().
+-  */
+-  ExprSetProperty(pExpr, EP_Static);
+-  sqlite3ExprDelete(db, pExpr);
+-  memcpy(pExpr, pDup, sizeof(*pExpr));
+-  if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
+-    assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
+-    pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
+-    pExpr->flags |= EP_MemToken;
++    /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
++    ** prevents ExprDelete() from deleting the Expr structure itself,
++    ** allowing it to be repopulated by the memcpy() on the following line.
++    ** The pExpr->u.zToken might point into memory that will be freed by the
++    ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
++    ** make a copy of the token before doing the sqlite3DbFree().
++    */
++    ExprSetProperty(pExpr, EP_Static);
++    sqlite3ExprDelete(db, pExpr);
++    memcpy(pExpr, pDup, sizeof(*pExpr));
++    if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
++      assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
++      pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
++      pExpr->flags |= EP_MemToken;
++    }
++    sqlite3DbFree(db, pDup);
+   }
+-  sqlite3DbFree(db, pDup);
++  ExprSetProperty(pExpr, EP_Alias);
+ }
+ 
+ 
+@@ -90212,7 +94592,7 @@
+ **                         (even if X is implied).
+ **    pExpr->iTable        Set to the cursor number for the table obtained
+ **                         from pSrcList.
+-**    pExpr->pTab          Points to the Table structure of X.Y (even if
++**    pExpr->y.pTab        Points to the Table structure of X.Y (even if
+ **                         X and/or Y are implied.)
+ **    pExpr->iColumn       Set to the column number within the table.
+ **    pExpr->op            Set to TK_COLUMN.
+@@ -90246,7 +94626,7 @@
+   struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
+   NameContext *pTopNC = pNC;        /* First namecontext in the list */
+   Schema *pSchema = 0;              /* Schema of the expression */
+-  int isTrigger = 0;                /* True if resolved to a trigger column */
++  int eNewExprOp = TK_COLUMN;       /* New value for pExpr->op on success */
+   Table *pTab = 0;                  /* Table hold the row */
+   Column *pCol;                     /* A column of pTab */
+ 
+@@ -90256,7 +94636,6 @@
+ 
+   /* Initialize the node to no-match */
+   pExpr->iTable = -1;
+-  pExpr->pTab = 0;
+   ExprSetVVAProperty(pExpr, EP_NoReduce);
+ 
+   /* Translate the schema name in zDb into a pointer to the corresponding
+@@ -90317,6 +94696,9 @@
+           if( sqlite3StrICmp(zTabName, zTab)!=0 ){
+             continue;
+           }
++          if( IN_RENAME_OBJECT && pItem->zAlias ){
++            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
++          }
+         }
+         if( 0==(cntTab++) ){
+           pMatch = pItem;
+@@ -90341,32 +94723,45 @@
+       }
+       if( pMatch ){
+         pExpr->iTable = pMatch->iCursor;
+-        pExpr->pTab = pMatch->pTab;
++        pExpr->y.pTab = pMatch->pTab;
+         /* RIGHT JOIN not (yet) supported */
+         assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
+         if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+           ExprSetProperty(pExpr, EP_CanBeNull);
+         }
+-        pSchema = pExpr->pTab->pSchema;
++        pSchema = pExpr->y.pTab->pSchema;
+       }
+     } /* if( pSrcList ) */
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
++#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
+     /* If we have not already resolved the name, then maybe 
+-    ** it is a new.* or old.* trigger argument reference
++    ** it is a new.* or old.* trigger argument reference.  Or
++    ** maybe it is an excluded.* from an upsert.
+     */
+-    if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
+-      int op = pParse->eTriggerOp;
+-      assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
+-      if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
+-        pExpr->iTable = 1;
+-        pTab = pParse->pTriggerTab;
+-      }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
+-        pExpr->iTable = 0;
+-        pTab = pParse->pTriggerTab;
+-      }else{
+-        pTab = 0;
++    if( zDb==0 && zTab!=0 && cntTab==0 ){
++      pTab = 0;
++#ifndef SQLITE_OMIT_TRIGGER
++      if( pParse->pTriggerTab!=0 ){
++        int op = pParse->eTriggerOp;
++        assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
++        if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
++          pExpr->iTable = 1;
++          pTab = pParse->pTriggerTab;
++        }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
++          pExpr->iTable = 0;
++          pTab = pParse->pTriggerTab;
++        }
+       }
++#endif /* SQLITE_OMIT_TRIGGER */
++#ifndef SQLITE_OMIT_UPSERT
++      if( (pNC->ncFlags & NC_UUpsert)!=0 ){
++        Upsert *pUpsert = pNC->uNC.pUpsert;
++        if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
++          pTab = pUpsert->pUpsertSrc->a[0].pTab;
++          pExpr->iTable = 2;
++        }
++      }
++#endif /* SQLITE_OMIT_UPSERT */
+ 
+       if( pTab ){ 
+         int iCol;
+@@ -90386,24 +94781,42 @@
+         }
+         if( iCol<pTab->nCol ){
+           cnt++;
+-          if( iCol<0 ){
+-            pExpr->affinity = SQLITE_AFF_INTEGER;
+-          }else if( pExpr->iTable==0 ){
+-            testcase( iCol==31 );
+-            testcase( iCol==32 );
+-            pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
+-          }else{
+-            testcase( iCol==31 );
+-            testcase( iCol==32 );
+-            pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++#ifndef SQLITE_OMIT_UPSERT
++          if( pExpr->iTable==2 ){
++            testcase( iCol==(-1) );
++            if( IN_RENAME_OBJECT ){
++              pExpr->iColumn = iCol;
++              pExpr->y.pTab = pTab;
++              eNewExprOp = TK_COLUMN;
++            }else{
++              pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
++              eNewExprOp = TK_REGISTER;
++              ExprSetProperty(pExpr, EP_Alias);
++            }
++          }else
++#endif /* SQLITE_OMIT_UPSERT */
++          {
++#ifndef SQLITE_OMIT_TRIGGER
++            if( iCol<0 ){
++              pExpr->affinity = SQLITE_AFF_INTEGER;
++            }else if( pExpr->iTable==0 ){
++              testcase( iCol==31 );
++              testcase( iCol==32 );
++              pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++            }else{
++              testcase( iCol==31 );
++              testcase( iCol==32 );
++              pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++            }
++            pExpr->y.pTab = pTab;
++            pExpr->iColumn = (i16)iCol;
++            eNewExprOp = TK_TRIGGER;
++#endif /* SQLITE_OMIT_TRIGGER */
+           }
+-          pExpr->iColumn = (i16)iCol;
+-          pExpr->pTab = pTab;
+-          isTrigger = 1;
+         }
+       }
+     }
+-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
++#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */
+ 
+     /*
+     ** Perhaps the name is a reference to the ROWID
+@@ -90438,10 +94851,12 @@
+     ** is supported for backwards compatibility only. Hence, we issue a warning
+     ** on sqlite3_log() whenever the capability is used.
+     */
+-    if( (pEList = pNC->pEList)!=0
++    if( (pNC->ncFlags & NC_UEList)!=0
++     && cnt==0
+      && zTab==0
+-     && cnt==0
+     ){
++      pEList = pNC->uNC.pEList;
++      assert( pEList!=0 );
+       for(j=0; j<pEList->nExpr; j++){
+         char *zAs = pEList->a[j].zName;
+         if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
+@@ -90462,6 +94877,9 @@
+           cnt = 1;
+           pMatch = 0;
+           assert( zTab==0 && zDb==0 );
++          if( IN_RENAME_OBJECT ){
++            sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
++          }
+           goto lookupname_end;
+         }
+       } 
+@@ -90486,10 +94904,16 @@
+   ** Because no reference was made to outer contexts, the pNC->nRef
+   ** fields are not changed in any context.
+   */
+-  if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
+-    pExpr->op = TK_STRING;
+-    pExpr->pTab = 0;
+-    return WRC_Prune;
++  if( cnt==0 && zTab==0 ){
++    assert( pExpr->op==TK_ID );
++    if( ExprHasProperty(pExpr,EP_DblQuoted) ){
++      pExpr->op = TK_STRING;
++      pExpr->y.pTab = 0;
++      return WRC_Prune;
++    }
++    if( sqlite3ExprIdToTrueFalse(pExpr) ){
++      return WRC_Prune;
++    }
+   }
+ 
+   /*
+@@ -90532,7 +94956,7 @@
+   pExpr->pLeft = 0;
+   sqlite3ExprDelete(db, pExpr->pRight);
+   pExpr->pRight = 0;
+-  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
++  pExpr->op = eNewExprOp;
+   ExprSetProperty(pExpr, EP_Leaf);
+ lookupname_end:
+   if( cnt==1 ){
+@@ -90562,9 +94986,9 @@
+   Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
+   if( p ){
+     struct SrcList_item *pItem = &pSrc->a[iSrc];
+-    p->pTab = pItem->pTab;
++    p->y.pTab = pItem->pTab;
+     p->iTable = pItem->iCursor;
+-    if( p->pTab->iPKey==iCol ){
++    if( p->y.pTab->iPKey==iCol ){
+       p->iColumn = -1;
+     }else{
+       p->iColumn = (ynVar)iCol;
+@@ -90651,9 +95075,10 @@
+       SrcList *pSrcList = pNC->pSrcList;
+       struct SrcList_item *pItem;
+       assert( pSrcList && pSrcList->nSrc==1 );
+-      pItem = pSrcList->a; 
++      pItem = pSrcList->a;
++      assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
+       pExpr->op = TK_COLUMN;
+-      pExpr->pTab = pItem->pTab;
++      pExpr->y.pTab = pItem->pTab;
+       pExpr->iTable = pItem->iCursor;
+       pExpr->iColumn = -1;
+       pExpr->affinity = SQLITE_AFF_INTEGER;
+@@ -90682,18 +95107,23 @@
+         zTable = 0;
+         zColumn = pExpr->u.zToken;
+       }else{
++        Expr *pLeft = pExpr->pLeft;
+         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;
++          zDb = pLeft->u.zToken;
++          pLeft = pRight->pLeft;
++          pRight = pRight->pRight;
+         }
++        zTable = pLeft->u.zToken;
++        zColumn = pRight->u.zToken;
++        if( IN_RENAME_OBJECT ){
++          sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
++          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
++        }
+       }
+       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
+     }
+@@ -90774,41 +95204,105 @@
+           notValid(pParse, pNC, "non-deterministic functions",
+                    NC_IdxExpr|NC_PartIdx);
+         }
++        if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
++         && pParse->nested==0
++         && sqlite3Config.bInternalFunctions==0
++        ){
++          /* Internal-use-only functions are disallowed unless the
++          ** SQL is being compiled using sqlite3NestedParse() */
++          no_such_func = 1;
++          pDef = 0;
++        }
+       }
+-      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
+-        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
+-        pNC->nErr++;
+-        is_agg = 0;
+-      }else if( no_such_func && pParse->db->init.busy==0
++
++      if( 0==IN_RENAME_OBJECT ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
++          || (pDef->xValue==0 && pDef->xInverse==0)
++          || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
++        );
++        if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
++          sqlite3ErrorMsg(pParse, 
++              "%.*s() may not be used as a window function", nId, zId
++          );
++          pNC->nErr++;
++        }else if( 
++              (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
++           || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
++           || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
++        ){
++          const char *zType;
++          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
++            zType = "window";
++          }else{
++            zType = "aggregate";
++          }
++          sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
++          pNC->nErr++;
++          is_agg = 0;
++        }
++#else
++        if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
++          sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
++          pNC->nErr++;
++          is_agg = 0;
++        }
++#endif
++        else if( no_such_func && pParse->db->init.busy==0
+ #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+-                && pParse->explain==0
++                  && pParse->explain==0
+ #endif
+-      ){
+-        sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
+-        pNC->nErr++;
+-      }else if( wrong_num_args ){
+-        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
+-             nId, zId);
+-        pNC->nErr++;
++        ){
++          sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
++          pNC->nErr++;
++        }else if( wrong_num_args ){
++          sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
++               nId, zId);
++          pNC->nErr++;
++        }
++        if( is_agg ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++          pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
++#else
++          pNC->ncFlags &= ~NC_AllowAgg;
++#endif
++        }
+       }
+-      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
+       sqlite3WalkExprList(pWalker, pList);
+       if( is_agg ){
+-        NameContext *pNC2 = pNC;
+-        pExpr->op = TK_AGG_FUNCTION;
+-        pExpr->op2 = 0;
+-        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
+-          pExpr->op2++;
+-          pNC2 = pNC2->pNext;
+-        }
+-        assert( pDef!=0 );
+-        if( pNC2 ){
+-          assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
+-          testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
+-          pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        if( pExpr->y.pWin ){
++          Select *pSel = pNC->pWinSelect;
++          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
++          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
++          sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
++          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
++          if( 0==pSel->pWin 
++           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
++          ){
++            pExpr->y.pWin->pNextWin = pSel->pWin;
++            pSel->pWin = pExpr->y.pWin;
++          }
++          pNC->ncFlags |= NC_AllowWin;
++        }else
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++        {
++          NameContext *pNC2 = pNC;
++          pExpr->op = TK_AGG_FUNCTION;
++          pExpr->op2 = 0;
++          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
++            pExpr->op2++;
++            pNC2 = pNC2->pNext;
++          }
++          assert( pDef!=0 );
++          if( pNC2 ){
++            assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
++            testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
++            pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+ 
++          }
++          pNC->ncFlags |= NC_AllowAgg;
+         }
+-        pNC->ncFlags |= NC_AllowAgg;
+       }
+       /* FIX ME:  Compute pExpr->affinity based on the expected return
+       ** type of the function 
+@@ -90837,6 +95331,23 @@
+       notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+       break;
+     }
++    case TK_IS:
++    case TK_ISNOT: {
++      Expr *pRight;
++      assert( !ExprHasProperty(pExpr, EP_Reduced) );
++      /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
++      ** and "x IS NOT FALSE". */
++      if( (pRight = pExpr->pRight)->op==TK_ID ){
++        int rc = resolveExprStep(pWalker, pRight);
++        if( rc==WRC_Abort ) return WRC_Abort;
++        if( pRight->op==TK_TRUEFALSE ){
++          pExpr->op2 = pExpr->op;
++          pExpr->op = TK_TRUTH;
++          return WRC_Continue;
++        }
++      }
++      /* Fall thru */
++    }
+     case TK_BETWEEN:
+     case TK_EQ:
+     case TK_NE:
+@@ -90843,9 +95354,7 @@
+     case TK_LT:
+     case TK_LE:
+     case TK_GT:
+-    case TK_GE:
+-    case TK_IS:
+-    case TK_ISNOT: {
++    case TK_GE: {
+       int nLeft, nRight;
+       if( pParse->db->mallocFailed ) break;
+       assert( pExpr->pLeft!=0 );
+@@ -90948,8 +95457,8 @@
+   memset(&nc, 0, sizeof(nc));
+   nc.pParse = pParse;
+   nc.pSrcList = pSelect->pSrc;
+-  nc.pEList = pEList;
+-  nc.ncFlags = NC_AllowAgg;
++  nc.uNC.pEList = pEList;
++  nc.ncFlags = NC_AllowAgg|NC_UEList;
+   nc.nErr = 0;
+   db = pParse->db;
+   savedSuppErr = db->suppressErr;
+@@ -91014,12 +95523,10 @@
+   pOrderBy = pSelect->pOrderBy;
+   if( pOrderBy==0 ) return 0;
+   db = pParse->db;
+-#if SQLITE_MAX_COLUMN
+   if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+     sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
+     return 1;
+   }
+-#endif
+   for(i=0; i<pOrderBy->nExpr; i++){
+     pOrderBy->a[i].done = 0;
+   }
+@@ -91111,12 +95618,10 @@
+   struct ExprList_item *pItem;
+ 
+   if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
+-#if SQLITE_MAX_COLUMN
+   if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+     sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
+     return 1;
+   }
+-#endif
+   pEList = pSelect->pEList;
+   assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
+   for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
+@@ -91198,6 +95703,19 @@
+     }
+     for(j=0; j<pSelect->pEList->nExpr; j++){
+       if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        if( ExprHasProperty(pE, EP_WinFunc) ){
++          /* Since this window function is being changed into a reference
++          ** to the same window function the result set, remove the instance
++          ** of this window function from the Select.pWin list. */
++          Window **pp;
++          for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
++            if( *pp==pE->y.pWin ){
++              *pp = (*pp)->pNextWin;
++            }    
++          }
++        }
++#endif
+         pItem->u.x.iOrderByCol = j+1;
+       }
+     }
+@@ -91254,8 +95772,8 @@
+     */
+     memset(&sNC, 0, sizeof(sNC));
+     sNC.pParse = pParse;
+-    if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
+-        sqlite3ResolveExprNames(&sNC, p->pOffset) ){
++    sNC.pWinSelect = p;
++    if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
+       return WRC_Abort;
+     }
+ 
+@@ -91303,12 +95821,13 @@
+     /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
+     ** resolve the result-set expression list.
+     */
+-    sNC.ncFlags = NC_AllowAgg;
++    sNC.ncFlags = NC_AllowAgg|NC_AllowWin;
+     sNC.pSrcList = p->pSrc;
+     sNC.pNext = pOuterNC;
+   
+     /* Resolve names in the result set. */
+     if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
++    sNC.ncFlags &= ~NC_AllowWin;
+   
+     /* If there are no aggregate functions in the result-set, and no GROUP BY 
+     ** expression, do not allow aggregates in any of the other expressions.
+@@ -91337,7 +95856,9 @@
+     ** Minor point: If this is the case, then the expression will be
+     ** re-evaluated for each reference to it.
+     */
+-    sNC.pEList = p->pEList;
++    assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 );
++    sNC.uNC.pEList = p->pEList;
++    sNC.ncFlags |= NC_UEList;
+     if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
+     if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+ 
+@@ -91355,7 +95876,7 @@
+     ** outer queries 
+     */
+     sNC.pNext = 0;
+-    sNC.ncFlags |= NC_AllowAgg;
++    sNC.ncFlags |= NC_AllowAgg|NC_AllowWin;
+ 
+     /* If this is a converted compound query, move the ORDER BY clause from 
+     ** the sub-query back to the parent query. At this point each term
+@@ -91386,6 +95907,7 @@
+     if( db->mallocFailed ){
+       return WRC_Abort;
+     }
++    sNC.ncFlags &= ~NC_AllowWin;
+   
+     /* Resolve the GROUP BY clause.  At the same time, make sure 
+     ** the GROUP BY clause does not contain aggregate functions.
+@@ -91570,7 +96092,7 @@
+   Table *pTab,        /* The table being referenced */
+   int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+   Expr *pExpr,        /* Expression to resolve.  May be NULL. */
+-  ExprList *pList     /* Expression list to resolve.  May be NUL. */
++  ExprList *pList     /* Expression list to resolve.  May be NULL. */
+ ){
+   SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
+   NameContext sNC;                /* Name context for pParse->pNewTable */
+@@ -91651,8 +96173,8 @@
+     return sqlite3AffinityType(pExpr->u.zToken, 0);
+   }
+ #endif
+-  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
+-    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
++  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
++    return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+   }
+   if( op==TK_SELECT_COLUMN ){
+     assert( pExpr->pLeft->flags&EP_xIsSelect );
+@@ -91717,6 +96239,11 @@
+ ** Return the collation sequence for the expression pExpr. If
+ ** there is no defined collating sequence, return NULL.
+ **
++** See also: sqlite3ExprNNCollSeq()
++**
++** The sqlite3ExprNNCollSeq() works the same exact that it returns the
++** default collation if pExpr has no defined collation.
++**
+ ** The collating sequence might be determined by a COLLATE operator
+ ** or by the presence of a column with a defined collating sequence.
+ ** COLLATE operators take first precedence.  Left operands take
+@@ -91729,27 +96256,27 @@
+   while( p ){
+     int op = p->op;
+     if( p->flags & EP_Generic ) break;
+-    if( op==TK_CAST || op==TK_UPLUS ){
+-      p = p->pLeft;
+-      continue;
+-    }
+-    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+-      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
+-      break;
+-    }
+     if( (op==TK_AGG_COLUMN || op==TK_COLUMN
+           || op==TK_REGISTER || op==TK_TRIGGER)
+-     && p->pTab!=0
++     && p->y.pTab!=0
+     ){
+-      /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
++      /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
+       ** a TK_COLUMN but was previously evaluated and cached in a register */
+       int j = p->iColumn;
+       if( j>=0 ){
+-        const char *zColl = p->pTab->aCol[j].zColl;
++        const char *zColl = p->y.pTab->aCol[j].zColl;
+         pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
+       }
+       break;
+     }
++    if( op==TK_CAST || op==TK_UPLUS ){
++      p = p->pLeft;
++      continue;
++    }
++    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
++      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
++      break;
++    }
+     if( p->flags & EP_Collate ){
+       if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
+         p = p->pLeft;
+@@ -91782,6 +96309,32 @@
+ }
+ 
+ /*
++** Return the collation sequence for the expression pExpr. If
++** there is no defined collating sequence, return a pointer to the
++** defautl collation sequence.
++**
++** See also: sqlite3ExprCollSeq()
++**
++** The sqlite3ExprCollSeq() routine works the same except that it
++** returns NULL if there is no defined collation.
++*/
++SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
++  CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
++  if( p==0 ) p = pParse->db->pDfltColl;
++  assert( p!=0 );
++  return p;
++}
++
++/*
++** Return TRUE if the two expressions have equivalent collating sequences.
++*/
++SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
++  CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
++  CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
++  return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
++}
++
++/*
+ ** pExpr is an operand of a comparison operator.  aff2 is the
+ ** type affinity of the other operand.  This routine returns the
+ ** type affinity that should be used for the comparison operator.
+@@ -92143,7 +96696,6 @@
+     Expr *pL, *pR; 
+     int r1, r2;
+     assert( i>=0 && i<nLeft );
+-    if( i>0 ) sqlite3ExprCachePush(pParse);
+     r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
+     r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
+     codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
+@@ -92155,7 +96707,6 @@
+     testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+     sqlite3ReleaseTempReg(pParse, regFree1);
+     sqlite3ReleaseTempReg(pParse, regFree2);
+-    if( i>0 ) sqlite3ExprCachePop(pParse);
+     if( i==nLeft-1 ){
+       break;
+     }
+@@ -92220,16 +96771,15 @@
+     }
+   }
+ }
+-static void heightOfSelect(Select *p, int *pnHeight){
+-  if( p ){
++static void heightOfSelect(Select *pSelect, int *pnHeight){
++  Select *p;
++  for(p=pSelect; p; p=p->pPrior){
+     heightOfExpr(p->pWhere, pnHeight);
+     heightOfExpr(p->pHaving, pnHeight);
+     heightOfExpr(p->pLimit, pnHeight);
+-    heightOfExpr(p->pOffset, pnHeight);
+     heightOfExprList(p->pEList, pnHeight);
+     heightOfExprList(p->pGroupBy, pnHeight);
+     heightOfExprList(p->pOrderBy, pnHeight);
+-    heightOfSelect(p->pPrior, pnHeight);
+   }
+ }
+ 
+@@ -92368,7 +96918,7 @@
+ ){
+   Token x;
+   x.z = zToken;
+-  x.n = zToken ? sqlite3Strlen30(zToken) : 0;
++  x.n = sqlite3Strlen30(zToken);
+   return sqlite3ExprAlloc(db, op, &x, 0);
+ }
+ 
+@@ -92504,7 +97054,12 @@
+ ** Construct a new expression node for a function with multiple
+ ** arguments.
+ */
+-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
++SQLITE_PRIVATE Expr *sqlite3ExprFunction(
++  Parse *pParse,        /* Parsing context */
++  ExprList *pList,      /* Argument list */
++  Token *pToken,        /* Name of the function */
++  int eDistinct         /* SF_Distinct or SF_ALL or 0 */
++){
+   Expr *pNew;
+   sqlite3 *db = pParse->db;
+   assert( pToken );
+@@ -92513,9 +97068,14 @@
+     sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
+     return 0;
+   }
++  if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
++    sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
++  }
+   pNew->x.pList = pList;
++  ExprSetProperty(pNew, EP_HasFunc);
+   assert( !ExprHasProperty(pNew, EP_xIsSelect) );
+   sqlite3ExprSetHeightAndFlags(pParse, pNew);
++  if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
+   return pNew;
+ }
+ 
+@@ -92607,6 +97167,10 @@
+   assert( p!=0 );
+   /* Sanity check: Assert that the IntValue is non-negative if it exists */
+   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
++
++  assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
++  assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
++          || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
+ #ifdef SQLITE_DEBUG
+   if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
+     assert( p->pLeft==0 );
+@@ -92625,6 +97189,10 @@
+     }else{
+       sqlite3ExprListDelete(db, p->x.pList);
+     }
++    if( ExprHasProperty(p, EP_WinFunc) ){
++      assert( p->op==TK_FUNCTION );
++      sqlite3WindowDelete(db, p->y.pWin);
++    }
+   }
+   if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
+   if( !ExprHasProperty(p, EP_Static) ){
+@@ -92673,7 +97241,7 @@
+ ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
+ ** (unreduced) Expr objects as they or originally constructed by the parser.
+ ** During expression analysis, extra information is computed and moved into
+-** later parts of teh Expr object and that extra information might get chopped
++** later parts of the Expr object and that extra information might get chopped
+ ** off if the expression is reduced.  Note also that it does not work to
+ ** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
+ ** to reduce a pristine expression tree from the parser.  The implementation
+@@ -92685,7 +97253,11 @@
+   assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
+   assert( EXPR_FULLSIZE<=0xfff );
+   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
+-  if( 0==flags || p->op==TK_SELECT_COLUMN ){
++  if( 0==flags || p->op==TK_SELECT_COLUMN 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++   || ExprHasProperty(p, EP_WinFunc)
++#endif
++  ){
+     nSize = EXPR_FULLSIZE;
+   }else{
+     assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+@@ -92710,7 +97282,7 @@
+ static int dupedExprNodeSize(Expr *p, int flags){
+   int nByte = dupedExprStructSize(p, flags) & 0xfff;
+   if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+-    nByte += sqlite3Strlen30(p->u.zToken)+1;
++    nByte += sqlite3Strlen30NN(p->u.zToken)+1;
+   }
+   return ROUND8(nByte);
+ }
+@@ -92813,7 +97385,7 @@
+     }
+ 
+     /* Fill in pNew->pLeft and pNew->pRight. */
+-    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
++    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
+       zAlloc += dupedExprNodeSize(p, dupFlags);
+       if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
+         pNew->pLeft = p->pLeft ?
+@@ -92821,6 +97393,12 @@
+         pNew->pRight = p->pRight ?
+                        exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
+       }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(p, EP_WinFunc) ){
++        pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
++        assert( ExprHasProperty(pNew, EP_WinFunc) );
++      }
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+       if( pzBuffer ){
+         *pzBuffer = zAlloc;
+       }
+@@ -92895,10 +97473,9 @@
+   Expr *pPriorSelectCol = 0;
+   assert( db!=0 );
+   if( p==0 ) return 0;
+-  pNew = sqlite3DbMallocRawNN(db, 
+-             sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
++  pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
+   if( pNew==0 ) return 0;
+-  pNew->nAlloc = pNew->nExpr = p->nExpr;
++  pNew->nExpr = p->nExpr;
+   pItem = pNew->a;
+   pOldItem = p->a;
+   for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
+@@ -92926,6 +97503,7 @@
+     pItem->sortOrder = pOldItem->sortOrder;
+     pItem->done = 0;
+     pItem->bSpanIsTab = pOldItem->bSpanIsTab;
++    pItem->bSorterRef = pOldItem->bSorterRef;
+     pItem->u = pOldItem->u;
+   }
+   return pNew;
+@@ -93024,7 +97602,6 @@
+     pNew->pNext = pNext;
+     pNew->pPrior = 0;
+     pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
+-    pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
+     pNew->iLimit = 0;
+     pNew->iOffset = 0;
+     pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
+@@ -93032,7 +97609,11 @@
+     pNew->addrOpenEphm[1] = -1;
+     pNew->nSelectRow = p->nSelectRow;
+     pNew->pWith = withDup(db, p->pWith);
+-    sqlite3SelectSetName(pNew, p->zSelName);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    pNew->pWin = 0;
++    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
++#endif
++    pNew->selId = p->selId;
+     *pp = pNew;
+     pp = &pNew->pPrior;
+     pNext = pNew;
+@@ -93052,6 +97633,13 @@
+ ** Add a new element to the end of an expression list.  If pList is
+ ** initially NULL, then create a new expression list.
+ **
++** The pList argument must be either NULL or a pointer to an ExprList
++** obtained from a prior call to sqlite3ExprListAppend().  This routine
++** may not be used with an ExprList obtained from sqlite3ExprListDup().
++** Reason:  This routine assumes that the number of slots in pList->a[]
++** is a power of two.  That is true for sqlite3ExprListAppend() returns
++** but is not necessarily true from the return value of sqlite3ExprListDup().
++**
+ ** If a memory allocation error occurs, the entire list is freed and
+ ** NULL is returned.  If non-NULL is returned, then it is guaranteed
+ ** that the new entry was successfully appended.
+@@ -93070,16 +97658,14 @@
+       goto no_mem;
+     }
+     pList->nExpr = 0;
+-    pList->nAlloc = 1;
+-  }else if( pList->nExpr==pList->nAlloc ){
++  }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
+     ExprList *pNew;
+     pNew = sqlite3DbRealloc(db, pList, 
+-             sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
++             sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0]));
+     if( pNew==0 ){
+       goto no_mem;
+     }
+     pList = pNew;
+-    pList->nAlloc *= 2;
+   }
+   pItem = &pList->a[pList->nExpr++];
+   assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
+@@ -93199,6 +97785,9 @@
+     assert( pItem->zName==0 );
+     pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+     if( dequote ) sqlite3Dequote(pItem->zName);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
++    }
+   }
+ }
+ 
+@@ -93213,7 +97802,8 @@
+ SQLITE_PRIVATE void sqlite3ExprListSetSpan(
+   Parse *pParse,          /* Parsing context */
+   ExprList *pList,        /* List to which to add the span. */
+-  ExprSpan *pSpan         /* The span to be added */
++  const char *zStart,     /* Start of the span */
++  const char *zEnd        /* End of the span */
+ ){
+   sqlite3 *db = pParse->db;
+   assert( pList!=0 || db->mallocFailed!=0 );
+@@ -93220,10 +97810,8 @@
+   if( pList ){
+     struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
+     assert( pList->nExpr>0 );
+-    assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
+     sqlite3DbFree(db, pItem->zSpan);
+-    pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+-                                    (int)(pSpan->zEnd - pSpan->zStart));
++    pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
+   }
+ }
+ 
+@@ -93270,17 +97858,57 @@
+ SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
+   int i;
+   u32 m = 0;
+-  if( pList ){
+-    for(i=0; i<pList->nExpr; i++){
+-       Expr *pExpr = pList->a[i].pExpr;
+-       assert( pExpr!=0 );
+-       m |= pExpr->flags;
+-    }
++  assert( pList!=0 );
++  for(i=0; i<pList->nExpr; i++){
++     Expr *pExpr = pList->a[i].pExpr;
++     assert( pExpr!=0 );
++     m |= pExpr->flags;
+   }
+   return m;
+ }
+ 
+ /*
++** This is a SELECT-node callback for the expression walker that
++** always "fails".  By "fail" in this case, we mean set
++** pWalker->eCode to zero and abort.
++**
++** This callback is used by multiple expression walkers.
++*/
++SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
++  UNUSED_PARAMETER(NotUsed);
++  pWalker->eCode = 0;
++  return WRC_Abort;
++}
++
++/*
++** If the input expression is an ID with the name "true" or "false"
++** then convert it into an TK_TRUEFALSE term.  Return non-zero if
++** the conversion happened, and zero if the expression is unaltered.
++*/
++SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
++  assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
++  if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
++   || sqlite3StrICmp(pExpr->u.zToken, "false")==0
++  ){
++    pExpr->op = TK_TRUEFALSE;
++    return 1;
++  }
++  return 0;
++}
++
++/*
++** The argument must be a TK_TRUEFALSE Expr node.  Return 1 if it is TRUE
++** and 0 if it is FALSE.
++*/
++SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
++  assert( pExpr->op==TK_TRUEFALSE );
++  assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
++       || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
++  return pExpr->u.zToken[4]==0;
++}
++
++
++/*
+ ** These routines are Walker callbacks used to check expressions to
+ ** see if they are "constant" for some definition of constant.  The
+ ** Walker.eCode value determines the type of "constant" we are looking
+@@ -93327,6 +97955,12 @@
+         return WRC_Abort;
+       }
+     case TK_ID:
++      /* Convert "true" or "false" in a DEFAULT clause into the
++      ** appropriate TK_TRUEFALSE operator */
++      if( sqlite3ExprIdToTrueFalse(pExpr) ){
++        return WRC_Prune;
++      }
++      /* Fall thru */
+     case TK_COLUMN:
+     case TK_AGG_FUNCTION:
+     case TK_AGG_COLUMN:
+@@ -93334,11 +97968,16 @@
+       testcase( pExpr->op==TK_COLUMN );
+       testcase( pExpr->op==TK_AGG_FUNCTION );
+       testcase( pExpr->op==TK_AGG_COLUMN );
++      if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){
++        return WRC_Continue;
++      }
+       if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
+         return WRC_Continue;
+       }
+       /* Fall through */
+     case TK_IF_NULL_ROW:
++    case TK_REGISTER:
++      testcase( pExpr->op==TK_REGISTER );
+       testcase( pExpr->op==TK_IF_NULL_ROW );
+       pWalker->eCode = 0;
+       return WRC_Abort;
+@@ -93356,21 +97995,16 @@
+       }
+       /* Fall through */
+     default:
+-      testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
+-      testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
++      testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
++      testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
+       return WRC_Continue;
+   }
+ }
+-static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
+-  UNUSED_PARAMETER(NotUsed);
+-  pWalker->eCode = 0;
+-  return WRC_Abort;
+-}
+ static int exprIsConst(Expr *p, int initFlag, int iCur){
+   Walker w;
+   w.eCode = initFlag;
+   w.xExprCallback = exprNodeIsConstant;
+-  w.xSelectCallback = selectNodeIsConstant;
++  w.xSelectCallback = sqlite3SelectWalkFail;
+ #ifdef SQLITE_DEBUG
+   w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+ #endif
+@@ -93392,10 +98026,17 @@
+ }
+ 
+ /*
+-** Walk an expression tree.  Return non-zero if the expression is constant
+-** that does no originate from the ON or USING clauses of a join.
+-** Return 0 if it involves variables or function calls or terms from
+-** an ON or USING clause.
++** Walk an expression tree.  Return non-zero if
++**
++**   (1) the expression is constant, and
++**   (2) the expression does originate in the ON or USING clause
++**       of a LEFT JOIN, and
++**   (3) the expression does not contain any EP_FixedCol TK_COLUMN
++**       operands created by the constant propagation optimization.
++**
++** When this routine returns true, it indicates that the expression
++** can be added to the pParse->pConstExpr list and evaluated once when
++** the prepared statement starts up.  See sqlite3ExprCodeAtInit().
+ */
+ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
+   return exprIsConst(p, 2, 0);
+@@ -93424,8 +98065,8 @@
+   for(i=0; i<pGroupBy->nExpr; i++){
+     Expr *p = pGroupBy->a[i].pExpr;
+     if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
+-      CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
+-      if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
++      CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
++      if( sqlite3IsBinary(pColl) ){
+         return WRC_Prune;
+       }
+     }
+@@ -93493,7 +98134,7 @@
+   Walker w;
+   w.eCode = 1;
+   w.xExprCallback = sqlite3ExprWalkNoop;
+-  w.xSelectCallback = selectNodeIsConstant;
++  w.xSelectCallback = sqlite3SelectWalkFail;
+ #ifdef SQLITE_DEBUG
+   w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+ #endif
+@@ -93566,9 +98207,9 @@
+     case TK_BLOB:
+       return 0;
+     case TK_COLUMN:
+-      assert( p->pTab!=0 );
+       return ExprHasProperty(p, EP_CanBeNull) ||
+-             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
++             p->y.pTab==0 ||  /* Reference to column of index on expression */
++             (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
+     default:
+       return 1;
+   }
+@@ -93623,6 +98264,14 @@
+   if( sqlite3StrICmp(z, "OID")==0 ) return 1;
+   return 0;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
++  if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
++  if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
++  if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
++  return 0;
++}
++#endif
+ 
+ /*
+ ** pX is the RHS of an IN operator.  If pX is a SELECT statement 
+@@ -93649,7 +98298,6 @@
+   }
+   assert( p->pGroupBy==0 );              /* Has no GROUP BY clause */
+   if( p->pLimit ) return 0;              /* Has no LIMIT clause */
+-  assert( p->pOffset==0 );               /* No LIMIT means no OFFSET */
+   if( p->pWhere ) return 0;              /* Has no WHERE clause */
+   pSrc = p->pSrc;
+   assert( pSrc!=0 );
+@@ -93739,16 +98387,15 @@
+ ** pX->iTable made to point to the ephemeral table instead of an
+ ** existing table.
+ **
+-** The inFlags parameter must contain exactly one of the bits
+-** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP.  If inFlags contains
+-** IN_INDEX_MEMBERSHIP, then the generated table will be used for a
+-** fast membership test.  When the IN_INDEX_LOOP bit is set, the
+-** IN index will be used to loop over all values of the RHS of the
+-** IN operator.
++** The inFlags parameter must contain, at a minimum, one of the bits
++** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both.  If inFlags contains
++** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast
++** membership test.  When the IN_INDEX_LOOP bit is set, the IN index will
++** be used to loop over all values of the RHS of the IN operator.
+ **
+ ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
+ ** through the set members) then the b-tree must not contain duplicates.
+-** An epheremal table must be used unless the selected columns are guaranteed
++** An epheremal table will be created unless the selected columns are guaranteed
+ ** to be unique - either because it is an INTEGER PRIMARY KEY or due to
+ ** a UNIQUE constraint or index.
+ **
+@@ -93849,7 +98496,8 @@
+ 
+       sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+       eType = IN_INDEX_ROWID;
+-
++      ExplainQueryPlan((pParse, 0,
++            "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName));
+       sqlite3VdbeJumpHere(v, iAddr);
+     }else{
+       Index *pIdx;                         /* Iterator variable */
+@@ -93928,11 +98576,8 @@
+           if( colUsed==(MASKBIT(nExpr)-1) ){
+             /* If we reach this point, that means the index pIdx is usable */
+             int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+-#ifndef SQLITE_OMIT_EXPLAIN
+-            sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
+-              sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
+-              P4_DYNAMIC);
+-#endif
++            ExplainQueryPlan((pParse, 0,
++                              "USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
+             sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+             sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+             VdbeComment((v, "%s", pIdx->zName));
+@@ -94111,7 +98756,6 @@
+   int rReg = 0;                           /* Register storing resulting */
+   Vdbe *v = sqlite3GetVdbe(pParse);
+   if( NEVER(v==0) ) return 0;
+-  sqlite3ExprCachePush(pParse);
+ 
+   /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+   ** is encountered if any of the following is true:
+@@ -94127,17 +98771,6 @@
+     jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+   }
+ 
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  if( pParse->explain==2 ){
+-    char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
+-        jmpIfDynamic>=0?"":"CORRELATED ",
+-        pExpr->op==TK_IN?"LIST":"SCALAR",
+-        pParse->iNextSelectId
+-    );
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
+-#endif
+-
+   switch( pExpr->op ){
+     case TK_IN: {
+       int addr;                   /* Address of OP_OpenEphemeral instruction */
+@@ -94175,6 +98808,9 @@
+         Select *pSelect = pExpr->x.pSelect;
+         ExprList *pEList = pSelect->pEList;
+ 
++        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
++            jmpIfDynamic>=0?"":"CORRELATED "
++        ));
+         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. */
+@@ -94216,7 +98852,6 @@
+         ExprList *pList = pExpr->x.pList;
+         struct ExprList_item *pItem;
+         int r1, r2, r3;
+-
+         affinity = sqlite3ExprAffinity(pLeft);
+         if( !affinity ){
+           affinity = SQLITE_AFF_BLOB;
+@@ -94229,7 +98864,7 @@
+         /* Loop through each expression in <exprlist>. */
+         r1 = sqlite3GetTempReg(pParse);
+         r2 = sqlite3GetTempReg(pParse);
+-        if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
++        if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
+         for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
+           Expr *pE2 = pItem->pExpr;
+           int iValToIns;
+@@ -94256,7 +98891,6 @@
+               sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
+             }else{
+               sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+-              sqlite3ExprCacheAffinityChange(pParse, r3, 1);
+               sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
+             }
+           }
+@@ -94289,6 +98923,7 @@
+       Select *pSel;                         /* SELECT statement to encode */
+       SelectDest dest;                      /* How to deal with SELECT result */
+       int nReg;                             /* Registers to allocate */
++      Expr *pLimit;                         /* New limit expression */
+ 
+       testcase( pExpr->op==TK_EXISTS );
+       testcase( pExpr->op==TK_SELECT );
+@@ -94296,6 +98931,8 @@
+       assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ 
+       pSel = pExpr->x.pSelect;
++      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
++            jmpIfDynamic>=0?"":"CORRELATED "));
+       nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+       sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+       pParse->nMem += nReg;
+@@ -94310,11 +98947,14 @@
+         sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
+         VdbeComment((v, "Init EXISTS result"));
+       }
+-      sqlite3ExprDelete(pParse->db, pSel->pLimit);
+-      pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
+-                                  &sqlite3IntTokens[1], 0);
++      pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
++      if( pSel->pLimit ){
++        sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
++        pSel->pLimit->pLeft = pLimit;
++      }else{
++        pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
++      }
+       pSel->iLimit = 0;
+-      pSel->selFlags &= ~SF_MultiValue;
+       if( sqlite3Select(pParse, pSel, &dest) ){
+         return 0;
+       }
+@@ -94331,7 +98971,6 @@
+   if( jmpIfDynamic>=0 ){
+     sqlite3VdbeJumpHere(v, jmpIfDynamic);
+   }
+-  sqlite3ExprCachePop(pParse);
+ 
+   return rReg;
+ }
+@@ -94450,7 +99089,6 @@
+   ** aiMap[] array contains a mapping from the original LHS field order to
+   ** the field order that matches the RHS index.
+   */
+-  sqlite3ExprCachePush(pParse);
+   rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
+   for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
+   if( i==nVector ){
+@@ -94609,7 +99247,6 @@
+ 
+ sqlite3ExprCodeIN_finished:
+   if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
+-  sqlite3ExprCachePop(pParse);
+   VdbeComment((v, "end IN expr"));
+ sqlite3ExprCodeIN_oom_error:
+   sqlite3DbFree(pParse->db, aiMap);
+@@ -94657,7 +99294,7 @@
+     const char *z = pExpr->u.zToken;
+     assert( z!=0 );
+     c = sqlite3DecOrHexToI64(z, &value);
+-    if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){
++    if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
+ #ifdef SQLITE_OMIT_FLOATING_POINT
+       sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
+ #else
+@@ -94671,152 +99308,13 @@
+       }
+ #endif
+     }else{
+-      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
++      if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; }
+       sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
+     }
+   }
+ }
+ 
+-/*
+-** Erase column-cache entry number i
+-*/
+-static void cacheEntryClear(Parse *pParse, int i){
+-  if( pParse->aColCache[i].tempReg ){
+-    if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+-      pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+-    }
+-  }
+-  pParse->nColCache--;
+-  if( i<pParse->nColCache ){
+-    pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
+-  }
+-}
+ 
+-
+-/*
+-** Record in the column cache that a particular column from a
+-** particular table is stored in a particular register.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
+-  int i;
+-  int minLru;
+-  int idxLru;
+-  struct yColCache *p;
+-
+-  /* Unless an error has occurred, register numbers are always positive. */
+-  assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
+-  assert( iCol>=-1 && iCol<32768 );  /* Finite column numbers */
+-
+-  /* The SQLITE_ColumnCache flag disables the column cache.  This is used
+-  ** for testing only - to verify that SQLite always gets the same answer
+-  ** with and without the column cache.
+-  */
+-  if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
+-
+-  /* First replace any existing entry.
+-  **
+-  ** Actually, the way the column cache is currently used, we are guaranteed
+-  ** that the object will never already be in cache.  Verify this guarantee.
+-  */
+-#ifndef NDEBUG
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    assert( p->iTable!=iTab || p->iColumn!=iCol );
+-  }
+-#endif
+-
+-  /* If the cache is already full, delete the least recently used entry */
+-  if( pParse->nColCache>=SQLITE_N_COLCACHE ){
+-    minLru = 0x7fffffff;
+-    idxLru = -1;
+-    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-      if( p->lru<minLru ){
+-        idxLru = i;
+-        minLru = p->lru;
+-      }
+-    }
+-    p = &pParse->aColCache[idxLru];
+-  }else{
+-    p = &pParse->aColCache[pParse->nColCache++];
+-  }
+-
+-  /* Add the new entry to the end of the cache */
+-  p->iLevel = pParse->iCacheLevel;
+-  p->iTable = iTab;
+-  p->iColumn = iCol;
+-  p->iReg = iReg;
+-  p->tempReg = 0;
+-  p->lru = pParse->iCacheCnt++;
+-}
+-
+-/*
+-** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
+-** Purge the range of registers from the column cache.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
+-  int i = 0;
+-  while( i<pParse->nColCache ){
+-    struct yColCache *p = &pParse->aColCache[i];
+-    if( p->iReg >= iReg && p->iReg < iReg+nReg ){
+-      cacheEntryClear(pParse, i);
+-    }else{
+-      i++;
+-    }
+-  }
+-}
+-
+-/*
+-** Remember the current column cache context.  Any new entries added
+-** added to the column cache after this call are removed when the
+-** corresponding pop occurs.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
+-  pParse->iCacheLevel++;
+-#ifdef SQLITE_DEBUG
+-  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+-    printf("PUSH to %d\n", pParse->iCacheLevel);
+-  }
+-#endif
+-}
+-
+-/*
+-** Remove from the column cache any entries that were added since the
+-** the previous sqlite3ExprCachePush operation.  In other words, restore
+-** the cache to the state it was in prior the most recent Push.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
+-  int i = 0;
+-  assert( pParse->iCacheLevel>=1 );
+-  pParse->iCacheLevel--;
+-#ifdef SQLITE_DEBUG
+-  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+-    printf("POP  to %d\n", pParse->iCacheLevel);
+-  }
+-#endif
+-  while( i<pParse->nColCache ){
+-    if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
+-      cacheEntryClear(pParse, i);
+-    }else{
+-      i++;
+-    }
+-  }
+-}
+-
+-/*
+-** When a cached column is reused, make sure that its register is
+-** no longer available as a temp register.  ticket #3879:  that same
+-** register might be in the cache in multiple places, so be sure to
+-** get them all.
+-*/
+-static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
+-  int i;
+-  struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    if( p->iReg==iReg ){
+-      p->tempReg = 0;
+-    }
+-  }
+-}
+-
+ /* Generate code that will load into register regOut a value that is
+ ** appropriate for the iIdxCol-th column of index pIdx.
+ */
+@@ -94871,13 +99369,8 @@
+ 
+ /*
+ ** Generate code that will extract the iColumn-th column from
+-** table pTab and store the column value in a register. 
++** table pTab and store the column value in register iReg. 
+ **
+-** An effort is made to store the column value in register iReg.  This
+-** is not garanteeed for GetColumn() - the result can be stored in
+-** any register.  But the result is guaranteed to land in register iReg
+-** for GetColumnToReg().
+-**
+ ** There must be an open cursor to pTab in iTable when this routine
+ ** is called.  If iColumn<0 then code is generated that extracts the rowid.
+ */
+@@ -94890,97 +99383,24 @@
+   u8 p5            /* P5 value for OP_Column + FLAGS */
+ ){
+   Vdbe *v = pParse->pVdbe;
+-  int i;
+-  struct yColCache *p;
+-
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    if( p->iTable==iTable && p->iColumn==iColumn ){
+-      p->lru = pParse->iCacheCnt++;
+-      sqlite3ExprCachePinRegister(pParse, p->iReg);
+-      return p->iReg;
+-    }
+-  }  
+   assert( v!=0 );
+   sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
+   if( p5 ){
+     sqlite3VdbeChangeP5(v, p5);
+-  }else{   
+-    sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
+   }
+   return iReg;
+ }
+-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
+-  Parse *pParse,   /* Parsing and code generating context */
+-  Table *pTab,     /* Description of the table we are reading from */
+-  int iColumn,     /* Index of the table column */
+-  int iTable,      /* The cursor pointing to the table */
+-  int iReg         /* Store results here */
+-){
+-  int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
+-  if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
+-}
+ 
+-
+ /*
+-** Clear all column cache entries.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
+-  int i;
+-
+-#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)
+-    ){
+-       pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+-    }
+-  }
+-  pParse->nColCache = 0;
+-}
+-
+-/*
+-** Record the fact that an affinity change has occurred on iCount
+-** registers starting with iStart.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
+-  sqlite3ExprCacheRemove(pParse, iStart, iCount);
+-}
+-
+-/*
+ ** Generate code to move content from registers iFrom...iFrom+nReg-1
+-** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
++** over to iTo..iTo+nReg-1.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
+   assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
+   sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
+-  sqlite3ExprCacheRemove(pParse, iFrom, nReg);
+ }
+ 
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
+ /*
+-** Return true if any register in the range iFrom..iTo (inclusive)
+-** is used as part of the column cache.
+-**
+-** This routine is used within assert() and testcase() macros only
+-** and does not appear in a normal build.
+-*/
+-static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
+-  int i;
+-  struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    int r = p->iReg;
+-    if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
+-  }
+-  return 0;
+-}
+-#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
+-
+-
+-/*
+ ** Convert a scalar expression node to a TK_REGISTER referencing
+ ** register iReg.  The caller must ensure that iReg already contains
+ ** the correct value for the expression.
+@@ -95055,6 +99475,7 @@
+     return 0;
+   }
+ 
++expr_code_doover:
+   if( pExpr==0 ){
+     op = TK_NULL;
+   }else{
+@@ -95076,6 +99497,28 @@
+     }
+     case TK_COLUMN: {
+       int iTab = pExpr->iTable;
++      if( ExprHasProperty(pExpr, EP_FixedCol) ){
++        /* This COLUMN expression is really a constant due to WHERE clause
++        ** constraints, and that constant is coded by the pExpr->pLeft
++        ** expresssion.  However, make sure the constant has the correct
++        ** datatype by applying the Affinity of the table column to the
++        ** constant.
++        */
++        int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
++        int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
++        if( aff!=SQLITE_AFF_BLOB ){
++          static const char zAff[] = "B\000C\000D\000E";
++          assert( SQLITE_AFF_BLOB=='A' );
++          assert( SQLITE_AFF_TEXT=='B' );
++          if( iReg!=target ){
++            sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
++            iReg = target;
++          }
++          sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
++                            &zAff[(aff-'B')*2], P4_STATIC);
++        }
++        return iReg;
++      }
+       if( iTab<0 ){
+         if( pParse->iSelfTab<0 ){
+           /* Generating CHECK constraints or inserting into partial index */
+@@ -95086,7 +99529,7 @@
+           iTab = pParse->iSelfTab - 1;
+         }
+       }
+-      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
++      return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
+                                pExpr->iColumn, iTab, target,
+                                pExpr->op2);
+     }
+@@ -95094,6 +99537,10 @@
+       codeInteger(pParse, pExpr, 0, target);
+       return target;
+     }
++    case TK_TRUEFALSE: {
++      sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target);
++      return target;
++    }
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+     case TK_FLOAT: {
+       assert( !ExprHasProperty(pExpr, EP_IntValue) );
+@@ -95152,8 +99599,6 @@
+       }
+       sqlite3VdbeAddOp2(v, OP_Cast, target,
+                         sqlite3AffinityType(pExpr->u.zToken, 0));
+-      testcase( usedAsColumnCache(pParse, inReg, inReg) );
+-      sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
+       return inReg;
+     }
+ #endif /* SQLITE_OMIT_CAST */
+@@ -95249,6 +99694,18 @@
+       sqlite3VdbeAddOp2(v, op, r1, inReg);
+       break;
+     }
++    case TK_TRUTH: {
++      int isTrue;    /* IS TRUE or IS NOT TRUE */
++      int bNormal;   /* IS TRUE or IS FALSE */
++      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
++      testcase( regFree1==0 );
++      isTrue = sqlite3ExprTruthValue(pExpr->pRight);
++      bNormal = pExpr->op2==TK_IS;
++      testcase( isTrue && bNormal);
++      testcase( !isTrue && bNormal);
++      sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal);
++      break;
++    }
+     case TK_ISNULL:
+     case TK_NOTNULL: {
+       int addr;
+@@ -95285,6 +99742,12 @@
+       u8 enc = ENC(db);      /* The text encoding used by this database */
+       CollSeq *pColl = 0;    /* A collating sequence */
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(pExpr, EP_WinFunc) ){
++        return pExpr->y.pWin->regResult;
++      }
++#endif
++
+       if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
+         /* SQL functions can be expensive. So try to move constant functions
+         ** out of the inner loop, even if that means an extra OP_Copy. */
+@@ -95321,10 +99784,7 @@
+         for(i=1; i<nFarg; i++){
+           sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
+           VdbeCoverage(v);
+-          sqlite3ExprCacheRemove(pParse, target, 1);
+-          sqlite3ExprCachePush(pParse);
+           sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
+-          sqlite3ExprCachePop(pParse);
+         }
+         sqlite3VdbeResolveLabel(v, endCoalesce);
+         break;
+@@ -95390,10 +99850,8 @@
+           }
+         }
+ 
+-        sqlite3ExprCachePush(pParse);     /* Ticket 2ea2425d34be */
+         sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
+                                 SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
+-        sqlite3ExprCachePop(pParse);      /* Ticket 2ea2425d34be */
+       }else{
+         r1 = 0;
+       }
+@@ -95410,7 +99868,7 @@
+       ** "glob(B,A).  We want to use the A in "A glob B" to test
+       ** for function overloading.  But we use the B term in "glob(B,A)".
+       */
+-      if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
++      if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
+         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
+       }else if( nFarg>0 ){
+         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
+@@ -95420,9 +99878,21 @@
+         if( !pColl ) pColl = db->pDfltColl; 
+         sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
+       }
+-      sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
+-                        constMask, r1, target, (char*)pDef, P4_FUNCDEF);
+-      sqlite3VdbeChangeP5(v, (u8)nFarg);
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
++      if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){
++        Expr *pArg = pFarg->a[0].pExpr;
++        if( pArg->op==TK_COLUMN ){
++          sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
++        }else{
++          sqlite3VdbeAddOp2(v, OP_Null, 0, target);
++        }
++      }else
++#endif
++      {
++        sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
++                          constMask, r1, target, (char*)pDef, P4_FUNCDEF);
++        sqlite3VdbeChangeP5(v, (u8)nFarg);
++      }
+       if( nFarg && constMask==0 ){
+         sqlite3ReleaseTempRange(pParse, r1, nFarg);
+       }
+@@ -95487,7 +99957,8 @@
+     case TK_SPAN:
+     case TK_COLLATE: 
+     case TK_UPLUS: {
+-      return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
++      pExpr = pExpr->pLeft;
++      goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
+     }
+ 
+     case TK_TRIGGER: {
+@@ -95516,7 +99987,7 @@
+       **   p1==1   ->    old.a         p1==4   ->    new.a
+       **   p1==2   ->    old.b         p1==5   ->    new.b       
+       */
+-      Table *pTab = pExpr->pTab;
++      Table *pTab = pExpr->y.pTab;
+       int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
+ 
+       assert( pExpr->iTable==0 || pExpr->iTable==1 );
+@@ -95525,10 +99996,9 @@
+       assert( p1>=0 && p1<(pTab->nCol*2+2) );
+ 
+       sqlite3VdbeAddOp2(v, OP_Param, p1, target);
+-      VdbeComment((v, "%s.%s -> $%d",
++      VdbeComment((v, "r[%d]=%s.%s", target,
+         (pExpr->iTable ? "new" : "old"),
+-        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
+-        target
++        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
+       ));
+ 
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+@@ -95554,9 +100024,7 @@
+     case TK_IF_NULL_ROW: {
+       int addrINR;
+       addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
+-      sqlite3ExprCachePush(pParse);
+       inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+-      sqlite3ExprCachePop(pParse);
+       sqlite3VdbeJumpHere(v, addrINR);
+       sqlite3VdbeChangeP3(v, addrINR, inReg);
+       break;
+@@ -95593,7 +100061,6 @@
+       Expr opCompare;                   /* The X==Ei expression */
+       Expr *pX;                         /* The X expression */
+       Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */
+-      VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
+ 
+       assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
+       assert(pExpr->x.pList->nExpr > 0);
+@@ -95617,7 +100084,6 @@
+         regFree1 = 0;
+       }
+       for(i=0; i<nExpr-1; i=i+2){
+-        sqlite3ExprCachePush(pParse);
+         if( pX ){
+           assert( pTest!=0 );
+           opCompare.pRight = aListelem[i].pExpr;
+@@ -95630,18 +100096,13 @@
+         testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
+         sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
+         sqlite3VdbeGoto(v, endLabel);
+-        sqlite3ExprCachePop(pParse);
+         sqlite3VdbeResolveLabel(v, nextCase);
+       }
+       if( (nExpr&1)!=0 ){
+-        sqlite3ExprCachePush(pParse);
+         sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
+-        sqlite3ExprCachePop(pParse);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+       }
+-      assert( pParse->db->mallocFailed || pParse->nErr>0 
+-           || pParse->iCacheLevel==iCacheLevel );
+       sqlite3VdbeResolveLabel(v, endLabel);
+       break;
+     }
+@@ -95791,7 +100252,7 @@
+ ** might choose to code the expression at initialization time.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
+-  if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
++  if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
+     sqlite3ExprCodeAtInit(pParse, pExpr, target);
+   }else{
+     sqlite3ExprCode(pParse, pExpr, target);
+@@ -95826,7 +100287,9 @@
+ ** Generate code that pushes the value of every element of the given
+ ** expression list into a sequence of registers beginning at target.
+ **
+-** Return the number of elements evaluated.
++** Return the number of elements evaluated.  The number returned will
++** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF
++** is defined.
+ **
+ ** The SQLITE_ECEL_DUP flag prevents the arguments from being
+ ** filled using OP_SCopy.  OP_Copy must be used instead.
+@@ -95837,6 +100300,8 @@
+ ** The SQLITE_ECEL_REF flag means that expressions in the list with
+ ** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
+ ** in registers at srcReg, and so the value can be copied from there.
++** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0
++** are simply omitted rather than being copied from srcReg.
+ */
+ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
+   Parse *pParse,     /* Parsing context */
+@@ -95856,6 +100321,12 @@
+   if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
+   for(pItem=pList->a, i=0; i<n; i++, pItem++){
+     Expr *pExpr = pItem->pExpr;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( pItem->bSorterRef ){
++      i--;
++      n--;
++    }else
++#endif
+     if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
+       if( flags & SQLITE_ECEL_OMITREF ){
+         i--;
+@@ -95863,7 +100334,9 @@
+       }else{
+         sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+       }
+-    }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
++    }else if( (flags & SQLITE_ECEL_FACTOR)!=0
++           && sqlite3ExprIsConstantNotJoin(pExpr)
++    ){
+       sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+     }else{
+       int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
+@@ -95989,18 +100462,14 @@
+       int d2 = sqlite3VdbeMakeLabel(v);
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+       sqlite3VdbeResolveLabel(v, d2);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_OR: {
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_NOT: {
+@@ -96008,6 +100477,23 @@
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+       break;
+     }
++    case TK_TRUTH: {
++      int isNot;      /* IS NOT TRUE or IS NOT FALSE */
++      int isTrue;     /* IS TRUE or IS NOT TRUE */
++      testcase( jumpIfNull==0 );
++      isNot = pExpr->op2==TK_ISNOT;
++      isTrue = sqlite3ExprTruthValue(pExpr->pRight);
++      testcase( isTrue && isNot );
++      testcase( !isTrue && isNot );
++      if( isTrue ^ isNot ){
++        sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
++                          isNot ? SQLITE_JUMPIFNULL : 0);
++      }else{
++        sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
++                           isNot ? SQLITE_JUMPIFNULL : 0);
++      }
++      break;
++    }
+     case TK_IS:
+     case TK_ISNOT:
+       testcase( op==TK_IS );
+@@ -96142,9 +100628,7 @@
+     case TK_AND: {
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_OR: {
+@@ -96151,10 +100635,8 @@
+       int d2 = sqlite3VdbeMakeLabel(v);
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+       sqlite3VdbeResolveLabel(v, d2);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_NOT: {
+@@ -96162,6 +100644,26 @@
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+       break;
+     }
++    case TK_TRUTH: {
++      int isNot;   /* IS NOT TRUE or IS NOT FALSE */
++      int isTrue;  /* IS TRUE or IS NOT TRUE */
++      testcase( jumpIfNull==0 );
++      isNot = pExpr->op2==TK_ISNOT;
++      isTrue = sqlite3ExprTruthValue(pExpr->pRight);
++      testcase( isTrue && isNot );
++      testcase( !isTrue && isNot );
++      if( isTrue ^ isNot ){
++        /* IS TRUE and IS NOT FALSE */
++        sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest,
++                           isNot ? 0 : SQLITE_JUMPIFNULL);
++
++      }else{
++        /* IS FALSE and IS NOT TRUE */
++        sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest,
++                          isNot ? 0 : SQLITE_JUMPIFNULL);
++      }
++      break;
++    }
+     case TK_IS:
+     case TK_ISNOT:
+       testcase( pExpr->op==TK_IS );
+@@ -96347,17 +100849,35 @@
+   if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
+     if( pA->op==TK_FUNCTION ){
+       if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      /* Justification for the assert():
++      ** window functions have p->op==TK_FUNCTION but aggregate functions
++      ** have p->op==TK_AGG_FUNCTION.  So any comparison between an aggregate
++      ** function and a window function should have failed before reaching
++      ** this point.  And, it is not possible to have a window function and
++      ** a scalar function with the same name and number of arguments.  So
++      ** if we reach this point, either A and B both window functions or
++      ** neither are a window functions. */
++      assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
++      if( ExprHasProperty(pA,EP_WinFunc) ){
++        if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
++      }
++#endif
++    }else if( pA->op==TK_COLLATE ){
++      if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+     }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+-      return pA->op==TK_COLLATE ? 1 : 2;
++      return 2;
+     }
+   }
+   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
+   if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+     if( combinedFlags & EP_xIsSelect ) return 2;
+-    if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
++    if( (combinedFlags & EP_FixedCol)==0
++     && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
+     if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
+     if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+-    if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
++    assert( (combinedFlags & EP_Reduced)==0 );
++    if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
+       if( pA->iColumn!=pB->iColumn ) return 2;
+       if( pA->iTable!=pB->iTable 
+        && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+@@ -96450,6 +100970,102 @@
+ }
+ 
+ /*
++** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
++** If the expression node requires that the table at pWalker->iCur
++** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
++**
++** This routine controls an optimization.  False positives (setting
++** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
++** (never setting pWalker->eCode) is a harmless missed optimization.
++*/
++static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
++  testcase( pExpr->op==TK_AGG_COLUMN );
++  testcase( pExpr->op==TK_AGG_FUNCTION );
++  if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
++  switch( pExpr->op ){
++    case TK_ISNOT:
++    case TK_NOT:
++    case TK_ISNULL:
++    case TK_IS:
++    case TK_OR:
++    case TK_CASE:
++    case TK_IN:
++    case TK_FUNCTION:
++      testcase( pExpr->op==TK_ISNOT );
++      testcase( pExpr->op==TK_NOT );
++      testcase( pExpr->op==TK_ISNULL );
++      testcase( pExpr->op==TK_IS );
++      testcase( pExpr->op==TK_OR );
++      testcase( pExpr->op==TK_CASE );
++      testcase( pExpr->op==TK_IN );
++      testcase( pExpr->op==TK_FUNCTION );
++      return WRC_Prune;
++    case TK_COLUMN:
++      if( pWalker->u.iCur==pExpr->iTable ){
++        pWalker->eCode = 1;
++        return WRC_Abort;
++      }
++      return WRC_Prune;
++
++    /* Virtual tables are allowed to use constraints like x=NULL.  So
++    ** a term of the form x=y does not prove that y is not null if x
++    ** is the column of a virtual table */
++    case TK_EQ:
++    case TK_NE:
++    case TK_LT:
++    case TK_LE:
++    case TK_GT:
++    case TK_GE:
++      testcase( pExpr->op==TK_EQ );
++      testcase( pExpr->op==TK_NE );
++      testcase( pExpr->op==TK_LT );
++      testcase( pExpr->op==TK_LE );
++      testcase( pExpr->op==TK_GT );
++      testcase( pExpr->op==TK_GE );
++      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
++       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
++      ){
++       return WRC_Prune;
++      }
++    default:
++      return WRC_Continue;
++  }
++}
++
++/*
++** Return true (non-zero) if expression p can only be true if at least
++** one column of table iTab is non-null.  In other words, return true
++** if expression p will always be NULL or false if every column of iTab
++** is NULL.
++**
++** False negatives are acceptable.  In other words, it is ok to return
++** zero even if expression p will never be true of every column of iTab
++** is NULL.  A false negative is merely a missed optimization opportunity.
++**
++** False positives are not allowed, however.  A false positive may result
++** in an incorrect answer.
++**
++** Terms of p that are marked with EP_FromJoin (and hence that come from
++** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
++**
++** This routine is used to check if a LEFT JOIN can be converted into
++** an ordinary JOIN.  The p argument is the WHERE clause.  If the WHERE
++** clause requires that some column of the right table of the LEFT JOIN
++** be non-NULL, then the LEFT JOIN can be safely converted into an
++** ordinary join.
++*/
++SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
++  Walker w;
++  w.xExprCallback = impliesNotNullRow;
++  w.xSelectCallback = 0;
++  w.xSelectCallback2 = 0;
++  w.eCode = 0;
++  w.u.iCur = iTab;
++  sqlite3WalkExpr(&w, p);
++  return w.eCode;
++}
++
++/*
+ ** An instance of the following structure is used by the tree walker
+ ** to determine if an expression can be evaluated by reference to the
+ ** index only, without having to do a search for the corresponding
+@@ -96604,8 +101220,9 @@
+   NameContext *pNC = pWalker->u.pNC;
+   Parse *pParse = pNC->pParse;
+   SrcList *pSrcList = pNC->pSrcList;
+-  AggInfo *pAggInfo = pNC->pAggInfo;
++  AggInfo *pAggInfo = pNC->uNC.pAggInfo;
+ 
++  assert( pNC->ncFlags & NC_UAggInfo );
+   switch( pExpr->op ){
+     case TK_AGG_COLUMN:
+     case TK_COLUMN: {
+@@ -96637,7 +101254,7 @@
+              && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 
+             ){
+               pCol = &pAggInfo->aCol[k];
+-              pCol->pTab = pExpr->pTab;
++              pCol->pTab = pExpr->y.pTab;
+               pCol->iTable = pExpr->iTable;
+               pCol->iColumn = pExpr->iColumn;
+               pCol->iMem = ++pParse->nMem;
+@@ -96783,21 +101400,9 @@
+ /*
+ ** Deallocate a register, making available for reuse for some other
+ ** purpose.
+-**
+-** If a register is currently being used by the column cache, then
+-** the deallocation is deferred until the column cache line that uses
+-** the register becomes stale.
+ */
+ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
+   if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+-    int i;
+-    struct yColCache *p;
+-    for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-      if( p->iReg==iReg ){
+-        p->tempReg = 1;
+-        return;
+-      }
+-    }
+     pParse->aTempReg[pParse->nTempReg++] = iReg;
+   }
+ }
+@@ -96811,7 +101416,6 @@
+   i = pParse->iRangeReg;
+   n = pParse->nRangeReg;
+   if( nReg<=n ){
+-    assert( !usedAsColumnCache(pParse, i, i+n-1) );
+     pParse->iRangeReg += nReg;
+     pParse->nRangeReg -= nReg;
+   }else{
+@@ -96825,7 +101429,6 @@
+     sqlite3ReleaseTempReg(pParse, iReg);
+     return;
+   }
+-  sqlite3ExprCacheRemove(pParse, iReg, nReg);
+   if( nReg>pParse->nRangeReg ){
+     pParse->nRangeReg = nReg;
+     pParse->iRangeReg = iReg;
+@@ -96887,369 +101490,66 @@
+ */
+ #ifndef SQLITE_OMIT_ALTERTABLE
+ 
+-
+ /*
+-** This function is used by SQL generated to implement the 
+-** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
+-** CREATE INDEX command. The second is a table name. The table name in 
+-** the CREATE TABLE or CREATE INDEX statement is replaced with the third
+-** argument and the result returned. Examples:
++** Parameter zName is the name of a table that is about to be altered
++** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
++** If the table is a system table, this function leaves an error message
++** in pParse->zErr (system tables may not be altered) and returns non-zero.
+ **
+-** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
+-**     -> 'CREATE TABLE def(a, b, c)'
+-**
+-** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
+-**     -> 'CREATE INDEX i ON def(a, b, c)'
++** Or, if zName is not a system table, zero is returned.
+ */
+-static void renameTableFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  unsigned char const *zSql = sqlite3_value_text(argv[0]);
+-  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+-
+-  int token;
+-  Token tname;
+-  unsigned char const *zCsr = zSql;
+-  int len = 0;
+-  char *zRet;
+-
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-
+-  UNUSED_PARAMETER(NotUsed);
+-
+-  /* The principle used to locate the table name in the CREATE TABLE 
+-  ** statement is that the table name is the first non-space token that
+-  ** is immediately followed by a TK_LP or TK_USING token.
+-  */
+-  if( zSql ){
+-    do {
+-      if( !*zCsr ){
+-        /* Ran out of input before finding an opening bracket. Return NULL. */
+-        return;
+-      }
+-
+-      /* Store the token that zCsr points to in tname. */
+-      tname.z = (char*)zCsr;
+-      tname.n = len;
+-
+-      /* Advance zCsr to the next token. Store that token type in 'token',
+-      ** and its length in 'len' (to be used next iteration of this loop).
+-      */
+-      do {
+-        zCsr += len;
+-        len = sqlite3GetToken(zCsr, &token);
+-      } while( token==TK_SPACE );
+-      assert( len>0 );
+-    } while( token!=TK_LP && token!=TK_USING );
+-
+-    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+-       zSql, zTableName, tname.z+tname.n);
+-    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
++static int isSystemTable(Parse *pParse, const char *zName){
++  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
++    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
++    return 1;
+   }
++  return 0;
+ }
+ 
+ /*
+-** This C function implements an SQL user function that is used by SQL code
+-** generated by the ALTER TABLE ... RENAME command to modify the definition
+-** of any foreign key constraints that use the table being renamed as the 
+-** parent table. It is passed three arguments:
+-**
+-**   1) The complete text of the CREATE TABLE statement being modified,
+-**   2) The old name of the table being renamed, and
+-**   3) The new name of the table being renamed.
+-**
+-** It returns the new CREATE TABLE statement. For example:
+-**
+-**   sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
+-**       -> 'CREATE TABLE t1(a REFERENCES t3)'
++** Generate code to verify that the schemas of database zDb and, if
++** bTemp is not true, database "temp", can still be parsed. This is
++** called at the end of the generation of an ALTER TABLE ... RENAME ...
++** statement to ensure that the operation has not rendered any schema
++** objects unusable.
+ */
+-#ifndef SQLITE_OMIT_FOREIGN_KEY
+-static void renameParentFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-  char *zOutput = 0;
+-  char *zResult;
+-  unsigned char const *zInput = sqlite3_value_text(argv[0]);
+-  unsigned char const *zOld = sqlite3_value_text(argv[1]);
+-  unsigned char const *zNew = sqlite3_value_text(argv[2]);
++static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
++  sqlite3NestedParse(pParse, 
++      "SELECT 1 "
++      "FROM \"%w\".%s "
++      "WHERE name NOT LIKE 'sqlite_%%'"
++      " AND sql NOT LIKE 'create virtual%%'"
++      " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
++      zDb, MASTER_NAME, 
++      zDb, bTemp
++  );
+ 
+-  unsigned const char *z;         /* Pointer to token */
+-  int n;                          /* Length of token z */
+-  int token;                      /* Type of token */
+-
+-  UNUSED_PARAMETER(NotUsed);
+-  if( zInput==0 || zOld==0 ) return;
+-  for(z=zInput; *z; z=z+n){
+-    n = sqlite3GetToken(z, &token);
+-    if( token==TK_REFERENCES ){
+-      char *zParent;
+-      do {
+-        z += n;
+-        n = sqlite3GetToken(z, &token);
+-      }while( token==TK_SPACE );
+-
+-      if( token==TK_ILLEGAL ) break;
+-      zParent = sqlite3DbStrNDup(db, (const char *)z, n);
+-      if( zParent==0 ) break;
+-      sqlite3Dequote(zParent);
+-      if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
+-        char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", 
+-            (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
+-        );
+-        sqlite3DbFree(db, zOutput);
+-        zOutput = zOut;
+-        zInput = &z[n];
+-      }
+-      sqlite3DbFree(db, zParent);
+-    }
++  if( bTemp==0 ){
++    sqlite3NestedParse(pParse, 
++        "SELECT 1 "
++        "FROM temp.%s "
++        "WHERE name NOT LIKE 'sqlite_%%'"
++        " AND sql NOT LIKE 'create virtual%%'"
++        " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
++        MASTER_NAME, zDb 
++    );
+   }
+-
+-  zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), 
+-  sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
+-  sqlite3DbFree(db, zOutput);
+ }
+-#endif
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
+-/* This function is used by SQL generated to implement the
+-** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
+-** statement. The second is a table name. The table name in the CREATE 
+-** TRIGGER statement is replaced with the third argument and the result 
+-** returned. This is analagous to renameTableFunc() above, except for CREATE
+-** TRIGGER, not CREATE INDEX and CREATE TABLE.
+-*/
+-static void renameTriggerFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  unsigned char const *zSql = sqlite3_value_text(argv[0]);
+-  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+-
+-  int token;
+-  Token tname;
+-  int dist = 3;
+-  unsigned char const *zCsr = zSql;
+-  int len = 0;
+-  char *zRet;
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-
+-  UNUSED_PARAMETER(NotUsed);
+-
+-  /* The principle used to locate the table name in the CREATE TRIGGER 
+-  ** statement is that the table name is the first token that is immediately
+-  ** preceded by either TK_ON or TK_DOT and immediately followed by one
+-  ** of TK_WHEN, TK_BEGIN or TK_FOR.
+-  */
+-  if( zSql ){
+-    do {
+-
+-      if( !*zCsr ){
+-        /* Ran out of input before finding the table name. Return NULL. */
+-        return;
+-      }
+-
+-      /* Store the token that zCsr points to in tname. */
+-      tname.z = (char*)zCsr;
+-      tname.n = len;
+-
+-      /* Advance zCsr to the next token. Store that token type in 'token',
+-      ** and its length in 'len' (to be used next iteration of this loop).
+-      */
+-      do {
+-        zCsr += len;
+-        len = sqlite3GetToken(zCsr, &token);
+-      }while( token==TK_SPACE );
+-      assert( len>0 );
+-
+-      /* Variable 'dist' stores the number of tokens read since the most
+-      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
+-      ** token is read and 'dist' equals 2, the condition stated above
+-      ** to be met.
+-      **
+-      ** Note that ON cannot be a database, table or column name, so
+-      ** there is no need to worry about syntax like 
+-      ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
+-      */
+-      dist++;
+-      if( token==TK_DOT || token==TK_ON ){
+-        dist = 0;
+-      }
+-    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
+-
+-    /* Variable tname now contains the token that is the old table-name
+-    ** in the CREATE TRIGGER statement.
+-    */
+-    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+-       zSql, zTableName, tname.z+tname.n);
+-    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
+-  }
+-}
+-#endif   /* !SQLITE_OMIT_TRIGGER */
+-
+ /*
+-** Register built-in functions used to help implement ALTER TABLE
++** Generate code to reload the schema for database iDb. And, if iDb!=1, for
++** the temp database as well.
+ */
+-SQLITE_PRIVATE void sqlite3AlterFunctions(void){
+-  static FuncDef aAlterTableFuncs[] = {
+-    FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
+-#ifndef SQLITE_OMIT_TRIGGER
+-    FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
+-#endif
+-#ifndef SQLITE_OMIT_FOREIGN_KEY
+-    FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
+-#endif
+-  };
+-  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
+-}
+-
+-/*
+-** This function is used to create the text of expressions of the form:
+-**
+-**   name=<constant1> OR name=<constant2> OR ...
+-**
+-** If argument zWhere is NULL, then a pointer string containing the text 
+-** "name=<constant>" is returned, where <constant> is the quoted version
+-** of the string passed as argument zConstant. The returned buffer is
+-** allocated using sqlite3DbMalloc(). It is the responsibility of the
+-** caller to ensure that it is eventually freed.
+-**
+-** If argument zWhere is not NULL, then the string returned is 
+-** "<where> OR name=<constant>", where <where> is the contents of zWhere.
+-** In this case zWhere is passed to sqlite3DbFree() before returning.
+-** 
+-*/
+-static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
+-  char *zNew;
+-  if( !zWhere ){
+-    zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
+-  }else{
+-    zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
+-    sqlite3DbFree(db, zWhere);
++static void renameReloadSchema(Parse *pParse, int iDb){
++  Vdbe *v = pParse->pVdbe;
++  if( v ){
++    sqlite3ChangeCookie(pParse, iDb);
++    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0);
++    if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0);
+   }
+-  return zNew;
+ }
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ /*
+-** Generate the text of a WHERE expression which can be used to select all
+-** tables that have foreign key constraints that refer to table pTab (i.e.
+-** constraints for which pTab is the parent table) from the sqlite_master
+-** table.
+-*/
+-static char *whereForeignKeys(Parse *pParse, Table *pTab){
+-  FKey *p;
+-  char *zWhere = 0;
+-  for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+-    zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
+-  }
+-  return zWhere;
+-}
+-#endif
+-
+-/*
+-** Generate the text of a WHERE expression which can be used to select all
+-** temporary triggers on table pTab from the sqlite_temp_master table. If
+-** table pTab has no temporary triggers, or is itself stored in the 
+-** temporary database, NULL is returned.
+-*/
+-static char *whereTempTriggers(Parse *pParse, Table *pTab){
+-  Trigger *pTrig;
+-  char *zWhere = 0;
+-  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
+-
+-  /* If the table is not located in the temp-db (in which case NULL is 
+-  ** returned, loop through the tables list of triggers. For each trigger
+-  ** that is not part of the temp-db schema, add a clause to the WHERE 
+-  ** expression being built up in zWhere.
+-  */
+-  if( pTab->pSchema!=pTempSchema ){
+-    sqlite3 *db = pParse->db;
+-    for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
+-      if( pTrig->pSchema==pTempSchema ){
+-        zWhere = whereOrName(db, zWhere, pTrig->zName);
+-      }
+-    }
+-  }
+-  if( zWhere ){
+-    char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
+-    sqlite3DbFree(pParse->db, zWhere);
+-    zWhere = zNew;
+-  }
+-  return zWhere;
+-}
+-
+-/*
+-** Generate code to drop and reload the internal representation of table
+-** pTab from the database, including triggers and temporary triggers.
+-** Argument zName is the name of the table in the database schema at
+-** the time the generated code is executed. This can be different from
+-** pTab->zName if this function is being called to code part of an 
+-** "ALTER TABLE RENAME TO" statement.
+-*/
+-static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
+-  Vdbe *v;
+-  char *zWhere;
+-  int iDb;                   /* Index of database containing pTab */
+-#ifndef SQLITE_OMIT_TRIGGER
+-  Trigger *pTrig;
+-#endif
+-
+-  v = sqlite3GetVdbe(pParse);
+-  if( NEVER(v==0) ) return;
+-  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
+-  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+-  assert( iDb>=0 );
+-
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* Drop any table triggers from the internal schema. */
+-  for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
+-    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
+-    assert( iTrigDb==iDb || iTrigDb==1 );
+-    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
+-  }
+-#endif
+-
+-  /* Drop the table and index from the internal schema.  */
+-  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
+-
+-  /* Reload the table, index and permanent trigger schemas. */
+-  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
+-  if( !zWhere ) return;
+-  sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
+-
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* Now, if the table is not stored in the temp database, reload any temp 
+-  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
+-  */
+-  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
+-    sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
+-  }
+-#endif
+-}
+-
+-/*
+-** Parameter zName is the name of a table that is about to be altered
+-** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
+-** If the table is a system table, this function leaves an error message
+-** in pParse->zErr (system tables may not be altered) and returns non-zero.
+-**
+-** Or, if zName is not a system table, zero is returned.
+-*/
+-static int isSystemTable(Parse *pParse, const char *zName){
+-  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+-    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+-    return 1;
+-  }
+-  return 0;
+-}
+-
+-/*
+ ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
+ ** command. 
+ */
+@@ -97266,13 +101566,10 @@
+   int nTabName;             /* Number of UTF-8 characters in zTabName */
+   const char *zTabName;     /* Original name of the table */
+   Vdbe *v;
+-#ifndef SQLITE_OMIT_TRIGGER
+-  char *zWhere = 0;         /* Where clause to locate temp triggers */
+-#endif
+   VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */
+-  int savedDbFlags;         /* Saved value of db->flags */
++  u32 savedDbFlags;         /* Saved value of db->mDbFlags */
+ 
+-  savedDbFlags = db->flags;  
++  savedDbFlags = db->mDbFlags;  
+   if( NEVER(db->mallocFailed) ) goto exit_rename_table;
+   assert( pSrc->nSrc==1 );
+   assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
+@@ -97281,7 +101578,7 @@
+   if( !pTab ) goto exit_rename_table;
+   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+   zDb = db->aDb[iDb].zDbSName;
+-  db->flags |= SQLITE_PreferBuiltin;
++  db->mDbFlags |= DBFLAG_PreferBuiltin;
+ 
+   /* Get a NULL terminated version of the new table name. */
+   zName = sqlite3NameFromToken(db, pName);
+@@ -97341,52 +101638,25 @@
+   if( v==0 ){
+     goto exit_rename_table;
+   }
+-  sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
+-  sqlite3ChangeCookie(pParse, iDb);
+ 
+-  /* If this is a virtual table, invoke the xRename() function if
+-  ** one is defined. The xRename() callback will modify the names
+-  ** of any resources used by the v-table implementation (including other
+-  ** SQLite tables) that are identified by the name of the virtual table.
+-  */
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if( pVTab ){
+-    int i = ++pParse->nMem;
+-    sqlite3VdbeLoadString(v, i, zName);
+-    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
+-    sqlite3MayAbort(pParse);
+-  }
+-#endif
+-
+   /* figure out how many UTF-8 characters are in zName */
+   zTabName = pTab->zName;
+   nTabName = sqlite3Utf8CharLen(zTabName, -1);
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  if( db->flags&SQLITE_ForeignKeys ){
+-    /* If foreign-key support is enabled, rewrite the CREATE TABLE 
+-    ** statements corresponding to all child tables of foreign key constraints
+-    ** for which the renamed table is the parent table.  */
+-    if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
+-      sqlite3NestedParse(pParse, 
+-          "UPDATE \"%w\".%s SET "
+-              "sql = sqlite_rename_parent(sql, %Q, %Q) "
+-              "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere);
+-      sqlite3DbFree(db, zWhere);
+-    }
+-  }
+-#endif
++  /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
++  ** the schema to use the new table name.  */
++  sqlite3NestedParse(pParse, 
++      "UPDATE \"%w\".%s SET "
++      "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
++      "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
++      "AND   name NOT LIKE 'sqlite_%%'"
++      , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
++  );
+ 
+-  /* Modify the sqlite_master table to use the new table name. */
++  /* Update the tbl_name and name columns of the sqlite_master table
++  ** as required.  */
+   sqlite3NestedParse(pParse,
+       "UPDATE %Q.%s SET "
+-#ifdef SQLITE_OMIT_TRIGGER
+-          "sql = sqlite_rename_table(sql, %Q), "
+-#else
+-          "sql = CASE "
+-            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
+-            "ELSE sqlite_rename_table(sql, %Q) END, "
+-#endif
+           "tbl_name = %Q, "
+           "name = CASE "
+             "WHEN type='table' THEN %Q "
+@@ -97395,11 +101665,9 @@
+             "ELSE name END "
+       "WHERE tbl_name=%Q COLLATE nocase AND "
+           "(type='table' OR type='index' OR type='trigger');", 
+-      zDb, MASTER_NAME, zName, zName, zName, 
+-#ifndef SQLITE_OMIT_TRIGGER
+-      zName,
+-#endif
+-      zName, nTabName, zTabName
++      zDb, MASTER_NAME, 
++      zName, zName, zName, 
++      nTabName, zTabName
+   );
+ 
+ #ifndef SQLITE_OMIT_AUTOINCREMENT
+@@ -97413,40 +101681,42 @@
+   }
+ #endif
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
+-  ** table. Don't do this if the table being ALTERed is itself located in
+-  ** the temp database.
+-  */
+-  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
++  /* If the table being renamed is not itself part of the temp database,
++  ** edit view and trigger definitions within the temp database 
++  ** as required.  */
++  if( iDb!=1 ){
+     sqlite3NestedParse(pParse, 
+         "UPDATE sqlite_temp_master SET "
+-            "sql = sqlite_rename_trigger(sql, %Q), "
+-            "tbl_name = %Q "
+-            "WHERE %s;", zName, zName, zWhere);
+-    sqlite3DbFree(db, zWhere);
++            "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
++            "tbl_name = "
++              "CASE WHEN tbl_name=%Q COLLATE nocase AND "
++              "          sqlite_rename_test(%Q, sql, type, name, 1) "
++              "THEN %Q ELSE tbl_name END "
++            "WHERE type IN ('view', 'trigger')"
++        , zDb, zTabName, zName, zTabName, zDb, zName);
+   }
+-#endif
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  if( db->flags&SQLITE_ForeignKeys ){
+-    FKey *p;
+-    for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+-      Table *pFrom = p->pFrom;
+-      if( pFrom!=pTab ){
+-        reloadTableSchema(pParse, p->pFrom, pFrom->zName);
+-      }
+-    }
++  /* If this is a virtual table, invoke the xRename() function if
++  ** one is defined. The xRename() callback will modify the names
++  ** of any resources used by the v-table implementation (including other
++  ** SQLite tables) that are identified by the name of the virtual table.
++  */
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( pVTab ){
++    int i = ++pParse->nMem;
++    sqlite3VdbeLoadString(v, i, zName);
++    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
++    sqlite3MayAbort(pParse);
+   }
+ #endif
+ 
+-  /* Drop and reload the internal table schema. */
+-  reloadTableSchema(pParse, pTab, zName);
++  renameReloadSchema(pParse, iDb);
++  renameTestSchema(pParse, zDb, iDb==1);
+ 
+ exit_rename_table:
+   sqlite3SrcListDelete(db, pSrc);
+   sqlite3DbFree(db, zName);
+-  db->flags = savedDbFlags;
++  db->mDbFlags = savedDbFlags;
+ }
+ 
+ /*
+@@ -97467,12 +101737,11 @@
+   Column *pCol;             /* The new column */
+   Expr *pDflt;              /* Default value for the new column */
+   sqlite3 *db;              /* The database connection; */
+-  Vdbe *v = pParse->pVdbe;  /* The prepared statement under construction */
++  Vdbe *v;                  /* The prepared statement under construction */
+   int r1;                   /* Temporary registers */
+ 
+   db = pParse->db;
+   if( pParse->nErr || db->mallocFailed ) return;
+-  assert( v!=0 );
+   pNew = pParse->pNewTable;
+   assert( pNew );
+ 
+@@ -97547,11 +101816,11 @@
+   zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
+   if( zCol ){
+     char *zEnd = &zCol[pColDef->n-1];
+-    int savedDbFlags = db->flags;
++    u32 savedDbFlags = db->mDbFlags;
+     while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
+       *zEnd-- = '\0';
+     }
+-    db->flags |= SQLITE_PreferBuiltin;
++    db->mDbFlags |= DBFLAG_PreferBuiltin;
+     sqlite3NestedParse(pParse, 
+         "UPDATE \"%w\".%s SET "
+           "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
+@@ -97560,7 +101829,7 @@
+       zTab
+     );
+     sqlite3DbFree(db, zCol);
+-    db->flags = savedDbFlags;
++    db->mDbFlags = savedDbFlags;
+   }
+ 
+   /* Make sure the schema version is at least 3.  But do not upgrade
+@@ -97567,17 +101836,20 @@
+   ** from less than 3 to 4, as that will corrupt any preexisting DESC
+   ** index.
+   */
+-  r1 = sqlite3GetTempReg(pParse);
+-  sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+-  sqlite3VdbeUsesBtree(v, iDb);
+-  sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
+-  sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
+-  VdbeCoverage(v);
+-  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
+-  sqlite3ReleaseTempReg(pParse, r1);
++  v = sqlite3GetVdbe(pParse);
++  if( v ){
++    r1 = sqlite3GetTempReg(pParse);
++    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
++    sqlite3VdbeUsesBtree(v, iDb);
++    sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
++    sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
++    sqlite3ReleaseTempReg(pParse, r1);
++  }
+ 
+-  /* Reload the schema of the modified table. */
+-  reloadTableSchema(pParse, pTab, pTab->zName);
++  /* Reload the table definition */
++  renameReloadSchema(pParse, iDb);
+ }
+ 
+ /*
+@@ -97598,7 +101870,6 @@
+ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
+   Table *pNew;
+   Table *pTab;
+-  Vdbe *v;
+   int iDb;
+   int i;
+   int nAlloc;
+@@ -97662,16 +101933,1146 @@
+   pNew->addColOffset = pTab->addColOffset;
+   pNew->nTabRef = 1;
+ 
+-  /* Begin a transaction and increment the schema cookie.  */
+-  sqlite3BeginWriteOperation(pParse, 0, iDb);
+-  v = sqlite3GetVdbe(pParse);
+-  if( !v ) goto exit_begin_add_column;
+-  sqlite3ChangeCookie(pParse, iDb);
+-
+ exit_begin_add_column:
+   sqlite3SrcListDelete(db, pSrc);
+   return;
+ }
++
++/*
++** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN
++** command. This function checks if the table is a view or virtual
++** table (columns of views or virtual tables may not be renamed). If so,
++** it loads an error message into pParse and returns non-zero.
++**
++** Or, if pTab is not a view or virtual table, zero is returned.
++*/
++#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
++static int isRealTable(Parse *pParse, Table *pTab){
++  const char *zType = 0;
++#ifndef SQLITE_OMIT_VIEW
++  if( pTab->pSelect ){
++    zType = "view";
++  }
++#endif
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( IsVirtual(pTab) ){
++    zType = "virtual table";
++  }
++#endif
++  if( zType ){
++    sqlite3ErrorMsg(
++        pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName
++    );
++    return 1;
++  }
++  return 0;
++}
++#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
++# define isRealTable(x,y) (0)
++#endif
++
++/*
++** Handles the following parser reduction:
++**
++**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
++*/
++SQLITE_PRIVATE void sqlite3AlterRenameColumn(
++  Parse *pParse,                  /* Parsing context */
++  SrcList *pSrc,                  /* Table being altered.  pSrc->nSrc==1 */
++  Token *pOld,                    /* Name of column being changed */
++  Token *pNew                     /* New column name */
++){
++  sqlite3 *db = pParse->db;       /* Database connection */
++  Table *pTab;                    /* Table being updated */
++  int iCol;                       /* Index of column being renamed */
++  char *zOld = 0;                 /* Old column name */
++  char *zNew = 0;                 /* New column name */
++  const char *zDb;                /* Name of schema containing the table */
++  int iSchema;                    /* Index of the schema */
++  int bQuote;                     /* True to quote the new name */
++
++  /* Locate the table to be altered */
++  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
++  if( !pTab ) goto exit_rename_column;
++
++  /* Cannot alter a system table */
++  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
++  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
++
++  /* Which schema holds the table to be altered */  
++  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
++  assert( iSchema>=0 );
++  zDb = db->aDb[iSchema].zDbSName;
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  /* Invoke the authorization callback. */
++  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
++    goto exit_rename_column;
++  }
++#endif
++
++  /* Make sure the old name really is a column name in the table to be
++  ** altered.  Set iCol to be the index of the column being renamed */
++  zOld = sqlite3NameFromToken(db, pOld);
++  if( !zOld ) goto exit_rename_column;
++  for(iCol=0; iCol<pTab->nCol; iCol++){
++    if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break;
++  }
++  if( iCol==pTab->nCol ){
++    sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
++    goto exit_rename_column;
++  }
++
++  /* Do the rename operation using a recursive UPDATE statement that
++  ** uses the sqlite_rename_column() SQL function to compute the new
++  ** CREATE statement text for the sqlite_master table.
++  */
++  zNew = sqlite3NameFromToken(db, pNew);
++  if( !zNew ) goto exit_rename_column;
++  assert( pNew->n>0 );
++  bQuote = sqlite3Isquote(pNew->z[0]);
++  sqlite3NestedParse(pParse, 
++      "UPDATE \"%w\".%s SET "
++      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
++      "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
++      " AND sql NOT LIKE 'create virtual%%'",
++      zDb, MASTER_NAME, 
++      zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
++      pTab->zName
++  );
++
++  sqlite3NestedParse(pParse, 
++      "UPDATE temp.%s SET "
++      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
++      "WHERE type IN ('trigger', 'view')",
++      MASTER_NAME, 
++      zDb, pTab->zName, iCol, zNew, bQuote
++  );
++
++  /* Drop and reload the database schema. */
++  renameReloadSchema(pParse, iSchema);
++  renameTestSchema(pParse, zDb, iSchema==1);
++
++ exit_rename_column:
++  sqlite3SrcListDelete(db, pSrc);
++  sqlite3DbFree(db, zOld);
++  sqlite3DbFree(db, zNew);
++  return;
++}
++
++/*
++** Each RenameToken object maps an element of the parse tree into
++** the token that generated that element.  The parse tree element
++** might be one of:
++**
++**     *  A pointer to an Expr that represents an ID
++**     *  The name of a table column in Column.zName
++**
++** A list of RenameToken objects can be constructed during parsing.
++** Each new object is created by sqlite3RenameTokenMap().
++** As the parse tree is transformed, the sqlite3RenameTokenRemap()
++** routine is used to keep the mapping current.
++**
++** After the parse finishes, renameTokenFind() routine can be used
++** to look up the actual token value that created some element in
++** the parse tree.
++*/
++struct RenameToken {
++  void *p;               /* Parse tree element created by token t */
++  Token t;               /* The token that created parse tree element p */
++  RenameToken *pNext;    /* Next is a list of all RenameToken objects */
++};
++
++/*
++** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
++** down into the Walker.
++*/
++typedef struct RenameCtx RenameCtx;
++struct RenameCtx {
++  RenameToken *pList;             /* List of tokens to overwrite */
++  int nList;                      /* Number of tokens in pList */
++  int iCol;                       /* Index of column being renamed */
++  Table *pTab;                    /* Table being ALTERed */ 
++  const char *zOld;               /* Old column name */
++};
++
++#ifdef SQLITE_DEBUG
++/*
++** This function is only for debugging. It performs two tasks:
++**
++**   1. Checks that pointer pPtr does not already appear in the 
++**      rename-token list.
++**
++**   2. Dereferences each pointer in the rename-token list.
++**
++** The second is most effective when debugging under valgrind or
++** address-sanitizer or similar. If any of these pointers no longer 
++** point to valid objects, an exception is raised by the memory-checking 
++** tool.
++**
++** The point of this is to prevent comparisons of invalid pointer values.
++** Even though this always seems to work, it is undefined according to the
++** C standard. Example of undefined comparison:
++**
++**     sqlite3_free(x);
++**     if( x==y ) ...
++**
++** Technically, as x no longer points into a valid object or to the byte
++** following a valid object, it may not be used in comparison operations.
++*/
++static void renameTokenCheckAll(Parse *pParse, void *pPtr){
++  if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
++    RenameToken *p;
++    u8 i = 0;
++    for(p=pParse->pRename; p; p=p->pNext){
++      if( p->p ){
++        assert( p->p!=pPtr );
++        i += *(u8*)(p->p);
++      }
++    }
++  }
++}
++#else
++# define renameTokenCheckAll(x,y)
++#endif
++
++/*
++** Remember that the parser tree element pPtr was created using
++** the token pToken.
++**
++** In other words, construct a new RenameToken object and add it
++** to the list of RenameToken objects currently being built up
++** in pParse->pRename.
++**
++** The pPtr argument is returned so that this routine can be used
++** with tail recursion in tokenExpr() routine, for a small performance
++** improvement.
++*/
++SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
++  RenameToken *pNew;
++  assert( pPtr || pParse->db->mallocFailed );
++  renameTokenCheckAll(pParse, pPtr);
++  pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
++  if( pNew ){
++    pNew->p = pPtr;
++    pNew->t = *pToken;
++    pNew->pNext = pParse->pRename;
++    pParse->pRename = pNew;
++  }
++
++  return pPtr;
++}
++
++/*
++** It is assumed that there is already a RenameToken object associated
++** with parse tree element pFrom. This function remaps the associated token
++** to parse tree element pTo.
++*/
++SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){
++  RenameToken *p;
++  renameTokenCheckAll(pParse, pTo);
++  for(p=pParse->pRename; p; p=p->pNext){
++    if( p->p==pFrom ){
++      p->p = pTo;
++      break;
++    }
++  }
++}
++
++/*
++** Walker callback used by sqlite3RenameExprUnmap().
++*/
++static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
++  Parse *pParse = pWalker->pParse;
++  sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
++  return WRC_Continue;
++}
++
++/*
++** Remove all nodes that are part of expression pExpr from the rename list.
++*/
++SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
++  Walker sWalker;
++  memset(&sWalker, 0, sizeof(Walker));
++  sWalker.pParse = pParse;
++  sWalker.xExprCallback = renameUnmapExprCb;
++  sqlite3WalkExpr(&sWalker, pExpr);
++}
++
++/*
++** Remove all nodes that are part of expression-list pEList from the 
++** rename list.
++*/
++SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
++  if( pEList ){
++    int i;
++    Walker sWalker;
++    memset(&sWalker, 0, sizeof(Walker));
++    sWalker.pParse = pParse;
++    sWalker.xExprCallback = renameUnmapExprCb;
++    sqlite3WalkExprList(&sWalker, pEList);
++    for(i=0; i<pEList->nExpr; i++){
++      sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
++    }
++  }
++}
++
++/*
++** Free the list of RenameToken objects given in the second argument
++*/
++static void renameTokenFree(sqlite3 *db, RenameToken *pToken){
++  RenameToken *pNext;
++  RenameToken *p;
++  for(p=pToken; p; p=pNext){
++    pNext = p->pNext;
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Search the Parse object passed as the first argument for a RenameToken
++** object associated with parse tree element pPtr. If found, remove it
++** from the Parse object and add it to the list maintained by the
++** RenameCtx object passed as the second argument.
++*/
++static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
++  RenameToken **pp;
++  assert( pPtr!=0 );
++  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
++    if( (*pp)->p==pPtr ){
++      RenameToken *pToken = *pp;
++      *pp = pToken->pNext;
++      pToken->pNext = pCtx->pList;
++      pCtx->pList = pToken;
++      pCtx->nList++;
++      break;
++    }
++  }
++}
++
++/*
++** This is a Walker select callback. It does nothing. It is only required
++** because without a dummy callback, sqlite3WalkExpr() and similar do not
++** descend into sub-select statements.
++*/
++static int renameColumnSelectCb(Walker *pWalker, Select *p){
++  UNUSED_PARAMETER(pWalker);
++  UNUSED_PARAMETER(p);
++  return WRC_Continue;
++}
++
++/*
++** This is a Walker expression callback.
++**
++** For every TK_COLUMN node in the expression tree, search to see
++** if the column being references is the column being renamed by an
++** ALTER TABLE statement.  If it is, then attach its associated
++** RenameToken object to the list of RenameToken objects being
++** constructed in RenameCtx object at pWalker->u.pRename.
++*/
++static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
++  RenameCtx *p = pWalker->u.pRename;
++  if( pExpr->op==TK_TRIGGER 
++   && pExpr->iColumn==p->iCol 
++   && pWalker->pParse->pTriggerTab==p->pTab
++  ){
++    renameTokenFind(pWalker->pParse, p, (void*)pExpr);
++  }else if( pExpr->op==TK_COLUMN 
++   && pExpr->iColumn==p->iCol 
++   && p->pTab==pExpr->y.pTab
++  ){
++    renameTokenFind(pWalker->pParse, p, (void*)pExpr);
++  }
++  return WRC_Continue;
++}
++
++/*
++** The RenameCtx contains a list of tokens that reference a column that
++** is being renamed by an ALTER TABLE statement.  Return the "last"
++** RenameToken in the RenameCtx and remove that RenameToken from the
++** RenameContext.  "Last" means the last RenameToken encountered when
++** the input SQL is parsed from left to right.  Repeated calls to this routine
++** return all column name tokens in the order that they are encountered
++** in the SQL statement.
++*/
++static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){
++  RenameToken *pBest = pCtx->pList;
++  RenameToken *pToken;
++  RenameToken **pp;
++
++  for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){
++    if( pToken->t.z>pBest->t.z ) pBest = pToken;
++  }
++  for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
++  *pp = pBest->pNext;
++
++  return pBest;
++}
++
++/*
++** An error occured while parsing or otherwise processing a database
++** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
++** ALTER TABLE RENAME COLUMN program. The error message emitted by the
++** sub-routine is currently stored in pParse->zErrMsg. This function
++** adds context to the error message and then stores it in pCtx.
++*/
++static void renameColumnParseError(
++  sqlite3_context *pCtx, 
++  int bPost,
++  sqlite3_value *pType,
++  sqlite3_value *pObject,
++  Parse *pParse
++){
++  const char *zT = (const char*)sqlite3_value_text(pType);
++  const char *zN = (const char*)sqlite3_value_text(pObject);
++  char *zErr;
++
++  zErr = sqlite3_mprintf("error in %s %s%s: %s", 
++      zT, zN, (bPost ? " after rename" : ""),
++      pParse->zErrMsg
++  );
++  sqlite3_result_error(pCtx, zErr, -1);
++  sqlite3_free(zErr);
++}
++
++/*
++** For each name in the the expression-list pEList (i.e. each
++** pEList->a[i].zName) that matches the string in zOld, extract the 
++** corresponding rename-token from Parse object pParse and add it
++** to the RenameCtx pCtx.
++*/
++static void renameColumnElistNames(
++  Parse *pParse, 
++  RenameCtx *pCtx, 
++  ExprList *pEList, 
++  const char *zOld
++){
++  if( pEList ){
++    int i;
++    for(i=0; i<pEList->nExpr; i++){
++      char *zName = pEList->a[i].zName;
++      if( 0==sqlite3_stricmp(zName, zOld) ){
++        renameTokenFind(pParse, pCtx, (void*)zName);
++      }
++    }
++  }
++}
++
++/*
++** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) 
++** that matches the string in zOld, extract the corresponding rename-token 
++** from Parse object pParse and add it to the RenameCtx pCtx.
++*/
++static void renameColumnIdlistNames(
++  Parse *pParse, 
++  RenameCtx *pCtx, 
++  IdList *pIdList, 
++  const char *zOld
++){
++  if( pIdList ){
++    int i;
++    for(i=0; i<pIdList->nId; i++){
++      char *zName = pIdList->a[i].zName;
++      if( 0==sqlite3_stricmp(zName, zOld) ){
++        renameTokenFind(pParse, pCtx, (void*)zName);
++      }
++    }
++  }
++}
++
++/*
++** Parse the SQL statement zSql using Parse object (*p). The Parse object
++** is initialized by this function before it is used.
++*/
++static int renameParseSql(
++  Parse *p,                       /* Memory to use for Parse object */
++  const char *zDb,                /* Name of schema SQL belongs to */
++  int bTable,                     /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
++  sqlite3 *db,                    /* Database handle */
++  const char *zSql,               /* SQL to parse */
++  int bTemp                       /* True if SQL is from temp schema */
++){
++  int rc;
++  char *zErr = 0;
++
++  db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
++
++  /* Parse the SQL statement passed as the first argument. If no error
++  ** occurs and the parse does not result in a new table, index or
++  ** trigger object, the database must be corrupt. */
++  memset(p, 0, sizeof(Parse));
++  p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
++  p->db = db;
++  p->nQueryLoop = 1;
++  rc = sqlite3RunParser(p, zSql, &zErr);
++  assert( p->zErrMsg==0 );
++  assert( rc!=SQLITE_OK || zErr==0 );
++  assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 );
++  p->zErrMsg = zErr;
++  if( db->mallocFailed ) rc = SQLITE_NOMEM;
++  if( rc==SQLITE_OK 
++   && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 
++  ){
++    rc = SQLITE_CORRUPT_BKPT;
++  }
++
++#ifdef SQLITE_DEBUG
++  /* Ensure that all mappings in the Parse.pRename list really do map to
++  ** a part of the input string.  */
++  if( rc==SQLITE_OK ){
++    int nSql = sqlite3Strlen30(zSql);
++    RenameToken *pToken;
++    for(pToken=p->pRename; pToken; pToken=pToken->pNext){
++      assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] );
++    }
++  }
++#endif
++
++  db->init.iDb = 0;
++  return rc;
++}
++
++/*
++** This function edits SQL statement zSql, replacing each token identified
++** by the linked list pRename with the text of zNew. If argument bQuote is
++** true, then zNew is always quoted first. If no error occurs, the result
++** is loaded into context object pCtx as the result.
++**
++** Or, if an error occurs (i.e. an OOM condition), an error is left in
++** pCtx and an SQLite error code returned.
++*/
++static int renameEditSql(
++  sqlite3_context *pCtx,          /* Return result here */
++  RenameCtx *pRename,             /* Rename context */
++  const char *zSql,               /* SQL statement to edit */
++  const char *zNew,               /* New token text */
++  int bQuote                      /* True to always quote token */
++){
++  int nNew = sqlite3Strlen30(zNew);
++  int nSql = sqlite3Strlen30(zSql);
++  sqlite3 *db = sqlite3_context_db_handle(pCtx);
++  int rc = SQLITE_OK;
++  char *zQuot;
++  char *zOut;
++  int nQuot;
++
++  /* Set zQuot to point to a buffer containing a quoted copy of the 
++  ** identifier zNew. If the corresponding identifier in the original 
++  ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to
++  ** point to zQuot so that all substitutions are made using the
++  ** quoted version of the new column name.  */
++  zQuot = sqlite3MPrintf(db, "\"%w\"", zNew);
++  if( zQuot==0 ){
++    return SQLITE_NOMEM;
++  }else{
++    nQuot = sqlite3Strlen30(zQuot);
++  }
++  if( bQuote ){
++    zNew = zQuot;
++    nNew = nQuot;
++  }
++
++  /* At this point pRename->pList contains a list of RenameToken objects
++  ** corresponding to all tokens in the input SQL that must be replaced
++  ** with the new column name. All that remains is to construct and
++  ** return the edited SQL string. */
++  assert( nQuot>=nNew );
++  zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1);
++  if( zOut ){
++    int nOut = nSql;
++    memcpy(zOut, zSql, nSql);
++    while( pRename->pList ){
++      int iOff;                   /* Offset of token to replace in zOut */
++      RenameToken *pBest = renameColumnTokenNext(pRename);
++
++      u32 nReplace;
++      const char *zReplace;
++      if( sqlite3IsIdChar(*pBest->t.z) ){
++        nReplace = nNew;
++        zReplace = zNew;
++      }else{
++        nReplace = nQuot;
++        zReplace = zQuot;
++      }
++
++      iOff = pBest->t.z - zSql;
++      if( pBest->t.n!=nReplace ){
++        memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], 
++            nOut - (iOff + pBest->t.n)
++        );
++        nOut += nReplace - pBest->t.n;
++        zOut[nOut] = '\0';
++      }
++      memcpy(&zOut[iOff], zReplace, nReplace);
++      sqlite3DbFree(db, pBest);
++    }
++
++    sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT);
++    sqlite3DbFree(db, zOut);
++  }else{
++    rc = SQLITE_NOMEM;
++  }
++
++  sqlite3_free(zQuot);
++  return rc;
++}
++
++/*
++** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming
++** it was read from the schema of database zDb. Return SQLITE_OK if 
++** successful. Otherwise, return an SQLite error code and leave an error
++** message in the Parse object.
++*/
++static int renameResolveTrigger(Parse *pParse, const char *zDb){
++  sqlite3 *db = pParse->db;
++  Trigger *pNew = pParse->pNewTrigger;
++  TriggerStep *pStep;
++  NameContext sNC;
++  int rc = SQLITE_OK;
++
++  memset(&sNC, 0, sizeof(sNC));
++  sNC.pParse = pParse;
++  assert( pNew->pTabSchema );
++  pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, 
++      db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
++  );
++  pParse->eTriggerOp = pNew->op;
++  /* ALWAYS() because if the table of the trigger does not exist, the
++  ** error would have been hit before this point */
++  if( ALWAYS(pParse->pTriggerTab) ){
++    rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
++  }
++
++  /* Resolve symbols in WHEN clause */
++  if( rc==SQLITE_OK && pNew->pWhen ){
++    rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
++  }
++
++  for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
++    if( pStep->pSelect ){
++      sqlite3SelectPrep(pParse, pStep->pSelect, &sNC);
++      if( pParse->nErr ) rc = pParse->rc;
++    }
++    if( rc==SQLITE_OK && pStep->zTarget ){
++      Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
++      if( pTarget==0 ){
++        rc = SQLITE_ERROR;
++      }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){
++        SrcList sSrc;
++        memset(&sSrc, 0, sizeof(sSrc));
++        sSrc.nSrc = 1;
++        sSrc.a[0].zName = pStep->zTarget;
++        sSrc.a[0].pTab = pTarget;
++        sNC.pSrcList = &sSrc;
++        if( pStep->pWhere ){
++          rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
++        }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
++        }
++        assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
++        if( pStep->pUpsert ){
++          Upsert *pUpsert = pStep->pUpsert;
++          assert( rc==SQLITE_OK );
++          pUpsert->pUpsertSrc = &sSrc;
++          sNC.uNC.pUpsert = pUpsert;
++          sNC.ncFlags = NC_UUpsert;
++          rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
++          if( rc==SQLITE_OK ){
++            ExprList *pUpsertSet = pUpsert->pUpsertSet;
++            rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
++          }
++          sNC.ncFlags = 0;
++        }
++      }
++    }
++  }
++  return rc;
++}
++
++/*
++** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr
++** objects that are part of the trigger passed as the second argument.
++*/
++static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
++  TriggerStep *pStep;
++
++  /* Find tokens to edit in WHEN clause */
++  sqlite3WalkExpr(pWalker, pTrigger->pWhen);
++
++  /* Find tokens to edit in trigger steps */
++  for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
++    sqlite3WalkSelect(pWalker, pStep->pSelect);
++    sqlite3WalkExpr(pWalker, pStep->pWhere);
++    sqlite3WalkExprList(pWalker, pStep->pExprList);
++    if( pStep->pUpsert ){
++      Upsert *pUpsert = pStep->pUpsert;
++      sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget);
++      sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet);
++      sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
++      sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
++    }
++  }
++}
++
++/*
++** Free the contents of Parse object (*pParse). Do not free the memory
++** occupied by the Parse object itself.
++*/
++static void renameParseCleanup(Parse *pParse){
++  sqlite3 *db = pParse->db;
++  if( pParse->pVdbe ){
++    sqlite3VdbeFinalize(pParse->pVdbe);
++  }
++  sqlite3DeleteTable(db, pParse->pNewTable);
++  if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
++  sqlite3DeleteTrigger(db, pParse->pNewTrigger);
++  sqlite3DbFree(db, pParse->zErrMsg);
++  renameTokenFree(db, pParse->pRename);
++  sqlite3ParserReset(pParse);
++}
++
++/*
++** SQL function:
++**
++**     sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
++**
++**   0. zSql:     SQL statement to rewrite
++**   1. type:     Type of object ("table", "view" etc.)
++**   2. object:   Name of object
++**   3. Database: Database name (e.g. "main")
++**   4. Table:    Table name
++**   5. iCol:     Index of column to rename
++**   6. zNew:     New column name
++**   7. bQuote:   Non-zero if the new column name should be quoted.
++**   8. bTemp:    True if zSql comes from temp schema
++**
++** Do a column rename operation on the CREATE statement given in zSql.
++** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
++** into zNew.  The name should be quoted if bQuote is true.
++**
++** This function is used internally by the ALTER TABLE RENAME COLUMN command.
++** It is only accessible to SQL created using sqlite3NestedParse().  It is
++** not reachable from ordinary SQL passed into sqlite3_prepare().
++*/
++static void renameColumnFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  RenameCtx sCtx;
++  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
++  const char *zDb = (const char*)sqlite3_value_text(argv[3]);
++  const char *zTable = (const char*)sqlite3_value_text(argv[4]);
++  int iCol = sqlite3_value_int(argv[5]);
++  const char *zNew = (const char*)sqlite3_value_text(argv[6]);
++  int bQuote = sqlite3_value_int(argv[7]);
++  int bTemp = sqlite3_value_int(argv[8]);
++  const char *zOld;
++  int rc;
++  Parse sParse;
++  Walker sWalker;
++  Index *pIdx;
++  int i;
++  Table *pTab;
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  sqlite3_xauth xAuth = db->xAuth;
++#endif
++
++  UNUSED_PARAMETER(NotUsed);
++  if( zSql==0 ) return;
++  if( zTable==0 ) return;
++  if( zNew==0 ) return;
++  if( iCol<0 ) return;
++  sqlite3BtreeEnterAll(db);
++  pTab = sqlite3FindTable(db, zTable, zDb);
++  if( pTab==0 || iCol>=pTab->nCol ){
++    sqlite3BtreeLeaveAll(db);
++    return;
++  }
++  zOld = pTab->aCol[iCol].zName;
++  memset(&sCtx, 0, sizeof(sCtx));
++  sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = 0;
++#endif
++  rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);
++
++  /* Find tokens that need to be replaced. */
++  memset(&sWalker, 0, sizeof(Walker));
++  sWalker.pParse = &sParse;
++  sWalker.xExprCallback = renameColumnExprCb;
++  sWalker.xSelectCallback = renameColumnSelectCb;
++  sWalker.u.pRename = &sCtx;
++
++  sCtx.pTab = pTab;
++  if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++  if( sParse.pNewTable ){
++    Select *pSelect = sParse.pNewTable->pSelect;
++    if( pSelect ){
++      sParse.rc = SQLITE_OK;
++      sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
++      rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
++      if( rc==SQLITE_OK ){
++        sqlite3WalkSelect(&sWalker, pSelect);
++      }
++      if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++    }else{
++      /* A regular table */
++      int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
++      FKey *pFKey;
++      assert( sParse.pNewTable->pSelect==0 );
++      sCtx.pTab = sParse.pNewTable;
++      if( bFKOnly==0 ){
++        renameTokenFind(
++            &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName
++        );
++        if( sCtx.iCol<0 ){
++          renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey);
++        }
++        sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck);
++        for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
++          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
++        }
++      }
++
++      for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
++        for(i=0; i<pFKey->nCol; i++){
++          if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
++            renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
++          }
++          if( 0==sqlite3_stricmp(pFKey->zTo, zTable)
++           && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld)
++          ){
++            renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol);
++          }
++        }
++      }
++    }
++  }else if( sParse.pNewIndex ){
++    sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
++    sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
++  }else{
++    /* A trigger */
++    TriggerStep *pStep;
++    rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb));
++    if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++
++    for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
++      if( pStep->zTarget ){ 
++        Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb);
++        if( pTarget==pTab ){
++          if( pStep->pUpsert ){
++            ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet;
++            renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld);
++          }
++          renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld);
++          renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld);
++        }
++      }
++    }
++
++
++    /* Find tokens to edit in UPDATE OF clause */
++    if( sParse.pTriggerTab==pTab ){
++      renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld);
++    }
++
++    /* Find tokens to edit in various expressions and selects */
++    renameWalkTrigger(&sWalker, sParse.pNewTrigger);
++  }
++
++  assert( rc==SQLITE_OK );
++  rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
++
++renameColumnFunc_done:
++  if( rc!=SQLITE_OK ){
++    if( sParse.zErrMsg ){
++      renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
++    }else{
++      sqlite3_result_error_code(context, rc);
++    }
++  }
++
++  renameParseCleanup(&sParse);
++  renameTokenFree(db, sCtx.pList);
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = xAuth;
++#endif
++  sqlite3BtreeLeaveAll(db);
++}
++
++/*
++** Walker expression callback used by "RENAME TABLE". 
++*/
++static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
++  RenameCtx *p = pWalker->u.pRename;
++  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
++    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
++  }
++  return WRC_Continue;
++}
++
++/*
++** Walker select callback used by "RENAME TABLE". 
++*/
++static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
++  int i;
++  RenameCtx *p = pWalker->u.pRename;
++  SrcList *pSrc = pSelect->pSrc;
++  for(i=0; i<pSrc->nSrc; i++){
++    struct SrcList_item *pItem = &pSrc->a[i];
++    if( pItem->pTab==p->pTab ){
++      renameTokenFind(pWalker->pParse, p, pItem->zName);
++    }
++  }
++
++  return WRC_Continue;
++}
++
++
++/*
++** This C function implements an SQL user function that is used by SQL code
++** generated by the ALTER TABLE ... RENAME command to modify the definition
++** of any foreign key constraints that use the table being renamed as the 
++** parent table. It is passed three arguments:
++**
++**   0: The database containing the table being renamed.
++**   1. type:     Type of object ("table", "view" etc.)
++**   2. object:   Name of object
++**   3: The complete text of the schema statement being modified,
++**   4: The old name of the table being renamed, and
++**   5: The new name of the table being renamed.
++**   6: True if the schema statement comes from the temp db.
++**
++** It returns the new schema statement. For example:
++**
++** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0)
++**       -> 'CREATE TABLE t1(a REFERENCES t3)'
++*/
++static void renameTableFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  const char *zDb = (const char*)sqlite3_value_text(argv[0]);
++  const char *zInput = (const char*)sqlite3_value_text(argv[3]);
++  const char *zOld = (const char*)sqlite3_value_text(argv[4]);
++  const char *zNew = (const char*)sqlite3_value_text(argv[5]);
++  int bTemp = sqlite3_value_int(argv[6]);
++  UNUSED_PARAMETER(NotUsed);
++
++  if( zInput && zOld && zNew ){
++    Parse sParse;
++    int rc;
++    int bQuote = 1;
++    RenameCtx sCtx;
++    Walker sWalker;
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++    sqlite3_xauth xAuth = db->xAuth;
++    db->xAuth = 0;
++#endif
++
++    sqlite3BtreeEnterAll(db);
++
++    memset(&sCtx, 0, sizeof(RenameCtx));
++    sCtx.pTab = sqlite3FindTable(db, zOld, zDb);
++    memset(&sWalker, 0, sizeof(Walker));
++    sWalker.pParse = &sParse;
++    sWalker.xExprCallback = renameTableExprCb;
++    sWalker.xSelectCallback = renameTableSelectCb;
++    sWalker.u.pRename = &sCtx;
++
++    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
++
++    if( rc==SQLITE_OK ){
++      int isLegacy = (db->flags & SQLITE_LegacyAlter);
++      if( sParse.pNewTable ){
++        Table *pTab = sParse.pNewTable;
++
++        if( pTab->pSelect ){
++          if( isLegacy==0 ){
++            NameContext sNC;
++            memset(&sNC, 0, sizeof(sNC));
++            sNC.pParse = &sParse;
++
++            sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
++            if( sParse.nErr ) rc = sParse.rc;
++            sqlite3WalkSelect(&sWalker, pTab->pSelect);
++          }
++        }else{
++          /* Modify any FK definitions to point to the new table. */
++#ifndef SQLITE_OMIT_FOREIGN_KEY
++          if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
++            FKey *pFKey;
++            for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
++              if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
++                renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
++              }
++            }
++          }
++#endif
++
++          /* If this is the table being altered, fix any table refs in CHECK
++          ** expressions. Also update the name that appears right after the
++          ** "CREATE [VIRTUAL] TABLE" bit. */
++          if( sqlite3_stricmp(zOld, pTab->zName)==0 ){
++            sCtx.pTab = pTab;
++            if( isLegacy==0 ){
++              sqlite3WalkExprList(&sWalker, pTab->pCheck);
++            }
++            renameTokenFind(&sParse, &sCtx, pTab->zName);
++          }
++        }
++      }
++
++      else if( sParse.pNewIndex ){
++        renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName);
++        if( isLegacy==0 ){
++          sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
++        }
++      }
++
++#ifndef SQLITE_OMIT_TRIGGER
++      else{
++        Trigger *pTrigger = sParse.pNewTrigger;
++        TriggerStep *pStep;
++        if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) 
++            && sCtx.pTab->pSchema==pTrigger->pTabSchema
++          ){
++          renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
++        }
++
++        if( isLegacy==0 ){
++          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
++          if( rc==SQLITE_OK ){
++            renameWalkTrigger(&sWalker, pTrigger);
++            for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
++              if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
++                renameTokenFind(&sParse, &sCtx, pStep->zTarget);
++              }
++            }
++          }
++        }
++      }
++#endif
++    }
++
++    if( rc==SQLITE_OK ){
++      rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
++    }
++    if( rc!=SQLITE_OK ){
++      if( sParse.zErrMsg ){
++        renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
++      }else{
++        sqlite3_result_error_code(context, rc);
++      }
++    }
++
++    renameParseCleanup(&sParse);
++    renameTokenFree(db, sCtx.pList);
++    sqlite3BtreeLeaveAll(db);
++#ifndef SQLITE_OMIT_AUTHORIZATION
++    db->xAuth = xAuth;
++#endif
++  }
++
++  return;
++}
++
++/*
++** An SQL user function that checks that there are no parse or symbol
++** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
++** After an ALTER TABLE .. RENAME operation is performed and the schema
++** reloaded, this function is called on each SQL statement in the schema
++** to ensure that it is still usable.
++**
++**   0: Database name ("main", "temp" etc.).
++**   1: SQL statement.
++**   2: Object type ("view", "table", "trigger" or "index").
++**   3: Object name.
++**   4: True if object is from temp schema.
++**
++** Unless it finds an error, this function normally returns NULL. However, it
++** returns integer value 1 if:
++**
++**   * the SQL argument creates a trigger, and
++**   * the table that the trigger is attached to is in database zDb.
++*/
++static void renameTableTest(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
++  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
++  int bTemp = sqlite3_value_int(argv[4]);
++  int isLegacy = (db->flags & SQLITE_LegacyAlter);
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  sqlite3_xauth xAuth = db->xAuth;
++  db->xAuth = 0;
++#endif
++
++  UNUSED_PARAMETER(NotUsed);
++  if( zDb && zInput ){
++    int rc;
++    Parse sParse;
++    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
++    if( rc==SQLITE_OK ){
++      if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
++        NameContext sNC;
++        memset(&sNC, 0, sizeof(sNC));
++        sNC.pParse = &sParse;
++        sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
++        if( sParse.nErr ) rc = sParse.rc;
++      }
++
++      else if( sParse.pNewTrigger ){
++        if( isLegacy==0 ){
++          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
++        }
++        if( rc==SQLITE_OK ){
++          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
++          int i2 = sqlite3FindDbName(db, zDb);
++          if( i1==i2 ) sqlite3_result_int(context, 1);
++        }
++      }
++    }
++
++    if( rc!=SQLITE_OK ){
++      renameColumnParseError(context, 1, argv[2], argv[3], &sParse);
++    }
++    renameParseCleanup(&sParse);
++  }
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = xAuth;
++#endif
++}
++
++/*
++** Register built-in functions used to help implement ALTER TABLE
++*/
++SQLITE_PRIVATE void sqlite3AlterFunctions(void){
++  static FuncDef aAlterTableFuncs[] = {
++    INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
++    INTERNAL_FUNCTION(sqlite_rename_table,  7, renameTableFunc),
++    INTERNAL_FUNCTION(sqlite_rename_test,   5, renameTableTest),
++  };
++  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
++}
+ #endif  /* SQLITE_ALTER_TABLE */
+ 
+ /************** End of alter.c ***********************************************/
+@@ -97912,6 +103313,10 @@
+            "DELETE FROM %Q.%s WHERE %s=%Q",
+            pDb->zDbSName, zTab, zWhereType, zWhere
+         );
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++      }else if( db->xPreUpdateCallback ){
++        sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
++#endif
+       }else{
+         /* The sqlite_stat[134] table already exists.  Delete all rows. */
+         sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
+@@ -98159,6 +103564,7 @@
+   0,               /* pNext */
+   statInit,        /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_init",     /* zName */
+   {0}
+ };
+@@ -98475,6 +103881,7 @@
+   0,               /* pNext */
+   statPush,        /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_push",     /* zName */
+   {0}
+ };
+@@ -98626,6 +104033,7 @@
+   0,               /* pNext */
+   statGet,         /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_get",      /* zName */
+   {0}
+ };
+@@ -98676,6 +104084,9 @@
+   int regIdxname = iMem++;     /* Register containing index name */
+   int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
+   int regPrev = iMem;          /* MUST BE LAST (see below) */
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  Table *pStat1 = 0; 
++#endif
+ 
+   pParse->nMem = MAX(pParse->nMem, iMem);
+   v = sqlite3GetVdbe(pParse);
+@@ -98686,7 +104097,7 @@
+     /* Do not gather statistics on views or virtual tables */
+     return;
+   }
+-  if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
++  if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
+     /* Do not gather statistics on system tables */
+     return;
+   }
+@@ -98701,6 +104112,18 @@
+   }
+ #endif
+ 
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  if( db->xPreUpdateCallback ){
++    pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
++    if( pStat1==0 ) return;
++    pStat1->zName = (char*)&pStat1[1];
++    memcpy(pStat1->zName, "sqlite_stat1", 13);
++    pStat1->nCol = 3;
++    pStat1->iPKey = -1;
++    sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
++  }
++#endif
++
+   /* Establish a read-lock on the table at the shared-cache level. 
+   ** Open a read-only cursor on the table. Also allocate a cursor number
+   ** to use for scanning indexes (iIdxCur). No index cursor is opened at
+@@ -98902,6 +104325,9 @@
+     sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
+     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++    sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
++#endif
+     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+ 
+     /* Add the entries to the stat3 or stat4 table. */
+@@ -98927,10 +104353,7 @@
+       callStatGet(v, regStat4, STAT_GET_NLT, regLt);
+       callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
+       sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
+-      /* We know that the regSampleRowid row exists because it was read by
+-      ** the previous loop.  Thus the not-found jump of seekOp will never
+-      ** be taken */
+-      VdbeCoverageNeverTaken(v);
++      VdbeCoverage(v);
+ #ifdef SQLITE_ENABLE_STAT3
+       sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
+ #else
+@@ -98965,6 +104388,9 @@
+     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
+     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++    sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
++#endif
+     sqlite3VdbeJumpHere(v, jZeroRows);
+   }
+ }
+@@ -99567,7 +104993,7 @@
+ 
+   /* Load the statistics from the sqlite_stat4 table. */
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+-  if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
++  if( rc==SQLITE_OK ){
+     db->lookaside.bDisable++;
+     rc = loadStat4(db, sInfo.zDatabase);
+     db->lookaside.bDisable--;
+@@ -99647,6 +105073,10 @@
+ **
+ ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
+ ** third argument.
++**
++** If the db->init.reopenMemdb flags is set, then instead of attaching a
++** new database, close the database on db->init.iDb and reopen it as an
++** empty MemDB.
+ */
+ static void attachFunc(
+   sqlite3_context *context,
+@@ -99667,70 +105097,86 @@
+   sqlite3_vfs *pVfs;
+ 
+   UNUSED_PARAMETER(NotUsed);
+-
+   zFile = (const char *)sqlite3_value_text(argv[0]);
+   zName = (const char *)sqlite3_value_text(argv[1]);
+   if( zFile==0 ) zFile = "";
+   if( zName==0 ) zName = "";
+ 
+-  /* Check for the following errors:
+-  **
+-  **     * Too many attached databases,
+-  **     * Transaction currently open
+-  **     * Specified database name already being used.
+-  */
+-  if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
+-    zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", 
+-      db->aLimit[SQLITE_LIMIT_ATTACHED]
+-    );
+-    goto attach_error;
+-  }
+-  if( !db->autoCommit ){
+-    zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
+-    goto attach_error;
+-  }
+-  for(i=0; i<db->nDb; i++){
+-    char *z = db->aDb[i].zDbSName;
+-    assert( z && zName );
+-    if( sqlite3StrICmp(z, zName)==0 ){
+-      zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
++#ifdef SQLITE_ENABLE_DESERIALIZE
++# define REOPEN_AS_MEMDB(db)  (db->init.reopenMemdb)
++#else
++# define REOPEN_AS_MEMDB(db)  (0)
++#endif
++
++  if( REOPEN_AS_MEMDB(db) ){
++    /* This is not a real ATTACH.  Instead, this routine is being called
++    ** from sqlite3_deserialize() to close database db->init.iDb and
++    ** reopen it as a MemDB */
++    pVfs = sqlite3_vfs_find("memdb");
++    if( pVfs==0 ) return;
++    pNew = &db->aDb[db->init.iDb];
++    if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
++    pNew->pBt = 0;
++    pNew->pSchema = 0;
++    rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
++  }else{
++    /* This is a real ATTACH
++    **
++    ** Check for the following errors:
++    **
++    **     * Too many attached databases,
++    **     * Transaction currently open
++    **     * Specified database name already being used.
++    */
++    if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
++      zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", 
++        db->aLimit[SQLITE_LIMIT_ATTACHED]
++      );
+       goto attach_error;
+     }
++    for(i=0; i<db->nDb; i++){
++      char *z = db->aDb[i].zDbSName;
++      assert( z && zName );
++      if( sqlite3StrICmp(z, zName)==0 ){
++        zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
++        goto attach_error;
++      }
++    }
++  
++    /* Allocate the new entry in the db->aDb[] array and initialize the schema
++    ** hash tables.
++    */
++    if( db->aDb==db->aDbStatic ){
++      aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
++      if( aNew==0 ) return;
++      memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
++    }else{
++      aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
++      if( aNew==0 ) return;
++    }
++    db->aDb = aNew;
++    pNew = &db->aDb[db->nDb];
++    memset(pNew, 0, sizeof(*pNew));
++  
++    /* Open the database file. If the btree is successfully opened, use
++    ** it to obtain the database schema. At this point the schema may
++    ** or may not be initialized.
++    */
++    flags = db->openFlags;
++    rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
++    if( rc!=SQLITE_OK ){
++      if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
++      sqlite3_result_error(context, zErr, -1);
++      sqlite3_free(zErr);
++      return;
++    }
++    assert( pVfs );
++    flags |= SQLITE_OPEN_MAIN_DB;
++    rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
++    sqlite3_free( zPath );
++    db->nDb++;
+   }
+-
+-  /* Allocate the new entry in the db->aDb[] array and initialize the schema
+-  ** hash tables.
+-  */
+-  if( db->aDb==db->aDbStatic ){
+-    aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
+-    if( aNew==0 ) return;
+-    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+-  }else{
+-    aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+-    if( aNew==0 ) return;
+-  }
+-  db->aDb = aNew;
+-  pNew = &db->aDb[db->nDb];
+-  memset(pNew, 0, sizeof(*pNew));
+-
+-  /* Open the database file. If the btree is successfully opened, use
+-  ** it to obtain the database schema. At this point the schema may
+-  ** or may not be initialized.
+-  */
+-  flags = db->openFlags;
+-  rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
+-  if( rc!=SQLITE_OK ){
+-    if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+-    sqlite3_result_error(context, zErr, -1);
+-    sqlite3_free(zErr);
+-    return;
+-  }
+-  assert( pVfs );
+-  flags |= SQLITE_OPEN_MAIN_DB;
+-  rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
+-  sqlite3_free( zPath );
+-  db->nDb++;
+-  db->skipBtreeMutex = 0;
++  db->noSharedCache = 0;
+   if( rc==SQLITE_CONSTRAINT ){
+     rc = SQLITE_ERROR;
+     zErrDyn = sqlite3MPrintf(db, "database is already attached");
+@@ -99756,7 +105202,7 @@
+     sqlite3BtreeLeave(pNew->pBt);
+   }
+   pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
+-  pNew->zDbSName = sqlite3DbStrDup(db, zName);
++  if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
+   if( rc==SQLITE_OK && pNew->zDbSName==0 ){
+     rc = SQLITE_NOMEM_BKPT;
+   }
+@@ -99796,13 +105242,16 @@
+ 
+   /* If the file was opened successfully, read the schema for the new database.
+   ** If this fails, or if opening the file failed, then close the file and 
+-  ** remove the entry from the db->aDb[] array. i.e. put everything back the way
+-  ** we found it.
++  ** remove the entry from the db->aDb[] array. i.e. put everything back the
++  ** way we found it.
+   */
+   if( rc==SQLITE_OK ){
+     sqlite3BtreeEnterAll(db);
++    db->init.iDb = 0;
++    db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
+     rc = sqlite3Init(db, &zErrDyn);
+     sqlite3BtreeLeaveAll(db);
++    assert( zErrDyn==0 || rc!=SQLITE_OK );
+   }
+ #ifdef SQLITE_USER_AUTHENTICATION
+   if( rc==SQLITE_OK ){
+@@ -99814,22 +105263,24 @@
+   }
+ #endif
+   if( rc ){
+-    int iDb = db->nDb - 1;
+-    assert( iDb>=2 );
+-    if( db->aDb[iDb].pBt ){
+-      sqlite3BtreeClose(db->aDb[iDb].pBt);
+-      db->aDb[iDb].pBt = 0;
+-      db->aDb[iDb].pSchema = 0;
++    if( !REOPEN_AS_MEMDB(db) ){
++      int iDb = db->nDb - 1;
++      assert( iDb>=2 );
++      if( db->aDb[iDb].pBt ){
++        sqlite3BtreeClose(db->aDb[iDb].pBt);
++        db->aDb[iDb].pBt = 0;
++        db->aDb[iDb].pSchema = 0;
++      }
++      sqlite3ResetAllSchemasOfConnection(db);
++      db->nDb = iDb;
++      if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
++        sqlite3OomFault(db);
++        sqlite3DbFree(db, zErrDyn);
++        zErrDyn = sqlite3MPrintf(db, "out of memory");
++      }else if( zErrDyn==0 ){
++        zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
++      }
+     }
+-    sqlite3ResetAllSchemasOfConnection(db);
+-    db->nDb = iDb;
+-    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+-      sqlite3OomFault(db);
+-      sqlite3DbFree(db, zErrDyn);
+-      zErrDyn = sqlite3MPrintf(db, "out of memory");
+-    }else if( zErrDyn==0 ){
+-      zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
+-    }
+     goto attach_error;
+   }
+   
+@@ -99880,11 +105331,6 @@
+     sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
+     goto detach_error;
+   }
+-  if( !db->autoCommit ){
+-    sqlite3_snprintf(sizeof(zErr), zErr,
+-                     "cannot DETACH database within transaction");
+-    goto detach_error;
+-  }
+   if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
+     sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
+     goto detach_error;
+@@ -99986,6 +105432,7 @@
+     0,                /* pNext */
+     detachFunc,       /* xSFunc */
+     0,                /* xFinalize */
++    0, 0,             /* xValue, xInverse */
+     "sqlite_detach",  /* zName */
+     {0}
+   };
+@@ -100005,6 +105452,7 @@
+     0,                /* pNext */
+     attachFunc,       /* xSFunc */
+     0,                /* xFinalize */
++    0, 0,             /* xValue, xInverse */
+     "sqlite_attach",  /* zName */
+     {0}
+   };
+@@ -100075,6 +105523,9 @@
+     if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
+     if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
+ #endif
++    if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){
++      return 1;
++    }
+   }
+   return 0;
+ }
+@@ -100105,8 +105556,13 @@
+     if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
+       return 1;
+     }
+-    if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
+-      return 1;
++    if( pSelect->pWith ){
++      int i;
++      for(i=0; i<pSelect->pWith->nCte; i++){
++        if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
++          return 1;
++        }
++      }
+     }
+     pSelect = pSelect->pPrior;
+   }
+@@ -100169,6 +105625,18 @@
+     if( sqlite3FixExprList(pFix, pStep->pExprList) ){
+       return 1;
+     }
++#ifndef SQLITE_OMIT_UPSERT
++    if( pStep->pUpsert ){
++      Upsert *pUp = pStep->pUpsert;
++      if( sqlite3FixExprList(pFix, pUp->pUpsertTarget)
++       || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere)
++       || sqlite3FixExprList(pFix, pUp->pUpsertSet)
++       || sqlite3FixExpr(pFix, pUp->pUpsertWhere)
++      ){
++        return 1;
++      }
++    }
++#endif
+     pStep = pStep->pNext;
+   }
+   return 0;
+@@ -100257,7 +105725,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   db->xAuth = (sqlite3_xauth)xAuth;
+   db->pAuthArg = pArg;
+-  sqlite3ExpirePreparedStatements(db);
++  sqlite3ExpirePreparedStatements(db, 0);
+   sqlite3_mutex_leave(db->mutex);
+   return SQLITE_OK;
+ }
+@@ -100297,11 +105765,9 @@
+ #endif
+                 );
+   if( rc==SQLITE_DENY ){
+-    if( db->nDb>2 || iDb!=0 ){
+-      sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
+-    }else{
+-      sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
+-    }
++    char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
++    if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
++    sqlite3ErrorMsg(pParse, "access to %z is prohibited", z);
+     pParse->rc = SQLITE_AUTH;
+   }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
+     sqliteAuthBadReturnCode(pParse);
+@@ -100331,6 +105797,8 @@
+   int iDb;              /* The index of the database the expression refers to */
+   int iCol;             /* Index of column in table */
+ 
++  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
++  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
+   if( db->xAuth==0 ) return;
+   iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
+   if( iDb<0 ){
+@@ -100339,7 +105807,6 @@
+     return;
+   }
+ 
+-  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
+   if( pExpr->op==TK_TRIGGER ){
+     pTab = pParse->pTriggerTab;
+   }else{
+@@ -100388,7 +105855,8 @@
+   /* Don't do any authorization checks if the database is initialising
+   ** or if the parser is being invoked from within sqlite3_declare_vtab.
+   */
+-  if( db->init.busy || IN_DECLARE_VTAB ){
++  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
++  if( db->init.busy || IN_SPECIAL_PARSE ){
+     return SQLITE_OK;
+   }
+ 
+@@ -100680,7 +106148,6 @@
+   /* Get the VDBE program ready for execution
+   */
+   if( v && pParse->nErr==0 && !db->mallocFailed ){
+-    assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
+     /* A minimum of one cursor is required if autoincrement is used
+     *  See ticket [a696379c1f08866] */
+     if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+@@ -100798,29 +106265,30 @@
+   const char *zDbase     /* Name of the database.  Might be NULL */
+ ){
+   Table *p;
++  sqlite3 *db = pParse->db;
+ 
+   /* Read the database schema. If an error occurs, leave an error message
+   ** and code in pParse and return NULL. */
+-  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
++  if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 
++   && SQLITE_OK!=sqlite3ReadSchema(pParse)
++  ){
+     return 0;
+   }
+ 
+-  p = sqlite3FindTable(pParse->db, zName, zDbase);
++  p = sqlite3FindTable(db, zName, zDbase);
+   if( p==0 ){
+     const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-    if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
+-      /* If zName is the not the name of a table in the schema created using
+-      ** CREATE, then check to see if it is the name of an virtual table that
+-      ** can be an eponymous virtual table. */
+-      Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+-      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+-        pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
+-      }
+-      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+-        return pMod->pEpoTab;
+-      }
++    /* If zName is the not the name of a table in the schema created using
++    ** CREATE, then check to see if it is the name of an virtual table that
++    ** can be an eponymous virtual table. */
++    Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
++    if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
++      pMod = sqlite3PragmaVtabRegister(db, zName);
+     }
++    if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
++      return pMod->pEpoTab;
++    }
+ #endif
+     if( (flags & LOCATE_NOERR)==0 ){
+       if( zDbase ){
+@@ -100892,7 +106360,7 @@
+ /*
+ ** Reclaim the memory used by an index
+ */
+-static void freeIndex(sqlite3 *db, Index *p){
++SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){
+ #ifndef SQLITE_OMIT_ANALYZE
+   sqlite3DeleteIndexSamples(db, p);
+ #endif
+@@ -100932,9 +106400,9 @@
+         p->pNext = pIndex->pNext;
+       }
+     }
+-    freeIndex(db, pIndex);
++    sqlite3FreeIndex(db, pIndex);
+   }
+-  db->flags |= SQLITE_InternChanges;
++  db->mDbFlags |= DBFLAG_SchemaChange;
+ }
+ 
+ /*
+@@ -100969,28 +106437,27 @@
+ 
+ /*
+ ** Reset the schema for the database at index iDb.  Also reset the
+-** TEMP schema.
++** TEMP schema.  The reset is deferred if db->nSchemaLock is not zero.
++** Deferred resets may be run by calling with iDb<0.
+ */
+ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
+-  Db *pDb;
++  int i;
+   assert( iDb<db->nDb );
+ 
+-  /* Case 1:  Reset the single schema identified by iDb */
+-  pDb = &db->aDb[iDb];
+-  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+-  assert( pDb->pSchema!=0 );
+-  sqlite3SchemaClear(pDb->pSchema);
++  if( iDb>=0 ){
++    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
++    DbSetProperty(db, iDb, DB_ResetWanted);
++    DbSetProperty(db, 1, DB_ResetWanted);
++    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
++  }
+ 
+-  /* If any database other than TEMP is reset, then also reset TEMP
+-  ** since TEMP might be holding triggers that reference tables in the
+-  ** other database.
+-  */
+-  if( iDb!=1 ){
+-    pDb = &db->aDb[1];
+-    assert( pDb->pSchema!=0 );
+-    sqlite3SchemaClear(pDb->pSchema);
++  if( db->nSchemaLock==0 ){
++    for(i=0; i<db->nDb; i++){
++      if( DbHasProperty(db, i, DB_ResetWanted) ){
++        sqlite3SchemaClear(db->aDb[i].pSchema);
++      }
++    }
+   }
+-  return;
+ }
+ 
+ /*
+@@ -101003,13 +106470,19 @@
+   for(i=0; i<db->nDb; i++){
+     Db *pDb = &db->aDb[i];
+     if( pDb->pSchema ){
+-      sqlite3SchemaClear(pDb->pSchema);
++      if( db->nSchemaLock==0 ){
++        sqlite3SchemaClear(pDb->pSchema);
++      }else{
++        DbSetProperty(db, i, DB_ResetWanted);
++      }
+     }
+   }
+-  db->flags &= ~SQLITE_InternChanges;
++  db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
+   sqlite3VtabUnlockList(db);
+   sqlite3BtreeLeaveAll(db);
+-  sqlite3CollapseDatabaseArray(db);
++  if( db->nSchemaLock==0 ){
++    sqlite3CollapseDatabaseArray(db);
++  }
+ }
+ 
+ /*
+@@ -101016,7 +106489,7 @@
+ ** This routine is called when a commit occurs.
+ */
+ SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
+-  db->flags &= ~SQLITE_InternChanges;
++  db->mDbFlags &= ~DBFLAG_SchemaChange;
+ }
+ 
+ /*
+@@ -101054,13 +106527,16 @@
+ */
+ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
+   Index *pIndex, *pNext;
+-  TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
+ 
++#ifdef SQLITE_DEBUG
+   /* Record the number of outstanding lookaside allocations in schema Tables
+   ** prior to doing any free() operations.  Since schema Tables do not use
+   ** lookaside, this number should not change. */
+-  TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
+-                         db->lookaside.nOut : 0 );
++  int nLookaside = 0;
++  if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
++    nLookaside = sqlite3LookasideUsed(db, 0);
++  }
++#endif
+ 
+   /* Delete all indices associated with this table. */
+   for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
+@@ -101075,7 +106551,7 @@
+       assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+       assert( pOld==pIndex || pOld==0 );
+     }
+-    freeIndex(db, pIndex);
++    sqlite3FreeIndex(db, pIndex);
+   }
+ 
+   /* Delete any foreign keys attached to this table. */
+@@ -101083,6 +106559,12 @@
+ 
+   /* Delete the Table structure itself.
+   */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  if( pTable->pColHash ){
++    sqlite3HashClear(pTable->pColHash);
++    sqlite3_free(pTable->pColHash);
++  }
++#endif
+   sqlite3DeleteColumnNames(db, pTable);
+   sqlite3DbFree(db, pTable->zName);
+   sqlite3DbFree(db, pTable->zColAff);
+@@ -101094,7 +106576,7 @@
+   sqlite3DbFree(db, pTable);
+ 
+   /* Verify that no lookaside memory was used by schema tables */
+-  assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
++  assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
+ }
+ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
+   /* Do not delete the table until the reference count reaches zero. */
+@@ -101120,7 +106602,7 @@
+   pDb = &db->aDb[iDb];
+   p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
+   sqlite3DeleteTable(db, p);
+-  db->flags |= SQLITE_InternChanges;
++  db->mDbFlags |= DBFLAG_SchemaChange;
+ }
+ 
+ /*
+@@ -101233,7 +106715,8 @@
+       return -1;
+     }
+   }else{
+-    assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
++    assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT
++             || (db->mDbFlags & DBFLAG_Vacuum)!=0);
+     iDb = db->init.iDb;
+     *pUnqual = pName1;
+   }
+@@ -101241,6 +106724,20 @@
+ }
+ 
+ /*
++** True if PRAGMA writable_schema is ON
++*/
++SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               SQLITE_WriteSchema );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               SQLITE_Defensive );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               (SQLITE_WriteSchema|SQLITE_Defensive) );
++  return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
++}
++
++/*
+ ** This routine is used to check if the UTF-8 string zName is a legal
+ ** unqualified name for a new schema object (table, index, view or
+ ** trigger). All names are legal except those that begin with the string
+@@ -101249,7 +106746,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
+   if( !pParse->db->init.busy && pParse->nested==0 
+-          && (pParse->db->flags & SQLITE_WriteSchema)==0
++          && sqlite3WritableSchema(pParse->db)==0
+           && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+     sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
+     return SQLITE_ERROR;
+@@ -101327,6 +106824,9 @@
+     }
+     if( !OMIT_TEMPDB && isTemp ) iDb = 1;
+     zName = sqlite3NameFromToken(db, pName);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, (void*)zName, pName);
++    }
+   }
+   pParse->sNameToken = *pName;
+   if( zName==0 ) return;
+@@ -101362,7 +106862,7 @@
+   ** and types will be used, so there is no need to test for namespace
+   ** collisions.
+   */
+-  if( !IN_DECLARE_VTAB ){
++  if( !IN_SPECIAL_PARSE ){
+     char *zDb = db->aDb[iDb].zDbSName;
+     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+       goto begin_table_error;
+@@ -101465,7 +106965,8 @@
+     }else
+ #endif
+     {
+-      pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
++      pParse->addrCrTab =
++         sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
+     }
+     sqlite3OpenMasterTable(pParse, iDb);
+     sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
+@@ -101514,14 +107015,13 @@
+   Column *pCol;
+   sqlite3 *db = pParse->db;
+   if( (p = pParse->pNewTable)==0 ) return;
+-#if SQLITE_MAX_COLUMN
+   if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+     sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
+     return;
+   }
+-#endif
+   z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
+   if( z==0 ) return;
++  if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
+   memcpy(z, pName->z, pName->n);
+   z[pName->n] = 0;
+   sqlite3Dequote(z);
+@@ -101548,15 +107048,20 @@
+  
+   if( pType->n==0 ){
+     /* If there is no type specified, columns have the default affinity
+-    ** 'BLOB'. */
++    ** 'BLOB' with a default size of 4 bytes. */
+     pCol->affinity = SQLITE_AFF_BLOB;
+     pCol->szEst = 1;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( 4>=sqlite3GlobalConfig.szSorterRef ){
++      pCol->colFlags |= COLFLAG_SORTERREF;
++    }
++#endif
+   }else{
+     zType = z + sqlite3Strlen30(z) + 1;
+     memcpy(zType, pType->z, pType->n);
+     zType[pType->n] = 0;
+     sqlite3Dequote(zType);
+-    pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
++    pCol->affinity = sqlite3AffinityType(zType, pCol);
+     pCol->colFlags |= COLFLAG_HASTYPE;
+   }
+   p->nCol++;
+@@ -101571,10 +107076,24 @@
+ */
+ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
+   Table *p;
++  Column *pCol;
+   p = pParse->pNewTable;
+   if( p==0 || NEVER(p->nCol<1) ) return;
+-  p->aCol[p->nCol-1].notNull = (u8)onError;
++  pCol = &p->aCol[p->nCol-1];
++  pCol->notNull = (u8)onError;
+   p->tabFlags |= TF_HasNotNull;
++
++  /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created
++  ** on this column.  */
++  if( pCol->colFlags & COLFLAG_UNIQUE ){
++    Index *pIdx;
++    for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
++      assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None );
++      if( pIdx->aiColumn[0]==p->nCol-1 ){
++        pIdx->uniqNotNull = 1;
++      }
++    }
++  }
+ }
+ 
+ /*
+@@ -101602,7 +107121,7 @@
+ ** If none of the substrings in the above table are found,
+ ** SQLITE_AFF_NUMERIC is returned.
+ */
+-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
++SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){
+   u32 h = 0;
+   char aff = SQLITE_AFF_NUMERIC;
+   const char *zChar = 0;
+@@ -101639,27 +107158,32 @@
+     }
+   }
+ 
+-  /* If pszEst is not NULL, store an estimate of the field size.  The
++  /* If pCol is not NULL, store an estimate of the field size.  The
+   ** estimate is scaled so that the size of an integer is 1.  */
+-  if( pszEst ){
+-    *pszEst = 1;   /* default size is approx 4 bytes */
++  if( pCol ){
++    int v = 0;   /* default size is approx 4 bytes */
+     if( aff<SQLITE_AFF_NUMERIC ){
+       if( zChar ){
+         while( zChar[0] ){
+           if( sqlite3Isdigit(zChar[0]) ){
+-            int v = 0;
++            /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+             sqlite3GetInt32(zChar, &v);
+-            v = v/4 + 1;
+-            if( v>255 ) v = 255;
+-            *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+             break;
+           }
+           zChar++;
+         }
+       }else{
+-        *pszEst = 5;   /* BLOB, TEXT, CLOB -> r=5  (approx 20 bytes)*/
++        v = 16;   /* BLOB, TEXT, CLOB -> r=5  (approx 20 bytes)*/
+       }
+     }
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( v>=sqlite3GlobalConfig.szSorterRef ){
++      pCol->colFlags |= COLFLAG_SORTERREF;
++    }
++#endif
++    v = v/4 + 1;
++    if( v>255 ) v = 255;
++    pCol->szEst = v;
+   }
+   return aff;
+ }
+@@ -101674,7 +107198,12 @@
+ ** This routine is called by the parser while in the middle of
+ ** parsing a CREATE TABLE statement.
+ */
+-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
++SQLITE_PRIVATE void sqlite3AddDefaultValue(
++  Parse *pParse,           /* Parsing context */
++  Expr *pExpr,             /* The parsed expression of the default value */
++  const char *zStart,      /* Start of the default value text */
++  const char *zEnd         /* First character past end of defaut value text */
++){
+   Table *p;
+   Column *pCol;
+   sqlite3 *db = pParse->db;
+@@ -101681,27 +107210,28 @@
+   p = pParse->pNewTable;
+   if( p!=0 ){
+     pCol = &(p->aCol[p->nCol-1]);
+-    if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
++    if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
+       sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
+           pCol->zName);
+     }else{
+       /* A copy of pExpr is used instead of the original, as pExpr contains
+-      ** tokens that point to volatile memory. The 'span' of the expression
+-      ** is required by pragma table_info.
++      ** tokens that point to volatile memory.
+       */
+       Expr x;
+       sqlite3ExprDelete(db, pCol->pDflt);
+       memset(&x, 0, sizeof(x));
+       x.op = TK_SPAN;
+-      x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+-                                    (int)(pSpan->zEnd - pSpan->zStart));
+-      x.pLeft = pSpan->pExpr;
++      x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
++      x.pLeft = pExpr;
+       x.flags = EP_Skip;
+       pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
+       sqlite3DbFree(db, x.u.zToken);
+     }
+   }
+-  sqlite3ExprDelete(db, pSpan->pExpr);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameExprUnmap(pParse, pExpr);
++  }
++  sqlite3ExprDelete(db, pExpr);
+ }
+ 
+ /*
+@@ -101792,6 +107322,9 @@
+    && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
+    && sortOrder!=SQLITE_SO_DESC
+   ){
++    if( IN_RENAME_OBJECT && pList ){
++      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
++    }
+     pTab->iPKey = iCol;
+     pTab->keyConf = (u8)onError;
+     assert( autoInc==0 || autoInc==1 );
+@@ -101932,7 +107465,7 @@
+   Vdbe *v = pParse->pVdbe;
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+   sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, 
+-                    db->aDb[iDb].pSchema->schema_cookie+1);
++                   (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie));
+ }
+ 
+ /*
+@@ -102117,6 +107650,31 @@
+   return 0;
+ }
+ 
++/* Recompute the colNotIdxed field of the Index.
++**
++** colNotIdxed is a bitmask that has a 0 bit representing each indexed
++** columns that are within the first 63 columns of the table.  The
++** high-order bit of colNotIdxed is always 1.  All unindexed columns
++** of the table have a 1.
++**
++** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
++** to determine if the index is covering index.
++*/
++static void recomputeColumnsNotIndexed(Index *pIdx){
++  Bitmask m = 0;
++  int j;
++  for(j=pIdx->nColumn-1; j>=0; j--){
++    int x = pIdx->aiColumn[j];
++    if( x>=0 ){
++      testcase( x==BMS-1 );
++      testcase( x==BMS-2 );
++      if( x<BMS-1 ) m |= MASKBIT(x);
++    }
++  }
++  pIdx->colNotIdxed = ~m;
++  assert( (pIdx->colNotIdxed>>63)==1 );
++}
++
+ /*
+ ** This routine runs at the end of parsing a CREATE TABLE statement that
+ ** has a WITHOUT ROWID clause.  The job of this routine is to convert both
+@@ -102125,9 +107683,8 @@
+ ** Changes include:
+ **
+ **     (1)  Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+-**     (2)  Convert the OP_CreateTable into an OP_CreateIndex.  There is
+-**          no rowid btree for a WITHOUT ROWID.  Instead, the canonical
+-**          data storage is a covering index btree.
++**     (2)  Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY 
++**          into BTREE_BLOBKEY.
+ **     (3)  Bypass the creation of the sqlite_master table entry
+ **          for the PRIMARY KEY as the primary key index is now
+ **          identified by the sqlite_master table entry of the table itself.
+@@ -102135,7 +107692,7 @@
+ **          schema to the rootpage from the main table.
+ **     (5)  Add all table columns to the PRIMARY KEY Index object
+ **          so that the PRIMARY KEY is a covering index.  The surplus
+-**          columns are part of KeyInfo.nXField and are not used for
++**          columns are part of KeyInfo.nAllField and are not used for
+ **          sorting or lookup or uniqueness checks.
+ **     (6)  Replace the rowid tail on all automatically generated UNIQUE
+ **          indices with the PRIMARY KEY columns.
+@@ -102160,17 +107717,12 @@
+     }
+   }
+ 
+-  /* The remaining transformations only apply to b-tree tables, not to
+-  ** virtual tables */
+-  if( IN_DECLARE_VTAB ) return;
+-
+-  /* Convert the OP_CreateTable opcode that would normally create the
+-  ** root-page for the table into an OP_CreateIndex opcode.  The index
+-  ** created will become the PRIMARY KEY index.
++  /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
++  ** into BTREE_BLOBKEY.
+   */
+   if( pParse->addrCrTab ){
+     assert( v );
+-    sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
++    sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY);
+   }
+ 
+   /* Locate the PRIMARY KEY index.  Or, if this table was originally
+@@ -102187,7 +107739,7 @@
+     assert( pParse->pNewTable==pTab );
+     sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
+                        SQLITE_IDXTYPE_PRIMARYKEY);
+-    if( db->mallocFailed ) return;
++    if( db->mallocFailed || pParse->nErr ) return;
+     pPk = sqlite3PrimaryKeyIndex(pTab);
+     pTab->iPKey = -1;
+   }else{
+@@ -102267,9 +107819,40 @@
+   }else{
+     pPk->nColumn = pTab->nCol;
+   }
++  recomputeColumnsNotIndexed(pPk);
+ }
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /*
++** Return true if zName is a shadow table name in the current database
++** connection.
++**
++** zName is temporarily modified while this routine is running, but is
++** restored to its original value prior to this routine returning.
++*/
++static int isShadowTableName(sqlite3 *db, char *zName){
++  char *zTail;                  /* Pointer to the last "_" in zName */
++  Table *pTab;                  /* Table that zName is a shadow of */
++  Module *pMod;                 /* Module for the virtual table */
++
++  zTail = strrchr(zName, '_');
++  if( zTail==0 ) return 0;
++  *zTail = 0;
++  pTab = sqlite3FindTable(db, zName, 0);
++  *zTail = '_';
++  if( pTab==0 ) return 0;
++  if( !IsVirtual(pTab) ) return 0;
++  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
++  if( pMod==0 ) return 0;
++  if( pMod->pModule->iVersion<3 ) return 0;
++  if( pMod->pModule->xShadowName==0 ) return 0;
++  return pMod->pModule->xShadowName(zTail+1);
++}
++#else
++# define isShadowTableName(x,y) 0
++#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
++
++/*
+ ** This routine is called to report the final ")" that terminates
+ ** a CREATE TABLE statement.
+ **
+@@ -102308,7 +107891,9 @@
+   p = pParse->pNewTable;
+   if( p==0 ) return;
+ 
+-  assert( !db->init.busy || !pSelect );
++  if( pSelect==0 && isShadowTableName(db, p->zName) ){
++    p->tabFlags |= TF_Shadow;
++  }
+ 
+   /* If the db->init.busy is 1 it means we are reading the SQL off the
+   ** "sqlite_master" or "sqlite_temp_master" table on the disk.
+@@ -102320,6 +107905,10 @@
+   ** table itself.  So mark it read-only.
+   */
+   if( db->init.busy ){
++    if( pSelect ){
++      sqlite3ErrorMsg(pParse, "");
++      return;
++    }
+     p->tnum = db->init.newTnum;
+     if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
+   }
+@@ -102420,10 +108009,6 @@
+       pParse->nTab = 2;
+       addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+       sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+-      sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+-      sqlite3Select(pParse, pSelect, &dest);
+-      sqlite3VdbeEndCoroutine(v, regYield);
+-      sqlite3VdbeJumpHere(v, addrTop - 1);
+       if( pParse->nErr ) return;
+       pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
+       if( pSelTab==0 ) return;
+@@ -102433,6 +108018,11 @@
+       pSelTab->nCol = 0;
+       pSelTab->aCol = 0;
+       sqlite3DeleteTable(db, pSelTab);
++      sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
++      sqlite3Select(pParse, pSelect, &dest);
++      if( pParse->nErr ) return;
++      sqlite3VdbeEndCoroutine(v, regYield);
++      sqlite3VdbeJumpHere(v, addrTop - 1);
+       addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
+       VdbeCoverage(v);
+       sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
+@@ -102510,7 +108100,7 @@
+       return;
+     }
+     pParse->pNewTable = 0;
+-    db->flags |= SQLITE_InternChanges;
++    db->mDbFlags |= DBFLAG_SchemaChange;
+ 
+ #ifndef SQLITE_OMIT_ALTERTABLE
+     if( !p->pSelect ){
+@@ -102567,7 +108157,12 @@
+   ** allocated rather than point to the input string - which means that
+   ** they will persist after the current sqlite3_exec() call returns.
+   */
+-  p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++  if( IN_RENAME_OBJECT ){
++    p->pSelect = pSelect;
++    pSelect = 0;
++  }else{
++    p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++  }
+   p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
+   if( db->mallocFailed ) goto create_view_fail;
+ 
+@@ -102575,7 +108170,7 @@
+   ** the end.
+   */
+   sEnd = pParse->sLastToken;
+-  assert( sEnd.z[0]!=0 );
++  assert( sEnd.z[0]!=0 || sEnd.n==0 );
+   if( sEnd.z[0]!=';' ){
+     sEnd.z += sEnd.n;
+   }
+@@ -102592,6 +108187,9 @@
+ 
+ create_view_fail:
+   sqlite3SelectDelete(db, pSelect);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameExprlistUnmap(pParse, pCNames);
++  }
+   sqlite3ExprListDelete(db, pCNames);
+   return;
+ }
+@@ -102609,6 +108207,9 @@
+   int nErr = 0;     /* Number of errors encountered */
+   int n;            /* Temporarily holds the number of cursors assigned */
+   sqlite3 *db = pParse->db;  /* Database connection for malloc errors */
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  int rc;
++#endif
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+   sqlite3_xauth xAuth;       /* Saved xAuth pointer */
+ #endif
+@@ -102616,8 +108217,11 @@
+   assert( pTable );
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if( sqlite3VtabCallConnect(pParse, pTable) ){
+-    return SQLITE_ERROR;
++  db->nSchemaLock++;
++  rc = sqlite3VtabCallConnect(pParse, pTable);
++  db->nSchemaLock--;
++  if( rc ){
++    return 1;
+   }
+   if( IsVirtual(pTable) ) return 0;
+ #endif
+@@ -102659,6 +108263,10 @@
+   assert( pTable->pSelect );
+   pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+   if( pSel ){
++#ifndef SQLITE_OMIT_ALTERTABLE
++    u8 eParseMode = pParse->eParseMode;
++    pParse->eParseMode = PARSE_MODE_NORMAL;
++#endif
+     n = pParse->nTab;
+     sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+     pTable->nCol = -1;
+@@ -102704,10 +108312,18 @@
+     sqlite3DeleteTable(db, pSelTab);
+     sqlite3SelectDelete(db, pSel);
+     db->lookaside.bDisable--;
++#ifndef SQLITE_OMIT_ALTERTABLE
++    pParse->eParseMode = eParseMode;
++#endif
+   } else {
+     nErr++;
+   }
+   pTable->pSchema->schemaFlags |= DB_UnresetViews;
++  if( db->mallocFailed ){
++    sqlite3DeleteColumnNames(db, pTable);
++    pTable->aCol = 0;
++    pTable->nCol = 0;
++  }
+ #endif /* SQLITE_OMIT_VIEW */
+   return nErr;  
+ }
+@@ -102786,7 +108402,7 @@
+ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
+   Vdbe *v = sqlite3GetVdbe(pParse);
+   int r1 = sqlite3GetTempReg(pParse);
+-  assert( iTable>1 );
++  if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
+   sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
+   sqlite3MayAbort(pParse);
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+@@ -102813,14 +108429,6 @@
+ ** is also added (this can happen with an auto-vacuum database).
+ */
+ static void destroyTable(Parse *pParse, Table *pTab){
+-#ifdef SQLITE_OMIT_AUTOVACUUM
+-  Index *pIdx;
+-  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+-  destroyRootPage(pParse, pTab->tnum, iDb);
+-  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-    destroyRootPage(pParse, pIdx->tnum, iDb);
+-  }
+-#else
+   /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
+   ** is not defined), then it is important to call OP_Destroy on the
+   ** table and index root-pages in order, starting with the numerically 
+@@ -102863,7 +108471,6 @@
+       iDestroyed = iLargest;
+     }
+   }
+-#endif
+ }
+ 
+ /*
+@@ -103055,8 +108662,10 @@
+   v = sqlite3GetVdbe(pParse);
+   if( v ){
+     sqlite3BeginWriteOperation(pParse, 1, iDb);
+-    sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
+-    sqlite3FkDropTable(pParse, pName, pTab);
++    if( !isView ){
++      sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
++      sqlite3FkDropTable(pParse, pName, pTab);
++    }
+     sqlite3CodeDropTable(pParse, pTab, iDb, isView);
+   }
+ 
+@@ -103131,6 +108740,9 @@
+   pFKey->pNextFrom = p->pFKey;
+   z = (char*)&pFKey->aCol[nCol];
+   pFKey->zTo = z;
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)z, pTo);
++  }
+   memcpy(z, pTo->z, pTo->n);
+   z[pTo->n] = 0;
+   sqlite3Dequote(z);
+@@ -103153,6 +108765,9 @@
+           pFromCol->a[i].zName);
+         goto fk_end;
+       }
++      if( IN_RENAME_OBJECT ){
++        sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName);
++      }
+     }
+   }
+   if( pToCol ){
+@@ -103159,6 +108774,9 @@
+     for(i=0; i<nCol; i++){
+       int n = sqlite3Strlen30(pToCol->a[i].zName);
+       pFKey->aCol[i].zCol = z;
++      if( IN_RENAME_OBJECT ){
++        sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName);
++      }
+       memcpy(z, pToCol->a[i].zName, n);
+       z[n] = 0;
+       z += n+1;
+@@ -103267,6 +108885,7 @@
+   sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
+   regRecord = sqlite3GetTempReg(pParse);
++  sqlite3MultiWrite(pParse);
+ 
+   sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
+   sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
+@@ -103280,17 +108899,18 @@
+ 
+   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
+   if( IsUniqueIndex(pIndex) ){
+-    int j2 = sqlite3VdbeCurrentAddr(v) + 3;
+-    sqlite3VdbeGoto(v, j2);
++    int j2 = sqlite3VdbeGoto(v, 1);
+     addr2 = sqlite3VdbeCurrentAddr(v);
++    sqlite3VdbeVerifyAbortable(v, OE_Abort);
+     sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+                          pIndex->nKeyCol); VdbeCoverage(v);
+     sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
++    sqlite3VdbeJumpHere(v, j2);
+   }else{
+     addr2 = sqlite3VdbeCurrentAddr(v);
+   }
+   sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
+-  sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
++  sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+   sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
+   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+   sqlite3ReleaseTempReg(pParse, regRecord);
+@@ -103448,7 +109068,11 @@
+ #if SQLITE_USER_AUTHENTICATION
+        && sqlite3UserAuthTable(pTab->zName)==0
+ #endif
+-       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
++#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
++       && sqlite3StrICmp(&pTab->zName[7],"master")!=0
++#endif
++       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0
++ ){
+     sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
+     goto exit_create_index;
+   }
+@@ -103485,21 +109109,23 @@
+     if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+       goto exit_create_index;
+     }
+-    if( !db->init.busy ){
+-      if( sqlite3FindTable(db, zName, 0)!=0 ){
+-        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
++    if( !IN_RENAME_OBJECT ){
++      if( !db->init.busy ){
++        if( sqlite3FindTable(db, zName, 0)!=0 ){
++          sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
++          goto exit_create_index;
++        }
++      }
++      if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
++        if( !ifNotExist ){
++          sqlite3ErrorMsg(pParse, "index %s already exists", zName);
++        }else{
++          assert( !db->init.busy );
++          sqlite3CodeVerifySchema(pParse, iDb);
++        }
+         goto exit_create_index;
+       }
+     }
+-    if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
+-      if( !ifNotExist ){
+-        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+-      }else{
+-        assert( !db->init.busy );
+-        sqlite3CodeVerifySchema(pParse, iDb);
+-      }
+-      goto exit_create_index;
+-    }
+   }else{
+     int n;
+     Index *pLoop;
+@@ -103514,13 +109140,13 @@
+     ** The following statement converts "sqlite3_autoindex..." into
+     ** "sqlite3_butoindex..." in order to make the names distinct.
+     ** The "vtab_err.test" test demonstrates the need of this statement. */
+-    if( IN_DECLARE_VTAB ) zName[7]++;
++    if( IN_SPECIAL_PARSE ) zName[7]++;
+   }
+ 
+   /* Check for authorization to create an index.
+   */
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  {
++  if( !IN_RENAME_OBJECT ){
+     const char *zDb = pDb->zDbSName;
+     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
+       goto exit_create_index;
+@@ -103539,7 +109165,9 @@
+   */
+   if( pList==0 ){
+     Token prevCol;
+-    sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
++    Column *pCol = &pTab->aCol[pTab->nCol-1];
++    pCol->colFlags |= COLFLAG_UNIQUE;
++    sqlite3TokenInit(&prevCol, pCol->zName);
+     pList = sqlite3ExprListAppend(pParse, 0,
+               sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
+     if( pList==0 ) goto exit_create_index;
+@@ -103605,7 +109233,12 @@
+   ** TODO: Issue a warning if the table primary key is used as part of the
+   ** index key.
+   */
+-  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
++  pListItem = pList->a;
++  if( IN_RENAME_OBJECT ){
++    pIndex->aColExpr = pList;
++    pList = 0;
++  }
++  for(i=0; i<pIndex->nKeyCol; i++, pListItem++){
+     Expr *pCExpr;                  /* The i-th index expression */
+     int requestedSortOrder;        /* ASC or DESC on the i-th expression */
+     const char *zColl;             /* Collation sequence name */
+@@ -103621,12 +109254,8 @@
+         goto exit_create_index;
+       }
+       if( pIndex->aColExpr==0 ){
+-        ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
+-        pIndex->aColExpr = pCopy;
+-        if( !db->mallocFailed ){
+-          assert( pCopy!=0 );
+-          pListItem = &pCopy->a[i];
+-        }
++        pIndex->aColExpr = pList;
++        pList = 0;
+       }
+       j = XN_EXPR;
+       pIndex->aiColumn[i] = XN_EXPR;
+@@ -103692,6 +109321,7 @@
+   ** it as a covering index */
+   assert( HasRowid(pTab) 
+       || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
++  recomputeColumnsNotIndexed(pIndex);
+   if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+     pIndex->isCovering = 1;
+     for(j=0; j<pTab->nCol; j++){
+@@ -103764,98 +109394,101 @@
+     }
+   }
+ 
+-  /* Link the new Index structure to its table and to the other
+-  ** in-memory database structures. 
+-  */
+-  assert( pParse->nErr==0 );
+-  if( db->init.busy ){
+-    Index *p;
+-    assert( !IN_DECLARE_VTAB );
+-    assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+-    p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
+-                          pIndex->zName, pIndex);
+-    if( p ){
+-      assert( p==pIndex );  /* Malloc must have failed */
+-      sqlite3OomFault(db);
+-      goto exit_create_index;
++  if( !IN_RENAME_OBJECT ){
++
++    /* Link the new Index structure to its table and to the other
++    ** in-memory database structures. 
++    */
++    assert( pParse->nErr==0 );
++    if( db->init.busy ){
++      Index *p;
++      assert( !IN_SPECIAL_PARSE );
++      assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
++      p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
++          pIndex->zName, pIndex);
++      if( p ){
++        assert( p==pIndex );  /* Malloc must have failed */
++        sqlite3OomFault(db);
++        goto exit_create_index;
++      }
++      db->mDbFlags |= DBFLAG_SchemaChange;
++      if( pTblName!=0 ){
++        pIndex->tnum = db->init.newTnum;
++      }
+     }
+-    db->flags |= SQLITE_InternChanges;
+-    if( pTblName!=0 ){
+-      pIndex->tnum = db->init.newTnum;
+-    }
+-  }
+ 
+-  /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+-  ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+-  ** emit code to allocate the index rootpage on disk and make an entry for
+-  ** the index in the sqlite_master table and populate the index with
+-  ** content.  But, do not do this if we are simply reading the sqlite_master
+-  ** table to parse the schema, or if this index is the PRIMARY KEY index
+-  ** of a WITHOUT ROWID table.
+-  **
+-  ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+-  ** or UNIQUE index in a CREATE TABLE statement.  Since the table
+-  ** has just been created, it contains no data and the index initialization
+-  ** step can be skipped.
+-  */
+-  else if( HasRowid(pTab) || pTblName!=0 ){
+-    Vdbe *v;
+-    char *zStmt;
+-    int iMem = ++pParse->nMem;
++    /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
++    ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
++    ** emit code to allocate the index rootpage on disk and make an entry for
++    ** the index in the sqlite_master table and populate the index with
++    ** content.  But, do not do this if we are simply reading the sqlite_master
++    ** table to parse the schema, or if this index is the PRIMARY KEY index
++    ** of a WITHOUT ROWID table.
++    **
++    ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
++    ** or UNIQUE index in a CREATE TABLE statement.  Since the table
++    ** has just been created, it contains no data and the index initialization
++    ** step can be skipped.
++    */
++    else if( HasRowid(pTab) || pTblName!=0 ){
++      Vdbe *v;
++      char *zStmt;
++      int iMem = ++pParse->nMem;
+ 
+-    v = sqlite3GetVdbe(pParse);
+-    if( v==0 ) goto exit_create_index;
++      v = sqlite3GetVdbe(pParse);
++      if( v==0 ) goto exit_create_index;
+ 
+-    sqlite3BeginWriteOperation(pParse, 1, iDb);
++      sqlite3BeginWriteOperation(pParse, 1, iDb);
+ 
+-    /* Create the rootpage for the index using CreateIndex. But before
+-    ** doing so, code a Noop instruction and store its address in 
+-    ** Index.tnum. This is required in case this index is actually a 
+-    ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
+-    ** that case the convertToWithoutRowidTable() routine will replace
+-    ** the Noop with a Goto to jump over the VDBE code generated below. */
+-    pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
+-    sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
++      /* Create the rootpage for the index using CreateIndex. But before
++      ** doing so, code a Noop instruction and store its address in 
++      ** Index.tnum. This is required in case this index is actually a 
++      ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
++      ** that case the convertToWithoutRowidTable() routine will replace
++      ** the Noop with a Goto to jump over the VDBE code generated below. */
++      pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
++      sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
+ 
+-    /* Gather the complete text of the CREATE INDEX statement into
+-    ** the zStmt variable
+-    */
+-    if( pStart ){
+-      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+-      if( pName->z[n-1]==';' ) n--;
+-      /* A named index with an explicit CREATE INDEX statement */
+-      zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
+-        onError==OE_None ? "" : " UNIQUE", n, pName->z);
+-    }else{
+-      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
+-      /* zStmt = sqlite3MPrintf(""); */
+-      zStmt = 0;
+-    }
++      /* Gather the complete text of the CREATE INDEX statement into
++      ** the zStmt variable
++      */
++      if( pStart ){
++        int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
++        if( pName->z[n-1]==';' ) n--;
++        /* A named index with an explicit CREATE INDEX statement */
++        zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
++            onError==OE_None ? "" : " UNIQUE", n, pName->z);
++      }else{
++        /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
++        /* zStmt = sqlite3MPrintf(""); */
++        zStmt = 0;
++      }
+ 
+-    /* Add an entry in sqlite_master for this index
+-    */
+-    sqlite3NestedParse(pParse, 
+-        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
+-        db->aDb[iDb].zDbSName, MASTER_NAME,
+-        pIndex->zName,
+-        pTab->zName,
+-        iMem,
+-        zStmt
+-    );
+-    sqlite3DbFree(db, zStmt);
++      /* Add an entry in sqlite_master for this index
++      */
++      sqlite3NestedParse(pParse, 
++          "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
++          db->aDb[iDb].zDbSName, MASTER_NAME,
++          pIndex->zName,
++          pTab->zName,
++          iMem,
++          zStmt
++          );
++      sqlite3DbFree(db, zStmt);
+ 
+-    /* Fill the index with data and reparse the schema. Code an OP_Expire
+-    ** to invalidate all pre-compiled statements.
+-    */
+-    if( pTblName ){
+-      sqlite3RefillIndex(pParse, pIndex, iMem);
+-      sqlite3ChangeCookie(pParse, iDb);
+-      sqlite3VdbeAddParseSchemaOp(v, iDb,
+-         sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
+-      sqlite3VdbeAddOp0(v, OP_Expire);
++      /* Fill the index with data and reparse the schema. Code an OP_Expire
++      ** to invalidate all pre-compiled statements.
++      */
++      if( pTblName ){
++        sqlite3RefillIndex(pParse, pIndex, iMem);
++        sqlite3ChangeCookie(pParse, iDb);
++        sqlite3VdbeAddParseSchemaOp(v, iDb,
++            sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
++        sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
++      }
++
++      sqlite3VdbeJumpHere(v, pIndex->tnum);
+     }
+-
+-    sqlite3VdbeJumpHere(v, pIndex->tnum);
+   }
+ 
+   /* When adding an index to the list of indices for a table, make
+@@ -103879,10 +109512,15 @@
+     }
+     pIndex = 0;
+   }
++  else if( IN_RENAME_OBJECT ){
++    assert( pParse->pNewIndex==0 );
++    pParse->pNewIndex = pIndex;
++    pIndex = 0;
++  }
+ 
+   /* Clean up before exiting */
+ exit_create_index:
+-  if( pIndex ) freeIndex(db, pIndex);
++  if( pIndex ) sqlite3FreeIndex(db, pIndex);
+   sqlite3ExprDelete(db, pPIWhere);
+   sqlite3ExprListDelete(db, pList);
+   sqlite3SrcListDelete(db, pTblName);
+@@ -104051,7 +109689,8 @@
+ **
+ ** A new IdList is returned, or NULL if malloc() fails.
+ */
+-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
++SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){
++  sqlite3 *db = pParse->db;
+   int i;
+   if( pList==0 ){
+     pList = sqlite3DbMallocZero(db, sizeof(IdList) );
+@@ -104069,6 +109708,9 @@
+     return 0;
+   }
+   pList->a[i].zName = sqlite3NameFromToken(db, pToken);
++  if( IN_RENAME_OBJECT && pList->a[i].zName ){
++    sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
++  }
+   return pList;
+ }
+ 
+@@ -104310,10 +109952,17 @@
+     goto append_from_error;
+   }
+   p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
+-  if( p==0 || NEVER(p->nSrc==0) ){
++  if( p==0 ){
+     goto append_from_error;
+   }
++  assert( p->nSrc>0 );
+   pItem = &p->a[p->nSrc-1];
++  assert( (pTable==0)==(pDatabase==0) );
++  assert( pItem->zName==0 || pDatabase!=0 );
++  if( IN_RENAME_OBJECT && pItem->zName ){
++    Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable;
++    sqlite3RenameTokenMap(pParse, pItem->zName, pToken);
++  }
+   assert( pAlias!=0 );
+   if( pAlias->n ){
+     pItem->zAlias = sqlite3NameFromToken(db, pAlias);
+@@ -104337,8 +109986,10 @@
+ */
+ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
+   assert( pIndexedBy!=0 );
+-  if( p && ALWAYS(p->nSrc>0) ){
+-    struct SrcList_item *pItem = &p->a[p->nSrc-1];
++  if( p && pIndexedBy->n>0 ){
++    struct SrcList_item *pItem;
++    assert( p->nSrc>0 );
++    pItem = &p->a[p->nSrc-1];
+     assert( pItem->fg.notIndexed==0 );
+     assert( pItem->fg.isIndexedBy==0 );
+     assert( pItem->fg.isTabFunc==0 );
+@@ -104348,7 +109999,7 @@
+       pItem->fg.notIndexed = 1;
+     }else{
+       pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
+-      pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0);
++      pItem->fg.isIndexedBy = 1;
+     }
+   }
+ }
+@@ -104622,16 +110273,16 @@
+ 
+   sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+   if( pIdx->aColExpr ){
+-    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
++    sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
+   }else{
+     for(j=0; j<pIdx->nKeyCol; j++){
+       char *zCol;
+       assert( pIdx->aiColumn[j]>=0 );
+       zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+-      if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+-      sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
+-      sqlite3StrAccumAppend(&errMsg, ".", 1);
+-      sqlite3StrAccumAppendAll(&errMsg, zCol);
++      if( j ) sqlite3_str_append(&errMsg, ", ", 2);
++      sqlite3_str_appendall(&errMsg, pTab->zName);
++      sqlite3_str_append(&errMsg, ".", 1);
++      sqlite3_str_appendall(&errMsg, zCol);
+     }
+   }
+   zErr = sqlite3StrAccumFinish(&errMsg);
+@@ -104819,6 +110470,18 @@
+       pKey->aSortOrder[i] = pIdx->aSortOrder[i];
+     }
+     if( pParse->nErr ){
++      assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
++      if( pIdx->bNoQuery==0 ){
++        /* Deactivate the index because it contains an unknown collating
++        ** sequence.  The only way to reactive the index is to reload the
++        ** schema.  Adding the missing collating sequence later does not
++        ** reactive the index.  The application had the chance to register
++        ** the missing index using the collation-needed callback.  For
++        ** simplicity, SQLite will not give the application a second chance.
++        */
++        pIdx->bNoQuery = 1;
++        pParse->rc = SQLITE_ERROR_RETRY;
++      }
+       sqlite3KeyInfoUnref(pKey);
+       pKey = 0;
+     }
+@@ -105004,6 +110667,7 @@
+   assert( !p || p->xCmp );
+   if( p==0 ){
+     sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
++    pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
+   }
+   return p;
+ }
+@@ -105193,6 +110857,21 @@
+   }
+   return 0;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
++  int h,               /* Hash of the name */
++  const char *zFunc,   /* Name of function */
++  int nFunc            /* Length of the name */
++){
++  FuncDef *p;
++  for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
++    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
++      return p;
++    }
++  }
++  return 0;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ /*
+ ** Insert a new FuncDef into a FuncDefHash hash table.
+@@ -105206,7 +110885,7 @@
+     FuncDef *pOther;
+     const char *zName = aDef[i].zName;
+     int nName = sqlite3Strlen30(zName);
+-    int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
++    int h = SQLITE_FUNC_HASH(zName[0], nName);
+     assert( zName[0]>='a' && zName[0]<='z' );
+     pOther = functionSearch(h, zName);
+     if( pOther ){
+@@ -105273,7 +110952,7 @@
+ 
+   /* If no match is found, search the built-in functions.
+   **
+-  ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
++  ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
+   ** functions even if a prior app-defined function was found.  And give
+   ** priority to built-in functions.
+   **
+@@ -105283,9 +110962,9 @@
+   ** new function.  But the FuncDefs for built-in functions are read-only.
+   ** So we must not search for built-ins when creating a new function.
+   */ 
+-  if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
++  if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
+     bestScore = 0;
+-    h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
++    h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
+     p = functionSearch(h, zName);
+     while( p ){
+       int score = matchQuality(p, nArg, enc);
+@@ -105304,10 +110983,12 @@
+   if( createFlag && bestScore<FUNC_PERFECT_MATCH && 
+       (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
+     FuncDef *pOther;
++    u8 *z;
+     pBest->zName = (const char*)&pBest[1];
+     pBest->nArg = (u16)nArg;
+     pBest->funcFlags = enc;
+     memcpy((char*)&pBest[1], zName, nName+1);
++    for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z];
+     pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+     if( pOther==pBest ){
+       sqlite3DbFree(db, pBest);
+@@ -105356,8 +111037,8 @@
+   pSchema->pSeqTab = 0;
+   if( pSchema->schemaFlags & DB_SchemaLoaded ){
+     pSchema->iGeneration++;
+-    pSchema->schemaFlags &= ~DB_SchemaLoaded;
+   }
++  pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
+ }
+ 
+ /*
+@@ -105431,6 +111112,39 @@
+   return pTab;
+ }
+ 
++/* Return true if table pTab is read-only.
++**
++** A table is read-only if any of the following are true:
++**
++**   1) It is a virtual table and no implementation of the xUpdate method
++**      has been provided
++**
++**   2) It is a system table (i.e. sqlite_master), this call is not
++**      part of a nested parse and writable_schema pragma has not 
++**      been specified
++**
++**   3) The table is a shadow table, the database connection is in
++**      defensive mode, and the current sqlite3_prepare()
++**      is for a top-level SQL statement.
++*/
++static int tabIsReadOnly(Parse *pParse, Table *pTab){
++  sqlite3 *db;
++  if( IsVirtual(pTab) ){
++    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
++  }
++  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
++  db = pParse->db;
++  if( (pTab->tabFlags & TF_Readonly)!=0 ){
++    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
++  }
++  assert( pTab->tabFlags & TF_Shadow );
++  return (db->flags & SQLITE_Defensive)!=0 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++          && db->pVtabCtx==0
++#endif
++          && db->nVdbeExec==0;
++}
++
+ /*
+ ** Check to make sure the given table is writable.  If it is not
+ ** writable, generate an error message and return 1.  If it is
+@@ -105437,26 +111151,10 @@
+ ** writable return 0;
+ */
+ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+-  /* A table is not writable under the following circumstances:
+-  **
+-  **   1) It is a virtual table and no implementation of the xUpdate method
+-  **      has been provided, or
+-  **   2) It is a system table (i.e. sqlite_master), this call is not
+-  **      part of a nested parse and writable_schema pragma has not 
+-  **      been specified.
+-  **
+-  ** In either case leave an error message in pParse and return non-zero.
+-  */
+-  if( ( IsVirtual(pTab) 
+-     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
+-   || ( (pTab->tabFlags & TF_Readonly)!=0
+-     && (pParse->db->flags & SQLITE_WriteSchema)==0
+-     && pParse->nested==0 )
+-  ){
++  if( tabIsReadOnly(pParse, pTab) ){
+     sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
+     return 1;
+   }
+-
+ #ifndef SQLITE_OMIT_VIEW
+   if( !viewOk && pTab->pSelect ){
+     sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
+@@ -105477,6 +111175,8 @@
+   Parse *pParse,       /* Parsing context */
+   Table *pView,        /* View definition */
+   Expr *pWhere,        /* Optional WHERE clause to be added */
++  ExprList *pOrderBy,  /* Optional ORDER BY clause */
++  Expr *pLimit,        /* Optional LIMIT clause */
+   int iCur             /* Cursor number for ephemeral table */
+ ){
+   SelectDest dest;
+@@ -105493,8 +111193,8 @@
+     assert( pFrom->a[0].pOn==0 );
+     assert( pFrom->a[0].pUsing==0 );
+   }
+-  pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 
+-                          SF_IncludeHidden, 0, 0);
++  pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, 
++                          SF_IncludeHidden, pLimit);
+   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
+   sqlite3Select(pParse, pSel, &dest);
+   sqlite3SelectDelete(db, pSel);
+@@ -105516,21 +111216,23 @@
+   Expr *pWhere,                /* The WHERE clause.  May be null */
+   ExprList *pOrderBy,          /* The ORDER BY clause.  May be null */
+   Expr *pLimit,                /* The LIMIT clause.  May be null */
+-  Expr *pOffset,               /* The OFFSET clause.  May be null */
+   char *zStmtType              /* Either DELETE or UPDATE.  For err msgs. */
+ ){
+-  Expr *pWhereRowid = NULL;    /* WHERE rowid .. */
++  sqlite3 *db = pParse->db;
++  Expr *pLhs = NULL;           /* LHS of IN(SELECT...) operator */
+   Expr *pInClause = NULL;      /* WHERE rowid IN ( select ) */
+-  Expr *pSelectRowid = NULL;   /* SELECT rowid ... */
+   ExprList *pEList = NULL;     /* Expression list contaning only pSelectRowid */
+   SrcList *pSelectSrc = NULL;  /* SELECT rowid FROM x ... (dup of pSrc) */
+   Select *pSelect = NULL;      /* Complete SELECT tree */
++  Table *pTab;
+ 
+   /* Check that there isn't an ORDER BY without a LIMIT clause.
+   */
+-  if( pOrderBy && (pLimit == 0) ) {
++  if( pOrderBy && pLimit==0 ) {
+     sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
+-    goto limit_where_cleanup;
++    sqlite3ExprDelete(pParse->db, pWhere);
++    sqlite3ExprListDelete(pParse->db, pOrderBy);
++    return 0;
+   }
+ 
+   /* We only need to generate a select expression if there
+@@ -105537,8 +111239,6 @@
+   ** is a limit/offset term to enforce.
+   */
+   if( pLimit == 0 ) {
+-    /* if pLimit is null, pOffset will always be null as well. */
+-    assert( pOffset == 0 );
+     return pWhere;
+   }
+ 
+@@ -105551,36 +111251,47 @@
+   **   );
+   */
+ 
+-  pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+-  if( pSelectRowid == 0 ) goto limit_where_cleanup;
+-  pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
+-  if( pEList == 0 ) goto limit_where_cleanup;
++  pTab = pSrc->a[0].pTab;
++  if( HasRowid(pTab) ){
++    pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
++    pEList = sqlite3ExprListAppend(
++        pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
++    );
++  }else{
++    Index *pPk = sqlite3PrimaryKeyIndex(pTab);
++    if( pPk->nKeyCol==1 ){
++      const char *zName = pTab->aCol[pPk->aiColumn[0]].zName;
++      pLhs = sqlite3Expr(db, TK_ID, zName);
++      pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));
++    }else{
++      int i;
++      for(i=0; i<pPk->nKeyCol; i++){
++        Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName);
++        pEList = sqlite3ExprListAppend(pParse, pEList, p);
++      }
++      pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
++      if( pLhs ){
++        pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);
++      }
++    }
++  }
+ 
+   /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
+   ** and the SELECT subtree. */
++  pSrc->a[0].pTab = 0;
+   pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
+-  if( pSelectSrc == 0 ) {
+-    sqlite3ExprListDelete(pParse->db, pEList);
+-    goto limit_where_cleanup;
+-  }
++  pSrc->a[0].pTab = pTab;
++  pSrc->a[0].pIBIndex = 0;
+ 
+   /* generate the SELECT expression tree. */
+-  pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
+-                             pOrderBy,0,pLimit,pOffset);
+-  if( pSelect == 0 ) return 0;
++  pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, 
++      pOrderBy,0,pLimit
++  );
+ 
+   /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
+-  pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+-  pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
++  pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
+   sqlite3PExprAddSelect(pParse, pInClause, pSelect);
+   return pInClause;
+-
+-limit_where_cleanup:
+-  sqlite3ExprDelete(pParse->db, pWhere);
+-  sqlite3ExprListDelete(pParse->db, pOrderBy);
+-  sqlite3ExprDelete(pParse->db, pLimit);
+-  sqlite3ExprDelete(pParse->db, pOffset);
+-  return 0;
+ }
+ #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
+        /*      && !defined(SQLITE_OMIT_SUBQUERY) */
+@@ -105595,7 +111306,9 @@
+ SQLITE_PRIVATE void sqlite3DeleteFrom(
+   Parse *pParse,         /* The parser context */
+   SrcList *pTabList,     /* The table from which we should delete things */
+-  Expr *pWhere           /* The WHERE clause.  May be null */
++  Expr *pWhere,          /* The WHERE clause.  May be null */
++  ExprList *pOrderBy,    /* ORDER BY clause. May be null */
++  Expr *pLimit           /* LIMIT clause. May be null */
+ ){
+   Vdbe *v;               /* The virtual database engine */
+   Table *pTab;           /* The table from which records will be deleted */
+@@ -105610,7 +111323,7 @@
+   AuthContext sContext;  /* Authorization context */
+   NameContext sNC;       /* Name context to resolve expressions in */
+   int iDb;               /* Database number */
+-  int memCnt = -1;       /* Memory cell used for change counting */
++  int memCnt = 0;        /* Memory cell used for change counting */
+   int rcauth;            /* Value returned by authorization callback */
+   int eOnePass;          /* ONEPASS_OFF or _SINGLE or _MULTI */
+   int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
+@@ -105640,6 +111353,7 @@
+   }
+   assert( pTabList->nSrc==1 );
+ 
++
+   /* Locate the table which we want to delete.  This table has to be
+   ** put in an SrcList structure because some of the subroutines we
+   ** will be calling are designed to work with multiple tables and expect
+@@ -105654,16 +111368,26 @@
+ #ifndef SQLITE_OMIT_TRIGGER
+   pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+   isView = pTab->pSelect!=0;
+-  bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
+ #else
+ # define pTrigger 0
+ # define isView 0
+ #endif
++  bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
+ #ifdef SQLITE_OMIT_VIEW
+ # undef isView
+ # define isView 0
+ #endif
+ 
++#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
++  if( !isView ){
++    pWhere = sqlite3LimitWhere(
++        pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
++    );
++    pOrderBy = 0;
++    pLimit = 0;
++  }
++#endif
++
+   /* If pTab is really a view, make sure it has been initialized.
+   */
+   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+@@ -105704,7 +111428,7 @@
+     goto delete_from_cleanup;
+   }
+   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+-  sqlite3BeginWriteOperation(pParse, 1, iDb);
++  sqlite3BeginWriteOperation(pParse, bComplex, iDb);
+ 
+   /* If we are trying to delete from a view, realize that view into
+   ** an ephemeral table.
+@@ -105711,8 +111435,12 @@
+   */
+ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+   if( isView ){
+-    sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
++    sqlite3MaterializeView(pParse, pTab, 
++        pWhere, pOrderBy, pLimit, iTabCur
++    );
+     iDataCur = iIdxCur = iTabCur;
++    pOrderBy = 0;
++    pLimit = 0;
+   }
+ #endif
+ 
+@@ -105728,7 +111456,10 @@
+   /* Initialize the counter of the number of rows deleted, if
+   ** we are counting rows.
+   */
+-  if( db->flags & SQLITE_CountRows ){
++  if( (db->flags & SQLITE_CountRows)!=0
++   && !pParse->nested
++   && !pParse->pTriggerTab
++  ){
+     memCnt = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
+   }
+@@ -105756,7 +111487,7 @@
+     assert( !isView );
+     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+     if( HasRowid(pTab) ){
+-      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
++      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1,
+                         pTab->zName, P4_STATIC);
+     }
+     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+@@ -105801,9 +111532,10 @@
+     eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+     assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
+     assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
++    if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
+   
+     /* Keep track of the number of rows to be deleted */
+-    if( db->flags & SQLITE_CountRows ){
++    if( memCnt ){
+       sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
+     }
+   
+@@ -105816,9 +111548,8 @@
+       }
+       iKey = iPk;
+     }else{
+-      iKey = pParse->nMem + 1;
+-      iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
+-      if( iKey>pParse->nMem ) pParse->nMem = iKey;
++      iKey = ++pParse->nMem;
++      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);
+     }
+   
+     if( eOnePass!=ONEPASS_OFF ){
+@@ -105889,7 +111620,11 @@
+       }
+     }else if( pPk ){
+       addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
+-      sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
++      if( IsVirtual(pTab) ){
++        sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey);
++      }else{
++        sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
++      }
+       assert( nKey==0 );  /* OP_Found will use a composite key */
+     }else{
+       addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+@@ -105902,13 +111637,16 @@
+     if( IsVirtual(pTab) ){
+       const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
+       sqlite3VtabMakeWritable(pParse, pTab);
+-      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
+-      sqlite3VdbeChangeP5(v, OE_Abort);
+       assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
+       sqlite3MayAbort(pParse);
+-      if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
+-        pParse->isMultiWrite = 0;
++      if( eOnePass==ONEPASS_SINGLE ){
++        sqlite3VdbeAddOp1(v, OP_Close, iTabCur);
++        if( sqlite3IsToplevel(pParse) ){
++          pParse->isMultiWrite = 0;
++        }
+       }
++      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
++      sqlite3VdbeChangeP5(v, OE_Abort);
+     }else
+ #endif
+     {
+@@ -105942,7 +111680,7 @@
+   ** generating code because of a call to sqlite3NestedParse(), do not
+   ** invoke the callback function.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
++  if( memCnt ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
+@@ -105952,6 +111690,10 @@
+   sqlite3AuthContextPop(&sContext);
+   sqlite3SrcListDelete(db, pTabList);
+   sqlite3ExprDelete(db, pWhere);
++#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
++  sqlite3ExprListDelete(db, pOrderBy);
++  sqlite3ExprDelete(db, pLimit);
++#endif
+   sqlite3DbFree(db, aToOpen);
+   return;
+ }
+@@ -106109,7 +111851,7 @@
+     u8 p5 = 0;
+     sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
+     sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
+-    if( pParse->nested==0 ){
++    if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
+       sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
+     }
+     if( eMode!=ONEPASS_OFF ){
+@@ -106240,7 +111982,6 @@
+     if( pIdx->pPartIdxWhere ){
+       *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+       pParse->iSelfTab = iDataCur + 1;
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
+                             SQLITE_JUMPIFNULL);
+       pParse->iSelfTab = 0;
+@@ -106287,7 +112028,6 @@
+ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
+   if( iLabel ){
+     sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
+-    sqlite3ExprCachePop(pParse);
+   }
+ }
+ 
+@@ -106330,6 +112070,8 @@
+ ** iteration of the aggregate loop.
+ */
+ static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
++  assert( context->isError<=0 );
++  context->isError = -1;
+   context->skipFlag = 1;
+ }
+ 
+@@ -106396,8 +112138,6 @@
+   int argc,
+   sqlite3_value **argv
+ ){
+-  int len;
+-
+   assert( argc==1 );
+   UNUSED_PARAMETER(argc);
+   switch( sqlite3_value_type(argv[0]) ){
+@@ -106409,13 +112149,17 @@
+     }
+     case SQLITE_TEXT: {
+       const unsigned char *z = sqlite3_value_text(argv[0]);
++      const unsigned char *z0;
++      unsigned char c;
+       if( z==0 ) return;
+-      len = 0;
+-      while( *z ){
+-        len++;
+-        SQLITE_SKIP_UTF8(z);
++      z0 = z;
++      while( (c = *z)!=0 ){
++        z++;
++        if( c>=0xc0 ){
++          while( (*z & 0xc0)==0x80 ){ z++; z0++; }
++        }
+       }
+-      sqlite3_result_int(context, len);
++      sqlite3_result_int(context, (int)(z-z0));
+       break;
+     }
+     default: {
+@@ -106542,7 +112286,7 @@
+     x.apArg = argv+1;
+     sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+     str.printfFlags = SQLITE_PRINTF_SQLFUNC;
+-    sqlite3XPrintf(&str, zFormat, &x);
++    sqlite3_str_appendf(&str, zFormat, &x);
+     n = str.nChar;
+     sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+                         SQLITE_DYNAMIC);
+@@ -106993,16 +112737,20 @@
+       ** c or cx.
+       */
+       if( c<=0x80 ){
+-        u32 cx;
++        char zStop[3];
+         int bMatch;
+         if( noCase ){
+-          cx = sqlite3Toupper(c);
+-          c = sqlite3Tolower(c);
++          zStop[0] = sqlite3Toupper(c);
++          zStop[1] = sqlite3Tolower(c);
++          zStop[2] = 0;
+         }else{
+-          cx = c;
++          zStop[0] = c;
++          zStop[1] = 0;
+         }
+-        while( (c2 = *(zString++))!=0 ){
+-          if( c2!=c && c2!=cx ) continue;
++        while(1){
++          zString += strcspn((const char*)zString, zStop);
++          if( zString[0]==0 ) break;
++          zString++;
+           bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+           if( bMatch!=SQLITE_NOMATCH ) return bMatch;
+         }
+@@ -107160,7 +112908,8 @@
+ #ifdef SQLITE_TEST
+     sqlite3_like_count++;
+ #endif
+-    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
++    sqlite3_result_int(context,
++                      patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
+   }
+ }
+ 
+@@ -107485,6 +113234,8 @@
+   i64 nOut;                /* Maximum size of zOut */
+   int loopLimit;           /* Last zStr[] that might match zPattern[] */
+   int i, j;                /* Loop counters */
++  unsigned cntExpand;      /* Number zOut expansions */
++  sqlite3 *db = sqlite3_context_db_handle(context);
+ 
+   assert( argc==3 );
+   UNUSED_PARAMETER(argc);
+@@ -107516,33 +113267,40 @@
+     return;
+   }
+   loopLimit = nStr - nPattern;  
++  cntExpand = 0;
+   for(i=j=0; i<=loopLimit; i++){
+     if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
+       zOut[j++] = zStr[i];
+     }else{
+-      u8 *zOld;
+-      sqlite3 *db = sqlite3_context_db_handle(context);
+-      nOut += nRep - nPattern;
+-      testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
+-      testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
+-      if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-        sqlite3_result_error_toobig(context);
+-        sqlite3_free(zOut);
+-        return;
++      if( nRep>nPattern ){
++        nOut += nRep - nPattern;
++        testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
++        testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
++        if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
++          sqlite3_result_error_toobig(context);
++          sqlite3_free(zOut);
++          return;
++        }
++        cntExpand++;
++        if( (cntExpand&(cntExpand-1))==0 ){
++          /* Grow the size of the output buffer only on substitutions
++          ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */
++          u8 *zOld;
++          zOld = zOut;
++          zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1));
++          if( zOut==0 ){
++            sqlite3_result_error_nomem(context);
++            sqlite3_free(zOld);
++            return;
++          }
++        }
+       }
+-      zOld = zOut;
+-      zOut = sqlite3_realloc64(zOut, (int)nOut);
+-      if( zOut==0 ){
+-        sqlite3_result_error_nomem(context);
+-        sqlite3_free(zOld);
+-        return;
+-      }
+       memcpy(&zOut[j], zRep, nRep);
+       j += nRep;
+       i += nPattern-1;
+     }
+   }
+-  assert( j+nStr-i+1==nOut );
++  assert( j+nStr-i+1<=nOut );
+   memcpy(&zOut[j], &zStr[i], nStr-i);
+   j += nStr - i;
+   assert( j<=nOut );
+@@ -107782,7 +113540,7 @@
+       i64 v = sqlite3_value_int64(argv[0]);
+       p->rSum += v;
+       if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
+-        p->overflow = 1;
++        p->approx = p->overflow = 1;
+       }
+     }else{
+       p->rSum += sqlite3_value_double(argv[0]);
+@@ -107790,6 +113548,32 @@
+     }
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
++  SumCtx *p;
++  int type;
++  assert( argc==1 );
++  UNUSED_PARAMETER(argc);
++  p = sqlite3_aggregate_context(context, sizeof(*p));
++  type = sqlite3_value_numeric_type(argv[0]);
++  /* p is always non-NULL because sumStep() will have been called first
++  ** to initialize it */
++  if( ALWAYS(p) && type!=SQLITE_NULL ){
++    assert( p->cnt>0 );
++    p->cnt--;
++    assert( type==SQLITE_INTEGER || p->approx );
++    if( type==SQLITE_INTEGER && p->approx==0 ){
++      i64 v = sqlite3_value_int64(argv[0]);
++      p->rSum -= v;
++      p->iSum -= v;
++    }else{
++      p->rSum -= sqlite3_value_double(argv[0]);
++    }
++  }
++}
++#else
++# define sumInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ static void sumFinalize(sqlite3_context *context){
+   SumCtx *p;
+   p = sqlite3_aggregate_context(context, 0);
+@@ -107824,6 +113608,9 @@
+ typedef struct CountCtx CountCtx;
+ struct CountCtx {
+   i64 n;
++#ifdef SQLITE_DEBUG
++  int bInverse;                   /* True if xInverse() ever called */
++#endif
+ };
+ 
+ /*
+@@ -107841,7 +113628,7 @@
+   ** sure it still operates correctly, verify that its count agrees with our 
+   ** internal count when using count(*) and when the total count can be
+   ** expressed as a 32-bit integer. */
+-  assert( argc==1 || p==0 || p->n>0x7fffffff
++  assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse
+           || p->n==sqlite3_aggregate_count(context) );
+ #endif
+ }   
+@@ -107850,6 +113637,21 @@
+   p = sqlite3_aggregate_context(context, 0);
+   sqlite3_result_int64(context, p ? p->n : 0);
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){
++  CountCtx *p;
++  p = sqlite3_aggregate_context(ctx, sizeof(*p));
++  /* p is always non-NULL since countStep() will have been called first */
++  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){
++    p->n--;
++#ifdef SQLITE_DEBUG
++    p->bInverse = 1;
++#endif
++  }
++}   
++#else
++# define countInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ 
+ /*
+ ** Routines to implement min() and max() aggregate functions.
+@@ -107866,7 +113668,7 @@
+   pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
+   if( !pBest ) return;
+ 
+-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
++  if( sqlite3_value_type(pArg)==SQLITE_NULL ){
+     if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
+   }else if( pBest->flags ){
+     int max;
+@@ -107892,7 +113694,7 @@
+     sqlite3VdbeMemCopy(pBest, pArg);
+   }
+ }
+-static void minMaxFinalize(sqlite3_context *context){
++static void minMaxValueFinalize(sqlite3_context *context, int bValue){
+   sqlite3_value *pRes;
+   pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
+   if( pRes ){
+@@ -107899,9 +113701,19 @@
+     if( pRes->flags ){
+       sqlite3_result_value(context, pRes);
+     }
+-    sqlite3VdbeMemRelease(pRes);
++    if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void minMaxValue(sqlite3_context *context){
++  minMaxValueFinalize(context, 1);
++}
++#else
++# define minMaxValue 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++static void minMaxFinalize(sqlite3_context *context){
++  minMaxValueFinalize(context, 0);
++}
+ 
+ /*
+ ** group_concat(EXPR, ?SEPARATOR?)
+@@ -107931,20 +113743,52 @@
+         zSep = ",";
+         nSep = 1;
+       }
+-      if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
++      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
+     }
+     zVal = (char*)sqlite3_value_text(argv[0]);
+     nVal = sqlite3_value_bytes(argv[0]);
+-    if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
++    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void groupConcatInverse(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  int n;
++  StrAccum *pAccum;
++  assert( argc==1 || argc==2 );
++  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
++  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
++  /* pAccum is always non-NULL since groupConcatStep() will have always
++  ** run frist to initialize it */
++  if( ALWAYS(pAccum) ){
++    n = sqlite3_value_bytes(argv[0]);
++    if( argc==2 ){
++      n += sqlite3_value_bytes(argv[1]);
++    }else{
++      n++;
++    }
++    if( n>=(int)pAccum->nChar ){
++      pAccum->nChar = 0;
++    }else{
++      pAccum->nChar -= n;
++      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
++    }
++    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
++  }
++}
++#else
++# define groupConcatInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ static void groupConcatFinalize(sqlite3_context *context){
+   StrAccum *pAccum;
+   pAccum = sqlite3_aggregate_context(context, 0);
+   if( pAccum ){
+-    if( pAccum->accError==STRACCUM_TOOBIG ){
++    if( pAccum->accError==SQLITE_TOOBIG ){
+       sqlite3_result_error_toobig(context);
+-    }else if( pAccum->accError==STRACCUM_NOMEM ){
++    }else if( pAccum->accError==SQLITE_NOMEM ){
+       sqlite3_result_error_nomem(context);
+     }else{    
+       sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
+@@ -107952,6 +113796,24 @@
+     }
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void groupConcatValue(sqlite3_context *context){
++  sqlite3_str *pAccum;
++  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
++  if( pAccum ){
++    if( pAccum->accError==SQLITE_TOOBIG ){
++      sqlite3_result_error_toobig(context);
++    }else if( pAccum->accError==SQLITE_NOMEM ){
++      sqlite3_result_error_nomem(context);
++    }else{    
++      const char *zText = sqlite3_str_value(pAccum);
++      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
++    }
++  }
++}
++#else
++# define groupConcatValue 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ 
+ /*
+ ** This routine does per-connection function registration.  Most
+@@ -107989,10 +113851,10 @@
+   }else{
+     pInfo = (struct compareInfo*)&likeInfoNorm;
+   }
+-  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
+-  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
++  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
++  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
+   sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
+-      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
++      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
+   setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
+   setLikeOptFlag(db, "like", 
+       caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+@@ -108001,10 +113863,15 @@
+ /*
+ ** pExpr points to an expression which implements a function.  If
+ ** it is appropriate to apply the LIKE optimization to that function
+-** then set aWc[0] through aWc[2] to the wildcard characters and
+-** return TRUE.  If the function is not a LIKE-style function then
+-** return FALSE.
++** then set aWc[0] through aWc[2] to the wildcard characters and the
++** escape character and then return TRUE.  If the function is not a 
++** LIKE-style function then return FALSE.
+ **
++** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
++** operator if c is a string literal that is exactly one byte in length.
++** That one byte is stored in aWc[3].  aWc[3] is set to zero if there is
++** no ESCAPE clause.
++**
+ ** *pIsNocase is set to true if uppercase and lowercase are equivalent for
+ ** the function (default for LIKE).  If the function makes the distinction
+ ** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
+@@ -108012,17 +113879,26 @@
+ */
+ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
+   FuncDef *pDef;
+-  if( pExpr->op!=TK_FUNCTION 
+-   || !pExpr->x.pList 
+-   || pExpr->x.pList->nExpr!=2
+-  ){
++  int nExpr;
++  if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){
+     return 0;
+   }
+   assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+-  pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
++  nExpr = pExpr->x.pList->nExpr;
++  pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
+   if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
+     return 0;
+   }
++  if( nExpr<3 ){
++    aWc[3] = 0;
++  }else{
++    Expr *pEscape = pExpr->x.pList->a[2].pExpr;
++    char *zEscape;
++    if( pEscape->op!=TK_STRING ) return 0;
++    zEscape = pEscape->u.zToken;
++    if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
++    aWc[3] = zEscape[0];
++  }
+ 
+   /* The memcpy() statement assumes that the wildcard characters are
+   ** the first three statements in the compareInfo structure.  The
+@@ -108075,6 +113951,10 @@
+ #ifdef SQLITE_DEBUG
+     FUNCTION2(affinity,          1, 0, 0, noopFunc,  SQLITE_FUNC_AFFINITY),
+ #endif
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
++    FUNCTION2(sqlite_offset,     1, 0, 0, noopFunc,  SQLITE_FUNC_OFFSET|
++                                                     SQLITE_FUNC_TYPEOF),
++#endif
+     FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
+     FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
+     FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
+@@ -108083,11 +113963,11 @@
+     FUNCTION(trim,               2, 3, 0, trimFunc         ),
+     FUNCTION(min,               -1, 0, 1, minmaxFunc       ),
+     FUNCTION(min,                0, 0, 1, 0                ),
+-    AGGREGATE2(min,              1, 0, 1, minmaxStep,      minMaxFinalize,
++    WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
+                                           SQLITE_FUNC_MINMAX ),
+     FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
+     FUNCTION(max,                0, 1, 1, 0                ),
+-    AGGREGATE2(max,              1, 1, 1, minmaxStep,      minMaxFinalize,
++    WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
+                                           SQLITE_FUNC_MINMAX ),
+     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
+     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
+@@ -108118,14 +113998,17 @@
+     FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
+     FUNCTION(substr,             2, 0, 0, substrFunc       ),
+     FUNCTION(substr,             3, 0, 0, substrFunc       ),
+-    AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
+-    AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
+-    AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
+-    AGGREGATE2(count,            0, 0, 0, countStep,       countFinalize,
+-               SQLITE_FUNC_COUNT  ),
+-    AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
+-    AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
+-    AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
++    WAGGREGATE(sum,   1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
++    WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0),
++    WAGGREGATE(avg,   1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0),
++    WAGGREGATE(count, 0,0,0, countStep, 
++        countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT  ),
++    WAGGREGATE(count, 1,0,0, countStep, 
++        countFinalize, countFinalize, countInverse, 0  ),
++    WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, 
++        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
++    WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, 
++        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
+   
+     LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+ #ifdef SQLITE_CASE_SENSITIVE_LIKE
+@@ -108145,6 +114028,7 @@
+ #ifndef SQLITE_OMIT_ALTERTABLE
+   sqlite3AlterFunctions();
+ #endif
++  sqlite3WindowFunctions();
+ #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+   sqlite3AnalyzeFunctions();
+ #endif
+@@ -108503,6 +114387,12 @@
+   int iCur = pParse->nTab - 1;              /* Cursor number to use */
+   int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */
+ 
++  sqlite3VdbeVerifyAbortable(v,
++    (!pFKey->isDeferred
++      && !(pParse->db->flags & SQLITE_DeferFKs)
++      && !pParse->pToplevel 
++      && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore);
++
+   /* If nIncr is less than zero, then check at runtime if there are any
+   ** outstanding constraints to resolve. If there are not, there is no need
+   ** to check if deleting this row resolves any outstanding violations.
+@@ -108668,7 +114558,7 @@
+ ){
+   Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+   if( pExpr ){
+-    pExpr->pTab = pTab;
++    pExpr->y.pTab = pTab;
+     pExpr->iTable = iCursor;
+     pExpr->iColumn = iCol;
+   }
+@@ -108876,11 +114766,12 @@
+ */
+ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
+   sqlite3 *db = pParse->db;
+-  if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
++  if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){
+     int iSkip = 0;
+     Vdbe *v = sqlite3GetVdbe(pParse);
+ 
+     assert( v );                  /* VDBE has already been allocated */
++    assert( pTab->pSelect==0 );   /* Not a view */
+     if( sqlite3FkReferences(pTab)==0 ){
+       /* Search for a deferred foreign key constraint for which this table
+       ** is the child table. If one cannot be found, return without 
+@@ -108897,7 +114788,7 @@
+     }
+ 
+     pParse->disableTriggers = 1;
+-    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
++    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
+     pParse->disableTriggers = 0;
+ 
+     /* If the DELETE has generated immediate foreign key constraint 
+@@ -108910,6 +114801,7 @@
+     ** constraints are violated.
+     */
+     if( (db->flags & SQLITE_DeferFKs)==0 ){
++      sqlite3VdbeVerifyAbortable(v, OE_Abort);
+       sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+       VdbeCoverage(v);
+       sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+@@ -109455,7 +115347,7 @@
+           sqlite3ExprListAppend(pParse, 0, pRaise),
+           sqlite3SrcListAppend(db, 0, &tFrom, 0),
+           pWhere,
+-          0, 0, 0, 0, 0, 0
++          0, 0, 0, 0, 0
+       );
+       pWhere = 0;
+     }
+@@ -109742,7 +115634,8 @@
+     }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
+     pTab->zColAff = zColAff;
+   }
+-  i = sqlite3Strlen30(zColAff);
++  assert( zColAff!=0 );
++  i = sqlite3Strlen30NN(zColAff);
+   if( i ){
+     if( iReg ){
+       sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
+@@ -109806,11 +115699,12 @@
+ ** first use of table pTab.  On 2nd and subsequent uses, the original
+ ** AutoincInfo structure is used.
+ **
+-** Three memory locations are allocated:
++** Four consecutive registers are allocated:
+ **
+-**   (1)  Register to hold the name of the pTab table.
+-**   (2)  Register to hold the maximum ROWID of pTab.
+-**   (3)  Register to hold the rowid in sqlite_sequence of pTab
++**   (1)  The name of the pTab table.
++**   (2)  The maximum ROWID of pTab.
++**   (3)  The rowid in sqlite_sequence of pTab
++**   (4)  The original value of the max ROWID in pTab, or NULL if none
+ **
+ ** The 2nd register is the one that is returned.  That is all the
+ ** insert routine needs to know about.
+@@ -109821,12 +115715,27 @@
+   Table *pTab         /* The table we are writing to */
+ ){
+   int memId = 0;      /* Register holding maximum rowid */
++  assert( pParse->db->aDb[iDb].pSchema!=0 );
+   if( (pTab->tabFlags & TF_Autoincrement)!=0
+-   && (pParse->db->flags & SQLITE_Vacuum)==0
++   && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
+   ){
+     Parse *pToplevel = sqlite3ParseToplevel(pParse);
+     AutoincInfo *pInfo;
++    Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
+ 
++    /* Verify that the sqlite_sequence table exists and is an ordinary
++    ** rowid table with exactly two columns.
++    ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */
++    if( pSeqTab==0
++     || !HasRowid(pSeqTab)
++     || IsVirtual(pSeqTab)
++     || pSeqTab->nCol!=2
++    ){
++      pParse->nErr++;
++      pParse->rc = SQLITE_CORRUPT_SEQUENCE;
++      return 0;
++    }
++
+     pInfo = pToplevel->pAinc;
+     while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
+     if( pInfo==0 ){
+@@ -109838,7 +115747,7 @@
+       pInfo->iDb = iDb;
+       pToplevel->nMem++;                  /* Register to hold name of table */
+       pInfo->regCtr = ++pToplevel->nMem;  /* Max rowid register */
+-      pToplevel->nMem++;                  /* Rowid in sqlite_sequence */
++      pToplevel->nMem +=2;       /* Rowid in sqlite_sequence + orig max val */
+     }
+     memId = pInfo->regCtr;
+   }
+@@ -109866,15 +115775,17 @@
+     static const int iLn = VDBE_OFFSET_LINENO(2);
+     static const VdbeOpList autoInc[] = {
+       /* 0  */ {OP_Null,    0,  0, 0},
+-      /* 1  */ {OP_Rewind,  0,  9, 0},
++      /* 1  */ {OP_Rewind,  0, 10, 0},
+       /* 2  */ {OP_Column,  0,  0, 0},
+-      /* 3  */ {OP_Ne,      0,  7, 0},
++      /* 3  */ {OP_Ne,      0,  9, 0},
+       /* 4  */ {OP_Rowid,   0,  0, 0},
+       /* 5  */ {OP_Column,  0,  1, 0},
+-      /* 6  */ {OP_Goto,    0,  9, 0},
+-      /* 7  */ {OP_Next,    0,  2, 0},
+-      /* 8  */ {OP_Integer, 0,  0, 0},
+-      /* 9  */ {OP_Close,   0,  0, 0} 
++      /* 6  */ {OP_AddImm,  0,  0, 0},
++      /* 7  */ {OP_Copy,    0,  0, 0},
++      /* 8  */ {OP_Goto,    0, 11, 0},
++      /* 9  */ {OP_Next,    0,  2, 0},
++      /* 10 */ {OP_Integer, 0,  0, 0},
++      /* 11 */ {OP_Close,   0,  0, 0} 
+     };
+     VdbeOp *aOp;
+     pDb = &db->aDb[p->iDb];
+@@ -109885,7 +115796,7 @@
+     aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn);
+     if( aOp==0 ) break;
+     aOp[0].p2 = memId;
+-    aOp[0].p3 = memId+1;
++    aOp[0].p3 = memId+2;
+     aOp[2].p3 = memId;
+     aOp[3].p1 = memId-1;
+     aOp[3].p3 = memId;
+@@ -109892,7 +115803,10 @@
+     aOp[3].p5 = SQLITE_JUMPIFNULL;
+     aOp[4].p2 = memId+1;
+     aOp[5].p3 = memId;
+-    aOp[8].p2 = memId;
++    aOp[6].p1 = memId;
++    aOp[7].p2 = memId+2;
++    aOp[7].p1 = memId;
++    aOp[10].p2 = memId;
+   }
+ }
+ 
+@@ -109939,6 +115853,8 @@
+ 
+     iRec = sqlite3GetTempReg(pParse);
+     assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
++    sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId);
++    VdbeCoverage(v);
+     sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
+     aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn);
+     if( aOp==0 ) break;
+@@ -110076,11 +115992,11 @@
+   SrcList *pTabList,    /* Name of table into which we are inserting */
+   Select *pSelect,      /* A SELECT statement to use as the data source */
+   IdList *pColumn,      /* Column names corresponding to IDLIST. */
+-  int onError           /* How to handle constraint errors */
++  int onError,          /* How to handle constraint errors */
++  Upsert *pUpsert       /* ON CONFLICT clauses for upsert, or NULL */
+ ){
+   sqlite3 *db;          /* The main database structure */
+   Table *pTab;          /* The table to insert into.  aka TABLE */
+-  char *zTab;           /* Name of the table into which we are inserting */
+   int i, j;             /* Loop counters */
+   Vdbe *v;              /* Generate code into this virtual machine */
+   Index *pIdx;          /* For looping over indices of the table */
+@@ -110136,8 +116052,6 @@
+   /* Locate the table into which we will be inserting new information.
+   */
+   assert( pTabList->nSrc==1 );
+-  zTab = pTabList->a[0].zName;
+-  if( NEVER(zTab==0) ) goto insert_cleanup;
+   pTab = sqlite3SrcListLookup(pParse, pTabList);
+   if( pTab==0 ){
+     goto insert_cleanup;
+@@ -110374,7 +116288,10 @@
+     
+   /* Initialize the count of rows to be inserted
+   */
+-  if( db->flags & SQLITE_CountRows ){
++  if( (db->flags & SQLITE_CountRows)!=0
++   && !pParse->nested
++   && !pParse->pTriggerTab
++  ){
+     regRowCount = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+   }
+@@ -110394,7 +116311,20 @@
+       pParse->nMem += pIdx->nColumn;
+     }
+   }
++#ifndef SQLITE_OMIT_UPSERT
++  if( pUpsert ){
++    pTabList->a[0].iCursor = iDataCur;
++    pUpsert->pUpsertSrc = pTabList;
++    pUpsert->regData = regData;
++    pUpsert->iDataCur = iDataCur;
++    pUpsert->iIdxCur = iIdxCur;
++    if( pUpsert->pUpsertTarget ){
++      sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert);
++    }
++  }
++#endif
+ 
++
+   /* This is the top of the main insertion loop */
+   if( useTempTable ){
+     /* This block codes the top of loop only.  The complete loop is the
+@@ -110508,7 +116438,8 @@
+         VdbeOp *pOp;
+         sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
+         pOp = sqlite3VdbeGetOp(v, -1);
+-        if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
++        assert( pOp!=0 );
++        if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+           appendFlag = 1;
+           pOp->opcode = OP_NewRowid;
+           pOp->p1 = iDataCur;
+@@ -110595,7 +116526,7 @@
+       int isReplace;    /* Set to true if constraints may cause a replace */
+       int bUseSeek;     /* True to use OPFLAG_SEEKRESULT */
+       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+-          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
++          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert
+       );
+       sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+ 
+@@ -110618,7 +116549,7 @@
+ 
+   /* Update the count of rows that are inserted
+   */
+-  if( (db->flags & SQLITE_CountRows)!=0 ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+   }
+ 
+@@ -110655,7 +116586,7 @@
+   ** generating code because of a call to sqlite3NestedParse(), do not
+   ** invoke the callback function.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
+@@ -110664,6 +116595,7 @@
+ insert_cleanup:
+   sqlite3SrcListDelete(db, pTabList);
+   sqlite3ExprListDelete(db, pList);
++  sqlite3UpsertDelete(db, pUpsert);
+   sqlite3SelectDelete(db, pSelect);
+   sqlite3IdListDelete(db, pColumn);
+   sqlite3DbFree(db, aRegIdx);
+@@ -110683,14 +116615,15 @@
+ #endif
+ 
+ /*
+-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
++** Meanings of bits in of pWalker->eCode for 
++** sqlite3ExprReferencesUpdatedColumn()
+ */
+ #define CKCNSTRNT_COLUMN   0x01    /* CHECK constraint uses a changing column */
+ #define CKCNSTRNT_ROWID    0x02    /* CHECK constraint references the ROWID */
+ 
+-/* This is the Walker callback from checkConstraintUnchanged().  Set
+-** bit 0x01 of pWalker->eCode if
+-** pWalker->eCode to 0 if this expression node references any of the
++/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
++*  Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
++** expression node references any of the
+ ** columns that are being modifed by an UPDATE statement.
+ */
+ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
+@@ -110712,12 +116645,21 @@
+ ** only columns that are modified by the UPDATE are those for which
+ ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
+ **
+-** Return true if CHECK constraint pExpr does not use any of the
++** Return true if CHECK constraint pExpr uses any of the
+ ** changing columns (or the rowid if it is changing).  In other words,
+-** return true if this CHECK constraint can be skipped when validating
++** return true if this CHECK constraint must be validated for
+ ** the new row in the UPDATE statement.
++**
++** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
++** The operation of this routine is the same - return true if an only if
++** the expression uses one or more of columns identified by the second and
++** third arguments.
+ */
+-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
++SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
++  Expr *pExpr,    /* The expression to be checked */
++  int *aiChng,    /* aiChng[x]>=0 if column x changed by the UPDATE */
++  int chngRowid   /* True if UPDATE changes the rowid */
++){
+   Walker w;
+   memset(&w, 0, sizeof(w));
+   w.eCode = 0;
+@@ -110732,7 +116674,7 @@
+   testcase( w.eCode==CKCNSTRNT_COLUMN );
+   testcase( w.eCode==CKCNSTRNT_ROWID );
+   testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
+-  return !w.eCode;
++  return w.eCode!=0;
+ }
+ 
+ /*
+@@ -110830,7 +116772,8 @@
+   u8 overrideError,    /* Override onError to this if not OE_Default */
+   int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
+   int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
+-  int *aiChng          /* column i is unchanged if aiChng[i]<0 */
++  int *aiChng,         /* column i is unchanged if aiChng[i]<0 */
++  Upsert *pUpsert      /* ON CONFLICT clauses, if any.  NULL otherwise */
+ ){
+   Vdbe *v;             /* VDBE under constrution */
+   Index *pIdx;         /* Pointer to one of the indices */
+@@ -110843,10 +116786,13 @@
+   int addr1;           /* Address of jump instruction */
+   int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
+   int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+-  int ipkTop = 0;      /* Top of the rowid change constraint check */
+-  int ipkBottom = 0;   /* Bottom of the rowid change constraint check */
++  Index *pUpIdx = 0;   /* Index to which to apply the upsert */
+   u8 isUpdate;         /* True if this is an UPDATE operation */
+   u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
++  int upsertBypass = 0;  /* Address of Goto to bypass upsert subroutine */
++  int upsertJump = 0;    /* Address of Goto that jumps into upsert subroutine */
++  int ipkTop = 0;        /* Top of the IPK uniqueness check */
++  int ipkBottom = 0;     /* OP_Goto at the end of the IPK uniqueness check */
+ 
+   isUpdate = regOldData!=0;
+   db = pParse->db;
+@@ -110934,8 +116880,15 @@
+     for(i=0; i<pCheck->nExpr; i++){
+       int allOk;
+       Expr *pExpr = pCheck->a[i].pExpr;
+-      if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
++      if( aiChng
++       && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
++      ){
++        /* The check constraints do not reference any of the columns being
++        ** updated so there is no point it verifying the check constraint */
++        continue;
++      }
+       allOk = sqlite3VdbeMakeLabel(v);
++      sqlite3VdbeVerifyAbortable(v, onError);
+       sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
+       if( onError==OE_Ignore ){
+         sqlite3VdbeGoto(v, ignoreDest);
+@@ -110953,6 +116906,50 @@
+   }
+ #endif /* !defined(SQLITE_OMIT_CHECK) */
+ 
++  /* UNIQUE and PRIMARY KEY constraints should be handled in the following
++  ** order:
++  **
++  **   (1)  OE_Update
++  **   (2)  OE_Abort, OE_Fail, OE_Rollback, OE_Ignore
++  **   (3)  OE_Replace
++  **
++  ** OE_Fail and OE_Ignore must happen before any changes are made.
++  ** OE_Update guarantees that only a single row will change, so it
++  ** must happen before OE_Replace.  Technically, OE_Abort and OE_Rollback
++  ** could happen in any order, but they are grouped up front for
++  ** convenience.
++  **
++  ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43
++  ** The order of constraints used to have OE_Update as (2) and OE_Abort
++  ** and so forth as (1). But apparently PostgreSQL checks the OE_Update
++  ** constraint before any others, so it had to be moved.
++  **
++  ** Constraint checking code is generated in this order:
++  **   (A)  The rowid constraint
++  **   (B)  Unique index constraints that do not have OE_Replace as their
++  **        default conflict resolution strategy
++  **   (C)  Unique index that do use OE_Replace by default.
++  **
++  ** The ordering of (2) and (3) is accomplished by making sure the linked
++  ** list of indexes attached to a table puts all OE_Replace indexes last
++  ** in the list.  See sqlite3CreateIndex() for where that happens.
++  */
++
++  if( pUpsert ){
++    if( pUpsert->pUpsertTarget==0 ){
++      /* An ON CONFLICT DO NOTHING clause, without a constraint-target.
++      ** Make all unique constraint resolution be OE_Ignore */
++      assert( pUpsert->pUpsertSet==0 );
++      overrideError = OE_Ignore;
++      pUpsert = 0;
++    }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){
++      /* If the constraint-target uniqueness check must be run first.
++      ** Jump to that uniqueness check now */
++      upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
++      VdbeComment((v, "UPSERT constraint goes first"));
++    }
++  }
++
+   /* If rowid is changing, make sure the new rowid does not previously
+   ** exist in the table.
+   */
+@@ -110967,6 +116964,28 @@
+       onError = OE_Abort;
+     }
+ 
++    /* figure out whether or not upsert applies in this case */
++    if( pUpsert && pUpsert->pUpsertIdx==0 ){
++      if( pUpsert->pUpsertSet==0 ){
++        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
++      }else{
++        onError = OE_Update;  /* DO UPDATE */
++      }
++    }
++
++    /* If the response to a rowid conflict is REPLACE but the response
++    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
++    ** to defer the running of the rowid conflict checking until after
++    ** the UNIQUE constraints have run.
++    */
++    if( onError==OE_Replace      /* IPK rule is REPLACE */
++     && onError!=overrideError   /* Rules for other contraints are different */
++     && pTab->pIndex             /* There exist other constraints */
++    ){
++      ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
++      VdbeComment((v, "defer IPK REPLACE until last"));
++    }
++
+     if( isUpdate ){
+       /* pkChng!=0 does not mean that the rowid has changed, only that
+       ** it might have changed.  Skip the conflict logic below if the rowid
+@@ -110976,26 +116995,13 @@
+       VdbeCoverage(v);
+     }
+ 
+-    /* If the response to a rowid conflict is REPLACE but the response
+-    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+-    ** to defer the running of the rowid conflict checking until after
+-    ** the UNIQUE constraints have run.
+-    */
+-    if( onError==OE_Replace && overrideError!=OE_Replace ){
+-      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-        if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+-          ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+-          break;
+-        }
+-      }
+-    }
+-
+     /* Check to see if the new rowid already exists in the table.  Skip
+     ** the following conflict logic if it does not. */
++    VdbeNoopComment((v, "uniqueness check for ROWID"));
++    sqlite3VdbeVerifyAbortable(v, onError);
+     sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+     VdbeCoverage(v);
+ 
+-    /* Generate code that deals with a rowid collision */
+     switch( onError ){
+       default: {
+         onError = OE_Abort;
+@@ -111004,6 +117010,9 @@
+       case OE_Rollback:
+       case OE_Abort:
+       case OE_Fail: {
++        testcase( onError==OE_Rollback );
++        testcase( onError==OE_Abort );
++        testcase( onError==OE_Fail );
+         sqlite3RowidConstraint(pParse, onError, pTab);
+         break;
+       }
+@@ -111040,14 +117049,13 @@
+                                    regNewData, 1, 0, OE_Replace, 1, -1);
+         }else{
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+-          if( HasRowid(pTab) ){
+-            /* This OP_Delete opcode fires the pre-update-hook only. It does
+-            ** not modify the b-tree. It is more efficient to let the coming
+-            ** OP_Insert replace the existing entry than it is to delete the
+-            ** existing entry and then insert a new one. */
+-            sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
+-            sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+-          }
++          assert( HasRowid(pTab) );
++          /* This OP_Delete opcode fires the pre-update-hook only. It does
++          ** not modify the b-tree. It is more efficient to let the coming
++          ** OP_Insert replace the existing entry than it is to delete the
++          ** existing entry and then insert a new one. */
++          sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
++          sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+           if( pTab->pIndex ){
+             sqlite3MultiWrite(pParse);
+@@ -111057,8 +117065,14 @@
+         seenReplace = 1;
+         break;
+       }
++#ifndef SQLITE_OMIT_UPSERT
++      case OE_Update: {
++        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur);
++        /* Fall through */
++      }
++#endif
+       case OE_Ignore: {
+-        /*assert( seenReplace==0 );*/
++        testcase( onError==OE_Ignore );
+         sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+@@ -111066,7 +117080,7 @@
+     sqlite3VdbeResolveLabel(v, addrRowidOk);
+     if( ipkTop ){
+       ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+-      sqlite3VdbeJumpHere(v, ipkTop);
++      sqlite3VdbeJumpHere(v, ipkTop-1);
+     }
+   }
+ 
+@@ -111084,13 +117098,22 @@
+     int addrUniqueOk;    /* Jump here if the UNIQUE constraint is satisfied */
+ 
+     if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
+-    if( bAffinityDone==0 ){
++    if( pUpIdx==pIdx ){
++      addrUniqueOk = upsertJump+1;
++      upsertBypass = sqlite3VdbeGoto(v, 0);
++      VdbeComment((v, "Skip upsert subroutine"));
++      sqlite3VdbeJumpHere(v, upsertJump);
++    }else{
++      addrUniqueOk = sqlite3VdbeMakeLabel(v);
++    }
++    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
+       sqlite3TableAffinity(v, pTab, regNewData+1);
+       bAffinityDone = 1;
+     }
++    VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
+     iThisCur = iIdxCur+ix;
+-    addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ 
++
+     /* Skip partial indices for which the WHERE clause is not true */
+     if( pIdx->pPartIdxWhere ){
+       sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+@@ -111149,6 +117172,15 @@
+       onError = OE_Abort;
+     }
+ 
++    /* Figure out if the upsert clause applies to this index */
++    if( pUpIdx==pIdx ){
++      if( pUpsert->pUpsertSet==0 ){
++        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
++      }else{
++        onError = OE_Update;  /* DO UPDATE */
++      }
++    }
++
+     /* Collision detection may be omitted if all of the following are true:
+     **   (1) The conflict resolution algorithm is REPLACE
+     **   (2) The table is a WITHOUT ROWID table
+@@ -111169,6 +117201,7 @@
+     }
+ 
+     /* Check to see if the new index entry will be unique */
++    sqlite3VdbeVerifyAbortable(v, onError);
+     sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+                          regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+ 
+@@ -111230,15 +117263,25 @@
+ 
+     /* Generate code that executes if the new index entry is not unique */
+     assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+-        || onError==OE_Ignore || onError==OE_Replace );
++        || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update );
+     switch( onError ){
+       case OE_Rollback:
+       case OE_Abort:
+       case OE_Fail: {
++        testcase( onError==OE_Rollback );
++        testcase( onError==OE_Abort );
++        testcase( onError==OE_Fail );
+         sqlite3UniqueConstraint(pParse, onError, pIdx);
+         break;
+       }
++#ifndef SQLITE_OMIT_UPSERT
++      case OE_Update: {
++        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix);
++        /* Fall through */
++      }
++#endif
+       case OE_Ignore: {
++        testcase( onError==OE_Ignore );
+         sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+@@ -111245,10 +117288,12 @@
+       default: {
+         Trigger *pTrigger = 0;
+         assert( onError==OE_Replace );
+-        sqlite3MultiWrite(pParse);
+         if( db->flags&SQLITE_RecTriggers ){
+           pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+         }
++        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
++          sqlite3MultiWrite(pParse);
++        }
+         sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+             regR, nPkField, 0, OE_Replace,
+             (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
+@@ -111256,14 +117301,22 @@
+         break;
+       }
+     }
+-    sqlite3VdbeResolveLabel(v, addrUniqueOk);
++    if( pUpIdx==pIdx ){
++      sqlite3VdbeGoto(v, upsertJump+1);
++      sqlite3VdbeJumpHere(v, upsertBypass);
++    }else{
++      sqlite3VdbeResolveLabel(v, addrUniqueOk);
++    }
+     if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
+   }
++
++  /* If the IPK constraint is a REPLACE, run it last */
+   if( ipkTop ){
+     sqlite3VdbeGoto(v, ipkTop+1);
++    VdbeComment((v, "Do IPK REPLACE"));
+     sqlite3VdbeJumpHere(v, ipkBottom);
+   }
+-  
++
+   *pbMayReplace = seenReplace;
+   VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
+ }
+@@ -111359,7 +117412,6 @@
+   sqlite3SetMakeRecordP5(v, pTab);
+   if( !bAffinityDone ){
+     sqlite3TableAffinity(v, pTab, 0);
+-    sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
+   }
+   if( pParse->nested ){
+     pik_flags = 0;
+@@ -111605,7 +117657,6 @@
+   if( pSelect->pLimit ){
+     return 0;   /* SELECT may not have a LIMIT clause */
+   }
+-  assert( pSelect->pOffset==0 );  /* Must be so if pLimit==0 */
+   if( pSelect->pPrior ){
+     return 0;   /* SELECT may not be a compound query */
+   }
+@@ -111655,7 +117706,7 @@
+     Column *pDestCol = &pDest->aCol[i];
+     Column *pSrcCol = &pSrc->aCol[i];
+ #ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
+-    if( (db->flags & SQLITE_Vacuum)==0 
++    if( (db->mDbFlags & DBFLAG_Vacuum)==0 
+      && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN 
+     ){
+       return 0;    /* Neither table may have __hidden__ columns */
+@@ -111731,7 +117782,7 @@
+   regRowid = sqlite3GetTempReg(pParse);
+   sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
+   assert( HasRowid(pDest) || destHasUniqueIdx );
+-  if( (db->flags & SQLITE_Vacuum)==0 && (
++  if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
+       (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
+    || destHasUniqueIdx                              /* (2) */
+    || (onError!=OE_Abort && onError!=OE_Rollback)   /* (3) */
+@@ -111738,8 +117789,8 @@
+   )){
+     /* In some circumstances, we are able to run the xfer optimization
+     ** only if the destination table is initially empty. Unless the
+-    ** SQLITE_Vacuum flag is set, this block generates code to make
+-    ** that determination. If SQLITE_Vacuum is set, then the destination
++    ** DBFLAG_Vacuum flag is set, this block generates code to make
++    ** that determination. If DBFLAG_Vacuum is set, then the destination
+     ** table is always empty.
+     **
+     ** Conditions under which the destination must be empty:
+@@ -111763,6 +117814,7 @@
+     emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+     if( pDest->iPKey>=0 ){
+       addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
++      sqlite3VdbeVerifyAbortable(v, onError);
+       addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+       VdbeCoverage(v);
+       sqlite3RowidConstraint(pParse, onError, pDest);
+@@ -111775,8 +117827,8 @@
+       assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+     }
+     sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+-    if( db->flags & SQLITE_Vacuum ){
+-      sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
++    if( db->mDbFlags & DBFLAG_Vacuum ){
++      sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
+       insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
+                            OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
+     }else{
+@@ -111807,13 +117859,13 @@
+     VdbeComment((v, "%s", pDestIdx->zName));
+     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+     sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+-    if( db->flags & SQLITE_Vacuum ){
++    if( db->mDbFlags & DBFLAG_Vacuum ){
+       /* This INSERT command is part of a VACUUM operation, which guarantees
+       ** that the destination table is empty. If all indexed columns use
+       ** collation sequence BINARY, then it can also be assumed that the
+       ** index will be populated by inserting keys in strictly sorted 
+       ** order. In this case, instead of seeking within the b-tree as part
+-      ** of every OP_IdxInsert opcode, an OP_Last is added before the
++      ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
+       ** OP_IdxInsert to seek to the point within the b-tree where each key 
+       ** should be inserted. This is faster.
+       **
+@@ -111828,7 +117880,7 @@
+       }
+       if( i==pSrcIdx->nColumn ){
+         idxInsFlags = OPFLAG_USESEEKRESULT;
+-        sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
++        sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
+       }
+     }
+     if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
+@@ -112159,7 +118211,7 @@
+   int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
+                          const char*,const char*),void*);
+   void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
+-  char * (*snprintf)(int,char*,const char*,...);
++  char * (*xsnprintf)(int,char*,const char*,...);
+   int  (*step)(sqlite3_stmt*);
+   int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
+                                 char const**,char const**,int*,int*,int*);
+@@ -112271,7 +118323,7 @@
+   int (*uri_boolean)(const char*,const char*,int);
+   sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
+   const char *(*uri_parameter)(const char*,const char*);
+-  char *(*vsnprintf)(int,char*,const char*,va_list);
++  char *(*xvsnprintf)(int,char*,const char*,va_list);
+   int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+   /* Version 3.8.7 and later */
+   int (*auto_extension)(void(*)(void));
+@@ -112317,6 +118369,33 @@
+   int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+   void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
+   void *(*value_pointer)(sqlite3_value*,const char*);
++  int (*vtab_nochange)(sqlite3_context*);
++  int (*value_nochange)(sqlite3_value*);
++  const char *(*vtab_collation)(sqlite3_index_info*,int);
++  /* Version 3.24.0 and later */
++  int (*keyword_count)(void);
++  int (*keyword_name)(int,const char**,int*);
++  int (*keyword_check)(const char*,int);
++  sqlite3_str *(*str_new)(sqlite3*);
++  char *(*str_finish)(sqlite3_str*);
++  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
++  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
++  void (*str_append)(sqlite3_str*, const char *zIn, int N);
++  void (*str_appendall)(sqlite3_str*, const char *zIn);
++  void (*str_appendchar)(sqlite3_str*, int N, char C);
++  void (*str_reset)(sqlite3_str*);
++  int (*str_errcode)(sqlite3_str*);
++  int (*str_length)(sqlite3_str*);
++  char *(*str_value)(sqlite3_str*);
++  /* Version 3.25.0 and later */
++  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
++                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++                            void (*xFinal)(sqlite3_context*),
++                            void (*xValue)(sqlite3_context*),
++                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
++                            void(*xDestroy)(void*));
++  /* Version 3.26.0 and later */
++  const char *(*normalized_sql)(sqlite3_stmt*);
+ };
+ 
+ /*
+@@ -112443,7 +118522,7 @@
+ #define sqlite3_rollback_hook          sqlite3_api->rollback_hook
+ #define sqlite3_set_authorizer         sqlite3_api->set_authorizer
+ #define sqlite3_set_auxdata            sqlite3_api->set_auxdata
+-#define sqlite3_snprintf               sqlite3_api->snprintf
++#define sqlite3_snprintf               sqlite3_api->xsnprintf
+ #define sqlite3_step                   sqlite3_api->step
+ #define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
+ #define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
+@@ -112467,7 +118546,7 @@
+ #define sqlite3_value_text16le         sqlite3_api->value_text16le
+ #define sqlite3_value_type             sqlite3_api->value_type
+ #define sqlite3_vmprintf               sqlite3_api->vmprintf
+-#define sqlite3_vsnprintf              sqlite3_api->vsnprintf
++#define sqlite3_vsnprintf              sqlite3_api->xvsnprintf
+ #define sqlite3_overload_function      sqlite3_api->overload_function
+ #define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+ #define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+@@ -112543,7 +118622,7 @@
+ #define sqlite3_uri_boolean            sqlite3_api->uri_boolean
+ #define sqlite3_uri_int64              sqlite3_api->uri_int64
+ #define sqlite3_uri_parameter          sqlite3_api->uri_parameter
+-#define sqlite3_uri_vsnprintf          sqlite3_api->vsnprintf
++#define sqlite3_uri_vsnprintf          sqlite3_api->xvsnprintf
+ #define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
+ /* Version 3.8.7 and later */
+ #define sqlite3_auto_extension         sqlite3_api->auto_extension
+@@ -112583,6 +118662,29 @@
+ #define sqlite3_bind_pointer           sqlite3_api->bind_pointer
+ #define sqlite3_result_pointer         sqlite3_api->result_pointer
+ #define sqlite3_value_pointer          sqlite3_api->value_pointer
++/* Version 3.22.0 and later */
++#define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
++#define sqlite3_value_nochange         sqlite3_api->value_nochange
++#define sqlite3_vtab_collation         sqlite3_api->vtab_collation
++/* Version 3.24.0 and later */
++#define sqlite3_keyword_count          sqlite3_api->keyword_count
++#define sqlite3_keyword_name           sqlite3_api->keyword_name
++#define sqlite3_keyword_check          sqlite3_api->keyword_check
++#define sqlite3_str_new                sqlite3_api->str_new
++#define sqlite3_str_finish             sqlite3_api->str_finish
++#define sqlite3_str_appendf            sqlite3_api->str_appendf
++#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
++#define sqlite3_str_append             sqlite3_api->str_append
++#define sqlite3_str_appendall          sqlite3_api->str_appendall
++#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
++#define sqlite3_str_reset              sqlite3_api->str_reset
++#define sqlite3_str_errcode            sqlite3_api->str_errcode
++#define sqlite3_str_length             sqlite3_api->str_length
++#define sqlite3_str_value              sqlite3_api->str_value
++/* Version 3.25.0 and later */
++#define sqlite3_create_window_function sqlite3_api->create_window_function
++/* Version 3.26.0 and later */
++#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
+ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+ 
+ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+@@ -112671,6 +118773,7 @@
+ # define sqlite3_declare_vtab 0
+ # define sqlite3_vtab_config 0
+ # define sqlite3_vtab_on_conflict 0
++# define sqlite3_vtab_collation 0
+ #endif
+ 
+ #ifdef SQLITE_OMIT_SHARED_CACHE
+@@ -113017,7 +119120,34 @@
+   sqlite3_prepare16_v3,
+   sqlite3_bind_pointer,
+   sqlite3_result_pointer,
+-  sqlite3_value_pointer
++  sqlite3_value_pointer,
++  /* Version 3.22.0 and later */
++  sqlite3_vtab_nochange,
++  sqlite3_value_nochange,
++  sqlite3_vtab_collation,
++  /* Version 3.24.0 and later */
++  sqlite3_keyword_count,
++  sqlite3_keyword_name,
++  sqlite3_keyword_check,
++  sqlite3_str_new,
++  sqlite3_str_finish,
++  sqlite3_str_appendf,
++  sqlite3_str_vappendf,
++  sqlite3_str_append,
++  sqlite3_str_appendall,
++  sqlite3_str_appendchar,
++  sqlite3_str_reset,
++  sqlite3_str_errcode,
++  sqlite3_str_length,
++  sqlite3_str_value,
++  /* Version 3.25.0 and later */
++  sqlite3_create_window_function,
++  /* Version 3.26.0 and later */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  sqlite3_normalized_sql
++#else
++  0
++#endif
+ };
+ 
+ /*
+@@ -113467,10 +119597,9 @@
+ #define PragTyp_ACTIVATE_EXTENSIONS           40
+ #define PragTyp_HEXKEY                        41
+ #define PragTyp_KEY                           42
+-#define PragTyp_REKEY                         43
+-#define PragTyp_LOCK_STATUS                   44
+-#define PragTyp_PARSER_TRACE                  45
+-#define PragTyp_STATS                         46
++#define PragTyp_LOCK_STATUS                   43
++#define PragTyp_PARSER_TRACE                  44
++#define PragTyp_STATS                         45
+ 
+ /* Property flags associated with various pragma. */
+ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
+@@ -113487,21 +119616,22 @@
+ ** result column is different from the name of the pragma
+ */
+ static const char *const pragCName[] = {
+-  /*   0 */ "cache_size",  /* Used by: default_cache_size */
+-  /*   1 */ "cid",         /* Used by: table_info */
+-  /*   2 */ "name",       
+-  /*   3 */ "type",       
+-  /*   4 */ "notnull",    
+-  /*   5 */ "dflt_value", 
+-  /*   6 */ "pk",         
+-  /*   7 */ "tbl",         /* Used by: stats */
+-  /*   8 */ "idx",        
+-  /*   9 */ "wdth",       
+-  /*  10 */ "hght",       
+-  /*  11 */ "flgs",       
+-  /*  12 */ "seqno",       /* Used by: index_info */
+-  /*  13 */ "cid",        
+-  /*  14 */ "name",       
++  /*   0 */ "id",          /* Used by: foreign_key_list */
++  /*   1 */ "seq",        
++  /*   2 */ "table",      
++  /*   3 */ "from",       
++  /*   4 */ "to",         
++  /*   5 */ "on_update",  
++  /*   6 */ "on_delete",  
++  /*   7 */ "match",      
++  /*   8 */ "cid",         /* Used by: table_xinfo */
++  /*   9 */ "name",       
++  /*  10 */ "type",       
++  /*  11 */ "notnull",    
++  /*  12 */ "dflt_value", 
++  /*  13 */ "pk",         
++  /*  14 */ "hidden",     
++                           /* table_info reuses 8 */
+   /*  15 */ "seqno",       /* Used by: index_xinfo */
+   /*  16 */ "cid",        
+   /*  17 */ "name",       
+@@ -113508,37 +119638,35 @@
+   /*  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 */
++  /*  21 */ "tbl",         /* Used by: stats */
++  /*  22 */ "idx",        
++  /*  23 */ "wdth",       
++  /*  24 */ "hght",       
++  /*  25 */ "flgs",       
++  /*  26 */ "seq",         /* Used by: index_list */
+   /*  27 */ "name",       
+-  /*  28 */ "file",       
+-  /*  29 */ "name",        /* Used by: function_list */
+-  /*  30 */ "builtin",    
+-  /*  31 */ "name",        /* Used by: module_list pragma_list */
+-  /*  32 */ "seq",         /* Used by: collation_list */
+-  /*  33 */ "name",       
+-  /*  34 */ "id",          /* Used by: foreign_key_list */
+-  /*  35 */ "seq",        
+-  /*  36 */ "table",      
+-  /*  37 */ "from",       
+-  /*  38 */ "to",         
+-  /*  39 */ "on_update",  
+-  /*  40 */ "on_delete",  
+-  /*  41 */ "match",      
+-  /*  42 */ "table",       /* Used by: foreign_key_check */
+-  /*  43 */ "rowid",      
+-  /*  44 */ "parent",     
+-  /*  45 */ "fkid",       
+-  /*  46 */ "busy",        /* Used by: wal_checkpoint */
+-  /*  47 */ "log",        
+-  /*  48 */ "checkpointed",
+-  /*  49 */ "timeout",     /* Used by: busy_timeout */
+-  /*  50 */ "database",    /* Used by: lock_status */
+-  /*  51 */ "status",     
++  /*  28 */ "unique",     
++  /*  29 */ "origin",     
++  /*  30 */ "partial",    
++  /*  31 */ "table",       /* Used by: foreign_key_check */
++  /*  32 */ "rowid",      
++  /*  33 */ "parent",     
++  /*  34 */ "fkid",       
++                           /* index_info reuses 15 */
++  /*  35 */ "seq",         /* Used by: database_list */
++  /*  36 */ "name",       
++  /*  37 */ "file",       
++  /*  38 */ "busy",        /* Used by: wal_checkpoint */
++  /*  39 */ "log",        
++  /*  40 */ "checkpointed",
++  /*  41 */ "name",        /* Used by: function_list */
++  /*  42 */ "builtin",    
++                           /* collation_list reuses 26 */
++  /*  43 */ "database",    /* Used by: lock_status */
++  /*  44 */ "status",     
++  /*  45 */ "cache_size",  /* Used by: default_cache_size */
++                           /* module_list pragma_list reuses 9 */
++  /*  46 */ "timeout",     /* Used by: busy_timeout */
+ };
+ 
+ /* Definitions of all built-in pragmas */
+@@ -113548,7 +119676,7 @@
+   u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
+   u8 iPragCName;           /* Start of column names in pragCName[] */
+   u8 nPragCName;           /* Num of col names. 0 means use pragma name */
+-  u32 iArg;                /* Extra argument */
++  u64 iArg;                /* Extra argument */
+ } PragmaName;
+ static const PragmaName aPragmaName[] = {
+ #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+@@ -113584,7 +119712,7 @@
+  {/* zName:     */ "busy_timeout",
+   /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 49, 1,
++  /* ColNames:  */ 46, 1,
+   /* iArg:      */ 0 },
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+  {/* zName:     */ "cache_size",
+@@ -113621,7 +119749,7 @@
+  {/* zName:     */ "collation_list",
+   /* ePragTyp:  */ PragTyp_COLLATION_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 32, 2,
++  /* ColNames:  */ 26, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+@@ -113656,7 +119784,7 @@
+  {/* zName:     */ "database_list",
+   /* ePragTyp:  */ PragTyp_DATABASE_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+-  /* ColNames:  */ 26, 3,
++  /* ColNames:  */ 35, 3,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+@@ -113663,7 +119791,7 @@
+  {/* zName:     */ "default_cache_size",
+   /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+-  /* ColNames:  */ 0, 1,
++  /* ColNames:  */ 45, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -113693,7 +119821,7 @@
+  {/* zName:     */ "foreign_key_check",
+   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+-  /* ColNames:  */ 42, 4,
++  /* ColNames:  */ 31, 4,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY)
+@@ -113700,7 +119828,7 @@
+  {/* zName:     */ "foreign_key_list",
+   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 34, 8,
++  /* ColNames:  */ 0, 8,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -113736,7 +119864,7 @@
+  {/* zName:     */ "function_list",
+   /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 29, 2,
++  /* ColNames:  */ 41, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #endif
+@@ -113745,12 +119873,12 @@
+   /* ePragTyp:  */ PragTyp_HEXKEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 2 },
+  {/* zName:     */ "hexrekey",
+   /* ePragTyp:  */ PragTyp_HEXKEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 3 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_CHECK)
+@@ -113772,12 +119900,12 @@
+  {/* zName:     */ "index_info",
+   /* ePragTyp:  */ PragTyp_INDEX_INFO,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 12, 3,
++  /* ColNames:  */ 15, 3,
+   /* iArg:      */ 0 },
+  {/* zName:     */ "index_list",
+   /* ePragTyp:  */ PragTyp_INDEX_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 21, 5,
++  /* ColNames:  */ 26, 5,
+   /* iArg:      */ 0 },
+  {/* zName:     */ "index_xinfo",
+   /* ePragTyp:  */ PragTyp_INDEX_INFO,
+@@ -113812,6 +119940,11 @@
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
++ {/* zName:     */ "legacy_alter_table",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_LegacyAlter },
+  {/* zName:     */ "legacy_file_format",
+   /* ePragTyp:  */ PragTyp_FLAG,
+   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
+@@ -113829,7 +119962,7 @@
+  {/* zName:     */ "lock_status",
+   /* ePragTyp:  */ PragTyp_LOCK_STATUS,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 50, 2,
++  /* ColNames:  */ 43, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+@@ -113855,7 +119988,7 @@
+  {/* zName:     */ "module_list",
+   /* ePragTyp:  */ PragTyp_MODULE_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 31, 1,
++  /* ColNames:  */ 9, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #endif
+@@ -113888,7 +120021,7 @@
+  {/* zName:     */ "pragma_list",
+   /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 31, 1,
++  /* ColNames:  */ 9, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -113919,10 +120052,10 @@
+ #endif
+ #if defined(SQLITE_HAS_CODEC)
+  {/* zName:     */ "rekey",
+-  /* ePragTyp:  */ PragTyp_REKEY,
++  /* ePragTyp:  */ PragTyp_KEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 1 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+  {/* zName:     */ "reverse_unordered_selects",
+@@ -113975,7 +120108,7 @@
+  {/* zName:     */ "stats",
+   /* ePragTyp:  */ PragTyp_STATS,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+-  /* ColNames:  */ 7, 5,
++  /* ColNames:  */ 21, 5,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+@@ -113989,8 +120122,13 @@
+  {/* zName:     */ "table_info",
+   /* ePragTyp:  */ PragTyp_TABLE_INFO,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 1, 6,
++  /* ColNames:  */ 8, 6,
+   /* iArg:      */ 0 },
++ {/* zName:     */ "table_xinfo",
++  /* ePragTyp:  */ PragTyp_TABLE_INFO,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 8, 7,
++  /* iArg:      */ 1 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+  {/* zName:     */ "temp_store",
+@@ -114004,6 +120142,18 @@
+   /* ColNames:  */ 0, 0,
+   /* iArg:      */ 0 },
+ #endif
++#if defined(SQLITE_HAS_CODEC)
++ {/* zName:     */ "textkey",
++  /* ePragTyp:  */ PragTyp_KEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 4 },
++ {/* zName:     */ "textrekey",
++  /* ePragTyp:  */ PragTyp_KEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 5 },
++#endif
+  {/* zName:     */ "threads",
+   /* ePragTyp:  */ PragTyp_THREADS,
+   /* ePragFlg:  */ PragFlg_Result0,
+@@ -114054,7 +120204,7 @@
+  {/* zName:     */ "wal_checkpoint",
+   /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
+   /* ePragFlg:  */ PragFlg_NeedSchema,
+-  /* ColNames:  */ 46, 3,
++  /* ColNames:  */ 38, 3,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -114062,10 +120212,10 @@
+   /* ePragTyp:  */ PragTyp_FLAG,
+   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ SQLITE_WriteSchema },
++  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
+ #endif
+ };
+-/* Number of pragmas: 60 on by default, 77 total. */
++/* Number of pragmas: 62 on by default, 81 total. */
+ 
+ /************** End of pragma.h **********************************************/
+ /************** Continuing where we left off in pragma.c *********************/
+@@ -114338,16 +120488,16 @@
+ /*
+ ** 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.
++** Generate code to output a single-column result row with a value of the
++** string held in register 3.  Decrement the result count in register 1
++** and halt if the maximum number of result rows have been issued.
+ */
+-static int integrityCheckResultRow(Vdbe *v, int regResult){
++static int integrityCheckResultRow(Vdbe *v){
+   int addr;
+-  sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
++  sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+   addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
+   VdbeCoverage(v);
+-  sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
++  sqlite3VdbeAddOp0(v, OP_Halt);
+   return addr;
+ }
+ 
+@@ -115077,7 +121227,7 @@
+       setPragmaResultColumnNames(v, pPragma);
+       returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
+     }else{
+-      int mask = pPragma->iArg;    /* Mask of bits to set or clear. */
++      u64 mask = pPragma->iArg;    /* Mask of bits to set or clear. */
+       if( db->autoCommit==0 ){
+         /* Foreign key support may not be enabled or disabled while not
+         ** in auto-commit mode.  */
+@@ -115120,20 +121270,23 @@
+   ** type:       Column declaration type.
+   ** notnull:    True if 'NOT NULL' is part of column declaration
+   ** dflt_value: The default value for the column, if any.
++  ** pk:         Non-zero for PK fields.
+   */
+   case PragTyp_TABLE_INFO: if( zRight ){
+     Table *pTab;
+     pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
+     if( pTab ){
++      int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+       int i, k;
+       int nHidden = 0;
+       Column *pCol;
+       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+-      pParse->nMem = 6;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      pParse->nMem = 7;
++      sqlite3CodeVerifySchema(pParse, iTabDb);
+       sqlite3ViewGetColumnNames(pParse, pTab);
+       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+-        if( IsHiddenColumn(pCol) ){
++        int isHidden = IsHiddenColumn(pCol);
++        if( isHidden && pPragma->iArg==0 ){
+           nHidden++;
+           continue;
+         }
+@@ -115145,13 +121298,14 @@
+           for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
+         }
+         assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
+-        sqlite3VdbeMultiLoad(v, 1, "issisi",
++        sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
+                i-nHidden,
+                pCol->zName,
+                sqlite3ColumnType(pCol,""),
+                pCol->notNull ? 1 : 0,
+                pCol->pDflt ? pCol->pDflt->u.zToken : 0,
+-               k);
++               k,
++               isHidden);
+       }
+     }
+   }
+@@ -115189,6 +121343,7 @@
+     Table *pTab;
+     pIdx = sqlite3FindIndex(db, zRight, zDb);
+     if( pIdx ){
++      int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
+       int i;
+       int mx;
+       if( pPragma->iArg ){
+@@ -115201,7 +121356,7 @@
+         pParse->nMem = 3;
+       }
+       pTab = pIdx->pTable;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      sqlite3CodeVerifySchema(pParse, iIdxDb);
+       assert( pParse->nMem<=pPragma->nPragCName );
+       for(i=0; i<mx; i++){
+         i16 cnum = pIdx->aiColumn[i];
+@@ -115225,8 +121380,9 @@
+     int i;
+     pTab = sqlite3FindTable(db, zRight, zDb);
+     if( pTab ){
++      int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+       pParse->nMem = 5;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      sqlite3CodeVerifySchema(pParse, iTabDb);
+       for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+         const char *azOrigin[] = { "c", "u", "pk" };
+         sqlite3VdbeMultiLoad(v, 1, "isisi",
+@@ -115273,14 +121429,13 @@
+     pParse->nMem = 2;
+     for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+       for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
++        if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
+         sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
+-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
+       }
+     }
+     for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
+       p = (FuncDef*)sqliteHashData(j);
+       sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
+     }
+   }
+   break;
+@@ -115292,7 +121447,6 @@
+     for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
+       Module *pMod = (Module*)sqliteHashData(j);
+       sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+     }
+   }
+   break;
+@@ -115302,7 +121456,6 @@
+     int i;
+     for(i=0; i<ArraySize(aPragmaName); i++){
+       sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
+-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
+     }
+   }
+   break;
+@@ -115318,9 +121471,10 @@
+     if( pTab ){
+       pFK = pTab->pFKey;
+       if( pFK ){
++        int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+         int i = 0; 
+         pParse->nMem = 8;
+-        sqlite3CodeVerifySchema(pParse, iDb);
++        sqlite3CodeVerifySchema(pParse, iTabDb);
+         while(pFK){
+           int j;
+           for(j=0; j<pFK->nCol; j++){
+@@ -115365,9 +121519,9 @@
+     pParse->nMem += 4;
+     regKey = ++pParse->nMem;
+     regRow = ++pParse->nMem;
+-    sqlite3CodeVerifySchema(pParse, iDb);
+     k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+     while( k ){
++      int iTabDb;
+       if( zRight ){
+         pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
+         k = 0;
+@@ -115376,21 +121530,23 @@
+         k = sqliteHashNext(k);
+       }
+       if( pTab==0 || pTab->pFKey==0 ) continue;
+-      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
++      iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
++      sqlite3CodeVerifySchema(pParse, iTabDb);
++      sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
+       if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+-      sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
++      sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
+       sqlite3VdbeLoadString(v, regResult, pTab->zName);
+       for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+         pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+         if( pParent==0 ) continue;
+         pIdx = 0;
+-        sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
++        sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
+         x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
+         if( x==0 ){
+           if( pIdx==0 ){
+-            sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
++            sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
+           }else{
+-            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
++            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
+             sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+           }
+         }else{
+@@ -115528,12 +121684,11 @@
+ 
+     /* 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;
++      HashElem *x;     /* For looping over tables in the schema */
++      Hash *pTbls;     /* Set of all tables in the schema */
++      int *aRoot;      /* Array of root page numbers of all btrees */
++      int cnt = 0;     /* Number of entries in aRoot[] */
++      int mxIdx = 0;   /* Maximum number of indexes for any table */
+ 
+       if( OMIT_TEMPDB && i==1 ) continue;
+       if( iDb>=0 && i!=iDb ) continue;
+@@ -115548,8 +121703,9 @@
+       assert( sqlite3SchemaMutexHeld(db, i, 0) );
+       pTbls = &db->aDb[i].pSchema->tblHash;
+       for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+-        Table *pTab = sqliteHashData(x);
+-        Index *pIdx;
++        Table *pTab = sqliteHashData(x);  /* Current table */
++        Index *pIdx;                      /* An index on pTab */
++        int nIdx;                         /* Number of indexes on pTab */
+         if( HasRowid(pTab) ) cnt++;
+         for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
+         if( nIdx>mxIdx ) mxIdx = nIdx;
+@@ -115559,12 +121715,12 @@
+       for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+         Table *pTab = sqliteHashData(x);
+         Index *pIdx;
+-        if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum;
++        if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
+         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-          aRoot[cnt++] = pIdx->tnum;
++          aRoot[++cnt] = pIdx->tnum;
+         }
+       }
+-      aRoot[cnt] = 0;
++      aRoot[0] = cnt;
+ 
+       /* Make sure sufficient number of registers have been allocated */
+       pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
+@@ -115577,9 +121733,8 @@
+       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);
+-      integrityCheckResultRow(v, 2);
++      sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3);
++      integrityCheckResultRow(v);
+       sqlite3VdbeJumpHere(v, addr);
+ 
+       /* Make sure all the indices are constructed correctly.
+@@ -115593,16 +121748,12 @@
+         int r1 = -1;
+ 
+         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);
+-        sqlite3ExprCacheClear(pParse);
+         sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+                                    1, 0, &iDataCur, &iIdxCur);
++        /* reg[7] counts the number of entries in the table.
++        ** reg[8+i] counts the number of entries in the i-th index 
++        */
+         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 */
+@@ -115611,6 +121762,11 @@
+         assert( sqlite3NoTempsInRange(pParse,1,7+j) );
+         sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
+         loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
++        if( !isQuick ){
++          /* Sanity check on record header decoding */
++          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
++          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
++        }
+         /* Verify that all NOT NULL columns really are NOT NULL */
+         for(j=0; j<pTab->nCol; j++){
+           char *zErr;
+@@ -115623,7 +121779,7 @@
+           zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
+                               pTab->aCol[j].zName);
+           sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+-          integrityCheckResultRow(v, 3);
++          integrityCheckResultRow(v);
+           sqlite3VdbeJumpHere(v, jmp2);
+         }
+         /* Verify CHECK constraints */
+@@ -115635,7 +121791,6 @@
+             char *zErr;
+             int k;
+             pParse->iSelfTab = iDataCur + 1;
+-            sqlite3ExprCachePush(pParse);
+             for(k=pCheck->nExpr-1; k>0; k--){
+               sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+             }
+@@ -115646,57 +121801,58 @@
+             zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
+                 pTab->zName);
+             sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+-            integrityCheckResultRow(v, 3);
++            integrityCheckResultRow(v);
+             sqlite3VdbeResolveLabel(v, addrCkOk);
+-            sqlite3ExprCachePop(pParse);
+           }
+           sqlite3ExprListDelete(db, pCheck);
+         }
+-        /* Validate index entries for the current row */
+-        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);
+-          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);
+-          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;
+-            for(kk=0; kk<pIdx->nKeyCol; kk++){
+-              int iCol = pIdx->aiColumn[kk];
+-              assert( iCol!=XN_ROWID && iCol<pTab->nCol );
+-              if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+-              sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+-              VdbeCoverage(v);
++        if( !isQuick ){ /* Omit the remaining tests for quick_check */
++          /* Validate index entries for the current row */
++          for(j=0, pIdx=pTab->pIndex; pIdx; 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);
++            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);
++            jmp4 = integrityCheckResultRow(v);
++            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;
++              for(kk=0; kk<pIdx->nKeyCol; kk++){
++                int iCol = pIdx->aiColumn[kk];
++                assert( iCol!=XN_ROWID && iCol<pTab->nCol );
++                if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
++                sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
++                VdbeCoverage(v);
++              }
++              jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
++              sqlite3VdbeGoto(v, uniqOk);
++              sqlite3VdbeJumpHere(v, jmp6);
++              sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
++                                   pIdx->nKeyCol); VdbeCoverage(v);
++              sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
++              sqlite3VdbeGoto(v, jmp5);
++              sqlite3VdbeResolveLabel(v, uniqOk);
+             }
+-            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);
+-            sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+-            sqlite3VdbeGoto(v, jmp5);
+-            sqlite3VdbeResolveLabel(v, uniqOk);
++            sqlite3VdbeJumpHere(v, jmp4);
++            sqlite3ResolvePartIdxLabel(pParse, jmp3);
+           }
+-          sqlite3VdbeJumpHere(v, jmp4);
+-          sqlite3ResolvePartIdxLabel(pParse, jmp3);
+         }
+         sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
+         sqlite3VdbeJumpHere(v, loopTop-1);
+@@ -115708,9 +121864,9 @@
+             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);
++            sqlite3VdbeLoadString(v, 4, pIdx->zName);
++            sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
++            integrityCheckResultRow(v);
+             sqlite3VdbeJumpHere(v, addr);
+           }
+         }
+@@ -115724,6 +121880,9 @@
+         { OP_IfNotZero,   1, 4,        0},    /* 1 */
+         { OP_String8,     0, 3,        0},    /* 2 */
+         { OP_ResultRow,   3, 1,        0},    /* 3 */
++        { OP_Halt,        0, 0,        0},    /* 4 */
++        { OP_String8,     0, 3,        0},    /* 5 */
++        { OP_Goto,        0, 3,        0},    /* 6 */
+       };
+       VdbeOp *aOp;
+ 
+@@ -115732,7 +121891,10 @@
+         aOp[0].p2 = 1-mxErr;
+         aOp[2].p4type = P4_STATIC;
+         aOp[2].p4.z = "ok";
++        aOp[5].p4type = P4_STATIC;
++        aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT);
+       }
++      sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2);
+     }
+   }
+   break;
+@@ -116153,14 +122315,26 @@
+ #endif
+ 
+ #ifdef SQLITE_HAS_CODEC
++  /* Pragma        iArg
++  ** ----------   ------
++  **  key           0
++  **  rekey         1
++  **  hexkey        2
++  **  hexrekey      3
++  **  textkey       4
++  **  textrekey     5
++  */
+   case PragTyp_KEY: {
+-    if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
++    if( zRight ){
++      int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
++      if( (pPragma->iArg & 1)==0 ){
++        sqlite3_key_v2(db, zDb, zRight, n);
++      }else{
++        sqlite3_rekey_v2(db, zDb, zRight, n);
++      }
++    }
+     break;
+   }
+-  case PragTyp_REKEY: {
+-    if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+-    break;
+-  }
+   case PragTyp_HEXKEY: {
+     if( zRight ){
+       u8 iByte;
+@@ -116170,7 +122344,7 @@
+         iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+         if( (i&1)!=0 ) zKey[i/2] = iByte;
+       }
+-      if( (zLeft[3] & 0xf)==0xb ){
++      if( (pPragma->iArg & 1)==0 ){
+         sqlite3_key_v2(db, zDb, zKey, i/2);
+       }else{
+         sqlite3_rekey_v2(db, zDb, zKey, i/2);
+@@ -116252,26 +122426,25 @@
+   UNUSED_PARAMETER(argc);
+   UNUSED_PARAMETER(argv);
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+-  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
++  sqlite3_str_appendall(&acc, "CREATE TABLE x");
+   for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
+-    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
++    sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
+     cSep = ',';
+   }
+   if( i==0 ){
+-    sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
+-    cSep = ',';
++    sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
+     i++;
+   }
+   j = 0;
+   if( pPragma->mPragFlg & PragFlg_Result1 ){
+-    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
++    sqlite3_str_appendall(&acc, ",arg HIDDEN");
+     j++;
+   }
+   if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
+-    sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
++    sqlite3_str_appendall(&acc, ",schema HIDDEN");
+     j++;
+   }
+-  sqlite3StrAccumAppend(&acc, ")", 1);
++  sqlite3_str_append(&acc, ")", 1);
+   sqlite3StrAccumFinish(&acc);
+   assert( strlen(zBuf) < sizeof(zBuf)-1 );
+   rc = sqlite3_declare_vtab(db, zBuf);
+@@ -116423,13 +122596,13 @@
+     }
+   }
+   sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
+-  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
++  sqlite3_str_appendall(&acc, "PRAGMA ");
+   if( pCsr->azArg[1] ){
+-    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
++    sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
+   }
+-  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
++  sqlite3_str_appendall(&acc, pTab->pName->zName);
+   if( pCsr->azArg[0] ){
+-    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
++    sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
+   }
+   zSql = sqlite3StrAccumFinish(&acc);
+   if( zSql==0 ) return SQLITE_NOMEM;
+@@ -116501,7 +122674,8 @@
+   0,                           /* xRename - rename the table */
+   0,                           /* xSavepoint */
+   0,                           /* xRelease */
+-  0                            /* xRollbackTo */
++  0,                           /* xRollbackTo */
++  0                            /* xShadowName */
+ };
+ 
+ /*
+@@ -116552,15 +122726,23 @@
+   const char *zExtra   /* Error information */
+ ){
+   sqlite3 *db = pData->db;
+-  if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
++  if( db->mallocFailed ){
++    pData->rc = SQLITE_NOMEM_BKPT;
++  }else if( pData->pzErrMsg[0]!=0 ){
++    /* A error message has already been generated.  Do not overwrite it */
++  }else if( pData->mInitFlags & INITFLAG_AlterTable ){
++    *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);
++    pData->rc = SQLITE_ERROR;
++  }else if( db->flags & SQLITE_WriteSchema ){
++    pData->rc = SQLITE_CORRUPT_BKPT;
++  }else{
+     char *z;
+     if( zObj==0 ) zObj = "?";
+     z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
+-    if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
+-    sqlite3DbFree(db, *pData->pzErrMsg);
++    if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
+     *pData->pzErrMsg = z;
++    pData->rc = SQLITE_CORRUPT_BKPT;
+   }
+-  pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
+ }
+ 
+ /*
+@@ -116612,7 +122794,7 @@
+     rc = db->errCode;
+     assert( (rc&0xFF)==(rcp&0xFF) );
+     db->init.iDb = saved_iDb;
+-    assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
++    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
+     if( SQLITE_OK!=rc ){
+       if( db->init.orphanTrigger ){
+         assert( iDb==1 );
+@@ -116659,7 +122841,7 @@
+ ** auxiliary databases.  Return one of the SQLITE_ error codes to
+ ** indicate success or failure.
+ */
+-static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
++SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
+   int rc;
+   int i;
+ #ifndef SQLITE_OMIT_DEPRECATED
+@@ -116672,11 +122854,14 @@
+   const char *zMasterName;
+   int openedTransaction = 0;
+ 
++  assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( db->aDb[iDb].pSchema );
+   assert( sqlite3_mutex_held(db->mutex) );
+   assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+ 
++  db->init.busy = 1;
++
+   /* Construct the in-memory representation schema tables (sqlite_master or
+   ** sqlite_temp_master) by invoking the parser directly.  The appropriate
+   ** table name will be inserted automatically by the parser so we can just
+@@ -116685,12 +122870,13 @@
+   azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
+   azArg[1] = "1";
+   azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
+-                            "rootpage integer,sql text)";
++                            "rootpage int,sql text)";
+   azArg[3] = 0;
+   initData.db = db;
+   initData.iDb = iDb;
+   initData.rc = SQLITE_OK;
+   initData.pzErrMsg = pzErrMsg;
++  initData.mInitFlags = mFlags;
+   sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
+   if( initData.rc ){
+     rc = initData.rc;
+@@ -116701,10 +122887,10 @@
+   */
+   pDb = &db->aDb[iDb];
+   if( pDb->pBt==0 ){
+-    if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
+-      DbSetProperty(db, 1, DB_SchemaLoaded);
+-    }
+-    return SQLITE_OK;
++    assert( iDb==1 );
++    DbSetProperty(db, 1, DB_SchemaLoaded);
++    rc = SQLITE_OK;
++    goto error_out;
+   }
+ 
+   /* If there is not already a read-only (or read-write) transaction opened
+@@ -116712,7 +122898,7 @@
+   ** will be closed before this function returns.  */
+   sqlite3BtreeEnter(pDb->pBt);
+   if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
+-    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
++    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
+     if( rc!=SQLITE_OK ){
+       sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
+       goto initone_error_out;
+@@ -116740,6 +122926,9 @@
+   for(i=0; i<ArraySize(meta); i++){
+     sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
+   }
++  if( (db->flags & SQLITE_ResetDatabase)!=0 ){
++    memset(meta, 0, sizeof(meta));
++  }
+   pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
+ 
+   /* If opening a non-empty database, check the text encoding. For the
+@@ -116839,8 +123028,8 @@
+     rc = SQLITE_NOMEM_BKPT;
+     sqlite3ResetAllSchemasOfConnection(db);
+   }
+-  if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
+-    /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
++  if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
++    /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
+     ** the schema loaded, even if errors occurred. In this situation the 
+     ** current sqlite3_prepare() operation will fail, but the following one
+     ** will attempt to compile the supplied statement against whatever subset
+@@ -116863,9 +123052,13 @@
+   sqlite3BtreeLeave(pDb->pBt);
+ 
+ error_out:
+-  if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+-    sqlite3OomFault(db);
++  if( rc ){
++    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
++      sqlite3OomFault(db);
++    }
++    sqlite3ResetOneSchema(db, iDb);
+   }
++  db->init.busy = 0;
+   return rc;
+ }
+ 
+@@ -116881,42 +123074,30 @@
+ */
+ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
+   int i, rc;
+-  int commit_internal = !(db->flags&SQLITE_InternChanges);
++  int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
+   
+   assert( sqlite3_mutex_held(db->mutex) );
+   assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
+   assert( db->init.busy==0 );
+-  rc = SQLITE_OK;
+-  db->init.busy = 1;
+   ENC(db) = SCHEMA_ENC(db);
+-  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+-    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
+-    rc = sqlite3InitOne(db, i, pzErrMsg);
+-    if( rc ){
+-      sqlite3ResetOneSchema(db, i);
+-    }
++  assert( db->nDb>0 );
++  /* Do the main schema first */
++  if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
++    rc = sqlite3InitOne(db, 0, pzErrMsg, 0);
++    if( rc ) return rc;
+   }
+-
+-  /* Once all the other databases have been initialized, load the schema
+-  ** for the TEMP database. This is loaded last, as the TEMP database
+-  ** schema may contain references to objects in other databases.
+-  */
+-#ifndef SQLITE_OMIT_TEMPDB
+-  assert( db->nDb>1 );
+-  if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+-    rc = sqlite3InitOne(db, 1, pzErrMsg);
+-    if( rc ){
+-      sqlite3ResetOneSchema(db, 1);
++  /* All other schemas after the main schema. The "temp" schema must be last */
++  for(i=db->nDb-1; i>0; i--){
++    assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) );
++    if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
++      rc = sqlite3InitOne(db, i, pzErrMsg, 0);
++      if( rc ) return rc;
+     }
+   }
+-#endif
+-
+-  db->init.busy = 0;
+-  if( rc==SQLITE_OK && commit_internal ){
++  if( commit_internal ){
+     sqlite3CommitInternalChanges(db);
+   }
+-
+-  return rc; 
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -116929,11 +123110,13 @@
+   assert( sqlite3_mutex_held(db->mutex) );
+   if( !db->init.busy ){
+     rc = sqlite3Init(db, &pParse->zErrMsg);
++    if( rc!=SQLITE_OK ){
++      pParse->rc = rc;
++      pParse->nErr++;
++    }else if( db->noSharedCache ){
++      db->mDbFlags |= DBFLAG_SchemaKnownOk;
++    }
+   }
+-  if( rc!=SQLITE_OK ){
+-    pParse->rc = rc;
+-    pParse->nErr++;
+-  }
+   return rc;
+ }
+ 
+@@ -116960,7 +123143,7 @@
+     ** on the b-tree database, open one now. If a transaction is opened, it 
+     ** will be closed immediately after reading the meta-value. */
+     if( !sqlite3BtreeIsInReadTrans(pBt) ){
+-      rc = sqlite3BtreeBeginTrans(pBt, 0);
++      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+       if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+         sqlite3OomFault(db);
+       }
+@@ -117007,7 +123190,8 @@
+   */
+   assert( sqlite3_mutex_held(db->mutex) );
+   if( pSchema ){
+-    for(i=0; ALWAYS(i<db->nDb); i++){
++    for(i=0; 1; i++){
++      assert( i<db->nDb );
+       if( db->aDb[i].pSchema==pSchema ){
+         break;
+       }
+@@ -117021,16 +123205,14 @@
+ ** Free all memory allocations in the pParse object
+ */
+ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
+-  if( pParse ){
+-    sqlite3 *db = pParse->db;
+-    sqlite3DbFree(db, pParse->aLabel);
+-    sqlite3ExprListDelete(db, pParse->pConstExpr);
+-    if( db ){
+-      assert( db->lookaside.bDisable >= pParse->disableLookaside );
+-      db->lookaside.bDisable -= pParse->disableLookaside;
+-    }
+-    pParse->disableLookaside = 0;
++  sqlite3 *db = pParse->db;
++  sqlite3DbFree(db, pParse->aLabel);
++  sqlite3ExprListDelete(db, pParse->pConstExpr);
++  if( db ){
++    assert( db->lookaside.bDisable >= pParse->disableLookaside );
++    db->lookaside.bDisable -= pParse->disableLookaside;
+   }
++  pParse->disableLookaside = 0;
+ }
+ 
+ /*
+@@ -117144,7 +123326,7 @@
+   if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+     static const char * const azColName[] = {
+        "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+-       "selectid", "order", "from", "detail"
++       "id", "parent", "notused", "detail"
+     };
+     int iFirst, mx;
+     if( sParse.explain==2 ){
+@@ -117190,8 +123372,6 @@
+ end_prepare:
+ 
+   sqlite3ParserReset(&sParse);
+-  rc = sqlite3ApiExit(db, rc);
+-  assert( (rc&db->errMask)==rc );
+   return rc;
+ }
+ static int sqlite3LockAndPrepare(
+@@ -117204,6 +123384,7 @@
+   const char **pzTail       /* OUT: End of parsed string */
+ ){
+   int rc;
++  int cnt = 0;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+@@ -117214,18 +123395,310 @@
+   }
+   sqlite3_mutex_enter(db->mutex);
+   sqlite3BtreeEnterAll(db);
+-  rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
+-  if( rc==SQLITE_SCHEMA ){
+-    sqlite3_finalize(*ppStmt);
++  do{
++    /* Make multiple attempts to compile the SQL, until it either succeeds
++    ** or encounters a permanent error.  A schema problem after one schema
++    ** reset is considered a permanent error. */
+     rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
+-  }
++    assert( rc==SQLITE_OK || *ppStmt==0 );
++  }while( rc==SQLITE_ERROR_RETRY
++       || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
+   sqlite3BtreeLeaveAll(db);
++  rc = sqlite3ApiExit(db, rc);
++  assert( (rc&db->errMask)==rc );
+   sqlite3_mutex_leave(db->mutex);
+-  assert( rc==SQLITE_OK || *ppStmt==0 );
+   return rc;
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
+ /*
++** Checks if the specified token is a table, column, or function name,
++** based on the databases associated with the statement being prepared.
++** If the function fails, zero is returned and pRc is filled with the
++** error code.
++*/
++static int shouldTreatAsIdentifier(
++  sqlite3 *db,        /* Database handle. */
++  const char *zToken, /* Pointer to start of token to be checked */
++  int nToken,         /* Length of token to be checked */
++  int *pRc            /* Pointer to error code upon failure */
++){
++  int bFound = 0;     /* Non-zero if token is an identifier name. */
++  int i, j;           /* Database and column loop indexes. */
++  Schema *pSchema;    /* Schema for current database. */
++  Hash *pHash;        /* Hash table of tables for current database. */
++  HashElem *e;        /* Hash element for hash table iteration. */
++  Table *pTab;        /* Database table for columns being checked. */
++
++  if( sqlite3IsRowidN(zToken, nToken) ){
++    return 1;
++  }
++  if( nToken>0 ){
++    int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
++    if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
++  }
++  assert( db!=0 );
++  sqlite3_mutex_enter(db->mutex);
++  sqlite3BtreeEnterAll(db);
++  for(i=0; i<db->nDb; i++){
++    pHash = &db->aFunc;
++    if( sqlite3HashFindN(pHash, zToken, nToken) ){
++      bFound = 1;
++      break;
++    }
++    pSchema = db->aDb[i].pSchema;
++    if( pSchema==0 ) continue;
++    pHash = &pSchema->tblHash;
++    if( sqlite3HashFindN(pHash, zToken, nToken) ){
++      bFound = 1;
++      break;
++    }
++    for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
++      pTab = sqliteHashData(e);
++      if( pTab==0 ) continue;
++      pHash = pTab->pColHash;
++      if( pHash==0 ){
++        pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
++        if( pHash ){
++          sqlite3HashInit(pHash);
++          for(j=0; j<pTab->nCol; j++){
++            Column *pCol = &pTab->aCol[j];
++            sqlite3HashInsert(pHash, pCol->zName, pCol);
++          }
++        }else{
++          *pRc = SQLITE_NOMEM_BKPT;
++          bFound = 0;
++          goto done;
++        }
++      }
++      if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
++        bFound = 1;
++        goto done;
++      }
++    }
++  }
++done:
++  sqlite3BtreeLeaveAll(db);
++  sqlite3_mutex_leave(db->mutex);
++  return bFound;
++}
++
++/*
++** Attempt to estimate the final output buffer size needed for the fully
++** normalized version of the specified SQL string.  This should take into
++** account any potential expansion that could occur (e.g. via IN clauses
++** being expanded, etc).  This size returned is the total number of bytes
++** including the NUL terminator.
++*/
++static int estimateNormalizedSize(
++  const char *zSql, /* The original SQL string */
++  int nSql,         /* Length of original SQL string */
++  u8 prepFlags      /* The flags passed to sqlite3_prepare_v3() */
++){
++  int nOut = nSql + 4;
++  const char *z = zSql;
++  while( nOut<nSql*5 ){
++    while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
++    if( z[0]==0 ) break;
++    z++;
++    if( z[0]!='N' && z[0]!='n' ) break;
++    z++;
++    while( sqlite3Isspace(z[0]) ){ z++; }
++    if( z[0]!='(' ) break;
++    z++;
++    nOut += 5; /* ?,?,? */
++  }
++  return nOut;
++}
++
++/*
++** Copy the current token into the output buffer while dealing with quoted
++** identifiers.  By default, all letters will be converted into lowercase.
++** If the bUpper flag is set, uppercase will be used.  The piOut argument
++** will be used to update the target index into the output string.
++*/
++static void copyNormalizedToken(
++  const char *zSql, /* The original SQL string */
++  int iIn,          /* Current index into the original SQL string */
++  int nToken,       /* Number of bytes in the current token */
++  int tokenFlags,   /* Flags returned by the tokenizer */
++  char *zOut,       /* The output string */
++  int *piOut        /* Pointer to target index into the output string */
++){
++  int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
++  int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
++  int j = *piOut, k = 0;
++  for(; k<nToken; k++){
++    if( bQuoted ){
++      if( k==0 && iIn>0 ){
++        zOut[j++] = '"';
++        continue;
++      }else if( k==nToken-1 ){
++        zOut[j++] = '"';
++        continue;
++      }
++    }
++    if( bKeyword ){
++      zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
++    }else{
++      zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
++    }
++  }
++  *piOut = j;
++}
++
++/*
++** Perform normalization of the SQL contained in the prepared statement and
++** store the result in the zNormSql field.  The schema for the associated
++** databases are consulted while performing the normalization in order to
++** determine if a token appears to be an identifier.  All identifiers are
++** left intact in the normalized SQL and all literals are replaced with a
++** single '?'.
++*/
++SQLITE_PRIVATE void sqlite3Normalize(
++  Vdbe *pVdbe,      /* VM being reprepared */
++  const char *zSql, /* The original SQL string */
++  int nSql,         /* Size of the input string in bytes */
++  u8 prepFlags      /* The flags passed to sqlite3_prepare_v3() */
++){
++  sqlite3 *db;           /* Database handle. */
++  char *z;               /* The output string */
++  int nZ;                /* Size of the output string in bytes */
++  int i;                 /* Next character to read from zSql[] */
++  int j;                 /* Next character to fill in on z[] */
++  int tokenType = 0;     /* Type of the next token */
++  int prevTokenType = 0; /* Type of the previous token, except spaces */
++  int n;                 /* Size of the next token */
++  int nParen = 0;        /* Nesting level of parenthesis */
++  Hash inHash;           /* Table of parenthesis levels to output index. */
++
++  db = sqlite3VdbeDb(pVdbe);
++  assert( db!=0 );
++  assert( pVdbe->zNormSql==0 );
++  if( zSql==0 ) return;
++  nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
++  z = sqlite3DbMallocRawNN(db, nZ);
++  if( z==0 ) return;
++  sqlite3HashInit(&inHash);
++  for(i=j=0; i<nSql && zSql[i]; i+=n){
++    int flags = 0;
++    if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
++    n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
++    switch( tokenType ){
++      case TK_SPACE: {
++        break;
++      }
++      case TK_ILLEGAL: {
++        sqlite3DbFree(db, z);
++        sqlite3HashClear(&inHash);
++        return;
++      }
++      case TK_STRING:
++      case TK_INTEGER:
++      case TK_FLOAT:
++      case TK_VARIABLE:
++      case TK_BLOB: {
++        z[j++] = '?';
++        break;
++      }
++      case TK_LP:
++      case TK_RP: {
++        if( tokenType==TK_LP ){
++          nParen++;
++          if( prevTokenType==TK_IN ){
++            assert( nParen<nSql );
++            sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
++          }
++        }else{
++          int jj;
++          assert( nParen<nSql );
++          jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
++          if( jj>0 ){
++            sqlite3HashInsert(&inHash, zSql+nParen, 0);
++            assert( jj+6<nZ );
++            memcpy(z+jj+1, "?,?,?", 5);
++            j = jj+6;
++            assert( nZ-1-j>=0 );
++            assert( nZ-1-j<nZ );
++            memset(z+j, 0, nZ-1-j);
++          }
++          nParen--;
++        }
++        assert( nParen>=0 );
++        /* Fall through */
++      }
++      case TK_MINUS:
++      case TK_SEMI:
++      case TK_PLUS:
++      case TK_STAR:
++      case TK_SLASH:
++      case TK_REM:
++      case TK_EQ:
++      case TK_LE:
++      case TK_NE:
++      case TK_LSHIFT:
++      case TK_LT:
++      case TK_RSHIFT:
++      case TK_GT:
++      case TK_GE:
++      case TK_BITOR:
++      case TK_CONCAT:
++      case TK_COMMA:
++      case TK_BITAND:
++      case TK_BITNOT:
++      case TK_DOT:
++      case TK_IN:
++      case TK_IS:
++      case TK_NOT:
++      case TK_NULL:
++      case TK_ID: {
++        if( tokenType==TK_NULL ){
++          if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
++            /* NULL is a keyword in this case, not a literal value */
++          }else{
++            /* Here the NULL is a literal value */
++            z[j++] = '?';
++            break;
++          }
++        }
++        if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
++          z[j++] = ' ';
++        }
++        if( tokenType==TK_ID ){
++          int i2 = i, n2 = n, rc = SQLITE_OK;
++          if( nParen>0 ){
++            assert( nParen<nSql );
++            sqlite3HashInsert(&inHash, zSql+nParen, 0);
++          }
++          if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
++          if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
++            if( rc!=SQLITE_OK ){
++              sqlite3DbFree(db, z);
++              sqlite3HashClear(&inHash);
++              return;
++            }
++            if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
++              z[j++] = '?';
++              break;
++            }
++          }
++        }
++        copyNormalizedToken(zSql, i, n, flags, z, &j);
++        break;
++      }
++    }
++  }
++  assert( j<nZ && "one" );
++  while( j>0 && z[j-1]==' ' ){ j--; }
++  if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
++  z[j] = 0;
++  assert( j<nZ && "two" );
++  pVdbe->zNormSql = z;
++  sqlite3HashClear(&inHash);
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
++/*
+ ** Rerun the compilation of a statement after a schema change.
+ **
+ ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
+@@ -117455,8 +123928,7 @@
+ /***/ int sqlite3SelectTrace = 0;
+ # define SELECTTRACE(K,P,S,X)  \
+   if(sqlite3SelectTrace&(K))   \
+-    sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
+-        (S)->zSelName,(S)),\
++    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
+     sqlite3DebugPrintf X
+ #else
+ # define SELECTTRACE(K,P,S,X)
+@@ -117479,6 +123951,20 @@
+ /*
+ ** An instance of the following object is used to record information about
+ ** the ORDER BY (or GROUP BY) clause of query is being coded.
++**
++** The aDefer[] array is used by the sorter-references optimization. For
++** example, assuming there is no index that can be used for the ORDER BY,
++** for the query:
++**
++**     SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10;
++**
++** it may be more efficient to add just the "a" values to the sorter, and
++** retrieve the associated "bigblob" values directly from table t1 as the
++** 10 smallest "a" values are extracted from the sorter.
++**
++** When the sorter-reference optimization is used, there is one entry in the
++** aDefer[] array for each database table that may be read as values are
++** extracted from the sorter.
+ */
+ typedef struct SortCtx SortCtx;
+ struct SortCtx {
+@@ -117489,8 +123975,17 @@
+   int labelBkOut;       /* Start label for the block-output subroutine */
+   int addrSortIndex;    /* Address of the OP_SorterOpen or OP_OpenEphemeral */
+   int labelDone;        /* Jump here when done, ex: LIMIT reached */
++  int labelOBLopt;      /* Jump here when sorter is full */
+   u8 sortFlags;         /* Zero or more SORTFLAG_* bits */
+-  u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  u8 nDefer;            /* Number of valid entries in aDefer[] */
++  struct DeferredCsr {
++    Table *pTab;        /* Table definition */
++    int iCsr;           /* Cursor number for table */
++    int nKey;           /* Number of PK columns for table pTab (>=1) */
++  } aDefer[4];
++#endif
++  struct RowLoadInfo *pDeferredRowLoad;  /* Deferred row loading info or NULL */
+ };
+ #define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */
+ 
+@@ -117508,8 +124003,12 @@
+     sqlite3ExprDelete(db, p->pHaving);
+     sqlite3ExprListDelete(db, p->pOrderBy);
+     sqlite3ExprDelete(db, p->pLimit);
+-    sqlite3ExprDelete(db, p->pOffset);
+-    if( p->pWith ) sqlite3WithDelete(db, p->pWith);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
++      sqlite3WindowListDelete(db, p->pWinDefn);
++    }
++#endif
++    if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
+     if( bFree ) sqlite3DbFreeNN(db, p);
+     p = pPrior;
+     bFree = 1;
+@@ -117541,8 +124040,7 @@
+   Expr *pHaving,        /* the HAVING clause */
+   ExprList *pOrderBy,   /* the ORDER BY clause */
+   u32 selFlags,         /* Flag parameters, such as SF_Distinct */
+-  Expr *pLimit,         /* LIMIT value.  NULL means not used */
+-  Expr *pOffset         /* OFFSET value.  NULL means no offset */
++  Expr *pLimit          /* LIMIT value.  NULL means not used */
+ ){
+   Select *pNew;
+   Select standin;
+@@ -117552,7 +124050,8 @@
+     pNew = &standin;
+   }
+   if( pEList==0 ){
+-    pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
++    pEList = sqlite3ExprListAppend(pParse, 0,
++                                   sqlite3Expr(pParse->db,TK_ASTERISK,0));
+   }
+   pNew->pEList = pEList;
+   pNew->op = TK_SELECT;
+@@ -117559,9 +124058,7 @@
+   pNew->selFlags = selFlags;
+   pNew->iLimit = 0;
+   pNew->iOffset = 0;
+-#if SELECTTRACE_ENABLED
+-  pNew->zSelName[0] = 0;
+-#endif
++  pNew->selId = ++pParse->nSelect;
+   pNew->addrOpenEphm[0] = -1;
+   pNew->addrOpenEphm[1] = -1;
+   pNew->nSelectRow = 0;
+@@ -117574,9 +124071,11 @@
+   pNew->pPrior = 0;
+   pNew->pNext = 0;
+   pNew->pLimit = pLimit;
+-  pNew->pOffset = pOffset;
+   pNew->pWith = 0;
+-  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  pNew->pWin = 0;
++  pNew->pWinDefn = 0;
++#endif
+   if( pParse->db->mallocFailed ) {
+     clearSelect(pParse->db, pNew, pNew!=&standin);
+     pNew = 0;
+@@ -117587,23 +124086,12 @@
+   return pNew;
+ }
+ 
+-#if SELECTTRACE_ENABLED
+-/*
+-** Set the name of a Select object
+-*/
+-SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
+-  if( p && zName ){
+-    sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
+-  }
+-}
+-#endif
+ 
+-
+ /*
+ ** Delete the given Select structure and all of its substructures.
+ */
+ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
+-  if( p ) clearSelect(db, p, 1);
++  if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
+ }
+ 
+ /*
+@@ -117820,6 +124308,29 @@
+   } 
+ }
+ 
++/* Undo the work of setJoinExpr().  In the expression tree p, convert every
++** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
++** an ordinary term that omits the EP_FromJoin mark.
++**
++** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
++*/
++static void unsetJoinExpr(Expr *p, int iTable){
++  while( p ){
++    if( ExprHasProperty(p, EP_FromJoin)
++     && (iTable<0 || p->iRightJoinTable==iTable) ){
++      ExprClearProperty(p, EP_FromJoin);
++    }
++    if( p->op==TK_FUNCTION && p->x.pList ){
++      int i;
++      for(i=0; i<p->x.pList->nExpr; i++){
++        unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
++      }
++    }
++    unsetJoinExpr(p->pLeft, iTable);
++    p = p->pRight;
++  } 
++}
++
+ /*
+ ** This routine processes the join information for a SELECT statement.
+ ** ON and USING clauses are converted into extra terms of the WHERE clause.
+@@ -117844,11 +124355,10 @@
+   pLeft = &pSrc->a[0];
+   pRight = &pLeft[1];
+   for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
+-    Table *pLeftTab = pLeft->pTab;
+     Table *pRightTab = pRight->pTab;
+     int isOuter;
+ 
+-    if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
++    if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
+     isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
+ 
+     /* When the NATURAL keyword is present, add WHERE clause terms for
+@@ -117922,15 +124432,63 @@
+   return 0;
+ }
+ 
+-/* Forward reference */
+-static KeyInfo *keyInfoFromExprList(
+-  Parse *pParse,       /* Parsing context */
+-  ExprList *pList,     /* Form the KeyInfo object from this ExprList */
+-  int iStart,          /* Begin with this column of pList */
+-  int nExtra           /* Add this many extra columns to the end */
+-);
++/*
++** An instance of this object holds information (beyond pParse and pSelect)
++** needed to load the next result row that is to be added to the sorter.
++*/
++typedef struct RowLoadInfo RowLoadInfo;
++struct RowLoadInfo {
++  int regResult;               /* Store results in array of registers here */
++  u8 ecelFlags;                /* Flag argument to ExprCodeExprList() */
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  ExprList *pExtra;            /* Extra columns needed by sorter refs */
++  int regExtraResult;          /* Where to load the extra columns */
++#endif
++};
+ 
+ /*
++** This routine does the work of loading query data into an array of
++** registers so that it can be added to the sorter.
++*/
++static void innerLoopLoadRow(
++  Parse *pParse,             /* Statement under construction */
++  Select *pSelect,           /* The query being coded */
++  RowLoadInfo *pInfo         /* Info needed to complete the row load */
++){
++  sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult,
++                          0, pInfo->ecelFlags);
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  if( pInfo->pExtra ){
++    sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0);
++    sqlite3ExprListDelete(pParse->db, pInfo->pExtra);
++  }
++#endif
++}
++
++/*
++** Code the OP_MakeRecord instruction that generates the entry to be
++** added into the sorter.
++**
++** Return the register in which the result is stored.
++*/
++static int makeSorterRecord(
++  Parse *pParse,
++  SortCtx *pSort,
++  Select *pSelect,
++  int regBase,
++  int nBase
++){
++  int nOBSat = pSort->nOBSat;
++  Vdbe *v = pParse->pVdbe;
++  int regOut = ++pParse->nMem;
++  if( pSort->pDeferredRowLoad ){
++    innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad);
++  }
++  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut);
++  return regOut;
++}
++
++/*
+ ** Generate code that will push the record in registers regData
+ ** through regData+nData-1 onto the sorter.
+ */
+@@ -117940,7 +124498,7 @@
+   Select *pSelect,       /* The whole SELECT statement */
+   int regData,           /* First register holding data to be sorted */
+   int regOrigData,       /* First register holding data before packing */
+-  int nData,             /* Number of elements in the data array */
++  int nData,             /* Number of elements in the regData data array */
+   int nPrefixReg         /* No. of reg prior to regData available for use */
+ ){
+   Vdbe *v = pParse->pVdbe;                         /* Stmt under construction */
+@@ -117948,16 +124506,32 @@
+   int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
+   int nBase = nExpr + bSeq + nData;                /* Fields in sorter record */
+   int regBase;                                     /* Regs for sorter record */
+-  int regRecord = ++pParse->nMem;                  /* Assembled sorter record */
++  int regRecord = 0;                               /* Assembled sorter record */
+   int nOBSat = pSort->nOBSat;                      /* ORDER BY terms to skip */
+   int op;                            /* Opcode to add sorter record to sorter */
+   int iLimit;                        /* LIMIT counter */
++  int iSkip = 0;                     /* End of the sorter insert loop */
+ 
+   assert( bSeq==0 || bSeq==1 );
++
++  /* Three cases:
++  **   (1) The data to be sorted has already been packed into a Record
++  **       by a prior OP_MakeRecord.  In this case nData==1 and regData
++  **       will be completely unrelated to regOrigData.
++  **   (2) All output columns are included in the sort record.  In that
++  **       case regData==regOrigData.
++  **   (3) Some output columns are omitted from the sort record due to
++  **       the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the
++  **       SQLITE_ECEL_OMITREF optimization, or due to the 
++  **       SortCtx.pDeferredRowLoad optimiation.  In any of these cases
++  **       regOrigData is 0 to prevent this routine from trying to copy
++  **       values that might not yet exist.
++  */
+   assert( nData==1 || regData==regOrigData || regOrigData==0 );
++
+   if( nPrefixReg ){
+     assert( nPrefixReg==nExpr+bSeq );
+-    regBase = regData - nExpr - bSeq;
++    regBase = regData - nPrefixReg;
+   }else{
+     regBase = pParse->nMem + 1;
+     pParse->nMem += nBase;
+@@ -117973,7 +124547,6 @@
+   if( nPrefixReg==0 && nData>0 ){
+     sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+   }
+-  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
+   if( nOBSat>0 ){
+     int regPrevKey;   /* The first nOBSat columns of the previous row */
+     int addrFirst;    /* Address of the OP_IfNot opcode */
+@@ -117982,6 +124555,7 @@
+     int nKey;         /* Number of sorting key columns, including OP_Sequence */
+     KeyInfo *pKI;     /* Original KeyInfo on the sorter table */
+ 
++    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
+     regPrevKey = pParse->nMem+1;
+     pParse->nMem += pSort->nOBSat;
+     nKey = nExpr - pSort->nOBSat + bSeq;
+@@ -117996,11 +124570,11 @@
+     if( pParse->db->mallocFailed ) return;
+     pOp->p2 = nKey + nData;
+     pKI = pOp->p4.pKeyInfo;
+-    memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
++    memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
+     sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
+-    testcase( pKI->nXField>2 );
+-    pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
+-                                           pKI->nXField-1);
++    testcase( pKI->nAllField > pKI->nKeyField+2 );
++    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
++                                           pKI->nAllField-pKI->nKeyField-1);
+     addrJmp = sqlite3VdbeCurrentAddr(v);
+     sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
+     pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+@@ -118015,6 +124589,34 @@
+     sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
+     sqlite3VdbeJumpHere(v, addrJmp);
+   }
++  if( iLimit ){
++    /* At this point the values for the new sorter entry are stored
++    ** in an array of registers. They need to be composed into a record
++    ** and inserted into the sorter if either (a) there are currently
++    ** less than LIMIT+OFFSET items or (b) the new record is smaller than 
++    ** the largest record currently in the sorter. If (b) is true and there
++    ** are already LIMIT+OFFSET items in the sorter, delete the largest
++    ** entry before inserting the new one. This way there are never more 
++    ** than LIMIT+OFFSET items in the sorter.
++    **
++    ** If the new record does not need to be inserted into the sorter,
++    ** jump to the next iteration of the loop. If the pSort->labelOBLopt
++    ** value is not zero, then it is a label of where to jump.  Otherwise,
++    ** just bypass the row insert logic.  See the header comment on the
++    ** sqlite3WhereOrderByLimitOptLabel() function for additional info.
++    */
++    int iCsr = pSort->iECursor;
++    sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0);
++    iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE,
++                                 iCsr, 0, regBase+nOBSat, nExpr-nOBSat);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp1(v, OP_Delete, iCsr);
++  }
++  if( regRecord==0 ){
++    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
++  }
+   if( pSort->sortFlags & SORTFLAG_UseSorter ){
+     op = OP_SorterInsert;
+   }else{
+@@ -118022,33 +124624,9 @@
+   }
+   sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
+                        regBase+nOBSat, nBase-nOBSat);
+-  if( iLimit ){
+-    int addr;
+-    int r1 = 0;
+-    /* Fill the sorter until it contains LIMIT+OFFSET entries.  (The iLimit
+-    ** register is initialized with value of LIMIT+OFFSET.)  After the sorter
+-    ** fills up, delete the least entry in the sorter after each insert.
+-    ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
+-    addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
+-    sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
+-    if( pSort->bOrderedInnerLoop ){
+-      r1 = ++pParse->nMem;
+-      sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1);
+-      VdbeComment((v, "seq"));
+-    }
+-    sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
+-    if( pSort->bOrderedInnerLoop ){
+-      /* If the inner loop is driven by an index such that values from
+-      ** the same iteration of the inner loop are in sorted order, then
+-      ** immediately jump to the next iteration of an inner loop if the
+-      ** entry from the current iteration does not fit into the top
+-      ** LIMIT+OFFSET entries of the sorter. */
+-      int iBrk = sqlite3VdbeCurrentAddr(v) + 2;
+-      sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1);
+-      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+-      VdbeCoverage(v);
+-    }
+-    sqlite3VdbeJumpHere(v, addr);
++  if( iSkip ){
++    sqlite3VdbeChangeP2(v, iSkip,
++         pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
+   }
+ }
+ 
+@@ -118094,20 +124672,100 @@
+   sqlite3ReleaseTempReg(pParse, r1);
+ }
+ 
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ /*
++** This function is called as part of inner-loop generation for a SELECT
++** statement with an ORDER BY that is not optimized by an index. It 
++** determines the expressions, if any, that the sorter-reference 
++** optimization should be used for. The sorter-reference optimization
++** is used for SELECT queries like:
++**
++**   SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10
++**
++** If the optimization is used for expression "bigblob", then instead of
++** storing values read from that column in the sorter records, the PK of
++** the row from table t1 is stored instead. Then, as records are extracted from
++** the sorter to return to the user, the required value of bigblob is
++** retrieved directly from table t1. If the values are very large, this 
++** can be more efficient than storing them directly in the sorter records.
++**
++** The ExprList_item.bSorterRef flag is set for each expression in pEList 
++** for which the sorter-reference optimization should be enabled. 
++** Additionally, the pSort->aDefer[] array is populated with entries
++** for all cursors required to evaluate all selected expressions. Finally.
++** output variable (*ppExtra) is set to an expression list containing
++** expressions for all extra PK values that should be stored in the
++** sorter records.
++*/
++static void selectExprDefer(
++  Parse *pParse,                  /* Leave any error here */
++  SortCtx *pSort,                 /* Sorter context */
++  ExprList *pEList,               /* Expressions destined for sorter */
++  ExprList **ppExtra              /* Expressions to append to sorter record */
++){
++  int i;
++  int nDefer = 0;
++  ExprList *pExtra = 0;
++  for(i=0; i<pEList->nExpr; i++){
++    struct ExprList_item *pItem = &pEList->a[i];
++    if( pItem->u.x.iOrderByCol==0 ){
++      Expr *pExpr = pItem->pExpr;
++      Table *pTab = pExpr->y.pTab;
++      if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
++       && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
++      ){
++        int j;
++        for(j=0; j<nDefer; j++){
++          if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
++        }
++        if( j==nDefer ){
++          if( nDefer==ArraySize(pSort->aDefer) ){
++            continue;
++          }else{
++            int nKey = 1;
++            int k;
++            Index *pPk = 0;
++            if( !HasRowid(pTab) ){
++              pPk = sqlite3PrimaryKeyIndex(pTab);
++              nKey = pPk->nKeyCol;
++            }
++            for(k=0; k<nKey; k++){
++              Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
++              if( pNew ){
++                pNew->iTable = pExpr->iTable;
++                pNew->y.pTab = pExpr->y.pTab;
++                pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
++                pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
++              }
++            }
++            pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
++            pSort->aDefer[nDefer].iCsr = pExpr->iTable;
++            pSort->aDefer[nDefer].nKey = nKey;
++            nDefer++;
++          }
++        }
++        pItem->bSorterRef = 1;
++      }
++    }
++  }
++  pSort->nDefer = (u8)nDefer;
++  *ppExtra = pExtra;
++}
++#endif
++
++/*
+ ** This routine generates the code for the inside of the inner loop
+ ** of a SELECT.
+ **
+-** If srcTab is negative, then the pEList expressions
++** If srcTab is negative, then the p->pEList expressions
+ ** are evaluated in order to get the data for this row.  If srcTab is
+-** zero or more, then data is pulled from srcTab and pEList is used only 
++** zero or more, then data is pulled from srcTab and p->pEList is used only 
+ ** to get the number of columns and the collation sequence for each column.
+ */
+ static void selectInnerLoop(
+   Parse *pParse,          /* The parser context */
+   Select *p,              /* The complete select statement being coded */
+-  ExprList *pEList,       /* List of values being extracted */
+-  int srcTab,             /* Pull data from this table */
++  int srcTab,             /* Pull data from this table if non-negative */
+   SortCtx *pSort,         /* If not NULL, info on how to process ORDER BY */
+   DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
+   SelectDest *pDest,      /* How to dispose of the results */
+@@ -118121,6 +124779,7 @@
+   int iParm = pDest->iSDParm; /* First argument to disposal method */
+   int nResultCol;             /* Number of result columns */
+   int nPrefixReg = 0;         /* Number of extra registers before regResult */
++  RowLoadInfo sRowLoadInfo;   /* Info for deferred row loading */
+ 
+   /* Usually, regResult is the first cell in an array of memory cells
+   ** containing the current result row. In this case regOrig is set to the
+@@ -118131,7 +124790,7 @@
+   int regOrig;                /* Start of memory holding full result (or 0) */
+ 
+   assert( v );
+-  assert( pEList!=0 );
++  assert( p->pEList!=0 );
+   hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
+   if( pSort && pSort->pOrderBy==0 ) pSort = 0;
+   if( pSort==0 && !hasDistinct ){
+@@ -118141,7 +124800,7 @@
+ 
+   /* Pull the requested columns.
+   */
+-  nResultCol = pEList->nExpr;
++  nResultCol = p->pEList->nExpr;
+ 
+   if( pDest->iSdst==0 ){
+     if( pSort ){
+@@ -118164,13 +124823,17 @@
+   if( srcTab>=0 ){
+     for(i=0; i<nResultCol; i++){
+       sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
+-      VdbeComment((v, "%s", pEList->a[i].zName));
++      VdbeComment((v, "%s", p->pEList->a[i].zName));
+     }
+   }else if( eDest!=SRT_Exists ){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    ExprList *pExtra = 0;
++#endif
+     /* If the destination is an EXISTS(...) expression, the actual
+     ** values returned by the SELECT are not required.
+     */
+-    u8 ecelFlags;
++    u8 ecelFlags;    /* "ecel" is an abbreviation of "ExprCodeExprList" */
++    ExprList *pEList;
+     if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
+       ecelFlags = SQLITE_ECEL_DUP;
+     }else{
+@@ -118177,24 +124840,75 @@
+       ecelFlags = 0;
+     }
+     if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
+-      /* For each expression in pEList that is a copy of an expression in
++      /* For each expression in p->pEList that is a copy of an expression in
+       ** the ORDER BY clause (pSort->pOrderBy), set the associated 
+       ** iOrderByCol value to one more than the index of the ORDER BY 
+       ** expression within the sort-key that pushOntoSorter() will generate.
+-      ** This allows the pEList field to be omitted from the sorted record,
++      ** This allows the p->pEList field to be omitted from the sorted record,
+       ** saving space and CPU cycles.  */
+       ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
++
+       for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
+         int j;
+         if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
+-          pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
++          p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
+         }
+       }
+-      regOrig = 0;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++      selectExprDefer(pParse, pSort, p->pEList, &pExtra);
++      if( pExtra && pParse->db->mallocFailed==0 ){
++        /* If there are any extra PK columns to add to the sorter records,
++        ** allocate extra memory cells and adjust the OpenEphemeral 
++        ** instruction to account for the larger records. This is only
++        ** required if there are one or more WITHOUT ROWID tables with
++        ** composite primary keys in the SortCtx.aDefer[] array.  */
++        VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
++        pOp->p2 += (pExtra->nExpr - pSort->nDefer);
++        pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer);
++        pParse->nMem += pExtra->nExpr;
++      }
++#endif
++
++      /* Adjust nResultCol to account for columns that are omitted
++      ** from the sorter by the optimizations in this branch */
++      pEList = p->pEList;
++      for(i=0; i<pEList->nExpr; i++){
++        if( pEList->a[i].u.x.iOrderByCol>0
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++         || pEList->a[i].bSorterRef
++#endif
++        ){
++          nResultCol--;
++          regOrig = 0;
++        }
++      }
++
++      testcase( regOrig );
++      testcase( eDest==SRT_Set );
++      testcase( eDest==SRT_Mem );
++      testcase( eDest==SRT_Coroutine );
++      testcase( eDest==SRT_Output );
+       assert( eDest==SRT_Set || eDest==SRT_Mem 
+            || eDest==SRT_Coroutine || eDest==SRT_Output );
+     }
+-    nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags);
++    sRowLoadInfo.regResult = regResult;
++    sRowLoadInfo.ecelFlags = ecelFlags;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    sRowLoadInfo.pExtra = pExtra;
++    sRowLoadInfo.regExtraResult = regResult + nResultCol;
++    if( pExtra ) nResultCol += pExtra->nExpr;
++#endif
++    if( p->iLimit
++     && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 
++     && nPrefixReg>0
++    ){
++      assert( pSort!=0 );
++      assert( hasDistinct==0 );
++      pSort->pDeferredRowLoad = &sRowLoadInfo;
++      regOrig = 0;
++    }else{
++      innerLoopLoadRow(pParse, p, &sRowLoadInfo);
++    }
+   }
+ 
+   /* If the DISTINCT keyword was present on the SELECT statement
+@@ -118226,7 +124940,7 @@
+ 
+         iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
+         for(i=0; i<nResultCol; i++){
+-          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
++          CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
+           if( i<nResultCol-1 ){
+             sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
+             VdbeCoverage(v);
+@@ -118310,7 +125024,8 @@
+       }
+ #endif
+       if( pSort ){
+-        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
++        assert( regResult==regOrig );
++        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg);
+       }else{
+         int r2 = sqlite3GetTempReg(pParse);
+         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
+@@ -118340,7 +125055,6 @@
+         assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
+         sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, 
+             r1, pDest->zAffSdst, nResultCol);
+-        sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+         sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+         sqlite3ReleaseTempReg(pParse, r1);
+       }
+@@ -118384,7 +125098,6 @@
+         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
+-        sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+       }
+       break;
+     }
+@@ -118469,8 +125182,8 @@
+   KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
+   if( p ){
+     p->aSortOrder = (u8*)&p->aColl[N+X];
+-    p->nField = (u16)N;
+-    p->nXField = (u16)X;
++    p->nKeyField = (u16)N;
++    p->nAllField = (u16)(N+X);
+     p->enc = ENC(db);
+     p->db = db;
+     p->nRef = 1;
+@@ -118527,7 +125240,7 @@
+ ** function is responsible for seeing that this structure is eventually
+ ** freed.
+ */
+-static KeyInfo *keyInfoFromExprList(
++SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(
+   Parse *pParse,       /* Parsing context */
+   ExprList *pList,     /* Form the KeyInfo object from this ExprList */
+   int iStart,          /* Begin with this column of pList */
+@@ -118544,10 +125257,7 @@
+   if( pInfo ){
+     assert( sqlite3KeyInfoIsWriteable(pInfo) );
+     for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
+-      CollSeq *pColl;
+-      pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
+-      if( !pColl ) pColl = db->pDfltColl;
+-      pInfo->aColl[i-iStart] = pColl;
++      pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
+       pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
+     }
+   }
+@@ -118580,11 +125290,7 @@
+ ** is determined by the zUsage argument.
+ */
+ static void explainTempTable(Parse *pParse, const char *zUsage){
+-  if( pParse->explain==2 ){
+-    Vdbe *v = pParse->pVdbe;
+-    char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
++  ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage));
+ }
+ 
+ /*
+@@ -118602,42 +125308,6 @@
+ # define explainSetInteger(y,z)
+ #endif
+ 
+-#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
+-/*
+-** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
+-** is a no-op. Otherwise, it adds a single row of output to the EQP result,
+-** where the caption is of one of the two forms:
+-**
+-**   "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
+-**   "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
+-**
+-** where iSub1 and iSub2 are the integers passed as the corresponding
+-** function parameters, and op is the text representation of the parameter
+-** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
+-** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is 
+-** false, or the second form if it is true.
+-*/
+-static void explainComposite(
+-  Parse *pParse,                  /* Parse context */
+-  int op,                         /* One of TK_UNION, TK_EXCEPT etc. */
+-  int iSub1,                      /* Subquery id 1 */
+-  int iSub2,                      /* Subquery id 2 */
+-  int bUseTmp                     /* True if a temp table was used */
+-){
+-  assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
+-  if( pParse->explain==2 ){
+-    Vdbe *v = pParse->pVdbe;
+-    char *zMsg = sqlite3MPrintf(
+-        pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
+-        bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
+-    );
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
+-}
+-#else
+-/* No-op versions of the explainXXX() functions and macros. */
+-# define explainComposite(v,w,x,y,z)
+-#endif
+ 
+ /*
+ ** If the inner loop was generated using a non-null pOrderBy argument,
+@@ -118655,7 +125325,7 @@
+   Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
+   int addrBreak = pSort->labelDone;            /* Jump here to exit loop */
+   int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
+-  int addr;
++  int addr;                       /* Top of output loop. Jump for Next. */
+   int addrOnce = 0;
+   int iTab;
+   ExprList *pOrderBy = pSort->pOrderBy;
+@@ -118664,11 +125334,11 @@
+   int regRow;
+   int regRowid;
+   int iCol;
+-  int nKey;
++  int nKey;                       /* Number of key columns in sorter record */
+   int iSortTab;                   /* Sorter cursor to read from */
+-  int nSortData;                  /* Trailing values to read from sorter */
+   int i;
+   int bSeq;                       /* True if sorter record includes seq. no. */
++  int nRefKey = 0;
+   struct ExprList_item *aOutEx = p->pEList->a;
+ 
+   assert( addrBreak<0 );
+@@ -118677,15 +125347,24 @@
+     sqlite3VdbeGoto(v, addrBreak);
+     sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
+   }
++
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  /* Open any cursors needed for sorter-reference expressions */
++  for(i=0; i<pSort->nDefer; i++){
++    Table *pTab = pSort->aDefer[i].pTab;
++    int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
++    sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead);
++    nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey);
++  }
++#endif
++
+   iTab = pSort->iECursor;
+   if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
+     regRowid = 0;
+     regRow = pDest->iSdst;
+-    nSortData = nColumn;
+   }else{
+     regRowid = sqlite3GetTempReg(pParse);
+     regRow = sqlite3GetTempRange(pParse, nColumn);
+-    nSortData = nColumn;
+   }
+   nKey = pOrderBy->nExpr - pSort->nOBSat;
+   if( pSort->sortFlags & SORTFLAG_UseSorter ){
+@@ -118694,7 +125373,8 @@
+     if( pSort->labelBkOut ){
+       addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+     }
+-    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
++    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, 
++        nKey+1+nColumn+nRefKey);
+     if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+     addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
+     VdbeCoverage(v);
+@@ -118707,16 +125387,60 @@
+     iSortTab = iTab;
+     bSeq = 1;
+   }
+-  for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
+-    int iRead;
+-    if( aOutEx[i].u.x.iOrderByCol ){
+-      iRead = aOutEx[i].u.x.iOrderByCol-1;
+-    }else{
+-      iRead = iCol++;
++  for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( aOutEx[i].bSorterRef ) continue;
++#endif
++    if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
++  }
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  if( pSort->nDefer ){
++    int iKey = iCol+1;
++    int regKey = sqlite3GetTempRange(pParse, nRefKey);
++
++    for(i=0; i<pSort->nDefer; i++){
++      int iCsr = pSort->aDefer[i].iCsr;
++      Table *pTab = pSort->aDefer[i].pTab;
++      int nKey = pSort->aDefer[i].nKey;
++
++      sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
++      if( HasRowid(pTab) ){
++        sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey);
++        sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, 
++            sqlite3VdbeCurrentAddr(v)+1, regKey);
++      }else{
++        int k;
++        int iJmp;
++        assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey );
++        for(k=0; k<nKey; k++){
++          sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey+k);
++        }
++        iJmp = sqlite3VdbeCurrentAddr(v);
++        sqlite3VdbeAddOp4Int(v, OP_SeekGE, iCsr, iJmp+2, regKey, nKey);
++        sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp+3, regKey, nKey);
++        sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
++      }
+     }
+-    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
+-    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
++    sqlite3ReleaseTempRange(pParse, regKey, nRefKey);
+   }
++#endif
++  for(i=nColumn-1; i>=0; i--){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( aOutEx[i].bSorterRef ){
++      sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i);
++    }else
++#endif
++    {
++      int iRead;
++      if( aOutEx[i].u.x.iOrderByCol ){
++        iRead = aOutEx[i].u.x.iOrderByCol-1;
++      }else{
++        iRead = iCol--;
++      }
++      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
++      VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan));
++    }
++  }
+   switch( eDest ){
+     case SRT_Table:
+     case SRT_EphemTab: {
+@@ -118730,7 +125454,6 @@
+       assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
+                         pDest->zAffSdst, nColumn);
+-      sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
+       sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
+       break;
+     }
+@@ -118745,7 +125468,6 @@
+       testcase( eDest==SRT_Coroutine );
+       if( eDest==SRT_Output ){
+         sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
+-        sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
+       }else{
+         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+       }
+@@ -118797,23 +125519,23 @@
+ ** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
+ */
+ #ifdef SQLITE_ENABLE_COLUMN_METADATA
+-# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
++# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E)
+ #else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+-# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
++# define columnType(A,B,C,D,E) columnTypeImpl(A,B)
+ #endif
+ static const char *columnTypeImpl(
+   NameContext *pNC, 
++#ifndef SQLITE_ENABLE_COLUMN_METADATA
++  Expr *pExpr
++#else
+   Expr *pExpr,
+-#ifdef SQLITE_ENABLE_COLUMN_METADATA
+   const char **pzOrigDb,
+   const char **pzOrigTab,
+-  const char **pzOrigCol,
++  const char **pzOrigCol
+ #endif
+-  u8 *pEstWidth
+ ){
+   char const *zType = 0;
+   int j;
+-  u8 estWidth = 1;
+ #ifdef SQLITE_ENABLE_COLUMN_METADATA
+   char const *zOrigDb = 0;
+   char const *zOrigTab = 0;
+@@ -118822,8 +125544,9 @@
+ 
+   assert( pExpr!=0 );
+   assert( pNC->pSrcList!=0 );
++  assert( pExpr->op!=TK_AGG_COLUMN );  /* This routine runes before aggregates
++                                       ** are processed */
+   switch( pExpr->op ){
+-    case TK_AGG_COLUMN:
+     case TK_COLUMN: {
+       /* The expression is a column. Locate the table the column is being
+       ** extracted from in NameContext.pSrcList. This table may be real
+@@ -118832,8 +125555,6 @@
+       Table *pTab = 0;            /* Table structure column is extracted from */
+       Select *pS = 0;             /* Select the column is extracted from */
+       int iCol = pExpr->iColumn;  /* Index of column in pTab */
+-      testcase( pExpr->op==TK_AGG_COLUMN );
+-      testcase( pExpr->op==TK_COLUMN );
+       while( pNC && !pTab ){
+         SrcList *pTabList = pNC->pSrcList;
+         for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
+@@ -118866,7 +125587,7 @@
+         break;
+       }
+ 
+-      assert( pTab && pExpr->pTab==pTab );
++      assert( pTab && pExpr->y.pTab==pTab );
+       if( pS ){
+         /* The "table" is actually a sub-select or a view in the FROM clause
+         ** of the SELECT statement. Return the declaration type and origin
+@@ -118882,14 +125603,14 @@
+           sNC.pSrcList = pS->pSrc;
+           sNC.pNext = pNC;
+           sNC.pParse = pNC->pParse;
+-          zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); 
++          zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); 
+         }
+-      }else if( pTab->pSchema ){
+-        /* A real table */
++      }else{
++        /* A real table or a CTE table */
+         assert( !pS );
++#ifdef SQLITE_ENABLE_COLUMN_METADATA
+         if( iCol<0 ) iCol = pTab->iPKey;
+-        assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+-#ifdef SQLITE_ENABLE_COLUMN_METADATA
++        assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
+         if( iCol<0 ){
+           zType = "INTEGER";
+           zOrigCol = "rowid";
+@@ -118896,19 +125617,18 @@
+         }else{
+           zOrigCol = pTab->aCol[iCol].zName;
+           zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+-          estWidth = pTab->aCol[iCol].szEst;
+         }
+         zOrigTab = pTab->zName;
+-        if( pNC->pParse ){
++        if( pNC->pParse && pTab->pSchema ){
+           int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
+           zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
+         }
+ #else
++        assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
+         if( iCol<0 ){
+           zType = "INTEGER";
+         }else{
+           zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
+-          estWidth = pTab->aCol[iCol].szEst;
+         }
+ #endif
+       }
+@@ -118927,7 +125647,7 @@
+       sNC.pSrcList = pS->pSrc;
+       sNC.pNext = pNC;
+       sNC.pParse = pNC->pParse;
+-      zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); 
++      zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); 
+       break;
+     }
+ #endif
+@@ -118941,7 +125661,6 @@
+     *pzOrigCol = zOrigCol;
+   }
+ #endif
+-  if( pEstWidth ) *pEstWidth = estWidth;
+   return zType;
+ }
+ 
+@@ -118968,7 +125687,7 @@
+     const char *zOrigDb = 0;
+     const char *zOrigTab = 0;
+     const char *zOrigCol = 0;
+-    zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0);
++    zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+ 
+     /* The vdbe must make its own copy of the column-type and other 
+     ** column specific strings, in case the schema is reset before this
+@@ -118978,7 +125697,7 @@
+     sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
+     sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
+ #else
+-    zType = columnType(&sNC, p, 0, 0, 0, 0);
++    zType = columnType(&sNC, p, 0, 0, 0);
+ #endif
+     sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
+   }
+@@ -119008,9 +125727,9 @@
+ **                              other words, the zSpan of the result expression.
+ **
+ **    short=ON, full=OFF:       (This is the default setting).  If the result
+-**                              refers directly to a table column, then the result
+-**                              column name is just the table column name: COLUMN. 
+-**                              Otherwise use zSpan.
++**                              refers directly to a table column, then the
++**                              result column name is just the table column
++**                              name: COLUMN.  Otherwise use zSpan.
+ **
+ **    full=ON, short=ANY:       If the result refers directly to a table column,
+ **                              then the result column name with the table name
+@@ -119036,9 +125755,10 @@
+   }
+ #endif
+ 
+-  if( pParse->colNamesSet || db->mallocFailed ) return;
++  if( pParse->colNamesSet ) return;
+   /* Column names are determined by the left-most term of a compound select */
+   while( pSelect->pPrior ) pSelect = pSelect->pPrior;
++  SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
+   pTabList = pSelect->pSrc;
+   pEList = pSelect->pEList;
+   assert( v!=0 );
+@@ -119051,6 +125771,8 @@
+     Expr *p = pEList->a[i].pExpr;
+ 
+     assert( p!=0 );
++    assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
++    assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
+     if( pEList->a[i].zName ){
+       /* An AS clause always takes first priority */
+       char *zName = pEList->a[i].zName;
+@@ -119058,7 +125780,7 @@
+     }else if( srcName && p->op==TK_COLUMN ){
+       char *zCol;
+       int iCol = p->iColumn;
+-      pTab = p->pTab;
++      pTab = p->y.pTab;
+       assert( pTab!=0 );
+       if( iCol<0 ) iCol = pTab->iPKey;
+       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+@@ -119125,6 +125847,7 @@
+     nCol = pEList->nExpr;
+     aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
+     testcase( aCol==0 );
++    if( nCol>32767 ) nCol = 32767;
+   }else{
+     nCol = 0;
+     aCol = 0;
+@@ -119144,10 +125867,12 @@
+         pColExpr = pColExpr->pRight;
+         assert( pColExpr!=0 );
+       }
+-      if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
++      assert( pColExpr->op!=TK_AGG_COLUMN );
++      if( pColExpr->op==TK_COLUMN ){
+         /* For columns use the column name name */
+         int iCol = pColExpr->iColumn;
+-        Table *pTab = pColExpr->pTab;
++        Table *pTab = pColExpr->y.pTab;
++        assert( pTab!=0 );
+         if( iCol<0 ) iCol = pTab->iPKey;
+         zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
+       }else if( pColExpr->op==TK_ID ){
+@@ -119219,7 +125944,6 @@
+   int i;
+   Expr *p;
+   struct ExprList_item *a;
+-  u64 szAll = 0;
+ 
+   assert( pSelect!=0 );
+   assert( (pSelect->selFlags & SF_Resolved)!=0 );
+@@ -119232,10 +125956,11 @@
+     const char *zType;
+     int n, m;
+     p = a[i].pExpr;
+-    zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
+-    szAll += pCol->szEst;
++    zType = columnType(&sNC, p, 0, 0, 0);
++    /* pCol->szEst = ... // Column size est for SELECT tables never used */
+     pCol->affinity = sqlite3ExprAffinity(p);
+-    if( zType && (m = sqlite3Strlen30(zType))>0 ){
++    if( zType ){
++      m = sqlite3Strlen30(zType);
+       n = sqlite3Strlen30(pCol->zName);
+       pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
+       if( pCol->zName ){
+@@ -119249,7 +125974,7 @@
+       pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
+     }
+   }
+-  pTab->szTabRow = sqlite3LogEst(szAll*4);
++  pTab->szTabRow = 1; /* Any non-zero value works */
+ }
+ 
+ /*
+@@ -119292,25 +126017,22 @@
+ ** Get a VDBE for the given parser context.  Create a new one if necessary.
+ ** If an error occurs, return NULL and leave a message in pParse.
+ */
+-static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
+-  Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+-  if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1);
++SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
++  if( pParse->pVdbe ){
++    return pParse->pVdbe;
++  }
+   if( pParse->pToplevel==0
+    && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+   ){
+     pParse->okConstFactor = 1;
+   }
+-  return v;
++  return sqlite3VdbeCreate(pParse);
+ }
+-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
+-  Vdbe *v = pParse->pVdbe;
+-  return v ? v : allocVdbe(pParse);
+-}
+ 
+ 
+ /*
+ ** Compute the iLimit and iOffset fields of the SELECT based on the
+-** pLimit and pOffset expressions.  pLimit and pOffset hold the expressions
++** pLimit expressions.  pLimit->pLeft and pLimit->pRight hold the expressions
+ ** that appear in the original SQL statement after the LIMIT and OFFSET
+ ** keywords.  Or NULL if those keywords are omitted. iLimit and iOffset 
+ ** are the integer memory register numbers for counters used to compute 
+@@ -119318,8 +126040,8 @@
+ ** iLimit and iOffset are negative.
+ **
+ ** This routine changes the values of iLimit and iOffset only if
+-** a limit or offset is defined by pLimit and pOffset.  iLimit and
+-** iOffset should have been preset to appropriate default values (zero)
++** a limit or offset is defined by pLimit->pLeft and pLimit->pRight.  iLimit
++** and iOffset should have been preset to appropriate default values (zero)
+ ** prior to calling this routine.
+ **
+ ** The iOffset register (if it exists) is initialized to the value
+@@ -119326,7 +126048,7 @@
+ ** of the OFFSET.  The iLimit register is initialized to LIMIT.  Register
+ ** iOffset+1 is initialized to LIMIT+OFFSET.
+ **
+-** Only if pLimit!=0 or pOffset!=0 do the limit registers get
++** Only if pLimit->pLeft!=0 do the limit registers get
+ ** redefined.  The UNION ALL operator uses this property to force
+ ** the reuse of the same limit and offset registers across multiple
+ ** SELECT statements.
+@@ -119336,6 +126058,8 @@
+   int iLimit = 0;
+   int iOffset;
+   int n;
++  Expr *pLimit = p->pLimit;
++
+   if( p->iLimit ) return;
+ 
+   /* 
+@@ -119344,13 +126068,13 @@
+   ** The current implementation interprets "LIMIT 0" to mean
+   ** no rows.
+   */
+-  sqlite3ExprCacheClear(pParse);
+-  assert( p->pOffset==0 || p->pLimit!=0 );
+-  if( p->pLimit ){
++  if( pLimit ){
++    assert( pLimit->op==TK_LIMIT );
++    assert( pLimit->pLeft!=0 );
+     p->iLimit = iLimit = ++pParse->nMem;
+     v = sqlite3GetVdbe(pParse);
+     assert( v!=0 );
+-    if( sqlite3ExprIsInteger(p->pLimit, &n) ){
++    if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
+       sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
+       VdbeComment((v, "LIMIT counter"));
+       if( n==0 ){
+@@ -119360,15 +126084,15 @@
+         p->selFlags |= SF_FixedLimit;
+       }
+     }else{
+-      sqlite3ExprCode(pParse, p->pLimit, iLimit);
++      sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
+       sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
+       VdbeComment((v, "LIMIT counter"));
+       sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
+     }
+-    if( p->pOffset ){
++    if( pLimit->pRight ){
+       p->iOffset = iOffset = ++pParse->nMem;
+       pParse->nMem++;   /* Allocate an extra register for limit+offset */
+-      sqlite3ExprCode(pParse, p->pOffset, iOffset);
++      sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
+       sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
+       VdbeComment((v, "OFFSET counter"));
+       sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
+@@ -119498,9 +126222,16 @@
+   int i;                        /* Loop counter */
+   int rc;                       /* Result code */
+   ExprList *pOrderBy;           /* The ORDER BY clause */
+-  Expr *pLimit, *pOffset;       /* Saved LIMIT and OFFSET */
++  Expr *pLimit;                 /* Saved LIMIT and OFFSET */
+   int regLimit, regOffset;      /* Registers used by LIMIT and OFFSET */
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( p->pWin ){
++    sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
++    return;
++  }
++#endif
++
+   /* Obtain authorization to do a recursive query */
+   if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
+ 
+@@ -119509,10 +126240,9 @@
+   p->nSelectRow = 320;  /* 4 billion rows */
+   computeLimitRegisters(pParse, p, addrBreak);
+   pLimit = p->pLimit;
+-  pOffset = p->pOffset;
+   regLimit = p->iLimit;
+   regOffset = p->iOffset;
+-  p->pLimit = p->pOffset = 0;
++  p->pLimit = 0;
+   p->iLimit = p->iOffset = 0;
+   pOrderBy = p->pOrderBy;
+ 
+@@ -119558,6 +126288,7 @@
+ 
+   /* Store the results of the setup-query in Queue. */
+   pSetup->pNext = 0;
++  ExplainQueryPlan((pParse, 1, "SETUP"));
+   rc = sqlite3Select(pParse, pSetup, &destQueue);
+   pSetup->pNext = p;
+   if( rc ) goto end_of_recursive_query;
+@@ -119577,7 +126308,7 @@
+   /* Output the single row in Current */
+   addrCont = sqlite3VdbeMakeLabel(v);
+   codeOffset(v, regOffset, addrCont);
+-  selectInnerLoop(pParse, p, p->pEList, iCurrent,
++  selectInnerLoop(pParse, p, iCurrent,
+       0, 0, pDest, addrCont, addrBreak);
+   if( regLimit ){
+     sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
+@@ -119592,6 +126323,7 @@
+     sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
+   }else{
+     p->pPrior = 0;
++    ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
+     sqlite3Select(pParse, p, &destQueue);
+     assert( p->pPrior==0 );
+     p->pPrior = pSetup;
+@@ -119605,7 +126337,6 @@
+   sqlite3ExprListDelete(pParse->db, p->pOrderBy);
+   p->pOrderBy = pOrderBy;
+   p->pLimit = pLimit;
+-  p->pOffset = pOffset;
+   return;
+ }
+ #endif /* SQLITE_OMIT_CTE */
+@@ -119624,9 +126355,14 @@
+ ** on a VALUES clause.
+ **
+ ** Because the Select object originates from a VALUES clause:
+-**   (1) It has no LIMIT or OFFSET
++**   (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
+ **   (2) All terms are UNION ALL
+ **   (3) There is no ORDER BY clause
++**
++** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
++** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
++** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
++** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
+ */
+ static int multiSelectValues(
+   Parse *pParse,        /* Parsing context */
+@@ -119633,27 +126369,24 @@
+   Select *p,            /* The right-most of SELECTs to be coded */
+   SelectDest *pDest     /* What to do with query results */
+ ){
+-  Select *pPrior;
+   int nRow = 1;
+   int rc = 0;
++  int bShowAll = p->pLimit==0;
+   assert( p->selFlags & SF_MultiValue );
+   do{
+     assert( p->selFlags & SF_Values );
+     assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+-    assert( p->pLimit==0 );
+-    assert( p->pOffset==0 );
+     assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
+     if( p->pPrior==0 ) break;
+     assert( p->pPrior->pNext==p );
+     p = p->pPrior;
+-    nRow++;
++    nRow += bShowAll;
+   }while(1);
++  ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
++                    nRow==1 ? "" : "S"));
+   while( p ){
+-    pPrior = p->pPrior;
+-    p->pPrior = 0;
+-    rc = sqlite3Select(pParse, p, pDest);
+-    p->pPrior = pPrior;
+-    if( rc ) break;
++    selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
++    if( !bShowAll ) break;
+     p->nSelectRow = nRow;
+     p = p->pNext;
+   }
+@@ -119702,10 +126435,6 @@
+   SelectDest dest;      /* Alternative data destination */
+   Select *pDelete = 0;  /* Chain of simple selects to delete */
+   sqlite3 *db;          /* Database connection */
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iSub1 = 0;        /* EQP id of left-hand query */
+-  int iSub2 = 0;        /* EQP id of right-hand query */
+-#endif
+ 
+   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
+   ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
+@@ -119715,18 +126444,12 @@
+   db = pParse->db;
+   pPrior = p->pPrior;
+   dest = *pDest;
+-  if( pPrior->pOrderBy ){
+-    sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
+-      selectOpName(p->op));
++  if( pPrior->pOrderBy || pPrior->pLimit ){
++    sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
++      pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op));
+     rc = 1;
+     goto multi_select_end;
+   }
+-  if( pPrior->pLimit ){
+-    sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
+-      selectOpName(p->op));
+-    rc = 1;
+-    goto multi_select_end;
+-  }
+ 
+   v = sqlite3GetVdbe(pParse);
+   assert( v!=0 );  /* The VDBE already created by calling function */
+@@ -119762,226 +126485,231 @@
+   */
+   if( p->pOrderBy ){
+     return multiSelectOrderBy(pParse, p, pDest);
+-  }else
++  }else{
+ 
+-  /* Generate code for the left and right SELECT statements.
+-  */
+-  switch( p->op ){
+-    case TK_ALL: {
+-      int addr = 0;
+-      int nLimit;
+-      assert( !pPrior->pLimit );
+-      pPrior->iLimit = p->iLimit;
+-      pPrior->iOffset = p->iOffset;
+-      pPrior->pLimit = p->pLimit;
+-      pPrior->pOffset = p->pOffset;
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &dest);
+-      p->pLimit = 0;
+-      p->pOffset = 0;
+-      if( rc ){
+-        goto multi_select_end;
++#ifndef SQLITE_OMIT_EXPLAIN
++    if( pPrior->pPrior==0 ){
++      ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
++      ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
++    }
++#endif
++
++    /* Generate code for the left and right SELECT statements.
++    */
++    switch( p->op ){
++      case TK_ALL: {
++        int addr = 0;
++        int nLimit;
++        assert( !pPrior->pLimit );
++        pPrior->iLimit = p->iLimit;
++        pPrior->iOffset = p->iOffset;
++        pPrior->pLimit = p->pLimit;
++        rc = sqlite3Select(pParse, pPrior, &dest);
++        p->pLimit = 0;
++        if( rc ){
++          goto multi_select_end;
++        }
++        p->pPrior = 0;
++        p->iLimit = pPrior->iLimit;
++        p->iOffset = pPrior->iOffset;
++        if( p->iLimit ){
++          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
++          VdbeComment((v, "Jump ahead if LIMIT reached"));
++          if( p->iOffset ){
++            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
++                              p->iLimit, p->iOffset+1, p->iOffset);
++          }
++        }
++        ExplainQueryPlan((pParse, 1, "UNION ALL"));
++        rc = sqlite3Select(pParse, p, &dest);
++        testcase( rc!=SQLITE_OK );
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
++        if( pPrior->pLimit
++         && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
++         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
++        ){
++          p->nSelectRow = sqlite3LogEst((u64)nLimit);
++        }
++        if( addr ){
++          sqlite3VdbeJumpHere(v, addr);
++        }
++        break;
+       }
+-      p->pPrior = 0;
+-      p->iLimit = pPrior->iLimit;
+-      p->iOffset = pPrior->iOffset;
+-      if( p->iLimit ){
+-        addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+-        VdbeComment((v, "Jump ahead if LIMIT reached"));
+-        if( p->iOffset ){
+-          sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+-                            p->iLimit, p->iOffset+1, p->iOffset);
++      case TK_EXCEPT:
++      case TK_UNION: {
++        int unionTab;    /* Cursor number of the temp table holding result */
++        u8 op = 0;       /* One of the SRT_ operations to apply to self */
++        int priorOp;     /* The SRT_ operation to apply to prior selects */
++        Expr *pLimit;    /* Saved values of p->nLimit  */
++        int addr;
++        SelectDest uniondest;
++  
++        testcase( p->op==TK_EXCEPT );
++        testcase( p->op==TK_UNION );
++        priorOp = SRT_Union;
++        if( dest.eDest==priorOp ){
++          /* We can reuse a temporary table generated by a SELECT to our
++          ** right.
++          */
++          assert( p->pLimit==0 );      /* Not allowed on leftward elements */
++          unionTab = dest.iSDParm;
++        }else{
++          /* We will need to create our own temporary table to hold the
++          ** intermediate results.
++          */
++          unionTab = pParse->nTab++;
++          assert( p->pOrderBy==0 );
++          addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
++          assert( p->addrOpenEphm[0] == -1 );
++          p->addrOpenEphm[0] = addr;
++          findRightmost(p)->selFlags |= SF_UsesEphemeral;
++          assert( p->pEList );
+         }
++  
++        /* Code the SELECT statements to our left
++        */
++        assert( !pPrior->pOrderBy );
++        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
++        rc = sqlite3Select(pParse, pPrior, &uniondest);
++        if( rc ){
++          goto multi_select_end;
++        }
++  
++        /* Code the current SELECT statement
++        */
++        if( p->op==TK_EXCEPT ){
++          op = SRT_Except;
++        }else{
++          assert( p->op==TK_UNION );
++          op = SRT_Union;
++        }
++        p->pPrior = 0;
++        pLimit = p->pLimit;
++        p->pLimit = 0;
++        uniondest.eDest = op;
++        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
++                          selectOpName(p->op)));
++        rc = sqlite3Select(pParse, p, &uniondest);
++        testcase( rc!=SQLITE_OK );
++        /* Query flattening in sqlite3Select() might refill p->pOrderBy.
++        ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
++        sqlite3ExprListDelete(db, p->pOrderBy);
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        p->pOrderBy = 0;
++        if( p->op==TK_UNION ){
++          p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
++        }
++        sqlite3ExprDelete(db, p->pLimit);
++        p->pLimit = pLimit;
++        p->iLimit = 0;
++        p->iOffset = 0;
++  
++        /* Convert the data in the temporary table into whatever form
++        ** it is that we currently need.
++        */
++        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
++        if( dest.eDest!=priorOp ){
++          int iCont, iBreak, iStart;
++          assert( p->pEList );
++          iBreak = sqlite3VdbeMakeLabel(v);
++          iCont = sqlite3VdbeMakeLabel(v);
++          computeLimitRegisters(pParse, p, iBreak);
++          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
++          iStart = sqlite3VdbeCurrentAddr(v);
++          selectInnerLoop(pParse, p, unionTab,
++                          0, 0, &dest, iCont, iBreak);
++          sqlite3VdbeResolveLabel(v, iCont);
++          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
++          sqlite3VdbeResolveLabel(v, iBreak);
++          sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
++        }
++        break;
+       }
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &dest);
+-      testcase( rc!=SQLITE_OK );
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+-      if( pPrior->pLimit
+-       && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
+-       && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
+-      ){
+-        p->nSelectRow = sqlite3LogEst((u64)nLimit);
+-      }
+-      if( addr ){
+-        sqlite3VdbeJumpHere(v, addr);
+-      }
+-      break;
+-    }
+-    case TK_EXCEPT:
+-    case TK_UNION: {
+-      int unionTab;    /* Cursor number of the temporary table holding result */
+-      u8 op = 0;       /* One of the SRT_ operations to apply to self */
+-      int priorOp;     /* The SRT_ operation to apply to prior selects */
+-      Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
+-      int addr;
+-      SelectDest uniondest;
+-
+-      testcase( p->op==TK_EXCEPT );
+-      testcase( p->op==TK_UNION );
+-      priorOp = SRT_Union;
+-      if( dest.eDest==priorOp ){
+-        /* We can reuse a temporary table generated by a SELECT to our
+-        ** right.
++      default: assert( p->op==TK_INTERSECT ); {
++        int tab1, tab2;
++        int iCont, iBreak, iStart;
++        Expr *pLimit;
++        int addr;
++        SelectDest intersectdest;
++        int r1;
++  
++        /* INTERSECT is different from the others since it requires
++        ** two temporary tables.  Hence it has its own case.  Begin
++        ** by allocating the tables we will need.
+         */
+-        assert( p->pLimit==0 );      /* Not allowed on leftward elements */
+-        assert( p->pOffset==0 );     /* Not allowed on leftward elements */
+-        unionTab = dest.iSDParm;
+-      }else{
+-        /* We will need to create our own temporary table to hold the
+-        ** intermediate results.
+-        */
+-        unionTab = pParse->nTab++;
++        tab1 = pParse->nTab++;
++        tab2 = pParse->nTab++;
+         assert( p->pOrderBy==0 );
+-        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
++  
++        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
+         assert( p->addrOpenEphm[0] == -1 );
+         p->addrOpenEphm[0] = addr;
+         findRightmost(p)->selFlags |= SF_UsesEphemeral;
+         assert( p->pEList );
+-      }
+-
+-      /* Code the SELECT statements to our left
+-      */
+-      assert( !pPrior->pOrderBy );
+-      sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &uniondest);
+-      if( rc ){
+-        goto multi_select_end;
+-      }
+-
+-      /* Code the current SELECT statement
+-      */
+-      if( p->op==TK_EXCEPT ){
+-        op = SRT_Except;
+-      }else{
+-        assert( p->op==TK_UNION );
+-        op = SRT_Union;
+-      }
+-      p->pPrior = 0;
+-      pLimit = p->pLimit;
+-      p->pLimit = 0;
+-      pOffset = p->pOffset;
+-      p->pOffset = 0;
+-      uniondest.eDest = op;
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &uniondest);
+-      testcase( rc!=SQLITE_OK );
+-      /* Query flattening in sqlite3Select() might refill p->pOrderBy.
+-      ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
+-      sqlite3ExprListDelete(db, p->pOrderBy);
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      p->pOrderBy = 0;
+-      if( p->op==TK_UNION ){
+-        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+-      }
+-      sqlite3ExprDelete(db, p->pLimit);
+-      p->pLimit = pLimit;
+-      p->pOffset = pOffset;
+-      p->iLimit = 0;
+-      p->iOffset = 0;
+-
+-      /* Convert the data in the temporary table into whatever form
+-      ** it is that we currently need.
+-      */
+-      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
+-      if( dest.eDest!=priorOp ){
+-        int iCont, iBreak, iStart;
++  
++        /* Code the SELECTs to our left into temporary table "tab1".
++        */
++        sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
++        rc = sqlite3Select(pParse, pPrior, &intersectdest);
++        if( rc ){
++          goto multi_select_end;
++        }
++  
++        /* Code the current SELECT into temporary table "tab2"
++        */
++        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
++        assert( p->addrOpenEphm[1] == -1 );
++        p->addrOpenEphm[1] = addr;
++        p->pPrior = 0;
++        pLimit = p->pLimit;
++        p->pLimit = 0;
++        intersectdest.iSDParm = tab2;
++        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
++                          selectOpName(p->op)));
++        rc = sqlite3Select(pParse, p, &intersectdest);
++        testcase( rc!=SQLITE_OK );
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        if( p->nSelectRow>pPrior->nSelectRow ){
++          p->nSelectRow = pPrior->nSelectRow;
++        }
++        sqlite3ExprDelete(db, p->pLimit);
++        p->pLimit = pLimit;
++  
++        /* Generate code to take the intersection of the two temporary
++        ** tables.
++        */
+         assert( p->pEList );
+         iBreak = sqlite3VdbeMakeLabel(v);
+         iCont = sqlite3VdbeMakeLabel(v);
+         computeLimitRegisters(pParse, p, iBreak);
+-        sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
+-        iStart = sqlite3VdbeCurrentAddr(v);
+-        selectInnerLoop(pParse, p, p->pEList, unionTab,
++        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
++        r1 = sqlite3GetTempReg(pParse);
++        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
++        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
++        VdbeCoverage(v);
++        sqlite3ReleaseTempReg(pParse, r1);
++        selectInnerLoop(pParse, p, tab1,
+                         0, 0, &dest, iCont, iBreak);
+         sqlite3VdbeResolveLabel(v, iCont);
+-        sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
++        sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
+         sqlite3VdbeResolveLabel(v, iBreak);
+-        sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
++        sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
++        sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
++        break;
+       }
+-      break;
+     }
+-    default: assert( p->op==TK_INTERSECT ); {
+-      int tab1, tab2;
+-      int iCont, iBreak, iStart;
+-      Expr *pLimit, *pOffset;
+-      int addr;
+-      SelectDest intersectdest;
+-      int r1;
+-
+-      /* INTERSECT is different from the others since it requires
+-      ** two temporary tables.  Hence it has its own case.  Begin
+-      ** by allocating the tables we will need.
+-      */
+-      tab1 = pParse->nTab++;
+-      tab2 = pParse->nTab++;
+-      assert( p->pOrderBy==0 );
+-
+-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
+-      assert( p->addrOpenEphm[0] == -1 );
+-      p->addrOpenEphm[0] = addr;
+-      findRightmost(p)->selFlags |= SF_UsesEphemeral;
+-      assert( p->pEList );
+-
+-      /* Code the SELECTs to our left into temporary table "tab1".
+-      */
+-      sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &intersectdest);
+-      if( rc ){
+-        goto multi_select_end;
+-      }
+-
+-      /* Code the current SELECT into temporary table "tab2"
+-      */
+-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
+-      assert( p->addrOpenEphm[1] == -1 );
+-      p->addrOpenEphm[1] = addr;
+-      p->pPrior = 0;
+-      pLimit = p->pLimit;
+-      p->pLimit = 0;
+-      pOffset = p->pOffset;
+-      p->pOffset = 0;
+-      intersectdest.iSDParm = tab2;
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &intersectdest);
+-      testcase( rc!=SQLITE_OK );
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
+-      sqlite3ExprDelete(db, p->pLimit);
+-      p->pLimit = pLimit;
+-      p->pOffset = pOffset;
+-
+-      /* Generate code to take the intersection of the two temporary
+-      ** tables.
+-      */
+-      assert( p->pEList );
+-      iBreak = sqlite3VdbeMakeLabel(v);
+-      iCont = sqlite3VdbeMakeLabel(v);
+-      computeLimitRegisters(pParse, p, iBreak);
+-      sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
+-      r1 = sqlite3GetTempReg(pParse);
+-      iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+-      sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
+-      sqlite3ReleaseTempReg(pParse, r1);
+-      selectInnerLoop(pParse, p, p->pEList, tab1,
+-                      0, 0, &dest, iCont, iBreak);
+-      sqlite3VdbeResolveLabel(v, iCont);
+-      sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
+-      sqlite3VdbeResolveLabel(v, iBreak);
+-      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
+-      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
+-      break;
++  
++  #ifndef SQLITE_OMIT_EXPLAIN
++    if( p->pNext==0 ){
++      ExplainQueryPlanPop(pParse);
+     }
++  #endif
+   }
+-
+-  explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
+-
++  
+   /* Compute collating sequences used by 
+   ** temporary tables needed to implement the compound select.
+   ** Attach the KeyInfo structure to all temporary tables.
+@@ -120132,7 +126860,6 @@
+       r1 = sqlite3GetTempReg(pParse);
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, 
+           r1, pDest->zAffSdst, pIn->nSdst);
+-      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+       sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
+                            pIn->iSdst, pIn->nSdst);
+       sqlite3ReleaseTempReg(pParse, r1);
+@@ -120175,7 +126902,6 @@
+     default: {
+       assert( pDest->eDest==SRT_Output );
+       sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+-      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+       break;
+     }
+   }
+@@ -120319,10 +127045,6 @@
+   ExprList *pOrderBy;   /* The ORDER BY clause */
+   int nOrderBy;         /* Number of terms in the ORDER BY clause */
+   int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iSub1;            /* EQP id of left-hand query */
+-  int iSub2;            /* EQP id of right-hand query */
+-#endif
+ 
+   assert( p->pOrderBy!=0 );
+   assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
+@@ -120434,8 +127156,6 @@
+   }
+   sqlite3ExprDelete(db, p->pLimit);
+   p->pLimit = 0;
+-  sqlite3ExprDelete(db, p->pOffset);
+-  p->pOffset = 0;
+ 
+   regAddrA = ++pParse->nMem;
+   regAddrB = ++pParse->nMem;
+@@ -120444,6 +127164,8 @@
+   sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
+   sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
+ 
++  ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
++
+   /* Generate a coroutine to evaluate the SELECT statement to the
+   ** left of the compound operator - the "A" select.
+   */
+@@ -120451,7 +127173,7 @@
+   addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+   VdbeComment((v, "left SELECT"));
+   pPrior->iLimit = regLimitA;
+-  explainSetInteger(iSub1, pParse->iNextSelectId);
++  ExplainQueryPlan((pParse, 1, "LEFT"));
+   sqlite3Select(pParse, pPrior, &destA);
+   sqlite3VdbeEndCoroutine(v, regAddrA);
+   sqlite3VdbeJumpHere(v, addr1);
+@@ -120466,7 +127188,7 @@
+   savedOffset = p->iOffset;
+   p->iLimit = regLimitB;
+   p->iOffset = 0;  
+-  explainSetInteger(iSub2, pParse->iNextSelectId);
++  ExplainQueryPlan((pParse, 1, "RIGHT"));
+   sqlite3Select(pParse, p, &destB);
+   p->iLimit = savedLimit;
+   p->iOffset = savedOffset;
+@@ -120578,7 +127300,7 @@
+ 
+   /*** TBD:  Insert subroutine calls to close cursors on incomplete
+   **** subqueries ****/
+-  explainComposite(pParse, p->op, iSub1, iSub2, 0);
++  ExplainQueryPlanPop(pParse);
+   return pParse->nErr!=0;
+ }
+ #endif
+@@ -120621,7 +127343,9 @@
+   Expr *pExpr            /* Expr in which substitution occurs */
+ ){
+   if( pExpr==0 ) return 0;
+-  if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
++  if( ExprHasProperty(pExpr, EP_FromJoin)
++   && pExpr->iRightJoinTable==pSubst->iTable
++  ){
+     pExpr->iRightJoinTable = pSubst->iNewTable;
+   }
+   if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
+@@ -120632,7 +127356,7 @@
+       Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
+       Expr ifNullRow;
+       assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
+-      assert( pExpr->pLeft==0 && pExpr->pRight==0 );
++      assert( pExpr->pRight==0 );
+       if( sqlite3ExprIsVector(pCopy) ){
+         sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
+       }else{
+@@ -120734,69 +127458,75 @@
+ ** exist on the table t1, a complete scan of the data might be
+ ** avoided.
+ **
+-** Flattening is only attempted if all of the following are true:
++** Flattening is subject to the following constraints:
+ **
+-**   (1)  The subquery and the outer query do not both use aggregates.
++**  (**)  We no longer attempt to flatten aggregate subqueries. Was:
++**        The subquery and the outer query cannot both be aggregates.
+ **
+-**   (2)  The subquery is not an aggregate or (2a) the outer query is not a join
+-**        and (2b) the outer query does not use subqueries other than the one
+-**        FROM-clause subquery that is a candidate for flattening.  (2b is
+-**        due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
++**  (**)  We no longer attempt to flatten aggregate subqueries. Was:
++**        (2) If the subquery is an aggregate then
++**        (2a) the outer query must not be a join and
++**        (2b) the outer query must not use subqueries
++**             other than the one FROM-clause subquery that is a candidate
++**             for flattening.  (This is due to ticket [2f7170d73bf9abf80]
++**             from 2015-02-09.)
+ **
+-**   (3)  The subquery is not the right operand of a LEFT JOIN
+-**        or (a) the subquery is not itself a join and (b) the FROM clause
+-**        of the subquery does not contain a virtual table and (c) the 
+-**        outer query is not an aggregate.
++**   (3)  If the subquery is the right operand of a LEFT JOIN then
++**        (3a) the subquery may not be a join and
++**        (3b) the FROM clause of the subquery may not contain a virtual
++**             table and
++**        (3c) the outer query may not be an aggregate.
+ **
+-**   (4)  The subquery is not DISTINCT.
++**   (4)  The subquery can not be DISTINCT.
+ **
+ **  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
+ **        sub-queries that were excluded from this optimization. Restriction 
+ **        (4) has since been expanded to exclude all DISTINCT subqueries.
+ **
+-**   (6)  The subquery does not use aggregates or the outer query is not
+-**        DISTINCT.
++**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
++**        If the subquery is aggregate, the outer query may not be DISTINCT.
+ **
+-**   (7)  The subquery has a FROM clause.  TODO:  For subqueries without
++**   (7)  The subquery must have a FROM clause.  TODO:  For subqueries without
+ **        A FROM clause, consider adding a FROM clause with the special
+ **        table sqlite_once that consists of a single row containing a
+ **        single NULL.
+ **
+-**   (8)  The subquery does not use LIMIT or the outer query is not a join.
++**   (8)  If the subquery uses LIMIT then the outer query may not be a join.
+ **
+-**   (9)  The subquery does not use LIMIT or the outer query does not use
+-**        aggregates.
++**   (9)  If the subquery uses LIMIT then the outer query may not be aggregate.
+ **
+ **  (**)  Restriction (10) was removed from the code on 2005-02-05 but we
+ **        accidently carried the comment forward until 2014-09-15.  Original
+-**        text: "The subquery does not use aggregates or the outer query 
+-**        does not use LIMIT."
++**        constraint: "If the subquery is aggregate then the outer query 
++**        may not use LIMIT."
+ **
+-**  (11)  The subquery and the outer query do not both have ORDER BY clauses.
++**  (11)  The subquery and the outer query may not both have ORDER BY clauses.
+ **
+ **  (**)  Not implemented.  Subsumed into restriction (3).  Was previously
+ **        a separate restriction deriving from ticket #350.
+ **
+-**  (13)  The subquery and outer query do not both use LIMIT.
++**  (13)  The subquery and outer query may not both use LIMIT.
+ **
+-**  (14)  The subquery does not use OFFSET.
++**  (14)  The subquery may not use OFFSET.
+ **
+-**  (15)  The outer query is not part of a compound select or the
+-**        subquery does not have a LIMIT clause.
++**  (15)  If the outer query is part of a compound select, then the
++**        subquery may not use LIMIT.
+ **        (See ticket #2339 and ticket [02a8e81d44]).
+ **
+-**  (16)  The outer query is not an aggregate or the subquery does
+-**        not contain ORDER BY.  (Ticket #2942)  This used to not matter
++**  (16)  If the outer query is aggregate, then the subquery may not
++**        use ORDER BY.  (Ticket #2942)  This used to not matter
+ **        until we introduced the group_concat() function.  
+ **
+-**  (17)  The sub-query is not a compound select, or it is a UNION ALL 
+-**        compound clause made up entirely of non-aggregate queries, and 
+-**        the parent query:
++**  (17)  If the subquery is a compound select, then
++**        (17a) all compound operators must be a UNION ALL, and
++**        (17b) no terms within the subquery compound may be aggregate
++**              or DISTINCT, and
++**        (17c) every term within the subquery compound must have a FROM clause
++**        (17d) the outer query may not be
++**              (17d1) aggregate, or
++**              (17d2) DISTINCT, or
++**              (17d3) a join.
+ **
+-**          * is not itself part of a compound select,
+-**          * is not an aggregate or DISTINCT query, and
+-**          * is not a join
+-**
+ **        The parent and sub-query may contain WHERE clauses. Subject to
+ **        rules (11), (13) and (14), they may also contain ORDER BY,
+ **        LIMIT and OFFSET clauses.  The subquery cannot use any compound
+@@ -120811,10 +127541,10 @@
+ **        syntax error and return a detailed message.
+ **
+ **  (18)  If the sub-query is a compound select, then all terms of the
+-**        ORDER by clause of the parent must be simple references to 
++**        ORDER BY clause of the parent must be simple references to 
+ **        columns of the sub-query.
+ **
+-**  (19)  The subquery does not use LIMIT or the outer query does not
++**  (19)  If the subquery uses LIMIT then the outer query may not
+ **        have a WHERE clause.
+ **
+ **  (20)  If the sub-query is a compound select, then it must not use
+@@ -120823,25 +127553,31 @@
+ **        appear as unmodified result columns in the outer query.  But we
+ **        have other optimizations in mind to deal with that case.
+ **
+-**  (21)  The subquery does not use LIMIT or the outer query is not
++**  (21)  If the subquery uses LIMIT then the outer query may not be
+ **        DISTINCT.  (See ticket [752e1646fc]).
+ **
+-**  (22)  The subquery is not a recursive CTE.
++**  (22)  The subquery may not be a recursive CTE.
+ **
+-**  (23)  The parent is not a recursive CTE, or the sub-query is not a
+-**        compound query. This restriction is because transforming the
++**  (**)  Subsumed into restriction (17d3).  Was: If the outer query is
++**        a recursive CTE, then the sub-query may not be a compound query.
++**        This restriction is because transforming the
+ **        parent to a compound query confuses the code that handles
+ **        recursive queries in multiSelect().
+ **
+-**  (24)  The subquery is not an aggregate that uses the built-in min() or 
++**  (**)  We no longer attempt to flatten aggregate subqueries.  Was:
++**        The subquery may not be an aggregate that uses the built-in min() or 
+ **        or max() functions.  (Without this restriction, a query like:
+ **        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
+ **        return the value X for which Y was maximal.)
+ **
++**  (25)  If either the subquery or the parent query contains a window
++**        function in the select list or ORDER BY clause, flattening
++**        is not attempted.
+ **
++**
+ ** In this routine, the "p" parameter is a pointer to the outer query.
+ ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
+-** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
++** uses aggregates.
+ **
+ ** If flattening is not attempted, this routine is a no-op and returns 0.
+ ** If flattening is attempted this routine returns 1.
+@@ -120853,8 +127589,7 @@
+   Parse *pParse,       /* Parsing context */
+   Select *p,           /* The parent or outer SELECT statement */
+   int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
+-  int isAgg,           /* True if outer SELECT uses aggregate functions */
+-  int subqueryIsAgg    /* True if the subquery uses aggregate functions */
++  int isAgg            /* True if outer SELECT uses aggregate functions */
+ ){
+   const char *zSavedAuthContext = pParse->zAuthContext;
+   Select *pParent;    /* Current UNION ALL term of the other query */
+@@ -120873,7 +127608,7 @@
+   /* Check to see if flattening is permitted.  Return 0 if not.
+   */
+   assert( p!=0 );
+-  assert( p->pPrior==0 );  /* Unable to flatten compound queries */
++  assert( p->pPrior==0 );
+   if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
+   pSrc = p->pSrc;
+   assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
+@@ -120881,17 +127616,11 @@
+   iParent = pSubitem->iCursor;
+   pSub = pSubitem->pSelect;
+   assert( pSub!=0 );
+-  if( subqueryIsAgg ){
+-    if( isAgg ) return 0;                                /* Restriction (1)   */
+-    if( pSrc->nSrc>1 ) return 0;                         /* Restriction (2a)  */
+-    if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
+-     || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
+-     || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
+-    ){
+-      return 0;                                          /* Restriction (2b)  */
+-    }
+-  }
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( p->pWin || pSub->pWin ) return 0;                  /* Restriction (25) */
++#endif
++
+   pSubSrc = pSub->pSrc;
+   assert( pSubSrc );
+   /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
+@@ -120900,18 +127629,15 @@
+   ** became arbitrary expressions, we were forced to add restrictions (13)
+   ** and (14). */
+   if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
+-  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
++  if( pSub->pLimit && pSub->pLimit->pRight ) return 0;   /* Restriction (14) */
+   if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
+     return 0;                                            /* Restriction (15) */
+   }
+   if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
+-  if( pSub->selFlags & SF_Distinct ) return 0;           /* Restriction (5)  */
++  if( pSub->selFlags & SF_Distinct ) return 0;           /* Restriction (4)  */
+   if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
+      return 0;         /* Restrictions (8)(9) */
+   }
+-  if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
+-     return 0;         /* Restriction (6)  */
+-  }
+   if( p->pOrderBy && pSub->pOrderBy ){
+      return 0;                                           /* Restriction (11) */
+   }
+@@ -120920,18 +127646,14 @@
+   if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
+      return 0;         /* Restriction (21) */
+   }
+-  testcase( pSub->selFlags & SF_Recursive );
+-  testcase( pSub->selFlags & SF_MinMaxAgg );
+-  if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
+-    return 0; /* Restrictions (22) and (24) */
++  if( pSub->selFlags & (SF_Recursive) ){
++    return 0; /* Restrictions (22) */
+   }
+-  if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
+-    return 0; /* Restriction (23) */
+-  }
+ 
+   /*
+   ** If the subquery is the right operand of a LEFT JOIN, then the
+-  ** subquery may not be a join itself.  Example of why this is not allowed:
++  ** subquery may not be a join itself (3a). Example of why this is not
++  ** allowed:
+   **
+   **         t1 LEFT OUTER JOIN (t2 JOIN t3)
+   **
+@@ -120942,9 +127664,9 @@
+   ** which is not at all the same thing.
+   **
+   ** If the subquery is the right operand of a LEFT JOIN, then the outer
+-  ** query cannot be an aggregate.  This is an artifact of the way aggregates
+-  ** are processed - there is no mechanism to determine if the LEFT JOIN
+-  ** table should be all-NULL.
++  ** query cannot be an aggregate. (3c)  This is an artifact of the way
++  ** aggregates are processed - there is no mechanism to determine if
++  ** the LEFT JOIN table should be all-NULL.
+   **
+   ** See also tickets #306, #350, and #3300.
+   */
+@@ -120951,19 +127673,21 @@
+   if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
+     isLeftJoin = 1;
+     if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
+-      return 0; /* Restriction (3) */
++      /*  (3a)             (3c)     (3b) */
++      return 0;
+     }
+   }
+ #ifdef SQLITE_EXTRA_IFNULLROW
+   else if( iFrom>0 && !isAgg ){
+     /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
+-    ** every reference to any result column from subquery in a join, even though
+-    ** they are not necessary.  This will stress-test the OP_IfNullRow opcode. */
++    ** every reference to any result column from subquery in a join, even
++    ** though they are not necessary.  This will stress-test the OP_IfNullRow 
++    ** opcode. */
+     isLeftJoin = -1;
+   }
+ #endif
+ 
+-  /* Restriction 17: If the sub-query is a compound SELECT, then it must
++  /* Restriction (17): If the sub-query is a compound SELECT, then it must
+   ** use only the UNION ALL operator. And none of the simple select queries
+   ** that make up the compound SELECT are allowed to be aggregate or distinct
+   ** queries.
+@@ -120970,10 +127694,10 @@
+   */
+   if( pSub->pPrior ){
+     if( pSub->pOrderBy ){
+-      return 0;  /* Restriction 20 */
++      return 0;  /* Restriction (20) */
+     }
+     if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
+-      return 0;
++      return 0; /* (17d1), (17d2), or (17d3) */
+     }
+     for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
+       testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+@@ -120980,9 +127704,9 @@
+       testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
+       assert( pSub->pSrc!=0 );
+       assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
+-      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
+-       || (pSub1->pPrior && pSub1->op!=TK_ALL) 
+-       || pSub1->pSrc->nSrc<1
++      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0    /* (17b) */
++       || (pSub1->pPrior && pSub1->op!=TK_ALL)                 /* (17a) */
++       || pSub1->pSrc->nSrc<1                                  /* (17c) */
+       ){
+         return 0;
+       }
+@@ -120989,7 +127713,7 @@
+       testcase( pSub1->pSrc->nSrc>1 );
+     }
+ 
+-    /* Restriction 18. */
++    /* Restriction (18). */
+     if( p->pOrderBy ){
+       int ii;
+       for(ii=0; ii<p->pOrderBy->nExpr; ii++){
+@@ -120998,9 +127722,17 @@
+     }
+   }
+ 
++  /* Ex-restriction (23):
++  ** The only way that the recursive part of a CTE can contain a compound
++  ** subquery is for the subquery to be one term of a join.  But if the
++  ** subquery is a join, then the flattening has already been stopped by
++  ** restriction (17d3)
++  */
++  assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );
++
+   /***** If we reach this point, flattening is permitted. *****/
+-  SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
+-                   pSub->zSelName, pSub, iFrom));
++  SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
++                   pSub->selId, pSub, iFrom));
+ 
+   /* Authorize the subquery */
+   pParse->zAuthContext = pSubitem->zName;
+@@ -121045,16 +127777,12 @@
+     Select *pNew;
+     ExprList *pOrderBy = p->pOrderBy;
+     Expr *pLimit = p->pLimit;
+-    Expr *pOffset = p->pOffset;
+     Select *pPrior = p->pPrior;
+     p->pOrderBy = 0;
+     p->pSrc = 0;
+     p->pPrior = 0;
+     p->pLimit = 0;
+-    p->pOffset = 0;
+     pNew = sqlite3SelectDup(db, p, 0);
+-    sqlite3SelectSetName(pNew, pSub->zSelName);
+-    p->pOffset = pOffset;
+     p->pLimit = pLimit;
+     p->pOrderBy = pOrderBy;
+     p->pSrc = pSrc;
+@@ -121066,9 +127794,8 @@
+       if( pPrior ) pPrior->pNext = pNew;
+       pNew->pNext = p;
+       p->pPrior = pNew;
+-      SELECTTRACE(2,pParse,p,
+-         ("compound-subquery flattener creates %s.%p as peer\n",
+-         pNew->zSelName, pNew));
++      SELECTTRACE(2,pParse,p,("compound-subquery flattener"
++                              " creates %u as peer\n",pNew->selId));
+     }
+     if( db->mallocFailed ) return 1;
+   }
+@@ -121202,7 +127929,6 @@
+         pOrderBy->a[i].u.x.iOrderByCol = 0;
+       }
+       assert( pParent->pOrderBy==0 );
+-      assert( pSub->pPrior==0 );
+       pParent->pOrderBy = pOrderBy;
+       pSub->pOrderBy = 0;
+     }
+@@ -121210,18 +127936,7 @@
+     if( isLeftJoin>0 ){
+       setJoinExpr(pWhere, iNewParent);
+     }
+-    if( subqueryIsAgg ){
+-      assert( pParent->pHaving==0 );
+-      pParent->pHaving = pParent->pWhere;
+-      pParent->pWhere = pWhere;
+-      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);
+-    }
++    pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+     if( db->mallocFailed==0 ){
+       SubstContext x;
+       x.pParse = pParse;
+@@ -121265,8 +127980,184 @@
+ }
+ #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+ 
++/*
++** A structure to keep track of all of the column values that are fixed to
++** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
++*/
++typedef struct WhereConst WhereConst;
++struct WhereConst {
++  Parse *pParse;   /* Parsing context */
++  int nConst;      /* Number for COLUMN=CONSTANT terms */
++  int nChng;       /* Number of times a constant is propagated */
++  Expr **apExpr;   /* [i*2] is COLUMN and [i*2+1] is VALUE */
++};
+ 
++/*
++** Add a new entry to the pConst object.  Except, do not add duplicate
++** pColumn entires.
++*/
++static void constInsert(
++  WhereConst *pConst,      /* The WhereConst into which we are inserting */
++  Expr *pColumn,           /* The COLUMN part of the constraint */
++  Expr *pValue             /* The VALUE part of the constraint */
++){
++  int i;
++  assert( pColumn->op==TK_COLUMN );
+ 
++  /* 2018-10-25 ticket [cf5ed20f]
++  ** Make sure the same pColumn is not inserted more than once */
++  for(i=0; i<pConst->nConst; i++){
++    const Expr *pExpr = pConst->apExpr[i*2];
++    assert( pExpr->op==TK_COLUMN );
++    if( pExpr->iTable==pColumn->iTable
++     && pExpr->iColumn==pColumn->iColumn
++    ){
++      return;  /* Already present.  Return without doing anything. */
++    }
++  }
++
++  pConst->nConst++;
++  pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
++                         pConst->nConst*2*sizeof(Expr*));
++  if( pConst->apExpr==0 ){
++    pConst->nConst = 0;
++  }else{
++    if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft;
++    pConst->apExpr[pConst->nConst*2-2] = pColumn;
++    pConst->apExpr[pConst->nConst*2-1] = pValue;
++  }
++}
++
++/*
++** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE
++** is a constant expression and where the term must be true because it
++** is part of the AND-connected terms of the expression.  For each term
++** found, add it to the pConst structure.
++*/
++static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
++  Expr *pRight, *pLeft;
++  if( pExpr==0 ) return;
++  if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
++  if( pExpr->op==TK_AND ){
++    findConstInWhere(pConst, pExpr->pRight);
++    findConstInWhere(pConst, pExpr->pLeft);
++    return;
++  }
++  if( pExpr->op!=TK_EQ ) return;
++  pRight = pExpr->pRight;
++  pLeft = pExpr->pLeft;
++  assert( pRight!=0 );
++  assert( pLeft!=0 );
++  if( pRight->op==TK_COLUMN
++   && !ExprHasProperty(pRight, EP_FixedCol)
++   && sqlite3ExprIsConstant(pLeft)
++   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
++  ){
++    constInsert(pConst, pRight, pLeft);
++  }else
++  if( pLeft->op==TK_COLUMN
++   && !ExprHasProperty(pLeft, EP_FixedCol)
++   && sqlite3ExprIsConstant(pRight)
++   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
++  ){
++    constInsert(pConst, pLeft, pRight);
++  }
++}
++
++/*
++** This is a Walker expression callback.  pExpr is a candidate expression
++** to be replaced by a value.  If pExpr is equivalent to one of the
++** columns named in pWalker->u.pConst, then overwrite it with its
++** corresponding value.
++*/
++static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
++  int i;
++  WhereConst *pConst;
++  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
++  if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue;
++  pConst = pWalker->u.pConst;
++  for(i=0; i<pConst->nConst; i++){
++    Expr *pColumn = pConst->apExpr[i*2];
++    if( pColumn==pExpr ) continue;
++    if( pColumn->iTable!=pExpr->iTable ) continue;
++    if( pColumn->iColumn!=pExpr->iColumn ) continue;
++    /* A match is found.  Add the EP_FixedCol property */
++    pConst->nChng++;
++    ExprClearProperty(pExpr, EP_Leaf);
++    ExprSetProperty(pExpr, EP_FixedCol);
++    assert( pExpr->pLeft==0 );
++    pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0);
++    break;
++  }
++  return WRC_Prune;
++}
++
++/*
++** The WHERE-clause constant propagation optimization.
++**
++** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
++** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level
++** AND-connected terms that are not part of a ON clause from a LEFT JOIN)
++** then throughout the query replace all other occurrences of COLUMN
++** with CONSTANT within the WHERE clause.
++**
++** For example, the query:
++**
++**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b
++**
++** Is transformed into
++**
++**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39
++**
++** Return true if any transformations where made and false if not.
++**
++** Implementation note:  Constant propagation is tricky due to affinity
++** and collating sequence interactions.  Consider this example:
++**
++**    CREATE TABLE t1(a INT,b TEXT);
++**    INSERT INTO t1 VALUES(123,'0123');
++**    SELECT * FROM t1 WHERE a=123 AND b=a;
++**    SELECT * FROM t1 WHERE a=123 AND b=123;
++**
++** The two SELECT statements above should return different answers.  b=a
++** is alway true because the comparison uses numeric affinity, but b=123
++** is false because it uses text affinity and '0123' is not the same as '123'.
++** To work around this, the expression tree is not actually changed from
++** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol
++** and the "123" value is hung off of the pLeft pointer.  Code generator
++** routines know to generate the constant "123" instead of looking up the
++** column value.  Also, to avoid collation problems, this optimization is
++** only attempted if the "a=123" term uses the default BINARY collation.
++*/
++static int propagateConstants(
++  Parse *pParse,   /* The parsing context */
++  Select *p        /* The query in which to propagate constants */
++){
++  WhereConst x;
++  Walker w;
++  int nChng = 0;
++  x.pParse = pParse;
++  do{
++    x.nConst = 0;
++    x.nChng = 0;
++    x.apExpr = 0;
++    findConstInWhere(&x, p->pWhere);
++    if( x.nConst ){
++      memset(&w, 0, sizeof(w));
++      w.pParse = pParse;
++      w.xExprCallback = propagateConstantExprRewrite;
++      w.xSelectCallback = sqlite3SelectWalkNoop;
++      w.xSelectCallback2 = 0;
++      w.walkerDepth = 0;
++      w.u.pConst = &x;
++      sqlite3WalkExpr(&w, p->pWhere);
++      sqlite3DbFree(x.pParse->db, x.apExpr);
++      nChng += x.nChng;
++    }
++  }while( x.nChng );  
++  return nChng;
++}
++
+ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ /*
+ ** Make copies of relevant WHERE clause terms of the outer query into
+@@ -121284,22 +128175,40 @@
+ **
+ ** Do not attempt this optimization if:
+ **
+-**   (1) The inner query is an aggregate.  (In that case, we'd really want
+-**       to copy the outer WHERE-clause terms onto the HAVING clause of the
+-**       inner query.  But they probably won't help there so do not bother.)
++**   (1) (** This restriction was removed on 2017-09-29.  We used to
++**           disallow this optimization for aggregate subqueries, but now
++**           it is allowed by putting the extra terms on the HAVING clause.
++**           The added HAVING clause is pointless if the subquery lacks
++**           a GROUP BY clause.  But such a HAVING clause is also harmless
++**           so there does not appear to be any reason to add extra logic
++**           to suppress it. **)
+ **
+ **   (2) The inner query is the recursive part of a common table expression.
+ **
+ **   (3) The inner query has a LIMIT clause (since the changes to the WHERE
+-**       close would change the meaning of the LIMIT).
++**       clause would change the meaning of the LIMIT).
+ **
+-**   (4) The inner query is the right operand of a LEFT JOIN.  (The caller
+-**       enforces this restriction since this routine does not have enough
+-**       information to know.)
++**   (4) The inner query is the right operand of a LEFT JOIN and the
++**       expression to be pushed down does not come from the ON clause
++**       on that LEFT JOIN.
+ **
+ **   (5) The WHERE clause expression originates in the ON or USING clause
+-**       of a LEFT JOIN.
++**       of a LEFT JOIN where iCursor is not the right-hand table of that
++**       left join.  An example:
+ **
++**           SELECT *
++**           FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa
++**           JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
++**           LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
++**
++**       The correct answer is three rows:  (1,1,NULL),(2,2,8),(2,2,9).
++**       But if the (b2=2) term were to be pushed down into the bb subquery,
++**       then the (1,1,NULL) row would be suppressed.
++**
++**   (6) The inner query features one or more window-functions (since 
++**       changes to the WHERE clause of the inner query could change the 
++**       window over which window functions are calculated).
++**
+ ** Return 0 if no changes are made and non-zero if one or more WHERE clause
+ ** terms are duplicated into the subquery.
+ */
+@@ -121307,33 +128216,54 @@
+   Parse *pParse,        /* Parse context (for malloc() and error reporting) */
+   Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
+   Expr *pWhere,         /* The WHERE clause of the outer query */
+-  int iCursor           /* Cursor number of the subquery */
++  int iCursor,          /* Cursor number of the subquery */
++  int isLeftJoin        /* True if pSubq is the right term of a LEFT JOIN */
+ ){
+   Expr *pNew;
+   int nChng = 0;
+-  Select *pX;           /* For looping over compound SELECTs in pSubq */
+   if( pWhere==0 ) return 0;
+-  for(pX=pSubq; pX; pX=pX->pPrior){
+-    if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
+-      testcase( pX->selFlags & SF_Aggregate );
+-      testcase( pX->selFlags & SF_Recursive );
+-      testcase( pX!=pSubq );
+-      return 0; /* restrictions (1) and (2) */
++  if( pSubq->selFlags & SF_Recursive ) return 0;  /* restriction (2) */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pSubq->pWin ) return 0;    /* restriction (6) */
++#endif
++
++#ifdef SQLITE_DEBUG
++  /* Only the first term of a compound can have a WITH clause.  But make
++  ** sure no other terms are marked SF_Recursive in case something changes
++  ** in the future.
++  */
++  {
++    Select *pX;  
++    for(pX=pSubq; pX; pX=pX->pPrior){
++      assert( (pX->selFlags & (SF_Recursive))==0 );
+     }
+   }
++#endif
++
+   if( pSubq->pLimit!=0 ){
+     return 0; /* restriction (3) */
+   }
+   while( pWhere->op==TK_AND ){
+-    nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
++    nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight,
++                                iCursor, isLeftJoin);
+     pWhere = pWhere->pLeft;
+   }
+-  if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
++  if( isLeftJoin
++   && (ExprHasProperty(pWhere,EP_FromJoin)==0
++         || pWhere->iRightJoinTable!=iCursor)
++  ){
++    return 0; /* restriction (4) */
++  }
++  if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
++    return 0; /* restriction (5) */
++  }
+   if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
+     nChng++;
+     while( pSubq ){
+       SubstContext x;
+       pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
++      unsetJoinExpr(pNew, -1);
+       x.pParse = pParse;
+       x.iTable = iCursor;
+       x.iNewTable = iCursor;
+@@ -121340,7 +128270,11 @@
+       x.isLeftJoin = 0;
+       x.pEList = pSubq->pEList;
+       pNew = substExpr(&x, pNew);
+-      pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
++      if( pSubq->selFlags & SF_Aggregate ){
++        pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
++      }else{
++        pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
++      }
+       pSubq = pSubq->pPrior;
+     }
+   }
+@@ -121349,42 +128283,44 @@
+ #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+ 
+ /*
+-** Based on the contents of the AggInfo structure indicated by the first
+-** argument, this function checks if the following are true:
++** The pFunc is the only aggregate function in the query.  Check to see
++** if the query is a candidate for the min/max optimization. 
+ **
+-**    * the query contains just a single aggregate function,
+-**    * the aggregate function is either min() or max(), and
+-**    * the argument to the aggregate function is a column value.
++** If the query is a candidate for the min/max optimization, then set
++** *ppMinMax to be an ORDER BY clause to be used for the optimization
++** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
++** whether pFunc is a min() or max() function.
+ **
+-** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
+-** is returned as appropriate. Also, *ppMinMax is set to point to the 
+-** list of arguments passed to the aggregate before returning.
++** If the query is not a candidate for the min/max optimization, return
++** WHERE_ORDERBY_NORMAL (which must be zero).
+ **
+-** Or, if the conditions above are not met, *ppMinMax is set to 0 and
+-** WHERE_ORDERBY_NORMAL is returned.
++** This routine must be called after aggregate functions have been
++** located but before their arguments have been subjected to aggregate
++** analysis.
+ */
+-static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
+-  int eRet = WHERE_ORDERBY_NORMAL;          /* Return value */
++static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
++  int eRet = WHERE_ORDERBY_NORMAL;      /* Return value */
++  ExprList *pEList = pFunc->x.pList;    /* Arguments to agg function */
++  const char *zFunc;                    /* Name of aggregate function pFunc */
++  ExprList *pOrderBy;
++  u8 sortOrder;
+ 
+-  *ppMinMax = 0;
+-  if( pAggInfo->nFunc==1 ){
+-    Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
+-    ExprList *pEList = pExpr->x.pList;      /* Arguments to agg function */
+-
+-    assert( pExpr->op==TK_AGG_FUNCTION );
+-    if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
+-      const char *zFunc = pExpr->u.zToken;
+-      if( sqlite3StrICmp(zFunc, "min")==0 ){
+-        eRet = WHERE_ORDERBY_MIN;
+-        *ppMinMax = pEList;
+-      }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+-        eRet = WHERE_ORDERBY_MAX;
+-        *ppMinMax = pEList;
+-      }
+-    }
++  assert( *ppMinMax==0 );
++  assert( pFunc->op==TK_AGG_FUNCTION );
++  if( pEList==0 || pEList->nExpr!=1 ) return eRet;
++  zFunc = pFunc->u.zToken;
++  if( sqlite3StrICmp(zFunc, "min")==0 ){
++    eRet = WHERE_ORDERBY_MIN;
++    sortOrder = SQLITE_SO_ASC;
++  }else if( sqlite3StrICmp(zFunc, "max")==0 ){
++    eRet = WHERE_ORDERBY_MAX;
++    sortOrder = SQLITE_SO_DESC;
++  }else{
++    return eRet;
+   }
+-
+-  assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
++  *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
++  assert( pOrderBy!=0 || db->mallocFailed );
++  if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
+   return eRet;
+ }
+ 
+@@ -121515,7 +128451,6 @@
+   assert( pNew->pPrior!=0 );
+   pNew->pPrior->pNext = pNew;
+   pNew->pLimit = 0;
+-  pNew->pOffset = 0;
+   return WRC_Continue;
+ }
+ 
+@@ -121668,7 +128603,8 @@
+       );
+       return SQLITE_ERROR;
+     }
+-    assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
++    assert( pTab->nTabRef==1 || 
++            ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
+ 
+     pCte->zCteErr = "circular reference: %s";
+     pSavedWith = pParse->pWith;
+@@ -121725,7 +128661,7 @@
+ */
+ static void selectPopWith(Walker *pWalker, Select *p){
+   Parse *pParse = pWalker->pParse;
+-  if( pParse->pWith && p->pPrior==0 ){
++  if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
+     With *pWith = findRightmost(p)->pWith;
+     if( pWith!=0 ){
+       assert( pParse->pWith==pWith );
+@@ -121738,6 +128674,35 @@
+ #endif
+ 
+ /*
++** The SrcList_item structure passed as the second argument represents a
++** sub-query in the FROM clause of a SELECT statement. This function
++** allocates and populates the SrcList_item.pTab object. If successful,
++** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
++** SQLITE_NOMEM.
++*/
++SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
++  Select *pSel = pFrom->pSelect;
++  Table *pTab;
++
++  assert( pSel );
++  pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
++  if( pTab==0 ) return SQLITE_NOMEM;
++  pTab->nTabRef = 1;
++  if( pFrom->zAlias ){
++    pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
++  }else{
++    pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId);
++  }
++  while( pSel->pPrior ){ pSel = pSel->pPrior; }
++  sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
++  pTab->iPKey = -1;
++  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
++  pTab->tabFlags |= TF_Ephemeral;
++
++  return SQLITE_OK;
++}
++
++/*
+ ** This routine is a Walker callback for "expanding" a SELECT statement.
+ ** "Expanding" means to do the following:
+ **
+@@ -121770,19 +128735,19 @@
+   sqlite3 *db = pParse->db;
+   Expr *pE, *pRight, *pExpr;
+   u16 selFlags = p->selFlags;
++  u32 elistFlags = 0;
+ 
+   p->selFlags |= SF_Expanded;
+   if( db->mallocFailed  ){
+     return WRC_Abort;
+   }
+-  if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
++  assert( p->pSrc!=0 );
++  if( (selFlags & SF_Expanded)!=0 ){
+     return WRC_Prune;
+   }
+   pTabList = p->pSrc;
+   pEList = p->pEList;
+-  if( p->pWith ){
+-    sqlite3WithPush(pParse, p->pWith, 0);
+-  }
++  sqlite3WithPush(pParse, p->pWith, 0);
+ 
+   /* Make sure cursor numbers have been assigned to all entries in
+   ** the FROM clause of the SELECT statement.
+@@ -121809,15 +128774,7 @@
+       assert( pSel!=0 );
+       assert( pFrom->pTab==0 );
+       if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
+-      pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+-      if( pTab==0 ) return WRC_Abort;
+-      pTab->nTabRef = 1;
+-      pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
+-      while( pSel->pPrior ){ pSel = pSel->pPrior; }
+-      sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
+-      pTab->iPKey = -1;
+-      pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+-      pTab->tabFlags |= TF_Ephemeral;
++      if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
+ #endif
+     }else{
+       /* An ordinary table or view name in the FROM clause */
+@@ -121840,7 +128797,6 @@
+         if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
+         assert( pFrom->pSelect==0 );
+         pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+-        sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
+         nCol = pTab->nCol;
+         pTab->nCol = -1;
+         sqlite3WalkSelect(pWalker, pFrom->pSelect);
+@@ -121878,6 +128834,7 @@
+     assert( pE->op!=TK_DOT || pE->pRight!=0 );
+     assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
+     if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
++    elistFlags |= pE->flags;
+   }
+   if( k<pEList->nExpr ){
+     /*
+@@ -121893,6 +128850,7 @@
+ 
+     for(k=0; k<pEList->nExpr; k++){
+       pE = a[k].pExpr;
++      elistFlags |= pE->flags;
+       pRight = pE->pRight;
+       assert( pE->op!=TK_DOT || pRight!=0 );
+       if( pE->op!=TK_ASTERISK
+@@ -122022,12 +128980,15 @@
+     sqlite3ExprListDelete(db, pEList);
+     p->pEList = pNew;
+   }
+-#if SQLITE_MAX_COLUMN
+-  if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+-    sqlite3ErrorMsg(pParse, "too many columns in result set");
+-    return WRC_Abort;
++  if( p->pEList ){
++    if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
++      sqlite3ErrorMsg(pParse, "too many columns in result set");
++      return WRC_Abort;
++    }
++    if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
++      p->selFlags |= SF_ComplexResult;
++    }
+   }
+-#endif
+   return WRC_Continue;
+ }
+ 
+@@ -122081,7 +129042,7 @@
+   Walker w;
+   w.xExprCallback = sqlite3ExprWalkNoop;
+   w.pParse = pParse;
+-  if( pParse->hasCompound ){
++  if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){
+     w.xSelectCallback = convertCompoundSelectToSubquery;
+     w.xSelectCallback2 = 0;
+     sqlite3WalkSelect(&w, pSelect);
+@@ -122113,7 +129074,7 @@
+   struct SrcList_item *pFrom;
+ 
+   assert( p->selFlags & SF_Resolved );
+-  assert( (p->selFlags & SF_HasTypeInfo)==0 );
++  if( p->selFlags & SF_HasTypeInfo ) return;
+   p->selFlags |= SF_HasTypeInfo;
+   pParse = pWalker->pParse;
+   pTabList = p->pSrc;
+@@ -122169,15 +129130,13 @@
+   Select *p,             /* The SELECT statement being coded. */
+   NameContext *pOuterNC  /* Name context for container */
+ ){
+-  sqlite3 *db;
+-  if( NEVER(p==0) ) return;
+-  db = pParse->db;
+-  if( db->mallocFailed ) return;
++  assert( p!=0 || pParse->db->mallocFailed );
++  if( pParse->db->mallocFailed ) return;
+   if( p->selFlags & SF_HasTypeInfo ) return;
+   sqlite3SelectExpand(pParse, p);
+-  if( pParse->nErr || db->mallocFailed ) return;
++  if( pParse->nErr || pParse->db->mallocFailed ) return;
+   sqlite3ResolveSelectNames(pParse, p, pOuterNC);
+-  if( pParse->nErr || db->mallocFailed ) return;
++  if( pParse->nErr || pParse->db->mallocFailed ) return;
+   sqlite3SelectAddTypeInfo(pParse, p);
+ }
+ 
+@@ -122218,7 +129177,7 @@
+            "argument");
+         pFunc->iDistinct = -1;
+       }else{
+-        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
++        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
+         sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
+                           (char*)pKeyInfo, P4_KEYINFO);
+       }
+@@ -122242,11 +129201,17 @@
+   }
+ }
+ 
++
+ /*
+ ** Update the accumulator memory cells for an aggregate based on
+ ** the current cursor position.
++**
++** If regAcc is non-zero and there are no min() or max() aggregates
++** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator
++** registers i register regAcc contains 0. The caller will take care
++** of setting and clearing regAcc.
+ */
+-static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
++static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
+   Vdbe *v = pParse->pVdbe;
+   int i;
+   int regHit = 0;
+@@ -122289,36 +129254,24 @@
+       if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+       sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
+     }
+-    sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
++    sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
+     sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+     sqlite3VdbeChangeP5(v, (u8)nArg);
+-    sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
+     sqlite3ReleaseTempRange(pParse, regAgg, nArg);
+     if( addrNext ){
+       sqlite3VdbeResolveLabel(v, addrNext);
+-      sqlite3ExprCacheClear(pParse);
+     }
+   }
+-
+-  /* Before populating the accumulator registers, clear the column cache.
+-  ** Otherwise, if any of the required column values are already present 
+-  ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
+-  ** to pC->iMem. But by the time the value is used, the original register
+-  ** may have been used, invalidating the underlying buffer holding the
+-  ** text or blob value. See ticket [883034dcb5].
+-  **
+-  ** Another solution would be to change the OP_SCopy used to copy cached
+-  ** values to an OP_Copy.
+-  */
++  if( regHit==0 && pAggInfo->nAccumulator ){
++    regHit = regAcc;
++  }
+   if( regHit ){
+     addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
+   }
+-  sqlite3ExprCacheClear(pParse);
+   for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
+     sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
+   }
+   pAggInfo->directMode = 0;
+-  sqlite3ExprCacheClear(pParse);
+   if( addrHitTest ){
+     sqlite3VdbeJumpHere(v, addrHitTest);
+   }
+@@ -122336,14 +129289,11 @@
+ ){
+   if( pParse->explain==2 ){
+     int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
+-    char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
++    sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
+         pTab->zName,
+         bCover ? " USING COVERING INDEX " : "",
+         bCover ? pIdx->zName : ""
+     );
+-    sqlite3VdbeAddOp4(
+-        pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
+-    );
+   }
+ }
+ #else
+@@ -122351,14 +129301,6 @@
+ #endif
+ 
+ /*
+-** Context object for havingToWhereExprCb().
+-*/
+-struct HavingToWhereCtx {
+-  Expr **ppWhere;
+-  ExprList *pGroupBy;
+-};
+-
+-/*
+ ** sqlite3WalkExpr() callback used by havingToWhere().
+ **
+ ** If the node passed to the callback is a TK_AND node, return 
+@@ -122371,15 +129313,16 @@
+ */
+ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
+   if( pExpr->op!=TK_AND ){
+-    struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
+-    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
++    Select *pS = pWalker->u.pSelect;
++    if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
+       sqlite3 *db = pWalker->pParse->db;
+       Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
+       if( pNew ){
+-        Expr *pWhere = *(p->ppWhere);
++        Expr *pWhere = pS->pWhere;
+         SWAP(Expr, *pNew, *pExpr);
+         pNew = sqlite3ExprAnd(db, pWhere, pNew);
+-        *(p->ppWhere) = pNew;
++        pS->pWhere = pNew;
++        pWalker->eCode = 1;
+       }
+     }
+     return WRC_Prune;
+@@ -122402,23 +129345,19 @@
+ ** entirely of constants and expressions that are also GROUP BY terms that
+ ** use the "BINARY" collation sequence.
+ */
+-static void havingToWhere(
+-  Parse *pParse,
+-  ExprList *pGroupBy,
+-  Expr *pHaving, 
+-  Expr **ppWhere
+-){
+-  struct HavingToWhereCtx sCtx;
++static void havingToWhere(Parse *pParse, Select *p){
+   Walker sWalker;
+-
+-  sCtx.ppWhere = ppWhere;
+-  sCtx.pGroupBy = pGroupBy;
+-
+   memset(&sWalker, 0, sizeof(sWalker));
+   sWalker.pParse = pParse;
+   sWalker.xExprCallback = havingToWhereExprCb;
+-  sWalker.u.pHavingCtx = &sCtx;
+-  sqlite3WalkExpr(&sWalker, pHaving);
++  sWalker.u.pSelect = p;
++  sqlite3WalkExpr(&sWalker, p->pHaving);
++#if SELECTTRACE_ENABLED
++  if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
++    SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
++    sqlite3TreeViewSelect(0, p, 0);
++  }
++#endif
+ }
+ 
+ /*
+@@ -122462,6 +129401,7 @@
+ ** The transformation only works if all of the following are true:
+ **
+ **   *  The subquery is a UNION ALL of two or more terms
++**   *  The subquery does not have a LIMIT clause
+ **   *  There is no WHERE or GROUP BY or HAVING clauses on the subqueries
+ **   *  The outer query is a simple count(*)
+ **
+@@ -122472,24 +129412,25 @@
+   Expr *pExpr;
+   Expr *pCount;
+   sqlite3 *db;
+-  if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate query */
++  if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate */
+   if( p->pEList->nExpr!=1 ) return 0;               /* Single result column */
+   pExpr = p->pEList->a[0].pExpr;
+   if( pExpr->op!=TK_AGG_FUNCTION ) return 0;        /* Result is an aggregate */
+-  if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0;  /* Must be count() */
++  if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0;  /* Is count() */
+   if( pExpr->x.pList!=0 ) return 0;                 /* Must be count(*) */
+-  if( p->pSrc->nSrc!=1 ) return 0;                  /* One table in the FROM clause */
++  if( p->pSrc->nSrc!=1 ) return 0;                  /* One table in FROM  */
+   pSub = p->pSrc->a[0].pSelect;
+   if( pSub==0 ) return 0;                           /* The FROM is a subquery */
+-  if( pSub->pPrior==0 ) return 0;                   /* Must be a compound subquery */
++  if( pSub->pPrior==0 ) return 0;                   /* Must be a compound ry */
+   do{
+     if( pSub->op!=TK_ALL && pSub->pPrior ) return 0;  /* Must be UNION ALL */
+     if( pSub->pWhere ) return 0;                      /* No WHERE clause */
++    if( pSub->pLimit ) return 0;                      /* No LIMIT clause */
+     if( pSub->selFlags & SF_Aggregate ) return 0;     /* Not an aggregate */
+-    pSub = pSub->pPrior;                              /* Repeat over compound terms */
++    pSub = pSub->pPrior;                              /* Repeat over compound */
+   }while( pSub );
+ 
+-  /* If we reach this point, that means it is OK to perform the transformation */
++  /* If we reach this point then it is OK to perform the transformation */
+ 
+   db = pParse->db;
+   pCount = pExpr;
+@@ -122564,13 +129505,11 @@
+   AggInfo sAggInfo;      /* Information used by aggregate queries */
+   int iEnd;              /* Address of the end of the query */
+   sqlite3 *db;           /* The database connection */
++  ExprList *pMinMaxOrderBy = 0;  /* Added ORDER BY for min/max queries */
++  u8 minMaxFlag;                 /* Flag for min/max queries */
+ 
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iRestoreSelectId = pParse->iSelectId;
+-  pParse->iSelectId = pParse->iNextSelectId++;
+-#endif
+-
+   db = pParse->db;
++  v = sqlite3GetVdbe(pParse);
+   if( p==0 || db->mallocFailed || pParse->nErr ){
+     return 1;
+   }
+@@ -122577,8 +129516,7 @@
+   if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
+   memset(&sAggInfo, 0, sizeof(sAggInfo));
+ #if SELECTTRACE_ENABLED
+-  pParse->nSelectIndent++;
+-  SELECTTRACE(1,pParse,p, ("begin processing:\n"));
++  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
+   if( sqlite3SelectTrace & 0x100 ){
+     sqlite3TreeViewSelect(0, p, 0);
+   }
+@@ -122600,37 +129538,60 @@
+     p->selFlags &= ~SF_Distinct;
+   }
+   sqlite3SelectPrep(pParse, p, 0);
+-  memset(&sSort, 0, sizeof(sSort));
+-  sSort.pOrderBy = p->pOrderBy;
+-  pTabList = p->pSrc;
+   if( pParse->nErr || db->mallocFailed ){
+     goto select_end;
+   }
+   assert( p->pEList!=0 );
+-  isAgg = (p->selFlags & SF_Aggregate)!=0;
+ #if SELECTTRACE_ENABLED
+-  if( sqlite3SelectTrace & 0x100 ){
+-    SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
++  if( sqlite3SelectTrace & 0x104 ){
++    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
+     sqlite3TreeViewSelect(0, p, 0);
+   }
+ #endif
+ 
+-  /* Get a pointer the VDBE under construction, allocating a new VDBE if one
+-  ** does not already exist */
+-  v = sqlite3GetVdbe(pParse);
+-  if( v==0 ) goto select_end;
+   if( pDest->eDest==SRT_Output ){
+     generateColumnNames(pParse, p);
+   }
+ 
+-  /* Try to flatten subqueries in the FROM clause up into the main query
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( sqlite3WindowRewrite(pParse, p) ){
++    goto select_end;
++  }
++#if SELECTTRACE_ENABLED
++  if( sqlite3SelectTrace & 0x108 ){
++    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
++    sqlite3TreeViewSelect(0, p, 0);
++  }
++#endif
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++  pTabList = p->pSrc;
++  isAgg = (p->selFlags & SF_Aggregate)!=0;
++  memset(&sSort, 0, sizeof(sSort));
++  sSort.pOrderBy = p->pOrderBy;
++
++  /* Try to various optimizations (flattening subqueries, and strength
++  ** reduction of join operators) in the FROM clause up into the main query
+   */
+ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+   for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
+     struct SrcList_item *pItem = &pTabList->a[i];
+     Select *pSub = pItem->pSelect;
+-    int isAggSub;
+     Table *pTab = pItem->pTab;
++
++    /* Convert LEFT JOIN into JOIN if there are terms of the right table
++    ** of the LEFT JOIN used in the WHERE clause.
++    */
++    if( (pItem->fg.jointype & JT_LEFT)!=0
++     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
++     && OptimizationEnabled(db, SQLITE_SimplifyJoin)
++    ){
++      SELECTTRACE(0x100,pParse,p,
++                ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
++      pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
++      unsetJoinExpr(p->pWhere, pItem->iCursor);
++    }
++
++    /* No futher action if this term of the FROM clause is no a subquery */
+     if( pSub==0 ) continue;
+ 
+     /* Catch mismatch in the declared columns of a view and the number of
+@@ -122641,13 +129602,45 @@
+       goto select_end;
+     }
+ 
+-    isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
+-    if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
++    /* Do not try to flatten an aggregate subquery.
++    **
++    ** Flattening an aggregate subquery is only possible if the outer query
++    ** is not a join.  But if the outer query is not a join, then the subquery
++    ** will be implemented as a co-routine and there is no advantage to
++    ** flattening in that case.
++    */
++    if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
++    assert( pSub->pGroupBy==0 );
++
++    /* If the outer query contains a "complex" result set (that is,
++    ** if the result set of the outer query uses functions or subqueries)
++    ** and if the subquery contains an ORDER BY clause and if
++    ** it will be implemented as a co-routine, then do not flatten.  This
++    ** restriction allows SQL constructs like this:
++    **
++    **  SELECT expensive_function(x)
++    **    FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
++    **
++    ** The expensive_function() is only computed on the 10 rows that
++    ** are output, rather than every row of the table.
++    **
++    ** The requirement that the outer query have a complex result set
++    ** means that flattening does occur on simpler SQL constraints without
++    ** the expensive_function() like:
++    **
++    **  SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
++    */
++    if( pSub->pOrderBy!=0
++     && i==0
++     && (p->selFlags & SF_ComplexResult)!=0
++     && (pTabList->nSrc==1
++         || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
++    ){
++      continue;
++    }
++
++    if( flattenSubquery(pParse, p, i, isAgg) ){
+       /* This subquery can be absorbed into its parent. */
+-      if( isAggSub ){
+-        isAgg = 1;
+-        p->selFlags |= SF_Aggregate;
+-      }
+       i = -1;
+     }
+     pTabList = p->pSrc;
+@@ -122664,15 +129657,46 @@
+   */
+   if( p->pPrior ){
+     rc = multiSelect(pParse, p, pDest);
+-    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+ #if SELECTTRACE_ENABLED
+-    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
+-    pParse->nSelectIndent--;
++    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
++    if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
++      sqlite3TreeViewSelect(0, p, 0);
++    }
+ #endif
++    if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
+     return rc;
+   }
+ #endif
+ 
++  /* Do the WHERE-clause constant propagation optimization if this is
++  ** a join.  No need to speed time on this operation for non-join queries
++  ** as the equivalent optimization will be handled by query planner in
++  ** sqlite3WhereBegin().
++  */
++  if( pTabList->nSrc>1
++   && OptimizationEnabled(db, SQLITE_PropagateConst)
++   && propagateConstants(pParse, p)
++  ){
++#if SELECTTRACE_ENABLED
++    if( sqlite3SelectTrace & 0x100 ){
++      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
++      sqlite3TreeViewSelect(0, p, 0);
++    }
++#endif
++  }else{
++    SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
++  }
++
++#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
++  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
++   && countOfViewOptimization(pParse, p)
++  ){
++    if( db->mallocFailed ) goto select_end;
++    pEList = p->pEList;
++    pTabList = p->pSrc;
++  }
++#endif
++
+   /* For each term in the FROM clause, do two things:
+   ** (1) Authorized unreferenced tables
+   ** (2) Generate code for all sub-queries
+@@ -122681,10 +129705,14 @@
+     struct SrcList_item *pItem = &pTabList->a[i];
+     SelectDest dest;
+     Select *pSub;
++#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
++    const char *zSavedAuthContext;
++#endif
+ 
+-    /* Issue SQLITE_READ authorizations with a fake column name for any tables that
+-    ** are referenced but from which no values are extracted. Examples of where these
+-    ** kinds of null SQLITE_READ authorizations would occur:
++    /* Issue SQLITE_READ authorizations with a fake column name for any
++    ** tables that are referenced but from which no values are extracted.
++    ** Examples of where these kinds of null SQLITE_READ authorizations
++    ** would occur:
+     **
+     **     SELECT count(*) FROM t1;   -- SQLITE_READ t1.""
+     **     SELECT t1.* FROM t1, t2;   -- SQLITE_READ t2.""
+@@ -122692,10 +129720,10 @@
+     ** The fake column name is an empty string.  It is possible for a table to
+     ** have a column named by the empty string, in which case there is no way to
+     ** distinguish between an unreferenced table and an actual reference to the
+-    ** "" column.  The original design was for the fake column name to be a NULL,
++    ** "" column. The original design was for the fake column name to be a NULL,
+     ** which would be unambiguous.  But legacy authorization callbacks might
+-    ** assume the column name is non-NULL and segfault.  The use of an empty string
+-    ** for the fake column name seems safer.
++    ** assume the column name is non-NULL and segfault.  The use of an empty
++    ** string for the fake column name seems safer.
+     */
+     if( pItem->colUsed==0 ){
+       sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
+@@ -122736,27 +129764,29 @@
+     /* Make copies of constant WHERE-clause terms in the outer query down
+     ** inside the subquery.  This can help the subquery to run more efficiently.
+     */
+-    if( (pItem->fg.jointype & JT_OUTER)==0
+-     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
++    if( OptimizationEnabled(db, SQLITE_PushDown)
++     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
++                           (pItem->fg.jointype & JT_OUTER)!=0)
+     ){
+ #if SELECTTRACE_ENABLED
+       if( sqlite3SelectTrace & 0x100 ){
+-        SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
++        SELECTTRACE(0x100,pParse,p,
++            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
+         sqlite3TreeViewSelect(0, p, 0);
+       }
+ #endif
++    }else{
++      SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
+     }
+ 
++    zSavedAuthContext = pParse->zAuthContext;
++    pParse->zAuthContext = pItem->zName;
++
+     /* Generate code to implement the subquery
+     **
+-    ** The subquery is implemented as a co-routine if all of these are true:
+-    **   (1)  The subquery is guaranteed to be the outer loop (so that it
+-    **        does not need to be computed more than once)
+-    **   (2)  The ALL keyword after SELECT is omitted.  (Applications are
+-    **        allowed to say "SELECT ALL" instead of just "SELECT" to disable
+-    **        the use of co-routines.)
+-    **   (3)  Co-routines are not disabled using sqlite3_test_control()
+-    **        with SQLITE_TESTCTRL_OPTIMIZATIONS.
++    ** The subquery is implemented as a co-routine if the subquery is
++    ** guaranteed to be the outer loop (so that it does not need to be
++    ** computed more than once)
+     **
+     ** TODO: Are there other reasons beside (1) to use a co-routine
+     ** implementation?
+@@ -122764,19 +129794,18 @@
+     if( i==0
+      && (pTabList->nSrc==1
+             || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
+-     && (p->selFlags & SF_All)==0                                   /* (2) */
+-     && OptimizationEnabled(db, SQLITE_SubqCoroutine)               /* (3) */
+     ){
+       /* Implement a co-routine that will return a single row of the result
+       ** set on each invocation.
+       */
+       int addrTop = sqlite3VdbeCurrentAddr(v)+1;
++     
+       pItem->regReturn = ++pParse->nMem;
+       sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
+       VdbeComment((v, "%s", pItem->pTab->zName));
+       pItem->addrFillSub = addrTop;
+       sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+-      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
++      ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId));
+       sqlite3Select(pParse, pSub, &dest);
+       pItem->pTab->nRowLogEst = pSub->nSelectRow;
+       pItem->fg.viaCoroutine = 1;
+@@ -122811,12 +129840,11 @@
+       pPrior = isSelfJoinView(pTabList, pItem);
+       if( pPrior ){
+         sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
+-        explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
+         assert( pPrior->pSelect!=0 );
+         pSub->nSelectRow = pPrior->pSelect->nSelectRow;
+       }else{
+         sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+-        explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
++        ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId));
+         sqlite3Select(pParse, pSub, &dest);
+       }
+       pItem->pTab->nRowLogEst = pSub->nSelectRow;
+@@ -122828,6 +129856,7 @@
+     }
+     if( db->mallocFailed ) goto select_end;
+     pParse->nHeight -= sqlite3SelectExprHeight(p);
++    pParse->zAuthContext = zSavedAuthContext;
+ #endif
+   }
+ 
+@@ -122846,16 +129875,6 @@
+   }
+ #endif
+ 
+-#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
+-  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
+-   && countOfViewOptimization(pParse, p)
+-  ){
+-    if( db->mallocFailed ) goto select_end;
+-    pEList = p->pEList;
+-    pTabList = p->pSrc;
+-  }
+-#endif
+-
+   /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
+   ** if the select-list is the same as the ORDER BY list, then this query
+   ** can be rewritten as a GROUP BY. In other words, this:
+@@ -122899,7 +129918,8 @@
+   */
+   if( sSort.pOrderBy ){
+     KeyInfo *pKeyInfo;
+-    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
++    pKeyInfo = sqlite3KeyInfoFromExprList(
++        pParse, sSort.pOrderBy, 0, pEList->nExpr);
+     sSort.iECursor = pParse->nTab++;
+     sSort.addrSortIndex =
+       sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+@@ -122933,9 +129953,9 @@
+   if( p->selFlags & SF_Distinct ){
+     sDistinct.tabTnct = pParse->nTab++;
+     sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+-                             sDistinct.tabTnct, 0, 0,
+-                             (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
+-                             P4_KEYINFO);
++                       sDistinct.tabTnct, 0, 0,
++                       (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0),
++                       P4_KEYINFO);
+     sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+     sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
+   }else{
+@@ -122944,11 +129964,19 @@
+ 
+   if( !isAgg && pGroupBy==0 ){
+     /* No aggregate functions and no GROUP BY clause */
+-    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
++    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
++                   | (p->selFlags & SF_FixedLimit);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    Window *pWin = p->pWin;      /* Master window object (or NULL) */
++    if( pWin ){
++      sqlite3WindowCodeInit(pParse, pWin);
++    }
++#endif
+     assert( WHERE_USE_LIMIT==SF_FixedLimit );
+-    wctrlFlags |= p->selFlags & SF_FixedLimit;
+ 
++
+     /* Begin the database scan. */
++    SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
+                                p->pEList, wctrlFlags, p->nSelectRow);
+     if( pWInfo==0 ) goto select_end;
+@@ -122960,7 +129988,7 @@
+     }
+     if( sSort.pOrderBy ){
+       sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
+-      sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
++      sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
+       if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
+         sSort.pOrderBy = 0;
+       }
+@@ -122974,14 +130002,37 @@
+       sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
+     }
+ 
+-    /* Use the standard inner loop. */
+-    selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest,
+-                    sqlite3WhereContinueLabel(pWInfo),
+-                    sqlite3WhereBreakLabel(pWInfo));
++    assert( p->pEList==pEList );
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( pWin ){
++      int addrGosub = sqlite3VdbeMakeLabel(v);
++      int iCont = sqlite3VdbeMakeLabel(v);
++      int iBreak = sqlite3VdbeMakeLabel(v);
++      int regGosub = ++pParse->nMem;
+ 
+-    /* End the database scan loop.
+-    */
+-    sqlite3WhereEnd(pWInfo);
++      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
++
++      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
++      sqlite3VdbeResolveLabel(v, addrGosub);
++      VdbeNoopComment((v, "inner-loop subroutine"));
++      sSort.labelOBLopt = 0;
++      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak);
++      sqlite3VdbeResolveLabel(v, iCont);
++      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
++      VdbeComment((v, "end inner-loop subroutine"));
++      sqlite3VdbeResolveLabel(v, iBreak);
++    }else
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++    {
++      /* Use the standard inner loop. */
++      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
++          sqlite3WhereContinueLabel(pWInfo),
++          sqlite3WhereBreakLabel(pWInfo));
++
++      /* End the database scan loop.
++      */
++      sqlite3WhereEnd(pWInfo);
++    }
+   }else{
+     /* This case when there exist aggregate functions or a GROUP BY clause
+     ** or both */
+@@ -123040,7 +130091,8 @@
+     memset(&sNC, 0, sizeof(sNC));
+     sNC.pParse = pParse;
+     sNC.pSrcList = pTabList;
+-    sNC.pAggInfo = &sAggInfo;
++    sNC.uNC.pAggInfo = &sAggInfo;
++    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
+     sAggInfo.mnReg = pParse->nMem+1;
+     sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
+     sAggInfo.pGroupBy = pGroupBy;
+@@ -123049,12 +130101,19 @@
+     if( pHaving ){
+       if( pGroupBy ){
+         assert( pWhere==p->pWhere );
+-        havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
++        assert( pHaving==p->pHaving );
++        assert( pGroupBy==p->pGroupBy );
++        havingToWhere(pParse, p);
+         pWhere = p->pWhere;
+       }
+       sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
+     }
+     sAggInfo.nAccumulator = sAggInfo.nColumn;
++    if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){
++      minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy);
++    }else{
++      minMaxFlag = WHERE_ORDERBY_NORMAL;
++    }
+     for(i=0; i<sAggInfo.nFunc; i++){
+       assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
+       sNC.ncFlags |= NC_InAggFunc;
+@@ -123063,7 +130122,25 @@
+     }
+     sAggInfo.mxReg = pParse->nMem;
+     if( db->mallocFailed ) goto select_end;
++#if SELECTTRACE_ENABLED
++    if( sqlite3SelectTrace & 0x400 ){
++      int ii;
++      SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
++      sqlite3TreeViewSelect(0, p, 0);
++      for(ii=0; ii<sAggInfo.nColumn; ii++){
++        sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
++            ii, sAggInfo.aCol[ii].iMem);
++        sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
++      }
++      for(ii=0; ii<sAggInfo.nFunc; ii++){
++        sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
++            ii, sAggInfo.aFunc[ii].iMem);
++        sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0);
++      }
++    }
++#endif
+ 
++
+     /* Processing for aggregates with GROUP BY is very different and
+     ** much more complex than aggregates without a GROUP BY.
+     */
+@@ -123084,7 +130161,7 @@
+       ** will be converted into a Noop.  
+       */
+       sAggInfo.sortingIdx = pParse->nTab++;
+-      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
++      pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
+       addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
+           sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
+           0, (char*)pKeyInfo, P4_KEYINFO);
+@@ -123103,8 +130180,6 @@
+       pParse->nMem += pGroupBy->nExpr;
+       sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
+       VdbeComment((v, "clear abort flag"));
+-      sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
+-      VdbeComment((v, "indicate accumulator empty"));
+       sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
+ 
+       /* Begin a loop that will extract all source rows in GROUP BY order.
+@@ -123113,6 +130188,7 @@
+       ** in the right order to begin with.
+       */
+       sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
++      SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
+           WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
+       );
+@@ -123149,7 +130225,6 @@
+           }
+         }
+         regBase = sqlite3GetTempRange(pParse, nCol);
+-        sqlite3ExprCacheClear(pParse);
+         sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+         j = nGroupBy;
+         for(i=0; i<sAggInfo.nColumn; i++){
+@@ -123156,8 +130231,8 @@
+           struct AggInfo_col *pCol = &sAggInfo.aCol[i];
+           if( pCol->iSorterColumn>=j ){
+             int r1 = j + regBase;
+-            sqlite3ExprCodeGetColumnToReg(pParse, 
+-                               pCol->pTab, pCol->iColumn, pCol->iTable, r1);
++            sqlite3ExprCodeGetColumnOfTable(v,
++                               pCol->pTab, pCol->iTable, pCol->iColumn, r1);
+             j++;
+           }
+         }
+@@ -123173,8 +130248,6 @@
+         sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
+         VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
+         sAggInfo.useSortingIdx = 1;
+-        sqlite3ExprCacheClear(pParse);
+-
+       }
+ 
+       /* If the index or temporary table used by the GROUP BY sort
+@@ -123197,7 +130270,6 @@
+       ** from the previous row currently stored in a0, a1, a2...
+       */
+       addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
+-      sqlite3ExprCacheClear(pParse);
+       if( groupBySort ){
+         sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
+                           sortOut, sortPTab);
+@@ -123236,7 +130308,7 @@
+       ** the current row
+       */
+       sqlite3VdbeJumpHere(v, addr1);
+-      updateAccumulator(pParse, &sAggInfo);
++      updateAccumulator(pParse, iUseFlag, &sAggInfo);
+       sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
+       VdbeComment((v, "indicate data in accumulator"));
+ 
+@@ -123278,7 +130350,7 @@
+       sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+       finalizeAggFunctions(pParse, &sAggInfo);
+       sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
+-      selectInnerLoop(pParse, p, p->pEList, -1, &sSort,
++      selectInnerLoop(pParse, p, -1, &sSort,
+                       &sDistinct, pDest,
+                       addrOutputRow+1, addrSetAbort);
+       sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
+@@ -123288,11 +130360,12 @@
+       */
+       sqlite3VdbeResolveLabel(v, addrReset);
+       resetAccumulator(pParse, &sAggInfo);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
++      VdbeComment((v, "indicate accumulator empty"));
+       sqlite3VdbeAddOp1(v, OP_Return, regReset);
+      
+     } /* endif pGroupBy.  Begin aggregate queries without GROUP BY: */
+     else {
+-      ExprList *pDel = 0;
+ #ifndef SQLITE_OMIT_BTREECOUNT
+       Table *pTab;
+       if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
+@@ -123354,67 +130427,50 @@
+       }else
+ #endif /* SQLITE_OMIT_BTREECOUNT */
+       {
+-        /* Check if the query is of one of the following forms:
+-        **
+-        **   SELECT min(x) FROM ...
+-        **   SELECT max(x) FROM ...
+-        **
+-        ** If it is, then ask the code in where.c to attempt to sort results
+-        ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. 
+-        ** If where.c is able to produce results sorted in this order, then
+-        ** add vdbe code to break out of the processing loop after the 
+-        ** first iteration (since the first iteration of the loop is 
+-        ** guaranteed to operate on the row with the minimum or maximum 
+-        ** value of x, the only row required).
+-        **
+-        ** A special flag must be passed to sqlite3WhereBegin() to slightly
+-        ** modify behavior as follows:
+-        **
+-        **   + If the query is a "SELECT min(x)", then the loop coded by
+-        **     where.c should not iterate over any values with a NULL value
+-        **     for x.
+-        **
+-        **   + The optimizer code in where.c (the thing that decides which
+-        **     index or indices to use) should place a different priority on 
+-        **     satisfying the 'ORDER BY' clause than it does in other cases.
+-        **     Refer to code and comments in where.c for details.
+-        */
+-        ExprList *pMinMax = 0;
+-        u8 flag = WHERE_ORDERBY_NORMAL;
+-        
+-        assert( p->pGroupBy==0 );
+-        assert( flag==0 );
+-        if( p->pHaving==0 ){
+-          flag = minMaxQuery(&sAggInfo, &pMinMax);
+-        }
+-        assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
++        int regAcc = 0;           /* "populate accumulators" flag */
+ 
+-        if( flag ){
+-          pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
+-          pDel = pMinMax;
+-          assert( db->mallocFailed || pMinMax!=0 );
+-          if( !db->mallocFailed ){
+-            pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
+-            pMinMax->a[0].pExpr->op = TK_COLUMN;
++        /* If there are accumulator registers but no min() or max() functions,
++        ** allocate register regAcc. Register regAcc will contain 0 the first
++        ** time the inner loop runs, and 1 thereafter. The code generated
++        ** by updateAccumulator() only updates the accumulator registers if
++        ** regAcc contains 0.  */
++        if( sAggInfo.nAccumulator ){
++          for(i=0; i<sAggInfo.nFunc; i++){
++            if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
+           }
++          if( i==sAggInfo.nFunc ){
++            regAcc = ++pParse->nMem;
++            sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
++          }
+         }
+-  
++
+         /* This case runs if the aggregate has no GROUP BY clause.  The
+         ** processing is much simpler since there is only a single row
+         ** of output.
+         */
++        assert( p->pGroupBy==0 );
+         resetAccumulator(pParse, &sAggInfo);
+-        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
++
++        /* If this query is a candidate for the min/max optimization, then
++        ** minMaxFlag will have been previously set to either
++        ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
++        ** be an appropriate ORDER BY expression for the optimization.
++        */
++        assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
++        assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
++
++        SELECTTRACE(1,pParse,p,("WhereBegin\n"));
++        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
++                                   0, minMaxFlag, 0);
+         if( pWInfo==0 ){
+-          sqlite3ExprListDelete(db, pDel);
+           goto select_end;
+         }
+-        updateAccumulator(pParse, &sAggInfo);
+-        assert( pMinMax==0 || pMinMax->nExpr==1 );
++        updateAccumulator(pParse, regAcc, &sAggInfo);
++        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
+         if( sqlite3WhereIsOrdered(pWInfo)>0 ){
+           sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
+           VdbeComment((v, "%s() by index",
+-                (flag==WHERE_ORDERBY_MIN?"min":"max")));
++                (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max")));
+         }
+         sqlite3WhereEnd(pWInfo);
+         finalizeAggFunctions(pParse, &sAggInfo);
+@@ -123422,9 +130478,8 @@
+ 
+       sSort.pOrderBy = 0;
+       sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
+-      selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, 
++      selectInnerLoop(pParse, p, -1, 0, 0, 
+                       pDest, addrEnd, addrEnd);
+-      sqlite3ExprListDelete(db, pDel);
+     }
+     sqlite3VdbeResolveLabel(v, addrEnd);
+     
+@@ -123440,6 +130495,7 @@
+   if( sSort.pOrderBy ){
+     explainTempTable(pParse,
+                      sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
++    assert( p->pEList==pEList );
+     generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
+   }
+ 
+@@ -123455,14 +130511,16 @@
+   ** successful coding of the SELECT.
+   */
+ select_end:
+-  explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+-
++  sqlite3ExprListDelete(db, pMinMaxOrderBy);
+   sqlite3DbFree(db, sAggInfo.aCol);
+   sqlite3DbFree(db, sAggInfo.aFunc);
+ #if SELECTTRACE_ENABLED
+-  SELECTTRACE(1,pParse,p,("end processing\n"));
+-  pParse->nSelectIndent--;
++  SELECTTRACE(0x1,pParse,p,("end processing\n"));
++  if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
++    sqlite3TreeViewSelect(0, p, 0);
++  }
+ #endif
++  ExplainQueryPlanPop(pParse);
+   return rc;
+ }
+ 
+@@ -123696,6 +130754,8 @@
+     sqlite3ExprListDelete(db, pTmp->pExprList);
+     sqlite3SelectDelete(db, pTmp->pSelect);
+     sqlite3IdListDelete(db, pTmp->pIdList);
++    sqlite3UpsertDelete(db, pTmp->pUpsert);
++    sqlite3DbFree(db, pTmp->zSpan);
+ 
+     sqlite3DbFree(db, pTmp);
+   }
+@@ -123850,14 +130910,16 @@
+     goto trigger_cleanup;
+   }
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+-  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
+-    if( !noErr ){
+-      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+-    }else{
+-      assert( !db->init.busy );
+-      sqlite3CodeVerifySchema(pParse, iDb);
++  if( !IN_RENAME_OBJECT ){
++    if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
++      if( !noErr ){
++        sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
++      }else{
++        assert( !db->init.busy );
++        sqlite3CodeVerifySchema(pParse, iDb);
++      }
++      goto trigger_cleanup;
+     }
+-    goto trigger_cleanup;
+   }
+ 
+   /* Do not create a trigger on a system table */
+@@ -123881,7 +130943,7 @@
+   }
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  {
++  if( !IN_RENAME_OBJECT ){
+     int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+     int code = SQLITE_CREATE_TRIGGER;
+     const char *zDb = db->aDb[iTabDb].zDbSName;
+@@ -123915,8 +130977,15 @@
+   pTrigger->pTabSchema = pTab->pSchema;
+   pTrigger->op = (u8)op;
+   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
+-  pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+-  pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName);
++    pTrigger->pWhen = pWhen;
++    pWhen = 0;
++  }else{
++    pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
++  }
++  pTrigger->pColumns = pColumns;
++  pColumns = 0;
+   assert( pParse->pNewTrigger==0 );
+   pParse->pNewTrigger = pTrigger;
+ 
+@@ -123965,6 +131034,14 @@
+     goto triggerfinish_cleanup;
+   }
+ 
++#ifndef SQLITE_OMIT_ALTERTABLE
++  if( IN_RENAME_OBJECT ){
++    assert( !db->init.busy );
++    pParse->pNewTrigger = pTrig;
++    pTrig = 0;
++  }else
++#endif
++
+   /* if we are not initializing,
+   ** build the sqlite_master entry
+   */
+@@ -124006,11 +131083,22 @@
+ 
+ triggerfinish_cleanup:
+   sqlite3DeleteTrigger(db, pTrig);
+-  assert( !pParse->pNewTrigger );
++  assert( IN_RENAME_OBJECT || !pParse->pNewTrigger );
+   sqlite3DeleteTriggerStep(db, pStepList);
+ }
+ 
+ /*
++** Duplicate a range of text from an SQL statement, then convert all
++** whitespace characters into ordinary space characters.
++*/
++static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
++  char *z = sqlite3DbSpanDup(db, zStart, zEnd);
++  int i;
++  if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
++  return z;
++}    
++
++/*
+ ** Turn a SELECT statement (that the pSelect parameter points to) into
+ ** a trigger step.  Return a pointer to a TriggerStep structure.
+ **
+@@ -124017,7 +131105,12 @@
+ ** The parser calls this routine when it finds a SELECT statement in
+ ** body of a TRIGGER.  
+ */
+-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
++SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
++  sqlite3 *db,                /* Database connection */
++  Select *pSelect,            /* The SELECT statement */
++  const char *zStart,         /* Start of SQL text */
++  const char *zEnd            /* End of SQL text */
++){
+   TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
+   if( pTriggerStep==0 ) {
+     sqlite3SelectDelete(db, pSelect);
+@@ -124026,6 +131119,7 @@
+   pTriggerStep->op = TK_SELECT;
+   pTriggerStep->pSelect = pSelect;
+   pTriggerStep->orconf = OE_Default;
++  pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
+   return pTriggerStep;
+ }
+ 
+@@ -124036,10 +131130,13 @@
+ ** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+ */
+ static TriggerStep *triggerStepAllocate(
+-  sqlite3 *db,                /* Database connection */
++  Parse *pParse,              /* Parser context */
+   u8 op,                      /* Trigger opcode */
+-  Token *pName                /* The target name */
++  Token *pName,               /* The target name */
++  const char *zStart,         /* Start of SQL text */
++  const char *zEnd            /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+   pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
+@@ -124049,6 +131146,10 @@
+     sqlite3Dequote(z);
+     pTriggerStep->zTarget = z;
+     pTriggerStep->op = op;
++    pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName);
++    }
+   }
+   return pTriggerStep;
+ }
+@@ -124061,23 +131162,36 @@
+ ** body of a trigger.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
+-  sqlite3 *db,        /* The database connection */
++  Parse *pParse,      /* Parser */
+   Token *pTableName,  /* Name of the table into which we insert */
+   IdList *pColumn,    /* List of columns in pTableName to insert into */
+   Select *pSelect,    /* A SELECT statement that supplies values */
+-  u8 orconf           /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
++  u8 orconf,          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
++  Upsert *pUpsert,    /* ON CONFLICT clauses for upsert */
++  const char *zStart, /* Start of SQL text */
++  const char *zEnd    /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+   assert(pSelect != 0 || db->mallocFailed);
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
++  pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pSelect = pSelect;
++      pSelect = 0;
++    }else{
++      pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->pIdList = pColumn;
++    pTriggerStep->pUpsert = pUpsert;
+     pTriggerStep->orconf = orconf;
+   }else{
++    testcase( pColumn );
+     sqlite3IdListDelete(db, pColumn);
++    testcase( pUpsert );
++    sqlite3UpsertDelete(db, pUpsert);
+   }
+   sqlite3SelectDelete(db, pSelect);
+ 
+@@ -124090,18 +131204,28 @@
+ ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
+-  sqlite3 *db,         /* The database connection */
++  Parse *pParse,          /* Parser */
+   Token *pTableName,   /* Name of the table to be updated */
+   ExprList *pEList,    /* The SET clause: list of column and new values */
+   Expr *pWhere,        /* The WHERE clause */
+-  u8 orconf            /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
++  u8 orconf,           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
++  const char *zStart,  /* Start of SQL text */
++  const char *zEnd     /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
++  pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+-    pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pExprList = pEList;
++      pTriggerStep->pWhere = pWhere;
++      pEList = 0;
++      pWhere = 0;
++    }else{
++      pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
++      pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->orconf = orconf;
+   }
+   sqlite3ExprListDelete(db, pEList);
+@@ -124115,15 +131239,23 @@
+ ** sees a DELETE statement inside the body of a CREATE TRIGGER.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
+-  sqlite3 *db,            /* Database connection */
++  Parse *pParse,          /* Parser */
+   Token *pTableName,      /* The table from which rows are deleted */
+-  Expr *pWhere            /* The WHERE clause */
++  Expr *pWhere,           /* The WHERE clause */
++  const char *zStart,     /* Start of SQL text */
++  const char *zEnd        /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
++  pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pWhere = pWhere;
++      pWhere = 0;
++    }else{
++      pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->orconf = OE_Default;
+   }
+   sqlite3ExprDelete(db, pWhere);
+@@ -124256,7 +131388,7 @@
+       *pp = (*pp)->pNext;
+     }
+     sqlite3DeleteTrigger(db, pTrigger);
+-    db->flags |= SQLITE_InternChanges;
++    db->mDbFlags |= DBFLAG_SchemaChange;
+   }
+ }
+ 
+@@ -124376,6 +131508,14 @@
+     pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
+     assert( pParse->okConstFactor==0 );
+ 
++#ifndef SQLITE_OMIT_TRACE
++    if( pStep->zSpan ){
++      sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
++                        sqlite3MPrintf(db, "-- %s", pStep->zSpan),
++                        P4_DYNAMIC);
++    }
++#endif
++
+     switch( pStep->op ){
+       case TK_UPDATE: {
+         sqlite3Update(pParse, 
+@@ -124382,7 +131522,7 @@
+           targetSrcList(pParse, pStep),
+           sqlite3ExprListDup(db, pStep->pExprList, 0), 
+           sqlite3ExprDup(db, pStep->pWhere, 0), 
+-          pParse->eOrconf
++          pParse->eOrconf, 0, 0, 0
+         );
+         break;
+       }
+@@ -124391,7 +131531,8 @@
+           targetSrcList(pParse, pStep),
+           sqlite3SelectDup(db, pStep->pSelect, 0), 
+           sqlite3IdListDup(db, pStep->pIdList), 
+-          pParse->eOrconf
++          pParse->eOrconf,
++          sqlite3UpsertDup(db, pStep->pUpsert)
+         );
+         break;
+       }
+@@ -124398,7 +131539,7 @@
+       case TK_DELETE: {
+         sqlite3DeleteFrom(pParse, 
+           targetSrcList(pParse, pStep),
+-          sqlite3ExprDup(db, pStep->pWhere, 0)
++          sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
+         );
+         break;
+       }
+@@ -124516,9 +131657,11 @@
+       pTab->zName
+     ));
+ #ifndef SQLITE_OMIT_TRACE
+-    sqlite3VdbeChangeP4(v, -1, 
+-      sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
+-    );
++    if( pTrigger->zName ){
++      sqlite3VdbeChangeP4(v, -1, 
++        sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
++      );
++    }
+ #endif
+ 
+     /* If one was specified, code the WHEN clause. If it evaluates to false
+@@ -124546,7 +131689,7 @@
+     VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
+ 
+     transferParseError(pParse, pSubParse);
+-    if( db->mallocFailed==0 ){
++    if( db->mallocFailed==0 && pParse->nErr==0 ){
+       pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
+     }
+     pProgram->nMem = pSubParse->nMem;
+@@ -124854,6 +131997,57 @@
+ }
+ 
+ /*
++** Check to see if column iCol of index pIdx references any of the
++** columns defined by aXRef and chngRowid.  Return true if it does
++** and false if not.  This is an optimization.  False-positives are a
++** performance degradation, but false-negatives can result in a corrupt
++** index and incorrect answers.
++**
++** aXRef[j] will be non-negative if column j of the original table is
++** being updated.  chngRowid will be true if the rowid of the table is
++** being updated.
++*/
++static int indexColumnIsBeingUpdated(
++  Index *pIdx,      /* The index to check */
++  int iCol,         /* Which column of the index to check */
++  int *aXRef,       /* aXRef[j]>=0 if column j is being updated */
++  int chngRowid     /* true if the rowid is being updated */
++){
++  i16 iIdxCol = pIdx->aiColumn[iCol];
++  assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
++  if( iIdxCol>=0 ){
++    return aXRef[iIdxCol]>=0;
++  }
++  assert( iIdxCol==XN_EXPR );
++  assert( pIdx->aColExpr!=0 );
++  assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
++  return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
++                                            aXRef,chngRowid);
++}
++
++/*
++** Check to see if index pIdx is a partial index whose conditional
++** expression might change values due to an UPDATE.  Return true if
++** the index is subject to change and false if the index is guaranteed
++** to be unchanged.  This is an optimization.  False-positives are a
++** performance degradation, but false-negatives can result in a corrupt
++** index and incorrect answers.
++**
++** aXRef[j] will be non-negative if column j of the original table is
++** being updated.  chngRowid will be true if the rowid of the table is
++** being updated.
++*/
++static int indexWhereClauseMightChange(
++  Index *pIdx,      /* The index to check */
++  int *aXRef,       /* aXRef[j]>=0 if column j is being updated */
++  int chngRowid     /* true if the rowid is being updated */
++){
++  if( pIdx->pPartIdxWhere==0 ) return 0;
++  return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
++                                            aXRef, chngRowid);
++}
++
++/*
+ ** Process an UPDATE statement.
+ **
+ **   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+@@ -124865,7 +132059,10 @@
+   SrcList *pTabList,     /* The table in which we should change things */
+   ExprList *pChanges,    /* Things to be changed */
+   Expr *pWhere,          /* The WHERE clause.  May be null */
+-  int onError            /* How to handle constraint errors */
++  int onError,           /* How to handle constraint errors */
++  ExprList *pOrderBy,    /* ORDER BY clause. May be null */
++  Expr *pLimit,          /* LIMIT clause. May be null */
++  Upsert *pUpsert        /* ON CONFLICT clause, or null */
+ ){
+   int i, j;              /* Loop counters */
+   Table *pTab;           /* The table to be updated */
+@@ -124950,6 +132147,16 @@
+ # define isView 0
+ #endif
+ 
++#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
++  if( !isView ){
++    pWhere = sqlite3LimitWhere(
++        pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
++    );
++    pOrderBy = 0;
++    pLimit = 0;
++  }
++#endif
++
+   if( sqlite3ViewGetColumnNames(pParse, pTab) ){
+     goto update_cleanup;
+   }
+@@ -124962,16 +132169,23 @@
+   ** need to occur right after the database cursor.  So go ahead and
+   ** allocate enough space, just in case.
+   */
+-  pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
++  iBaseCur = iDataCur = pParse->nTab++;
+   iIdxCur = iDataCur+1;
+   pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
++  testcase( pPk!=0 && pPk!=pTab->pIndex );
+   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+-    if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){
++    if( pPk==pIdx ){
+       iDataCur = pParse->nTab;
+-      pTabList->a[0].iCursor = iDataCur;
+     }
+     pParse->nTab++;
+   }
++  if( pUpsert ){
++    /* On an UPSERT, reuse the same cursors already opened by INSERT */
++    iDataCur = pUpsert->iDataCur;
++    iIdxCur = pUpsert->iIdxCur;
++    pParse->nTab = iBaseCur;
++  }
++  pTabList->a[0].iCursor = iDataCur;
+ 
+   /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].  
+   ** Initialize aXRef[] and aToOpen[] to their default values.
+@@ -124988,6 +132202,8 @@
+   memset(&sNC, 0, sizeof(sNC));
+   sNC.pParse = pParse;
+   sNC.pSrcList = pTabList;
++  sNC.uNC.pUpsert = pUpsert;
++  sNC.ncFlags = NC_UUpsert;
+ 
+   /* Resolve the column names in all the expressions of the
+   ** of the UPDATE statement.  Also find the column index
+@@ -125054,19 +132270,18 @@
+   /* There is one entry in the aRegIdx[] array for each index on the table
+   ** being updated.  Fill in aRegIdx[] with a register number that will hold
+   ** the key for accessing each index.
+-  **
+-  ** FIXME:  Be smarter about omitting indexes that use expressions.
+   */
+   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+     int reg;
+-    if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
++    if( chngKey || hasFK>1 || pIdx==pPk
++     || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
++    ){
+       reg = ++pParse->nMem;
+       pParse->nMem += pIdx->nColumn;
+     }else{
+       reg = 0;
+       for(i=0; i<pIdx->nKeyCol; i++){
+-        i16 iIdxCol = pIdx->aiColumn[i];
+-        if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
++        if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
+           reg = ++pParse->nMem;
+           pParse->nMem += pIdx->nColumn;
+           if( (onError==OE_Replace)
+@@ -125091,7 +132306,7 @@
+   v = sqlite3GetVdbe(pParse);
+   if( v==0 ) goto update_cleanup;
+   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+-  sqlite3BeginWriteOperation(pParse, 1, iDb);
++  sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
+ 
+   /* Allocate required registers. */
+   if( !IsVirtual(pTab) ){
+@@ -125118,7 +132333,11 @@
+   */
+ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
+   if( isView ){
+-    sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
++    sqlite3MaterializeView(pParse, pTab, 
++        pWhere, pOrderBy, pLimit, iDataCur
++    );
++    pOrderBy = 0;
++    pLimit = 0;
+   }
+ #endif
+ 
+@@ -125138,8 +132357,16 @@
+   }
+ #endif
+ 
+-  /* Initialize the count of updated rows */
+-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
++  /* Jump to labelBreak to abandon further processing of this UPDATE */
++  labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
++
++  /* Not an UPSERT.  Normal processing.  Begin by
++  ** initialize the count of updated rows */
++  if( (db->flags&SQLITE_CountRows)!=0
++   && !pParse->pTriggerTab
++   && !pParse->nested
++   && pUpsert==0
++  ){
+     regRowCount = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+   }
+@@ -125152,46 +132379,61 @@
+     iPk = pParse->nMem+1;
+     pParse->nMem += nPk;
+     regKey = ++pParse->nMem;
+-    iEph = pParse->nTab++;
+-
+-    sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+-    addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+-    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
++    if( pUpsert==0 ){
++      iEph = pParse->nTab++;
++        sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
++      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
++      sqlite3VdbeSetP4KeyInfo(pParse, pPk);
++    }
+   }
+-
+-  /* Begin the database scan. 
+-  **
+-  ** Do not consider a single-pass strategy for a multi-row update if
+-  ** there are any triggers or foreign keys to process, or rows may
+-  ** be deleted as a result of REPLACE conflict handling. Any of these
+-  ** things might disturb a cursor being used to scan through the table
+-  ** or index, causing a single-pass approach to malfunction.  */
+-  flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
+-  if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+-    flags |= WHERE_ONEPASS_MULTIROW;
++  
++  if( pUpsert ){
++    /* If this is an UPSERT, then all cursors have already been opened by
++    ** the outer INSERT and the data cursor should be pointing at the row
++    ** that is to be updated.  So bypass the code that searches for the
++    ** row(s) to be updated.
++    */
++    pWInfo = 0;
++    eOnePass = ONEPASS_SINGLE;
++    sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
++  }else{
++    /* Begin the database scan. 
++    **
++    ** Do not consider a single-pass strategy for a multi-row update if
++    ** there are any triggers or foreign keys to process, or rows may
++    ** be deleted as a result of REPLACE conflict handling. Any of these
++    ** things might disturb a cursor being used to scan through the table
++    ** or index, causing a single-pass approach to malfunction.  */
++    flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
++    if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
++      flags |= WHERE_ONEPASS_MULTIROW;
++    }
++    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
++    if( pWInfo==0 ) goto update_cleanup;
++  
++    /* A one-pass strategy that might update more than one row may not
++    ** be used if any column of the index used for the scan is being
++    ** updated. Otherwise, if there is an index on "b", statements like
++    ** the following could create an infinite loop:
++    **
++    **   UPDATE t1 SET b=b+1 WHERE b>?
++    **
++    ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
++    ** strategy that uses an index for which one or more columns are being
++    ** updated.  */
++    eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++    if( eOnePass!=ONEPASS_SINGLE ){
++      sqlite3MultiWrite(pParse);
++      if( eOnePass==ONEPASS_MULTI ){
++        int iCur = aiCurOnePass[1];
++        if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
++          eOnePass = ONEPASS_OFF;
++        }
++        assert( iCur!=iDataCur || !HasRowid(pTab) );
++      }
++    }
+   }
+-  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
+-  if( pWInfo==0 ) goto update_cleanup;
+ 
+-  /* A one-pass strategy that might update more than one row may not
+-  ** be used if any column of the index used for the scan is being
+-  ** updated. Otherwise, if there is an index on "b", statements like
+-  ** the following could create an infinite loop:
+-  **
+-  **   UPDATE t1 SET b=b+1 WHERE b>?
+-  **
+-  ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
+-  ** strategy that uses an index for which one or more columns are being
+-  ** updated.  */
+-  eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+-  if( eOnePass==ONEPASS_MULTI ){
+-    int iCur = aiCurOnePass[1];
+-    if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
+-      eOnePass = ONEPASS_OFF;
+-    }
+-    assert( iCur!=iDataCur || !HasRowid(pTab) );
+-  }
+-  
+   if( HasRowid(pTab) ){
+     /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
+     ** mode, write the rowid into the FIFO. In either of the one-pass modes,
+@@ -125211,7 +132453,7 @@
+       sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
+     }
+     if( eOnePass ){
+-      sqlite3VdbeChangeToNoop(v, addrOpen);
++      if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
+       nKey = nPk;
+       regKey = iPk;
+     }else{
+@@ -125221,59 +132463,58 @@
+     }
+   }
+ 
+-  if( eOnePass!=ONEPASS_MULTI ){
+-    sqlite3WhereEnd(pWInfo);
+-  }
+-
+-  labelBreak = sqlite3VdbeMakeLabel(v);
+-  if( !isView ){
+-    int addrOnce = 0;
+-
+-    /* Open every index that needs updating. */
+-    if( eOnePass!=ONEPASS_OFF ){
+-      if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+-      if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
++  if( pUpsert==0 ){
++    if( eOnePass!=ONEPASS_MULTI ){
++      sqlite3WhereEnd(pWInfo);
+     }
+-
+-    if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
+-      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++  
++    if( !isView ){
++      int addrOnce = 0;
++  
++      /* Open every index that needs updating. */
++      if( eOnePass!=ONEPASS_OFF ){
++        if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
++        if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
++      }
++  
++      if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
++        addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++      }
++      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
++                                 aToOpen, 0, 0);
++      if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+     }
+-    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
+-                               0, 0);
+-    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+-  }
+-
+-  /* Top of the update loop */
+-  if( eOnePass!=ONEPASS_OFF ){
+-    if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
+-      assert( pPk );
+-      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+-      VdbeCoverageNeverTaken(v);
+-    }
+-    if( eOnePass==ONEPASS_SINGLE ){
+-      labelContinue = labelBreak;
++  
++    /* Top of the update loop */
++    if( eOnePass!=ONEPASS_OFF ){
++      if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
++        assert( pPk );
++        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
++        VdbeCoverage(v);
++      }
++      if( eOnePass!=ONEPASS_SINGLE ){
++        labelContinue = sqlite3VdbeMakeLabel(v);
++      }
++      sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
++      VdbeCoverageIf(v, pPk==0);
++      VdbeCoverageIf(v, pPk!=0);
++    }else if( pPk ){
++      labelContinue = sqlite3VdbeMakeLabel(v);
++      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
++      addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
++      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
++      VdbeCoverage(v);
+     }else{
+-      labelContinue = sqlite3VdbeMakeLabel(v);
++      labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
++                               regOldRowid);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
++      VdbeCoverage(v);
+     }
+-    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+-    VdbeCoverageIf(v, pPk==0);
+-    VdbeCoverageIf(v, pPk!=0);
+-  }else if( pPk ){
+-    labelContinue = sqlite3VdbeMakeLabel(v);
+-    sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+-    addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
+-    sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+-    VdbeCoverage(v);
+-  }else{
+-    labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+-                             regOldRowid);
+-    VdbeCoverage(v);
+-    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+-    VdbeCoverage(v);
+   }
+ 
+-  /* If the record number will change, set register regNewRowid to
+-  ** contain the new value. If the record number is not being modified,
++  /* If the rowid value will change, set register regNewRowid to
++  ** contain the new value. If the rowid is not being modified,
+   ** then regNewRowid is the same register as regOldRowid, which is
+   ** already populated.  */
+   assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
+@@ -125336,7 +132577,7 @@
+         */
+         testcase( i==31 );
+         testcase( i==32 );
+-        sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
++        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+       }
+@@ -125365,10 +132606,14 @@
+       VdbeCoverage(v);
+     }
+ 
+-    /* If it did not delete it, the row-trigger may still have modified 
++    /* After-BEFORE-trigger-reload-loop:
++    ** If it did not delete it, the BEFORE trigger may still have modified 
+     ** some of the columns of the row being updated. Load the values for 
+-    ** all columns not modified by the update statement into their 
+-    ** registers in case this has happened.
++    ** all columns not modified by the update statement into their registers
++    ** in case this has happened. Only unmodified columns are reloaded.
++    ** The values computed for modified columns use the values before the
++    ** BEFORE trigger runs.  See test case trigger1-18.0 (added 2018-04-26)
++    ** for an example.
+     */
+     for(i=0; i<pTab->nCol; i++){
+       if( aXRef[i]<0 && i!=pTab->iPKey ){
+@@ -125384,7 +132629,7 @@
+     assert( regOldRowid>0 );
+     sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+         regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
+-        aXRef);
++        aXRef, 0);
+ 
+     /* Do FK constraint checks. */
+     if( hasFK ){
+@@ -125454,7 +132699,7 @@
+ 
+   /* Increment the row counter 
+   */
+-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+   }
+ 
+@@ -125481,16 +132726,15 @@
+   ** maximum rowid counter values recorded while inserting into
+   ** autoincrement tables.
+   */
+-  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
++  if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){
+     sqlite3AutoincrementEnd(pParse);
+   }
+ 
+   /*
+-  ** Return the number of rows that were changed. If this routine is 
+-  ** generating code because of a call to sqlite3NestedParse(), do not
+-  ** invoke the callback function.
++  ** Return the number of rows that were changed, if we are tracking
++  ** that information.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
+@@ -125502,6 +132746,10 @@
+   sqlite3SrcListDelete(db, pTabList);
+   sqlite3ExprListDelete(db, pChanges);
+   sqlite3ExprDelete(db, pWhere);
++#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) 
++  sqlite3ExprListDelete(db, pOrderBy);
++  sqlite3ExprDelete(db, pLimit);
++#endif
+   return;
+ }
+ /* Make sure "isView" and other macros defined above are undefined. Otherwise
+@@ -125558,10 +132806,10 @@
+   int regRowid;                   /* Register for ephem table rowid */
+   int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
+   int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
+-  int bOnePass;                   /* True to use onepass strategy */
++  int eOnePass;                   /* True to use onepass strategy */
+   int addr;                       /* Address of OP_OpenEphemeral */
+ 
+-  /* Allocate nArg registers to martial the arguments to VUpdate. Then
++  /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
+   ** create and open the ephemeral table in which the records created from
+   ** these arguments will be temporarily stored. */
+   assert( v );
+@@ -125577,40 +132825,58 @@
+   if( pWInfo==0 ) return;
+ 
+   /* Populate the argument registers. */
+-  sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
+-  if( pRowid ){
+-    sqlite3ExprCode(pParse, pRowid, regArg+1);
+-  }else{
+-    sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
+-  }
+   for(i=0; i<pTab->nCol; i++){
+     if( aXRef[i]>=0 ){
+       sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
+     }else{
+       sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
++      sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
+     }
+   }
++  if( HasRowid(pTab) ){
++    sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
++    if( pRowid ){
++      sqlite3ExprCode(pParse, pRowid, regArg+1);
++    }else{
++      sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
++    }
++  }else{
++    Index *pPk;   /* PRIMARY KEY index */
++    i16 iPk;      /* PRIMARY KEY column */
++    pPk = sqlite3PrimaryKeyIndex(pTab);
++    assert( pPk!=0 );
++    assert( pPk->nKeyCol==1 );
++    iPk = pPk->aiColumn[0];
++    sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg);
++    sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
++  }
+ 
+-  bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
++  eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+ 
+-  if( bOnePass ){
++  /* There is no ONEPASS_MULTI on virtual tables */
++  assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
++
++  if( eOnePass ){
+     /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
+-    ** above. Also, if this is a top-level parse (not a trigger), clear the
+-    ** multi-write flag so that the VM does not open a statement journal */
++    ** above. */
+     sqlite3VdbeChangeToNoop(v, addr);
+-    if( sqlite3IsToplevel(pParse) ){
+-      pParse->isMultiWrite = 0;
+-    }
++    sqlite3VdbeAddOp1(v, OP_Close, iCsr);
+   }else{
+     /* Create a record from the argument register contents and insert it into
+     ** the ephemeral table. */
++    sqlite3MultiWrite(pParse);
+     sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
++#ifdef SQLITE_DEBUG
++    /* Signal an assert() within OP_MakeRecord that it is allowed to
++    ** accept no-change records with serial_type 10 */
++    sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
++#endif
+     sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
+     sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
+   }
+ 
+ 
+-  if( bOnePass==0 ){
++  if( eOnePass==ONEPASS_OFF ){
+     /* End the virtual table scan */
+     sqlite3WhereEnd(pWInfo);
+ 
+@@ -125630,7 +132896,7 @@
+ 
+   /* End of the ephemeral table scan. Or, if using the onepass strategy,
+   ** jump to here if the scan visited zero rows. */
+-  if( bOnePass==0 ){
++  if( eOnePass==ONEPASS_OFF ){
+     sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+     sqlite3VdbeJumpHere(v, addr);
+     sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+@@ -125641,6 +132907,261 @@
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+ /************** End of update.c **********************************************/
++/************** Begin file upsert.c ******************************************/
++/*
++** 2018-04-12
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains code to implement various aspects of UPSERT
++** processing and handling of the Upsert object.
++*/
++/* #include "sqliteInt.h" */
++
++#ifndef SQLITE_OMIT_UPSERT
++/*
++** Free a list of Upsert objects
++*/
++SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){
++  if( p ){
++    sqlite3ExprListDelete(db, p->pUpsertTarget);
++    sqlite3ExprDelete(db, p->pUpsertTargetWhere);
++    sqlite3ExprListDelete(db, p->pUpsertSet);
++    sqlite3ExprDelete(db, p->pUpsertWhere);
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Duplicate an Upsert object.
++*/
++SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){
++  if( p==0 ) return 0;
++  return sqlite3UpsertNew(db,
++           sqlite3ExprListDup(db, p->pUpsertTarget, 0),
++           sqlite3ExprDup(db, p->pUpsertTargetWhere, 0),
++           sqlite3ExprListDup(db, p->pUpsertSet, 0),
++           sqlite3ExprDup(db, p->pUpsertWhere, 0)
++         );
++}
++
++/*
++** Create a new Upsert object.
++*/
++SQLITE_PRIVATE Upsert *sqlite3UpsertNew(
++  sqlite3 *db,           /* Determines which memory allocator to use */
++  ExprList *pTarget,     /* Target argument to ON CONFLICT, or NULL */
++  Expr *pTargetWhere,    /* Optional WHERE clause on the target */
++  ExprList *pSet,        /* UPDATE columns, or NULL for a DO NOTHING */
++  Expr *pWhere           /* WHERE clause for the ON CONFLICT UPDATE */
++){
++  Upsert *pNew;
++  pNew = sqlite3DbMallocRaw(db, sizeof(Upsert));
++  if( pNew==0 ){
++    sqlite3ExprListDelete(db, pTarget);
++    sqlite3ExprDelete(db, pTargetWhere);
++    sqlite3ExprListDelete(db, pSet);
++    sqlite3ExprDelete(db, pWhere);
++    return 0;
++  }else{
++    pNew->pUpsertTarget = pTarget;
++    pNew->pUpsertTargetWhere = pTargetWhere;
++    pNew->pUpsertSet = pSet;
++    pNew->pUpsertWhere = pWhere;
++    pNew->pUpsertIdx = 0;
++  }
++  return pNew;
++}
++
++/*
++** Analyze the ON CONFLICT clause described by pUpsert.  Resolve all
++** symbols in the conflict-target.
++**
++** Return SQLITE_OK if everything works, or an error code is something
++** is wrong.
++*/
++SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
++  Parse *pParse,     /* The parsing context */
++  SrcList *pTabList, /* Table into which we are inserting */
++  Upsert *pUpsert    /* The ON CONFLICT clauses */
++){
++  Table *pTab;            /* That table into which we are inserting */
++  int rc;                 /* Result code */
++  int iCursor;            /* Cursor used by pTab */
++  Index *pIdx;            /* One of the indexes of pTab */
++  ExprList *pTarget;      /* The conflict-target clause */
++  Expr *pTerm;            /* One term of the conflict-target clause */
++  NameContext sNC;        /* Context for resolving symbolic names */
++  Expr sCol[2];           /* Index column converted into an Expr */
++
++  assert( pTabList->nSrc==1 );
++  assert( pTabList->a[0].pTab!=0 );
++  assert( pUpsert!=0 );
++  assert( pUpsert->pUpsertTarget!=0 );
++
++  /* Resolve all symbolic names in the conflict-target clause, which
++  ** includes both the list of columns and the optional partial-index
++  ** WHERE clause.
++  */
++  memset(&sNC, 0, sizeof(sNC));
++  sNC.pParse = pParse;
++  sNC.pSrcList = pTabList;
++  rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
++  if( rc ) return rc;
++  rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
++  if( rc ) return rc;
++
++  /* Check to see if the conflict target matches the rowid. */  
++  pTab = pTabList->a[0].pTab;
++  pTarget = pUpsert->pUpsertTarget;
++  iCursor = pTabList->a[0].iCursor;
++  if( HasRowid(pTab) 
++   && pTarget->nExpr==1
++   && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
++   && pTerm->iColumn==XN_ROWID
++  ){
++    /* The conflict-target is the rowid of the primary table */
++    assert( pUpsert->pUpsertIdx==0 );
++    return SQLITE_OK;
++  }
++
++  /* Initialize sCol[0..1] to be an expression parse tree for a
++  ** single column of an index.  The sCol[0] node will be the TK_COLLATE
++  ** operator and sCol[1] will be the TK_COLUMN operator.  Code below
++  ** will populate the specific collation and column number values
++  ** prior to comparing against the conflict-target expression.
++  */
++  memset(sCol, 0, sizeof(sCol));
++  sCol[0].op = TK_COLLATE;
++  sCol[0].pLeft = &sCol[1];
++  sCol[1].op = TK_COLUMN;
++  sCol[1].iTable = pTabList->a[0].iCursor;
++
++  /* Check for matches against other indexes */
++  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
++    int ii, jj, nn;
++    if( !IsUniqueIndex(pIdx) ) continue;
++    if( pTarget->nExpr!=pIdx->nKeyCol ) continue;
++    if( pIdx->pPartIdxWhere ){
++      if( pUpsert->pUpsertTargetWhere==0 ) continue;
++      if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere,
++                             pIdx->pPartIdxWhere, iCursor)!=0 ){
++        continue;
++      }
++    }
++    nn = pIdx->nKeyCol;
++    for(ii=0; ii<nn; ii++){
++      Expr *pExpr;
++      sCol[0].u.zToken = (char*)pIdx->azColl[ii];
++      if( pIdx->aiColumn[ii]==XN_EXPR ){
++        assert( pIdx->aColExpr!=0 );
++        assert( pIdx->aColExpr->nExpr>ii );
++        pExpr = pIdx->aColExpr->a[ii].pExpr;
++        if( pExpr->op!=TK_COLLATE ){
++          sCol[0].pLeft = pExpr;
++          pExpr = &sCol[0];
++        }
++      }else{
++        sCol[0].pLeft = &sCol[1];
++        sCol[1].iColumn = pIdx->aiColumn[ii];
++        pExpr = &sCol[0];
++      }
++      for(jj=0; jj<nn; jj++){
++        if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){
++          break;  /* Column ii of the index matches column jj of target */
++        }
++      }
++      if( jj>=nn ){
++        /* The target contains no match for column jj of the index */
++        break;
++      }
++    }
++    if( ii<nn ){
++      /* Column ii of the index did not match any term of the conflict target.
++      ** Continue the search with the next index. */
++      continue;
++    }
++    pUpsert->pUpsertIdx = pIdx;
++    return SQLITE_OK;
++  }
++  sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any "
++                          "PRIMARY KEY or UNIQUE constraint");
++  return SQLITE_ERROR;
++}
++
++/*
++** Generate bytecode that does an UPDATE as part of an upsert.
++**
++** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
++** In this case parameter iCur is a cursor open on the table b-tree that
++** currently points to the conflicting table row. Otherwise, if pIdx
++** is not NULL, then pIdx is the constraint that failed and iCur is a
++** cursor points to the conflicting row.
++*/
++SQLITE_PRIVATE void sqlite3UpsertDoUpdate(
++  Parse *pParse,        /* The parsing and code-generating context */
++  Upsert *pUpsert,      /* The ON CONFLICT clause for the upsert */
++  Table *pTab,          /* The table being updated */
++  Index *pIdx,          /* The UNIQUE constraint that failed */
++  int iCur              /* Cursor for pIdx (or pTab if pIdx==NULL) */
++){
++  Vdbe *v = pParse->pVdbe;
++  sqlite3 *db = pParse->db;
++  SrcList *pSrc;            /* FROM clause for the UPDATE */
++  int iDataCur;
++
++  assert( v!=0 );
++  assert( pUpsert!=0 );
++  VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
++  iDataCur = pUpsert->iDataCur;
++  if( pIdx && iCur!=iDataCur ){
++    if( HasRowid(pTab) ){
++      int regRowid = sqlite3GetTempReg(pParse);
++      sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid);
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid);
++      VdbeCoverage(v);
++      sqlite3ReleaseTempReg(pParse, regRowid);
++    }else{
++      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
++      int nPk = pPk->nKeyCol;
++      int iPk = pParse->nMem+1;
++      int i;
++      pParse->nMem += nPk;
++      for(i=0; i<nPk; i++){
++        int k;
++        assert( pPk->aiColumn[i]>=0 );
++        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
++        sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
++        VdbeComment((v, "%s.%s", pIdx->zName,
++                    pTab->aCol[pPk->aiColumn[i]].zName));
++      }
++      sqlite3VdbeVerifyAbortable(v, OE_Abort);
++      i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, 
++            "corrupt database", P4_STATIC);
++      sqlite3VdbeJumpHere(v, i);
++    }
++  }
++  /* pUpsert does not own pUpsertSrc - the outer INSERT statement does.  So
++  ** we have to make a copy before passing it down into sqlite3Update() */
++  pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0);
++  sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet,
++      pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert);
++  pUpsert->pUpsertSet = 0;    /* Will have been deleted by sqlite3Update() */
++  pUpsert->pUpsertWhere = 0;  /* Will have been deleted by sqlite3Update() */
++  VdbeNoopComment((v, "End DO UPDATE of UPSERT"));
++}
++
++#endif /* SQLITE_OMIT_UPSERT */
++
++/************** End of upsert.c **********************************************/
+ /************** Begin file vacuum.c ******************************************/
+ /*
+ ** 2003 April 6
+@@ -125683,8 +133204,14 @@
+   while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
+     const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
+     assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
+-    if( zSubSql ){
+-      assert( zSubSql[0]!='S' );
++    /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
++    ** or INSERT.  Historically there have been attacks that first
++    ** corrupt the sqlite_master.sql field with other kinds of statements
++    ** then run VACUUM to get those statements to execute at inappropriate
++    ** times. */
++    if( zSubSql
++     && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
++    ){
+       rc = execSql(db, pzErrMsg, zSubSql);
+       if( rc!=SQLITE_OK ) break;
+     }
+@@ -125774,7 +133301,8 @@
+   int rc = SQLITE_OK;     /* Return code from service routines */
+   Btree *pMain;           /* The database being vacuumed */
+   Btree *pTemp;           /* The temporary database we vacuum into */
+-  int saved_flags;        /* Saved value of the db->flags */
++  u16 saved_mDbFlags;     /* Saved value of db->mDbFlags */
++  u32 saved_flags;        /* Saved value of db->flags */
+   int saved_nChange;      /* Saved value of db->nChange */
+   int saved_nTotalChange; /* Saved value of db->nTotalChange */
+   u8 saved_mTrace;        /* Saved trace settings */
+@@ -125797,12 +133325,14 @@
+   ** restored before returning. Then set the writable-schema flag, and
+   ** disable CHECK and foreign key constraints.  */
+   saved_flags = db->flags;
++  saved_mDbFlags = db->mDbFlags;
+   saved_nChange = db->nChange;
+   saved_nTotalChange = db->nTotalChange;
+   saved_mTrace = db->mTrace;
+-  db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
+-                 | SQLITE_PreferBuiltin | SQLITE_Vacuum);
+-  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
++  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
++  db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
++  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
++                   | SQLITE_Defensive | SQLITE_CountRows);
+   db->mTrace = 0;
+ 
+   zDbMain = db->aDb[iDb].zDbSName;
+@@ -125860,7 +133390,7 @@
+   */
+   rc = execSql(db, pzErrMsg, "BEGIN");
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  rc = sqlite3BtreeBeginTrans(pMain, 2);
++  rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ 
+   /* Do not attempt to change the page size for a WAL database */
+@@ -125895,7 +133425,7 @@
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+   rc = execSqlF(db, pzErrMsg,
+       "SELECT sql FROM \"%w\".sqlite_master"
+-      " WHERE type='index' AND length(sql)>10",
++      " WHERE type='index'",
+       zDbMain
+   );
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+@@ -125912,8 +133442,8 @@
+       "WHERE type='table'AND coalesce(rootpage,1)>0",
+       zDbMain
+   );
+-  assert( (db->flags & SQLITE_Vacuum)!=0 );
+-  db->flags &= ~SQLITE_Vacuum;
++  assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
++  db->mDbFlags &= ~DBFLAG_Vacuum;
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ 
+   /* Copy the triggers, views, and virtual tables from the main database
+@@ -125981,6 +133511,7 @@
+ end_of_vacuum:
+   /* Restore the original value of db->flags */
+   db->init.iDb = 0;
++  db->mDbFlags = saved_mDbFlags;
+   db->flags = saved_flags;
+   db->nChange = saved_nChange;
+   db->nTotalChange = saved_nTotalChange;
+@@ -126057,8 +133588,10 @@
+ ){
+   Module *pMod;
+   int nName = sqlite3Strlen30(zName);
+-  pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
+-  if( pMod ){
++  pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
++  if( pMod==0 ){
++    sqlite3OomFault(db);
++  }else{
+     Module *pDel;
+     char *zCopy = (char *)(&pMod[1]);
+     memcpy(zCopy, zName, nName+1);
+@@ -126275,7 +133808,7 @@
+   assert( sqlite3_mutex_held(db->mutex) );
+ 
+   if( p ){
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+     do {
+       VTable *pNext = p->pNext;
+       sqlite3VtabUnlock(p);
+@@ -126341,7 +133874,6 @@
+   Token *pModuleName,   /* Name of the module for the virtual table */
+   int ifNotExists       /* No error if the table already exists */
+ ){
+-  int iDb;              /* The database the table is being created in */
+   Table *pTable;        /* The new virtual table */
+   sqlite3 *db;          /* Database connection */
+ 
+@@ -126351,8 +133883,6 @@
+   assert( 0==pTable->pIndex );
+ 
+   db = pParse->db;
+-  iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+-  assert( iDb>=0 );
+ 
+   assert( pTable->nModuleArg==0 );
+   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
+@@ -126372,6 +133902,8 @@
+   ** The second call, to obtain permission to create the table, is made now.
+   */
+   if( pTable->azModuleArg ){
++    int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
++    assert( iDb>=0 ); /* The database the table is being created in */
+     sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
+             pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
+   }
+@@ -126533,13 +134065,14 @@
+     }
+   }
+ 
+-  zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
++  zModuleName = sqlite3DbStrDup(db, pTab->zName);
+   if( !zModuleName ){
+     return SQLITE_NOMEM_BKPT;
+   }
+ 
+-  pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
++  pVTable = sqlite3MallocZero(sizeof(VTable));
+   if( !pVTable ){
++    sqlite3OomFault(db);
+     sqlite3DbFree(db, zModuleName);
+     return SQLITE_NOMEM_BKPT;
+   }
+@@ -126659,6 +134192,7 @@
+     rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
+     if( rc!=SQLITE_OK ){
+       sqlite3ErrorMsg(pParse, "%s", zErr);
++      pParse->rc = rc;
+     }
+     sqlite3DbFree(db, zErr);
+   }
+@@ -126748,10 +134282,10 @@
+ */
+ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+   VtabCtx *pCtx;
+-  Parse *pParse;
+   int rc = SQLITE_OK;
+   Table *pTab;
+   char *zErr = 0;
++  Parse sParse;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
+@@ -126768,56 +134302,56 @@
+   pTab = pCtx->pTab;
+   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
+-     && !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;
+-        pNew->aCol = 0;
+-        assert( pTab->pIndex==0 );
+-        if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){
+-          rc = SQLITE_ERROR;
+-        }
+-        pIdx = pNew->pIndex;
+-        if( pIdx ){
+-          assert( pIdx->pNext==0 );
+-          pTab->pIndex = pIdx;
+-          pNew->pIndex = 0;
+-          pIdx->pTable = pTab;
+-        }
++  memset(&sParse, 0, sizeof(sParse));
++  sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
++  sParse.db = db;
++  sParse.nQueryLoop = 1;
++  if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) 
++   && sParse.pNewTable
++   && !db->mallocFailed
++   && !sParse.pNewTable->pSelect
++   && !IsVirtual(sParse.pNewTable)
++  ){
++    if( !pTab->aCol ){
++      Table *pNew = sParse.pNewTable;
++      Index *pIdx;
++      pTab->aCol = pNew->aCol;
++      pTab->nCol = pNew->nCol;
++      pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
++      pNew->nCol = 0;
++      pNew->aCol = 0;
++      assert( pTab->pIndex==0 );
++      assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
++      if( !HasRowid(pNew)
++       && pCtx->pVTable->pMod->pModule->xUpdate!=0
++       && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1
++      ){
++        /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0)
++        ** or else must have a single-column PRIMARY KEY */
++        rc = SQLITE_ERROR;
+       }
+-      pCtx->bDeclared = 1;
+-    }else{
+-      sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+-      sqlite3DbFree(db, zErr);
+-      rc = SQLITE_ERROR;
++      pIdx = pNew->pIndex;
++      if( pIdx ){
++        assert( pIdx->pNext==0 );
++        pTab->pIndex = pIdx;
++        pNew->pIndex = 0;
++        pIdx->pTable = pTab;
++      }
+     }
+-    pParse->declareVtab = 0;
+-  
+-    if( pParse->pVdbe ){
+-      sqlite3VdbeFinalize(pParse->pVdbe);
+-    }
+-    sqlite3DeleteTable(db, pParse->pNewTable);
+-    sqlite3ParserReset(pParse);
+-    sqlite3StackFree(db, pParse);
++    pCtx->bDeclared = 1;
++  }else{
++    sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
++    sqlite3DbFree(db, zErr);
++    rc = SQLITE_ERROR;
+   }
++  sParse.eParseMode = PARSE_MODE_NORMAL;
+ 
++  if( sParse.pVdbe ){
++    sqlite3VdbeFinalize(sParse.pVdbe);
++  }
++  sqlite3DeleteTable(db, sParse.pNewTable);
++  sqlite3ParserReset(&sParse);
++
+   assert( (rc&0xff)==rc );
+   rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+@@ -127060,14 +134594,11 @@
+   void *pArg = 0;
+   FuncDef *pNew;
+   int rc = 0;
+-  char *zLowerName;
+-  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;
++  pTab = pExpr->y.pTab;
+   if( pTab==0 ) return pDef;
+   if( !IsVirtual(pTab) ) return pDef;
+   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+@@ -127077,16 +134608,22 @@
+   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 
++  ** to see if the implementation wants to overload this function.
++  **
++  ** Though undocumented, we have historically always invoked xFindFunction
++  ** with an all lower-case function name.  Continue in this tradition to
++  ** avoid any chance of an incompatibility.
+   */
+-  zLowerName = sqlite3DbStrDup(db, pDef->zName);
+-  if( zLowerName ){
+-    for(z=(unsigned char*)zLowerName; *z; z++){
+-      *z = sqlite3UpperToLower[*z];
++#ifdef SQLITE_DEBUG
++  {
++    int i;
++    for(i=0; pDef->zName[i]; i++){
++      unsigned char x = (unsigned char)pDef->zName[i];
++      assert( x==sqlite3UpperToLower[x] );
+     }
+-    rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
+-    sqlite3DbFree(db, zLowerName);
+   }
++#endif
++  rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg);
+   if( rc==0 ){
+     return pDef;
+   }
+@@ -127298,7 +134835,7 @@
+ ** Trace output macros
+ */
+ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+-/***/ int sqlite3WhereTrace;
++/***/ extern int sqlite3WhereTrace;
+ #endif
+ #if defined(SQLITE_DEBUG) \
+     && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
+@@ -127361,6 +134898,8 @@
+       struct InLoop {
+         int iCur;              /* The VDBE cursor used by this IN operator */
+         int addrInTop;         /* Top of the IN loop */
++        int iBase;             /* Base register of multi-key index record */
++        int nPrefix;           /* Number of prior entires in the key */
+         u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
+       } *aInLoop;           /* Information about each nested IN operator */
+     } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
+@@ -127599,6 +135138,7 @@
+   WhereInfo *pWInfo;       /* WHERE clause processing context */
+   WhereClause *pOuter;     /* Outer conjunction */
+   u8 op;                   /* Split operator.  TK_AND or TK_OR */
++  u8 hasOr;                /* True if any a[].eOperator is WO_OR */
+   int nTerm;               /* Number of terms */
+   int nSlot;               /* Number of entries in a[] */
+   WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
+@@ -127678,6 +135218,7 @@
+   int nRecValid;            /* Number of valid fields currently in pRec */
+ #endif
+   unsigned int bldFlags;    /* SQLITE_BLDF_* flags */
++  unsigned int iPlanLimit;  /* Search limiter */
+ };
+ 
+ /* Allowed values for WhereLoopBuider.bldFlags */
+@@ -127684,6 +135225,26 @@
+ #define SQLITE_BLDF_INDEXED  0x0001   /* An index is used */
+ #define SQLITE_BLDF_UNIQUE   0x0002   /* All keys of a UNIQUE index used */
+ 
++/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
++** index+constraint combinations the query planner will consider for a
++** particular query.  If this parameter is unlimited, then certain
++** pathological queries can spend excess time in the sqlite3WhereBegin()
++** routine.  The limit is high enough that is should not impact real-world
++** queries.
++**
++** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit.  The limit is
++** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
++** clause is processed, so that every table in a join is guaranteed to be
++** able to propose a some index+constraint combinations even if the initial
++** baseline limit was exhausted by prior tables of the join.
++*/
++#ifndef SQLITE_QUERY_PLANNER_LIMIT
++# define SQLITE_QUERY_PLANNER_LIMIT 20000
++#endif
++#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
++# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
++#endif
++
+ /*
+ ** The WHERE clause processing routine has two halves.  The
+ ** first part does the start of the WHERE loop and the second
+@@ -127746,12 +135307,10 @@
+   Parse *pParse,                  /* Parse context */
+   SrcList *pTabList,              /* Table list this loop refers to */
+   WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
+-  int iLevel,                     /* Value for "level" column of output */
+-  int iFrom,                      /* Value for "from" column of output */
+   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
+ );
+ #else
+-# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
++# define sqlite3WhereExplainOneScan(u,v,w,x) 0
+ #endif /* SQLITE_OMIT_EXPLAIN */
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
+@@ -127774,6 +135333,7 @@
+ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
+ SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
+ SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
+ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
+@@ -127794,7 +135354,6 @@
+ **     WO_LE    == SQLITE_INDEX_CONSTRAINT_LE
+ **     WO_GT    == SQLITE_INDEX_CONSTRAINT_GT
+ **     WO_GE    == SQLITE_INDEX_CONSTRAINT_GE
+-**     WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
+ */
+ #define WO_IN     0x0001
+ #define WO_EQ     0x0002
+@@ -127802,7 +135361,7 @@
+ #define WO_LE     (WO_EQ<<(TK_LE-TK_EQ))
+ #define WO_GT     (WO_EQ<<(TK_GT-TK_EQ))
+ #define WO_GE     (WO_EQ<<(TK_GE-TK_EQ))
+-#define WO_MATCH  0x0040
++#define WO_AUX    0x0040       /* Op useful to virtual tables only */
+ #define WO_IS     0x0080
+ #define WO_ISNULL 0x0100
+ #define WO_OR     0x0200       /* Two or more OR-connected terms */
+@@ -127837,6 +135396,7 @@
+ #define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
+ #define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
+ #define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
++#define WHERE_IN_EARLYOUT  0x00040000  /* Perhaps quit IN loops early */
+ 
+ /************** End of whereInt.h ********************************************/
+ /************** Continuing where we left off in wherecode.c ******************/
+@@ -127872,23 +135432,23 @@
+   int i;
+ 
+   assert( nTerm>=1 );
+-  if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
++  if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
+ 
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
+   for(i=0; i<nTerm; i++){
+-    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+-    sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
++    if( i ) sqlite3_str_append(pStr, ",", 1);
++    sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
+   }
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
+ 
+-  sqlite3StrAccumAppend(pStr, zOp, 1);
++  sqlite3_str_append(pStr, zOp, 1);
+ 
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
+   for(i=0; i<nTerm; i++){
+-    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+-    sqlite3StrAccumAppend(pStr, "?", 1);
++    if( i ) sqlite3_str_append(pStr, ",", 1);
++    sqlite3_str_append(pStr, "?", 1);
+   }
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
+ }
+ 
+ /*
+@@ -127912,11 +135472,11 @@
+   int i, j;
+ 
+   if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
+-  sqlite3StrAccumAppend(pStr, " (", 2);
++  sqlite3_str_append(pStr, " (", 2);
+   for(i=0; i<nEq; i++){
+     const char *z = explainIndexColumnName(pIndex, i);
+-    if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+-    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
++    if( i ) sqlite3_str_append(pStr, " AND ", 5);
++    sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
+   }
+ 
+   j = i;
+@@ -127927,7 +135487,7 @@
+   if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
+     explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
+   }
+-  sqlite3StrAccumAppend(pStr, ")", 1);
++  sqlite3_str_append(pStr, ")", 1);
+ }
+ 
+ /*
+@@ -127943,19 +135503,16 @@
+   Parse *pParse,                  /* Parse context */
+   SrcList *pTabList,              /* Table list this loop refers to */
+   WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
+-  int iLevel,                     /* Value for "level" column of output */
+-  int iFrom,                      /* Value for "from" column of output */
+   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
+ ){
+   int ret = 0;
+ #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+-  if( pParse->explain==2 )
++  if( sqlite3ParseToplevel(pParse)->explain==2 )
+ #endif
+   {
+     struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
+     Vdbe *v = pParse->pVdbe;      /* VM being constructed */
+     sqlite3 *db = pParse->db;     /* Database handle */
+-    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
+     int isSearch;                 /* True for a SEARCH. False for SCAN. */
+     WhereLoop *pLoop;             /* The controlling WhereLoop object */
+     u32 flags;                    /* Flags that describe this loop */
+@@ -127972,15 +135529,15 @@
+             || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+ 
+     sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+-    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
++    sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
+     if( pItem->pSelect ){
+-      sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
++      sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId);
+     }else{
+-      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
++      sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
+     }
+ 
+     if( pItem->zAlias ){
+-      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
++      sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
+     }
+     if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
+       const char *zFmt = 0;
+@@ -128003,8 +135560,8 @@
+         zFmt = "INDEX %s";
+       }
+       if( zFmt ){
+-        sqlite3StrAccumAppend(&str, " USING ", 7);
+-        sqlite3XPrintf(&str, zFmt, pIdx->zName);
++        sqlite3_str_append(&str, " USING ", 7);
++        sqlite3_str_appendf(&str, zFmt, pIdx->zName);
+         explainIndexRange(&str, pLoop);
+       }
+     }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
+@@ -128019,23 +135576,26 @@
+         assert( flags&WHERE_TOP_LIMIT);
+         zRangeOp = "<";
+       }
+-      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
++      sqlite3_str_appendf(&str, 
++          " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
+     }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
+-      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
++      sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
+                   pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
+     }
+ #endif
+ #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
+     if( pLoop->nOut>=10 ){
+-      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
++      sqlite3_str_appendf(&str, " (~%llu rows)",
++             sqlite3LogEstToInt(pLoop->nOut));
+     }else{
+-      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
++      sqlite3_str_append(&str, " (~1 row)", 9);
+     }
+ #endif
+     zMsg = sqlite3StrAccumFinish(&str);
+-    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
++    ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
++                            pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
+   }
+   return ret;
+ }
+@@ -128115,8 +135675,8 @@
+ */
+ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
+   int nLoop = 0;
+-  while( ALWAYS(pTerm!=0)
+-      && (pTerm->wtFlags & TERM_CODED)==0
++  assert( pTerm!=0 );
++  while( (pTerm->wtFlags & TERM_CODED)==0
+       && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+       && (pLevel->notReady & pTerm->prereqAll)==0
+   ){
+@@ -128127,6 +135687,7 @@
+     }
+     if( pTerm->iParent<0 ) break;
+     pTerm = &pTerm->pWC->a[pTerm->iParent];
++    assert( pTerm!=0 );
+     pTerm->nChild--;
+     if( pTerm->nChild!=0 ) break;
+     nLoop++;
+@@ -128167,7 +135728,6 @@
+   /* Code the OP_Affinity opcode if there is anything left to do. */
+   if( n>0 ){
+     sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
+-    sqlite3ExprCacheAffinityChange(pParse, base, n);
+   }
+ }
+ 
+@@ -128197,7 +135757,103 @@
+   }
+ }
+ 
++
+ /*
++** pX is an expression of the form:  (vector) IN (SELECT ...)
++** In other words, it is a vector IN operator with a SELECT clause on the
++** LHS.  But not all terms in the vector are indexable and the terms might
++** not be in the correct order for indexing.
++**
++** This routine makes a copy of the input pX expression and then adjusts
++** the vector on the LHS with corresponding changes to the SELECT so that
++** the vector contains only index terms and those terms are in the correct
++** order.  The modified IN expression is returned.  The caller is responsible
++** for deleting the returned expression.
++**
++** Example:
++**
++**    CREATE TABLE t1(a,b,c,d,e,f);
++**    CREATE INDEX t1x1 ON t1(e,c);
++**    SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2)
++**                           \_______________________________________/
++**                                     The pX expression
++**
++** Since only columns e and c can be used with the index, in that order,
++** the modified IN expression that is returned will be:
++**
++**        (e,c) IN (SELECT z,x FROM t2)
++**
++** The reduced pX is different from the original (obviously) and thus is
++** only used for indexing, to improve performance.  The original unaltered
++** IN expression must also be run on each output row for correctness.
++*/
++static Expr *removeUnindexableInClauseTerms(
++  Parse *pParse,        /* The parsing context */
++  int iEq,              /* Look at loop terms starting here */
++  WhereLoop *pLoop,     /* The current loop */
++  Expr *pX              /* The IN expression to be reduced */
++){
++  sqlite3 *db = pParse->db;
++  Expr *pNew = sqlite3ExprDup(db, pX, 0);
++  if( db->mallocFailed==0 ){
++    ExprList *pOrigRhs = pNew->x.pSelect->pEList;  /* Original unmodified RHS */
++    ExprList *pOrigLhs = pNew->pLeft->x.pList;     /* Original unmodified LHS */
++    ExprList *pRhs = 0;         /* New RHS after modifications */
++    ExprList *pLhs = 0;         /* New LHS after mods */
++    int i;                      /* Loop counter */
++    Select *pSelect;            /* Pointer to the SELECT on the RHS */
++
++    for(i=iEq; i<pLoop->nLTerm; i++){
++      if( pLoop->aLTerm[i]->pExpr==pX ){
++        int iField = pLoop->aLTerm[i]->iField - 1;
++        if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
++        pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
++        pOrigRhs->a[iField].pExpr = 0;
++        assert( pOrigLhs->a[iField].pExpr!=0 );
++        pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
++        pOrigLhs->a[iField].pExpr = 0;
++      }
++    }
++    sqlite3ExprListDelete(db, pOrigRhs);
++    sqlite3ExprListDelete(db, pOrigLhs);
++    pNew->pLeft->x.pList = pLhs;
++    pNew->x.pSelect->pEList = pRhs;
++    if( pLhs && pLhs->nExpr==1 ){
++      /* Take care here not to generate a TK_VECTOR containing only a
++      ** single value. Since the parser never creates such a vector, some
++      ** of the subroutines do not handle this case.  */
++      Expr *p = pLhs->a[0].pExpr;
++      pLhs->a[0].pExpr = 0;
++      sqlite3ExprDelete(db, pNew->pLeft);
++      pNew->pLeft = p;
++    }
++    pSelect = pNew->x.pSelect;
++    if( pSelect->pOrderBy ){
++      /* If the SELECT statement has an ORDER BY clause, zero the 
++      ** iOrderByCol variables. These are set to non-zero when an 
++      ** ORDER BY term exactly matches one of the terms of the 
++      ** result-set. Since the result-set of the SELECT statement may
++      ** have been modified or reordered, these variables are no longer 
++      ** set correctly.  Since setting them is just an optimization, 
++      ** it's easiest just to zero them here.  */
++      ExprList *pOrderBy = pSelect->pOrderBy;
++      for(i=0; i<pOrderBy->nExpr; i++){
++        pOrderBy->a[i].u.x.iOrderByCol = 0;
++      }
++    }
++
++#if 0
++    printf("For indexing, change the IN expr:\n");
++    sqlite3TreeViewExpr(0, pX, 0);
++    printf("Into:\n");
++    sqlite3TreeViewExpr(0, pNew, 0);
++#endif
++  }
++  return pNew;
++}
++
++
++/*
+ ** Generate code for a single equality term of the WHERE clause.  An equality
+ ** term can be either X=expr or X IN (...).   pTerm is the term to be 
+ ** coded.
+@@ -128259,68 +135915,23 @@
+       }
+     }
+     for(i=iEq;i<pLoop->nLTerm; i++){
+-      if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++;
++      assert( pLoop->aLTerm[i]!=0 );
++      if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+     }
+ 
+     if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
+       eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
+     }else{
+-      Select *pSelect = pX->x.pSelect;
+       sqlite3 *db = pParse->db;
+-      u16 savedDbOptFlags = db->dbOptFlags;
+-      ExprList *pOrigRhs = pSelect->pEList;
+-      ExprList *pOrigLhs = pX->pLeft->x.pList;
+-      ExprList *pRhs = 0;         /* New Select.pEList for RHS */
+-      ExprList *pLhs = 0;         /* New pX->pLeft vector */
++      pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
+ 
+-      for(i=iEq;i<pLoop->nLTerm; i++){
+-        if( pLoop->aLTerm[i]->pExpr==pX ){
+-          int iField = pLoop->aLTerm[i]->iField - 1;
+-          Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0);
+-          Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0);
+-
+-          pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs);
+-          pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs);
+-        }
+-      }
+       if( !db->mallocFailed ){
+-        Expr *pLeft = pX->pLeft;
+-
+-        if( pSelect->pOrderBy ){
+-          /* If the SELECT statement has an ORDER BY clause, zero the 
+-          ** iOrderByCol variables. These are set to non-zero when an 
+-          ** ORDER BY term exactly matches one of the terms of the 
+-          ** result-set. Since the result-set of the SELECT statement may
+-          ** have been modified or reordered, these variables are no longer 
+-          ** set correctly.  Since setting them is just an optimization, 
+-          ** it's easiest just to zero them here.  */
+-          ExprList *pOrderBy = pSelect->pOrderBy;
+-          for(i=0; i<pOrderBy->nExpr; i++){
+-            pOrderBy->a[i].u.x.iOrderByCol = 0;
+-          }
+-        }
+-
+-        /* Take care here not to generate a TK_VECTOR containing only a
+-        ** single value. Since the parser never creates such a vector, some
+-        ** of the subroutines do not handle this case.  */
+-        if( pLhs->nExpr==1 ){
+-          pX->pLeft = pLhs->a[0].pExpr;
+-        }else{
+-          pLeft->x.pList = pLhs;
+-          aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq);
+-          testcase( aiMap==0 );
+-        }
+-        pSelect->pEList = pRhs;
+-        db->dbOptFlags |= SQLITE_QueryFlattener;
++        aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
+         eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
+-        db->dbOptFlags = savedDbOptFlags;
+-        testcase( aiMap!=0 && aiMap[0]!=0 );
+-        pSelect->pEList = pOrigRhs;
+-        pLeft->x.pList = pOrigLhs;
+-        pX->pLeft = pLeft;
++        pTerm->pExpr->iTable = pX->iTable;
+       }
+-      sqlite3ExprListDelete(pParse->db, pLhs);
+-      sqlite3ExprListDelete(pParse->db, pRhs);
++      sqlite3ExprDelete(db, pX);
++      pX = pTerm->pExpr;
+     }
+ 
+     if( eType==IN_INDEX_INDEX_DESC ){
+@@ -128360,7 +135971,14 @@
+           sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
+           if( i==iEq ){
+             pIn->iCur = iTab;
+-            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
++            pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
++            if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
++              pIn->iBase = iReg - i;
++              pIn->nPrefix = i;
++              pLoop->wsFlags |= WHERE_IN_EARLYOUT;
++            }else{
++              pIn->nPrefix = 0;
++            }
+           }else{
+             pIn->eEndLoopOp = OP_Noop;
+           }
+@@ -128615,7 +136233,7 @@
+     pWalker->eCode = 1;
+   }else if( pExpr->op==TK_FUNCTION ){
+     int d1;
+-    char d2[3];
++    char d2[4];
+     if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
+       pWalker->eCode = 1;
+     }
+@@ -128647,11 +136265,8 @@
+   struct CCurHint *pHint = pWalker->u.pCCurHint;
+   if( pExpr->op==TK_COLUMN ){
+     if( pExpr->iTable!=pHint->iTabCur ){
+-      Vdbe *v = pWalker->pParse->pVdbe;
+       int reg = ++pWalker->pParse->nMem;   /* Register for column value */
+-      sqlite3ExprCodeGetColumnOfTable(
+-          v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
+-      );
++      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
+       pExpr->op = TK_REGISTER;
+       pExpr->iTable = reg;
+     }else if( pHint->pIdx!=0 ){
+@@ -128838,7 +136453,7 @@
+ */
+ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
+   assert( nReg>0 );
+-  if( sqlite3ExprIsVector(p) ){
++  if( p && sqlite3ExprIsVector(p) ){
+ #ifndef SQLITE_OMIT_SUBQUERY
+     if( (p->flags & EP_xIsSelect) ){
+       Vdbe *v = pParse->pVdbe;
+@@ -128883,7 +136498,7 @@
+     pExpr->op = TK_COLUMN;
+     pExpr->iTable = pX->iIdxCur;
+     pExpr->iColumn = pX->iIdxCol;
+-    pExpr->pTab = 0;
++    pExpr->y.pTab = 0;
+     return WRC_Prune;
+   }else{
+     return WRC_Continue;
+@@ -128891,9 +136506,9 @@
+ }
+ 
+ /*
+-** For an indexes on expression X, locate every instance of expression X in pExpr
+-** and change that subexpression into a reference to the appropriate column of
+-** the index.
++** For an indexes on expression X, locate every instance of expression X
++** in pExpr and change that subexpression into a reference to the appropriate
++** column of the index.
+ */
+ static void whereIndexExprTrans(
+   Index *pIdx,      /* The Index */
+@@ -128984,6 +136599,9 @@
+   ** initialize a memory cell that records if this table matches any
+   ** row of the left table of the join.
+   */
++  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
++       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
++  );
+   if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
+     pLevel->iLeftJoin = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
+@@ -129001,7 +136619,7 @@
+     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));
++    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+     pLevel->op = OP_Goto;
+   }else
+ 
+@@ -129015,7 +136633,6 @@
+     int nConstraint = pLoop->nLTerm;
+     int iIn;    /* Counter for IN constraints */
+ 
+-    sqlite3ExprCachePush(pParse);
+     iReg = sqlite3GetTempRange(pParse, nConstraint+2);
+     addrNotFound = pLevel->addrBrk;
+     for(j=0; j<nConstraint; j++){
+@@ -129088,7 +136705,6 @@
+     **
+     **    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+     */
+-    sqlite3ExprCachePop(pParse);
+   }else
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+@@ -129112,9 +136728,6 @@
+     addrNxt = pLevel->addrNxt;
+     sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
+     VdbeCoverage(v);
+-    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
+-    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+-    VdbeComment((v, "pk"));
+     pLevel->op = OP_Noop;
+   }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+          && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+@@ -129164,7 +136777,15 @@
+       if( sqlite3ExprIsVector(pX->pRight) ){
+         r1 = rTemp = sqlite3GetTempReg(pParse);
+         codeExprOrVector(pParse, pX->pRight, r1, 1);
+-        op = aMoveOp[(pX->op - TK_GT) | 0x0001];
++        testcase( pX->op==TK_GT );
++        testcase( pX->op==TK_GE );
++        testcase( pX->op==TK_LT );
++        testcase( pX->op==TK_LE );
++        op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1];
++        assert( pX->op!=TK_GT || op==OP_SeekGE );
++        assert( pX->op!=TK_GE || op==OP_SeekGE );
++        assert( pX->op!=TK_LT || op==OP_SeekLE );
++        assert( pX->op!=TK_LE || op==OP_SeekLE );
+       }else{
+         r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+         disableTerm(pLevel, pStart);
+@@ -129176,7 +136797,6 @@
+       VdbeCoverageIf(v, pX->op==TK_LE);
+       VdbeCoverageIf(v, pX->op==TK_LT);
+       VdbeCoverageIf(v, pX->op==TK_GE);
+-      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+       sqlite3ReleaseTempReg(pParse, rTemp);
+     }else{
+       sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
+@@ -129211,7 +136831,6 @@
+     if( testOp!=OP_Noop ){
+       iRowidReg = ++pParse->nMem;
+       sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
+-      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+       sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
+       VdbeCoverageIf(v, testOp==OP_Le);
+       VdbeCoverageIf(v, testOp==OP_Lt);
+@@ -129416,6 +137035,9 @@
+       ** above has already left the cursor sitting on the correct row,
+       ** so no further seeking is needed */
+     }else{
++      if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
++        sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
++      }
+       op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+       assert( op!=0 );
+       sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+@@ -129434,7 +137056,6 @@
+     nConstraint = nEq;
+     if( pRangeEnd ){
+       Expr *pRight = pRangeEnd->pExpr->pRight;
+-      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
+       codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
+       whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
+       if( (pRangeEnd->wtFlags & TERM_VNULL)==0
+@@ -129478,6 +137099,10 @@
+       testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
+     }
+ 
++    if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
++      sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
++    }
++
+     /* Seek the table cursor, if required */
+     if( omitTable ){
+       /* pIdx is a covering index.  No need to access the main table. */
+@@ -129488,7 +137113,6 @@
+       )){
+         iRowidReg = ++pParse->nMem;
+         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
+-        sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+         sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
+         VdbeCoverage(v);
+       }else{
+@@ -129508,10 +137132,17 @@
+     /* If pIdx is an index on one or more expressions, then look through
+     ** all the expressions in pWInfo and try to transform matching expressions
+     ** into reference to index columns.
++    **
++    ** Do not do this for the RHS of a LEFT JOIN. This is because the 
++    ** expression may be evaluated after OP_NullRow has been executed on
++    ** the cursor. In this case it is important to do the full evaluation,
++    ** as the result of the expression may not be NULL, even if all table
++    ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
+     */
+-    whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
++    if( pLevel->iLeftJoin==0 ){
++      whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
++    }
+ 
+-
+     /* Record the instruction used to terminate the loop. */
+     if( pLoop->wsFlags & WHERE_ONEROW ){
+       pLevel->op = OP_Noop;
+@@ -129666,7 +137297,6 @@
+       for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
+         Expr *pExpr = pWC->a[iTerm].pExpr;
+         if( &pWC->a[iTerm] == pTerm ) continue;
+-        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
+         testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
+         testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
+         if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
+@@ -129685,6 +137315,7 @@
+     ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
+     */
+     wctrlFlags =  WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
++    ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
+     for(ii=0; ii<pOrWc->nTerm; ii++){
+       WhereTerm *pOrTerm = &pOrWc->a[ii];
+       if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
+@@ -129691,7 +137322,10 @@
+         WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
+         Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
+         int jmp1 = 0;                   /* Address of jump operation */
+-        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
++        assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 
++             || ExprHasProperty(pOrExpr, EP_FromJoin) 
++        );
++        if( pAndExpr ){
+           pAndExpr->pLeft = pOrExpr;
+           pOrExpr = pAndExpr;
+         }
+@@ -129703,7 +137337,7 @@
+         if( pSubWInfo ){
+           WhereLoop *pSubLoop;
+           int addrExplain = sqlite3WhereExplainOneScan(
+-              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
++              pParse, pOrTab, &pSubWInfo->a[0], 0
+           );
+           sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
+ 
+@@ -129713,23 +137347,23 @@
+           ** row will be skipped in subsequent sub-WHERE clauses.
+           */
+           if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+-            int r;
+             int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
+             if( HasRowid(pTab) ){
+-              r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
++              sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid);
+               jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
+-                                           r,iSet);
++                                          regRowid, iSet);
+               VdbeCoverage(v);
+             }else{
+               Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+               int nPk = pPk->nKeyCol;
+               int iPk;
++              int r;
+ 
+               /* Read the PK into an array of temp registers. */
+               r = sqlite3GetTempRange(pParse, nPk);
+               for(iPk=0; iPk<nPk; iPk++){
+                 int iCol = pPk->aiColumn[iPk];
+-                sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
++                sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk);
+               }
+ 
+               /* Check if the temp table already contains this key. If so,
+@@ -129802,6 +137436,7 @@
+         }
+       }
+     }
++    ExplainQueryPlanPop(pParse);
+     pLevel->u.pCovidx = pCov;
+     if( pCov ) pLevel->iIdxCur = iCovCur;
+     if( pAndExpr ){
+@@ -129874,7 +137509,7 @@
+       }
+       pE = pTerm->pExpr;
+       assert( pE!=0 );
+-      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
++      if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
+         continue;
+       }
+       
+@@ -129887,7 +137522,7 @@
+         continue;
+       }
+ 
+-      if( pTerm->wtFlags & TERM_LIKECOND ){
++      if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){
+         /* If the TERM_LIKECOND flag is set, that means that the range search
+         ** is sufficient to guarantee that the LIKE operator is true, so we
+         ** can skip the call to the like(A,B) function.  But this only works
+@@ -129897,8 +137532,9 @@
+         continue;
+ #else
+         u32 x = pLevel->iLikeRepCntr;
+-        assert( x>0 );
+-        skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1));
++        if( x>0 ){
++          skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
++        }
+         VdbeCoverage(v);
+ #endif
+       }
+@@ -129938,6 +137574,12 @@
+                     WO_EQ|WO_IN|WO_IS, 0);
+     if( pAlt==0 ) continue;
+     if( pAlt->wtFlags & (TERM_CODED) ) continue;
++    if( (pAlt->eOperator & WO_IN) 
++     && (pAlt->pExpr->flags & EP_xIsSelect)
++     && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
++    ){
++      continue;
++    }
+     testcase( pAlt->eOperator & WO_EQ );
+     testcase( pAlt->eOperator & WO_IS );
+     testcase( pAlt->eOperator & WO_IN );
+@@ -129954,7 +137596,6 @@
+     pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
+     sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
+     VdbeComment((v, "record LEFT JOIN hit"));
+-    sqlite3ExprCacheClear(pParse);
+     for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
+       testcase( pTerm->wtFlags & TERM_VIRTUAL );
+       testcase( pTerm->wtFlags & TERM_CODED );
+@@ -130170,18 +137811,18 @@
+   int *pisComplete, /* True if the only wildcard is % in the last character */
+   int *pnoCase      /* True if uppercase is equivalent to lowercase */
+ ){
+-  const char *z = 0;         /* String on RHS of LIKE operator */
++  const u8 *z = 0;           /* String on RHS of LIKE operator */
+   Expr *pRight, *pLeft;      /* Right and left size of LIKE operator */
+   ExprList *pList;           /* List of operands to the LIKE operator */
+-  int c;                     /* One character in z[] */
++  u8 c;                      /* One character in z[] */
+   int cnt;                   /* Number of non-wildcard prefix characters */
+-  char wc[3];                /* Wildcard characters */
++  u8 wc[4];                  /* Wildcard characters */
+   sqlite3 *db = pParse->db;  /* Database connection */
+   sqlite3_value *pVal = 0;
+   int op;                    /* Opcode of pRight */
+   int rc;                    /* Result code to return */
+ 
+-  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
++  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){
+     return 0;
+   }
+ #ifdef SQLITE_EBCDIC
+@@ -130197,41 +137838,78 @@
+     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);
++      z = 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;
++    z = (u8*)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;
+-      }
+-    }
++    /* Count the number of prefix characters prior to the first wildcard */
+     cnt = 0;
+     while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
+       cnt++;
++      if( c==wc[3] && z[cnt]!=0 ) cnt++;
+     }
+-    if( cnt!=0 && 255!=(u8)z[cnt-1] ){
++
++    /* The optimization is possible only if (1) the pattern does not begin
++    ** with a wildcard and if (2) the non-wildcard prefix does not end with
++    ** an (illegal 0xff) character, or (3) the pattern does not consist of
++    ** a single escape character. The second condition is necessary so
++    ** that we can increment the prefix key to find an upper bound for the
++    ** range search. The third is because the caller assumes that the pattern
++    ** consists of at least one character after all escapes have been
++    ** removed.  */
++    if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){
+       Expr *pPrefix;
++
++      /* A "complete" match if the pattern ends with "*" or "%" */
+       *pisComplete = c==wc[0] && z[cnt+1]==0;
+-      pPrefix = sqlite3Expr(db, TK_STRING, z);
+-      if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
++
++      /* Get the pattern prefix.  Remove all escapes from the prefix. */
++      pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
++      if( pPrefix ){
++        int iFrom, iTo;
++        char *zNew = pPrefix->u.zToken;
++        zNew[cnt] = 0;
++        for(iFrom=iTo=0; iFrom<cnt; iFrom++){
++          if( zNew[iFrom]==wc[3] ) iFrom++;
++          zNew[iTo++] = zNew[iFrom];
++        }
++        zNew[iTo] = 0;
++
++        /* 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.
++        **
++        ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
++        ** The RHS pattern must not be '/%' because the termination condition
++        ** will then become "x<'0'" and if the affinity is numeric, will then
++        ** be converted into "x<0", which is incorrect.
++        */
++        if( sqlite3Isdigit(zNew[0])
++         || zNew[0]=='-'
++         || (zNew[0]+1=='0' && iTo==1)
++        ){
++          if( pLeft->op!=TK_COLUMN 
++           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
++           || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
++          ){
++            sqlite3ExprDelete(db, pPrefix);
++            sqlite3ValueFree(pVal);
++            return 0;
++          }
++        }
++      }
+       *ppPrefix = pPrefix;
++
++      /* If the RHS pattern is a bound parameter, make arrangements to
++      ** reprepare the statement when that parameter is rebound */
+       if( op==TK_VARIABLE ){
+         Vdbe *v = pParse->pVdbe;
+         sqlite3VdbeSetVarmask(v, pRight->iColumn);
+@@ -130262,48 +137940,123 @@
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ /*
+-** Check to see if the given expression is of the form
++** Check to see if the pExpr expression is a form that needs to be passed
++** to the xBestIndex method of virtual tables.  Forms of interest include:
+ **
+-**         column OP expr
++**          Expression                   Virtual Table Operator
++**          -----------------------      ---------------------------------
++**      1.  column MATCH expr            SQLITE_INDEX_CONSTRAINT_MATCH
++**      2.  column GLOB expr             SQLITE_INDEX_CONSTRAINT_GLOB
++**      3.  column LIKE expr             SQLITE_INDEX_CONSTRAINT_LIKE
++**      4.  column REGEXP expr           SQLITE_INDEX_CONSTRAINT_REGEXP
++**      5.  column != expr               SQLITE_INDEX_CONSTRAINT_NE
++**      6.  expr != column               SQLITE_INDEX_CONSTRAINT_NE
++**      7.  column IS NOT expr           SQLITE_INDEX_CONSTRAINT_ISNOT
++**      8.  expr IS NOT column           SQLITE_INDEX_CONSTRAINT_ISNOT
++**      9.  column IS NOT NULL           SQLITE_INDEX_CONSTRAINT_ISNOTNULL
+ **
+-** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a 
+-** column of a virtual table.
++** In every case, "column" must be a column of a virtual table.  If there
++** is a match, set *ppLeft to the "column" expression, set *ppRight to the 
++** "expr" expression (even though in forms (6) and (8) the column is on the
++** right and the expression is on the left).  Also set *peOp2 to the
++** appropriate virtual table operator.  The return value is 1 or 2 if there
++** is a match.  The usual return is 1, but if the RHS is also a column
++** of virtual table in forms (5) or (7) then return 2.
+ **
+-** If it is then return TRUE.  If not, return FALSE.
++** If the expression matches none of the patterns above, return 0.
+ */
+-static int isMatchOfColumn(
++static int isAuxiliaryVtabOperator(
++  sqlite3 *db,                    /* Parsing context */
+   Expr *pExpr,                    /* Test this expression */
+-  unsigned char *peOp2            /* OUT: 0 for MATCH, or else an op2 value */
++  unsigned char *peOp2,           /* OUT: 0 for MATCH, or else an op2 value */
++  Expr **ppLeft,                  /* Column expression to left of MATCH/op2 */
++  Expr **ppRight                  /* Expression to left of MATCH/op2 */
+ ){
+-  static const struct Op2 {
+-    const char *zOp;
+-    unsigned char eOp2;
+-  } aOp[] = {
+-    { "match",  SQLITE_INDEX_CONSTRAINT_MATCH },
+-    { "glob",   SQLITE_INDEX_CONSTRAINT_GLOB },
+-    { "like",   SQLITE_INDEX_CONSTRAINT_LIKE },
+-    { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
+-  };
+-  ExprList *pList;
+-  Expr *pCol;                     /* Column reference */
+-  int i;
++  if( pExpr->op==TK_FUNCTION ){
++    static const struct Op2 {
++      const char *zOp;
++      unsigned char eOp2;
++    } aOp[] = {
++      { "match",  SQLITE_INDEX_CONSTRAINT_MATCH },
++      { "glob",   SQLITE_INDEX_CONSTRAINT_GLOB },
++      { "like",   SQLITE_INDEX_CONSTRAINT_LIKE },
++      { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
++    };
++    ExprList *pList;
++    Expr *pCol;                     /* Column reference */
++    int i;
+ 
+-  if( pExpr->op!=TK_FUNCTION ){
+-    return 0;
+-  }
+-  pList = pExpr->x.pList;
+-  if( pList==0 || pList->nExpr!=2 ){
+-    return 0;
+-  }
+-  pCol = pList->a[1].pExpr;
+-  if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
+-    return 0;
+-  }
+-  for(i=0; i<ArraySize(aOp); i++){
+-    if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+-      *peOp2 = aOp[i].eOp2;
+-      return 1;
++    pList = pExpr->x.pList;
++    if( pList==0 || pList->nExpr!=2 ){
++      return 0;
+     }
++
++    /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
++    ** virtual table on their second argument, which is the same as
++    ** the left-hand side operand in their in-fix form.
++    **
++    **       vtab_column MATCH expression
++    **       MATCH(expression,vtab_column)
++    */
++    pCol = pList->a[1].pExpr;
++    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
++      for(i=0; i<ArraySize(aOp); i++){
++        if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
++          *peOp2 = aOp[i].eOp2;
++          *ppRight = pList->a[0].pExpr;
++          *ppLeft = pCol;
++          return 1;
++        }
++      }
++    }
++
++    /* We can also match against the first column of overloaded
++    ** functions where xFindFunction returns a value of at least
++    ** SQLITE_INDEX_CONSTRAINT_FUNCTION.
++    **
++    **      OVERLOADED(vtab_column,expression)
++    **
++    ** Historically, xFindFunction expected to see lower-case function
++    ** names.  But for this use case, xFindFunction is expected to deal
++    ** with function names in an arbitrary case.
++    */
++    pCol = pList->a[0].pExpr;
++    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
++      sqlite3_vtab *pVtab;
++      sqlite3_module *pMod;
++      void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
++      void *pNotUsed;
++      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
++      assert( pVtab!=0 );
++      assert( pVtab->pModule!=0 );
++      pMod = (sqlite3_module *)pVtab->pModule;
++      if( pMod->xFindFunction!=0 ){
++        i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
++        if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
++          *peOp2 = i;
++          *ppRight = pList->a[1].pExpr;
++          *ppLeft = pCol;
++          return 1;
++        }
++      }
++    }
++  }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
++    int res = 0;
++    Expr *pLeft = pExpr->pLeft;
++    Expr *pRight = pExpr->pRight;
++    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
++      res++;
++    }
++    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
++      res++;
++      SWAP(Expr*, pLeft, pRight);
++    }
++    *ppLeft = pLeft;
++    *ppRight = pRight;
++    if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE;
++    if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT;
++    if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
++    return res;
+   }
+   return 0;
+ }
+@@ -130554,7 +138307,7 @@
+           for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
+             assert( pAndTerm->pExpr );
+             if( allowedOp(pAndTerm->pExpr->op) 
+-             || pAndTerm->eOperator==WO_MATCH 
++             || pAndTerm->eOperator==WO_AUX
+             ){
+               b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
+             }
+@@ -130586,7 +138339,12 @@
+   ** empty.
+   */
+   pOrInfo->indexable = indexable;
+-  pTerm->eOperator = indexable==0 ? 0 : WO_OR;
++  if( indexable ){
++    pTerm->eOperator = WO_OR;
++    pWC->hasOr = 1;
++  }else{
++    pTerm->eOperator = WO_OR;
++  }
+ 
+   /* For a two-way OR, attempt to implementation case 2.
+   */
+@@ -130727,12 +138485,11 @@
+         idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+         testcase( idxNew==0 );
+         exprAnalyze(pSrc, pWC, idxNew);
+-        pTerm = &pWC->a[idxTerm];
++        /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
+         markTermAsChild(pWC, idxNew, idxTerm);
+       }else{
+         sqlite3ExprListDelete(db, pList);
+       }
+-      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 3 */
+     }
+   }
+ }
+@@ -130756,7 +138513,6 @@
+ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
+   char aff1, aff2;
+   CollSeq *pColl;
+-  const char *zColl1, *zColl2;
+   if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
+   if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
+   if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
+@@ -130768,12 +138524,8 @@
+     return 0;
+   }
+   pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
+-  if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
+-  pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+-  zColl1 = pColl ? pColl->zName : 0;
+-  pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
+-  zColl2 = pColl ? pColl->zName : 0;
+-  return sqlite3_stricmp(zColl1, zColl2)==0;
++  if( sqlite3IsBinary(pColl) ) return 1;
++  return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
+ }
+ 
+ /*
+@@ -130795,6 +138547,9 @@
+       for(i=0; i<pSrc->nSrc; i++){
+         mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
+         mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
++        if( pSrc->a[i].fg.isTabFunc ){
++          mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
++        }
+       }
+     }
+     pS = pS->pPrior;
+@@ -130902,7 +138657,7 @@
+   int op;                          /* Top-level operator.  pExpr->op */
+   Parse *pParse = pWInfo->pParse;  /* Parsing context */
+   sqlite3 *db = pParse->db;        /* Database connection */
+-  unsigned char eOp2;              /* op2 value for LIKE/REGEXP/GLOB */
++  unsigned char eOp2 = 0;          /* op2 value for LIKE/REGEXP/GLOB */
+   int nLeft;                       /* Number of elements on left side vector */
+ 
+   if( db->mallocFailed ){
+@@ -130928,7 +138683,7 @@
+     pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
+   }
+   pMaskSet->bVarSelect = 0;
+-  prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
++  prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
+   if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
+   if( ExprHasProperty(pExpr, EP_FromJoin) ){
+     Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
+@@ -131110,7 +138865,7 @@
+       }
+       *pC = c + 1;
+     }
+-    zCollSeqName = noCase ? "NOCASE" : "BINARY";
++    zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY;
+     pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
+     pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+            sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
+@@ -131136,41 +138891,46 @@
+ #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
+ 
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  /* Add a WO_MATCH auxiliary term to the constraint set if the
+-  ** current expression is of the form:  column MATCH expr.
++  /* Add a WO_AUX auxiliary term to the constraint set if the
++  ** current expression is of the form "column OP expr" where OP
++  ** is an operator that gets passed into virtual tables but which is
++  ** not normally optimized for ordinary tables.  In other words, OP
++  ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL.
+   ** This information is used by the xBestIndex methods of
+   ** virtual tables.  The native query optimizer does not attempt
+   ** to do anything with MATCH functions.
+   */
+-  if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){
+-    int idxNew;
+-    Expr *pRight, *pLeft;
+-    WhereTerm *pNewTerm;
+-    Bitmask prereqColumn, prereqExpr;
++  if( pWC->op==TK_AND ){
++    Expr *pRight = 0, *pLeft = 0;
++    int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
++    while( res-- > 0 ){
++      int idxNew;
++      WhereTerm *pNewTerm;
++      Bitmask prereqColumn, prereqExpr;
+ 
+-    pRight = pExpr->x.pList->a[0].pExpr;
+-    pLeft = pExpr->x.pList->a[1].pExpr;
+-    prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
+-    prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
+-    if( (prereqExpr & prereqColumn)==0 ){
+-      Expr *pNewExpr;
+-      pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
+-                              0, sqlite3ExprDup(db, pRight, 0));
+-      if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
+-        ExprSetProperty(pNewExpr, EP_FromJoin);
++      prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
++      prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
++      if( (prereqExpr & prereqColumn)==0 ){
++        Expr *pNewExpr;
++        pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 
++            0, sqlite3ExprDup(db, pRight, 0));
++        if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
++          ExprSetProperty(pNewExpr, EP_FromJoin);
++        }
++        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
++        testcase( idxNew==0 );
++        pNewTerm = &pWC->a[idxNew];
++        pNewTerm->prereqRight = prereqExpr;
++        pNewTerm->leftCursor = pLeft->iTable;
++        pNewTerm->u.leftColumn = pLeft->iColumn;
++        pNewTerm->eOperator = WO_AUX;
++        pNewTerm->eMatchOp = eOp2;
++        markTermAsChild(pWC, idxNew, idxTerm);
++        pTerm = &pWC->a[idxTerm];
++        pTerm->wtFlags |= TERM_COPIED;
++        pNewTerm->prereqAll = pTerm->prereqAll;
+       }
+-      idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+-      testcase( idxNew==0 );
+-      pNewTerm = &pWC->a[idxNew];
+-      pNewTerm->prereqRight = prereqExpr;
+-      pNewTerm->leftCursor = pLeft->iTable;
+-      pNewTerm->u.leftColumn = pLeft->iColumn;
+-      pNewTerm->eOperator = WO_MATCH;
+-      pNewTerm->eMatchOp = eOp2;
+-      markTermAsChild(pWC, idxNew, idxTerm);
+-      pTerm = &pWC->a[idxTerm];
+-      pTerm->wtFlags |= TERM_COPIED;
+-      pNewTerm->prereqAll = pTerm->prereqAll;
++      SWAP(Expr*, pLeft, pRight);
+     }
+   }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -131202,7 +138962,7 @@
+       exprAnalyze(pSrc, pWC, idxNew);
+     }
+     pTerm = &pWC->a[idxTerm];
+-    pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
++    pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
+     pTerm->eOperator = 0;
+   }
+ 
+@@ -131239,6 +138999,7 @@
+   if( pExpr->op==TK_NOTNULL
+    && pExpr->pLeft->op==TK_COLUMN
+    && pExpr->pLeft->iColumn>=0
++   && !ExprHasProperty(pExpr, EP_FromJoin)
+    && OptimizationEnabled(db, SQLITE_Stat34)
+   ){
+     Expr *pNewExpr;
+@@ -131316,6 +139077,7 @@
+   WhereInfo *pWInfo        /* The WHERE processing context */
+ ){
+   pWC->pWInfo = pWInfo;
++  pWC->hasOr = 0;
+   pWC->pOuter = 0;
+   pWC->nTerm = 0;
+   pWC->nSlot = ArraySize(pWC->aStatic);
+@@ -131352,17 +139114,18 @@
+ ** a bitmask indicating which tables are used in that expression
+ ** tree.
+ */
+-SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
+   Bitmask mask;
+-  if( p==0 ) return 0;
+-  if( p->op==TK_COLUMN ){
++  if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
+     return sqlite3WhereGetMask(pMaskSet, p->iTable);
++  }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
++    assert( p->op!=TK_IF_NULL_ROW );
++    return 0;
+   }
+   mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
+-  assert( !ExprHasProperty(p, EP_TokenOnly) );
+-  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
++  if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
+   if( p->pRight ){
+-    mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
++    mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
+     assert( p->x.pList==0 );
+   }else if( ExprHasProperty(p, EP_xIsSelect) ){
+     if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
+@@ -131372,6 +139135,9 @@
+   }
+   return mask;
+ }
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
++  return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
++}
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
+   int i;
+   Bitmask mask = 0;
+@@ -131425,6 +139191,7 @@
+   pArgs = pItem->u1.pFuncArg;
+   if( pArgs==0 ) return;
+   for(j=k=0; j<pArgs->nExpr; j++){
++    Expr *pRhs;
+     while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
+     if( k>=pTab->nCol ){
+       sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
+@@ -131435,9 +139202,10 @@
+     if( pColRef==0 ) return;
+     pColRef->iTable = pItem->iCursor;
+     pColRef->iColumn = k++;
+-    pColRef->pTab = pTab;
+-    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
+-                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
++    pColRef->y.pTab = pTab;
++    pRhs = sqlite3PExpr(pParse, TK_UPLUS, 
++        sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
++    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
+     whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+   }
+ }
+@@ -131465,6 +139233,21 @@
+ /* #include "sqliteInt.h" */
+ /* #include "whereInt.h" */
+ 
++/*
++** Extra information appended to the end of sqlite3_index_info but not
++** visible to the xBestIndex function, at least not directly.  The
++** sqlite3_vtab_collation() interface knows how to reach it, however.
++**
++** This object is not an API and can be changed from one release to the
++** next.  As long as allocateIndexInfo() and sqlite3_vtab_collation()
++** agree on the structure, all will be well.
++*/
++typedef struct HiddenIndexInfo HiddenIndexInfo;
++struct HiddenIndexInfo {
++  WhereClause *pWC;   /* The Where clause being analyzed */
++  Parse *pParse;      /* The parsing context */
++};
++
+ /* Forward declaration of methods */
+ static int whereLoopResize(sqlite3*, WhereLoop*, int);
+ 
+@@ -131498,15 +139281,38 @@
+ }
+ 
+ /*
+-** Return TRUE if the innermost loop of the WHERE clause implementation
+-** returns rows in ORDER BY order for complete run of the inner loop.
++** In the ORDER BY LIMIT optimization, if the inner-most loop is known
++** to emit rows in increasing order, and if the last row emitted by the
++** inner-most loop did not fit within the sorter, then we can skip all
++** subsequent rows for the current iteration of the inner loop (because they
++** will not fit in the sorter either) and continue with the second inner
++** loop - the loop immediately outside the inner-most.
+ **
+-** Across multiple iterations of outer loops, the output rows need not be
+-** sorted.  As long as rows are sorted for just the innermost loop, this
+-** routine can return TRUE.
++** When a row does not fit in the sorter (because the sorter already
++** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
++** label returned by this function.
++**
++** If the ORDER BY LIMIT optimization applies, the jump destination should
++** be the continuation for the second-inner-most loop.  If the ORDER BY
++** LIMIT optimization does not apply, then the jump destination should
++** be the continuation for the inner-most loop.
++**
++** It is always safe for this routine to return the continuation of the
++** inner-most loop, in the sense that a correct answer will result.  
++** Returning the continuation the second inner loop is an optimization
++** that might make the code run a little faster, but should not change
++** the final answer.
+ */
+-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){
+-  return pWInfo->bOrderedInnerLoop;
++SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
++  WhereLevel *pInner;
++  if( !pWInfo->bOrderedInnerLoop ){
++    /* The ORDER BY LIMIT optimization does not apply.  Jump to the 
++    ** continuation of the inner-most loop. */
++    return pWInfo->iContinue;
++  }
++  pInner = &pWInfo->a[pWInfo->nLevel-1];
++  assert( pInner->addrNxt!=0 );
++  return pInner->addrNxt;
+ }
+ 
+ /*
+@@ -131849,8 +139655,8 @@
+      && p->iColumn==pIdx->aiColumn[iCol]
+      && p->iTable==iBase
+     ){
+-      CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
+-      if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
++      CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
++      if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
+         return i;
+       }
+     }
+@@ -132233,7 +140039,6 @@
+   VdbeComment((v, "for %s", pTable->zName));
+ 
+   /* Fill the automatic index with content */
+-  sqlite3ExprCachePush(pParse);
+   pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
+   if( pTabItem->fg.viaCoroutine ){
+     int regYield = pTabItem->regReturn;
+@@ -132241,7 +140046,7 @@
+     sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+     addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
+     VdbeCoverage(v);
+-    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
++    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+   }else{
+     addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
+   }
+@@ -132263,7 +140068,6 @@
+     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);
+   }
+@@ -132270,7 +140074,6 @@
+   sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
+   sqlite3VdbeJumpHere(v, addrTop);
+   sqlite3ReleaseTempReg(pParse, regRecord);
+-  sqlite3ExprCachePop(pParse);
+   
+   /* Jump here when skipping the initialization */
+   sqlite3VdbeJumpHere(v, addrInit);
+@@ -132287,11 +140090,11 @@
+ ** by passing the pointer returned by this function to sqlite3_free().
+ */
+ static sqlite3_index_info *allocateIndexInfo(
+-  Parse *pParse,
+-  WhereClause *pWC,
++  Parse *pParse,                  /* The parsing context */
++  WhereClause *pWC,               /* The WHERE clause being analyzed */
+   Bitmask mUnusable,              /* Ignore terms with these prereqs */
+-  struct SrcList_item *pSrc,
+-  ExprList *pOrderBy,
++  struct SrcList_item *pSrc,      /* The FROM clause term that is the vtab */
++  ExprList *pOrderBy,             /* The ORDER BY clause */
+   u16 *pmNoOmit                   /* Mask of terms not to omit */
+ ){
+   int i, j;
+@@ -132299,6 +140102,7 @@
+   struct sqlite3_index_constraint *pIdxCons;
+   struct sqlite3_index_orderby *pIdxOrderBy;
+   struct sqlite3_index_constraint_usage *pUsage;
++  struct HiddenIndexInfo *pHidden;
+   WhereTerm *pTerm;
+   int nOrderBy;
+   sqlite3_index_info *pIdxInfo;
+@@ -132314,7 +140118,7 @@
+     testcase( pTerm->eOperator & WO_ISNULL );
+     testcase( pTerm->eOperator & WO_IS );
+     testcase( pTerm->eOperator & WO_ALL );
+-    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
++    if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+     if( pTerm->wtFlags & TERM_VNULL ) continue;
+     assert( pTerm->u.leftColumn>=(-1) );
+     nTerm++;
+@@ -132340,7 +140144,7 @@
+   */
+   pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+                            + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
+-                           + sizeof(*pIdxOrderBy)*nOrderBy );
++                           + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
+   if( pIdxInfo==0 ){
+     sqlite3ErrorMsg(pParse, "out of memory");
+     return 0;
+@@ -132351,7 +140155,8 @@
+   ** changing them.  We have to do some funky casting in order to
+   ** initialize those fields.
+   */
+-  pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];
++  pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
++  pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
+   pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
+   pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
+   *(int*)&pIdxInfo->nConstraint = nTerm;
+@@ -132361,8 +140166,10 @@
+   *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
+                                                                    pUsage;
+ 
++  pHidden->pWC = pWC;
++  pHidden->pParse = pParse;
+   for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+-    u8 op;
++    u16 op;
+     if( pTerm->leftCursor != pSrc->iCursor ) continue;
+     if( pTerm->prereqRight & mUnusable ) continue;
+     assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+@@ -132370,34 +140177,54 @@
+     testcase( pTerm->eOperator & WO_IS );
+     testcase( pTerm->eOperator & WO_ISNULL );
+     testcase( pTerm->eOperator & WO_ALL );
+-    if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
++    if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+     if( pTerm->wtFlags & TERM_VNULL ) continue;
++    if( (pSrc->fg.jointype & JT_LEFT)!=0
++     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
++     && (pTerm->eOperator & (WO_IS|WO_ISNULL))
++    ){
++      /* An "IS" term in the WHERE clause where the virtual table is the rhs
++      ** of a LEFT JOIN. Do not pass this term to the virtual table
++      ** implementation, as this can lead to incorrect results from SQL such
++      ** as:
++      **
++      **   "LEFT JOIN vtab WHERE vtab.col IS NULL"  */
++      testcase( pTerm->eOperator & WO_ISNULL );
++      testcase( pTerm->eOperator & WO_IS );
++      continue;
++    }
+     assert( pTerm->u.leftColumn>=(-1) );
+     pIdxCons[j].iColumn = pTerm->u.leftColumn;
+     pIdxCons[j].iTermOffset = i;
+-    op = (u8)pTerm->eOperator & WO_ALL;
++    op = pTerm->eOperator & WO_ALL;
+     if( op==WO_IN ) op = WO_EQ;
+-    if( op==WO_MATCH ){
+-      op = pTerm->eMatchOp;
+-    }
+-    pIdxCons[j].op = op;
+-    /* The direct assignment in the previous line is possible only because
+-    ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical.  The
+-    ** following asserts verify this fact. */
+-    assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
+-    assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
+-    assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
+-    assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
+-    assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
+-    assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
+-    assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
++    if( op==WO_AUX ){
++      pIdxCons[j].op = pTerm->eMatchOp;
++    }else if( op & (WO_ISNULL|WO_IS) ){
++      if( op==WO_ISNULL ){
++        pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
++      }else{
++        pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
++      }
++    }else{
++      pIdxCons[j].op = (u8)op;
++      /* The direct assignment in the previous line is possible only because
++      ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical.  The
++      ** following asserts verify this fact. */
++      assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
++      assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
++      assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
++      assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
++      assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
++      assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
+ 
+-    if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
+-     && sqlite3ExprIsVector(pTerm->pExpr->pRight) 
+-    ){
+-      if( i<16 ) mNoOmit |= (1 << i);
+-      if( op==WO_LT ) pIdxCons[j].op = WO_LE;
+-      if( op==WO_GT ) pIdxCons[j].op = WO_GE;
++      if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
++       && sqlite3ExprIsVector(pTerm->pExpr->pRight) 
++      ){
++        if( i<16 ) mNoOmit |= (1 << i);
++        if( op==WO_LT ) pIdxCons[j].op = WO_LE;
++        if( op==WO_GT ) pIdxCons[j].op = WO_GE;
++      }
+     }
+ 
+     j++;
+@@ -132418,9 +140245,11 @@
+ ** method of the virtual table with the sqlite3_index_info object that
+ ** comes in as the 3rd argument to this function.
+ **
+-** If an error occurs, pParse is populated with an error message and a
+-** non-zero value is returned. Otherwise, 0 is returned and the output
+-** part of the sqlite3_index_info structure is left populated.
++** If an error occurs, pParse is populated with an error message and an
++** appropriate error code is returned.  A return of SQLITE_CONSTRAINT from
++** xBestIndex is not considered an error.  SQLITE_CONSTRAINT indicates that
++** the current configuration of "unusable" flags in sqlite3_index_info can
++** not result in a valid plan.
+ **
+ ** Whether or not an error is returned, it is the responsibility of the
+ ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
+@@ -132434,7 +140263,7 @@
+   rc = pVtab->pModule->xBestIndex(pVtab, p);
+   TRACE_IDX_OUTPUTS(p);
+ 
+-  if( rc!=SQLITE_OK ){
++  if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
+     if( rc==SQLITE_NOMEM ){
+       sqlite3OomFault(pParse->db);
+     }else if( !pVtab->zErrMsg ){
+@@ -132445,19 +140274,7 @@
+   }
+   sqlite3_free(pVtab->zErrMsg);
+   pVtab->zErrMsg = 0;
+-
+-#if 0
+-  /* This error is now caught by the caller.
+-  ** Search for "xBestIndex malfunction" below */
+-  for(i=0; i<p->nConstraint; i++){
+-    if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
+-      sqlite3ErrorMsg(pParse, 
+-          "table %s: xBestIndex returned an invalid plan", pTab->zName);
+-    }
+-  }
+-#endif
+-
+-  return pParse->nErr;
++  return rc;
+ }
+ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
+ 
+@@ -132857,7 +140674,9 @@
+   Index *p = pLoop->u.btree.pIndex;
+   int nEq = pLoop->u.btree.nEq;
+ 
+-  if( p->nSample>0 && nEq<p->nSampleCol ){
++  if( p->nSample>0 && nEq<p->nSampleCol
++   && OptimizationEnabled(pParse->db, SQLITE_Stat34)
++  ){
+     if( nEq==pBuilder->nRecValid ){
+       UnpackedRecord *pRec = pBuilder->pRec;
+       tRowcnt a[2];
+@@ -133303,22 +141122,21 @@
+ ** Free a WhereInfo structure
+ */
+ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
+-  if( ALWAYS(pWInfo) ){
+-    int i;
+-    for(i=0; i<pWInfo->nLevel; i++){
+-      WhereLevel *pLevel = &pWInfo->a[i];
+-      if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
+-        sqlite3DbFree(db, pLevel->u.in.aInLoop);
+-      }
++  int i;
++  assert( pWInfo!=0 );
++  for(i=0; i<pWInfo->nLevel; i++){
++    WhereLevel *pLevel = &pWInfo->a[i];
++    if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
++      sqlite3DbFree(db, pLevel->u.in.aInLoop);
+     }
+-    sqlite3WhereClauseClear(&pWInfo->sWC);
+-    while( pWInfo->pLoops ){
+-      WhereLoop *p = pWInfo->pLoops;
+-      pWInfo->pLoops = p->pNextLoop;
+-      whereLoopDelete(db, p);
+-    }
+-    sqlite3DbFreeNN(db, pWInfo);
+   }
++  sqlite3WhereClauseClear(&pWInfo->sWC);
++  while( pWInfo->pLoops ){
++    WhereLoop *p = pWInfo->pLoops;
++    pWInfo->pLoops = p->pNextLoop;
++    whereLoopDelete(db, p);
++  }
++  sqlite3DbFreeNN(db, pWInfo);
+ }
+ 
+ /*
+@@ -133325,18 +141143,19 @@
+ ** Return TRUE if all of the following are true:
+ **
+ **   (1)  X has the same or lower cost that Y
+-**   (2)  X is a proper subset of Y
+-**   (3)  X skips at least as many columns as Y
++**   (2)  X uses fewer WHERE clause terms than Y
++**   (3)  Every WHERE clause term used by X is also used by Y
++**   (4)  X skips at least as many columns as Y
++**   (5)  If X is a covering index, than Y is too
+ **
+-** By "proper subset" we mean that X uses fewer WHERE clause terms
+-** than Y and that every WHERE clause term used by X is also used
+-** by Y.
+-**
++** Conditions (2) and (3) mean that X is a "proper subset" of Y.
+ ** If X is a proper subset of Y then Y is a better choice and ought
+ ** to have a lower cost.  This routine returns TRUE when that cost 
+-** relationship is inverted and needs to be adjusted.  The third rule
++** relationship is inverted and needs to be adjusted.  Constraint (4)
+ ** was added because if X uses skip-scan less than Y it still might
+-** deserve a lower cost even if it is a proper subset of Y.
++** deserve a lower cost even if it is a proper subset of Y.  Constraint (5)
++** was added because a covering index probably deserves to have a lower cost
++** than a non-covering index even if it is a proper subset.
+ */
+ static int whereLoopCheaperProperSubset(
+   const WhereLoop *pX,       /* First WhereLoop to compare */
+@@ -133358,6 +141177,10 @@
+     }
+     if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
+   }
++  if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 
++   && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
++    return 0;  /* Constraint (5) */
++  }
+   return 1;  /* All conditions meet */
+ }
+ 
+@@ -133506,6 +141329,14 @@
+   sqlite3 *db = pWInfo->pParse->db;
+   int rc;
+ 
++  /* Stop the search once we hit the query planner search limit */
++  if( pBuilder->iPlanLimit==0 ){
++    WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
++    if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
++    return SQLITE_DONE;
++  }
++  pBuilder->iPlanLimit--;
++
+   /* If pBuilder->pOrSet is defined, then only keep track of the costs
+   ** and prereqs.
+   */
+@@ -133790,8 +141621,8 @@
+ 
+   pNew = pBuilder->pNew;
+   if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+-  WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n",
+-                     pProbe->zName, pNew->u.btree.nEq));
++  WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n",
++                     pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq));
+ 
+   assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
+   assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
+@@ -133837,15 +141668,12 @@
+     ** to mix with a lower range bound from some other source */
+     if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
+ 
+-    /* Do not allow IS constraints from the WHERE clause to be used by the
++    /* Do not allow constraints from the WHERE clause to be used by the
+     ** right table of a LEFT JOIN.  Only constraints in the ON clause are
+     ** allowed */
+     if( (pSrc->fg.jointype & JT_LEFT)!=0
+      && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+-     && (eOp & (WO_IS|WO_ISNULL))!=0
+     ){
+-      testcase( eOp & WO_IS );
+-      testcase( eOp & WO_ISNULL );
+       continue;
+     }
+ 
+@@ -133871,7 +141699,6 @@
+ 
+     if( eOp & WO_IN ){
+       Expr *pExpr = pTerm->pExpr;
+-      pNew->wsFlags |= WHERE_COLUMN_IN;
+       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+         /* "x IN (SELECT ...)":  TUNING: the SELECT returns 25 rows */
+         int i;
+@@ -133891,17 +141718,55 @@
+         assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
+                           ** changes "x IN (?)" into "x=?". */
+       }
++      if( pProbe->hasStat1 ){
++        LogEst M, logK, safetyMargin;
++        /* Let:
++        **   N = the total number of rows in the table
++        **   K = the number of entries on the RHS of the IN operator
++        **   M = the number of rows in the table that match terms to the 
++        **       to the left in the same index.  If the IN operator is on
++        **       the left-most index column, M==N.
++        **
++        ** Given the definitions above, it is better to omit the IN operator
++        ** from the index lookup and instead do a scan of the M elements,
++        ** testing each scanned row against the IN operator separately, if:
++        **
++        **        M*log(K) < K*log(N)
++        **
++        ** Our estimates for M, K, and N might be inaccurate, so we build in
++        ** a safety margin of 2 (LogEst: 10) that favors using the IN operator
++        ** with the index, as using an index has better worst-case behavior.
++        ** If we do not have real sqlite_stat1 data, always prefer to use
++        ** the index.
++        */
++        M = pProbe->aiRowLogEst[saved_nEq];
++        logK = estLog(nIn);
++        safetyMargin = 10;  /* TUNING: extra weight for indexed IN */
++        if( M + logK + safetyMargin < nIn + rLogSize ){
++          WHERETRACE(0x40,
++            ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
++             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
++          continue;
++        }else{
++          WHERETRACE(0x40,
++            ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
++             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
++        }
++      }
++      pNew->wsFlags |= WHERE_COLUMN_IN;
+     }else if( eOp & (WO_EQ|WO_IS) ){
+       int iCol = pProbe->aiColumn[saved_nEq];
+       pNew->wsFlags |= WHERE_COLUMN_EQ;
+       assert( saved_nEq==pNew->u.btree.nEq );
+       if( iCol==XN_ROWID 
+-       || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
++       || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
+       ){
+-        if( iCol>=0 && pProbe->uniqNotNull==0 ){
++        if( iCol==XN_ROWID || pProbe->uniqNotNull 
++         || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) 
++        ){
++          pNew->wsFlags |= WHERE_ONEROW;
++        }else{
+           pNew->wsFlags |= WHERE_UNQ_WANTED;
+-        }else{
+-          pNew->wsFlags |= WHERE_ONEROW;
+         }
+       }
+     }else if( eOp & WO_ISNULL ){
+@@ -133967,6 +141832,7 @@
+          && pProbe->nSample 
+          && pNew->u.btree.nEq<=pProbe->nSampleCol
+          && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
++         && OptimizationEnabled(db, SQLITE_Stat34)
+         ){
+           Expr *pExpr = pTerm->pExpr;
+           if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
+@@ -134055,6 +141921,7 @@
+   if( saved_nEq==saved_nSkip
+    && saved_nEq+1<pProbe->nKeyCol
+    && pProbe->noSkipScan==0
++   && OptimizationEnabled(db, SQLITE_SkipScan)
+    && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
+    && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
+   ){
+@@ -134075,8 +141942,8 @@
+     pNew->wsFlags = saved_wsFlags;
+   }
+ 
+-  WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n",
+-                      pProbe->zName, saved_nEq, rc));
++  WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n",
++                      pProbe->pTable->zName, pProbe->zName, saved_nEq, rc));
+   return rc;
+ }
+ 
+@@ -134109,7 +141976,7 @@
+     }else if( (aColExpr = pIndex->aColExpr)!=0 ){
+       for(jj=0; jj<pIndex->nKeyCol; jj++){
+         if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
+-        if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
++        if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
+           return 1;
+         }
+       }
+@@ -134118,24 +141985,6 @@
+   return 0;
+ }
+ 
+-/*
+-** Return a bitmask where 1s indicate that the corresponding column of
+-** the table is used by an index.  Only the first 63 columns are considered.
+-*/
+-static Bitmask columnsInIndex(Index *pIdx){
+-  Bitmask m = 0;
+-  int j;
+-  for(j=pIdx->nColumn-1; j>=0; j--){
+-    int x = pIdx->aiColumn[j];
+-    if( x>=0 ){
+-      testcase( x==BMS-1 );
+-      testcase( x==BMS-2 );
+-      if( x<BMS-1 ) m |= MASKBIT(x);
+-    }
+-  }
+-  return m;
+-}
+-
+ /* Check to see if a partial index with pPartIndexWhere can be used
+ ** in the current query.  Return true if it can be and false if not.
+ */
+@@ -134280,14 +142129,16 @@
+         /* TUNING: One-time cost for computing the automatic index is
+         ** estimated to be X*N*log2(N) where N is the number of rows in
+         ** the table being indexed and where X is 7 (LogEst=28) for normal
+-        ** tables or 1.375 (LogEst=4) for views and subqueries.  The value
++        ** tables or 0.5 (LogEst=-10) for views and subqueries.  The value
+         ** of X is smaller for views and subqueries so that the query planner
+         ** will be more aggressive about generating automatic indexes for
+         ** those objects, since there is no opportunity to add schema
+         ** indexes on subqueries and views. */
+-        pNew->rSetup = rLogSize + rSize + 4;
++        pNew->rSetup = rLogSize + rSize;
+         if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
+-          pNew->rSetup += 24;
++          pNew->rSetup += 28;
++        }else{
++          pNew->rSetup -= 10;
+         }
+         ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
+         if( pNew->rSetup<0 ) pNew->rSetup = 0;
+@@ -134305,14 +142156,17 @@
+   }
+ #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
+ 
+-  /* Loop over all indices
+-  */
+-  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
++  /* Loop over all indices. If there was an INDEXED BY clause, then only 
++  ** consider index pProbe.  */
++  for(; rc==SQLITE_OK && pProbe; 
++      pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
++  ){
+     if( pProbe->pPartIdxWhere!=0
+      && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
+       testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
+       continue;  /* Partial index inappropriate for this query */
+     }
++    if( pProbe->bNoQuery ) continue;
+     rSize = pProbe->aiRowLogEst[0];
+     pNew->u.btree.nEq = 0;
+     pNew->u.btree.nBtm = 0;
+@@ -134346,7 +142200,7 @@
+         pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
+         m = 0;
+       }else{
+-        m = pSrc->colUsed & ~columnsInIndex(pProbe);
++        m = pSrc->colUsed & pProbe->colNotIdxed;
+         pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+       }
+ 
+@@ -134417,10 +142271,6 @@
+     pBuilder->nRecValid = 0;
+     pBuilder->pRec = 0;
+ #endif
+-
+-    /* If there was an INDEXED BY clause, then only that one index is
+-    ** considered. */
+-    if( pSrc->pIBIndex ) break;
+   }
+   return rc;
+ }
+@@ -134497,7 +142347,17 @@
+ 
+   /* Invoke the virtual table xBestIndex() method */
+   rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+-  if( rc ) return rc;
++  if( rc ){
++    if( rc==SQLITE_CONSTRAINT ){
++      /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
++      ** that the particular combination of parameters provided is unusable.
++      ** Make no entries in the loop table.
++      */
++      WHERETRACE(0xffff, ("  ^^^^--- non-viable plan rejected!\n"));
++      return SQLITE_OK;
++    }
++    return rc;
++  }
+ 
+   mxTerm = -1;
+   assert( pNew->nLSlot>=nConstraint );
+@@ -134515,9 +142375,9 @@
+        || pNew->aLTerm[iTerm]!=0
+        || pIdxCons->usable==0
+       ){
+-        rc = SQLITE_ERROR;
+         sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
+-        return rc;
++        testcase( pIdxInfo->needToFreeIdxStr );
++        return SQLITE_ERROR;
+       }
+       testcase( iTerm==nConstraint-1 );
+       testcase( j==0 );
+@@ -134545,6 +142405,15 @@
+   pNew->u.vtab.omitMask &= ~mNoOmit;
+ 
+   pNew->nLTerm = mxTerm+1;
++  for(i=0; i<=mxTerm; i++){
++    if( pNew->aLTerm[i]==0 ){
++      /* The non-zero argvIdx values must be contiguous.  Raise an
++      ** error if they are not */
++      sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
++      testcase( pIdxInfo->needToFreeIdxStr );
++      return SQLITE_ERROR;
++    }
++  }
+   assert( pNew->nLTerm<=pNew->nLSlot );
+   pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+   pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+@@ -134575,6 +142444,27 @@
+   return rc;
+ }
+ 
++/*
++** If this function is invoked from within an xBestIndex() callback, it
++** returns a pointer to a buffer containing the name of the collation
++** sequence associated with element iCons of the sqlite3_index_info.aConstraint
++** array. Or, if iCons is out of range or there is no active xBestIndex
++** call, return NULL.
++*/
++SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
++  HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
++  const char *zRet = 0;
++  if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
++    CollSeq *pC = 0;
++    int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
++    Expr *pX = pHidden->pWC->a[iTerm].pExpr;
++    if( pX->pLeft ){
++      pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight);
++    }
++    zRet = (pC ? pC->zName : sqlite3StrBINARY);
++  }
++  return zRet;
++}
+ 
+ /*
+ ** Add all WhereLoop objects for a table of the join identified by
+@@ -134639,6 +142529,7 @@
+   }
+ 
+   /* First call xBestIndex() with all constraints usable. */
++  WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
+   WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
+   rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
+ 
+@@ -134714,6 +142605,7 @@
+ 
+   if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
+   sqlite3DbFreeNN(pParse->db, p);
++  WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
+   return rc;
+ }
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -134861,9 +142753,11 @@
+   /* Loop over the tables in the join, from left to right */
+   pNew = pBuilder->pNew;
+   whereLoopInit(pNew);
++  pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
+   for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
+     Bitmask mUnusable = 0;
+     pNew->iTab = iTab;
++    pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
+     pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
+     if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
+       /* This condition is true when pItem is the FROM clause term on the
+@@ -134885,11 +142779,19 @@
+     {
+       rc = whereLoopAddBtree(pBuilder, mPrereq);
+     }
+-    if( rc==SQLITE_OK ){
++    if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
+       rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
+     }
+     mPrior |= pNew->maskSelf;
+-    if( rc || db->mallocFailed ) break;
++    if( rc || db->mallocFailed ){
++      if( rc==SQLITE_DONE ){
++        /* We hit the query planner search limit set by iPlanLimit */
++        sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
++        rc = SQLITE_OK;
++      }else{
++        break;
++      }
++    }
+   }
+ 
+   whereLoopClear(db, pNew);
+@@ -135019,14 +142921,10 @@
+         if( j>=pLoop->nLTerm ) continue;
+       }
+       if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
+-        const char *z1, *z2;
+-        pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+-        if( !pColl ) pColl = db->pDfltColl;
+-        z1 = pColl->zName;
+-        pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
+-        if( !pColl ) pColl = db->pDfltColl;
+-        z2 = pColl->zName;
+-        if( sqlite3StrICmp(z1, z2)!=0 ) continue;
++        if( sqlite3ExprCollSeqMatch(pWInfo->pParse, 
++                  pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){
++          continue;
++        }
+         testcase( pTerm->pExpr->op==TK_IS );
+       }
+       obSat |= MASKBIT(i);
+@@ -135098,7 +142996,7 @@
+         if( pIndex ){
+           iColumn = pIndex->aiColumn[j];
+           revIdx = pIndex->aSortOrder[j];
+-          if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
++          if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
+         }else{
+           iColumn = XN_ROWID;
+           revIdx = 0;
+@@ -135125,19 +143023,18 @@
+           testcase( wctrlFlags & WHERE_GROUPBY );
+           testcase( wctrlFlags & WHERE_DISTINCTBY );
+           if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
+-          if( iColumn>=(-1) ){
++          if( iColumn>=XN_ROWID ){
+             if( pOBExpr->op!=TK_COLUMN ) continue;
+             if( pOBExpr->iTable!=iCur ) continue;
+             if( pOBExpr->iColumn!=iColumn ) continue;
+           }else{
+-            if( sqlite3ExprCompare(0,
+-                  pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
++            Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
++            if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
+               continue;
+             }
+           }
+-          if( iColumn>=0 ){
+-            pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+-            if( !pColl ) pColl = db->pDfltColl;
++          if( iColumn!=XN_ROWID ){
++            pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+             if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
+           }
+           pLoop->u.btree.nIdxCol = j+1;
+@@ -135397,12 +143294,15 @@
+ 
+         if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+         if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+-        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
++        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
+           /* Do not use an automatic index if the this loop is expected
+-          ** to run less than 2 times. */
++          ** to run less than 1.25 times.  It is tempting to also exclude
++          ** automatic index usage on an outer loop, but sometimes an automatic
++          ** index is useful in the outer loop of a correlated subquery. */
+           assert( 10==sqlite3LogEst(2) );
+           continue;
+         }
++
+         /* At this point, pWLoop is a candidate to be the next loop. 
+         ** Compute its cost */
+         rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+@@ -135422,7 +143322,11 @@
+                 pWInfo, nRowEst, nOrderBy, isOrdered
+             );
+           }
+-          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
++          /* TUNING:  Add a small extra penalty (5) to sorting as an
++          ** extra encouragment to the query planner to select a plan
++          ** where the rows emerge in the correct order without any sorting
++          ** required. */
++          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
+ 
+           WHERETRACE(0x002,
+               ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
+@@ -135612,6 +143516,7 @@
+       pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+     }
+   }
++  pWInfo->bOrderedInnerLoop = 0;
+   if( pWInfo->pOrderBy ){
+     if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
+       if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
+@@ -135723,7 +143628,7 @@
+       }
+       if( j!=pIdx->nKeyCol ) continue;
+       pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
+-      if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
++      if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){
+         pLoop->wsFlags |= WHERE_IDX_ONLY;
+       }
+       pLoop->nLTerm = j;
+@@ -135774,6 +143679,7 @@
+   memset(&w, 0, sizeof(w));
+   w.eCode = 1;
+   w.xExprCallback = exprNodeIsDeterministic;
++  w.xSelectCallback = sqlite3SelectWalkFail;
+   sqlite3WalkExpr(&w, p);
+   return w.eCode;
+ }
+@@ -135983,37 +143889,39 @@
+     if( wctrlFlags & WHERE_WANT_DISTINCT ){
+       pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+     }
+-  }
+-
+-  /* Assign a bit from the bitmask to every term in the FROM clause.
+-  **
+-  ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
+-  **
+-  ** The rule of the previous sentence ensures thta if X is the bitmask for
+-  ** a table T, then X-1 is the bitmask for all other tables to the left of T.
+-  ** Knowing the bitmask for all tables to the left of a left join is
+-  ** important.  Ticket #3015.
+-  **
+-  ** Note that bitmasks are created for all pTabList->nSrc tables in
+-  ** pTabList, not just the first nTabList tables.  nTabList is normally
+-  ** equal to pTabList->nSrc but might be shortened to 1 if the
+-  ** WHERE_OR_SUBCLAUSE flag is set.
+-  */
+-  for(ii=0; ii<pTabList->nSrc; ii++){
+-    createMask(pMaskSet, pTabList->a[ii].iCursor);
+-    sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
+-  }
+-#ifdef SQLITE_DEBUG
+-  {
+-    Bitmask mx = 0;
+-    for(ii=0; ii<pTabList->nSrc; ii++){
+-      Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
+-      assert( m>=mx );
+-      mx = m;
++    ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
++  }else{
++    /* Assign a bit from the bitmask to every term in the FROM clause.
++    **
++    ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
++    **
++    ** The rule of the previous sentence ensures thta if X is the bitmask for
++    ** a table T, then X-1 is the bitmask for all other tables to the left of T.
++    ** Knowing the bitmask for all tables to the left of a left join is
++    ** important.  Ticket #3015.
++    **
++    ** Note that bitmasks are created for all pTabList->nSrc tables in
++    ** pTabList, not just the first nTabList tables.  nTabList is normally
++    ** equal to pTabList->nSrc but might be shortened to 1 if the
++    ** WHERE_OR_SUBCLAUSE flag is set.
++    */
++    ii = 0;
++    do{
++      createMask(pMaskSet, pTabList->a[ii].iCursor);
++      sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
++    }while( (++ii)<pTabList->nSrc );
++  #ifdef SQLITE_DEBUG
++    {
++      Bitmask mx = 0;
++      for(ii=0; ii<pTabList->nSrc; ii++){
++        Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
++        assert( m>=mx );
++        mx = m;
++      }
+     }
++  #endif
+   }
+-#endif
+-
++  
+   /* Analyze all of the subexpressions. */
+   sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
+   if( db->mallocFailed ) goto whereBeginError;
+@@ -136031,6 +143939,7 @@
+   */
+   for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+     WhereTerm *pT = &sWLB.pWC->a[ii];
++    if( pT->wtFlags & TERM_VIRTUAL ) continue;
+     if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
+       sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
+       pT->wtFlags |= TERM_CODED;
+@@ -136118,35 +144027,80 @@
+     }
+   }
+ #endif
+-  /* Attempt to omit tables from the join that do not effect the result */
++
++  /* Attempt to omit tables from the join that do not affect the result.
++  ** For a table to not affect the result, the following must be true:
++  **
++  **   1) The query must not be an aggregate.
++  **   2) The table must be the RHS of a LEFT JOIN.
++  **   3) Either the query must be DISTINCT, or else the ON or USING clause
++  **      must contain a constraint that limits the scan of the table to 
++  **      at most a single row.
++  **   4) The table must not be referenced by any part of the query apart
++  **      from its own USING or ON clause.
++  **
++  ** For example, given:
++  **
++  **     CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
++  **     CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
++  **     CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
++  **
++  ** then table t2 can be omitted from the following:
++  **
++  **     SELECT v1, v3 FROM t1 
++  **       LEFT JOIN t2 USING (t1.ipk=t2.ipk)
++  **       LEFT JOIN t3 USING (t1.ipk=t3.ipk)
++  **
++  ** or from:
++  **
++  **     SELECT DISTINCT v1, v3 FROM t1 
++  **       LEFT JOIN t2
++  **       LEFT JOIN t3 USING (t1.ipk=t3.ipk)
++  */
++  notReady = ~(Bitmask)0;
+   if( pWInfo->nLevel>=2
+-   && pResultSet!=0
++   && pResultSet!=0               /* guarantees condition (1) above */
+    && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+   ){
++    int i;
+     Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
+     if( sWLB.pOrderBy ){
+       tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
+     }
+-    while( pWInfo->nLevel>=2 ){
++    for(i=pWInfo->nLevel-1; i>=1; i--){
+       WhereTerm *pTerm, *pEnd;
+-      pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
+-      if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
++      struct SrcList_item *pItem;
++      pLoop = pWInfo->a[i].pWLoop;
++      pItem = &pWInfo->pTabList->a[pLoop->iTab];
++      if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
+       if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
+        && (pLoop->wsFlags & WHERE_ONEROW)==0
+       ){
+-        break;
++        continue;
+       }
+-      if( (tabUsed & pLoop->maskSelf)!=0 ) break;
++      if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
+       pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
+       for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+-        if( (pTerm->prereqAll & pLoop->maskSelf)!=0
+-         && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+-        ){
+-          break;
++        if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
++          if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
++           || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
++          ){
++            break;
++          }
+         }
+       }
+-      if( pTerm<pEnd ) break;
++      if( pTerm<pEnd ) continue;
+       WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
++      notReady &= ~pLoop->maskSelf;
++      for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
++        if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
++          pTerm->wtFlags |= TERM_CODED;
++        }
++      }
++      if( i!=pWInfo->nLevel-1 ){
++        int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
++        memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
++      }
+       pWInfo->nLevel--;
+       nTabList--;
+     }
+@@ -136156,15 +144110,32 @@
+ 
+   /* If the caller is an UPDATE or DELETE statement that is requesting
+   ** to use a one-pass algorithm, determine if this is appropriate.
++  **
++  ** A one-pass approach can be used if the caller has requested one
++  ** and either (a) the scan visits at most one row or (b) each
++  ** of the following are true:
++  **
++  **   * the caller has indicated that a one-pass approach can be used
++  **     with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
++  **   * the table is not a virtual table, and
++  **   * either the scan does not use the OR optimization or the caller
++  **     is a DELETE operation (WHERE_DUPLICATES_OK is only specified
++  **     for DELETE).
++  **
++  ** The last qualification is because an UPDATE statement uses
++  ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
++  ** use a one-pass approach, and this is not set accurately for scans
++  ** that use the OR optimization.
+   */
+   assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
+   if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
+     int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
+     int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
+-    if( bOnerow
+-     || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
+-           && 0==(wsFlags & WHERE_VIRTUALTABLE))
+-    ){
++    if( bOnerow || (
++        0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
++     && 0==(wsFlags & WHERE_VIRTUALTABLE)
++     && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
++    )){
+       pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
+       if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
+         if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
+@@ -136236,7 +144207,7 @@
+       Index *pIx = pLoop->u.btree.pIndex;
+       int iIndexCur;
+       int op = OP_OpenRead;
+-      /* iAuxArg is always set if to a positive value if ONEPASS is possible */
++      /* iAuxArg is always set to a positive value if ONEPASS is possible */
+       assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+       if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
+        && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0
+@@ -136301,7 +144272,6 @@
+   ** loop below generates code for a single nested loop of the VM
+   ** program.
+   */
+-  notReady = ~(Bitmask)0;
+   for(ii=0; ii<nTabList; ii++){
+     int addrExplain;
+     int wsFlags;
+@@ -136315,7 +144285,7 @@
+     }
+ #endif
+     addrExplain = sqlite3WhereExplainOneScan(
+-        pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
++        pParse, pTabList, pLevel, wctrlFlags
+     );
+     pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+     notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+@@ -136339,6 +144309,26 @@
+ }
+ 
+ /*
++** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
++** index rather than the main table.  In SQLITE_DEBUG mode, we want
++** to trace those changes if PRAGMA vdbe_addoptrace=on.  This routine
++** does that.
++*/
++#ifndef SQLITE_DEBUG
++# define OpcodeRewriteTrace(D,K,P) /* no-op */
++#else
++# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P)
++  static void sqlite3WhereOpcodeRewriteTrace(
++    sqlite3 *db,
++    int pc,
++    VdbeOp *pOp
++  ){
++    if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
++    sqlite3VdbePrintOp(0, pc, pOp);
++  }
++#endif
++
++/*
+ ** Generate the end of the WHERE loop.  See comments on 
+ ** sqlite3WhereBegin() for additional information.
+ */
+@@ -136354,7 +144344,6 @@
+   /* Generate loop termination code.
+   */
+   VdbeModuleComment((v, "End WHERE-core"));
+-  sqlite3ExprCacheClear(pParse);
+   for(i=pWInfo->nLevel-1; i>=0; i--){
+     int addr;
+     pLevel = &pWInfo->a[i];
+@@ -136365,6 +144354,7 @@
+       Index *pIdx;
+       int n;
+       if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
++       && i==pWInfo->nLevel-1  /* Ticket [ef9318757b152e3] 2017-10-21 */
+        && (pLoop->wsFlags & WHERE_INDEXED)!=0
+        && (pIdx = pLoop->u.btree.pIndex)->hasStat1
+        && (n = pLoop->u.btree.nIdxCol)>0
+@@ -136404,10 +144394,17 @@
+       for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
+         sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
+         if( pIn->eEndLoopOp!=OP_Noop ){
++          if( pIn->nPrefix ){
++            assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
++            sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
++                              sqlite3VdbeCurrentAddr(v)+2,
++                              pIn->iBase, pIn->nPrefix);
++            VdbeCoverage(v);
++          }
+           sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+           VdbeCoverage(v);
+-          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+-          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
+         }
+         sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
+       }
+@@ -136431,7 +144428,8 @@
+       addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
+       assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
+       if( (ws & WHERE_IDX_ONLY)==0 ){
+-        sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
++        assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
++        sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
+       }
+       if( (ws & WHERE_INDEXED) 
+        || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) 
+@@ -136497,10 +144495,19 @@
+     ){
+       last = sqlite3VdbeCurrentAddr(v);
+       k = pLevel->addrBody;
++#ifdef SQLITE_DEBUG
++      if( db->flags & SQLITE_VdbeAddopTrace ){
++        printf("TRANSLATE opcodes in range %d..%d\n", k, last-1);
++      }
++#endif
+       pOp = sqlite3VdbeGetOp(v, k);
+       for(; k<last; k++, pOp++){
+         if( pOp->p1!=pLevel->iTabCur ) continue;
+-        if( pOp->opcode==OP_Column ){
++        if( pOp->opcode==OP_Column
++#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
++         || pOp->opcode==OP_Offset
++#endif
++        ){
+           int x = pOp->p2;
+           assert( pIdx->pTable==pTab );
+           if( !HasRowid(pTab) ){
+@@ -136512,6 +144519,7 @@
+           if( x>=0 ){
+             pOp->p2 = x;
+             pOp->p1 = pLevel->iIdxCur;
++            OpcodeRewriteTrace(db, k, pOp);
+           }
+           assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
+               || pWInfo->eOnePass );
+@@ -136518,10 +144526,15 @@
+         }else if( pOp->opcode==OP_Rowid ){
+           pOp->p1 = pLevel->iIdxCur;
+           pOp->opcode = OP_IdxRowid;
++          OpcodeRewriteTrace(db, k, pOp);
+         }else if( pOp->opcode==OP_IfNullRow ){
+           pOp->p1 = pLevel->iIdxCur;
++          OpcodeRewriteTrace(db, k, pOp);
+         }
+       }
++#ifdef SQLITE_DEBUG
++      if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
++#endif
+     }
+   }
+ 
+@@ -136533,6 +144546,2263 @@
+ }
+ 
+ /************** End of where.c ***********************************************/
++/************** Begin file window.c ******************************************/
++/*
++** 2018 May 08
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++*/
++/* #include "sqliteInt.h" */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++
++/*
++** SELECT REWRITING
++**
++**   Any SELECT statement that contains one or more window functions in
++**   either the select list or ORDER BY clause (the only two places window
++**   functions may be used) is transformed by function sqlite3WindowRewrite()
++**   in order to support window function processing. For example, with the
++**   schema:
++**
++**     CREATE TABLE t1(a, b, c, d, e, f, g);
++**
++**   the statement:
++**
++**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
++**
++**   is transformed to:
++**
++**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
++**         SELECT a, e, c, d, b FROM t1 ORDER BY c, d
++**     ) ORDER BY e;
++**
++**   The flattening optimization is disabled when processing this transformed
++**   SELECT statement. This allows the implementation of the window function
++**   (in this case max()) to process rows sorted in order of (c, d), which
++**   makes things easier for obvious reasons. More generally:
++**
++**     * FROM, WHERE, GROUP BY and HAVING clauses are all moved to 
++**       the sub-query.
++**
++**     * ORDER BY, LIMIT and OFFSET remain part of the parent query.
++**
++**     * Terminals from each of the expression trees that make up the 
++**       select-list and ORDER BY expressions in the parent query are
++**       selected by the sub-query. For the purposes of the transformation,
++**       terminals are column references and aggregate functions.
++**
++**   If there is more than one window function in the SELECT that uses
++**   the same window declaration (the OVER bit), then a single scan may
++**   be used to process more than one window function. For example:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
++**            min(e) OVER (PARTITION BY c ORDER BY d) 
++**     FROM t1;
++**
++**   is transformed in the same way as the example above. However:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
++**            min(e) OVER (PARTITION BY a ORDER BY b) 
++**     FROM t1;
++**
++**   Must be transformed to:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
++**         SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
++**           SELECT a, e, c, d, b FROM t1 ORDER BY a, b
++**         ) ORDER BY c, d
++**     ) ORDER BY e;
++**
++**   so that both min() and max() may process rows in the order defined by
++**   their respective window declarations.
++**
++** INTERFACE WITH SELECT.C
++**
++**   When processing the rewritten SELECT statement, code in select.c calls
++**   sqlite3WhereBegin() to begin iterating through the results of the
++**   sub-query, which is always implemented as a co-routine. It then calls
++**   sqlite3WindowCodeStep() to process rows and finish the scan by calling
++**   sqlite3WhereEnd().
++**
++**   sqlite3WindowCodeStep() generates VM code so that, for each row returned
++**   by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
++**   When the sub-routine is invoked:
++**
++**     * The results of all window-functions for the row are stored
++**       in the associated Window.regResult registers.
++**
++**     * The required terminal values are stored in the current row of
++**       temp table Window.iEphCsr.
++**
++**   In some cases, depending on the window frame and the specific window
++**   functions invoked, sqlite3WindowCodeStep() caches each entire partition
++**   in a temp table before returning any rows. In other cases it does not.
++**   This detail is encapsulated within this file, the code generated by
++**   select.c is the same in either case.
++**
++** BUILT-IN WINDOW FUNCTIONS
++**
++**   This implementation features the following built-in window functions:
++**
++**     row_number()
++**     rank()
++**     dense_rank()
++**     percent_rank()
++**     cume_dist()
++**     ntile(N)
++**     lead(expr [, offset [, default]])
++**     lag(expr [, offset [, default]])
++**     first_value(expr)
++**     last_value(expr)
++**     nth_value(expr, N)
++**   
++**   These are the same built-in window functions supported by Postgres. 
++**   Although the behaviour of aggregate window functions (functions that
++**   can be used as either aggregates or window funtions) allows them to
++**   be implemented using an API, built-in window functions are much more
++**   esoteric. Additionally, some window functions (e.g. nth_value()) 
++**   may only be implemented by caching the entire partition in memory.
++**   As such, some built-in window functions use the same API as aggregate
++**   window functions and some are implemented directly using VDBE 
++**   instructions. Additionally, for those functions that use the API, the
++**   window frame is sometimes modified before the SELECT statement is
++**   rewritten. For example, regardless of the specified window frame, the
++**   row_number() function always uses:
++**
++**     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   See sqlite3WindowUpdate() for details.
++**
++**   As well as some of the built-in window functions, aggregate window
++**   functions min() and max() are implemented using VDBE instructions if
++**   the start of the window frame is declared as anything other than 
++**   UNBOUNDED PRECEDING.
++*/
++
++/*
++** Implementation of built-in window function row_number(). Assumes that the
++** window frame has been coerced to:
++**
++**   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++*/
++static void row_numberStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ) (*p)++;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void row_numberValueFunc(sqlite3_context *pCtx){
++  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  sqlite3_result_int64(pCtx, (p ? *p : 0));
++}
++
++/*
++** Context object type used by rank(), dense_rank(), percent_rank() and
++** cume_dist().
++*/
++struct CallCount {
++  i64 nValue;
++  i64 nStep;
++  i64 nTotal;
++};
++
++/*
++** Implementation of built-in window function dense_rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void dense_rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ) p->nStep = 1;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void dense_rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nStep ){
++      p->nValue++;
++      p->nStep = 0;
++    }
++    sqlite3_result_int64(pCtx, p->nValue);
++  }
++}
++
++/*
++** Implementation of built-in window function rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    p->nStep++;
++    if( p->nValue==0 ){
++      p->nValue = p->nStep;
++    }
++  }
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    sqlite3_result_int64(pCtx, p->nValue);
++    p->nValue = 0;
++  }
++}
++
++/*
++** Implementation of built-in window function percent_rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void percent_rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  UNUSED_PARAMETER(nArg); assert( nArg==1 );
++
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nTotal = sqlite3_value_int64(apArg[0]);
++    }
++    p->nStep++;
++    if( p->nValue==0 ){
++      p->nValue = p->nStep;
++    }
++  }
++}
++static void percent_rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal>1 ){
++      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
++      sqlite3_result_double(pCtx, r);
++    }else{
++      sqlite3_result_double(pCtx, 0.0);
++    }
++    p->nValue = 0;
++  }
++}
++
++/*
++** Implementation of built-in window function cume_dist(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void cume_distStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
++
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nTotal = sqlite3_value_int64(apArg[0]);
++    }
++    p->nStep++;
++  }
++}
++static void cume_distValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->nTotal ){
++    double r = (double)(p->nStep) / (double)(p->nTotal);
++    sqlite3_result_double(pCtx, r);
++  }
++}
++
++/*
++** Context object for ntile() window function.
++*/
++struct NtileCtx {
++  i64 nTotal;                     /* Total rows in partition */
++  i64 nParam;                     /* Parameter passed to ntile(N) */
++  i64 iRow;                       /* Current row */
++};
++
++/*
++** Implementation of ntile(). This assumes that the window frame has
++** been coerced to:
++**
++**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
++*/
++static void ntileStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct NtileCtx *p;
++  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
++  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nParam = sqlite3_value_int64(apArg[0]);
++      p->nTotal = sqlite3_value_int64(apArg[1]);
++      if( p->nParam<=0 ){
++        sqlite3_result_error(
++            pCtx, "argument of ntile must be a positive integer", -1
++        );
++      }
++    }
++    p->iRow++;
++  }
++}
++static void ntileValueFunc(sqlite3_context *pCtx){
++  struct NtileCtx *p;
++  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->nParam>0 ){
++    int nSize = (p->nTotal / p->nParam);
++    if( nSize==0 ){
++      sqlite3_result_int64(pCtx, p->iRow);
++    }else{
++      i64 nLarge = p->nTotal - p->nParam*nSize;
++      i64 iSmall = nLarge*(nSize+1);
++      i64 iRow = p->iRow-1;
++
++      assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
++
++      if( iRow<iSmall ){
++        sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
++      }else{
++        sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
++      }
++    }
++  }
++}
++
++/*
++** Context object for last_value() window function.
++*/
++struct LastValueCtx {
++  sqlite3_value *pVal;
++  int nVal;
++};
++
++/*
++** Implementation of last_value().
++*/
++static void last_valueStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct LastValueCtx *p;
++  UNUSED_PARAMETER(nArg);
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    sqlite3_value_free(p->pVal);
++    p->pVal = sqlite3_value_dup(apArg[0]);
++    if( p->pVal==0 ){
++      sqlite3_result_error_nomem(pCtx);
++    }else{
++      p->nVal++;
++    }
++  }
++}
++static void last_valueInvFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct LastValueCtx *p;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( ALWAYS(p) ){
++    p->nVal--;
++    if( p->nVal==0 ){
++      sqlite3_value_free(p->pVal);
++      p->pVal = 0;
++    }
++  }
++}
++static void last_valueValueFunc(sqlite3_context *pCtx){
++  struct LastValueCtx *p;
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->pVal ){
++    sqlite3_result_value(pCtx, p->pVal);
++  }
++}
++static void last_valueFinalizeFunc(sqlite3_context *pCtx){
++  struct LastValueCtx *p;
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->pVal ){
++    sqlite3_result_value(pCtx, p->pVal);
++    sqlite3_value_free(p->pVal);
++    p->pVal = 0;
++  }
++}
++
++/*
++** Static names for the built-in window function names.  These static
++** names are used, rather than string literals, so that FuncDef objects
++** can be associated with a particular window function by direct
++** comparison of the zName pointer.  Example:
++**
++**       if( pFuncDef->zName==row_valueName ){ ... }
++*/
++static const char row_numberName[] =   "row_number";
++static const char dense_rankName[] =   "dense_rank";
++static const char rankName[] =         "rank";
++static const char percent_rankName[] = "percent_rank";
++static const char cume_distName[] =    "cume_dist";
++static const char ntileName[] =        "ntile";
++static const char last_valueName[] =   "last_value";
++static const char nth_valueName[] =    "nth_value";
++static const char first_valueName[] =  "first_value";
++static const char leadName[] =         "lead";
++static const char lagName[] =          "lag";
++
++/*
++** No-op implementations of xStep() and xFinalize().  Used as place-holders
++** for built-in window functions that never call those interfaces.
++**
++** The noopValueFunc() is called but is expected to do nothing.  The
++** noopStepFunc() is never called, and so it is marked with NO_TEST to
++** let the test coverage routine know not to expect this function to be
++** invoked.
++*/
++static void noopStepFunc(    /*NO_TEST*/
++  sqlite3_context *p,        /*NO_TEST*/
++  int n,                     /*NO_TEST*/
++  sqlite3_value **a          /*NO_TEST*/
++){                           /*NO_TEST*/
++  UNUSED_PARAMETER(p);       /*NO_TEST*/
++  UNUSED_PARAMETER(n);       /*NO_TEST*/
++  UNUSED_PARAMETER(a);       /*NO_TEST*/
++  assert(0);                 /*NO_TEST*/
++}                            /*NO_TEST*/
++static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
++
++/* Window functions that use all window interfaces: xStep, xFinal,
++** xValue, and xInverse */
++#define WINDOWFUNCALL(name,nArg,extra) {                                   \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc,               \
++  name ## InvFunc, name ## Name, {0}                                       \
++}
++
++/* Window functions that are implemented using bytecode and thus have
++** no-op routines for their methods */
++#define WINDOWFUNCNOOP(name,nArg,extra) {                                  \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  noopStepFunc, noopValueFunc, noopValueFunc,                              \
++  noopStepFunc, name ## Name, {0}                                          \
++}
++
++/* Window functions that use all window interfaces: xStep, the
++** same routine for xFinalize and xValue and which never call
++** xInverse. */
++#define WINDOWFUNCX(name,nArg,extra) {                                     \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  name ## StepFunc, name ## ValueFunc, name ## ValueFunc,                  \
++  noopStepFunc, name ## Name, {0}                                          \
++}
++
++
++/*
++** Register those built-in window functions that are not also aggregates.
++*/
++SQLITE_PRIVATE void sqlite3WindowFunctions(void){
++  static FuncDef aWindowFuncs[] = {
++    WINDOWFUNCX(row_number, 0, 0),
++    WINDOWFUNCX(dense_rank, 0, 0),
++    WINDOWFUNCX(rank, 0, 0),
++    WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCALL(last_value, 1, 0),
++    WINDOWFUNCNOOP(nth_value, 2, 0),
++    WINDOWFUNCNOOP(first_value, 1, 0),
++    WINDOWFUNCNOOP(lead, 1, 0),
++    WINDOWFUNCNOOP(lead, 2, 0),
++    WINDOWFUNCNOOP(lead, 3, 0),
++    WINDOWFUNCNOOP(lag, 1, 0),
++    WINDOWFUNCNOOP(lag, 2, 0),
++    WINDOWFUNCNOOP(lag, 3, 0),
++  };
++  sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
++}
++
++/*
++** This function is called immediately after resolving the function name
++** for a window function within a SELECT statement. Argument pList is a
++** linked list of WINDOW definitions for the current SELECT statement.
++** Argument pFunc is the function definition just resolved and pWin
++** is the Window object representing the associated OVER clause. This
++** function updates the contents of pWin as follows:
++**
++**   * If the OVER clause refered to a named window (as in "max(x) OVER win"),
++**     search list pList for a matching WINDOW definition, and update pWin
++**     accordingly. If no such WINDOW clause can be found, leave an error
++**     in pParse.
++**
++**   * If the function is a built-in window function that requires the
++**     window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
++**     of this file), pWin is updated here.
++*/
++SQLITE_PRIVATE void sqlite3WindowUpdate(
++  Parse *pParse, 
++  Window *pList,                  /* List of named windows for this SELECT */
++  Window *pWin,                   /* Window frame to update */
++  FuncDef *pFunc                  /* Window function definition */
++){
++  if( pWin->zName && pWin->eType==0 ){
++    Window *p;
++    for(p=pList; p; p=p->pNextWin){
++      if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
++    }
++    if( p==0 ){
++      sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
++      return;
++    }
++    pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
++    pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
++    pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
++    pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
++    pWin->eStart = p->eStart;
++    pWin->eEnd = p->eEnd;
++    pWin->eType = p->eType;
++  }
++  if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
++    sqlite3 *db = pParse->db;
++    if( pWin->pFilter ){
++      sqlite3ErrorMsg(pParse, 
++          "FILTER clause may only be used with aggregate window functions"
++      );
++    }else
++    if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
++      sqlite3ExprDelete(db, pWin->pStart);
++      sqlite3ExprDelete(db, pWin->pEnd);
++      pWin->pStart = pWin->pEnd = 0;
++      pWin->eType = TK_ROWS;
++      pWin->eStart = TK_UNBOUNDED;
++      pWin->eEnd = TK_CURRENT;
++    }else
++
++    if( pFunc->zName==dense_rankName || pFunc->zName==rankName
++     || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
++    ){
++      sqlite3ExprDelete(db, pWin->pStart);
++      sqlite3ExprDelete(db, pWin->pEnd);
++      pWin->pStart = pWin->pEnd = 0;
++      pWin->eType = TK_RANGE;
++      pWin->eStart = TK_UNBOUNDED;
++      pWin->eEnd = TK_CURRENT;
++    }
++  }
++  pWin->pFunc = pFunc;
++}
++
++/*
++** Context object passed through sqlite3WalkExprList() to
++** selectWindowRewriteExprCb() by selectWindowRewriteEList().
++*/
++typedef struct WindowRewrite WindowRewrite;
++struct WindowRewrite {
++  Window *pWin;
++  SrcList *pSrc;
++  ExprList *pSub;
++  Select *pSubSelect;             /* Current sub-select, if any */
++};
++
++/*
++** Callback function used by selectWindowRewriteEList(). If necessary,
++** this function appends to the output expression-list and updates 
++** expression (*ppExpr) in place.
++*/
++static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
++  struct WindowRewrite *p = pWalker->u.pRewrite;
++  Parse *pParse = pWalker->pParse;
++
++  /* If this function is being called from within a scalar sub-select
++  ** that used by the SELECT statement being processed, only process
++  ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
++  ** not process aggregates or window functions at all, as they belong
++  ** to the scalar sub-select.  */
++  if( p->pSubSelect ){
++    if( pExpr->op!=TK_COLUMN ){
++      return WRC_Continue;
++    }else{
++      int nSrc = p->pSrc->nSrc;
++      int i;
++      for(i=0; i<nSrc; i++){
++        if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
++      }
++      if( i==nSrc ) return WRC_Continue;
++    }
++  }
++
++  switch( pExpr->op ){
++
++    case TK_FUNCTION:
++      if( !ExprHasProperty(pExpr, EP_WinFunc) ){
++        break;
++      }else{
++        Window *pWin;
++        for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
++          if( pExpr->y.pWin==pWin ){
++            assert( pWin->pOwner==pExpr );
++            return WRC_Prune;
++          }
++        }
++      }
++      /* Fall through.  */
++
++    case TK_AGG_FUNCTION:
++    case TK_COLUMN: {
++      Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
++      p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
++      if( p->pSub ){
++        assert( ExprHasProperty(pExpr, EP_Static)==0 );
++        ExprSetProperty(pExpr, EP_Static);
++        sqlite3ExprDelete(pParse->db, pExpr);
++        ExprClearProperty(pExpr, EP_Static);
++        memset(pExpr, 0, sizeof(Expr));
++
++        pExpr->op = TK_COLUMN;
++        pExpr->iColumn = p->pSub->nExpr-1;
++        pExpr->iTable = p->pWin->iEphCsr;
++      }
++
++      break;
++    }
++
++    default: /* no-op */
++      break;
++  }
++
++  return WRC_Continue;
++}
++static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
++  struct WindowRewrite *p = pWalker->u.pRewrite;
++  Select *pSave = p->pSubSelect;
++  if( pSave==pSelect ){
++    return WRC_Continue;
++  }else{
++    p->pSubSelect = pSelect;
++    sqlite3WalkSelect(pWalker, pSelect);
++    p->pSubSelect = pSave;
++  }
++  return WRC_Prune;
++}
++
++
++/*
++** Iterate through each expression in expression-list pEList. For each:
++**
++**   * TK_COLUMN,
++**   * aggregate function, or
++**   * window function with a Window object that is not a member of the 
++**     Window list passed as the second argument (pWin).
++**
++** Append the node to output expression-list (*ppSub). And replace it
++** with a TK_COLUMN that reads the (N-1)th element of table 
++** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
++** appending the new one.
++*/
++static void selectWindowRewriteEList(
++  Parse *pParse, 
++  Window *pWin,
++  SrcList *pSrc,
++  ExprList *pEList,               /* Rewrite expressions in this list */
++  ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
++){
++  Walker sWalker;
++  WindowRewrite sRewrite;
++
++  memset(&sWalker, 0, sizeof(Walker));
++  memset(&sRewrite, 0, sizeof(WindowRewrite));
++
++  sRewrite.pSub = *ppSub;
++  sRewrite.pWin = pWin;
++  sRewrite.pSrc = pSrc;
++
++  sWalker.pParse = pParse;
++  sWalker.xExprCallback = selectWindowRewriteExprCb;
++  sWalker.xSelectCallback = selectWindowRewriteSelectCb;
++  sWalker.u.pRewrite = &sRewrite;
++
++  (void)sqlite3WalkExprList(&sWalker, pEList);
++
++  *ppSub = sRewrite.pSub;
++}
++
++/*
++** Append a copy of each expression in expression-list pAppend to
++** expression list pList. Return a pointer to the result list.
++*/
++static ExprList *exprListAppendList(
++  Parse *pParse,          /* Parsing context */
++  ExprList *pList,        /* List to which to append. Might be NULL */
++  ExprList *pAppend       /* List of values to append. Might be NULL */
++){
++  if( pAppend ){
++    int i;
++    int nInit = pList ? pList->nExpr : 0;
++    for(i=0; i<pAppend->nExpr; i++){
++      Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
++      pList = sqlite3ExprListAppend(pParse, pList, pDup);
++      if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
++    }
++  }
++  return pList;
++}
++
++/*
++** If the SELECT statement passed as the second argument does not invoke
++** any SQL window functions, this function is a no-op. Otherwise, it 
++** rewrites the SELECT statement so that window function xStep functions
++** are invoked in the correct order as described under "SELECT REWRITING"
++** at the top of this file.
++*/
++SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
++  int rc = SQLITE_OK;
++  if( p->pWin && p->pPrior==0 ){
++    Vdbe *v = sqlite3GetVdbe(pParse);
++    sqlite3 *db = pParse->db;
++    Select *pSub = 0;             /* The subquery */
++    SrcList *pSrc = p->pSrc;
++    Expr *pWhere = p->pWhere;
++    ExprList *pGroupBy = p->pGroupBy;
++    Expr *pHaving = p->pHaving;
++    ExprList *pSort = 0;
++
++    ExprList *pSublist = 0;       /* Expression list for sub-query */
++    Window *pMWin = p->pWin;      /* Master window object */
++    Window *pWin;                 /* Window object iterator */
++
++    p->pSrc = 0;
++    p->pWhere = 0;
++    p->pGroupBy = 0;
++    p->pHaving = 0;
++
++    /* Create the ORDER BY clause for the sub-select. This is the concatenation
++    ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
++    ** redundant, remove the ORDER BY from the parent SELECT.  */
++    pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
++    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
++    if( pSort && p->pOrderBy ){
++      if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
++        sqlite3ExprListDelete(db, p->pOrderBy);
++        p->pOrderBy = 0;
++      }
++    }
++
++    /* Assign a cursor number for the ephemeral table used to buffer rows.
++    ** The OpenEphemeral instruction is coded later, after it is known how
++    ** many columns the table will have.  */
++    pMWin->iEphCsr = pParse->nTab++;
++
++    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
++    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
++    pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
++
++    /* Append the PARTITION BY and ORDER BY expressions to the to the 
++    ** sub-select expression list. They are required to figure out where 
++    ** boundaries for partitions and sets of peer rows lie.  */
++    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
++    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
++
++    /* Append the arguments passed to each window function to the
++    ** sub-select expression list. Also allocate two registers for each
++    ** window function - one for the accumulator, another for interim
++    ** results.  */
++    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++      pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
++      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
++      if( pWin->pFilter ){
++        Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
++        pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
++      }
++      pWin->regAccum = ++pParse->nMem;
++      pWin->regResult = ++pParse->nMem;
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++    }
++
++    /* If there is no ORDER BY or PARTITION BY clause, and the window
++    ** function accepts zero arguments, and there are no other columns
++    ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
++    ** that pSublist is still NULL here. Add a constant expression here to 
++    ** keep everything legal in this case. 
++    */
++    if( pSublist==0 ){
++      pSublist = sqlite3ExprListAppend(pParse, 0, 
++          sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
++      );
++    }
++
++    pSub = sqlite3SelectNew(
++        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
++    );
++    p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
++    assert( p->pSrc || db->mallocFailed );
++    if( p->pSrc ){
++      p->pSrc->a[0].pSelect = pSub;
++      sqlite3SrcListAssignCursors(pParse, p->pSrc);
++      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
++        rc = SQLITE_NOMEM;
++      }else{
++        pSub->selFlags |= SF_Expanded;
++        p->selFlags &= ~SF_Aggregate;
++        sqlite3SelectPrep(pParse, pSub, 0);
++      }
++
++      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
++    }else{
++      sqlite3SelectDelete(db, pSub);
++    }
++    if( db->mallocFailed ) rc = SQLITE_NOMEM;
++  }
++
++  return rc;
++}
++
++/*
++** Free the Window object passed as the second argument.
++*/
++SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){
++  if( p ){
++    sqlite3ExprDelete(db, p->pFilter);
++    sqlite3ExprListDelete(db, p->pPartition);
++    sqlite3ExprListDelete(db, p->pOrderBy);
++    sqlite3ExprDelete(db, p->pEnd);
++    sqlite3ExprDelete(db, p->pStart);
++    sqlite3DbFree(db, p->zName);
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Free the linked list of Window objects starting at the second argument.
++*/
++SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
++  while( p ){
++    Window *pNext = p->pNextWin;
++    sqlite3WindowDelete(db, p);
++    p = pNext;
++  }
++}
++
++/*
++** The argument expression is an PRECEDING or FOLLOWING offset.  The
++** value should be a non-negative integer.  If the value is not a
++** constant, change it to NULL.  The fact that it is then a non-negative
++** integer will be caught later.  But it is important not to leave
++** variable values in the expression tree.
++*/
++static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
++  if( 0==sqlite3ExprIsConstant(pExpr) ){
++    sqlite3ExprDelete(pParse->db, pExpr);
++    pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
++  }
++  return pExpr;
++}
++
++/*
++** Allocate and return a new Window object describing a Window Definition.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowAlloc(
++  Parse *pParse,    /* Parsing context */
++  int eType,        /* Frame type. TK_RANGE or TK_ROWS */
++  int eStart,       /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
++  Expr *pStart,     /* Start window size if TK_PRECEDING or FOLLOWING */
++  int eEnd,         /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
++  Expr *pEnd        /* End window size if TK_FOLLOWING or PRECEDING */
++){
++  Window *pWin = 0;
++
++  /* Parser assures the following: */
++  assert( eType==TK_RANGE || eType==TK_ROWS );
++  assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
++           || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
++  assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
++           || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
++  assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
++  assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
++
++
++  /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
++  ** either "<expr> PRECEDING" or "<expr> FOLLOWING".
++  */
++  if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
++    sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
++    goto windowAllocErr;
++  }
++
++  /* Additionally, the
++  ** starting boundary type may not occur earlier in the following list than
++  ** the ending boundary type:
++  **
++  **   UNBOUNDED PRECEDING
++  **   <expr> PRECEDING
++  **   CURRENT ROW
++  **   <expr> FOLLOWING
++  **   UNBOUNDED FOLLOWING
++  **
++  ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
++  ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
++  ** frame boundary.
++  */
++  if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
++   || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
++  ){
++    sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
++    goto windowAllocErr;
++  }
++
++  pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
++  if( pWin==0 ) goto windowAllocErr;
++  pWin->eType = eType;
++  pWin->eStart = eStart;
++  pWin->eEnd = eEnd;
++  pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
++  pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
++  return pWin;
++
++windowAllocErr:
++  sqlite3ExprDelete(pParse->db, pEnd);
++  sqlite3ExprDelete(pParse->db, pStart);
++  return 0;
++}
++
++/*
++** Attach window object pWin to expression p.
++*/
++SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
++  if( p ){
++    assert( p->op==TK_FUNCTION );
++    /* This routine is only called for the parser.  If pWin was not
++    ** allocated due to an OOM, then the parser would fail before ever
++    ** invoking this routine */
++    if( ALWAYS(pWin) ){
++      p->y.pWin = pWin;
++      ExprSetProperty(p, EP_WinFunc);
++      pWin->pOwner = p;
++      if( p->flags & EP_Distinct ){
++        sqlite3ErrorMsg(pParse,
++           "DISTINCT is not supported for window functions");
++      }
++    }
++  }else{
++    sqlite3WindowDelete(pParse->db, pWin);
++  }
++}
++
++/*
++** Return 0 if the two window objects are identical, or non-zero otherwise.
++** Identical window objects can be processed in a single scan.
++*/
++SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
++  if( p1->eType!=p2->eType ) return 1;
++  if( p1->eStart!=p2->eStart ) return 1;
++  if( p1->eEnd!=p2->eEnd ) return 1;
++  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
++  if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
++  if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
++  if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
++  return 0;
++}
++
++
++/*
++** This is called by code in select.c before it calls sqlite3WhereBegin()
++** to begin iterating through the sub-query results. It is used to allocate
++** and initialize registers and cursors used by sqlite3WindowCodeStep().
++*/
++SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
++  Window *pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
++  nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
++  if( nPart ){
++    pMWin->regPart = pParse->nMem+1;
++    pParse->nMem += nPart;
++    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
++  }
++
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *p = pWin->pFunc;
++    if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
++      /* The inline versions of min() and max() require a single ephemeral
++      ** table and 3 registers. The registers are used as follows:
++      **
++      **   regApp+0: slot to copy min()/max() argument to for MakeRecord
++      **   regApp+1: integer value used to ensure keys are unique
++      **   regApp+2: output of MakeRecord
++      */
++      ExprList *pList = pWin->pOwner->x.pList;
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
++      pWin->csrApp = pParse->nTab++;
++      pWin->regApp = pParse->nMem+1;
++      pParse->nMem += 3;
++      if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
++        assert( pKeyInfo->aSortOrder[0]==0 );
++        pKeyInfo->aSortOrder[0] = 1;
++      }
++      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
++      sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++    else if( p->zName==nth_valueName || p->zName==first_valueName ){
++      /* Allocate two registers at pWin->regApp. These will be used to
++      ** store the start and end index of the current frame.  */
++      assert( pMWin->iEphCsr );
++      pWin->regApp = pParse->nMem+1;
++      pWin->csrApp = pParse->nTab++;
++      pParse->nMem += 2;
++      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
++    }
++    else if( p->zName==leadName || p->zName==lagName ){
++      assert( pMWin->iEphCsr );
++      pWin->csrApp = pParse->nTab++;
++      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
++    }
++  }
++}
++
++/*
++** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
++** value of the second argument to nth_value() (eCond==2) has just been
++** evaluated and the result left in register reg. This function generates VM
++** code to check that the value is a non-negative integer and throws an
++** exception if it is not.
++*/
++static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
++  static const char *azErr[] = {
++    "frame starting offset must be a non-negative integer",
++    "frame ending offset must be a non-negative integer",
++    "second argument to nth_value must be a positive integer"
++  };
++  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regZero = sqlite3GetTempReg(pParse);
++  assert( eCond==0 || eCond==1 || eCond==2 );
++  sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
++  sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverageIf(v, eCond==0);
++  VdbeCoverageIf(v, eCond==1);
++  VdbeCoverageIf(v, eCond==2);
++  sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
++  VdbeCoverageNeverNullIf(v, eCond==0);
++  VdbeCoverageNeverNullIf(v, eCond==1);
++  VdbeCoverageNeverNullIf(v, eCond==2);
++  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
++  sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
++  sqlite3ReleaseTempReg(pParse, regZero);
++}
++
++/*
++** Return the number of arguments passed to the window-function associated
++** with the object passed as the only argument to this function.
++*/
++static int windowArgCount(Window *pWin){
++  ExprList *pList = pWin->pOwner->x.pList;
++  return (pList ? pList->nExpr : 0);
++}
++
++/*
++** Generate VM code to invoke either xStep() (if bInverse is 0) or 
++** xInverse (if bInverse is non-zero) for each window function in the 
++** linked list starting at pMWin. Or, for built-in window functions
++** that do not use the standard function API, generate the required
++** inline VM code.
++**
++** If argument csr is greater than or equal to 0, then argument reg is
++** the first register in an array of registers guaranteed to be large
++** enough to hold the array of arguments for each function. In this case
++** the arguments are extracted from the current row of csr into the
++** array of registers before invoking OP_AggStep or OP_AggInverse
++**
++** Or, if csr is less than zero, then the array of registers at reg is
++** already populated with all columns from the current row of the sub-query.
++**
++** If argument regPartSize is non-zero, then it is a register containing the
++** number of rows in the current partition.
++*/
++static void windowAggStep(
++  Parse *pParse, 
++  Window *pMWin,                  /* Linked list of window functions */
++  int csr,                        /* Read arguments from this cursor */
++  int bInverse,                   /* True to invoke xInverse instead of xStep */
++  int reg,                        /* Array of registers */
++  int regPartSize                 /* Register containing size of partition */
++){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    int flags = pWin->pFunc->funcFlags;
++    int regArg;
++    int nArg = windowArgCount(pWin);
++
++    if( csr>=0 ){
++      int i;
++      for(i=0; i<nArg; i++){
++        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
++      }
++      regArg = reg;
++      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
++        if( nArg==0 ){
++          regArg = regPartSize;
++        }else{
++          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
++        }
++        nArg++;
++      }
++    }else{
++      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
++      regArg = reg + pWin->iArgCol;
++    }
++
++    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
++      && pWin->eStart!=TK_UNBOUNDED 
++    ){
++      int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
++      VdbeCoverage(v);
++      if( bInverse==0 ){
++        sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
++        sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
++        sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
++        sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
++      }else{
++        sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
++        VdbeCoverageNeverTaken(v);
++        sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
++        sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
++      }
++      sqlite3VdbeJumpHere(v, addrIsNull);
++    }else if( pWin->regApp ){
++      assert( pWin->pFunc->zName==nth_valueName
++           || pWin->pFunc->zName==first_valueName
++      );
++      assert( bInverse==0 || bInverse==1 );
++      sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
++    }else if( pWin->pFunc->zName==leadName
++           || pWin->pFunc->zName==lagName
++    ){
++      /* no-op */
++    }else{
++      int addrIf = 0;
++      if( pWin->pFilter ){
++        int regTmp;
++        assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
++        assert( nArg || pWin->pOwner->x.pList==0 );
++        if( csr>0 ){
++          regTmp = sqlite3GetTempReg(pParse);
++          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
++        }else{
++          regTmp = regArg + nArg;
++        }
++        addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
++        VdbeCoverage(v);
++        if( csr>0 ){
++          sqlite3ReleaseTempReg(pParse, regTmp);
++        }
++      }
++      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
++        CollSeq *pColl;
++        assert( nArg>0 );
++        pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
++        sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
++      }
++      sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
++                        bInverse, regArg, pWin->regAccum);
++      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++      sqlite3VdbeChangeP5(v, (u8)nArg);
++      if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
++    }
++  }
++}
++
++/*
++** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
++** (bFinal==1) for each window function in the linked list starting at
++** pMWin. Or, for built-in window-functions that do not use the standard
++** API, generate the equivalent VM code.
++*/
++static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
++     && pWin->eStart!=TK_UNBOUNDED 
++    ){
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++      sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
++      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
++      if( bFinal ){
++        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
++      }
++    }else if( pWin->regApp ){
++    }else{
++      if( bFinal ){
++        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
++        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++        sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
++        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++      }else{
++        sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
++                             pWin->regResult);
++        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++      }
++    }
++  }
++}
++
++/*
++** This function generates VM code to invoke the sub-routine at address
++** lblFlushPart once for each partition with the entire partition cached in
++** the Window.iEphCsr temp table.
++*/
++static void windowPartitionCache(
++  Parse *pParse,
++  Select *p,                      /* The rewritten SELECT statement */
++  WhereInfo *pWInfo,              /* WhereInfo to call WhereEnd() on */
++  int regFlushPart,               /* Register to use with Gosub lblFlushPart */
++  int lblFlushPart,               /* Subroutine to Gosub to */
++  int *pRegSize                   /* OUT: Register containing partition size */
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int iSubCsr = p->pSrc->a[0].iCursor;
++  int nSub = p->pSrc->a[0].pTab->nCol;
++  int k;
++
++  int reg = pParse->nMem+1;
++  int regRecord = reg+nSub;
++  int regRowid = regRecord+1;
++
++  *pRegSize = regRowid;
++  pParse->nMem += nSub + 2;
++
++  /* Load the column values for the row returned by the sub-select
++  ** into an array of registers starting at reg. */
++  for(k=0; k<nSub; k++){
++    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
++  }
++  sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
++
++  /* Check if this is the start of a new partition. If so, call the
++  ** flush_partition sub-routine.  */
++  if( pMWin->pPartition ){
++    int addr;
++    ExprList *pPart = pMWin->pPartition;
++    int nPart = pPart->nExpr;
++    int regNewPart = reg + pMWin->nBufferCol;
++    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
++
++    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
++    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
++    VdbeCoverageEqNe(v);
++    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
++    sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
++    VdbeComment((v, "call flush_partition"));
++  }
++
++  /* Buffer the current row in the ephemeral table. */
++  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
++  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
++
++  /* End of the input loop */
++  sqlite3WhereEnd(pWInfo);
++
++  /* Invoke "flush_partition" to deal with the final (or only) partition */
++  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
++  VdbeComment((v, "call flush_partition"));
++}
++
++/*
++** Invoke the sub-routine at regGosub (generated by code in select.c) to
++** return the current row of Window.iEphCsr. If all window functions are
++** aggregate window functions that use the standard API, a single
++** OP_Gosub instruction is all that this routine generates. Extra VM code
++** for per-row processing is only generated for the following built-in window
++** functions:
++**
++**   nth_value()
++**   first_value()
++**   lag()
++**   lead()
++*/
++static void windowReturnOneRow(
++  Parse *pParse,
++  Window *pMWin,
++  int regGosub,
++  int addrGosub
++){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *pFunc = pWin->pFunc;
++    if( pFunc->zName==nth_valueName
++     || pFunc->zName==first_valueName
++    ){
++      int csr = pWin->csrApp;
++      int lbl = sqlite3VdbeMakeLabel(v);
++      int tmpReg = sqlite3GetTempReg(pParse);
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++
++      if( pFunc->zName==nth_valueName ){
++        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
++        windowCheckIntValue(pParse, tmpReg, 2);
++      }else{
++        sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
++      }
++      sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
++      sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
++      VdbeCoverageNeverNull(v);
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
++      VdbeCoverageNeverTaken(v);
++      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
++      sqlite3VdbeResolveLabel(v, lbl);
++      sqlite3ReleaseTempReg(pParse, tmpReg);
++    }
++    else if( pFunc->zName==leadName || pFunc->zName==lagName ){
++      int nArg = pWin->pOwner->x.pList->nExpr;
++      int iEph = pMWin->iEphCsr;
++      int csr = pWin->csrApp;
++      int lbl = sqlite3VdbeMakeLabel(v);
++      int tmpReg = sqlite3GetTempReg(pParse);
++
++      if( nArg<3 ){
++        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++      }else{
++        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
++      }
++      sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
++      if( nArg<2 ){
++        int val = (pFunc->zName==leadName ? 1 : -1);
++        sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
++      }else{
++        int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
++        int tmpReg2 = sqlite3GetTempReg(pParse);
++        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
++        sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
++        sqlite3ReleaseTempReg(pParse, tmpReg2);
++      }
++
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
++      sqlite3VdbeResolveLabel(v, lbl);
++      sqlite3ReleaseTempReg(pParse, tmpReg);
++    }
++  }
++  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++}
++
++/*
++** Invoke the code generated by windowReturnOneRow() and, optionally, the
++** xInverse() function for each window function, for one or more rows
++** from the Window.iEphCsr temp table. This routine generates VM code
++** similar to:
++**
++**   while( regCtr>0 ){
++**     regCtr--;
++**     windowReturnOneRow()
++**     if( bInverse ){
++**       AggInverse
++**     }
++**     Next (Window.iEphCsr)
++**   }
++*/
++static void windowReturnRows(
++  Parse *pParse,
++  Window *pMWin,                  /* List of window functions */
++  int regCtr,                     /* Register containing number of rows */
++  int regGosub,                   /* Register for Gosub addrGosub */
++  int addrGosub,                  /* Address of sub-routine for ReturnOneRow */
++  int regInvArg,                  /* Array of registers for xInverse args */
++  int regInvSize                  /* Register containing size of partition */
++){
++  int addr;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  windowAggFinal(pParse, pMWin, 0);
++  addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
++  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
++  if( regInvArg ){
++    windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
++  }
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
++  VdbeCoverage(v);
++  sqlite3VdbeJumpHere(v, addr+1);   /* The OP_Goto */
++}
++
++/*
++** Generate code to set the accumulator register for each window function
++** in the linked list passed as the second argument to NULL. And perform
++** any equivalent initialization required by any built-in window functions
++** in the list.
++*/
++static int windowInitAccum(Parse *pParse, Window *pMWin){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regArg;
++  int nArg = 0;
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *pFunc = pWin->pFunc;
++    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++    nArg = MAX(nArg, windowArgCount(pWin));
++    if( pFunc->zName==nth_valueName
++     || pFunc->zName==first_valueName
++    ){
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++
++    if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
++      assert( pWin->eStart!=TK_UNBOUNDED );
++      sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++  }
++  regArg = pParse->nMem+1;
++  pParse->nMem += nArg;
++  return regArg;
++}
++
++
++/*
++** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
++** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
++** ROW". Pseudo-code for each follows.
++**
++** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
++**
++**     ...
++**       if( new partition ){
++**         Gosub flush_partition
++**       }
++**       Insert (record in eph-table)
++**     sqlite3WhereEnd()
++**     Gosub flush_partition
++**  
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrStart)
++**       OpenDup (iEphCsr -> csrEnd)
++**     }
++**     regStart = <expr1>                // PRECEDING expression
++**     regEnd = <expr2>                  // FOLLOWING expression
++**     if( regStart<0 || regEnd<0 ){ error! }
++**     Rewind (csr,csrStart,csrEnd)      // if EOF goto flush_partition_done
++**       Next(csrEnd)                    // if EOF skip Aggstep
++**       Aggstep (csrEnd)
++**       if( (regEnd--)<=0 ){
++**         AggFinal (xValue)
++**         Gosub addrGosub
++**         Next(csr)                // if EOF goto flush_partition_done
++**         if( (regStart--)<=0 ){
++**           AggInverse (csrStart)
++**           Next(csrStart)
++**         }
++**       }
++**   flush_partition_done:
++**     ResetSorter (csr)
++**     Return
++**
++** ROWS BETWEEN <expr> PRECEDING    AND CURRENT ROW
++** ROWS BETWEEN CURRENT ROW         AND <expr> FOLLOWING
++** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
++**
++**   These are similar to the above. For "CURRENT ROW", intialize the
++**   register to 0. For "UNBOUNDED PRECEDING" to infinity.
++**
++** ROWS BETWEEN <expr> PRECEDING    AND UNBOUNDED FOLLOWING
++** ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING
++**
++**     Rewind (csr,csrStart,csrEnd)    // if EOF goto flush_partition_done
++**     while( 1 ){
++**       Next(csrEnd)                  // Exit while(1) at EOF
++**       Aggstep (csrEnd)
++**     }
++**     while( 1 ){
++**       AggFinal (xValue)
++**       Gosub addrGosub
++**       Next(csr)                     // if EOF goto flush_partition_done
++**       if( (regStart--)<=0 ){
++**         AggInverse (csrStart)
++**         Next(csrStart)
++**       }
++**     }
++**
++**   For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() 
++**   condition is always true (as if regStart were initialized to 0).
++**
++** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++** 
++**   This is the only RANGE case handled by this routine. It modifies the
++**   second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
++**   be:
++**
++**     while( 1 ){
++**       AggFinal (xValue)
++**       while( 1 ){
++**         regPeer++
++**         Gosub addrGosub
++**         Next(csr)                     // if EOF goto flush_partition_done
++**         if( new peer ) break;
++**       }
++**       while( (regPeer--)>0 ){
++**         AggInverse (csrStart)
++**         Next(csrStart)
++**       }
++**     }
++**
++** ROWS BETWEEN <expr> FOLLOWING    AND <expr> FOLLOWING
++**
++**   regEnd = regEnd - regStart
++**   Rewind (csr,csrStart,csrEnd)   // if EOF goto flush_partition_done
++**     Aggstep (csrEnd)
++**     Next(csrEnd)                 // if EOF fall-through
++**     if( (regEnd--)<=0 ){
++**       if( (regStart--)<=0 ){
++**         AggFinal (xValue)
++**         Gosub addrGosub
++**         Next(csr)              // if EOF goto flush_partition_done
++**       }
++**       AggInverse (csrStart)
++**       Next (csrStart)
++**     }
++**
++** ROWS BETWEEN <expr> PRECEDING    AND <expr> PRECEDING
++**
++**   Replace the bit after "Rewind" in the above with:
++**
++**     if( (regEnd--)<=0 ){
++**       AggStep (csrEnd)
++**       Next (csrEnd)
++**     }
++**     AggFinal (xValue)
++**     Gosub addrGosub
++**     Next(csr)                  // if EOF goto flush_partition_done
++**     if( (regStart--)<=0 ){
++**       AggInverse (csr2)
++**       Next (csr2)
++**     }
++**
++*/
++static void windowCodeRowExprStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regFlushPart;               /* Register for "Gosub flush_partition" */
++  int lblFlushPart;               /* Label for "Gosub flush_partition" */
++  int lblFlushDone;               /* Label for "Gosub flush_partition_done" */
++
++  int regArg;
++  int addr;
++  int csrStart = pParse->nTab++;
++  int csrEnd = pParse->nTab++;
++  int regStart;                    /* Value of <expr> PRECEDING */
++  int regEnd;                      /* Value of <expr> FOLLOWING */
++  int addrGoto;
++  int addrTop;
++  int addrIfPos1 = 0;
++  int addrIfPos2 = 0;
++  int regSize = 0;
++
++  assert( pMWin->eStart==TK_PRECEDING 
++       || pMWin->eStart==TK_CURRENT 
++       || pMWin->eStart==TK_FOLLOWING 
++       || pMWin->eStart==TK_UNBOUNDED 
++  );
++  assert( pMWin->eEnd==TK_FOLLOWING 
++       || pMWin->eEnd==TK_CURRENT 
++       || pMWin->eEnd==TK_UNBOUNDED 
++       || pMWin->eEnd==TK_PRECEDING 
++  );
++
++  /* Allocate register and label for the "flush_partition" sub-routine. */
++  regFlushPart = ++pParse->nMem;
++  lblFlushPart = sqlite3VdbeMakeLabel(v);
++  lblFlushDone = sqlite3VdbeMakeLabel(v);
++
++  regStart = ++pParse->nMem;
++  regEnd = ++pParse->nMem;
++
++  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
++
++  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++
++  /* Start of "flush_partition" */
++  sqlite3VdbeResolveLabel(v, lblFlushPart);
++  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
++  VdbeCoverage(v);
++  VdbeComment((v, "Flush_partition subroutine"));
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
++
++  /* If either regStart or regEnd are not non-negative integers, throw 
++  ** an exception.  */
++  if( pMWin->pStart ){
++    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
++    windowCheckIntValue(pParse, regStart, 0);
++  }
++  if( pMWin->pEnd ){
++    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
++    windowCheckIntValue(pParse, regEnd, 1);
++  }
++
++  /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
++  **
++  **   if( regEnd<regStart ){
++  **     // The frame always consists of 0 rows
++  **     regStart = regSize;
++  **   }
++  **   regEnd = regEnd - regStart;
++  */
++  if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
++    assert( pMWin->pStart!=0 );
++    assert( pMWin->eEnd==TK_FOLLOWING );
++    sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
++    VdbeCoverageNeverNull(v);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
++    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
++  }
++
++  if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
++    assert( pMWin->pEnd!=0 );
++    assert( pMWin->eStart==TK_PRECEDING );
++    sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
++    VdbeCoverageNeverNull(v);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
++  }
++
++  /* Initialize the accumulator register for each window function to NULL */
++  regArg = windowInitAccum(pParse, pMWin);
++
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
++  VdbeCoverageNeverTaken(v);
++  sqlite3VdbeChangeP5(v, 1);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
++  VdbeCoverageNeverTaken(v);
++  sqlite3VdbeChangeP5(v, 1);
++
++  /* Invoke AggStep function for each window function using the row that
++  ** csrEnd currently points to. Or, if csrEnd is already at EOF,
++  ** do nothing.  */
++  addrTop = sqlite3VdbeCurrentAddr(v);
++  if( pMWin->eEnd==TK_PRECEDING ){
++    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
++    VdbeCoverage(v);
++  }
++  sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  addr = sqlite3VdbeAddOp0(v, OP_Goto);
++  windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
++  if( pMWin->eEnd==TK_UNBOUNDED ){
++    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
++    sqlite3VdbeJumpHere(v, addr);
++    addrTop = sqlite3VdbeCurrentAddr(v);
++  }else{
++    sqlite3VdbeJumpHere(v, addr);
++    if( pMWin->eEnd==TK_PRECEDING ){
++      sqlite3VdbeJumpHere(v, addrIfPos1);
++    }
++  }
++
++  if( pMWin->eEnd==TK_FOLLOWING ){
++    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
++    VdbeCoverage(v);
++  }
++  if( pMWin->eStart==TK_FOLLOWING ){
++    addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
++    VdbeCoverage(v);
++  }
++  windowAggFinal(pParse, pMWin, 0);
++  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
++  if( pMWin->eStart==TK_FOLLOWING ){
++    sqlite3VdbeJumpHere(v, addrIfPos2);
++  }
++
++  if( pMWin->eStart==TK_CURRENT 
++   || pMWin->eStart==TK_PRECEDING 
++   || pMWin->eStart==TK_FOLLOWING 
++  ){
++    int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
++    if( pMWin->eStart==TK_PRECEDING ){
++      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
++      VdbeCoverage(v);
++    }
++    if( pMWin->eStart==TK_FOLLOWING ){
++      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
++    }else{
++      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
++      VdbeCoverageAlwaysTaken(v);
++    }
++    windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
++    sqlite3VdbeResolveLabel(v, lblSkipInverse);
++  }
++  if( pMWin->eEnd==TK_FOLLOWING ){
++    sqlite3VdbeJumpHere(v, addrIfPos1);
++  }
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
++
++  /* flush_partition_done: */
++  sqlite3VdbeResolveLabel(v, lblFlushDone);
++  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
++  VdbeComment((v, "end flush_partition subroutine"));
++
++  /* Jump to here to skip over flush_partition */
++  sqlite3VdbeJumpHere(v, addrGoto);
++}
++
++/*
++** This function does the work of sqlite3WindowCodeStep() for cases that
++** would normally be handled by windowCodeDefaultStep() when there are
++** one or more built-in window-functions that require the entire partition
++** to be cached in a temp table before any rows can be returned. Additionally.
++** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
++** this function.
++**
++** Pseudo-code corresponding to the VM code generated by this function
++** for each type of window follows.
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     Integer ctr 0
++**     foreach row (csrLead){
++**       if( new peer ){
++**         AggFinal (xValue)
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           Next iEphCsr
++**         }
++**         Integer ctr 0
++**       }
++**       AggStep (csrLead)
++**       Incr ctr
++**     }
++**
++**     AggFinal (xFinalize)
++**     for(i=0; i<ctr; i++){
++**       Gosub addrGosub
++**       Next iEphCsr
++**     }
++**
++**     ResetSorter (csr)
++**     Return
++**
++** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   As above, except that the "if( new peer )" branch is always taken.
++**
++** RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
++**
++**   As above, except that each of the for() loops becomes:
++**
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           AggInverse (iEphCsr)
++**           Next iEphCsr
++**         }
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     foreach row (csrLead) {
++**       AggStep (csrLead)
++**     }
++**     foreach row (iEphCsr) {
++**       Gosub addrGosub
++**     }
++** 
++** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     foreach row (csrLead){
++**       AggStep (csrLead)
++**     }
++**     Rewind (csrLead)
++**     Integer ctr 0
++**     foreach row (csrLead){
++**       if( new peer ){
++**         AggFinal (xValue)
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           AggInverse (iEphCsr)
++**           Next iEphCsr
++**         }
++**         Integer ctr 0
++**       }
++**       Incr ctr
++**     }
++**
++**     AggFinal (xFinalize)
++**     for(i=0; i<ctr; i++){
++**       Gosub addrGosub
++**       Next iEphCsr
++**     }
++**
++**     ResetSorter (csr)
++**     Return
++*/
++static void windowCodeCacheStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int k;
++  int addr;
++  ExprList *pPart = pMWin->pPartition;
++  ExprList *pOrderBy = pMWin->pOrderBy;
++  int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
++  int regNewPeer;
++
++  int addrGoto;                   /* Address of Goto used to jump flush_par.. */
++  int addrNext;                   /* Jump here for next iteration of loop */
++  int regFlushPart;
++  int lblFlushPart;
++  int csrLead;
++  int regCtr;
++  int regArg;                     /* Register array to martial function args */
++  int regSize;
++  int lblEmpty;
++  int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT 
++          && pMWin->eEnd==TK_UNBOUNDED;
++
++  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
++       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
++  );
++
++  lblEmpty = sqlite3VdbeMakeLabel(v);
++  regNewPeer = pParse->nMem+1;
++  pParse->nMem += nPeer;
++
++  /* Allocate register and label for the "flush_partition" sub-routine. */
++  regFlushPart = ++pParse->nMem;
++  lblFlushPart = sqlite3VdbeMakeLabel(v);
++
++  csrLead = pParse->nTab++;
++  regCtr = ++pParse->nMem;
++
++  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
++  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++
++  /* Start of "flush_partition" */
++  sqlite3VdbeResolveLabel(v, lblFlushPart);
++  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
++
++  /* Initialize the accumulator register for each window function to NULL */
++  regArg = windowInitAccum(pParse, pMWin);
++
++  sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
++  VdbeCoverageNeverTaken(v);
++
++  if( bReverse ){
++    int addr2 = sqlite3VdbeCurrentAddr(v);
++    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
++    sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
++    VdbeCoverageNeverTaken(v);
++  }
++  addrNext = sqlite3VdbeCurrentAddr(v);
++
++  if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
++    int bCurrent = (pMWin->eStart==TK_CURRENT);
++    int addrJump = 0;             /* Address of OP_Jump below */
++    if( pMWin->eType==TK_RANGE ){
++      int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
++      int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
++      for(k=0; k<nPeer; k++){
++        sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
++      }
++      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
++      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
++    }
++
++    windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 
++        (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
++    );
++    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++  }
++
++  if( bReverse==0 ){
++    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
++  }
++  sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
++  sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
++  VdbeCoverage(v);
++
++  windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
++
++  sqlite3VdbeResolveLabel(v, lblEmpty);
++  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
++
++  /* Jump to here to skip over flush_partition */
++  sqlite3VdbeJumpHere(v, addrGoto);
++}
++
++
++/*
++** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   ...
++**     if( new partition ){
++**       AggFinal (xFinalize)
++**       Gosub addrGosub
++**       ResetSorter eph-table
++**     }
++**     else if( new peer ){
++**       AggFinal (xValue)
++**       Gosub addrGosub
++**       ResetSorter eph-table
++**     }
++**     AggStep
++**     Insert (record into eph-table)
++**   sqlite3WhereEnd()
++**   AggFinal (xFinalize)
++**   Gosub addrGosub
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++**
++**   As above, except take no action for a "new peer". Invoke
++**   the sub-routine once only for each partition.
++**
++** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
++**
++**   As above, except that the "new peer" condition is handled in the
++**   same way as "new partition" (so there is no "else if" block).
++**
++** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++** 
++**   As above, except assume every row is a "new peer".
++*/
++static void windowCodeDefaultStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int k;
++  int iSubCsr = p->pSrc->a[0].iCursor;
++  int nSub = p->pSrc->a[0].pTab->nCol;
++  int reg = pParse->nMem+1;
++  int regRecord = reg+nSub;
++  int regRowid = regRecord+1;
++  int addr;
++  ExprList *pPart = pMWin->pPartition;
++  ExprList *pOrderBy = pMWin->pOrderBy;
++
++  assert( pMWin->eType==TK_RANGE 
++      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
++  );
++
++  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
++       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
++  );
++
++  if( pMWin->eEnd==TK_UNBOUNDED ){
++    pOrderBy = 0;
++  }
++
++  pParse->nMem += nSub + 2;
++
++  /* Load the individual column values of the row returned by
++  ** the sub-select into an array of registers. */
++  for(k=0; k<nSub; k++){
++    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
++  }
++
++  /* Check if this is the start of a new partition or peer group. */
++  if( pPart || pOrderBy ){
++    int nPart = (pPart ? pPart->nExpr : 0);
++    int addrGoto = 0;
++    int addrJump = 0;
++    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
++
++    if( pPart ){
++      int regNewPart = reg + pMWin->nBufferCol;
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
++      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
++      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++      VdbeCoverageEqNe(v);
++      windowAggFinal(pParse, pMWin, 1);
++      if( pOrderBy ){
++        addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++      }
++    }
++
++    if( pOrderBy ){
++      int regNewPeer = reg + pMWin->nBufferCol + nPart;
++      int regPeer = pMWin->regPart + nPart;
++
++      if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++      if( pMWin->eType==TK_RANGE ){
++        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
++        addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
++        sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++        addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++        VdbeCoverage(v);
++      }else{
++        addrJump = 0;
++      }
++      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
++      if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
++    }
++
++    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
++    VdbeCoverage(v);
++
++    sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++    sqlite3VdbeAddOp3(
++        v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
++    );
++
++    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++  }
++
++  /* Invoke step function for window functions */
++  windowAggStep(pParse, pMWin, -1, 0, reg, 0);
++
++  /* Buffer the current row in the ephemeral table. */
++  if( pMWin->nBufferCol>0 ){
++    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
++  }else{
++    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
++    sqlite3VdbeAppendP4(v, (void*)"", 0);
++  }
++  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
++  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
++
++  /* End the database scan loop. */
++  sqlite3WhereEnd(pWInfo);
++
++  windowAggFinal(pParse, pMWin, 1);
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
++  VdbeCoverage(v);
++}
++
++/*
++** Allocate and return a duplicate of the Window object indicated by the
++** third argument. Set the Window.pOwner field of the new object to
++** pOwner.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
++  Window *pNew = 0;
++  if( ALWAYS(p) ){
++    pNew = sqlite3DbMallocZero(db, sizeof(Window));
++    if( pNew ){
++      pNew->zName = sqlite3DbStrDup(db, p->zName);
++      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
++      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
++      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
++      pNew->eType = p->eType;
++      pNew->eEnd = p->eEnd;
++      pNew->eStart = p->eStart;
++      pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
++      pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
++      pNew->pOwner = pOwner;
++    }
++  }
++  return pNew;
++}
++
++/*
++** Return a copy of the linked list of Window objects passed as the
++** second argument.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
++  Window *pWin;
++  Window *pRet = 0;
++  Window **pp = &pRet;
++
++  for(pWin=p; pWin; pWin=pWin->pNextWin){
++    *pp = sqlite3WindowDup(db, 0, pWin);
++    if( *pp==0 ) break;
++    pp = &((*pp)->pNextWin);
++  }
++
++  return pRet;
++}
++
++/*
++** sqlite3WhereBegin() has already been called for the SELECT statement 
++** passed as the second argument when this function is invoked. It generates
++** code to populate the Window.regResult register for each window function and
++** invoke the sub-routine at instruction addrGosub once for each row.
++** This function calls sqlite3WhereEnd() before returning. 
++*/
++SQLITE_PRIVATE void sqlite3WindowCodeStep(
++  Parse *pParse,                  /* Parse context */
++  Select *p,                      /* Rewritten SELECT statement */
++  WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
++  int regGosub,                   /* Register for OP_Gosub */
++  int addrGosub                   /* OP_Gosub here to return each row */
++){
++  Window *pMWin = p->pWin;
++
++  /* There are three different functions that may be used to do the work
++  ** of this one, depending on the window frame and the specific built-in
++  ** window functions used (if any).
++  **
++  ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
++  **
++  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++  **
++  ** The exception is because windowCodeRowExprStep() implements all window
++  ** frame types by caching the entire partition in a temp table, and
++  ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
++  ** implement without such a cache.
++  **
++  ** windowCodeCacheStep() is used for:
++  **
++  **   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++  **
++  ** It is also used for anything not handled by windowCodeRowExprStep() 
++  ** that invokes a built-in window function that requires the entire 
++  ** partition to be cached in a temp table before any rows are returned
++  ** (e.g. nth_value() or percent_rank()).
++  **
++  ** Finally, assuming there is no built-in window function that requires
++  ** the partition to be cached, windowCodeDefaultStep() is used for:
++  **
++  **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++  **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++  **   RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
++  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++  **
++  ** windowCodeDefaultStep() is the only one of the three functions that
++  ** does not cache each partition in a temp table before beginning to
++  ** return rows.
++  */
++  if( pMWin->eType==TK_ROWS 
++   && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
++  ){
++    VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
++    windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
++  }else{
++    Window *pWin;
++    int bCache = 0;               /* True to use CacheStep() */
++
++    if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
++      bCache = 1;
++    }else{
++      for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++        FuncDef *pFunc = pWin->pFunc;
++        if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
++         || (pFunc->zName==nth_valueName)
++         || (pFunc->zName==first_valueName)
++         || (pFunc->zName==leadName)
++         || (pFunc->zName==lagName)
++        ){
++          bCache = 1;
++          break;
++        }
++      }
++    }
++
++    /* Otherwise, call windowCodeDefaultStep().  */
++    if( bCache ){
++      VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
++      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
++    }else{
++      VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
++      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
++    }
++  }
++}
++
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/************** End of window.c **********************************************/
+ /************** Begin file parse.c *******************************************/
+ /*
+ ** 2000-05-29
+@@ -136559,6 +146829,7 @@
+ ** input grammar file:
+ */
+ /* #include <stdio.h> */
++/* #include <assert.h> */
+ /************ Begin %include sections from the grammar ************************/
+ 
+ /* #include "sqliteInt.h" */
+@@ -136600,15 +146871,6 @@
+ #define YYMALLOCARGTYPE  u64
+ 
+ /*
+-** An instance of this structure holds information about the
+-** LIMIT clause of a SELECT statement.
+-*/
+-struct LimitVal {
+-  Expr *pLimit;    /* The LIMIT expression.  NULL if there is no limit */
+-  Expr *pOffset;   /* The OFFSET expression.  NULL if there is none */
+-};
+-
+-/*
+ ** An instance of the following structure describes the event of a
+ ** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
+ ** TK_DELETE, or TK_INSTEAD.  If the event is of the form
+@@ -136619,6 +146881,8 @@
+ */
+ struct TrigEvent { int a; IdList * b; };
+ 
++struct FrameBound     { int eType; Expr *pExpr; };
++
+ /*
+ ** Disable lookaside memory allocation for objects that might be
+ ** shared across database connections.
+@@ -136651,26 +146915,26 @@
+     }
+   }
+ 
+-  /* This is a utility routine used to set the ExprSpan.zStart and
+-  ** ExprSpan.zEnd values of pOut so that the span covers the complete
+-  ** range of text beginning with pStart and going to the end of pEnd.
+-  */
+-  static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
+-    pOut->zStart = pStart->z;
+-    pOut->zEnd = &pEnd->z[pEnd->n];
+-  }
+ 
+   /* Construct a new Expr object from a single identifier.  Use the
+   ** new Expr to populate pOut.  Set the span of pOut to be the identifier
+   ** that created the expression.
+   */
+-  static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
++  static Expr *tokenExpr(Parse *pParse, int op, Token t){
+     Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
+     if( p ){
+-      memset(p, 0, sizeof(Expr));
++      /* memset(p, 0, sizeof(Expr)); */
+       p->op = (u8)op;
++      p->affinity = 0;
+       p->flags = EP_Leaf;
+       p->iAgg = -1;
++      p->pLeft = p->pRight = 0;
++      p->x.pList = 0;
++      p->pAggInfo = 0;
++      p->y.pTab = 0;
++      p->op2 = 0;
++      p->iTable = 0;
++      p->iColumn = 0;
+       p->u.zToken = (char*)&p[1];
+       memcpy(p->u.zToken, t.z, t.n);
+       p->u.zToken[t.n] = 0;
+@@ -136681,51 +146945,19 @@
+ #if SQLITE_MAX_EXPR_DEPTH>0
+       p->nHeight = 1;
+ #endif  
++      if( IN_RENAME_OBJECT ){
++        return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t);
++      }
+     }
+-    pOut->pExpr = p;
+-    pOut->zStart = t.z;
+-    pOut->zEnd = &t.z[t.n];
++    return p;
+   }
+ 
+-  /* This routine constructs a binary expression node out of two ExprSpan
+-  ** objects and uses the result to populate a new ExprSpan object.
+-  */
+-  static void spanBinaryExpr(
+-    Parse *pParse,      /* The parsing context.  Errors accumulate here */
+-    int op,             /* The binary operation */
+-    ExprSpan *pLeft,    /* The left operand, and output */
+-    ExprSpan *pRight    /* The right operand */
+-  ){
+-    pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
+-    pLeft->zEnd = pRight->zEnd;
+-  }
+ 
+-  /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
+-  ** outside of *ppExpr.
+-  */
+-  static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
+-    if( doNot ){
+-      pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
+-    }
+-  }
+-
+-  /* Construct an expression node for a unary postfix operator
+-  */
+-  static void spanUnaryPostfix(
+-    Parse *pParse,         /* Parsing context to record errors */
+-    int op,                /* The operator */
+-    ExprSpan *pOperand,    /* The operand, and output */
+-    Token *pPostOp         /* The operand token for setting the span */
+-  ){
+-    pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
+-    pOperand->zEnd = &pPostOp->z[pPostOp->n];
+-  }                           
+-
+   /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
+   ** unary TK_ISNULL or TK_NOTNULL expression. */
+   static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
+     sqlite3 *db = pParse->db;
+-    if( pA && pY && pY->op==TK_NULL ){
++    if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){
+       pA->op = (u8)op;
+       sqlite3ExprDelete(db, pA->pRight);
+       pA->pRight = 0;
+@@ -136732,20 +146964,6 @@
+     }
+   }
+ 
+-  /* Construct an expression node for a unary prefix operator
+-  */
+-  static void spanUnaryPrefix(
+-    ExprSpan *pOut,        /* Write the new expression node here */
+-    Parse *pParse,         /* Parsing context to record errors */
+-    int op,                /* The operator */
+-    ExprSpan *pOperand,    /* The operand */
+-    Token *pPreOp         /* The operand token for setting the span */
+-  ){
+-    pOut->zStart = pPreOp->z;
+-    pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
+-    pOut->zEnd = pOperand->zEnd;
+-  }
+-
+   /* Add a single new term to an ExprList that is used to store a
+   ** list of identifiers.  Report an error if the ID list contains
+   ** a COLLATE clause or an ASC or DESC keyword, except ignore the
+@@ -136808,64 +147026,78 @@
+ **                       zero the stack is dynamically sized using realloc()
+ **    sqlite3ParserARG_SDECL     A static variable declaration for the %extra_argument
+ **    sqlite3ParserARG_PDECL     A parameter declaration for the %extra_argument
++**    sqlite3ParserARG_PARAM     Code to pass %extra_argument as a subroutine parameter
+ **    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
+ **    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
++**    sqlite3ParserCTX_*         As sqlite3ParserARG_ except for %extra_context
+ **    YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
+ **    YYNSTATE           the combined number of states.
+ **    YYNRULE            the number of rules in the grammar
++**    YYNTOKEN           Number of terminal symbols
+ **    YY_MAX_SHIFT       Maximum value for shift actions
+ **    YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+ **    YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+-**    YY_MIN_REDUCE      Maximum value for reduce actions
+ **    YY_ERROR_ACTION    The yy_action[] code for syntax error
+ **    YY_ACCEPT_ACTION   The yy_action[] code for accept
+ **    YY_NO_ACTION       The yy_action[] code for no-op
++**    YY_MIN_REDUCE      Minimum value for reduce actions
++**    YY_MAX_REDUCE      Maximum value for reduce actions
+ */
+ #ifndef INTERFACE
+ # define INTERFACE 1
+ #endif
+ /************* Begin control #defines *****************************************/
+-#define YYCODETYPE unsigned char
+-#define YYNOCODE 252
++#define YYCODETYPE unsigned short int
++#define YYNOCODE 277
+ #define YYACTIONTYPE unsigned short int
+-#define YYWILDCARD 69
++#define YYWILDCARD 91
+ #define sqlite3ParserTOKENTYPE Token
+ typedef union {
+   int yyinit;
+   sqlite3ParserTOKENTYPE yy0;
+-  Expr* yy72;
+-  TriggerStep* yy145;
+-  ExprList* yy148;
+-  SrcList* yy185;
+-  ExprSpan yy190;
+-  int yy194;
+-  Select* yy243;
+-  IdList* yy254;
+-  With* yy285;
+-  struct TrigEvent yy332;
+-  struct LimitVal yy354;
+-  struct {int value; int mask;} yy497;
++  Expr* yy18;
++  struct TrigEvent yy34;
++  IdList* yy48;
++  int yy70;
++  struct {int value; int mask;} yy111;
++  struct FrameBound yy119;
++  SrcList* yy135;
++  TriggerStep* yy207;
++  Window* yy327;
++  Upsert* yy340;
++  const char* yy392;
++  ExprList* yy420;
++  With* yy449;
++  Select* yy489;
+ } YYMINORTYPE;
+ #ifndef YYSTACKDEPTH
+ #define YYSTACKDEPTH 100
+ #endif
+-#define sqlite3ParserARG_SDECL Parse *pParse;
+-#define sqlite3ParserARG_PDECL ,Parse *pParse
+-#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
+-#define sqlite3ParserARG_STORE yypParser->pParse = pParse
++#define sqlite3ParserARG_SDECL
++#define sqlite3ParserARG_PDECL
++#define sqlite3ParserARG_PARAM
++#define sqlite3ParserARG_FETCH
++#define sqlite3ParserARG_STORE
++#define sqlite3ParserCTX_SDECL Parse *pParse;
++#define sqlite3ParserCTX_PDECL ,Parse *pParse
++#define sqlite3ParserCTX_PARAM ,pParse
++#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
++#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
+ #define YYFALLBACK 1
+-#define YYNSTATE             455
+-#define YYNRULE              329
+-#define YY_MAX_SHIFT         454
+-#define YY_MIN_SHIFTREDUCE   664
+-#define YY_MAX_SHIFTREDUCE   992
+-#define YY_MIN_REDUCE        993
+-#define YY_MAX_REDUCE        1321
+-#define YY_ERROR_ACTION      1322
+-#define YY_ACCEPT_ACTION     1323
+-#define YY_NO_ACTION         1324
++#define YYNSTATE             521
++#define YYNRULE              367
++#define YYNTOKEN             155
++#define YY_MAX_SHIFT         520
++#define YY_MIN_SHIFTREDUCE   756
++#define YY_MAX_SHIFTREDUCE   1122
++#define YY_ERROR_ACTION      1123
++#define YY_ACCEPT_ACTION     1124
++#define YY_NO_ACTION         1125
++#define YY_MIN_REDUCE        1126
++#define YY_MAX_REDUCE        1492
+ /************* End control #defines *******************************************/
++#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
+ 
+ /* Define the yytestcase() macro to be a no-op if is not already defined
+ ** otherwise.
+@@ -136894,9 +147126,6 @@
+ **   N between YY_MIN_SHIFTREDUCE       Shift to an arbitrary state then
+ **     and YY_MAX_SHIFTREDUCE           reduce by rule N-YY_MIN_SHIFTREDUCE.
+ **
+-**   N between YY_MIN_REDUCE            Reduce by rule N-YY_MIN_REDUCE
+-**     and YY_MAX_REDUCE
+-**
+ **   N == YY_ERROR_ACTION               A syntax error has occurred.
+ **
+ **   N == YY_ACCEPT_ACTION              The parser accepts its input.
+@@ -136904,6 +147133,9 @@
+ **   N == YY_NO_ACTION                  No such action.  Denotes unused
+ **                                      slots in the yy_action[] table.
+ **
++**   N between YY_MIN_REDUCE            Reduce by rule N-YY_MIN_REDUCE
++**     and YY_MAX_REDUCE
++**
+ ** The action table is constructed as a single large table named yy_action[].
+ ** Given state S and lookahead X, the action is computed as either:
+ **
+@@ -136910,19 +147142,13 @@
+ **    (A)   N = yy_action[ yy_shift_ofst[S] + X ]
+ **    (B)   N = yy_default[S]
+ **
+-** The (A) formula is preferred.  The B formula is used instead if:
+-**    (1)  The yy_shift_ofst[S]+X value is out of range, or
+-**    (2)  yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
+-**    (3)  yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
+-** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
+-** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
+-** Hence only tests (1) and (2) need to be evaluated.)
++** The (A) formula is preferred.  The B formula is used instead if
++** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
+ **
+ ** The formulas above are for computing the action when the lookahead is
+ ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
+ ** a reduce action) then the yy_reduce_ofst[] array is used in place of
+-** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+-** YY_SHIFT_USE_DFLT.
++** the yy_shift_ofst[] array.
+ **
+ ** The following are the tables generated in this section:
+ **
+@@ -136936,463 +147162,568 @@
+ **  yy_default[]       Default action for each state.
+ **
+ *********** Begin parsing tables **********************************************/
+-#define YY_ACTTAB_COUNT (1565)
++#define YY_ACTTAB_COUNT (2009)
+ static const YYACTIONTYPE yy_action[] = {
+- /*     0 */   324,  410,  342,  747,  747,  203,  939,  353,  969,   98,
+- /*    10 */    98,   98,   98,   91,   96,   96,   96,   96,   95,   95,
+- /*    20 */    94,   94,   94,   93,  350, 1323,  155,  155,    2,  808,
+- /*    30 */   971,  971,   98,   98,   98,   98,   20,   96,   96,   96,
+- /*    40 */    96,   95,   95,   94,   94,   94,   93,  350,   92,   89,
+- /*    50 */   178,   99,  100,   90,  847,  850,  839,  839,   97,   97,
+- /*    60 */    98,   98,   98,   98,  350,   96,   96,   96,   96,   95,
+- /*    70 */    95,   94,   94,   94,   93,  350,  324,  339,  969,  262,
+- /*    80 */   364,  251,  212,  169,  287,  404,  282,  403,  199,  786,
+- /*    90 */   242,  411,   21,  950,  378,  280,   93,  350,  787,   95,
+- /*   100 */    95,   94,   94,   94,   93,  350,  971,  971,   96,   96,
+- /*   110 */    96,   96,   95,   95,   94,   94,   94,   93,  350,  808,
+- /*   120 */   328,  242,  411, 1235,  826, 1235,  132,   99,  100,   90,
+- /*   130 */   847,  850,  839,  839,   97,   97,   98,   98,   98,   98,
+- /*   140 */   449,   96,   96,   96,   96,   95,   95,   94,   94,   94,
+- /*   150 */    93,  350,  324,  819,  348,  347,  120,  818,  120,   75,
+- /*   160 */    52,   52,  950,  951,  952, 1084,  977,  146,  360,  262,
+- /*   170 */   369,  261,  950,  975,  954,  976,   92,   89,  178,  370,
+- /*   180 */   230,  370,  971,  971, 1141,  360,  359,  101,  818,  818,
+- /*   190 */   820,  383,   24, 1286,  380,  427,  412,  368,  978,  379,
+- /*   200 */   978, 1032,  324,   99,  100,   90,  847,  850,  839,  839,
+- /*   210 */    97,   97,   98,   98,   98,   98,  372,   96,   96,   96,
+- /*   220 */    96,   95,   95,   94,   94,   94,   93,  350,  950,  132,
+- /*   230 */   890,  449,  971,  971,  890,   60,   94,   94,   94,   93,
+- /*   240 */   350,  950,  951,  952,  954,  103,  360,  950,  384,  333,
+- /*   250 */   697,   52,   52,   99,  100,   90,  847,  850,  839,  839,
+- /*   260 */    97,   97,   98,   98,   98,   98, 1022,   96,   96,   96,
+- /*   270 */    96,   95,   95,   94,   94,   94,   93,  350,  324,  454,
+- /*   280 */   995,  449,  227,   61,  157,  243,  343,  114, 1025, 1211,
+- /*   290 */   147,  826,  950,  372, 1071,  950,  319,  950,  951,  952,
+- /*   300 */   194,   10,   10,  401,  398,  397, 1211, 1213,  971,  971,
+- /*   310 */   757,  171,  170,  157,  396,  336,  950,  951,  952,  697,
+- /*   320 */   819,  310,  153,  950,  818,  320,   82,   23,   80,   99,
+- /*   330 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
+- /*   340 */    98,   98,  888,   96,   96,   96,   96,   95,   95,   94,
+- /*   350 */    94,   94,   93,  350,  324,  818,  818,  820,  277,  231,
+- /*   360 */   300,  950,  951,  952,  950,  951,  952, 1211,  194,   25,
+- /*   370 */   449,  401,  398,  397,  950,  354,  300,  449,  950,   74,
+- /*   380 */   449,    1,  396,  132,  971,  971,  950,  224,  224,  808,
+- /*   390 */    10,   10,  950,  951,  952, 1290,  132,   52,   52,  414,
+- /*   400 */    52,   52, 1063, 1063,  338,   99,  100,   90,  847,  850,
+- /*   410 */   839,  839,   97,   97,   98,   98,   98,   98, 1114,   96,
+- /*   420 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  350,
+- /*   430 */   324, 1113,  427,  417,  701,  427,  426, 1260, 1260,  262,
+- /*   440 */   369,  261,  950,  950,  951,  952,  752,  950,  951,  952,
+- /*   450 */   449,  751,  449, 1058, 1037,  950,  951,  952,  442,  706,
+- /*   460 */   971,  971, 1058,  393,   92,   89,  178,  446,  446,  446,
+- /*   470 */    51,   51,   52,   52,  438,  773, 1024,   92,   89,  178,
+- /*   480 */   172,   99,  100,   90,  847,  850,  839,  839,   97,   97,
+- /*   490 */    98,   98,   98,   98,  198,   96,   96,   96,   96,   95,
+- /*   500 */    95,   94,   94,   94,   93,  350,  324,  427,  407,  909,
+- /*   510 */   694,  950,  951,  952,   92,   89,  178,  224,  224,  157,
+- /*   520 */   241,  221,  418,  299,  771,  910,  415,  374,  449,  414,
+- /*   530 */    58,  323, 1061, 1061, 1242,  378,  971,  971,  378,  772,
+- /*   540 */   448,  911,  362,  735,  296,  681,    9,    9,   52,   52,
+- /*   550 */   234,  329,  234,  256,  416,  736,  280,   99,  100,   90,
+- /*   560 */   847,  850,  839,  839,   97,   97,   98,   98,   98,   98,
+- /*   570 */   449,   96,   96,   96,   96,   95,   95,   94,   94,   94,
+- /*   580 */    93,  350,  324,  422,   72,  449,  827,  120,  367,  449,
+- /*   590 */    10,   10,    5,  301,  203,  449,  177,  969,  253,  419,
+- /*   600 */   255,  771,  200,  175,  233,   10,   10,  836,  836,   36,
+- /*   610 */    36, 1289,  971,  971,  724,   37,   37,  348,  347,  424,
+- /*   620 */   203,  260,  771,  969,  232,  930, 1316,  870,  337, 1316,
+- /*   630 */   421,  848,  851,   99,  100,   90,  847,  850,  839,  839,
+- /*   640 */    97,   97,   98,   98,   98,   98,  268,   96,   96,   96,
+- /*   650 */    96,   95,   95,   94,   94,   94,   93,  350,  324,  840,
+- /*   660 */   449,  978,  813,  978, 1200,  449,  909,  969,  715,  349,
+- /*   670 */   349,  349,  928,  177,  449,  930, 1317,  254,  198, 1317,
+- /*   680 */    12,   12,  910,  402,  449,   27,   27,  250,  971,  971,
+- /*   690 */   118,  716,  162,  969,   38,   38,  268,  176,  911,  771,
+- /*   700 */   432, 1265,  939,  353,   39,   39,  316,  991,  324,   99,
+- /*   710 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
+- /*   720 */    98,   98,  928,   96,   96,   96,   96,   95,   95,   94,
+- /*   730 */    94,   94,   93,  350,  449,  329,  449,  357,  971,  971,
+- /*   740 */  1041,  316,  929,  340,  893,  893,  386,  669,  670,  671,
+- /*   750 */   275, 1318,  317,  992,   40,   40,   41,   41,  268,   99,
+- /*   760 */   100,   90,  847,  850,  839,  839,   97,   97,   98,   98,
+- /*   770 */    98,   98,  449,   96,   96,   96,   96,   95,   95,   94,
+- /*   780 */    94,   94,   93,  350,  324,  449,  355,  449,  992,  449,
+- /*   790 */  1016,  330,   42,   42,  786,  270,  449,  273,  449,  228,
+- /*   800 */   449,  298,  449,  787,  449,   28,   28,   29,   29,   31,
+- /*   810 */    31,  449, 1141,  449,  971,  971,   43,   43,   44,   44,
+- /*   820 */    45,   45,   11,   11,   46,   46,  887,   78,  887,  268,
+- /*   830 */   268,  105,  105,   47,   47,   99,  100,   90,  847,  850,
+- /*   840 */   839,  839,   97,   97,   98,   98,   98,   98,  449,   96,
+- /*   850 */    96,   96,   96,   95,   95,   94,   94,   94,   93,  350,
+- /*   860 */   324,  449,  117,  449, 1073,  158,  449,  691,   48,   48,
+- /*   870 */   229, 1241,  449, 1250,  449,  414,  449,  334,  449,  245,
+- /*   880 */   449,   33,   33,   49,   49,  449,   50,   50,  246, 1141,
+- /*   890 */   971,  971,   34,   34,  122,  122,  123,  123,  124,  124,
+- /*   900 */    56,   56,  268,   81,  249,   35,   35,  197,  196,  195,
+- /*   910 */   324,   99,  100,   90,  847,  850,  839,  839,   97,   97,
+- /*   920 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
+- /*   930 */    95,   94,   94,   94,   93,  350,  449,  691,  449, 1141,
+- /*   940 */   971,  971,  968, 1207,  106,  106,  268, 1209,  268, 1266,
+- /*   950 */     2,  886,  268,  886,  335, 1040,   53,   53,  107,  107,
+- /*   960 */   324,   99,  100,   90,  847,  850,  839,  839,   97,   97,
+- /*   970 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
+- /*   980 */    95,   94,   94,   94,   93,  350,  449, 1070,  449, 1066,
+- /*   990 */   971,  971, 1039,  267,  108,  108,  445,  330,  331,  133,
+- /*  1000 */   223,  175,  301,  225,  385, 1255,  104,  104,  121,  121,
+- /*  1010 */   324,   99,   88,   90,  847,  850,  839,  839,   97,   97,
+- /*  1020 */    98,   98,   98,   98, 1141,   96,   96,   96,   96,   95,
+- /*  1030 */    95,   94,   94,   94,   93,  350,  449,  346,  449,  167,
+- /*  1040 */   971,  971,  925,  810,  371,  318,  202,  202,  373,  263,
+- /*  1050 */   394,  202,   74,  208,  721,  722,  119,  119,  112,  112,
+- /*  1060 */   324,  406,  100,   90,  847,  850,  839,  839,   97,   97,
+- /*  1070 */    98,   98,   98,   98,  449,   96,   96,   96,   96,   95,
+- /*  1080 */    95,   94,   94,   94,   93,  350,  449,  752,  449,  344,
+- /*  1090 */   971,  971,  751,  278,  111,  111,   74,  714,  713,  704,
+- /*  1100 */   286,  877,  749, 1279,  257,   77,  109,  109,  110,  110,
+- /*  1110 */  1230,  285, 1134,   90,  847,  850,  839,  839,   97,   97,
+- /*  1120 */    98,   98,   98,   98, 1233,   96,   96,   96,   96,   95,
+- /*  1130 */    95,   94,   94,   94,   93,  350,   86,  444,  449,    3,
+- /*  1140 */  1193,  449, 1069,  132,  351,  120, 1013,   86,  444,  780,
+- /*  1150 */     3, 1091,  202,  376,  447,  351, 1229,  120,   55,   55,
+- /*  1160 */   449,   57,   57,  822,  873,  447,  449,  208,  449,  704,
+- /*  1170 */   449,  877,  237,  433,  435,  120,  439,  428,  361,  120,
+- /*  1180 */    54,   54,  132,  449,  433,  826,   52,   52,   26,   26,
+- /*  1190 */    30,   30,  381,  132,  408,  443,  826,  689,  264,  389,
+- /*  1200 */   116,  269,  272,   32,   32,   83,   84,  120,  274,  120,
+- /*  1210 */   120,  276,   85,  351,  451,  450,   83,   84,  818, 1054,
+- /*  1220 */  1038,  427,  429,   85,  351,  451,  450,  120,  120,  818,
+- /*  1230 */   377,  218,  281,  822, 1107, 1140,   86,  444,  409,    3,
+- /*  1240 */  1087, 1098,  430,  431,  351,  302,  303, 1146, 1021,  818,
+- /*  1250 */   818,  820,  821,   19,  447, 1015, 1004, 1003, 1005, 1273,
+- /*  1260 */   818,  818,  820,  821,   19,  289,  159,  291,  293,    7,
+- /*  1270 */   315,  173,  259,  433, 1129,  363,  252, 1232,  375, 1037,
+- /*  1280 */   295,  434,  168,  986,  399,  826,  284, 1204, 1203,  205,
+- /*  1290 */  1276,  308, 1249,   86,  444,  983,    3, 1247,  332,  144,
+- /*  1300 */   130,  351,   72,  135,   59,   83,   84,  756,  137,  365,
+- /*  1310 */  1126,  447,   85,  351,  451,  450,  139,  226,  818,  140,
+- /*  1320 */   156,   62,  314,  314,  313,  215,  311,  366,  392,  678,
+- /*  1330 */   433,  185,  141, 1234,  142,  160,  148, 1136, 1198,  382,
+- /*  1340 */   189,   67,  826,  180,  388,  248, 1218, 1099,  219,  818,
+- /*  1350 */   818,  820,  821,   19,  247,  190,  266,  154,  390,  271,
+- /*  1360 */   191,  192,   83,   84, 1006,  405, 1057,  182,  321,   85,
+- /*  1370 */   351,  451,  450, 1056,  183,  818,  341,  132,  181,  706,
+- /*  1380 */  1055,  420,   76,  444, 1029,    3,  322, 1028,  283, 1048,
+- /*  1390 */   351, 1095, 1027, 1288, 1047,   71,  204,    6,  288,  290,
+- /*  1400 */   447, 1096, 1094, 1093,   79,  292,  818,  818,  820,  821,
+- /*  1410 */    19,  294,  297,  437,  345,  441,  102, 1184, 1077,  433,
+- /*  1420 */   238,  425,   73,  305,  239,  304,  325,  240,  423,  306,
+- /*  1430 */   307,  826,  213, 1012,   22,  945,  452,  214,  216,  217,
+- /*  1440 */   453, 1001,  115,  996,  125,  126,  235,  127,  665,  352,
+- /*  1450 */   326,   83,   84,  358,  166,  244,  179,  327,   85,  351,
+- /*  1460 */   451,  450,  134,  356,  818,  113,  885,  806,  883,  136,
+- /*  1470 */   128,  138,  738,  258,  184,  899,  143,  145,   63,   64,
+- /*  1480 */    65,   66,  129,  902,  187,  186,  898,    8,   13,  188,
+- /*  1490 */   265,  891,  149,  202,  980,  818,  818,  820,  821,   19,
+- /*  1500 */   150,  387,  161,  680,  285,  391,  151,  395,  400,  193,
+- /*  1510 */    68,   14,  236,  279,   15,   69,  717,  825,  131,  824,
+- /*  1520 */   853,   70,  746,   16,  413,  750,    4,  174,  220,  222,
+- /*  1530 */   152,  779,  857,  774,  201,   77,   74,  868,   17,  854,
+- /*  1540 */   852,  908,   18,  907,  207,  206,  934,  163,  436,  210,
+- /*  1550 */   935,  164,  209,  165,  440,  856,  823,  690,   87,  211,
+- /*  1560 */   309,  312, 1281,  940, 1280,
++ /*     0 */   368,  105,  102,  197,  105,  102,  197,  515, 1124,    1,
++ /*    10 */     1,  520,    2, 1128,  515, 1192, 1171, 1456,  275,  370,
++ /*    20 */   127, 1389, 1197, 1197, 1192, 1166,  178, 1205,   64,   64,
++ /*    30 */   477,  887,  322,  428,  348,   37,   37,  808,  362,  888,
++ /*    40 */   509,  509,  509,  112,  113,  103, 1100, 1100,  953,  956,
++ /*    50 */   946,  946,  110,  110,  111,  111,  111,  111,  365,  252,
++ /*    60 */   252,  515,  252,  252,  497,  515,  309,  515,  459,  515,
++ /*    70 */  1079,  491,  512,  478,    6,  512,  809,  134,  498,  228,
++ /*    80 */   194,  428,   37,   37,  515,  208,   64,   64,   64,   64,
++ /*    90 */    13,   13,  109,  109,  109,  109,  108,  108,  107,  107,
++ /*   100 */   107,  106,  401,  258,  381,   13,   13,  398,  397,  428,
++ /*   110 */   252,  252,  370,  476,  405, 1104, 1079, 1080, 1081,  386,
++ /*   120 */  1106,  390,  497,  512,  497, 1423, 1419,  304, 1105,  307,
++ /*   130 */  1256,  496,  370,  499,   16,   16,  112,  113,  103, 1100,
++ /*   140 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   150 */   111,  262, 1107,  495, 1107,  401,  112,  113,  103, 1100,
++ /*   160 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   170 */   111,  129, 1425,  343, 1420,  339, 1059,  492, 1057,  263,
++ /*   180 */    73,  105,  102,  197,  994,  109,  109,  109,  109,  108,
++ /*   190 */   108,  107,  107,  107,  106,  401,  370,  111,  111,  111,
++ /*   200 */   111,  104,  492,   89, 1432,  109,  109,  109,  109,  108,
++ /*   210 */   108,  107,  107,  107,  106,  401,  111,  111,  111,  111,
++ /*   220 */   112,  113,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*   230 */   110,  111,  111,  111,  111,  109,  109,  109,  109,  108,
++ /*   240 */   108,  107,  107,  107,  106,  401,  114,  108,  108,  107,
++ /*   250 */   107,  107,  106,  401,  109,  109,  109,  109,  108,  108,
++ /*   260 */   107,  107,  107,  106,  401,  152,  399,  399,  399,  109,
++ /*   270 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*   280 */   178,  493, 1412,  434, 1037, 1486, 1079,  515, 1486,  370,
++ /*   290 */   421,  297,  357,  412,   74, 1079,  109,  109,  109,  109,
++ /*   300 */   108,  108,  107,  107,  107,  106,  401, 1413,   37,   37,
++ /*   310 */  1431,  274,  506,  112,  113,  103, 1100, 1100,  953,  956,
++ /*   320 */   946,  946,  110,  110,  111,  111,  111,  111, 1436,  520,
++ /*   330 */     2, 1128, 1079, 1080, 1081,  430,  275, 1079,  127,  366,
++ /*   340 */   933, 1079, 1080, 1081,  220, 1205,  913,  458,  455,  454,
++ /*   350 */   392,  167,  515, 1035,  152,  445,  924,  453,  152,  874,
++ /*   360 */   923,  289,  109,  109,  109,  109,  108,  108,  107,  107,
++ /*   370 */   107,  106,  401,   13,   13,  261,  853,  252,  252,  227,
++ /*   380 */   106,  401,  370, 1079, 1080, 1081,  311,  388, 1079,  296,
++ /*   390 */   512,  923,  923,  925,  231,  323, 1255, 1388, 1423,  490,
++ /*   400 */   274,  506,   12,  208,  274,  506,  112,  113,  103, 1100,
++ /*   410 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   420 */   111, 1440,  286, 1128,  288, 1079, 1097,  247,  275, 1098,
++ /*   430 */   127,  387,  405,  389, 1079, 1080, 1081, 1205,  159,  238,
++ /*   440 */   255,  321,  461,  316,  460,  225,  790,  105,  102,  197,
++ /*   450 */   513,  314,  842,  842,  445,  109,  109,  109,  109,  108,
++ /*   460 */   108,  107,  107,  107,  106,  401,  515,  514,  515,  252,
++ /*   470 */   252, 1079, 1080, 1081,  435,  370, 1098,  933, 1460,  794,
++ /*   480 */   274,  506,  512,  105,  102,  197,  336,   63,   63,   64,
++ /*   490 */    64,   27,  790,  924,  287,  208, 1354,  923,  515,  112,
++ /*   500 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*   510 */   111,  111,  111,  111,  107,  107,  107,  106,  401,   49,
++ /*   520 */    49,  515,   28, 1079,  405,  497,  421,  297,  923,  923,
++ /*   530 */   925,  186,  468, 1079,  467,  999,  999,  442,  515, 1079,
++ /*   540 */   334,  515,   45,   45, 1083,  342,  173,  168,  109,  109,
++ /*   550 */   109,  109,  108,  108,  107,  107,  107,  106,  401,   13,
++ /*   560 */    13,  205,   13,   13,  252,  252, 1195, 1195,  370, 1079,
++ /*   570 */  1080, 1081,  787,  265,    5,  359,  494,  512,  469, 1079,
++ /*   580 */  1080, 1081,  398,  397, 1079, 1079, 1080, 1081,    3,  282,
++ /*   590 */  1079, 1083,  112,  113,  103, 1100, 1100,  953,  956,  946,
++ /*   600 */   946,  110,  110,  111,  111,  111,  111,  252,  252, 1015,
++ /*   610 */   220, 1079,  873,  458,  455,  454,  943,  943,  954,  957,
++ /*   620 */   512,  252,  252,  453, 1016, 1079,  445, 1107, 1209, 1107,
++ /*   630 */  1079, 1080, 1081,  515,  512,  426, 1079, 1080, 1081, 1017,
++ /*   640 */   512,  109,  109,  109,  109,  108,  108,  107,  107,  107,
++ /*   650 */   106,  401, 1052,  515,   50,   50,  515, 1079, 1080, 1081,
++ /*   660 */   828,  370, 1051,  379,  411, 1064, 1358,  207,  408,  773,
++ /*   670 */   829, 1079, 1080, 1081,   64,   64,  322,   64,   64, 1302,
++ /*   680 */   947,  411,  410, 1358, 1360,  112,  113,  103, 1100, 1100,
++ /*   690 */   953,  956,  946,  946,  110,  110,  111,  111,  111,  111,
++ /*   700 */   294,  482,  515, 1037, 1487,  515,  434, 1487,  354, 1120,
++ /*   710 */   483,  996,  913,  485,  466,  996,  132,  178,   33,  450,
++ /*   720 */  1203,  136,  406,   64,   64,  479,   64,   64,  419,  369,
++ /*   730 */   283, 1146,  252,  252,  109,  109,  109,  109,  108,  108,
++ /*   740 */   107,  107,  107,  106,  401,  512,  224,  440,  411,  266,
++ /*   750 */  1358,  266,  252,  252,  370,  296,  416,  284,  934,  396,
++ /*   760 */   976,  470,  400,  252,  252,  512,    9,  473,  231,  500,
++ /*   770 */   354, 1036, 1035, 1488,  355,  374,  512, 1121,  112,  113,
++ /*   780 */   103, 1100, 1100,  953,  956,  946,  946,  110,  110,  111,
++ /*   790 */   111,  111,  111,  252,  252, 1015,  515, 1347,  295,  252,
++ /*   800 */   252,  252,  252, 1098,  375,  249,  512,  445,  872,  322,
++ /*   810 */  1016,  480,  512,  195,  512,  434,  273,   15,   15,  515,
++ /*   820 */   314,  515,   95,  515,   93, 1017,  367,  109,  109,  109,
++ /*   830 */   109,  108,  108,  107,  107,  107,  106,  401,  515, 1121,
++ /*   840 */    39,   39,   51,   51,   52,   52,  503,  370,  515, 1204,
++ /*   850 */  1098,  918,  439,  341,  133,  436,  223,  222,  221,   53,
++ /*   860 */    53,  322, 1400,  761,  762,  763,  515,  370,   88,   54,
++ /*   870 */    54,  112,  113,  103, 1100, 1100,  953,  956,  946,  946,
++ /*   880 */   110,  110,  111,  111,  111,  111,  407,   55,   55,  196,
++ /*   890 */   515,  112,  113,  103, 1100, 1100,  953,  956,  946,  946,
++ /*   900 */   110,  110,  111,  111,  111,  111,  135,  264, 1149,  376,
++ /*   910 */   515,   40,   40,  515,  872,  515,  993,  515,  993,  116,
++ /*   920 */   109,  109,  109,  109,  108,  108,  107,  107,  107,  106,
++ /*   930 */   401,   41,   41,  515,   43,   43,   44,   44,   56,   56,
++ /*   940 */   109,  109,  109,  109,  108,  108,  107,  107,  107,  106,
++ /*   950 */   401,  515,  379,  515,   57,   57,  515,  799,  515,  379,
++ /*   960 */   515,  445,  200,  515,  323,  515, 1397,  515, 1459,  515,
++ /*   970 */  1287,  817,   58,   58,   14,   14,  515,   59,   59,  118,
++ /*   980 */   118,   60,   60,  515,   46,   46,   61,   61,   62,   62,
++ /*   990 */    47,   47,  515,  190,  189,   91,  515,  140,  140,  515,
++ /*  1000 */   394,  515,  277, 1200,  141,  141,  515, 1115,  515,  992,
++ /*  1010 */   515,  992,  515,   69,   69,  370,  278,   48,   48,  259,
++ /*  1020 */    65,   65,  119,  119,  246,  246,  260,   66,   66,  120,
++ /*  1030 */   120,  121,  121,  117,  117,  370,  515,  512,  383,  112,
++ /*  1040 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*  1050 */   111,  111,  111,  111,  515,  872,  515,  139,  139,  112,
++ /*  1060 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*  1070 */   111,  111,  111,  111, 1287,  138,  138,  125,  125,  515,
++ /*  1080 */    12,  515,  281, 1287,  515,  445,  131, 1287,  109,  109,
++ /*  1090 */   109,  109,  108,  108,  107,  107,  107,  106,  401,  515,
++ /*  1100 */   124,  124,  122,  122,  515,  123,  123,  515,  109,  109,
++ /*  1110 */   109,  109,  108,  108,  107,  107,  107,  106,  401,  515,
++ /*  1120 */    68,   68,  463,  783,  515,   70,   70,  302,   67,   67,
++ /*  1130 */  1032,  253,  253,  356, 1287,  191,  196, 1433,  465, 1301,
++ /*  1140 */    38,   38,  384,   94,  512,   42,   42,  177,  848,  274,
++ /*  1150 */   506,  385,  420,  847, 1356,  441,  508,  376,  377,  153,
++ /*  1160 */   423,  872,  432,  370,  224,  251,  194,  887,  182,  293,
++ /*  1170 */   783,  848,   88,  254,  466,  888,  847,  915,  807,  806,
++ /*  1180 */   230, 1241,  910,  370,   17,  413,  797,  112,  113,  103,
++ /*  1190 */  1100, 1100,  953,  956,  946,  946,  110,  110,  111,  111,
++ /*  1200 */   111,  111,  395,  814,  815, 1175,  983,  112,  101,  103,
++ /*  1210 */  1100, 1100,  953,  956,  946,  946,  110,  110,  111,  111,
++ /*  1220 */   111,  111,  375,  422,  427,  429,  298,  230,  230,   88,
++ /*  1230 */  1240,  451,  312,  797,  226,   88,  109,  109,  109,  109,
++ /*  1240 */   108,  108,  107,  107,  107,  106,  401,   86,  433,  979,
++ /*  1250 */   927,  881,  226,  983,  230,  415,  109,  109,  109,  109,
++ /*  1260 */   108,  108,  107,  107,  107,  106,  401,  320,  845,  781,
++ /*  1270 */   846,  100,  130,  100, 1403,  290,  370,  319, 1377, 1376,
++ /*  1280 */   437, 1449,  299, 1237,  303,  306,  308,  310, 1188, 1174,
++ /*  1290 */  1173, 1172,  315,  324,  325, 1228,  370,  927, 1249,  271,
++ /*  1300 */  1286,  113,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*  1310 */   110,  111,  111,  111,  111, 1224, 1235,  502,  501, 1292,
++ /*  1320 */  1221, 1155,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*  1330 */   110,  111,  111,  111,  111, 1148, 1137, 1136, 1138, 1443,
++ /*  1340 */   446,  244,  184,   98,  507,  188,    4,  353,  327,  109,
++ /*  1350 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*  1360 */   510,  329,  331,  199,  414,  456,  292,  285,  318,  109,
++ /*  1370 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*  1380 */    11, 1271, 1279,  402,  361,  192, 1171, 1351,  431,  505,
++ /*  1390 */   346, 1350,  333,   98,  507,  504,    4,  187, 1446, 1115,
++ /*  1400 */   233, 1396,  155, 1394, 1112,  152,   72,   75,  378,  425,
++ /*  1410 */   510,  165,  149,  157,  933, 1276,   86,   30, 1268,  417,
++ /*  1420 */    96,   96,    8,  160,  161,  162,  163,   97,  418,  402,
++ /*  1430 */   517,  516,  449,  402,  923,  210,  358,  424, 1282,  438,
++ /*  1440 */   169,  214,  360, 1345,   80,  504,   31,  444, 1365,  301,
++ /*  1450 */   245,  274,  506,  216,  174,  305,  488,  447,  217,  462,
++ /*  1460 */  1139,  487,  218,  363,  933,  923,  923,  925,  926,   24,
++ /*  1470 */    96,   96, 1191, 1190, 1189,  391, 1182,   97, 1163,  402,
++ /*  1480 */   517,  516,  799,  364,  923, 1162,  317, 1161,   98,  507,
++ /*  1490 */  1181,    4, 1458,  472,  393,  269,  270,  475,  481, 1232,
++ /*  1500 */    85, 1233,  326,  328,  232,  510,  495, 1231,  330,   98,
++ /*  1510 */   507, 1230,    4,  486,  335,  923,  923,  925,  926,   24,
++ /*  1520 */  1435, 1068,  404,  181,  336,  256,  510,  115,  402,  332,
++ /*  1530 */   352,  352,  351,  241,  349, 1214, 1414,  770,  338,   10,
++ /*  1540 */   504,  340,  272,   92, 1331, 1213,   87,  183,  484,  402,
++ /*  1550 */   201,  488,  280,  239,  344,  345,  489, 1145,   29,  933,
++ /*  1560 */   279,  504, 1074,  518,  240,   96,   96,  242,  243,  519,
++ /*  1570 */  1134, 1129,   97,  154,  402,  517,  516,  372,  373,  923,
++ /*  1580 */   933,  142,  143,  128, 1381,  267,   96,   96,  852,  757,
++ /*  1590 */   203,  144,  403,   97, 1382,  402,  517,  516,  204, 1380,
++ /*  1600 */   923,  146, 1379, 1159, 1158,   71, 1156,  276,  202,  185,
++ /*  1610 */   923,  923,  925,  926,   24,  198,  257,  126,  991,  989,
++ /*  1620 */   907,   98,  507,  156,    4,  145,  158,  206,  831,  209,
++ /*  1630 */   291,  923,  923,  925,  926,   24, 1005,  911,  510,  164,
++ /*  1640 */   147,  380,  371,  382,  166,   76,   77,  274,  506,  148,
++ /*  1650 */    78,   79, 1008,  211,  212, 1004,  137,  213,   18,  300,
++ /*  1660 */   230,  402,  997, 1109,  443,  215,   32,  170,  171,  772,
++ /*  1670 */   409,  448,  319,  504,  219,  172,  452,   81,   19,  457,
++ /*  1680 */   313,   20,   82,  268,  488,  150,  810,  179,   83,  487,
++ /*  1690 */   464,  151,  933,  180,  959,   84, 1040,   34,   96,   96,
++ /*  1700 */   471, 1041,   35,  474,  193,   97,  248,  402,  517,  516,
++ /*  1710 */  1068,  404,  923,  250,  256,  880,  229,  175,  875,  352,
++ /*  1720 */   352,  351,  241,  349,  100,   21,  770,   22, 1054, 1056,
++ /*  1730 */     7,   98,  507, 1045,    4,  337, 1058,   23,  974,  201,
++ /*  1740 */   176,  280,   88,  923,  923,  925,  926,   24,  510,  279,
++ /*  1750 */   960,  958,  962, 1014,  963, 1013,  235,  234,   25,   36,
++ /*  1760 */    99,   90,  507,  928,    4,  511,  350,  782,   26,  841,
++ /*  1770 */   236,  402,  347, 1069,  237, 1125, 1125, 1451,  510,  203,
++ /*  1780 */  1450, 1125, 1125,  504, 1125, 1125, 1125,  204, 1125, 1125,
++ /*  1790 */   146, 1125, 1125, 1125, 1125, 1125, 1125,  202, 1125, 1125,
++ /*  1800 */  1125,  402,  933, 1125, 1125, 1125, 1125, 1125,   96,   96,
++ /*  1810 */  1125, 1125, 1125,  504, 1125,   97, 1125,  402,  517,  516,
++ /*  1820 */  1125, 1125,  923, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1830 */  1125,  371,  933, 1125, 1125, 1125,  274,  506,   96,   96,
++ /*  1840 */  1125, 1125, 1125, 1125, 1125,   97, 1125,  402,  517,  516,
++ /*  1850 */  1125, 1125,  923,  923,  923,  925,  926,   24, 1125,  409,
++ /*  1860 */  1125, 1125, 1125,  256, 1125, 1125, 1125, 1125,  352,  352,
++ /*  1870 */   351,  241,  349, 1125, 1125,  770, 1125, 1125, 1125, 1125,
++ /*  1880 */  1125, 1125, 1125,  923,  923,  925,  926,   24,  201, 1125,
++ /*  1890 */   280, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  279, 1125,
++ /*  1900 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1910 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1920 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  203, 1125,
++ /*  1930 */  1125, 1125, 1125, 1125, 1125, 1125,  204, 1125, 1125,  146,
++ /*  1940 */  1125, 1125, 1125, 1125, 1125, 1125,  202, 1125, 1125, 1125,
++ /*  1950 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1960 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1970 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1980 */   371, 1125, 1125, 1125, 1125,  274,  506, 1125, 1125, 1125,
++ /*  1990 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  2000 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  409,
+ };
+ static const YYCODETYPE yy_lookahead[] = {
+- /*     0 */    19,  115,   19,  117,  118,   24,    1,    2,   27,   79,
+- /*    10 */    80,   81,   82,   83,   84,   85,   86,   87,   88,   89,
+- /*    20 */    90,   91,   92,   93,   94,  144,  145,  146,  147,   58,
+- /*    30 */    49,   50,   79,   80,   81,   82,   22,   84,   85,   86,
+- /*    40 */    87,   88,   89,   90,   91,   92,   93,   94,  221,  222,
+- /*    50 */   223,   70,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*    60 */    79,   80,   81,   82,   94,   84,   85,   86,   87,   88,
+- /*    70 */    89,   90,   91,   92,   93,   94,   19,   94,   97,  108,
+- /*    80 */   109,  110,   99,  100,  101,  102,  103,  104,  105,   32,
+- /*    90 */   119,  120,   78,   27,  152,  112,   93,   94,   41,   88,
+- /*   100 */    89,   90,   91,   92,   93,   94,   49,   50,   84,   85,
+- /*   110 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   58,
+- /*   120 */   157,  119,  120,  163,   68,  163,   65,   70,   71,   72,
+- /*   130 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
+- /*   140 */   152,   84,   85,   86,   87,   88,   89,   90,   91,   92,
+- /*   150 */    93,   94,   19,   97,   88,   89,  196,  101,  196,   26,
+- /*   160 */   172,  173,   96,   97,   98,  210,  100,   22,  152,  108,
+- /*   170 */   109,  110,   27,  107,   27,  109,  221,  222,  223,  219,
+- /*   180 */   238,  219,   49,   50,  152,  169,  170,   54,  132,  133,
+- /*   190 */   134,  228,  232,  171,  231,  207,  208,  237,  132,  237,
+- /*   200 */   134,  179,   19,   70,   71,   72,   73,   74,   75,   76,
+- /*   210 */    77,   78,   79,   80,   81,   82,  152,   84,   85,   86,
+- /*   220 */    87,   88,   89,   90,   91,   92,   93,   94,   27,   65,
+- /*   230 */    30,  152,   49,   50,   34,   52,   90,   91,   92,   93,
+- /*   240 */    94,   96,   97,   98,   97,   22,  230,   27,   48,  217,
+- /*   250 */    27,  172,  173,   70,   71,   72,   73,   74,   75,   76,
+- /*   260 */    77,   78,   79,   80,   81,   82,  172,   84,   85,   86,
+- /*   270 */    87,   88,   89,   90,   91,   92,   93,   94,   19,  148,
+- /*   280 */   149,  152,  218,   24,  152,  154,  207,  156,  172,  152,
+- /*   290 */    22,   68,   27,  152,  163,   27,  164,   96,   97,   98,
+- /*   300 */    99,  172,  173,  102,  103,  104,  169,  170,   49,   50,
+- /*   310 */    90,   88,   89,  152,  113,  186,   96,   97,   98,   96,
+- /*   320 */    97,  160,   57,   27,  101,  164,  137,  196,  139,   70,
+- /*   330 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
+- /*   340 */    81,   82,   11,   84,   85,   86,   87,   88,   89,   90,
+- /*   350 */    91,   92,   93,   94,   19,  132,  133,  134,   23,  218,
+- /*   360 */   152,   96,   97,   98,   96,   97,   98,  230,   99,   22,
+- /*   370 */   152,  102,  103,  104,   27,  244,  152,  152,   27,   26,
+- /*   380 */   152,   22,  113,   65,   49,   50,   27,  194,  195,   58,
+- /*   390 */   172,  173,   96,   97,   98,  185,   65,  172,  173,  206,
+- /*   400 */   172,  173,  190,  191,  186,   70,   71,   72,   73,   74,
+- /*   410 */    75,   76,   77,   78,   79,   80,   81,   82,  175,   84,
+- /*   420 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
+- /*   430 */    19,  175,  207,  208,   23,  207,  208,  119,  120,  108,
+- /*   440 */   109,  110,   27,   96,   97,   98,  116,   96,   97,   98,
+- /*   450 */   152,  121,  152,  179,  180,   96,   97,   98,  250,  106,
+- /*   460 */    49,   50,  188,   19,  221,  222,  223,  168,  169,  170,
+- /*   470 */   172,  173,  172,  173,  250,  124,  172,  221,  222,  223,
+- /*   480 */    26,   70,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*   490 */    79,   80,   81,   82,   50,   84,   85,   86,   87,   88,
+- /*   500 */    89,   90,   91,   92,   93,   94,   19,  207,  208,   12,
+- /*   510 */    23,   96,   97,   98,  221,  222,  223,  194,  195,  152,
+- /*   520 */   199,   23,   19,  225,   26,   28,  152,  152,  152,  206,
+- /*   530 */   209,  164,  190,  191,  241,  152,   49,   50,  152,  124,
+- /*   540 */   152,   44,  219,   46,  152,   21,  172,  173,  172,  173,
+- /*   550 */   183,  107,  185,   16,  163,   58,  112,   70,   71,   72,
+- /*   560 */    73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
+- /*   570 */   152,   84,   85,   86,   87,   88,   89,   90,   91,   92,
+- /*   580 */    93,   94,   19,  207,  130,  152,   23,  196,   64,  152,
+- /*   590 */   172,  173,   22,  152,   24,  152,   98,   27,   61,   96,
+- /*   600 */    63,   26,  211,  212,  186,  172,  173,   49,   50,  172,
+- /*   610 */   173,   23,   49,   50,   26,  172,  173,   88,   89,  186,
+- /*   620 */    24,  238,  124,   27,  238,   22,   23,  103,  187,   26,
+- /*   630 */   152,   73,   74,   70,   71,   72,   73,   74,   75,   76,
+- /*   640 */    77,   78,   79,   80,   81,   82,  152,   84,   85,   86,
+- /*   650 */    87,   88,   89,   90,   91,   92,   93,   94,   19,  101,
+- /*   660 */   152,  132,   23,  134,  140,  152,   12,   97,   36,  168,
+- /*   670 */   169,  170,   69,   98,  152,   22,   23,  140,   50,   26,
+- /*   680 */   172,  173,   28,   51,  152,  172,  173,  193,   49,   50,
+- /*   690 */    22,   59,   24,   97,  172,  173,  152,  152,   44,  124,
+- /*   700 */    46,    0,    1,    2,  172,  173,   22,   23,   19,   70,
+- /*   710 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
+- /*   720 */    81,   82,   69,   84,   85,   86,   87,   88,   89,   90,
+- /*   730 */    91,   92,   93,   94,  152,  107,  152,  193,   49,   50,
+- /*   740 */   181,   22,   23,  111,  108,  109,  110,    7,    8,    9,
+- /*   750 */    16,  247,  248,   69,  172,  173,  172,  173,  152,   70,
+- /*   760 */    71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
+- /*   770 */    81,   82,  152,   84,   85,   86,   87,   88,   89,   90,
+- /*   780 */    91,   92,   93,   94,   19,  152,  242,  152,   69,  152,
+- /*   790 */   166,  167,  172,  173,   32,   61,  152,   63,  152,  193,
+- /*   800 */   152,  152,  152,   41,  152,  172,  173,  172,  173,  172,
+- /*   810 */   173,  152,  152,  152,   49,   50,  172,  173,  172,  173,
+- /*   820 */   172,  173,  172,  173,  172,  173,  132,  138,  134,  152,
+- /*   830 */   152,  172,  173,  172,  173,   70,   71,   72,   73,   74,
+- /*   840 */    75,   76,   77,   78,   79,   80,   81,   82,  152,   84,
+- /*   850 */    85,   86,   87,   88,   89,   90,   91,   92,   93,   94,
+- /*   860 */    19,  152,   22,  152,  195,   24,  152,   27,  172,  173,
+- /*   870 */   193,  193,  152,  152,  152,  206,  152,  217,  152,  152,
+- /*   880 */   152,  172,  173,  172,  173,  152,  172,  173,  152,  152,
+- /*   890 */    49,   50,  172,  173,  172,  173,  172,  173,  172,  173,
+- /*   900 */   172,  173,  152,  138,  152,  172,  173,  108,  109,  110,
+- /*   910 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*   920 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
+- /*   930 */    89,   90,   91,   92,   93,   94,  152,   97,  152,  152,
+- /*   940 */    49,   50,   26,  193,  172,  173,  152,  152,  152,  146,
+- /*   950 */   147,  132,  152,  134,  217,  181,  172,  173,  172,  173,
+- /*   960 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*   970 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
+- /*   980 */    89,   90,   91,   92,   93,   94,  152,  193,  152,  193,
+- /*   990 */    49,   50,  181,  193,  172,  173,  166,  167,  245,  246,
+- /*  1000 */   211,  212,  152,   22,  217,  152,  172,  173,  172,  173,
+- /*  1010 */    19,   70,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*  1020 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
+- /*  1030 */    89,   90,   91,   92,   93,   94,  152,  187,  152,  123,
+- /*  1040 */    49,   50,   23,   23,   23,   26,   26,   26,   23,   23,
+- /*  1050 */    23,   26,   26,   26,    7,    8,  172,  173,  172,  173,
+- /*  1060 */    19,   90,   71,   72,   73,   74,   75,   76,   77,   78,
+- /*  1070 */    79,   80,   81,   82,  152,   84,   85,   86,   87,   88,
+- /*  1080 */    89,   90,   91,   92,   93,   94,  152,  116,  152,  217,
+- /*  1090 */    49,   50,  121,   23,  172,  173,   26,  100,  101,   27,
+- /*  1100 */   101,   27,   23,  122,  152,   26,  172,  173,  172,  173,
+- /*  1110 */   152,  112,  163,   72,   73,   74,   75,   76,   77,   78,
+- /*  1120 */    79,   80,   81,   82,  163,   84,   85,   86,   87,   88,
+- /*  1130 */    89,   90,   91,   92,   93,   94,   19,   20,  152,   22,
+- /*  1140 */    23,  152,  163,   65,   27,  196,  163,   19,   20,   23,
+- /*  1150 */    22,  213,   26,   19,   37,   27,  152,  196,  172,  173,
+- /*  1160 */   152,  172,  173,   27,   23,   37,  152,   26,  152,   97,
+- /*  1170 */   152,   97,  210,   56,  163,  196,  163,  163,  100,  196,
+- /*  1180 */   172,  173,   65,  152,   56,   68,  172,  173,  172,  173,
+- /*  1190 */   172,  173,  152,   65,  163,  163,   68,   23,  152,  234,
+- /*  1200 */    26,  152,  152,  172,  173,   88,   89,  196,  152,  196,
+- /*  1210 */   196,  152,   95,   96,   97,   98,   88,   89,  101,  152,
+- /*  1220 */   152,  207,  208,   95,   96,   97,   98,  196,  196,  101,
+- /*  1230 */    96,  233,  152,   97,  152,  152,   19,   20,  207,   22,
+- /*  1240 */   152,  152,  152,  191,   27,  152,  152,  152,  152,  132,
+- /*  1250 */   133,  134,  135,  136,   37,  152,  152,  152,  152,  152,
+- /*  1260 */   132,  133,  134,  135,  136,  210,  197,  210,  210,  198,
+- /*  1270 */   150,  184,  239,   56,  201,  214,  214,  201,  239,  180,
+- /*  1280 */   214,  227,  198,   38,  176,   68,  175,  175,  175,  122,
+- /*  1290 */   155,  200,  159,   19,   20,   40,   22,  159,  159,   22,
+- /*  1300 */    70,   27,  130,  243,  240,   88,   89,   90,  189,   18,
+- /*  1310 */   201,   37,   95,   96,   97,   98,  192,    5,  101,  192,
+- /*  1320 */   220,  240,   10,   11,   12,   13,   14,  159,   18,   17,
+- /*  1330 */    56,  158,  192,  201,  192,  220,  189,  189,  201,  159,
+- /*  1340 */   158,  137,   68,   31,   45,   33,  236,  159,  159,  132,
+- /*  1350 */   133,  134,  135,  136,   42,  158,  235,   22,  177,  159,
+- /*  1360 */   158,  158,   88,   89,  159,  107,  174,   55,  177,   95,
+- /*  1370 */    96,   97,   98,  174,   62,  101,   47,   65,   66,  106,
+- /*  1380 */   174,  125,   19,   20,  174,   22,  177,  176,  174,  182,
+- /*  1390 */    27,  216,  174,  174,  182,  107,  159,   22,  215,  215,
+- /*  1400 */    37,  216,  216,  216,  137,  215,  132,  133,  134,  135,
+- /*  1410 */   136,  215,  159,  177,   94,  177,  129,  224,  205,   56,
+- /*  1420 */   226,  126,  128,  203,  229,  204,  114,  229,  127,  202,
+- /*  1430 */   201,   68,   25,  162,   26,   13,  161,  153,  153,    6,
+- /*  1440 */   151,  151,  178,  151,  165,  165,  178,  165,    4,    3,
+- /*  1450 */   249,   88,   89,  141,   22,  142,   15,  249,   95,   96,
+- /*  1460 */    97,   98,  246,   67,  101,   16,   23,  120,   23,  131,
+- /*  1470 */   111,  123,   20,   16,  125,    1,  123,  131,   78,   78,
+- /*  1480 */    78,   78,  111,   96,  122,   35,    1,    5,   22,  107,
+- /*  1490 */   140,   53,   53,   26,   60,  132,  133,  134,  135,  136,
+- /*  1500 */   107,   43,   24,   20,  112,   19,   22,   52,   52,  105,
+- /*  1510 */    22,   22,   52,   23,   22,   22,   29,   23,   39,   23,
+- /*  1520 */    23,   26,  116,   22,   26,   23,   22,  122,   23,   23,
+- /*  1530 */    22,   96,   11,  124,   35,   26,   26,   23,   35,   23,
+- /*  1540 */    23,   23,   35,   23,   22,   26,   23,   22,   24,  122,
+- /*  1550 */    23,   22,   26,   22,   24,   23,   23,   23,   22,  122,
+- /*  1560 */    23,   15,  122,    1,  122,
++ /*     0 */   184,  238,  239,  240,  238,  239,  240,  163,  155,  156,
++ /*    10 */   157,  158,  159,  160,  163,  191,  192,  183,  165,   19,
++ /*    20 */   167,  258,  202,  203,  200,  191,  163,  174,  184,  185,
++ /*    30 */   174,   31,  163,  163,  171,  184,  185,   35,  175,   39,
++ /*    40 */   179,  180,  181,   43,   44,   45,   46,   47,   48,   49,
++ /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,  184,  206,
++ /*    60 */   207,  163,  206,  207,  220,  163,   16,  163,   66,  163,
++ /*    70 */    59,  270,  219,  229,  273,  219,   74,  208,  174,  223,
++ /*    80 */   224,  163,  184,  185,  163,  232,  184,  185,  184,  185,
++ /*    90 */   184,  185,   92,   93,   94,   95,   96,   97,   98,   99,
++ /*   100 */   100,  101,  102,  233,  198,  184,  185,   96,   97,  163,
++ /*   110 */   206,  207,   19,  163,  261,  104,  105,  106,  107,  198,
++ /*   120 */   109,  119,  220,  219,  220,  274,  275,   77,  117,   79,
++ /*   130 */   187,  229,   19,  229,  184,  185,   43,   44,   45,   46,
++ /*   140 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   150 */    57,  233,  141,  134,  143,  102,   43,   44,   45,   46,
++ /*   160 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   170 */    57,  152,  274,  216,  276,  218,   83,  163,   85,  233,
++ /*   180 */    67,  238,  239,  240,   11,   92,   93,   94,   95,   96,
++ /*   190 */    97,   98,   99,  100,  101,  102,   19,   54,   55,   56,
++ /*   200 */    57,   58,  163,   26,  163,   92,   93,   94,   95,   96,
++ /*   210 */    97,   98,   99,  100,  101,  102,   54,   55,   56,   57,
++ /*   220 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*   230 */    53,   54,   55,   56,   57,   92,   93,   94,   95,   96,
++ /*   240 */    97,   98,   99,  100,  101,  102,   69,   96,   97,   98,
++ /*   250 */    99,  100,  101,  102,   92,   93,   94,   95,   96,   97,
++ /*   260 */    98,   99,  100,  101,  102,   81,  179,  180,  181,   92,
++ /*   270 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*   280 */   163,  267,  268,  163,   22,   23,   59,  163,   26,   19,
++ /*   290 */   117,  118,  175,  109,   24,   59,   92,   93,   94,   95,
++ /*   300 */    96,   97,   98,   99,  100,  101,  102,  268,  184,  185,
++ /*   310 */   269,  127,  128,   43,   44,   45,   46,   47,   48,   49,
++ /*   320 */    50,   51,   52,   53,   54,   55,   56,   57,  157,  158,
++ /*   330 */   159,  160,  105,  106,  107,  163,  165,   59,  167,  184,
++ /*   340 */    90,  105,  106,  107,  108,  174,   73,  111,  112,  113,
++ /*   350 */    19,   22,  163,   91,   81,  163,  106,  121,   81,  132,
++ /*   360 */   110,   16,   92,   93,   94,   95,   96,   97,   98,   99,
++ /*   370 */   100,  101,  102,  184,  185,  255,   98,  206,  207,   26,
++ /*   380 */   101,  102,   19,  105,  106,  107,   23,  198,   59,  116,
++ /*   390 */   219,  141,  142,  143,   24,  163,  187,  205,  274,  275,
++ /*   400 */   127,  128,  182,  232,  127,  128,   43,   44,   45,   46,
++ /*   410 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   420 */    57,  158,   77,  160,   79,   59,   26,  182,  165,   59,
++ /*   430 */   167,  199,  261,  102,  105,  106,  107,  174,   72,  108,
++ /*   440 */   109,  110,  111,  112,  113,  114,   59,  238,  239,  240,
++ /*   450 */   123,  120,  125,  126,  163,   92,   93,   94,   95,   96,
++ /*   460 */    97,   98,   99,  100,  101,  102,  163,  163,  163,  206,
++ /*   470 */   207,  105,  106,  107,  254,   19,  106,   90,  197,   23,
++ /*   480 */   127,  128,  219,  238,  239,  240,   22,  184,  185,  184,
++ /*   490 */   185,   22,  105,  106,  149,  232,  205,  110,  163,   43,
++ /*   500 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*   510 */    54,   55,   56,   57,   98,   99,  100,  101,  102,  184,
++ /*   520 */   185,  163,   53,   59,  261,  220,  117,  118,  141,  142,
++ /*   530 */   143,  131,  174,   59,  229,  116,  117,  118,  163,   59,
++ /*   540 */   163,  163,  184,  185,   59,  242,   72,   22,   92,   93,
++ /*   550 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  184,
++ /*   560 */   185,   24,  184,  185,  206,  207,  202,  203,   19,  105,
++ /*   570 */   106,  107,   23,  198,   22,  174,  198,  219,  220,  105,
++ /*   580 */   106,  107,   96,   97,   59,  105,  106,  107,   22,  174,
++ /*   590 */    59,  106,   43,   44,   45,   46,   47,   48,   49,   50,
++ /*   600 */    51,   52,   53,   54,   55,   56,   57,  206,  207,   12,
++ /*   610 */   108,   59,  132,  111,  112,  113,   46,   47,   48,   49,
++ /*   620 */   219,  206,  207,  121,   27,   59,  163,  141,  207,  143,
++ /*   630 */   105,  106,  107,  163,  219,  234,  105,  106,  107,   42,
++ /*   640 */   219,   92,   93,   94,   95,   96,   97,   98,   99,  100,
++ /*   650 */   101,  102,   76,  163,  184,  185,  163,  105,  106,  107,
++ /*   660 */    63,   19,   86,  163,  163,   23,  163,  130,  205,   21,
++ /*   670 */    73,  105,  106,  107,  184,  185,  163,  184,  185,  237,
++ /*   680 */   110,  180,  181,  180,  181,   43,   44,   45,   46,   47,
++ /*   690 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
++ /*   700 */   174,  163,  163,   22,   23,  163,  163,   26,   22,   23,
++ /*   710 */   220,   29,   73,  220,  272,   33,   22,  163,   24,   19,
++ /*   720 */   174,  208,  259,  184,  185,   19,  184,  185,   80,  175,
++ /*   730 */   230,  174,  206,  207,   92,   93,   94,   95,   96,   97,
++ /*   740 */    98,   99,  100,  101,  102,  219,   46,   65,  247,  195,
++ /*   750 */   247,  197,  206,  207,   19,  116,  117,  118,   23,  220,
++ /*   760 */   112,  174,  220,  206,  207,  219,   22,  174,   24,  174,
++ /*   770 */    22,   23,   91,  264,  265,  168,  219,   91,   43,   44,
++ /*   780 */    45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
++ /*   790 */    55,   56,   57,  206,  207,   12,  163,  149,  255,  206,
++ /*   800 */   207,  206,  207,   59,  104,   23,  219,  163,   26,  163,
++ /*   810 */    27,  105,  219,  163,  219,  163,  211,  184,  185,  163,
++ /*   820 */   120,  163,  146,  163,  148,   42,  221,   92,   93,   94,
++ /*   830 */    95,   96,   97,   98,   99,  100,  101,  102,  163,   91,
++ /*   840 */   184,  185,  184,  185,  184,  185,   63,   19,  163,  205,
++ /*   850 */   106,   23,  245,  163,  208,  248,  116,  117,  118,  184,
++ /*   860 */   185,  163,  163,    7,    8,    9,  163,   19,   26,  184,
++ /*   870 */   185,   43,   44,   45,   46,   47,   48,   49,   50,   51,
++ /*   880 */    52,   53,   54,   55,   56,   57,  163,  184,  185,  107,
++ /*   890 */   163,   43,   44,   45,   46,   47,   48,   49,   50,   51,
++ /*   900 */    52,   53,   54,   55,   56,   57,  208,  255,  177,  178,
++ /*   910 */   163,  184,  185,  163,  132,  163,  141,  163,  143,   22,
++ /*   920 */    92,   93,   94,   95,   96,   97,   98,   99,  100,  101,
++ /*   930 */   102,  184,  185,  163,  184,  185,  184,  185,  184,  185,
++ /*   940 */    92,   93,   94,   95,   96,   97,   98,   99,  100,  101,
++ /*   950 */   102,  163,  163,  163,  184,  185,  163,  115,  163,  163,
++ /*   960 */   163,  163,   15,  163,  163,  163,  163,  163,   23,  163,
++ /*   970 */   163,   26,  184,  185,  184,  185,  163,  184,  185,  184,
++ /*   980 */   185,  184,  185,  163,  184,  185,  184,  185,  184,  185,
++ /*   990 */   184,  185,  163,   96,   97,  147,  163,  184,  185,  163,
++ /*  1000 */   199,  163,  163,  205,  184,  185,  163,   60,  163,  141,
++ /*  1010 */   163,  143,  163,  184,  185,   19,  163,  184,  185,  230,
++ /*  1020 */   184,  185,  184,  185,  206,  207,  230,  184,  185,  184,
++ /*  1030 */   185,  184,  185,  184,  185,   19,  163,  219,  231,   43,
++ /*  1040 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*  1050 */    54,   55,   56,   57,  163,   26,  163,  184,  185,   43,
++ /*  1060 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*  1070 */    54,   55,   56,   57,  163,  184,  185,  184,  185,  163,
++ /*  1080 */   182,  163,  163,  163,  163,  163,   22,  163,   92,   93,
++ /*  1090 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  163,
++ /*  1100 */   184,  185,  184,  185,  163,  184,  185,  163,   92,   93,
++ /*  1110 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  163,
++ /*  1120 */   184,  185,   98,   59,  163,  184,  185,  205,  184,  185,
++ /*  1130 */    23,  206,  207,   26,  163,   26,  107,  153,  154,  237,
++ /*  1140 */   184,  185,  231,  147,  219,  184,  185,  249,  124,  127,
++ /*  1150 */   128,  231,  254,  129,  163,  231,  177,  178,  262,  263,
++ /*  1160 */   118,  132,   19,   19,   46,  223,  224,   31,   24,   23,
++ /*  1170 */   106,  124,   26,   22,  272,   39,  129,   23,  109,  110,
++ /*  1180 */    26,  163,  140,   19,   22,  234,   59,   43,   44,   45,
++ /*  1190 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
++ /*  1200 */    56,   57,  231,    7,    8,  193,   59,   43,   44,   45,
++ /*  1210 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
++ /*  1220 */    56,   57,  104,   61,   23,   23,   23,   26,   26,   26,
++ /*  1230 */   163,   23,   23,  106,   26,   26,   92,   93,   94,   95,
++ /*  1240 */    96,   97,   98,   99,  100,  101,  102,  138,  105,   23,
++ /*  1250 */    59,   23,   26,  106,   26,  163,   92,   93,   94,   95,
++ /*  1260 */    96,   97,   98,   99,  100,  101,  102,  110,   23,   23,
++ /*  1270 */    23,   26,   26,   26,  163,  163,   19,  120,  163,  163,
++ /*  1280 */   163,  130,  163,  163,  163,  163,  163,  163,  163,  193,
++ /*  1290 */   193,  163,  163,  163,  163,  225,   19,  106,  163,  222,
++ /*  1300 */   163,   44,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*  1310 */    53,   54,   55,   56,   57,  163,  163,  203,  163,  163,
++ /*  1320 */   222,  163,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*  1330 */    53,   54,   55,   56,   57,  163,  163,  163,  163,  163,
++ /*  1340 */   251,  250,  209,   19,   20,  182,   22,  161,  222,   92,
++ /*  1350 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*  1360 */    36,  222,  222,  260,  226,  188,  256,  226,  187,   92,
++ /*  1370 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*  1380 */   210,  213,  213,   59,  213,  196,  192,  187,  256,  244,
++ /*  1390 */   212,  187,  226,   19,   20,   71,   22,  210,  166,   60,
++ /*  1400 */   130,  170,  260,  170,   38,   81,  257,  257,  170,  104,
++ /*  1410 */    36,   22,   43,  201,   90,  236,  138,  235,  213,   18,
++ /*  1420 */    96,   97,   48,  204,  204,  204,  204,  103,  170,  105,
++ /*  1430 */   106,  107,   18,   59,  110,  169,  213,  213,  201,  170,
++ /*  1440 */   201,  169,  236,  213,  146,   71,  235,   62,  253,  252,
++ /*  1450 */   170,  127,  128,  169,   22,  170,   82,  189,  169,  104,
++ /*  1460 */   170,   87,  169,  189,   90,  141,  142,  143,  144,  145,
++ /*  1470 */    96,   97,  186,  186,  186,   64,  194,  103,  186,  105,
++ /*  1480 */   106,  107,  115,  189,  110,  188,  186,  186,   19,   20,
++ /*  1490 */   194,   22,  186,  189,  102,  246,  246,  189,  133,  228,
++ /*  1500 */   104,  228,  227,  227,  170,   36,  134,  228,  227,   19,
++ /*  1510 */    20,  228,   22,   84,  271,  141,  142,  143,  144,  145,
++ /*  1520 */     0,    1,    2,  216,   22,    5,   36,  137,   59,  227,
++ /*  1530 */    10,   11,   12,   13,   14,  217,  269,   17,  216,   22,
++ /*  1540 */    71,  170,  243,  146,  241,  217,  136,  215,  135,   59,
++ /*  1550 */    30,   82,   32,   25,  214,  213,   87,  173,   26,   90,
++ /*  1560 */    40,   71,   13,  172,  164,   96,   97,  164,    6,  162,
++ /*  1570 */   162,  162,  103,  263,  105,  106,  107,  266,  266,  110,
++ /*  1580 */    90,  176,  176,  190,  182,  190,   96,   97,   98,    4,
++ /*  1590 */    70,  176,    3,  103,  182,  105,  106,  107,   78,  182,
++ /*  1600 */   110,   81,  182,  182,  182,  182,  182,  151,   88,   22,
++ /*  1610 */   141,  142,  143,  144,  145,   15,   89,   16,   23,   23,
++ /*  1620 */   128,   19,   20,  139,   22,  119,  131,   24,   20,  133,
++ /*  1630 */    16,  141,  142,  143,  144,  145,    1,  140,   36,  131,
++ /*  1640 */   119,   61,  122,   37,  139,   53,   53,  127,  128,  119,
++ /*  1650 */    53,   53,  105,   34,  130,    1,    5,  104,   22,  149,
++ /*  1660 */    26,   59,   68,   75,   41,  130,   24,   68,  104,   20,
++ /*  1670 */   150,   19,  120,   71,  114,   22,   67,   22,   22,   67,
++ /*  1680 */    23,   22,   22,   67,   82,   37,   28,   23,  138,   87,
++ /*  1690 */    22,  153,   90,   23,   23,   26,   23,   22,   96,   97,
++ /*  1700 */    24,   23,   22,   24,  130,  103,   23,  105,  106,  107,
++ /*  1710 */     1,    2,  110,   23,    5,  105,   34,   22,  132,   10,
++ /*  1720 */    11,   12,   13,   14,   26,   34,   17,   34,   85,   83,
++ /*  1730 */    44,   19,   20,   23,   22,   24,   75,   34,   23,   30,
++ /*  1740 */    26,   32,   26,  141,  142,  143,  144,  145,   36,   40,
++ /*  1750 */    23,   23,   23,   23,   11,   23,   22,   26,   22,   22,
++ /*  1760 */    22,   19,   20,   23,   22,   26,   15,   23,   22,  124,
++ /*  1770 */   130,   59,   23,    1,  130,  277,  277,  130,   36,   70,
++ /*  1780 */   130,  277,  277,   71,  277,  277,  277,   78,  277,  277,
++ /*  1790 */    81,  277,  277,  277,  277,  277,  277,   88,  277,  277,
++ /*  1800 */   277,   59,   90,  277,  277,  277,  277,  277,   96,   97,
++ /*  1810 */   277,  277,  277,   71,  277,  103,  277,  105,  106,  107,
++ /*  1820 */   277,  277,  110,  277,  277,  277,  277,  277,  277,  277,
++ /*  1830 */   277,  122,   90,  277,  277,  277,  127,  128,   96,   97,
++ /*  1840 */   277,  277,  277,  277,  277,  103,  277,  105,  106,  107,
++ /*  1850 */   277,  277,  110,  141,  142,  143,  144,  145,  277,  150,
++ /*  1860 */   277,  277,  277,    5,  277,  277,  277,  277,   10,   11,
++ /*  1870 */    12,   13,   14,  277,  277,   17,  277,  277,  277,  277,
++ /*  1880 */   277,  277,  277,  141,  142,  143,  144,  145,   30,  277,
++ /*  1890 */    32,  277,  277,  277,  277,  277,  277,  277,   40,  277,
++ /*  1900 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1910 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1920 */   277,  277,  277,  277,  277,  277,  277,  277,   70,  277,
++ /*  1930 */   277,  277,  277,  277,  277,  277,   78,  277,  277,   81,
++ /*  1940 */   277,  277,  277,  277,  277,  277,   88,  277,  277,  277,
++ /*  1950 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1960 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1970 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1980 */   122,  277,  277,  277,  277,  127,  128,  277,  277,  277,
++ /*  1990 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  2000 */   277,  277,  277,  277,  277,  277,  277,  277,  150,  277,
++ /*  2010 */   277,  277,  277,  277,  277,  277,  277,  277,  277,
+ };
+-#define YY_SHIFT_USE_DFLT (1565)
+-#define YY_SHIFT_COUNT    (454)
+-#define YY_SHIFT_MIN      (-114)
+-#define YY_SHIFT_MAX      (1562)
+-static const short yy_shift_ofst[] = {
+- /*     0 */     5, 1117, 1312, 1128, 1274, 1274, 1274, 1274,   61,  -19,
+- /*    10 */    57,   57,  183, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+- /*    20 */    66,   66,  201,  -29,  331,  318,  133,  259,  335,  411,
+- /*    30 */   487,  563,  639,  689,  765,  841,  891,  891,  891,  891,
+- /*    40 */   891,  891,  891,  891,  891,  891,  891,  891,  891,  891,
+- /*    50 */   891,  891,  891,  941,  891,  991, 1041, 1041, 1217, 1274,
+- /*    60 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+- /*    70 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+- /*    80 */  1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+- /*    90 */  1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
+- /*   100 */  1274, 1274, 1274, 1274,  -70,  -47,  -47,  -47,  -47,  -47,
+- /*   110 */    24,   11,  146,  296,  524,  444,  529,  529,  296,    3,
+- /*   120 */     2,  -30, 1565, 1565, 1565,  -17,  -17,  -17,  145,  145,
+- /*   130 */   497,  497,  265,  603,  653,  296,  296,  296,  296,  296,
+- /*   140 */   296,  296,  296,  296,  296,  296,  296,  296,  296,  296,
+- /*   150 */   296,  296,  296,  296,  296,  701, 1078,  147,  147,    2,
+- /*   160 */   164,  164,  164,  164,  164,  164, 1565, 1565, 1565,  223,
+- /*   170 */    56,   56,  268,  269,  220,  347,  351,  415,  359,  296,
+- /*   180 */   296,  296,  296,  296,  296,  296,  296,  296,  296,  296,
+- /*   190 */   296,  296,  296,  296,  296,  632,  632,  632,  296,  296,
+- /*   200 */   498,  296,  296,  296,  570,  296,  296,  654,  296,  296,
+- /*   210 */   296,  296,  296,  296,  296,  296,  296,  296,  636,  200,
+- /*   220 */   596,  596,  596,  575, -114,  971,  740,  454,  503,  503,
+- /*   230 */  1134,  454, 1134,  353,  588,  628,  762,  503,  189,  762,
+- /*   240 */   762,  916,  330,  668, 1245, 1167, 1167, 1255, 1255, 1167,
+- /*   250 */  1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172,
+- /*   260 */  1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167,
+- /*   270 */  1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258,
+- /*   280 */  1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288,
+- /*   290 */  1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267,
+- /*   300 */  1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407,
+- /*   310 */  1408, 1422, 1422, 1433, 1433, 1433, 1565, 1565, 1565, 1565,
+- /*   320 */  1565, 1565, 1565, 1565,  558,  537,  684,  719,  734,  799,
+- /*   330 */   840, 1019,   14, 1020, 1021, 1025, 1026, 1027, 1070, 1072,
+- /*   340 */   997, 1047,  999, 1079, 1126, 1074, 1141,  694,  819, 1174,
+- /*   350 */  1136,  981, 1444, 1446, 1432, 1313, 1441, 1396, 1449, 1443,
+- /*   360 */  1445, 1347, 1338, 1359, 1348, 1452, 1349, 1457, 1474, 1353,
+- /*   370 */  1346, 1400, 1401, 1402, 1403, 1371, 1387, 1450, 1362, 1485,
+- /*   380 */  1482, 1466, 1382, 1350, 1438, 1467, 1439, 1434, 1458, 1393,
+- /*   390 */  1478, 1483, 1486, 1392, 1404, 1484, 1455, 1488, 1489, 1490,
+- /*   400 */  1492, 1456, 1487, 1493, 1460, 1479, 1494, 1496, 1497, 1495,
+- /*   410 */  1406, 1501, 1502, 1504, 1498, 1405, 1505, 1506, 1435, 1499,
+- /*   420 */  1508, 1409, 1509, 1503, 1510, 1507, 1514, 1509, 1516, 1517,
+- /*   430 */  1518, 1519, 1520, 1522, 1521, 1523, 1525, 1524, 1526, 1527,
+- /*   440 */  1529, 1530, 1526, 1532, 1531, 1533, 1534, 1536, 1427, 1437,
+- /*   450 */  1440, 1442, 1537, 1546, 1562,
++#define YY_SHIFT_COUNT    (520)
++#define YY_SHIFT_MIN      (0)
++#define YY_SHIFT_MAX      (1858)
++static const unsigned short int yy_shift_ofst[] = {
++ /*     0 */  1709, 1520, 1858, 1324, 1324,  277, 1374, 1469, 1602, 1712,
++ /*    10 */  1712, 1712,  273,    0,    0,  113, 1016, 1712, 1712, 1712,
++ /*    20 */  1712, 1712, 1712, 1712, 1712, 1712, 1712,   11,   11,  236,
++ /*    30 */   184,  277,  277,  277,  277,  277,  277,   93,  177,  270,
++ /*    40 */   363,  456,  549,  642,  735,  828,  848,  996, 1144, 1016,
++ /*    50 */  1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016,
++ /*    60 */  1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277,
++ /*    70 */  1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*    80 */  1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*    90 */  1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*   100 */  1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*   110 */  1712, 1712, 1712, 1712, 1712, 1712, 1712,  143,  162,  162,
++ /*   120 */   162,  162,  162,  204,  151,  416,  531,  648,  700,  531,
++ /*   130 */   486,  486,  531,  353,  353,  353,  353,  409,  279,   53,
++ /*   140 */  2009, 2009,  331,  331,  331,  329,  366,  329,  329,  597,
++ /*   150 */   597,  464,  474,  262,  681,  531,  531,  531,  531,  531,
++ /*   160 */   531,  531,  531,  531,  531,  531,  531,  531,  531,  531,
++ /*   170 */   531,  531,  531,  531,  531,  531,  531,  173,  485,  984,
++ /*   180 */   984,  576,  485,   19, 1022, 2009, 2009, 2009,  387,  250,
++ /*   190 */   250,  525,  502,  278,  552,  227,  480,  566,  531,  531,
++ /*   200 */   531,  531,  531,  531,  531,  531,  531,  531,  639,  531,
++ /*   210 */   531,  531,  531,  531,  531,  531,  531,  531,  531,  531,
++ /*   220 */   531,    2,    2,    2,  531,  531,  531,  531,  782,  531,
++ /*   230 */   531,  531,  744,  531,  531,  783,  531,  531,  531,  531,
++ /*   240 */   531,  531,  531,  531,  419,  682,  327,  370,  370,  370,
++ /*   250 */   370, 1029,  327,  327, 1024,  897,  856,  947, 1109,  706,
++ /*   260 */   706, 1143, 1109, 1109, 1143,  842,  945, 1118, 1136, 1136,
++ /*   270 */  1136,  706,  676,  400, 1047,  694, 1339, 1270, 1270, 1366,
++ /*   280 */  1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401,
++ /*   290 */  1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270,
++ /*   300 */  1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414,
++ /*   310 */  1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411,
++ /*   320 */  1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396,
++ /*   330 */  1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372,
++ /*   340 */  1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549,
++ /*   350 */  1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009,
++ /*   360 */  2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
++ /*   370 */   570,  345,  686,  748,   50,  740, 1064, 1107,  469,  537,
++ /*   380 */  1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127,
++ /*   390 */  1069, 1196, 1157, 1147, 1226, 1228, 1245,  775,  868, 1246,
++ /*   400 */  1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601,
++ /*   410 */  1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614,
++ /*   420 */  1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597,
++ /*   430 */  1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510,
++ /*   440 */  1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652,
++ /*   450 */  1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658,
++ /*   460 */  1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669,
++ /*   470 */  1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610,
++ /*   480 */  1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646,
++ /*   490 */  1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728,
++ /*   500 */  1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744,
++ /*   510 */  1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751,
++ /*   520 */  1772,
+ };
+-#define YY_REDUCE_USE_DFLT (-174)
+-#define YY_REDUCE_COUNT (323)
+-#define YY_REDUCE_MIN   (-173)
+-#define YY_REDUCE_MAX   (1292)
++#define YY_REDUCE_COUNT (369)
++#define YY_REDUCE_MIN   (-237)
++#define YY_REDUCE_MAX   (1424)
+ static const short yy_reduce_ofst[] = {
+- /*     0 */  -119, 1014,  131, 1031,  -12,  225,  228,  300,  -40,  -45,
+- /*    10 */   243,  256,  293,  129,  218,  418,   79,  376,  433,  298,
+- /*    20 */    16,  137,  367,  323,  -38,  391, -173, -173, -173, -173,
+- /*    30 */  -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+- /*    40 */  -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
+- /*    50 */  -173, -173, -173, -173, -173, -173, -173, -173,  374,  437,
+- /*    60 */   443,  508,  513,  522,  532,  582,  584,  620,  633,  635,
+- /*    70 */   637,  644,  646,  648,  650,  652,  659,  661,  696,  709,
+- /*    80 */   711,  714,  720,  722,  724,  726,  728,  733,  772,  784,
+- /*    90 */   786,  822,  834,  836,  884,  886,  922,  934,  936,  986,
+- /*   100 */   989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173,
+- /*   110 */  -173, -173, -173,  544,  -37,  274,  299,  501,  161, -173,
+- /*   120 */   193, -173, -173, -173, -173,   22,   22,   22,   64,  141,
+- /*   130 */   212,  342,  208,  504,  504,  132,  494,  606,  677,  678,
+- /*   140 */   750,  794,  796,  -58,   32,  383,  660,  737,  386,  787,
+- /*   150 */   800,  441,  872,  224,  850,  803,  949,  624,  830,  669,
+- /*   160 */   961,  979,  983, 1011, 1013, 1032,  753,  789,  321,   94,
+- /*   170 */   116,  304,  375,  210,  388,  392,  478,  545,  649,  721,
+- /*   180 */   727,  736,  752,  795,  853,  952,  958, 1004, 1040, 1046,
+- /*   190 */  1049, 1050, 1056, 1059, 1067,  559,  774,  811, 1068, 1080,
+- /*   200 */   938, 1082, 1083, 1088,  962, 1089, 1090, 1052, 1093, 1094,
+- /*   210 */  1095,  388, 1096, 1103, 1104, 1105, 1106, 1107,  965,  998,
+- /*   220 */  1055, 1057, 1058,  938, 1069, 1071, 1120, 1073, 1061, 1062,
+- /*   230 */  1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112,
+- /*   240 */  1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139,
+- /*   250 */  1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132,
+- /*   260 */  1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189,
+- /*   270 */  1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206,
+- /*   280 */  1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183,
+- /*   290 */  1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194,
+- /*   300 */  1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271,
+- /*   310 */  1275, 1284, 1285, 1289, 1290, 1292, 1201, 1208, 1216, 1279,
+- /*   320 */  1280, 1264, 1268, 1282,
++ /*     0 */  -147,  171,  263,  -96,  358, -144, -149, -102,  124, -156,
++ /*    10 */   -98,  305,  401,  -57,  209, -237,  245,  -94,  -79,  189,
++ /*    20 */   375,  490,  493,  378,  303,  539,  542,  501,  503,  554,
++ /*    30 */   415,  526,  546,  557,  587,  593,  595, -234, -234, -234,
++ /*    40 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    50 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    60 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    70 */  -234,  -50,  335,  470,  633,  656,  658,  660,  675,  685,
++ /*    80 */   703,  727,  747,  750,  752,  754,  770,  788,  790,  793,
++ /*    90 */   795,  797,  800,  802,  804,  806,  813,  820,  829,  833,
++ /*   100 */   836,  838,  843,  845,  847,  849,  873,  891,  893,  916,
++ /*   110 */   918,  921,  936,  941,  944,  956,  961, -234, -234, -234,
++ /*   120 */  -234, -234, -234, -234, -234, -234,  463,  607, -176,   14,
++ /*   130 */  -139,   87, -137,  818,  925,  818,  925,  898, -234, -234,
++ /*   140 */  -234, -234, -166, -166, -166, -130, -131,  -82,  -54, -180,
++ /*   150 */   364,   41,  513,  509,  509,  117,  500,  789,  796,  646,
++ /*   160 */   192,  291,  644,  798,  120,  807,  543,  911,  920,  652,
++ /*   170 */   924,  922,  232,  698,  801,  971,   39,  220,  731,  442,
++ /*   180 */   902, -199,  979,  -43,  421,  896,  942,  605, -184, -126,
++ /*   190 */   155,  172,  281,  304,  377,  538,  650,  690,  699,  723,
++ /*   200 */   803,  839,  853,  919,  991, 1018, 1067, 1092,  951, 1111,
++ /*   210 */  1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124,
++ /*   220 */  1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135,
++ /*   230 */  1137, 1152, 1077, 1153, 1155, 1114, 1156,  304, 1158, 1172,
++ /*   240 */  1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139,
++ /*   250 */  1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138,
++ /*   260 */  1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200,
++ /*   270 */  1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149,
++ /*   280 */  1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222,
++ /*   290 */  1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269,
++ /*   300 */  1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293,
++ /*   310 */  1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296,
++ /*   320 */  1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276,
++ /*   330 */  1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322,
++ /*   340 */  1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400,
++ /*   350 */  1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412,
++ /*   360 */  1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415,
+ };
+ static const YYACTIONTYPE yy_default[] = {
+- /*     0 */  1270, 1260, 1260, 1260, 1193, 1193, 1193, 1193, 1260, 1088,
+- /*    10 */  1117, 1117, 1244, 1322, 1322, 1322, 1322, 1322, 1322, 1192,
+- /*    20 */  1322, 1322, 1322, 1322, 1260, 1092, 1123, 1322, 1322, 1322,
+- /*    30 */  1322, 1194, 1195, 1322, 1322, 1322, 1243, 1245, 1133, 1132,
+- /*    40 */  1131, 1130, 1226, 1104, 1128, 1121, 1125, 1194, 1188, 1189,
+- /*    50 */  1187, 1191, 1195, 1322, 1124, 1158, 1172, 1157, 1322, 1322,
+- /*    60 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*    70 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*    80 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*    90 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   100 */  1322, 1322, 1322, 1322, 1166, 1171, 1178, 1170, 1167, 1160,
+- /*   110 */  1159, 1161, 1162, 1322, 1011, 1059, 1322, 1322, 1322, 1163,
+- /*   120 */  1322, 1164, 1175, 1174, 1173, 1251, 1278, 1277, 1322, 1322,
+- /*   130 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   140 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   150 */  1322, 1322, 1322, 1322, 1322, 1270, 1260, 1017, 1017, 1322,
+- /*   160 */  1260, 1260, 1260, 1260, 1260, 1260, 1256, 1092, 1083, 1322,
+- /*   170 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   180 */  1248, 1246, 1322, 1208, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   190 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   200 */  1322, 1322, 1322, 1322, 1088, 1322, 1322, 1322, 1322, 1322,
+- /*   210 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1272, 1322, 1221,
+- /*   220 */  1088, 1088, 1088, 1090, 1072, 1082,  997, 1127, 1106, 1106,
+- /*   230 */  1311, 1127, 1311, 1034, 1292, 1031, 1117, 1106, 1190, 1117,
+- /*   240 */  1117, 1089, 1082, 1322, 1314, 1097, 1097, 1313, 1313, 1097,
+- /*   250 */  1138, 1062, 1127, 1068, 1068, 1068, 1068, 1097, 1008, 1127,
+- /*   260 */  1138, 1062, 1062, 1127, 1097, 1008, 1225, 1308, 1097, 1097,
+- /*   270 */  1008, 1201, 1097, 1008, 1097, 1008, 1201, 1060, 1060, 1060,
+- /*   280 */  1049, 1201, 1060, 1034, 1060, 1049, 1060, 1060, 1110, 1105,
+- /*   290 */  1110, 1105, 1110, 1105, 1110, 1105, 1097, 1196, 1097, 1322,
+- /*   300 */  1201, 1205, 1205, 1201, 1122, 1111, 1120, 1118, 1127, 1014,
+- /*   310 */  1052, 1275, 1275, 1271, 1271, 1271, 1319, 1319, 1256, 1287,
+- /*   320 */  1287, 1036, 1036, 1287, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   330 */  1282, 1322, 1210, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   340 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   350 */  1322, 1143, 1322,  993, 1253, 1322, 1322, 1252, 1322, 1322,
+- /*   360 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   370 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1310, 1322,
+- /*   380 */  1322, 1322, 1322, 1322, 1322, 1224, 1223, 1322, 1322, 1322,
+- /*   390 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   400 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+- /*   410 */  1074, 1322, 1322, 1322, 1296, 1322, 1322, 1322, 1322, 1322,
+- /*   420 */  1322, 1322, 1119, 1322, 1112, 1322, 1322, 1301, 1322, 1322,
+- /*   430 */  1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1262, 1322,
+- /*   440 */  1322, 1322, 1261, 1322, 1322, 1322, 1322, 1322, 1145, 1322,
+- /*   450 */  1144, 1148, 1322, 1002, 1322,
++ /*     0 */  1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340,
++ /*    10 */  1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123,
++ /*    20 */  1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123,
++ /*    30 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123,
++ /*    40 */  1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390,
++ /*    50 */  1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267,
++ /*    60 */  1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320,
++ /*    70 */  1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*    80 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*    90 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   100 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   110 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325,
++ /*   120 */  1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123,
++ /*   130 */  1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312,
++ /*   140 */  1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123,
++ /*   150 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   160 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   170 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300,
++ /*   180 */  1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123,
++ /*   190 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   200 */  1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123,
++ /*   210 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   220 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   230 */  1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   240 */  1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225,
++ /*   250 */  1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248,
++ /*   260 */  1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259,
++ /*   270 */  1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483,
++ /*   280 */  1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202,
++ /*   290 */  1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234,
++ /*   300 */  1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141,
++ /*   310 */  1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183,
++ /*   320 */  1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247,
++ /*   330 */  1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253,
++ /*   340 */  1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445,
++ /*   350 */  1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154,
++ /*   360 */  1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457,
++ /*   370 */  1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238,
++ /*   380 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   390 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   400 */  1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123,
++ /*   410 */  1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123,
++ /*   420 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   430 */  1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123,
++ /*   440 */  1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123,
++ /*   450 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   460 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   470 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   480 */  1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123,
++ /*   490 */  1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123,
++ /*   500 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   510 */  1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135,
++ /*   520 */  1123,
+ };
+ /********** End of lemon-generated parsing tables *****************************/
+ 
+@@ -137414,73 +147745,95 @@
+ static const YYCODETYPE yyFallback[] = {
+     0,  /*          $ => nothing */
+     0,  /*       SEMI => nothing */
+-   27,  /*    EXPLAIN => ID */
+-   27,  /*      QUERY => ID */
+-   27,  /*       PLAN => ID */
+-   27,  /*      BEGIN => ID */
++   59,  /*    EXPLAIN => ID */
++   59,  /*      QUERY => ID */
++   59,  /*       PLAN => ID */
++   59,  /*      BEGIN => ID */
+     0,  /* TRANSACTION => nothing */
+-   27,  /*   DEFERRED => ID */
+-   27,  /*  IMMEDIATE => ID */
+-   27,  /*  EXCLUSIVE => ID */
++   59,  /*   DEFERRED => ID */
++   59,  /*  IMMEDIATE => ID */
++   59,  /*  EXCLUSIVE => ID */
+     0,  /*     COMMIT => nothing */
+-   27,  /*        END => ID */
+-   27,  /*   ROLLBACK => ID */
+-   27,  /*  SAVEPOINT => ID */
+-   27,  /*    RELEASE => ID */
++   59,  /*        END => ID */
++   59,  /*   ROLLBACK => ID */
++   59,  /*  SAVEPOINT => ID */
++   59,  /*    RELEASE => ID */
+     0,  /*         TO => nothing */
+     0,  /*      TABLE => nothing */
+     0,  /*     CREATE => nothing */
+-   27,  /*         IF => ID */
++   59,  /*         IF => ID */
+     0,  /*        NOT => nothing */
+     0,  /*     EXISTS => nothing */
+-   27,  /*       TEMP => ID */
++   59,  /*       TEMP => ID */
+     0,  /*         LP => nothing */
+     0,  /*         RP => nothing */
+     0,  /*         AS => nothing */
+-   27,  /*    WITHOUT => ID */
++   59,  /*    WITHOUT => ID */
+     0,  /*      COMMA => nothing */
++   59,  /*      ABORT => ID */
++   59,  /*     ACTION => ID */
++   59,  /*      AFTER => ID */
++   59,  /*    ANALYZE => ID */
++   59,  /*        ASC => ID */
++   59,  /*     ATTACH => ID */
++   59,  /*     BEFORE => ID */
++   59,  /*         BY => ID */
++   59,  /*    CASCADE => ID */
++   59,  /*       CAST => ID */
++   59,  /*   CONFLICT => ID */
++   59,  /*   DATABASE => ID */
++   59,  /*       DESC => ID */
++   59,  /*     DETACH => ID */
++   59,  /*       EACH => ID */
++   59,  /*       FAIL => ID */
++    0,  /*         OR => nothing */
++    0,  /*        AND => nothing */
++    0,  /*         IS => nothing */
++   59,  /*      MATCH => ID */
++   59,  /*    LIKE_KW => ID */
++    0,  /*    BETWEEN => nothing */
++    0,  /*         IN => nothing */
++    0,  /*     ISNULL => nothing */
++    0,  /*    NOTNULL => nothing */
++    0,  /*         NE => nothing */
++    0,  /*         EQ => nothing */
++    0,  /*         GT => nothing */
++    0,  /*         LE => nothing */
++    0,  /*         LT => nothing */
++    0,  /*         GE => nothing */
++    0,  /*     ESCAPE => nothing */
+     0,  /*         ID => nothing */
+-   27,  /*      ABORT => ID */
+-   27,  /*     ACTION => ID */
+-   27,  /*      AFTER => ID */
+-   27,  /*    ANALYZE => ID */
+-   27,  /*        ASC => ID */
+-   27,  /*     ATTACH => ID */
+-   27,  /*     BEFORE => ID */
+-   27,  /*         BY => ID */
+-   27,  /*    CASCADE => ID */
+-   27,  /*       CAST => ID */
+-   27,  /*   COLUMNKW => ID */
+-   27,  /*   CONFLICT => ID */
+-   27,  /*   DATABASE => ID */
+-   27,  /*       DESC => ID */
+-   27,  /*     DETACH => ID */
+-   27,  /*       EACH => ID */
+-   27,  /*       FAIL => ID */
+-   27,  /*        FOR => ID */
+-   27,  /*     IGNORE => ID */
+-   27,  /*  INITIALLY => ID */
+-   27,  /*    INSTEAD => ID */
+-   27,  /*    LIKE_KW => ID */
+-   27,  /*      MATCH => ID */
+-   27,  /*         NO => ID */
+-   27,  /*        KEY => ID */
+-   27,  /*         OF => ID */
+-   27,  /*     OFFSET => ID */
+-   27,  /*     PRAGMA => ID */
+-   27,  /*      RAISE => ID */
+-   27,  /*  RECURSIVE => ID */
+-   27,  /*    REPLACE => ID */
+-   27,  /*   RESTRICT => ID */
+-   27,  /*        ROW => ID */
+-   27,  /*    TRIGGER => ID */
+-   27,  /*     VACUUM => ID */
+-   27,  /*       VIEW => ID */
+-   27,  /*    VIRTUAL => ID */
+-   27,  /*       WITH => ID */
+-   27,  /*    REINDEX => ID */
+-   27,  /*     RENAME => ID */
+-   27,  /*   CTIME_KW => ID */
++   59,  /*   COLUMNKW => ID */
++   59,  /*         DO => ID */
++   59,  /*        FOR => ID */
++   59,  /*     IGNORE => ID */
++   59,  /*  INITIALLY => ID */
++   59,  /*    INSTEAD => ID */
++   59,  /*         NO => ID */
++   59,  /*        KEY => ID */
++   59,  /*         OF => ID */
++   59,  /*     OFFSET => ID */
++   59,  /*     PRAGMA => ID */
++   59,  /*      RAISE => ID */
++   59,  /*  RECURSIVE => ID */
++   59,  /*    REPLACE => ID */
++   59,  /*   RESTRICT => ID */
++   59,  /*        ROW => ID */
++   59,  /*       ROWS => ID */
++   59,  /*    TRIGGER => ID */
++   59,  /*     VACUUM => ID */
++   59,  /*       VIEW => ID */
++   59,  /*    VIRTUAL => ID */
++   59,  /*       WITH => ID */
++   59,  /*    CURRENT => ID */
++   59,  /*  FOLLOWING => ID */
++   59,  /*  PARTITION => ID */
++   59,  /*  PRECEDING => ID */
++   59,  /*      RANGE => ID */
++   59,  /*  UNBOUNDED => ID */
++   59,  /*    REINDEX => ID */
++   59,  /*     RENAME => ID */
++   59,  /*   CTIME_KW => ID */
+ };
+ #endif /* YYFALLBACK */
+ 
+@@ -137520,6 +147873,7 @@
+   int yyerrcnt;                 /* Shifts left before out of the error */
+ #endif
+   sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
++  sqlite3ParserCTX_SDECL                /* A place to hold %extra_context */
+ #if YYSTACKDEPTH<=0
+   int yystksz;                  /* Current side of the stack */
+   yyStackEntry *yystack;        /* The parser's stack */
+@@ -137563,75 +147917,289 @@
+ }
+ #endif /* NDEBUG */
+ 
+-#ifndef NDEBUG
++#if defined(YYCOVERAGE) || !defined(NDEBUG)
+ /* For tracing shifts, the names of all terminals and nonterminals
+ ** are required.  The following table supplies these names */
+ static const char *const yyTokenName[] = { 
+-  "$",             "SEMI",          "EXPLAIN",       "QUERY",       
+-  "PLAN",          "BEGIN",         "TRANSACTION",   "DEFERRED",    
+-  "IMMEDIATE",     "EXCLUSIVE",     "COMMIT",        "END",         
+-  "ROLLBACK",      "SAVEPOINT",     "RELEASE",       "TO",          
+-  "TABLE",         "CREATE",        "IF",            "NOT",         
+-  "EXISTS",        "TEMP",          "LP",            "RP",          
+-  "AS",            "WITHOUT",       "COMMA",         "ID",          
+-  "ABORT",         "ACTION",        "AFTER",         "ANALYZE",     
+-  "ASC",           "ATTACH",        "BEFORE",        "BY",          
+-  "CASCADE",       "CAST",          "COLUMNKW",      "CONFLICT",    
+-  "DATABASE",      "DESC",          "DETACH",        "EACH",        
+-  "FAIL",          "FOR",           "IGNORE",        "INITIALLY",   
+-  "INSTEAD",       "LIKE_KW",       "MATCH",         "NO",          
+-  "KEY",           "OF",            "OFFSET",        "PRAGMA",      
+-  "RAISE",         "RECURSIVE",     "REPLACE",       "RESTRICT",    
+-  "ROW",           "TRIGGER",       "VACUUM",        "VIEW",        
+-  "VIRTUAL",       "WITH",          "REINDEX",       "RENAME",      
+-  "CTIME_KW",      "ANY",           "OR",            "AND",         
+-  "IS",            "BETWEEN",       "IN",            "ISNULL",      
+-  "NOTNULL",       "NE",            "EQ",            "GT",          
+-  "LE",            "LT",            "GE",            "ESCAPE",      
+-  "BITAND",        "BITOR",         "LSHIFT",        "RSHIFT",      
+-  "PLUS",          "MINUS",         "STAR",          "SLASH",       
+-  "REM",           "CONCAT",        "COLLATE",       "BITNOT",      
+-  "INDEXED",       "STRING",        "JOIN_KW",       "CONSTRAINT",  
+-  "DEFAULT",       "NULL",          "PRIMARY",       "UNIQUE",      
+-  "CHECK",         "REFERENCES",    "AUTOINCR",      "ON",          
+-  "INSERT",        "DELETE",        "UPDATE",        "SET",         
+-  "DEFERRABLE",    "FOREIGN",       "DROP",          "UNION",       
+-  "ALL",           "EXCEPT",        "INTERSECT",     "SELECT",      
+-  "VALUES",        "DISTINCT",      "DOT",           "FROM",        
+-  "JOIN",          "USING",         "ORDER",         "GROUP",       
+-  "HAVING",        "LIMIT",         "WHERE",         "INTO",        
+-  "FLOAT",         "BLOB",          "INTEGER",       "VARIABLE",    
+-  "CASE",          "WHEN",          "THEN",          "ELSE",        
+-  "INDEX",         "ALTER",         "ADD",           "error",       
+-  "input",         "cmdlist",       "ecmd",          "explain",     
+-  "cmdx",          "cmd",           "transtype",     "trans_opt",   
+-  "nm",            "savepoint_opt",  "create_table",  "create_table_args",
+-  "createkw",      "temp",          "ifnotexists",   "dbnm",        
+-  "columnlist",    "conslist_opt",  "table_options",  "select",      
+-  "columnname",    "carglist",      "typetoken",     "typename",    
+-  "signed",        "plus_num",      "minus_num",     "ccons",       
+-  "term",          "expr",          "onconf",        "sortorder",   
+-  "autoinc",       "eidlist_opt",   "refargs",       "defer_subclause",
+-  "refarg",        "refact",        "init_deferred_pred_opt",  "conslist",    
+-  "tconscomma",    "tcons",         "sortlist",      "eidlist",     
+-  "defer_subclause_opt",  "orconf",        "resolvetype",   "raisetype",   
+-  "ifexists",      "fullname",      "selectnowith",  "oneselect",   
+-  "with",          "multiselect_op",  "distinct",      "selcollist",  
+-  "from",          "where_opt",     "groupby_opt",   "having_opt",  
+-  "orderby_opt",   "limit_opt",     "values",        "nexprlist",   
+-  "exprlist",      "sclp",          "as",            "seltablist",  
+-  "stl_prefix",    "joinop",        "indexed_opt",   "on_opt",      
+-  "using_opt",     "idlist",        "setlist",       "insert_cmd",  
+-  "idlist_opt",    "likeop",        "between_op",    "in_op",       
+-  "paren_exprlist",  "case_operand",  "case_exprlist",  "case_else",   
+-  "uniqueflag",    "collate",       "nmnum",         "trigger_decl",
+-  "trigger_cmd_list",  "trigger_time",  "trigger_event",  "foreach_clause",
+-  "when_clause",   "trigger_cmd",   "trnm",          "tridxby",     
+-  "database_kw_opt",  "key_opt",       "add_column_fullname",  "kwcolumn_opt",
+-  "create_vtab",   "vtabarglist",   "vtabarg",       "vtabargtoken",
+-  "lp",            "anylist",       "wqlist",      
++  /*    0 */ "$",
++  /*    1 */ "SEMI",
++  /*    2 */ "EXPLAIN",
++  /*    3 */ "QUERY",
++  /*    4 */ "PLAN",
++  /*    5 */ "BEGIN",
++  /*    6 */ "TRANSACTION",
++  /*    7 */ "DEFERRED",
++  /*    8 */ "IMMEDIATE",
++  /*    9 */ "EXCLUSIVE",
++  /*   10 */ "COMMIT",
++  /*   11 */ "END",
++  /*   12 */ "ROLLBACK",
++  /*   13 */ "SAVEPOINT",
++  /*   14 */ "RELEASE",
++  /*   15 */ "TO",
++  /*   16 */ "TABLE",
++  /*   17 */ "CREATE",
++  /*   18 */ "IF",
++  /*   19 */ "NOT",
++  /*   20 */ "EXISTS",
++  /*   21 */ "TEMP",
++  /*   22 */ "LP",
++  /*   23 */ "RP",
++  /*   24 */ "AS",
++  /*   25 */ "WITHOUT",
++  /*   26 */ "COMMA",
++  /*   27 */ "ABORT",
++  /*   28 */ "ACTION",
++  /*   29 */ "AFTER",
++  /*   30 */ "ANALYZE",
++  /*   31 */ "ASC",
++  /*   32 */ "ATTACH",
++  /*   33 */ "BEFORE",
++  /*   34 */ "BY",
++  /*   35 */ "CASCADE",
++  /*   36 */ "CAST",
++  /*   37 */ "CONFLICT",
++  /*   38 */ "DATABASE",
++  /*   39 */ "DESC",
++  /*   40 */ "DETACH",
++  /*   41 */ "EACH",
++  /*   42 */ "FAIL",
++  /*   43 */ "OR",
++  /*   44 */ "AND",
++  /*   45 */ "IS",
++  /*   46 */ "MATCH",
++  /*   47 */ "LIKE_KW",
++  /*   48 */ "BETWEEN",
++  /*   49 */ "IN",
++  /*   50 */ "ISNULL",
++  /*   51 */ "NOTNULL",
++  /*   52 */ "NE",
++  /*   53 */ "EQ",
++  /*   54 */ "GT",
++  /*   55 */ "LE",
++  /*   56 */ "LT",
++  /*   57 */ "GE",
++  /*   58 */ "ESCAPE",
++  /*   59 */ "ID",
++  /*   60 */ "COLUMNKW",
++  /*   61 */ "DO",
++  /*   62 */ "FOR",
++  /*   63 */ "IGNORE",
++  /*   64 */ "INITIALLY",
++  /*   65 */ "INSTEAD",
++  /*   66 */ "NO",
++  /*   67 */ "KEY",
++  /*   68 */ "OF",
++  /*   69 */ "OFFSET",
++  /*   70 */ "PRAGMA",
++  /*   71 */ "RAISE",
++  /*   72 */ "RECURSIVE",
++  /*   73 */ "REPLACE",
++  /*   74 */ "RESTRICT",
++  /*   75 */ "ROW",
++  /*   76 */ "ROWS",
++  /*   77 */ "TRIGGER",
++  /*   78 */ "VACUUM",
++  /*   79 */ "VIEW",
++  /*   80 */ "VIRTUAL",
++  /*   81 */ "WITH",
++  /*   82 */ "CURRENT",
++  /*   83 */ "FOLLOWING",
++  /*   84 */ "PARTITION",
++  /*   85 */ "PRECEDING",
++  /*   86 */ "RANGE",
++  /*   87 */ "UNBOUNDED",
++  /*   88 */ "REINDEX",
++  /*   89 */ "RENAME",
++  /*   90 */ "CTIME_KW",
++  /*   91 */ "ANY",
++  /*   92 */ "BITAND",
++  /*   93 */ "BITOR",
++  /*   94 */ "LSHIFT",
++  /*   95 */ "RSHIFT",
++  /*   96 */ "PLUS",
++  /*   97 */ "MINUS",
++  /*   98 */ "STAR",
++  /*   99 */ "SLASH",
++  /*  100 */ "REM",
++  /*  101 */ "CONCAT",
++  /*  102 */ "COLLATE",
++  /*  103 */ "BITNOT",
++  /*  104 */ "ON",
++  /*  105 */ "INDEXED",
++  /*  106 */ "STRING",
++  /*  107 */ "JOIN_KW",
++  /*  108 */ "CONSTRAINT",
++  /*  109 */ "DEFAULT",
++  /*  110 */ "NULL",
++  /*  111 */ "PRIMARY",
++  /*  112 */ "UNIQUE",
++  /*  113 */ "CHECK",
++  /*  114 */ "REFERENCES",
++  /*  115 */ "AUTOINCR",
++  /*  116 */ "INSERT",
++  /*  117 */ "DELETE",
++  /*  118 */ "UPDATE",
++  /*  119 */ "SET",
++  /*  120 */ "DEFERRABLE",
++  /*  121 */ "FOREIGN",
++  /*  122 */ "DROP",
++  /*  123 */ "UNION",
++  /*  124 */ "ALL",
++  /*  125 */ "EXCEPT",
++  /*  126 */ "INTERSECT",
++  /*  127 */ "SELECT",
++  /*  128 */ "VALUES",
++  /*  129 */ "DISTINCT",
++  /*  130 */ "DOT",
++  /*  131 */ "FROM",
++  /*  132 */ "JOIN",
++  /*  133 */ "USING",
++  /*  134 */ "ORDER",
++  /*  135 */ "GROUP",
++  /*  136 */ "HAVING",
++  /*  137 */ "LIMIT",
++  /*  138 */ "WHERE",
++  /*  139 */ "INTO",
++  /*  140 */ "NOTHING",
++  /*  141 */ "FLOAT",
++  /*  142 */ "BLOB",
++  /*  143 */ "INTEGER",
++  /*  144 */ "VARIABLE",
++  /*  145 */ "CASE",
++  /*  146 */ "WHEN",
++  /*  147 */ "THEN",
++  /*  148 */ "ELSE",
++  /*  149 */ "INDEX",
++  /*  150 */ "ALTER",
++  /*  151 */ "ADD",
++  /*  152 */ "WINDOW",
++  /*  153 */ "OVER",
++  /*  154 */ "FILTER",
++  /*  155 */ "input",
++  /*  156 */ "cmdlist",
++  /*  157 */ "ecmd",
++  /*  158 */ "cmdx",
++  /*  159 */ "explain",
++  /*  160 */ "cmd",
++  /*  161 */ "transtype",
++  /*  162 */ "trans_opt",
++  /*  163 */ "nm",
++  /*  164 */ "savepoint_opt",
++  /*  165 */ "create_table",
++  /*  166 */ "create_table_args",
++  /*  167 */ "createkw",
++  /*  168 */ "temp",
++  /*  169 */ "ifnotexists",
++  /*  170 */ "dbnm",
++  /*  171 */ "columnlist",
++  /*  172 */ "conslist_opt",
++  /*  173 */ "table_options",
++  /*  174 */ "select",
++  /*  175 */ "columnname",
++  /*  176 */ "carglist",
++  /*  177 */ "typetoken",
++  /*  178 */ "typename",
++  /*  179 */ "signed",
++  /*  180 */ "plus_num",
++  /*  181 */ "minus_num",
++  /*  182 */ "scanpt",
++  /*  183 */ "ccons",
++  /*  184 */ "term",
++  /*  185 */ "expr",
++  /*  186 */ "onconf",
++  /*  187 */ "sortorder",
++  /*  188 */ "autoinc",
++  /*  189 */ "eidlist_opt",
++  /*  190 */ "refargs",
++  /*  191 */ "defer_subclause",
++  /*  192 */ "refarg",
++  /*  193 */ "refact",
++  /*  194 */ "init_deferred_pred_opt",
++  /*  195 */ "conslist",
++  /*  196 */ "tconscomma",
++  /*  197 */ "tcons",
++  /*  198 */ "sortlist",
++  /*  199 */ "eidlist",
++  /*  200 */ "defer_subclause_opt",
++  /*  201 */ "orconf",
++  /*  202 */ "resolvetype",
++  /*  203 */ "raisetype",
++  /*  204 */ "ifexists",
++  /*  205 */ "fullname",
++  /*  206 */ "selectnowith",
++  /*  207 */ "oneselect",
++  /*  208 */ "wqlist",
++  /*  209 */ "multiselect_op",
++  /*  210 */ "distinct",
++  /*  211 */ "selcollist",
++  /*  212 */ "from",
++  /*  213 */ "where_opt",
++  /*  214 */ "groupby_opt",
++  /*  215 */ "having_opt",
++  /*  216 */ "orderby_opt",
++  /*  217 */ "limit_opt",
++  /*  218 */ "window_clause",
++  /*  219 */ "values",
++  /*  220 */ "nexprlist",
++  /*  221 */ "sclp",
++  /*  222 */ "as",
++  /*  223 */ "seltablist",
++  /*  224 */ "stl_prefix",
++  /*  225 */ "joinop",
++  /*  226 */ "indexed_opt",
++  /*  227 */ "on_opt",
++  /*  228 */ "using_opt",
++  /*  229 */ "exprlist",
++  /*  230 */ "xfullname",
++  /*  231 */ "idlist",
++  /*  232 */ "with",
++  /*  233 */ "setlist",
++  /*  234 */ "insert_cmd",
++  /*  235 */ "idlist_opt",
++  /*  236 */ "upsert",
++  /*  237 */ "over_clause",
++  /*  238 */ "likeop",
++  /*  239 */ "between_op",
++  /*  240 */ "in_op",
++  /*  241 */ "paren_exprlist",
++  /*  242 */ "case_operand",
++  /*  243 */ "case_exprlist",
++  /*  244 */ "case_else",
++  /*  245 */ "uniqueflag",
++  /*  246 */ "collate",
++  /*  247 */ "nmnum",
++  /*  248 */ "trigger_decl",
++  /*  249 */ "trigger_cmd_list",
++  /*  250 */ "trigger_time",
++  /*  251 */ "trigger_event",
++  /*  252 */ "foreach_clause",
++  /*  253 */ "when_clause",
++  /*  254 */ "trigger_cmd",
++  /*  255 */ "trnm",
++  /*  256 */ "tridxby",
++  /*  257 */ "database_kw_opt",
++  /*  258 */ "key_opt",
++  /*  259 */ "add_column_fullname",
++  /*  260 */ "kwcolumn_opt",
++  /*  261 */ "create_vtab",
++  /*  262 */ "vtabarglist",
++  /*  263 */ "vtabarg",
++  /*  264 */ "vtabargtoken",
++  /*  265 */ "lp",
++  /*  266 */ "anylist",
++  /*  267 */ "windowdefn_list",
++  /*  268 */ "windowdefn",
++  /*  269 */ "window",
++  /*  270 */ "frame_opt",
++  /*  271 */ "part_opt",
++  /*  272 */ "filter_opt",
++  /*  273 */ "range_or_rows",
++  /*  274 */ "frame_bound",
++  /*  275 */ "frame_bound_s",
++  /*  276 */ "frame_bound_e",
+ };
+-#endif /* NDEBUG */
++#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
+ 
+ #ifndef NDEBUG
+ /* For tracing reduce actions, the names of all rules are required.
+@@ -137665,307 +148233,345 @@
+  /*  25 */ "typetoken ::= typename LP signed RP",
+  /*  26 */ "typetoken ::= typename LP signed COMMA signed RP",
+  /*  27 */ "typename ::= typename ID|STRING",
+- /*  28 */ "ccons ::= CONSTRAINT nm",
+- /*  29 */ "ccons ::= DEFAULT term",
+- /*  30 */ "ccons ::= DEFAULT LP expr RP",
+- /*  31 */ "ccons ::= DEFAULT PLUS term",
+- /*  32 */ "ccons ::= DEFAULT MINUS term",
+- /*  33 */ "ccons ::= DEFAULT ID|INDEXED",
+- /*  34 */ "ccons ::= NOT NULL onconf",
+- /*  35 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+- /*  36 */ "ccons ::= UNIQUE onconf",
+- /*  37 */ "ccons ::= CHECK LP expr RP",
+- /*  38 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+- /*  39 */ "ccons ::= defer_subclause",
+- /*  40 */ "ccons ::= COLLATE ID|STRING",
+- /*  41 */ "autoinc ::=",
+- /*  42 */ "autoinc ::= AUTOINCR",
+- /*  43 */ "refargs ::=",
+- /*  44 */ "refargs ::= refargs refarg",
+- /*  45 */ "refarg ::= MATCH nm",
+- /*  46 */ "refarg ::= ON INSERT refact",
+- /*  47 */ "refarg ::= ON DELETE refact",
+- /*  48 */ "refarg ::= ON UPDATE refact",
+- /*  49 */ "refact ::= SET NULL",
+- /*  50 */ "refact ::= SET DEFAULT",
+- /*  51 */ "refact ::= CASCADE",
+- /*  52 */ "refact ::= RESTRICT",
+- /*  53 */ "refact ::= NO ACTION",
+- /*  54 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+- /*  55 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+- /*  56 */ "init_deferred_pred_opt ::=",
+- /*  57 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+- /*  58 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+- /*  59 */ "conslist_opt ::=",
+- /*  60 */ "tconscomma ::= COMMA",
+- /*  61 */ "tcons ::= CONSTRAINT nm",
+- /*  62 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+- /*  63 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+- /*  64 */ "tcons ::= CHECK LP expr RP onconf",
+- /*  65 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+- /*  66 */ "defer_subclause_opt ::=",
+- /*  67 */ "onconf ::=",
+- /*  68 */ "onconf ::= ON CONFLICT resolvetype",
+- /*  69 */ "orconf ::=",
+- /*  70 */ "orconf ::= OR resolvetype",
+- /*  71 */ "resolvetype ::= IGNORE",
+- /*  72 */ "resolvetype ::= REPLACE",
+- /*  73 */ "cmd ::= DROP TABLE ifexists fullname",
+- /*  74 */ "ifexists ::= IF EXISTS",
+- /*  75 */ "ifexists ::=",
+- /*  76 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+- /*  77 */ "cmd ::= DROP VIEW ifexists fullname",
+- /*  78 */ "cmd ::= select",
+- /*  79 */ "select ::= with selectnowith",
+- /*  80 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+- /*  81 */ "multiselect_op ::= UNION",
+- /*  82 */ "multiselect_op ::= UNION ALL",
+- /*  83 */ "multiselect_op ::= EXCEPT|INTERSECT",
+- /*  84 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+- /*  85 */ "values ::= VALUES LP nexprlist RP",
+- /*  86 */ "values ::= values COMMA LP exprlist RP",
+- /*  87 */ "distinct ::= DISTINCT",
+- /*  88 */ "distinct ::= ALL",
+- /*  89 */ "distinct ::=",
+- /*  90 */ "sclp ::=",
+- /*  91 */ "selcollist ::= sclp expr as",
+- /*  92 */ "selcollist ::= sclp STAR",
+- /*  93 */ "selcollist ::= sclp nm DOT STAR",
+- /*  94 */ "as ::= AS nm",
+- /*  95 */ "as ::=",
+- /*  96 */ "from ::=",
+- /*  97 */ "from ::= FROM seltablist",
+- /*  98 */ "stl_prefix ::= seltablist joinop",
+- /*  99 */ "stl_prefix ::=",
+- /* 100 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+- /* 101 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+- /* 102 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+- /* 103 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+- /* 104 */ "dbnm ::=",
+- /* 105 */ "dbnm ::= DOT nm",
+- /* 106 */ "fullname ::= nm dbnm",
+- /* 107 */ "joinop ::= COMMA|JOIN",
+- /* 108 */ "joinop ::= JOIN_KW JOIN",
+- /* 109 */ "joinop ::= JOIN_KW nm JOIN",
+- /* 110 */ "joinop ::= JOIN_KW nm nm JOIN",
+- /* 111 */ "on_opt ::= ON expr",
+- /* 112 */ "on_opt ::=",
+- /* 113 */ "indexed_opt ::=",
+- /* 114 */ "indexed_opt ::= INDEXED BY nm",
+- /* 115 */ "indexed_opt ::= NOT INDEXED",
+- /* 116 */ "using_opt ::= USING LP idlist RP",
+- /* 117 */ "using_opt ::=",
+- /* 118 */ "orderby_opt ::=",
+- /* 119 */ "orderby_opt ::= ORDER BY sortlist",
+- /* 120 */ "sortlist ::= sortlist COMMA expr sortorder",
+- /* 121 */ "sortlist ::= expr sortorder",
+- /* 122 */ "sortorder ::= ASC",
+- /* 123 */ "sortorder ::= DESC",
+- /* 124 */ "sortorder ::=",
+- /* 125 */ "groupby_opt ::=",
+- /* 126 */ "groupby_opt ::= GROUP BY nexprlist",
+- /* 127 */ "having_opt ::=",
+- /* 128 */ "having_opt ::= HAVING expr",
+- /* 129 */ "limit_opt ::=",
+- /* 130 */ "limit_opt ::= LIMIT expr",
+- /* 131 */ "limit_opt ::= LIMIT expr OFFSET expr",
+- /* 132 */ "limit_opt ::= LIMIT expr COMMA expr",
+- /* 133 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+- /* 134 */ "where_opt ::=",
+- /* 135 */ "where_opt ::= WHERE expr",
+- /* 136 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+- /* 137 */ "setlist ::= setlist COMMA nm EQ expr",
+- /* 138 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+- /* 139 */ "setlist ::= nm EQ expr",
+- /* 140 */ "setlist ::= LP idlist RP EQ expr",
+- /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+- /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+- /* 143 */ "insert_cmd ::= INSERT orconf",
+- /* 144 */ "insert_cmd ::= REPLACE",
+- /* 145 */ "idlist_opt ::=",
+- /* 146 */ "idlist_opt ::= LP idlist RP",
+- /* 147 */ "idlist ::= idlist COMMA nm",
+- /* 148 */ "idlist ::= nm",
+- /* 149 */ "expr ::= LP expr RP",
+- /* 150 */ "expr ::= ID|INDEXED",
+- /* 151 */ "expr ::= JOIN_KW",
+- /* 152 */ "expr ::= nm DOT nm",
+- /* 153 */ "expr ::= nm DOT nm DOT nm",
+- /* 154 */ "term ::= NULL|FLOAT|BLOB",
+- /* 155 */ "term ::= STRING",
+- /* 156 */ "term ::= INTEGER",
+- /* 157 */ "expr ::= VARIABLE",
+- /* 158 */ "expr ::= expr COLLATE ID|STRING",
+- /* 159 */ "expr ::= CAST LP expr AS typetoken RP",
+- /* 160 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+- /* 161 */ "expr ::= ID|INDEXED LP STAR RP",
+- /* 162 */ "term ::= CTIME_KW",
+- /* 163 */ "expr ::= LP nexprlist COMMA expr RP",
+- /* 164 */ "expr ::= expr AND expr",
+- /* 165 */ "expr ::= expr OR expr",
+- /* 166 */ "expr ::= expr LT|GT|GE|LE expr",
+- /* 167 */ "expr ::= expr EQ|NE expr",
+- /* 168 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+- /* 169 */ "expr ::= expr PLUS|MINUS expr",
+- /* 170 */ "expr ::= expr STAR|SLASH|REM expr",
+- /* 171 */ "expr ::= expr CONCAT expr",
+- /* 172 */ "likeop ::= NOT LIKE_KW|MATCH",
+- /* 173 */ "expr ::= expr likeop expr",
+- /* 174 */ "expr ::= expr likeop expr ESCAPE expr",
+- /* 175 */ "expr ::= expr ISNULL|NOTNULL",
+- /* 176 */ "expr ::= expr NOT NULL",
+- /* 177 */ "expr ::= expr IS expr",
+- /* 178 */ "expr ::= expr IS NOT expr",
+- /* 179 */ "expr ::= NOT expr",
+- /* 180 */ "expr ::= BITNOT expr",
+- /* 181 */ "expr ::= MINUS expr",
+- /* 182 */ "expr ::= PLUS expr",
+- /* 183 */ "between_op ::= BETWEEN",
+- /* 184 */ "between_op ::= NOT BETWEEN",
+- /* 185 */ "expr ::= expr between_op expr AND expr",
+- /* 186 */ "in_op ::= IN",
+- /* 187 */ "in_op ::= NOT IN",
+- /* 188 */ "expr ::= expr in_op LP exprlist RP",
+- /* 189 */ "expr ::= LP select RP",
+- /* 190 */ "expr ::= expr in_op LP select RP",
+- /* 191 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+- /* 192 */ "expr ::= EXISTS LP select RP",
+- /* 193 */ "expr ::= CASE case_operand case_exprlist case_else END",
+- /* 194 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+- /* 195 */ "case_exprlist ::= WHEN expr THEN expr",
+- /* 196 */ "case_else ::= ELSE expr",
+- /* 197 */ "case_else ::=",
+- /* 198 */ "case_operand ::= expr",
+- /* 199 */ "case_operand ::=",
+- /* 200 */ "exprlist ::=",
+- /* 201 */ "nexprlist ::= nexprlist COMMA expr",
+- /* 202 */ "nexprlist ::= expr",
+- /* 203 */ "paren_exprlist ::=",
+- /* 204 */ "paren_exprlist ::= LP exprlist RP",
+- /* 205 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+- /* 206 */ "uniqueflag ::= UNIQUE",
+- /* 207 */ "uniqueflag ::=",
+- /* 208 */ "eidlist_opt ::=",
+- /* 209 */ "eidlist_opt ::= LP eidlist RP",
+- /* 210 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+- /* 211 */ "eidlist ::= nm collate sortorder",
+- /* 212 */ "collate ::=",
+- /* 213 */ "collate ::= COLLATE ID|STRING",
+- /* 214 */ "cmd ::= DROP INDEX ifexists fullname",
+- /* 215 */ "cmd ::= VACUUM",
+- /* 216 */ "cmd ::= VACUUM nm",
+- /* 217 */ "cmd ::= PRAGMA nm dbnm",
+- /* 218 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+- /* 219 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+- /* 220 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+- /* 221 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+- /* 222 */ "plus_num ::= PLUS INTEGER|FLOAT",
+- /* 223 */ "minus_num ::= MINUS INTEGER|FLOAT",
+- /* 224 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+- /* 225 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+- /* 226 */ "trigger_time ::= BEFORE|AFTER",
+- /* 227 */ "trigger_time ::= INSTEAD OF",
+- /* 228 */ "trigger_time ::=",
+- /* 229 */ "trigger_event ::= DELETE|INSERT",
+- /* 230 */ "trigger_event ::= UPDATE",
+- /* 231 */ "trigger_event ::= UPDATE OF idlist",
+- /* 232 */ "when_clause ::=",
+- /* 233 */ "when_clause ::= WHEN expr",
+- /* 234 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+- /* 235 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+- /* 236 */ "trnm ::= nm DOT nm",
+- /* 237 */ "tridxby ::= INDEXED BY nm",
+- /* 238 */ "tridxby ::= NOT INDEXED",
+- /* 239 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+- /* 240 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+- /* 241 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+- /* 242 */ "trigger_cmd ::= select",
+- /* 243 */ "expr ::= RAISE LP IGNORE RP",
+- /* 244 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+- /* 245 */ "raisetype ::= ROLLBACK",
+- /* 246 */ "raisetype ::= ABORT",
+- /* 247 */ "raisetype ::= FAIL",
+- /* 248 */ "cmd ::= DROP TRIGGER ifexists fullname",
+- /* 249 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+- /* 250 */ "cmd ::= DETACH database_kw_opt expr",
+- /* 251 */ "key_opt ::=",
+- /* 252 */ "key_opt ::= KEY expr",
+- /* 253 */ "cmd ::= REINDEX",
+- /* 254 */ "cmd ::= REINDEX nm dbnm",
+- /* 255 */ "cmd ::= ANALYZE",
+- /* 256 */ "cmd ::= ANALYZE nm dbnm",
+- /* 257 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+- /* 258 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+- /* 259 */ "add_column_fullname ::= fullname",
+- /* 260 */ "cmd ::= create_vtab",
+- /* 261 */ "cmd ::= create_vtab LP vtabarglist RP",
+- /* 262 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+- /* 263 */ "vtabarg ::=",
+- /* 264 */ "vtabargtoken ::= ANY",
+- /* 265 */ "vtabargtoken ::= lp anylist RP",
+- /* 266 */ "lp ::= LP",
+- /* 267 */ "with ::=",
+- /* 268 */ "with ::= WITH wqlist",
+- /* 269 */ "with ::= WITH RECURSIVE wqlist",
+- /* 270 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+- /* 271 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+- /* 272 */ "input ::= cmdlist",
+- /* 273 */ "cmdlist ::= cmdlist ecmd",
+- /* 274 */ "cmdlist ::= ecmd",
+- /* 275 */ "ecmd ::= SEMI",
+- /* 276 */ "ecmd ::= explain cmdx SEMI",
+- /* 277 */ "explain ::=",
+- /* 278 */ "trans_opt ::=",
+- /* 279 */ "trans_opt ::= TRANSACTION",
+- /* 280 */ "trans_opt ::= TRANSACTION nm",
+- /* 281 */ "savepoint_opt ::= SAVEPOINT",
+- /* 282 */ "savepoint_opt ::=",
+- /* 283 */ "cmd ::= create_table create_table_args",
+- /* 284 */ "columnlist ::= columnlist COMMA columnname carglist",
+- /* 285 */ "columnlist ::= columnname carglist",
+- /* 286 */ "nm ::= ID|INDEXED",
+- /* 287 */ "nm ::= STRING",
+- /* 288 */ "nm ::= JOIN_KW",
+- /* 289 */ "typetoken ::= typename",
+- /* 290 */ "typename ::= ID|STRING",
+- /* 291 */ "signed ::= plus_num",
+- /* 292 */ "signed ::= minus_num",
+- /* 293 */ "carglist ::= carglist ccons",
+- /* 294 */ "carglist ::=",
+- /* 295 */ "ccons ::= NULL onconf",
+- /* 296 */ "conslist_opt ::= COMMA conslist",
+- /* 297 */ "conslist ::= conslist tconscomma tcons",
+- /* 298 */ "conslist ::= tcons",
+- /* 299 */ "tconscomma ::=",
+- /* 300 */ "defer_subclause_opt ::= defer_subclause",
+- /* 301 */ "resolvetype ::= raisetype",
+- /* 302 */ "selectnowith ::= oneselect",
+- /* 303 */ "oneselect ::= values",
+- /* 304 */ "sclp ::= selcollist COMMA",
+- /* 305 */ "as ::= ID|STRING",
+- /* 306 */ "expr ::= term",
+- /* 307 */ "likeop ::= LIKE_KW|MATCH",
+- /* 308 */ "exprlist ::= nexprlist",
+- /* 309 */ "nmnum ::= plus_num",
+- /* 310 */ "nmnum ::= nm",
+- /* 311 */ "nmnum ::= ON",
+- /* 312 */ "nmnum ::= DELETE",
+- /* 313 */ "nmnum ::= DEFAULT",
+- /* 314 */ "plus_num ::= INTEGER|FLOAT",
+- /* 315 */ "foreach_clause ::=",
+- /* 316 */ "foreach_clause ::= FOR EACH ROW",
+- /* 317 */ "trnm ::= nm",
+- /* 318 */ "tridxby ::=",
+- /* 319 */ "database_kw_opt ::= DATABASE",
+- /* 320 */ "database_kw_opt ::=",
+- /* 321 */ "kwcolumn_opt ::=",
+- /* 322 */ "kwcolumn_opt ::= COLUMNKW",
+- /* 323 */ "vtabarglist ::= vtabarg",
+- /* 324 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+- /* 325 */ "vtabarg ::= vtabarg vtabargtoken",
+- /* 326 */ "anylist ::=",
+- /* 327 */ "anylist ::= anylist LP anylist RP",
+- /* 328 */ "anylist ::= anylist ANY",
++ /*  28 */ "scanpt ::=",
++ /*  29 */ "ccons ::= CONSTRAINT nm",
++ /*  30 */ "ccons ::= DEFAULT scanpt term scanpt",
++ /*  31 */ "ccons ::= DEFAULT LP expr RP",
++ /*  32 */ "ccons ::= DEFAULT PLUS term scanpt",
++ /*  33 */ "ccons ::= DEFAULT MINUS term scanpt",
++ /*  34 */ "ccons ::= DEFAULT scanpt ID|INDEXED",
++ /*  35 */ "ccons ::= NOT NULL onconf",
++ /*  36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
++ /*  37 */ "ccons ::= UNIQUE onconf",
++ /*  38 */ "ccons ::= CHECK LP expr RP",
++ /*  39 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
++ /*  40 */ "ccons ::= defer_subclause",
++ /*  41 */ "ccons ::= COLLATE ID|STRING",
++ /*  42 */ "autoinc ::=",
++ /*  43 */ "autoinc ::= AUTOINCR",
++ /*  44 */ "refargs ::=",
++ /*  45 */ "refargs ::= refargs refarg",
++ /*  46 */ "refarg ::= MATCH nm",
++ /*  47 */ "refarg ::= ON INSERT refact",
++ /*  48 */ "refarg ::= ON DELETE refact",
++ /*  49 */ "refarg ::= ON UPDATE refact",
++ /*  50 */ "refact ::= SET NULL",
++ /*  51 */ "refact ::= SET DEFAULT",
++ /*  52 */ "refact ::= CASCADE",
++ /*  53 */ "refact ::= RESTRICT",
++ /*  54 */ "refact ::= NO ACTION",
++ /*  55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
++ /*  56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
++ /*  57 */ "init_deferred_pred_opt ::=",
++ /*  58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
++ /*  59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
++ /*  60 */ "conslist_opt ::=",
++ /*  61 */ "tconscomma ::= COMMA",
++ /*  62 */ "tcons ::= CONSTRAINT nm",
++ /*  63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
++ /*  64 */ "tcons ::= UNIQUE LP sortlist RP onconf",
++ /*  65 */ "tcons ::= CHECK LP expr RP onconf",
++ /*  66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
++ /*  67 */ "defer_subclause_opt ::=",
++ /*  68 */ "onconf ::=",
++ /*  69 */ "onconf ::= ON CONFLICT resolvetype",
++ /*  70 */ "orconf ::=",
++ /*  71 */ "orconf ::= OR resolvetype",
++ /*  72 */ "resolvetype ::= IGNORE",
++ /*  73 */ "resolvetype ::= REPLACE",
++ /*  74 */ "cmd ::= DROP TABLE ifexists fullname",
++ /*  75 */ "ifexists ::= IF EXISTS",
++ /*  76 */ "ifexists ::=",
++ /*  77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
++ /*  78 */ "cmd ::= DROP VIEW ifexists fullname",
++ /*  79 */ "cmd ::= select",
++ /*  80 */ "select ::= WITH wqlist selectnowith",
++ /*  81 */ "select ::= WITH RECURSIVE wqlist selectnowith",
++ /*  82 */ "select ::= selectnowith",
++ /*  83 */ "selectnowith ::= selectnowith multiselect_op oneselect",
++ /*  84 */ "multiselect_op ::= UNION",
++ /*  85 */ "multiselect_op ::= UNION ALL",
++ /*  86 */ "multiselect_op ::= EXCEPT|INTERSECT",
++ /*  87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
++ /*  88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
++ /*  89 */ "values ::= VALUES LP nexprlist RP",
++ /*  90 */ "values ::= values COMMA LP nexprlist RP",
++ /*  91 */ "distinct ::= DISTINCT",
++ /*  92 */ "distinct ::= ALL",
++ /*  93 */ "distinct ::=",
++ /*  94 */ "sclp ::=",
++ /*  95 */ "selcollist ::= sclp scanpt expr scanpt as",
++ /*  96 */ "selcollist ::= sclp scanpt STAR",
++ /*  97 */ "selcollist ::= sclp scanpt nm DOT STAR",
++ /*  98 */ "as ::= AS nm",
++ /*  99 */ "as ::=",
++ /* 100 */ "from ::=",
++ /* 101 */ "from ::= FROM seltablist",
++ /* 102 */ "stl_prefix ::= seltablist joinop",
++ /* 103 */ "stl_prefix ::=",
++ /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
++ /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
++ /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
++ /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
++ /* 108 */ "dbnm ::=",
++ /* 109 */ "dbnm ::= DOT nm",
++ /* 110 */ "fullname ::= nm",
++ /* 111 */ "fullname ::= nm DOT nm",
++ /* 112 */ "xfullname ::= nm",
++ /* 113 */ "xfullname ::= nm DOT nm",
++ /* 114 */ "xfullname ::= nm DOT nm AS nm",
++ /* 115 */ "xfullname ::= nm AS nm",
++ /* 116 */ "joinop ::= COMMA|JOIN",
++ /* 117 */ "joinop ::= JOIN_KW JOIN",
++ /* 118 */ "joinop ::= JOIN_KW nm JOIN",
++ /* 119 */ "joinop ::= JOIN_KW nm nm JOIN",
++ /* 120 */ "on_opt ::= ON expr",
++ /* 121 */ "on_opt ::=",
++ /* 122 */ "indexed_opt ::=",
++ /* 123 */ "indexed_opt ::= INDEXED BY nm",
++ /* 124 */ "indexed_opt ::= NOT INDEXED",
++ /* 125 */ "using_opt ::= USING LP idlist RP",
++ /* 126 */ "using_opt ::=",
++ /* 127 */ "orderby_opt ::=",
++ /* 128 */ "orderby_opt ::= ORDER BY sortlist",
++ /* 129 */ "sortlist ::= sortlist COMMA expr sortorder",
++ /* 130 */ "sortlist ::= expr sortorder",
++ /* 131 */ "sortorder ::= ASC",
++ /* 132 */ "sortorder ::= DESC",
++ /* 133 */ "sortorder ::=",
++ /* 134 */ "groupby_opt ::=",
++ /* 135 */ "groupby_opt ::= GROUP BY nexprlist",
++ /* 136 */ "having_opt ::=",
++ /* 137 */ "having_opt ::= HAVING expr",
++ /* 138 */ "limit_opt ::=",
++ /* 139 */ "limit_opt ::= LIMIT expr",
++ /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr",
++ /* 141 */ "limit_opt ::= LIMIT expr COMMA expr",
++ /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
++ /* 143 */ "where_opt ::=",
++ /* 144 */ "where_opt ::= WHERE expr",
++ /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
++ /* 146 */ "setlist ::= setlist COMMA nm EQ expr",
++ /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
++ /* 148 */ "setlist ::= nm EQ expr",
++ /* 149 */ "setlist ::= LP idlist RP EQ expr",
++ /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
++ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
++ /* 152 */ "upsert ::=",
++ /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
++ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
++ /* 155 */ "upsert ::= ON CONFLICT DO NOTHING",
++ /* 156 */ "insert_cmd ::= INSERT orconf",
++ /* 157 */ "insert_cmd ::= REPLACE",
++ /* 158 */ "idlist_opt ::=",
++ /* 159 */ "idlist_opt ::= LP idlist RP",
++ /* 160 */ "idlist ::= idlist COMMA nm",
++ /* 161 */ "idlist ::= nm",
++ /* 162 */ "expr ::= LP expr RP",
++ /* 163 */ "expr ::= ID|INDEXED",
++ /* 164 */ "expr ::= JOIN_KW",
++ /* 165 */ "expr ::= nm DOT nm",
++ /* 166 */ "expr ::= nm DOT nm DOT nm",
++ /* 167 */ "term ::= NULL|FLOAT|BLOB",
++ /* 168 */ "term ::= STRING",
++ /* 169 */ "term ::= INTEGER",
++ /* 170 */ "expr ::= VARIABLE",
++ /* 171 */ "expr ::= expr COLLATE ID|STRING",
++ /* 172 */ "expr ::= CAST LP expr AS typetoken RP",
++ /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
++ /* 174 */ "expr ::= ID|INDEXED LP STAR RP",
++ /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
++ /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
++ /* 177 */ "term ::= CTIME_KW",
++ /* 178 */ "expr ::= LP nexprlist COMMA expr RP",
++ /* 179 */ "expr ::= expr AND expr",
++ /* 180 */ "expr ::= expr OR expr",
++ /* 181 */ "expr ::= expr LT|GT|GE|LE expr",
++ /* 182 */ "expr ::= expr EQ|NE expr",
++ /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
++ /* 184 */ "expr ::= expr PLUS|MINUS expr",
++ /* 185 */ "expr ::= expr STAR|SLASH|REM expr",
++ /* 186 */ "expr ::= expr CONCAT expr",
++ /* 187 */ "likeop ::= NOT LIKE_KW|MATCH",
++ /* 188 */ "expr ::= expr likeop expr",
++ /* 189 */ "expr ::= expr likeop expr ESCAPE expr",
++ /* 190 */ "expr ::= expr ISNULL|NOTNULL",
++ /* 191 */ "expr ::= expr NOT NULL",
++ /* 192 */ "expr ::= expr IS expr",
++ /* 193 */ "expr ::= expr IS NOT expr",
++ /* 194 */ "expr ::= NOT expr",
++ /* 195 */ "expr ::= BITNOT expr",
++ /* 196 */ "expr ::= PLUS|MINUS expr",
++ /* 197 */ "between_op ::= BETWEEN",
++ /* 198 */ "between_op ::= NOT BETWEEN",
++ /* 199 */ "expr ::= expr between_op expr AND expr",
++ /* 200 */ "in_op ::= IN",
++ /* 201 */ "in_op ::= NOT IN",
++ /* 202 */ "expr ::= expr in_op LP exprlist RP",
++ /* 203 */ "expr ::= LP select RP",
++ /* 204 */ "expr ::= expr in_op LP select RP",
++ /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist",
++ /* 206 */ "expr ::= EXISTS LP select RP",
++ /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END",
++ /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
++ /* 209 */ "case_exprlist ::= WHEN expr THEN expr",
++ /* 210 */ "case_else ::= ELSE expr",
++ /* 211 */ "case_else ::=",
++ /* 212 */ "case_operand ::= expr",
++ /* 213 */ "case_operand ::=",
++ /* 214 */ "exprlist ::=",
++ /* 215 */ "nexprlist ::= nexprlist COMMA expr",
++ /* 216 */ "nexprlist ::= expr",
++ /* 217 */ "paren_exprlist ::=",
++ /* 218 */ "paren_exprlist ::= LP exprlist RP",
++ /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
++ /* 220 */ "uniqueflag ::= UNIQUE",
++ /* 221 */ "uniqueflag ::=",
++ /* 222 */ "eidlist_opt ::=",
++ /* 223 */ "eidlist_opt ::= LP eidlist RP",
++ /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder",
++ /* 225 */ "eidlist ::= nm collate sortorder",
++ /* 226 */ "collate ::=",
++ /* 227 */ "collate ::= COLLATE ID|STRING",
++ /* 228 */ "cmd ::= DROP INDEX ifexists fullname",
++ /* 229 */ "cmd ::= VACUUM",
++ /* 230 */ "cmd ::= VACUUM nm",
++ /* 231 */ "cmd ::= PRAGMA nm dbnm",
++ /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
++ /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
++ /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
++ /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
++ /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT",
++ /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT",
++ /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
++ /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
++ /* 240 */ "trigger_time ::= BEFORE|AFTER",
++ /* 241 */ "trigger_time ::= INSTEAD OF",
++ /* 242 */ "trigger_time ::=",
++ /* 243 */ "trigger_event ::= DELETE|INSERT",
++ /* 244 */ "trigger_event ::= UPDATE",
++ /* 245 */ "trigger_event ::= UPDATE OF idlist",
++ /* 246 */ "when_clause ::=",
++ /* 247 */ "when_clause ::= WHEN expr",
++ /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
++ /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI",
++ /* 250 */ "trnm ::= nm DOT nm",
++ /* 251 */ "tridxby ::= INDEXED BY nm",
++ /* 252 */ "tridxby ::= NOT INDEXED",
++ /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
++ /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
++ /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
++ /* 256 */ "trigger_cmd ::= scanpt select scanpt",
++ /* 257 */ "expr ::= RAISE LP IGNORE RP",
++ /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP",
++ /* 259 */ "raisetype ::= ROLLBACK",
++ /* 260 */ "raisetype ::= ABORT",
++ /* 261 */ "raisetype ::= FAIL",
++ /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname",
++ /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
++ /* 264 */ "cmd ::= DETACH database_kw_opt expr",
++ /* 265 */ "key_opt ::=",
++ /* 266 */ "key_opt ::= KEY expr",
++ /* 267 */ "cmd ::= REINDEX",
++ /* 268 */ "cmd ::= REINDEX nm dbnm",
++ /* 269 */ "cmd ::= ANALYZE",
++ /* 270 */ "cmd ::= ANALYZE nm dbnm",
++ /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
++ /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
++ /* 273 */ "add_column_fullname ::= fullname",
++ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
++ /* 275 */ "cmd ::= create_vtab",
++ /* 276 */ "cmd ::= create_vtab LP vtabarglist RP",
++ /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
++ /* 278 */ "vtabarg ::=",
++ /* 279 */ "vtabargtoken ::= ANY",
++ /* 280 */ "vtabargtoken ::= lp anylist RP",
++ /* 281 */ "lp ::= LP",
++ /* 282 */ "with ::= WITH wqlist",
++ /* 283 */ "with ::= WITH RECURSIVE wqlist",
++ /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP",
++ /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
++ /* 286 */ "windowdefn_list ::= windowdefn",
++ /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
++ /* 288 */ "windowdefn ::= nm AS window",
++ /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP",
++ /* 290 */ "part_opt ::= PARTITION BY nexprlist",
++ /* 291 */ "part_opt ::=",
++ /* 292 */ "frame_opt ::=",
++ /* 293 */ "frame_opt ::= range_or_rows frame_bound_s",
++ /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
++ /* 295 */ "range_or_rows ::= RANGE",
++ /* 296 */ "range_or_rows ::= ROWS",
++ /* 297 */ "frame_bound_s ::= frame_bound",
++ /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
++ /* 299 */ "frame_bound_e ::= frame_bound",
++ /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
++ /* 301 */ "frame_bound ::= expr PRECEDING",
++ /* 302 */ "frame_bound ::= CURRENT ROW",
++ /* 303 */ "frame_bound ::= expr FOLLOWING",
++ /* 304 */ "window_clause ::= WINDOW windowdefn_list",
++ /* 305 */ "over_clause ::= filter_opt OVER window",
++ /* 306 */ "over_clause ::= filter_opt OVER nm",
++ /* 307 */ "filter_opt ::=",
++ /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP",
++ /* 309 */ "input ::= cmdlist",
++ /* 310 */ "cmdlist ::= cmdlist ecmd",
++ /* 311 */ "cmdlist ::= ecmd",
++ /* 312 */ "ecmd ::= SEMI",
++ /* 313 */ "ecmd ::= cmdx SEMI",
++ /* 314 */ "ecmd ::= explain cmdx",
++ /* 315 */ "trans_opt ::=",
++ /* 316 */ "trans_opt ::= TRANSACTION",
++ /* 317 */ "trans_opt ::= TRANSACTION nm",
++ /* 318 */ "savepoint_opt ::= SAVEPOINT",
++ /* 319 */ "savepoint_opt ::=",
++ /* 320 */ "cmd ::= create_table create_table_args",
++ /* 321 */ "columnlist ::= columnlist COMMA columnname carglist",
++ /* 322 */ "columnlist ::= columnname carglist",
++ /* 323 */ "nm ::= ID|INDEXED",
++ /* 324 */ "nm ::= STRING",
++ /* 325 */ "nm ::= JOIN_KW",
++ /* 326 */ "typetoken ::= typename",
++ /* 327 */ "typename ::= ID|STRING",
++ /* 328 */ "signed ::= plus_num",
++ /* 329 */ "signed ::= minus_num",
++ /* 330 */ "carglist ::= carglist ccons",
++ /* 331 */ "carglist ::=",
++ /* 332 */ "ccons ::= NULL onconf",
++ /* 333 */ "conslist_opt ::= COMMA conslist",
++ /* 334 */ "conslist ::= conslist tconscomma tcons",
++ /* 335 */ "conslist ::= tcons",
++ /* 336 */ "tconscomma ::=",
++ /* 337 */ "defer_subclause_opt ::= defer_subclause",
++ /* 338 */ "resolvetype ::= raisetype",
++ /* 339 */ "selectnowith ::= oneselect",
++ /* 340 */ "oneselect ::= values",
++ /* 341 */ "sclp ::= selcollist COMMA",
++ /* 342 */ "as ::= ID|STRING",
++ /* 343 */ "expr ::= term",
++ /* 344 */ "likeop ::= LIKE_KW|MATCH",
++ /* 345 */ "exprlist ::= nexprlist",
++ /* 346 */ "nmnum ::= plus_num",
++ /* 347 */ "nmnum ::= nm",
++ /* 348 */ "nmnum ::= ON",
++ /* 349 */ "nmnum ::= DELETE",
++ /* 350 */ "nmnum ::= DEFAULT",
++ /* 351 */ "plus_num ::= INTEGER|FLOAT",
++ /* 352 */ "foreach_clause ::=",
++ /* 353 */ "foreach_clause ::= FOR EACH ROW",
++ /* 354 */ "trnm ::= nm",
++ /* 355 */ "tridxby ::=",
++ /* 356 */ "database_kw_opt ::= DATABASE",
++ /* 357 */ "database_kw_opt ::=",
++ /* 358 */ "kwcolumn_opt ::=",
++ /* 359 */ "kwcolumn_opt ::= COLUMNKW",
++ /* 360 */ "vtabarglist ::= vtabarg",
++ /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
++ /* 362 */ "vtabarg ::= vtabarg vtabargtoken",
++ /* 363 */ "anylist ::=",
++ /* 364 */ "anylist ::= anylist LP anylist RP",
++ /* 365 */ "anylist ::= anylist ANY",
++ /* 366 */ "with ::=",
+ };
+ #endif /* NDEBUG */
+ 
+@@ -138014,28 +148620,29 @@
+ 
+ /* Initialize a new parser that has already been allocated.
+ */
+-SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
+-  yyParser *pParser = (yyParser*)yypParser;
++SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){
++  yyParser *yypParser = (yyParser*)yypRawParser;
++  sqlite3ParserCTX_STORE
+ #ifdef YYTRACKMAXSTACKDEPTH
+-  pParser->yyhwm = 0;
++  yypParser->yyhwm = 0;
+ #endif
+ #if YYSTACKDEPTH<=0
+-  pParser->yytos = NULL;
+-  pParser->yystack = NULL;
+-  pParser->yystksz = 0;
+-  if( yyGrowStack(pParser) ){
+-    pParser->yystack = &pParser->yystk0;
+-    pParser->yystksz = 1;
++  yypParser->yytos = NULL;
++  yypParser->yystack = NULL;
++  yypParser->yystksz = 0;
++  if( yyGrowStack(yypParser) ){
++    yypParser->yystack = &yypParser->yystk0;
++    yypParser->yystksz = 1;
+   }
+ #endif
+ #ifndef YYNOERRORRECOVERY
+-  pParser->yyerrcnt = -1;
++  yypParser->yyerrcnt = -1;
+ #endif
+-  pParser->yytos = pParser->yystack;
+-  pParser->yystack[0].stateno = 0;
+-  pParser->yystack[0].major = 0;
++  yypParser->yytos = yypParser->yystack;
++  yypParser->yystack[0].stateno = 0;
++  yypParser->yystack[0].major = 0;
+ #if YYSTACKDEPTH>0
+-  pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
++  yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
+ #endif
+ }
+ 
+@@ -138052,11 +148659,14 @@
+ ** A pointer to a parser.  This pointer is used in subsequent calls
+ ** to sqlite3Parser and sqlite3ParserFree.
+ */
+-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
+-  yyParser *pParser;
+-  pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
+-  if( pParser ) sqlite3ParserInit(pParser);
+-  return pParser;
++SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){
++  yyParser *yypParser;
++  yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
++  if( yypParser ){
++    sqlite3ParserCTX_STORE
++    sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM);
++  }
++  return (void*)yypParser;
+ }
+ #endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+ 
+@@ -138073,7 +148683,8 @@
+   YYCODETYPE yymajor,     /* Type code for object to destroy */
+   YYMINORTYPE *yypminor   /* The object to be destroyed */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+   switch( yymajor ){
+     /* Here is inserted the actions which take place when a
+     ** terminal or non-terminal is destroyed.  This can happen
+@@ -138086,79 +148697,98 @@
+     ** inside the C code.
+     */
+ /********* Begin destructor definitions ***************************************/
+-    case 163: /* select */
+-    case 194: /* selectnowith */
+-    case 195: /* oneselect */
+-    case 206: /* values */
++    case 174: /* select */
++    case 206: /* selectnowith */
++    case 207: /* oneselect */
++    case 219: /* values */
+ {
+-sqlite3SelectDelete(pParse->db, (yypminor->yy243));
++sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+ }
+       break;
+-    case 172: /* term */
+-    case 173: /* expr */
++    case 184: /* term */
++    case 185: /* expr */
++    case 213: /* where_opt */
++    case 215: /* having_opt */
++    case 227: /* on_opt */
++    case 242: /* case_operand */
++    case 244: /* case_else */
++    case 253: /* when_clause */
++    case 258: /* key_opt */
++    case 272: /* filter_opt */
+ {
+-sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
++sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+ }
+       break;
+-    case 177: /* eidlist_opt */
+-    case 186: /* sortlist */
+-    case 187: /* eidlist */
+-    case 199: /* selcollist */
+-    case 202: /* groupby_opt */
+-    case 204: /* orderby_opt */
+-    case 207: /* nexprlist */
+-    case 208: /* exprlist */
+-    case 209: /* sclp */
+-    case 218: /* setlist */
+-    case 224: /* paren_exprlist */
+-    case 226: /* case_exprlist */
++    case 189: /* eidlist_opt */
++    case 198: /* sortlist */
++    case 199: /* eidlist */
++    case 211: /* selcollist */
++    case 214: /* groupby_opt */
++    case 216: /* orderby_opt */
++    case 220: /* nexprlist */
++    case 221: /* sclp */
++    case 229: /* exprlist */
++    case 233: /* setlist */
++    case 241: /* paren_exprlist */
++    case 243: /* case_exprlist */
++    case 271: /* part_opt */
+ {
+-sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
++sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
+ }
+       break;
+-    case 193: /* fullname */
+-    case 200: /* from */
+-    case 211: /* seltablist */
+-    case 212: /* stl_prefix */
++    case 205: /* fullname */
++    case 212: /* from */
++    case 223: /* seltablist */
++    case 224: /* stl_prefix */
++    case 230: /* xfullname */
+ {
+-sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
++sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
+ }
+       break;
+-    case 196: /* with */
+-    case 250: /* wqlist */
++    case 208: /* wqlist */
+ {
+-sqlite3WithDelete(pParse->db, (yypminor->yy285));
++sqlite3WithDelete(pParse->db, (yypminor->yy449));
+ }
+       break;
+-    case 201: /* where_opt */
+-    case 203: /* having_opt */
+-    case 215: /* on_opt */
+-    case 225: /* case_operand */
+-    case 227: /* case_else */
+-    case 236: /* when_clause */
+-    case 241: /* key_opt */
++    case 218: /* window_clause */
++    case 267: /* windowdefn_list */
+ {
+-sqlite3ExprDelete(pParse->db, (yypminor->yy72));
++sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
+ }
+       break;
+-    case 216: /* using_opt */
+-    case 217: /* idlist */
+-    case 220: /* idlist_opt */
++    case 228: /* using_opt */
++    case 231: /* idlist */
++    case 235: /* idlist_opt */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy254));
++sqlite3IdListDelete(pParse->db, (yypminor->yy48));
+ }
+       break;
+-    case 232: /* trigger_cmd_list */
+-    case 237: /* trigger_cmd */
++    case 237: /* over_clause */
++    case 268: /* windowdefn */
++    case 269: /* window */
++    case 270: /* frame_opt */
+ {
+-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145));
++sqlite3WindowDelete(pParse->db, (yypminor->yy327));
+ }
+       break;
+-    case 234: /* trigger_event */
++    case 249: /* trigger_cmd_list */
++    case 254: /* trigger_cmd */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy332).b);
++sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
+ }
+       break;
++    case 251: /* trigger_event */
++{
++sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
++}
++      break;
++    case 274: /* frame_bound */
++    case 275: /* frame_bound_s */
++    case 276: /* frame_bound_e */
++{
++sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
++}
++      break;
+ /********* End destructor definitions *****************************************/
+     default:  break;   /* If no destructor action specified: do nothing */
+   }
+@@ -138227,24 +148857,66 @@
+ }
+ #endif
+ 
++/* This array of booleans keeps track of the parser statement
++** coverage.  The element yycoverage[X][Y] is set when the parser
++** is in state X and has a lookahead token Y.  In a well-tested
++** systems, every element of this matrix should end up being set.
++*/
++#if defined(YYCOVERAGE)
++static unsigned char yycoverage[YYNSTATE][YYNTOKEN];
++#endif
++
+ /*
++** Write into out a description of every state/lookahead combination that
++**
++**   (1)  has not been used by the parser, and
++**   (2)  is not a syntax error.
++**
++** Return the number of missed state/lookahead combinations.
++*/
++#if defined(YYCOVERAGE)
++SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){
++  int stateno, iLookAhead, i;
++  int nMissed = 0;
++  for(stateno=0; stateno<YYNSTATE; stateno++){
++    i = yy_shift_ofst[stateno];
++    for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){
++      if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
++      if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
++      if( out ){
++        fprintf(out,"State %d lookahead %s %s\n", stateno,
++                yyTokenName[iLookAhead],
++                yycoverage[stateno][iLookAhead] ? "ok" : "missed");
++      }
++    }
++  }
++  return nMissed;
++}
++#endif
++
++/*
+ ** Find the appropriate action for a parser given the terminal
+ ** look-ahead token iLookAhead.
+ */
+-static unsigned int yy_find_shift_action(
+-  yyParser *pParser,        /* The parser */
+-  YYCODETYPE iLookAhead     /* The look-ahead token */
++static YYACTIONTYPE yy_find_shift_action(
++  YYCODETYPE iLookAhead,    /* The look-ahead token */
++  YYACTIONTYPE stateno      /* Current state number */
+ ){
+   int i;
+-  int stateno = pParser->yytos->stateno;
+- 
+-  if( stateno>=YY_MIN_REDUCE ) return stateno;
++
++  if( stateno>YY_MAX_SHIFT ) return stateno;
+   assert( stateno <= YY_SHIFT_COUNT );
++#if defined(YYCOVERAGE)
++  yycoverage[stateno][iLookAhead] = 1;
++#endif
+   do{
+     i = yy_shift_ofst[stateno];
++    assert( i>=0 );
++    /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
+     assert( iLookAhead!=YYNOCODE );
++    assert( iLookAhead < YYNTOKEN );
+     i += iLookAhead;
+-    if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
++    if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
+ #ifdef YYFALLBACK
+       YYCODETYPE iFallback;            /* Fallback token */
+       if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+@@ -138270,6 +148942,7 @@
+ #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+           j<YY_ACTTAB_COUNT &&
+ #endif
++          j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) &&
+           yy_lookahead[j]==YYWILDCARD && iLookAhead>0
+         ){
+ #ifndef NDEBUG
+@@ -138294,8 +148967,8 @@
+ ** Find the appropriate action for a parser given the non-terminal
+ ** look-ahead token iLookAhead.
+ */
+-static int yy_find_reduce_action(
+-  int stateno,              /* Current state number */
++static YYACTIONTYPE yy_find_reduce_action(
++  YYACTIONTYPE stateno,     /* Current state number */
+   YYCODETYPE iLookAhead     /* The look-ahead token */
+ ){
+   int i;
+@@ -138307,7 +148980,6 @@
+   assert( stateno<=YY_REDUCE_COUNT );
+ #endif
+   i = yy_reduce_ofst[stateno];
+-  assert( i!=YY_REDUCE_USE_DFLT );
+   assert( iLookAhead!=YYNOCODE );
+   i += iLookAhead;
+ #ifdef YYERRORSYMBOL
+@@ -138325,7 +148997,8 @@
+ ** The following routine is called if the stack overflows.
+ */
+ static void yyStackOverflow(yyParser *yypParser){
+-   sqlite3ParserARG_FETCH;
++   sqlite3ParserARG_FETCH
++   sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+    if( yyTraceFILE ){
+      fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+@@ -138338,7 +149011,8 @@
+ 
+   sqlite3ErrorMsg(pParse, "parser stack overflow");
+ /******** End %stack_overflow code ********************************************/
+-   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
++   sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
++   sqlite3ParserCTX_STORE
+ }
+ 
+ /*
+@@ -138345,20 +149019,21 @@
+ ** Print tracing information for a SHIFT action
+ */
+ #ifndef NDEBUG
+-static void yyTraceShift(yyParser *yypParser, int yyNewState){
++static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
+   if( yyTraceFILE ){
+     if( yyNewState<YYNSTATE ){
+-      fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
+-         yyTracePrompt,yyTokenName[yypParser->yytos->major],
++      fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n",
++         yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
+          yyNewState);
+     }else{
+-      fprintf(yyTraceFILE,"%sShift '%s'\n",
+-         yyTracePrompt,yyTokenName[yypParser->yytos->major]);
++      fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n",
++         yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
++         yyNewState - YY_MIN_REDUCE);
+     }
+   }
+ }
+ #else
+-# define yyTraceShift(X,Y)
++# define yyTraceShift(X,Y,Z)
+ #endif
+ 
+ /*
+@@ -138366,8 +149041,8 @@
+ */
+ static void yy_shift(
+   yyParser *yypParser,          /* The parser to be shifted */
+-  int yyNewState,               /* The new state to shift in */
+-  int yyMajor,                  /* The major token to shift in */
++  YYACTIONTYPE yyNewState,      /* The new state to shift in */
++  YYCODETYPE yyMajor,           /* The major token to shift in */
+   sqlite3ParserTOKENTYPE yyMinor        /* The minor token to shift in */
+ ){
+   yyStackEntry *yytos;
+@@ -138397,10 +149072,10 @@
+     yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+   }
+   yytos = yypParser->yytos;
+-  yytos->stateno = (YYACTIONTYPE)yyNewState;
+-  yytos->major = (YYCODETYPE)yyMajor;
++  yytos->stateno = yyNewState;
++  yytos->major = yyMajor;
+   yytos->minor.yy0 = yyMinor;
+-  yyTraceShift(yypParser, yyNewState);
++  yyTraceShift(yypParser, yyNewState, "Shift");
+ }
+ 
+ /* The following table contains information about every rule that
+@@ -138410,335 +149085,373 @@
+   YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
+   signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
+ } yyRuleInfo[] = {
+-  { 147, -1 },
+-  { 147, -3 },
+-  { 148, -1 },
+-  { 149, -3 },
+-  { 150, 0 },
+-  { 150, -1 },
+-  { 150, -1 },
+-  { 150, -1 },
+-  { 149, -2 },
+-  { 149, -2 },
+-  { 149, -2 },
+-  { 149, -3 },
+-  { 149, -5 },
+-  { 154, -6 },
+-  { 156, -1 },
+-  { 158, 0 },
+-  { 158, -3 },
+-  { 157, -1 },
+-  { 157, 0 },
+-  { 155, -5 },
+-  { 155, -2 },
+-  { 162, 0 },
+-  { 162, -2 },
+-  { 164, -2 },
+-  { 166, 0 },
+-  { 166, -4 },
+-  { 166, -6 },
+-  { 167, -2 },
+-  { 171, -2 },
+-  { 171, -2 },
+-  { 171, -4 },
+-  { 171, -3 },
+-  { 171, -3 },
+-  { 171, -2 },
+-  { 171, -3 },
+-  { 171, -5 },
+-  { 171, -2 },
+-  { 171, -4 },
+-  { 171, -4 },
+-  { 171, -1 },
+-  { 171, -2 },
+-  { 176, 0 },
+-  { 176, -1 },
+-  { 178, 0 },
+-  { 178, -2 },
+-  { 180, -2 },
+-  { 180, -3 },
+-  { 180, -3 },
+-  { 180, -3 },
+-  { 181, -2 },
+-  { 181, -2 },
+-  { 181, -1 },
+-  { 181, -1 },
+-  { 181, -2 },
+-  { 179, -3 },
+-  { 179, -2 },
+-  { 182, 0 },
+-  { 182, -2 },
+-  { 182, -2 },
+-  { 161, 0 },
+-  { 184, -1 },
+-  { 185, -2 },
+-  { 185, -7 },
+-  { 185, -5 },
+-  { 185, -5 },
+-  { 185, -10 },
+-  { 188, 0 },
+-  { 174, 0 },
+-  { 174, -3 },
+-  { 189, 0 },
+-  { 189, -2 },
+-  { 190, -1 },
+-  { 190, -1 },
+-  { 149, -4 },
+-  { 192, -2 },
+-  { 192, 0 },
+-  { 149, -9 },
+-  { 149, -4 },
+-  { 149, -1 },
+-  { 163, -2 },
+-  { 194, -3 },
+-  { 197, -1 },
+-  { 197, -2 },
+-  { 197, -1 },
+-  { 195, -9 },
+-  { 206, -4 },
+-  { 206, -5 },
+-  { 198, -1 },
+-  { 198, -1 },
+-  { 198, 0 },
+-  { 209, 0 },
+-  { 199, -3 },
+-  { 199, -2 },
+-  { 199, -4 },
+-  { 210, -2 },
+-  { 210, 0 },
+-  { 200, 0 },
+-  { 200, -2 },
+-  { 212, -2 },
+-  { 212, 0 },
+-  { 211, -7 },
+-  { 211, -9 },
+-  { 211, -7 },
+-  { 211, -7 },
+-  { 159, 0 },
+-  { 159, -2 },
+-  { 193, -2 },
+-  { 213, -1 },
+-  { 213, -2 },
+-  { 213, -3 },
+-  { 213, -4 },
+-  { 215, -2 },
+-  { 215, 0 },
+-  { 214, 0 },
+-  { 214, -3 },
+-  { 214, -2 },
+-  { 216, -4 },
+-  { 216, 0 },
+-  { 204, 0 },
+-  { 204, -3 },
+-  { 186, -4 },
+-  { 186, -2 },
+-  { 175, -1 },
+-  { 175, -1 },
+-  { 175, 0 },
+-  { 202, 0 },
+-  { 202, -3 },
+-  { 203, 0 },
+-  { 203, -2 },
+-  { 205, 0 },
+-  { 205, -2 },
+-  { 205, -4 },
+-  { 205, -4 },
+-  { 149, -6 },
+-  { 201, 0 },
+-  { 201, -2 },
+-  { 149, -8 },
+-  { 218, -5 },
+-  { 218, -7 },
+-  { 218, -3 },
+-  { 218, -5 },
+-  { 149, -6 },
+-  { 149, -7 },
+-  { 219, -2 },
+-  { 219, -1 },
+-  { 220, 0 },
+-  { 220, -3 },
+-  { 217, -3 },
+-  { 217, -1 },
+-  { 173, -3 },
+-  { 173, -1 },
+-  { 173, -1 },
+-  { 173, -3 },
+-  { 173, -5 },
+-  { 172, -1 },
+-  { 172, -1 },
+-  { 172, -1 },
+-  { 173, -1 },
+-  { 173, -3 },
+-  { 173, -6 },
+-  { 173, -5 },
+-  { 173, -4 },
+-  { 172, -1 },
+-  { 173, -5 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 221, -2 },
+-  { 173, -3 },
+-  { 173, -5 },
+-  { 173, -2 },
+-  { 173, -3 },
+-  { 173, -3 },
+-  { 173, -4 },
+-  { 173, -2 },
+-  { 173, -2 },
+-  { 173, -2 },
+-  { 173, -2 },
+-  { 222, -1 },
+-  { 222, -2 },
+-  { 173, -5 },
+-  { 223, -1 },
+-  { 223, -2 },
+-  { 173, -5 },
+-  { 173, -3 },
+-  { 173, -5 },
+-  { 173, -5 },
+-  { 173, -4 },
+-  { 173, -5 },
+-  { 226, -5 },
+-  { 226, -4 },
+-  { 227, -2 },
+-  { 227, 0 },
+-  { 225, -1 },
+-  { 225, 0 },
+-  { 208, 0 },
+-  { 207, -3 },
+-  { 207, -1 },
+-  { 224, 0 },
+-  { 224, -3 },
+-  { 149, -12 },
+-  { 228, -1 },
+-  { 228, 0 },
+-  { 177, 0 },
+-  { 177, -3 },
+-  { 187, -5 },
+-  { 187, -3 },
+-  { 229, 0 },
+-  { 229, -2 },
+-  { 149, -4 },
+-  { 149, -1 },
+-  { 149, -2 },
+-  { 149, -3 },
+-  { 149, -5 },
+-  { 149, -6 },
+-  { 149, -5 },
+-  { 149, -6 },
+-  { 169, -2 },
+-  { 170, -2 },
+-  { 149, -5 },
+-  { 231, -11 },
+-  { 233, -1 },
+-  { 233, -2 },
+-  { 233, 0 },
+-  { 234, -1 },
+-  { 234, -1 },
+-  { 234, -3 },
+-  { 236, 0 },
+-  { 236, -2 },
+-  { 232, -3 },
+-  { 232, -2 },
+-  { 238, -3 },
+-  { 239, -3 },
+-  { 239, -2 },
+-  { 237, -7 },
+-  { 237, -5 },
+-  { 237, -5 },
+-  { 237, -1 },
+-  { 173, -4 },
+-  { 173, -6 },
+-  { 191, -1 },
+-  { 191, -1 },
+-  { 191, -1 },
+-  { 149, -4 },
+-  { 149, -6 },
+-  { 149, -3 },
+-  { 241, 0 },
+-  { 241, -2 },
+-  { 149, -1 },
+-  { 149, -3 },
+-  { 149, -1 },
+-  { 149, -3 },
+-  { 149, -6 },
+-  { 149, -7 },
+-  { 242, -1 },
+-  { 149, -1 },
+-  { 149, -4 },
+-  { 244, -8 },
+-  { 246, 0 },
+-  { 247, -1 },
+-  { 247, -3 },
+-  { 248, -1 },
+-  { 196, 0 },
+-  { 196, -2 },
+-  { 196, -3 },
+-  { 250, -6 },
+-  { 250, -8 },
+-  { 144, -1 },
+-  { 145, -2 },
+-  { 145, -1 },
+-  { 146, -1 },
+-  { 146, -3 },
+-  { 147, 0 },
+-  { 151, 0 },
+-  { 151, -1 },
+-  { 151, -2 },
+-  { 153, -1 },
+-  { 153, 0 },
+-  { 149, -2 },
+-  { 160, -4 },
+-  { 160, -2 },
+-  { 152, -1 },
+-  { 152, -1 },
+-  { 152, -1 },
+-  { 166, -1 },
+-  { 167, -1 },
+-  { 168, -1 },
+-  { 168, -1 },
+-  { 165, -2 },
+-  { 165, 0 },
+-  { 171, -2 },
+-  { 161, -2 },
+-  { 183, -3 },
+-  { 183, -1 },
+-  { 184, 0 },
+-  { 188, -1 },
+-  { 190, -1 },
+-  { 194, -1 },
+-  { 195, -1 },
+-  { 209, -2 },
+-  { 210, -1 },
+-  { 173, -1 },
+-  { 221, -1 },
+-  { 208, -1 },
+-  { 230, -1 },
+-  { 230, -1 },
+-  { 230, -1 },
+-  { 230, -1 },
+-  { 230, -1 },
+-  { 169, -1 },
+-  { 235, 0 },
+-  { 235, -3 },
+-  { 238, -1 },
+-  { 239, 0 },
+-  { 240, -1 },
+-  { 240, 0 },
+-  { 243, 0 },
+-  { 243, -1 },
+-  { 245, -1 },
+-  { 245, -3 },
+-  { 246, -2 },
+-  { 249, 0 },
+-  { 249, -4 },
+-  { 249, -2 },
++  {  159,   -1 }, /* (0) explain ::= EXPLAIN */
++  {  159,   -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
++  {  158,   -1 }, /* (2) cmdx ::= cmd */
++  {  160,   -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
++  {  161,    0 }, /* (4) transtype ::= */
++  {  161,   -1 }, /* (5) transtype ::= DEFERRED */
++  {  161,   -1 }, /* (6) transtype ::= IMMEDIATE */
++  {  161,   -1 }, /* (7) transtype ::= EXCLUSIVE */
++  {  160,   -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
++  {  160,   -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
++  {  160,   -2 }, /* (10) cmd ::= SAVEPOINT nm */
++  {  160,   -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
++  {  160,   -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
++  {  165,   -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
++  {  167,   -1 }, /* (14) createkw ::= CREATE */
++  {  169,    0 }, /* (15) ifnotexists ::= */
++  {  169,   -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
++  {  168,   -1 }, /* (17) temp ::= TEMP */
++  {  168,    0 }, /* (18) temp ::= */
++  {  166,   -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
++  {  166,   -2 }, /* (20) create_table_args ::= AS select */
++  {  173,    0 }, /* (21) table_options ::= */
++  {  173,   -2 }, /* (22) table_options ::= WITHOUT nm */
++  {  175,   -2 }, /* (23) columnname ::= nm typetoken */
++  {  177,    0 }, /* (24) typetoken ::= */
++  {  177,   -4 }, /* (25) typetoken ::= typename LP signed RP */
++  {  177,   -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
++  {  178,   -2 }, /* (27) typename ::= typename ID|STRING */
++  {  182,    0 }, /* (28) scanpt ::= */
++  {  183,   -2 }, /* (29) ccons ::= CONSTRAINT nm */
++  {  183,   -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
++  {  183,   -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
++  {  183,   -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
++  {  183,   -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
++  {  183,   -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
++  {  183,   -3 }, /* (35) ccons ::= NOT NULL onconf */
++  {  183,   -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
++  {  183,   -2 }, /* (37) ccons ::= UNIQUE onconf */
++  {  183,   -4 }, /* (38) ccons ::= CHECK LP expr RP */
++  {  183,   -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
++  {  183,   -1 }, /* (40) ccons ::= defer_subclause */
++  {  183,   -2 }, /* (41) ccons ::= COLLATE ID|STRING */
++  {  188,    0 }, /* (42) autoinc ::= */
++  {  188,   -1 }, /* (43) autoinc ::= AUTOINCR */
++  {  190,    0 }, /* (44) refargs ::= */
++  {  190,   -2 }, /* (45) refargs ::= refargs refarg */
++  {  192,   -2 }, /* (46) refarg ::= MATCH nm */
++  {  192,   -3 }, /* (47) refarg ::= ON INSERT refact */
++  {  192,   -3 }, /* (48) refarg ::= ON DELETE refact */
++  {  192,   -3 }, /* (49) refarg ::= ON UPDATE refact */
++  {  193,   -2 }, /* (50) refact ::= SET NULL */
++  {  193,   -2 }, /* (51) refact ::= SET DEFAULT */
++  {  193,   -1 }, /* (52) refact ::= CASCADE */
++  {  193,   -1 }, /* (53) refact ::= RESTRICT */
++  {  193,   -2 }, /* (54) refact ::= NO ACTION */
++  {  191,   -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
++  {  191,   -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
++  {  194,    0 }, /* (57) init_deferred_pred_opt ::= */
++  {  194,   -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
++  {  194,   -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
++  {  172,    0 }, /* (60) conslist_opt ::= */
++  {  196,   -1 }, /* (61) tconscomma ::= COMMA */
++  {  197,   -2 }, /* (62) tcons ::= CONSTRAINT nm */
++  {  197,   -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
++  {  197,   -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
++  {  197,   -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
++  {  197,  -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
++  {  200,    0 }, /* (67) defer_subclause_opt ::= */
++  {  186,    0 }, /* (68) onconf ::= */
++  {  186,   -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
++  {  201,    0 }, /* (70) orconf ::= */
++  {  201,   -2 }, /* (71) orconf ::= OR resolvetype */
++  {  202,   -1 }, /* (72) resolvetype ::= IGNORE */
++  {  202,   -1 }, /* (73) resolvetype ::= REPLACE */
++  {  160,   -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
++  {  204,   -2 }, /* (75) ifexists ::= IF EXISTS */
++  {  204,    0 }, /* (76) ifexists ::= */
++  {  160,   -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
++  {  160,   -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
++  {  160,   -1 }, /* (79) cmd ::= select */
++  {  174,   -3 }, /* (80) select ::= WITH wqlist selectnowith */
++  {  174,   -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
++  {  174,   -1 }, /* (82) select ::= selectnowith */
++  {  206,   -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
++  {  209,   -1 }, /* (84) multiselect_op ::= UNION */
++  {  209,   -2 }, /* (85) multiselect_op ::= UNION ALL */
++  {  209,   -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
++  {  207,   -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
++  {  207,  -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
++  {  219,   -4 }, /* (89) values ::= VALUES LP nexprlist RP */
++  {  219,   -5 }, /* (90) values ::= values COMMA LP nexprlist RP */
++  {  210,   -1 }, /* (91) distinct ::= DISTINCT */
++  {  210,   -1 }, /* (92) distinct ::= ALL */
++  {  210,    0 }, /* (93) distinct ::= */
++  {  221,    0 }, /* (94) sclp ::= */
++  {  211,   -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */
++  {  211,   -3 }, /* (96) selcollist ::= sclp scanpt STAR */
++  {  211,   -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
++  {  222,   -2 }, /* (98) as ::= AS nm */
++  {  222,    0 }, /* (99) as ::= */
++  {  212,    0 }, /* (100) from ::= */
++  {  212,   -2 }, /* (101) from ::= FROM seltablist */
++  {  224,   -2 }, /* (102) stl_prefix ::= seltablist joinop */
++  {  224,    0 }, /* (103) stl_prefix ::= */
++  {  223,   -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++  {  223,   -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
++  {  223,   -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
++  {  223,   -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
++  {  170,    0 }, /* (108) dbnm ::= */
++  {  170,   -2 }, /* (109) dbnm ::= DOT nm */
++  {  205,   -1 }, /* (110) fullname ::= nm */
++  {  205,   -3 }, /* (111) fullname ::= nm DOT nm */
++  {  230,   -1 }, /* (112) xfullname ::= nm */
++  {  230,   -3 }, /* (113) xfullname ::= nm DOT nm */
++  {  230,   -5 }, /* (114) xfullname ::= nm DOT nm AS nm */
++  {  230,   -3 }, /* (115) xfullname ::= nm AS nm */
++  {  225,   -1 }, /* (116) joinop ::= COMMA|JOIN */
++  {  225,   -2 }, /* (117) joinop ::= JOIN_KW JOIN */
++  {  225,   -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */
++  {  225,   -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */
++  {  227,   -2 }, /* (120) on_opt ::= ON expr */
++  {  227,    0 }, /* (121) on_opt ::= */
++  {  226,    0 }, /* (122) indexed_opt ::= */
++  {  226,   -3 }, /* (123) indexed_opt ::= INDEXED BY nm */
++  {  226,   -2 }, /* (124) indexed_opt ::= NOT INDEXED */
++  {  228,   -4 }, /* (125) using_opt ::= USING LP idlist RP */
++  {  228,    0 }, /* (126) using_opt ::= */
++  {  216,    0 }, /* (127) orderby_opt ::= */
++  {  216,   -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */
++  {  198,   -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */
++  {  198,   -2 }, /* (130) sortlist ::= expr sortorder */
++  {  187,   -1 }, /* (131) sortorder ::= ASC */
++  {  187,   -1 }, /* (132) sortorder ::= DESC */
++  {  187,    0 }, /* (133) sortorder ::= */
++  {  214,    0 }, /* (134) groupby_opt ::= */
++  {  214,   -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */
++  {  215,    0 }, /* (136) having_opt ::= */
++  {  215,   -2 }, /* (137) having_opt ::= HAVING expr */
++  {  217,    0 }, /* (138) limit_opt ::= */
++  {  217,   -2 }, /* (139) limit_opt ::= LIMIT expr */
++  {  217,   -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
++  {  217,   -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */
++  {  160,   -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
++  {  213,    0 }, /* (143) where_opt ::= */
++  {  213,   -2 }, /* (144) where_opt ::= WHERE expr */
++  {  160,   -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
++  {  233,   -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */
++  {  233,   -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
++  {  233,   -3 }, /* (148) setlist ::= nm EQ expr */
++  {  233,   -5 }, /* (149) setlist ::= LP idlist RP EQ expr */
++  {  160,   -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
++  {  160,   -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
++  {  236,    0 }, /* (152) upsert ::= */
++  {  236,  -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
++  {  236,   -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
++  {  236,   -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */
++  {  234,   -2 }, /* (156) insert_cmd ::= INSERT orconf */
++  {  234,   -1 }, /* (157) insert_cmd ::= REPLACE */
++  {  235,    0 }, /* (158) idlist_opt ::= */
++  {  235,   -3 }, /* (159) idlist_opt ::= LP idlist RP */
++  {  231,   -3 }, /* (160) idlist ::= idlist COMMA nm */
++  {  231,   -1 }, /* (161) idlist ::= nm */
++  {  185,   -3 }, /* (162) expr ::= LP expr RP */
++  {  185,   -1 }, /* (163) expr ::= ID|INDEXED */
++  {  185,   -1 }, /* (164) expr ::= JOIN_KW */
++  {  185,   -3 }, /* (165) expr ::= nm DOT nm */
++  {  185,   -5 }, /* (166) expr ::= nm DOT nm DOT nm */
++  {  184,   -1 }, /* (167) term ::= NULL|FLOAT|BLOB */
++  {  184,   -1 }, /* (168) term ::= STRING */
++  {  184,   -1 }, /* (169) term ::= INTEGER */
++  {  185,   -1 }, /* (170) expr ::= VARIABLE */
++  {  185,   -3 }, /* (171) expr ::= expr COLLATE ID|STRING */
++  {  185,   -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */
++  {  185,   -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
++  {  185,   -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */
++  {  185,   -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
++  {  185,   -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
++  {  184,   -1 }, /* (177) term ::= CTIME_KW */
++  {  185,   -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */
++  {  185,   -3 }, /* (179) expr ::= expr AND expr */
++  {  185,   -3 }, /* (180) expr ::= expr OR expr */
++  {  185,   -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */
++  {  185,   -3 }, /* (182) expr ::= expr EQ|NE expr */
++  {  185,   -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
++  {  185,   -3 }, /* (184) expr ::= expr PLUS|MINUS expr */
++  {  185,   -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */
++  {  185,   -3 }, /* (186) expr ::= expr CONCAT expr */
++  {  238,   -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */
++  {  185,   -3 }, /* (188) expr ::= expr likeop expr */
++  {  185,   -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */
++  {  185,   -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */
++  {  185,   -3 }, /* (191) expr ::= expr NOT NULL */
++  {  185,   -3 }, /* (192) expr ::= expr IS expr */
++  {  185,   -4 }, /* (193) expr ::= expr IS NOT expr */
++  {  185,   -2 }, /* (194) expr ::= NOT expr */
++  {  185,   -2 }, /* (195) expr ::= BITNOT expr */
++  {  185,   -2 }, /* (196) expr ::= PLUS|MINUS expr */
++  {  239,   -1 }, /* (197) between_op ::= BETWEEN */
++  {  239,   -2 }, /* (198) between_op ::= NOT BETWEEN */
++  {  185,   -5 }, /* (199) expr ::= expr between_op expr AND expr */
++  {  240,   -1 }, /* (200) in_op ::= IN */
++  {  240,   -2 }, /* (201) in_op ::= NOT IN */
++  {  185,   -5 }, /* (202) expr ::= expr in_op LP exprlist RP */
++  {  185,   -3 }, /* (203) expr ::= LP select RP */
++  {  185,   -5 }, /* (204) expr ::= expr in_op LP select RP */
++  {  185,   -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
++  {  185,   -4 }, /* (206) expr ::= EXISTS LP select RP */
++  {  185,   -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
++  {  243,   -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
++  {  243,   -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */
++  {  244,   -2 }, /* (210) case_else ::= ELSE expr */
++  {  244,    0 }, /* (211) case_else ::= */
++  {  242,   -1 }, /* (212) case_operand ::= expr */
++  {  242,    0 }, /* (213) case_operand ::= */
++  {  229,    0 }, /* (214) exprlist ::= */
++  {  220,   -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */
++  {  220,   -1 }, /* (216) nexprlist ::= expr */
++  {  241,    0 }, /* (217) paren_exprlist ::= */
++  {  241,   -3 }, /* (218) paren_exprlist ::= LP exprlist RP */
++  {  160,  -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
++  {  245,   -1 }, /* (220) uniqueflag ::= UNIQUE */
++  {  245,    0 }, /* (221) uniqueflag ::= */
++  {  189,    0 }, /* (222) eidlist_opt ::= */
++  {  189,   -3 }, /* (223) eidlist_opt ::= LP eidlist RP */
++  {  199,   -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
++  {  199,   -3 }, /* (225) eidlist ::= nm collate sortorder */
++  {  246,    0 }, /* (226) collate ::= */
++  {  246,   -2 }, /* (227) collate ::= COLLATE ID|STRING */
++  {  160,   -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */
++  {  160,   -1 }, /* (229) cmd ::= VACUUM */
++  {  160,   -2 }, /* (230) cmd ::= VACUUM nm */
++  {  160,   -3 }, /* (231) cmd ::= PRAGMA nm dbnm */
++  {  160,   -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */
++  {  160,   -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */
++  {  160,   -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */
++  {  160,   -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */
++  {  180,   -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */
++  {  181,   -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */
++  {  160,   -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
++  {  248,  -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
++  {  250,   -1 }, /* (240) trigger_time ::= BEFORE|AFTER */
++  {  250,   -2 }, /* (241) trigger_time ::= INSTEAD OF */
++  {  250,    0 }, /* (242) trigger_time ::= */
++  {  251,   -1 }, /* (243) trigger_event ::= DELETE|INSERT */
++  {  251,   -1 }, /* (244) trigger_event ::= UPDATE */
++  {  251,   -3 }, /* (245) trigger_event ::= UPDATE OF idlist */
++  {  253,    0 }, /* (246) when_clause ::= */
++  {  253,   -2 }, /* (247) when_clause ::= WHEN expr */
++  {  249,   -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
++  {  249,   -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */
++  {  255,   -3 }, /* (250) trnm ::= nm DOT nm */
++  {  256,   -3 }, /* (251) tridxby ::= INDEXED BY nm */
++  {  256,   -2 }, /* (252) tridxby ::= NOT INDEXED */
++  {  254,   -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
++  {  254,   -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
++  {  254,   -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
++  {  254,   -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */
++  {  185,   -4 }, /* (257) expr ::= RAISE LP IGNORE RP */
++  {  185,   -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */
++  {  203,   -1 }, /* (259) raisetype ::= ROLLBACK */
++  {  203,   -1 }, /* (260) raisetype ::= ABORT */
++  {  203,   -1 }, /* (261) raisetype ::= FAIL */
++  {  160,   -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */
++  {  160,   -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
++  {  160,   -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */
++  {  258,    0 }, /* (265) key_opt ::= */
++  {  258,   -2 }, /* (266) key_opt ::= KEY expr */
++  {  160,   -1 }, /* (267) cmd ::= REINDEX */
++  {  160,   -3 }, /* (268) cmd ::= REINDEX nm dbnm */
++  {  160,   -1 }, /* (269) cmd ::= ANALYZE */
++  {  160,   -3 }, /* (270) cmd ::= ANALYZE nm dbnm */
++  {  160,   -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */
++  {  160,   -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
++  {  259,   -1 }, /* (273) add_column_fullname ::= fullname */
++  {  160,   -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
++  {  160,   -1 }, /* (275) cmd ::= create_vtab */
++  {  160,   -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */
++  {  261,   -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
++  {  263,    0 }, /* (278) vtabarg ::= */
++  {  264,   -1 }, /* (279) vtabargtoken ::= ANY */
++  {  264,   -3 }, /* (280) vtabargtoken ::= lp anylist RP */
++  {  265,   -1 }, /* (281) lp ::= LP */
++  {  232,   -2 }, /* (282) with ::= WITH wqlist */
++  {  232,   -3 }, /* (283) with ::= WITH RECURSIVE wqlist */
++  {  208,   -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */
++  {  208,   -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
++  {  267,   -1 }, /* (286) windowdefn_list ::= windowdefn */
++  {  267,   -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */
++  {  268,   -3 }, /* (288) windowdefn ::= nm AS window */
++  {  269,   -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */
++  {  271,   -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */
++  {  271,    0 }, /* (291) part_opt ::= */
++  {  270,    0 }, /* (292) frame_opt ::= */
++  {  270,   -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */
++  {  270,   -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
++  {  273,   -1 }, /* (295) range_or_rows ::= RANGE */
++  {  273,   -1 }, /* (296) range_or_rows ::= ROWS */
++  {  275,   -1 }, /* (297) frame_bound_s ::= frame_bound */
++  {  275,   -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */
++  {  276,   -1 }, /* (299) frame_bound_e ::= frame_bound */
++  {  276,   -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */
++  {  274,   -2 }, /* (301) frame_bound ::= expr PRECEDING */
++  {  274,   -2 }, /* (302) frame_bound ::= CURRENT ROW */
++  {  274,   -2 }, /* (303) frame_bound ::= expr FOLLOWING */
++  {  218,   -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */
++  {  237,   -3 }, /* (305) over_clause ::= filter_opt OVER window */
++  {  237,   -3 }, /* (306) over_clause ::= filter_opt OVER nm */
++  {  272,    0 }, /* (307) filter_opt ::= */
++  {  272,   -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */
++  {  155,   -1 }, /* (309) input ::= cmdlist */
++  {  156,   -2 }, /* (310) cmdlist ::= cmdlist ecmd */
++  {  156,   -1 }, /* (311) cmdlist ::= ecmd */
++  {  157,   -1 }, /* (312) ecmd ::= SEMI */
++  {  157,   -2 }, /* (313) ecmd ::= cmdx SEMI */
++  {  157,   -2 }, /* (314) ecmd ::= explain cmdx */
++  {  162,    0 }, /* (315) trans_opt ::= */
++  {  162,   -1 }, /* (316) trans_opt ::= TRANSACTION */
++  {  162,   -2 }, /* (317) trans_opt ::= TRANSACTION nm */
++  {  164,   -1 }, /* (318) savepoint_opt ::= SAVEPOINT */
++  {  164,    0 }, /* (319) savepoint_opt ::= */
++  {  160,   -2 }, /* (320) cmd ::= create_table create_table_args */
++  {  171,   -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */
++  {  171,   -2 }, /* (322) columnlist ::= columnname carglist */
++  {  163,   -1 }, /* (323) nm ::= ID|INDEXED */
++  {  163,   -1 }, /* (324) nm ::= STRING */
++  {  163,   -1 }, /* (325) nm ::= JOIN_KW */
++  {  177,   -1 }, /* (326) typetoken ::= typename */
++  {  178,   -1 }, /* (327) typename ::= ID|STRING */
++  {  179,   -1 }, /* (328) signed ::= plus_num */
++  {  179,   -1 }, /* (329) signed ::= minus_num */
++  {  176,   -2 }, /* (330) carglist ::= carglist ccons */
++  {  176,    0 }, /* (331) carglist ::= */
++  {  183,   -2 }, /* (332) ccons ::= NULL onconf */
++  {  172,   -2 }, /* (333) conslist_opt ::= COMMA conslist */
++  {  195,   -3 }, /* (334) conslist ::= conslist tconscomma tcons */
++  {  195,   -1 }, /* (335) conslist ::= tcons */
++  {  196,    0 }, /* (336) tconscomma ::= */
++  {  200,   -1 }, /* (337) defer_subclause_opt ::= defer_subclause */
++  {  202,   -1 }, /* (338) resolvetype ::= raisetype */
++  {  206,   -1 }, /* (339) selectnowith ::= oneselect */
++  {  207,   -1 }, /* (340) oneselect ::= values */
++  {  221,   -2 }, /* (341) sclp ::= selcollist COMMA */
++  {  222,   -1 }, /* (342) as ::= ID|STRING */
++  {  185,   -1 }, /* (343) expr ::= term */
++  {  238,   -1 }, /* (344) likeop ::= LIKE_KW|MATCH */
++  {  229,   -1 }, /* (345) exprlist ::= nexprlist */
++  {  247,   -1 }, /* (346) nmnum ::= plus_num */
++  {  247,   -1 }, /* (347) nmnum ::= nm */
++  {  247,   -1 }, /* (348) nmnum ::= ON */
++  {  247,   -1 }, /* (349) nmnum ::= DELETE */
++  {  247,   -1 }, /* (350) nmnum ::= DEFAULT */
++  {  180,   -1 }, /* (351) plus_num ::= INTEGER|FLOAT */
++  {  252,    0 }, /* (352) foreach_clause ::= */
++  {  252,   -3 }, /* (353) foreach_clause ::= FOR EACH ROW */
++  {  255,   -1 }, /* (354) trnm ::= nm */
++  {  256,    0 }, /* (355) tridxby ::= */
++  {  257,   -1 }, /* (356) database_kw_opt ::= DATABASE */
++  {  257,    0 }, /* (357) database_kw_opt ::= */
++  {  260,    0 }, /* (358) kwcolumn_opt ::= */
++  {  260,   -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */
++  {  262,   -1 }, /* (360) vtabarglist ::= vtabarg */
++  {  262,   -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */
++  {  263,   -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */
++  {  266,    0 }, /* (363) anylist ::= */
++  {  266,   -4 }, /* (364) anylist ::= anylist LP anylist RP */
++  {  266,   -2 }, /* (365) anylist ::= anylist ANY */
++  {  232,    0 }, /* (366) with ::= */
+ };
+ 
+ static void yy_accept(yyParser*);  /* Forward Declaration */
+@@ -138746,22 +149459,39 @@
+ /*
+ ** Perform a reduce action and the shift that must immediately
+ ** follow the reduce.
++**
++** The yyLookahead and yyLookaheadToken parameters provide reduce actions
++** access to the lookahead token (if any).  The yyLookahead will be YYNOCODE
++** if the lookahead token has already been consumed.  As this procedure is
++** only called from one place, optimizing compilers will in-line it, which
++** means that the extra parameters have no performance impact.
+ */
+-static void yy_reduce(
++static YYACTIONTYPE yy_reduce(
+   yyParser *yypParser,         /* The parser */
+-  unsigned int yyruleno        /* Number of the rule by which to reduce */
++  unsigned int yyruleno,       /* Number of the rule by which to reduce */
++  int yyLookahead,             /* Lookahead token, or YYNOCODE if none */
++  sqlite3ParserTOKENTYPE yyLookaheadToken  /* Value of the lookahead token */
++  sqlite3ParserCTX_PDECL                   /* %extra_context */
+ ){
+   int yygoto;                     /* The next state */
+-  int yyact;                      /* The next action */
++  YYACTIONTYPE yyact;             /* The next action */
+   yyStackEntry *yymsp;            /* The top of the parser's stack */
+   int yysize;                     /* Amount to pop the stack */
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  (void)yyLookahead;
++  (void)yyLookaheadToken;
+   yymsp = yypParser->yytos;
+ #ifndef NDEBUG
+   if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+     yysize = yyRuleInfo[yyruleno].nrhs;
+-    fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
+-      yyRuleName[yyruleno], yymsp[yysize].stateno);
++    if( yysize ){
++      fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
++        yyTracePrompt,
++        yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
++    }else{
++      fprintf(yyTraceFILE, "%sReduce %d [%s].\n",
++        yyTracePrompt, yyruleno, yyRuleName[yyruleno]);
++    }
+   }
+ #endif /* NDEBUG */
+ 
+@@ -138778,13 +149508,19 @@
+ #if YYSTACKDEPTH>0 
+     if( yypParser->yytos>=yypParser->yystackEnd ){
+       yyStackOverflow(yypParser);
+-      return;
++      /* The call to yyStackOverflow() above pops the stack until it is
++      ** empty, causing the main parser loop to exit.  So the return value
++      ** is never used and does not matter. */
++      return 0;
+     }
+ #else
+     if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
+       if( yyGrowStack(yypParser) ){
+         yyStackOverflow(yypParser);
+-        return;
++        /* The call to yyStackOverflow() above pops the stack until it is
++        ** empty, causing the main parser loop to exit.  So the return value
++        ** is never used and does not matter. */
++        return 0;
+       }
+       yymsp = yypParser->yytos;
+     }
+@@ -138812,15 +149548,15 @@
+ { sqlite3FinishCoding(pParse); }
+         break;
+       case 3: /* cmd ::= BEGIN transtype trans_opt */
+-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);}
++{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
+         break;
+       case 4: /* transtype ::= */
+-{yymsp[1].minor.yy194 = TK_DEFERRED;}
++{yymsp[1].minor.yy70 = TK_DEFERRED;}
+         break;
+       case 5: /* transtype ::= DEFERRED */
+       case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
+       case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
+-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/}
++{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
+         break;
+       case 8: /* cmd ::= COMMIT|END trans_opt */
+       case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
+@@ -138843,7 +149579,7 @@
+         break;
+       case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ {
+-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194);
++   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70);
+ }
+         break;
+       case 14: /* createkw ::= CREATE */
+@@ -138852,38 +149588,38 @@
+       case 15: /* ifnotexists ::= */
+       case 18: /* temp ::= */ yytestcase(yyruleno==18);
+       case 21: /* table_options ::= */ yytestcase(yyruleno==21);
+-      case 41: /* autoinc ::= */ yytestcase(yyruleno==41);
+-      case 56: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==56);
+-      case 66: /* defer_subclause_opt ::= */ yytestcase(yyruleno==66);
+-      case 75: /* ifexists ::= */ yytestcase(yyruleno==75);
+-      case 89: /* distinct ::= */ yytestcase(yyruleno==89);
+-      case 212: /* collate ::= */ yytestcase(yyruleno==212);
+-{yymsp[1].minor.yy194 = 0;}
++      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 93: /* distinct ::= */ yytestcase(yyruleno==93);
++      case 226: /* collate ::= */ yytestcase(yyruleno==226);
++{yymsp[1].minor.yy70 = 0;}
+         break;
+       case 16: /* ifnotexists ::= IF NOT EXISTS */
+-{yymsp[-2].minor.yy194 = 1;}
++{yymsp[-2].minor.yy70 = 1;}
+         break;
+       case 17: /* temp ::= TEMP */
+-      case 42: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==42);
+-{yymsp[0].minor.yy194 = 1;}
++      case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
++{yymsp[0].minor.yy70 = 1;}
+         break;
+       case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
+ {
+-  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0);
++  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0);
+ }
+         break;
+       case 20: /* create_table_args ::= AS select */
+ {
+-  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
++  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ }
+         break;
+       case 22: /* table_options ::= WITHOUT nm */
+ {
+   if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+-    yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid;
++    yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
+   }else{
+-    yymsp[-1].minor.yy194 = 0;
++    yymsp[-1].minor.yy70 = 0;
+     sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+   }
+ }
+@@ -138892,8 +149628,8 @@
+ {sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+         break;
+       case 24: /* typetoken ::= */
+-      case 59: /* conslist_opt ::= */ yytestcase(yyruleno==59);
+-      case 95: /* as ::= */ yytestcase(yyruleno==95);
++      case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
++      case 99: /* as ::= */ yytestcase(yyruleno==99);
+ {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
+         break;
+       case 25: /* typetoken ::= typename LP signed RP */
+@@ -138909,177 +149645,206 @@
+       case 27: /* typename ::= typename ID|STRING */
+ {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
+         break;
+-      case 28: /* ccons ::= CONSTRAINT nm */
+-      case 61: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==61);
++      case 28: /* scanpt ::= */
++{
++  assert( yyLookahead!=YYNOCODE );
++  yymsp[1].minor.yy392 = yyLookaheadToken.z;
++}
++        break;
++      case 29: /* ccons ::= CONSTRAINT nm */
++      case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
+ {pParse->constraintName = yymsp[0].minor.yy0;}
+         break;
+-      case 29: /* ccons ::= DEFAULT term */
+-      case 31: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==31);
+-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
++      case 30: /* ccons ::= DEFAULT scanpt term scanpt */
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+         break;
+-      case 30: /* ccons ::= DEFAULT LP expr RP */
+-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
++      case 31: /* ccons ::= DEFAULT LP expr RP */
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+         break;
+-      case 32: /* ccons ::= DEFAULT MINUS term */
++      case 32: /* ccons ::= DEFAULT PLUS term scanpt */
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
++        break;
++      case 33: /* ccons ::= DEFAULT MINUS term scanpt */
+ {
+-  ExprSpan v;
+-  v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0);
+-  v.zStart = yymsp[-1].minor.yy0.z;
+-  v.zEnd = yymsp[0].minor.yy190.zEnd;
+-  sqlite3AddDefaultValue(pParse,&v);
++  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
++  sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
+ }
+         break;
+-      case 33: /* ccons ::= DEFAULT ID|INDEXED */
++      case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
+ {
+-  ExprSpan v;
+-  spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0);
+-  sqlite3AddDefaultValue(pParse,&v);
++  Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
++  if( p ){
++    sqlite3ExprIdToTrueFalse(p);
++    testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
++  }
++    sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
+ }
+         break;
+-      case 34: /* ccons ::= NOT NULL onconf */
+-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
++      case 35: /* ccons ::= NOT NULL onconf */
++{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);}
+         break;
+-      case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);}
++      case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
++{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
+         break;
+-      case 36: /* ccons ::= UNIQUE onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0,
++      case 37: /* ccons ::= UNIQUE onconf */
++{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
+                                    SQLITE_IDXTYPE_UNIQUE);}
+         break;
+-      case 37: /* ccons ::= CHECK LP expr RP */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
++      case 38: /* ccons ::= CHECK LP expr RP */
++{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
+         break;
+-      case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
++      case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
++{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
+         break;
+-      case 39: /* ccons ::= defer_subclause */
+-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);}
++      case 40: /* ccons ::= defer_subclause */
++{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
+         break;
+-      case 40: /* ccons ::= COLLATE ID|STRING */
++      case 41: /* ccons ::= COLLATE ID|STRING */
+ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
+         break;
+-      case 43: /* refargs ::= */
+-{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */}
++      case 44: /* refargs ::= */
++{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
+         break;
+-      case 44: /* refargs ::= refargs refarg */
+-{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; }
++      case 45: /* refargs ::= refargs refarg */
++{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
+         break;
+-      case 45: /* refarg ::= MATCH nm */
+-{ yymsp[-1].minor.yy497.value = 0;     yymsp[-1].minor.yy497.mask = 0x000000; }
++      case 46: /* refarg ::= MATCH nm */
++{ yymsp[-1].minor.yy111.value = 0;     yymsp[-1].minor.yy111.mask = 0x000000; }
+         break;
+-      case 46: /* refarg ::= ON INSERT refact */
+-{ yymsp[-2].minor.yy497.value = 0;     yymsp[-2].minor.yy497.mask = 0x000000; }
++      case 47: /* refarg ::= ON INSERT refact */
++{ yymsp[-2].minor.yy111.value = 0;     yymsp[-2].minor.yy111.mask = 0x000000; }
+         break;
+-      case 47: /* refarg ::= ON DELETE refact */
+-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194;     yymsp[-2].minor.yy497.mask = 0x0000ff; }
++      case 48: /* refarg ::= ON DELETE refact */
++{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70;     yymsp[-2].minor.yy111.mask = 0x0000ff; }
+         break;
+-      case 48: /* refarg ::= ON UPDATE refact */
+-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8;  yymsp[-2].minor.yy497.mask = 0x00ff00; }
++      case 49: /* refarg ::= ON UPDATE refact */
++{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8;  yymsp[-2].minor.yy111.mask = 0x00ff00; }
+         break;
+-      case 49: /* refact ::= SET NULL */
+-{ yymsp[-1].minor.yy194 = OE_SetNull;  /* EV: R-33326-45252 */}
++      case 50: /* refact ::= SET NULL */
++{ yymsp[-1].minor.yy70 = OE_SetNull;  /* EV: R-33326-45252 */}
+         break;
+-      case 50: /* refact ::= SET DEFAULT */
+-{ yymsp[-1].minor.yy194 = OE_SetDflt;  /* EV: R-33326-45252 */}
++      case 51: /* refact ::= SET DEFAULT */
++{ yymsp[-1].minor.yy70 = OE_SetDflt;  /* EV: R-33326-45252 */}
+         break;
+-      case 51: /* refact ::= CASCADE */
+-{ yymsp[0].minor.yy194 = OE_Cascade;  /* EV: R-33326-45252 */}
++      case 52: /* refact ::= CASCADE */
++{ yymsp[0].minor.yy70 = OE_Cascade;  /* EV: R-33326-45252 */}
+         break;
+-      case 52: /* refact ::= RESTRICT */
+-{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */}
++      case 53: /* refact ::= RESTRICT */
++{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
+         break;
+-      case 53: /* refact ::= NO ACTION */
+-{ yymsp[-1].minor.yy194 = OE_None;     /* EV: R-33326-45252 */}
++      case 54: /* refact ::= NO ACTION */
++{ yymsp[-1].minor.yy70 = OE_None;     /* EV: R-33326-45252 */}
+         break;
+-      case 54: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+-{yymsp[-2].minor.yy194 = 0;}
++      case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
++{yymsp[-2].minor.yy70 = 0;}
+         break;
+-      case 55: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+-      case 70: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==70);
+-      case 143: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==143);
+-{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
++      case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
++      case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
++      case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
++{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;}
+         break;
+-      case 57: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+-      case 74: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==74);
+-      case 184: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==184);
+-      case 187: /* in_op ::= NOT IN */ yytestcase(yyruleno==187);
+-      case 213: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==213);
+-{yymsp[-1].minor.yy194 = 1;}
++      case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
++      case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
++      case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
++      case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
++      case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
++{yymsp[-1].minor.yy70 = 1;}
+         break;
+-      case 58: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+-{yymsp[-1].minor.yy194 = 0;}
++      case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
++{yymsp[-1].minor.yy70 = 0;}
+         break;
+-      case 60: /* tconscomma ::= COMMA */
++      case 61: /* tconscomma ::= COMMA */
+ {pParse->constraintName.n = 0;}
+         break;
+-      case 62: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);}
++      case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
++{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);}
+         break;
+-      case 63: /* tcons ::= UNIQUE LP sortlist RP onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0,
++      case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
++{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0,
+                                        SQLITE_IDXTYPE_UNIQUE);}
+         break;
+-      case 64: /* tcons ::= CHECK LP expr RP onconf */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
++      case 65: /* tcons ::= CHECK LP expr RP onconf */
++{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
+         break;
+-      case 65: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
++      case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ {
+-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194);
+-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194);
++    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
++    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
+ }
+         break;
+-      case 67: /* onconf ::= */
+-      case 69: /* orconf ::= */ yytestcase(yyruleno==69);
+-{yymsp[1].minor.yy194 = OE_Default;}
++      case 68: /* onconf ::= */
++      case 70: /* orconf ::= */ yytestcase(yyruleno==70);
++{yymsp[1].minor.yy70 = OE_Default;}
+         break;
+-      case 68: /* onconf ::= ON CONFLICT resolvetype */
+-{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;}
++      case 69: /* onconf ::= ON CONFLICT resolvetype */
++{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
+         break;
+-      case 71: /* resolvetype ::= IGNORE */
+-{yymsp[0].minor.yy194 = OE_Ignore;}
++      case 72: /* resolvetype ::= IGNORE */
++{yymsp[0].minor.yy70 = OE_Ignore;}
+         break;
+-      case 72: /* resolvetype ::= REPLACE */
+-      case 144: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==144);
+-{yymsp[0].minor.yy194 = OE_Replace;}
++      case 73: /* resolvetype ::= REPLACE */
++      case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
++{yymsp[0].minor.yy70 = OE_Replace;}
+         break;
+-      case 73: /* cmd ::= DROP TABLE ifexists fullname */
++      case 74: /* cmd ::= DROP TABLE ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
+ }
+         break;
+-      case 76: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
++      case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ {
+-  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194);
++  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
+ }
+         break;
+-      case 77: /* cmd ::= DROP VIEW ifexists fullname */
++      case 78: /* cmd ::= DROP VIEW ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
+ }
+         break;
+-      case 78: /* cmd ::= select */
++      case 79: /* cmd ::= select */
+ {
+   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
+-  sqlite3Select(pParse, yymsp[0].minor.yy243, &dest);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
++  sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ }
+         break;
+-      case 79: /* select ::= with selectnowith */
++      case 80: /* select ::= WITH wqlist selectnowith */
+ {
+-  Select *p = yymsp[0].minor.yy243;
++  Select *p = yymsp[0].minor.yy489;
+   if( p ){
+-    p->pWith = yymsp[-1].minor.yy285;
++    p->pWith = yymsp[-1].minor.yy449;
+     parserDoubleLinkSelect(pParse, p);
+   }else{
+-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285);
++    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+   }
+-  yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/
++  yymsp[-2].minor.yy489 = p;
+ }
+         break;
+-      case 80: /* selectnowith ::= selectnowith multiselect_op oneselect */
++      case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
+ {
+-  Select *pRhs = yymsp[0].minor.yy243;
+-  Select *pLhs = yymsp[-2].minor.yy243;
++  Select *p = yymsp[0].minor.yy489;
++  if( p ){
++    p->pWith = yymsp[-1].minor.yy449;
++    parserDoubleLinkSelect(pParse, p);
++  }else{
++    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
++  }
++  yymsp[-3].minor.yy489 = p;
++}
++        break;
++      case 82: /* select ::= selectnowith */
++{
++  Select *p = yymsp[0].minor.yy489;
++  if( p ){
++    parserDoubleLinkSelect(pParse, p);
++  }
++  yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
++}
++        break;
++      case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
++{
++  Select *pRhs = yymsp[0].minor.yy489;
++  Select *pLhs = yymsp[-2].minor.yy489;
+   if( pRhs && pRhs->pPrior ){
+     SrcList *pFrom;
+     Token x;
+@@ -139086,162 +149851,145 @@
+     x.n = 0;
+     parserDoubleLinkSelect(pParse, pRhs);
+     pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
+-    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
++    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
+   }
+   if( pRhs ){
+-    pRhs->op = (u8)yymsp[-1].minor.yy194;
++    pRhs->op = (u8)yymsp[-1].minor.yy70;
+     pRhs->pPrior = pLhs;
+     if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
+     pRhs->selFlags &= ~SF_MultiValue;
+-    if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1;
++    if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
+   }else{
+     sqlite3SelectDelete(pParse->db, pLhs);
+   }
+-  yymsp[-2].minor.yy243 = pRhs;
++  yymsp[-2].minor.yy489 = pRhs;
+ }
+         break;
+-      case 81: /* multiselect_op ::= UNION */
+-      case 83: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==83);
+-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/}
++      case 84: /* multiselect_op ::= UNION */
++      case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
++{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
+         break;
+-      case 82: /* multiselect_op ::= UNION ALL */
+-{yymsp[-1].minor.yy194 = TK_ALL;}
++      case 85: /* multiselect_op ::= UNION ALL */
++{yymsp[-1].minor.yy70 = TK_ALL;}
+         break;
+-      case 84: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
++      case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ {
+-#if SELECTTRACE_ENABLED
+-  Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
+-#endif
+-  yymsp[-8].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset);
+-#if SELECTTRACE_ENABLED
+-  /* Populate the Select.zSelName[] string that is used to help with
+-  ** query planner debugging, to differentiate between multiple Select
+-  ** objects in a complex query.
+-  **
+-  ** If the SELECT keyword is immediately followed by a C-style comment
+-  ** then extract the first few alphanumeric characters from within that
+-  ** comment to be the zSelName value.  Otherwise, the label is #N where
+-  ** is an integer that is incremented with each SELECT statement seen.
+-  */
+-  if( yymsp[-8].minor.yy243!=0 ){
+-    const char *z = s.z+6;
+-    int i;
+-    sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "#%d",
+-                     ++pParse->nSelect);
+-    while( z[0]==' ' ) z++;
+-    if( z[0]=='/' && z[1]=='*' ){
+-      z += 2;
+-      while( z[0]==' ' ) z++;
+-      for(i=0; sqlite3Isalnum(z[i]); i++){}
+-      sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, z);
+-    }
++  yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18);
++}
++        break;
++      case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
++{
++  yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18);
++  if( yymsp[-9].minor.yy489 ){
++    yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327;
++  }else{
++    sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
+   }
+-#endif /* SELECTRACE_ENABLED */
+ }
+         break;
+-      case 85: /* values ::= VALUES LP nexprlist RP */
++      case 89: /* values ::= VALUES LP nexprlist RP */
+ {
+-  yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0);
++  yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
+ }
+         break;
+-      case 86: /* values ::= values COMMA LP exprlist RP */
++      case 90: /* values ::= values COMMA LP nexprlist RP */
+ {
+-  Select *pRight, *pLeft = yymsp[-4].minor.yy243;
+-  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
++  Select *pRight, *pLeft = yymsp[-4].minor.yy489;
++  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+   if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+   if( pRight ){
+     pRight->op = TK_ALL;
+     pRight->pPrior = pLeft;
+-    yymsp[-4].minor.yy243 = pRight;
++    yymsp[-4].minor.yy489 = pRight;
+   }else{
+-    yymsp[-4].minor.yy243 = pLeft;
++    yymsp[-4].minor.yy489 = pLeft;
+   }
+ }
+         break;
+-      case 87: /* distinct ::= DISTINCT */
+-{yymsp[0].minor.yy194 = SF_Distinct;}
++      case 91: /* distinct ::= DISTINCT */
++{yymsp[0].minor.yy70 = SF_Distinct;}
+         break;
+-      case 88: /* distinct ::= ALL */
+-{yymsp[0].minor.yy194 = SF_All;}
++      case 92: /* distinct ::= ALL */
++{yymsp[0].minor.yy70 = SF_All;}
+         break;
+-      case 90: /* sclp ::= */
+-      case 118: /* orderby_opt ::= */ yytestcase(yyruleno==118);
+-      case 125: /* groupby_opt ::= */ yytestcase(yyruleno==125);
+-      case 200: /* exprlist ::= */ yytestcase(yyruleno==200);
+-      case 203: /* paren_exprlist ::= */ yytestcase(yyruleno==203);
+-      case 208: /* eidlist_opt ::= */ yytestcase(yyruleno==208);
+-{yymsp[1].minor.yy148 = 0;}
++      case 94: /* sclp ::= */
++      case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
++      case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134);
++      case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
++      case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
++      case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
++{yymsp[1].minor.yy420 = 0;}
+         break;
+-      case 91: /* selcollist ::= sclp expr as */
++      case 95: /* selcollist ::= sclp scanpt expr scanpt 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);
++   yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
++   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1);
++   sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392);
+ }
+         break;
+-      case 92: /* selcollist ::= sclp STAR */
++      case 96: /* selcollist ::= sclp scanpt STAR */
+ {
+   Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
+-  yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
++  yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
+ }
+         break;
+-      case 93: /* selcollist ::= sclp nm DOT STAR */
++      case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
+ {
+   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);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
+ }
+         break;
+-      case 94: /* as ::= AS nm */
+-      case 105: /* dbnm ::= DOT nm */ yytestcase(yyruleno==105);
+-      case 222: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==222);
+-      case 223: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==223);
++      case 98: /* as ::= AS nm */
++      case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
++      case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236);
++      case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237);
+ {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 96: /* from ::= */
+-{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
++      case 100: /* from ::= */
++{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
+         break;
+-      case 97: /* from ::= FROM seltablist */
++      case 101: /* from ::= FROM seltablist */
+ {
+-  yymsp[-1].minor.yy185 = yymsp[0].minor.yy185;
+-  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185);
++  yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
++  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
+ }
+         break;
+-      case 98: /* stl_prefix ::= seltablist joinop */
++      case 102: /* stl_prefix ::= seltablist joinop */
+ {
+-   if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194;
++   if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70;
+ }
+         break;
+-      case 99: /* stl_prefix ::= */
+-{yymsp[1].minor.yy185 = 0;}
++      case 103: /* stl_prefix ::= */
++{yymsp[1].minor.yy135 = 0;}
+         break;
+-      case 100: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++      case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ {
+-  yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0);
++  yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0);
+ }
+         break;
+-      case 101: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
++      case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ {
+-  yymsp[-8].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+-  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148);
++  yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420);
+ }
+         break;
+-      case 102: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
++      case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ {
+-    yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
++    yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+   }
+         break;
+-      case 103: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
++      case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ {
+-    if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){
+-      yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185;
+-    }else if( yymsp[-4].minor.yy185->nSrc==1 ){
+-      yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+-      if( yymsp[-6].minor.yy185 ){
+-        struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1];
+-        struct SrcList_item *pOld = yymsp[-4].minor.yy185->a;
++    if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){
++      yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135;
++    }else if( yymsp[-4].minor.yy135->nSrc==1 ){
++      yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++      if( yymsp[-6].minor.yy135 ){
++        struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1];
++        struct SrcList_item *pOld = yymsp[-4].minor.yy135->a;
+         pNew->zName = pOld->zName;
+         pNew->zDatabase = pOld->zDatabase;
+         pNew->pSelect = pOld->pSelect;
+@@ -139248,199 +149996,240 @@
+         pOld->zName = pOld->zDatabase = 0;
+         pOld->pSelect = 0;
+       }
+-      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy185);
++      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
+     }else{
+       Select *pSubquery;
+-      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185);
+-      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0);
+-      yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
++      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135);
++      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0);
++      yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+     }
+   }
+         break;
+-      case 104: /* dbnm ::= */
+-      case 113: /* indexed_opt ::= */ yytestcase(yyruleno==113);
++      case 108: /* dbnm ::= */
++      case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
+ {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
+         break;
+-      case 106: /* fullname ::= nm dbnm */
+-{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 110: /* fullname ::= nm */
++{
++  yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0);
++  if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
++}
++  yymsp[0].minor.yy135 = yylhsminor.yy135;
+         break;
+-      case 107: /* joinop ::= COMMA|JOIN */
+-{ yymsp[0].minor.yy194 = JT_INNER; }
++      case 111: /* fullname ::= nm DOT nm */
++{
++  yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
++  if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
++}
++  yymsp[-2].minor.yy135 = yylhsminor.yy135;
+         break;
+-      case 108: /* joinop ::= JOIN_KW JOIN */
+-{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
++      case 112: /* xfullname ::= nm */
++{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+         break;
+-      case 109: /* joinop ::= JOIN_KW nm JOIN */
+-{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
++      case 113: /* xfullname ::= nm DOT nm */
++{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+         break;
+-      case 110: /* joinop ::= JOIN_KW nm nm JOIN */
+-{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
++      case 114: /* xfullname ::= nm DOT nm AS nm */
++{
++   yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
++   if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
++}
+         break;
+-      case 111: /* on_opt ::= ON expr */
+-      case 128: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==128);
+-      case 135: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==135);
+-      case 196: /* case_else ::= ELSE expr */ yytestcase(yyruleno==196);
+-{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
++      case 115: /* xfullname ::= nm AS nm */
++{  
++   yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
++   if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
++}
+         break;
+-      case 112: /* on_opt ::= */
+-      case 127: /* having_opt ::= */ yytestcase(yyruleno==127);
+-      case 134: /* where_opt ::= */ yytestcase(yyruleno==134);
+-      case 197: /* case_else ::= */ yytestcase(yyruleno==197);
+-      case 199: /* case_operand ::= */ yytestcase(yyruleno==199);
+-{yymsp[1].minor.yy72 = 0;}
++      case 116: /* joinop ::= COMMA|JOIN */
++{ yymsp[0].minor.yy70 = JT_INNER; }
+         break;
+-      case 114: /* indexed_opt ::= INDEXED BY nm */
++      case 117: /* joinop ::= JOIN_KW JOIN */
++{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
++        break;
++      case 118: /* joinop ::= JOIN_KW nm JOIN */
++{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
++        break;
++      case 119: /* joinop ::= JOIN_KW nm nm JOIN */
++{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
++        break;
++      case 120: /* on_opt ::= ON expr */
++      case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
++      case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
++      case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
++{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;}
++        break;
++      case 121: /* on_opt ::= */
++      case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
++      case 138: /* limit_opt ::= */ yytestcase(yyruleno==138);
++      case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
++      case 211: /* case_else ::= */ yytestcase(yyruleno==211);
++      case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
++{yymsp[1].minor.yy18 = 0;}
++        break;
++      case 123: /* indexed_opt ::= INDEXED BY nm */
+ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 115: /* indexed_opt ::= NOT INDEXED */
++      case 124: /* indexed_opt ::= NOT INDEXED */
+ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
+         break;
+-      case 116: /* using_opt ::= USING LP idlist RP */
+-{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
++      case 125: /* using_opt ::= USING LP idlist RP */
++{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
+         break;
+-      case 117: /* using_opt ::= */
+-      case 145: /* idlist_opt ::= */ yytestcase(yyruleno==145);
+-{yymsp[1].minor.yy254 = 0;}
++      case 126: /* using_opt ::= */
++      case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
++{yymsp[1].minor.yy48 = 0;}
+         break;
+-      case 119: /* orderby_opt ::= ORDER BY sortlist */
+-      case 126: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==126);
+-{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;}
++      case 128: /* orderby_opt ::= ORDER BY sortlist */
++      case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
++{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;}
+         break;
+-      case 120: /* sortlist ::= sortlist COMMA expr sortorder */
++      case 129: /* sortlist ::= sortlist COMMA expr sortorder */
+ {
+-  yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr);
+-  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
++  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
+ }
+         break;
+-      case 121: /* sortlist ::= expr sortorder */
++      case 130: /* sortlist ::= expr sortorder */
+ {
+-  yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/
+-  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194);
++  yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
++  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
+ }
+         break;
+-      case 122: /* sortorder ::= ASC */
+-{yymsp[0].minor.yy194 = SQLITE_SO_ASC;}
++      case 131: /* sortorder ::= ASC */
++{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
+         break;
+-      case 123: /* sortorder ::= DESC */
+-{yymsp[0].minor.yy194 = SQLITE_SO_DESC;}
++      case 132: /* sortorder ::= DESC */
++{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
+         break;
+-      case 124: /* sortorder ::= */
+-{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;}
++      case 133: /* sortorder ::= */
++{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
+         break;
+-      case 129: /* limit_opt ::= */
+-{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;}
++      case 139: /* limit_opt ::= LIMIT expr */
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
+         break;
+-      case 130: /* limit_opt ::= LIMIT expr */
+-{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;}
++      case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
++{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+         break;
+-      case 131: /* limit_opt ::= LIMIT expr OFFSET expr */
+-{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;}
++      case 141: /* limit_opt ::= LIMIT expr COMMA expr */
++{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
+         break;
+-      case 132: /* limit_opt ::= LIMIT expr COMMA expr */
+-{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;}
+-        break;
+-      case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
++      case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ {
+-  sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0);
+-  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0);
++  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0);
+ }
+         break;
+-      case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
++      case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ {
+-  sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0);
+-  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); 
+-  sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0);
++  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list"); 
++  sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0);
+ }
+         break;
+-      case 137: /* setlist ::= setlist COMMA nm EQ expr */
++      case 146: /* setlist ::= setlist COMMA nm EQ expr */
+ {
+-  yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
+-  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
++  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1);
+ }
+         break;
+-      case 138: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
++      case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ {
+-  yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
++  yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 139: /* setlist ::= nm EQ expr */
++      case 148: /* setlist ::= nm EQ expr */
+ {
+-  yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
+-  sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1);
++  yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
++  sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
+ }
+-  yymsp[-2].minor.yy148 = yylhsminor.yy148;
++  yymsp[-2].minor.yy420 = yylhsminor.yy420;
+         break;
+-      case 140: /* setlist ::= LP idlist RP EQ expr */
++      case 149: /* setlist ::= LP idlist RP EQ expr */
+ {
+-  yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
++      case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ {
+-  sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
+-  sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194);
++  sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
+ }
+         break;
+-      case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
++      case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ {
+-  sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1);
+-  sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);
++  sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
+ }
+         break;
+-      case 146: /* idlist_opt ::= LP idlist RP */
+-{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
++      case 152: /* upsert ::= */
++{ yymsp[1].minor.yy340 = 0; }
+         break;
+-      case 147: /* idlist ::= idlist COMMA nm */
+-{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
++      case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
++{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);}
+         break;
+-      case 148: /* idlist ::= nm */
+-{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
++      case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
++{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); }
+         break;
+-      case 149: /* expr ::= LP expr RP */
+-{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/  yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
++      case 155: /* upsert ::= ON CONFLICT DO NOTHING */
++{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+         break;
+-      case 150: /* expr ::= ID|INDEXED */
+-      case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
+-{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 159: /* idlist_opt ::= LP idlist RP */
++{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
+         break;
+-      case 152: /* expr ::= nm DOT nm */
++      case 160: /* idlist ::= idlist COMMA nm */
++{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
++        break;
++      case 161: /* idlist ::= nm */
++{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
++        break;
++      case 162: /* expr ::= LP expr RP */
++{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;}
++        break;
++      case 163: /* expr ::= ID|INDEXED */
++      case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
++{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++        break;
++      case 165: /* expr ::= nm DOT nm */
+ {
+   Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+   Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+-  spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
+-  yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
++    sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
++  }
++  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ }
++  yymsp[-2].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 153: /* expr ::= nm DOT nm DOT nm */
++      case 166: /* expr ::= nm DOT nm DOT nm */
+ {
+   Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
+   Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+   Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+   Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
+-  spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
+-  yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
++    sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
++  }
++  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ }
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 154: /* term ::= NULL|FLOAT|BLOB */
+-      case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
+-{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 167: /* term ::= NULL|FLOAT|BLOB */
++      case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
++{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+         break;
+-      case 156: /* term ::= INTEGER */
++      case 169: /* 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;
++  yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ }
+-  yymsp[0].minor.yy190 = yylhsminor.yy190;
++  yymsp[0].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 157: /* expr ::= VARIABLE */
++      case 170: /* 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);
+-    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
++    yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
++    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
+   }else{
+     /* When doing a nested parse, one can include terms in an expression
+     ** that look like this:   #1 #2 ...  These terms refer to registers
+@@ -139447,159 +150236,156 @@
+     ** in the virtual machine.  #N is the N-th register. */
+     Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
+     assert( t.n>=2 );
+-    spanSet(&yymsp[0].minor.yy190, &t, &t);
+     if( pParse->nested==0 ){
+       sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
+-      yymsp[0].minor.yy190.pExpr = 0;
++      yymsp[0].minor.yy18 = 0;
+     }else{
+-      yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+-      if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
++      yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
++      if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
+     }
+   }
+ }
+         break;
+-      case 158: /* expr ::= expr COLLATE ID|STRING */
++      case 171: /* expr ::= expr COLLATE ID|STRING */
+ {
+-  yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
+-  yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
++  yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
+ }
+         break;
+-      case 159: /* expr ::= CAST LP expr AS typetoken RP */
++      case 172: /* expr ::= CAST LP expr AS typetoken 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_CAST, &yymsp[-1].minor.yy0, 1);
+-  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0);
++  yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
++  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0);
+ }
+         break;
+-      case 160: /* expr ::= ID|INDEXED LP distinct exprlist RP */
++      case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ {
+-  if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+-    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
+-  }
+-  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
+-  spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+-  if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){
+-    yylhsminor.yy190.pExpr->flags |= EP_Distinct;
+-  }
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+ }
+-  yymsp[-4].minor.yy190 = yylhsminor.yy190;
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 161: /* expr ::= ID|INDEXED LP STAR RP */
++      case 174: /* expr ::= ID|INDEXED LP STAR RP */
+ {
+-  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+-  spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ }
+-  yymsp[-3].minor.yy190 = yylhsminor.yy190;
++  yymsp[-3].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 162: /* term ::= CTIME_KW */
++      case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ {
+-  yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+-  spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
++  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ }
+-  yymsp[0].minor.yy190 = yylhsminor.yy190;
++  yymsp[-5].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 163: /* expr ::= LP nexprlist COMMA expr RP */
++      case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
+ {
+-  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
+-  yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+-  if( yylhsminor.yy190.pExpr ){
+-    yylhsminor.yy190.pExpr->x.pList = pList;
+-    spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
++  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
++}
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
++        break;
++      case 177: /* term ::= CTIME_KW */
++{
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
++}
++  yymsp[0].minor.yy18 = yylhsminor.yy18;
++        break;
++      case 178: /* expr ::= LP nexprlist COMMA expr RP */
++{
++  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->x.pList = pList;
+   }else{
+     sqlite3ExprListDelete(pParse->db, pList);
+   }
+ }
+-  yymsp[-4].minor.yy190 = yylhsminor.yy190;
+         break;
+-      case 164: /* expr ::= expr AND expr */
+-      case 165: /* expr ::= expr OR expr */ yytestcase(yyruleno==165);
+-      case 166: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==166);
+-      case 167: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==167);
+-      case 168: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==168);
+-      case 169: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==169);
+-      case 170: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==170);
+-      case 171: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==171);
+-{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
++      case 179: /* expr ::= expr AND expr */
++      case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
++      case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
++      case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
++      case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
++      case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
++      case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
++      case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
++{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+         break;
+-      case 172: /* likeop ::= NOT LIKE_KW|MATCH */
++      case 187: /* 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 173: /* expr ::= expr likeop expr */
++      case 188: /* 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;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18);
++  yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
++  if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0);
++  if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 174: /* expr ::= expr likeop expr ESCAPE expr */
++      case 189: /* 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;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
++  if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 175: /* expr ::= expr ISNULL|NOTNULL */
+-{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
++      case 190: /* expr ::= expr ISNULL|NOTNULL */
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
+         break;
+-      case 176: /* expr ::= expr NOT NULL */
+-{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
++      case 191: /* expr ::= expr NOT NULL */
++{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
+         break;
+-      case 177: /* expr ::= expr IS expr */
++      case 192: /* 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);
++  yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL);
+ }
+         break;
+-      case 178: /* expr ::= expr IS NOT expr */
++      case 193: /* 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);
++  yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL);
+ }
+         break;
+-      case 179: /* expr ::= NOT expr */
+-      case 180: /* expr ::= BITNOT expr */ yytestcase(yyruleno==180);
+-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
++      case 194: /* expr ::= NOT expr */
++      case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/}
+         break;
+-      case 181: /* expr ::= MINUS expr */
+-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
++      case 196: /* expr ::= PLUS|MINUS expr */
++{
++  yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
++  /*A-overwrites-B*/
++}
+         break;
+-      case 182: /* expr ::= PLUS expr */
+-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
++      case 197: /* between_op ::= BETWEEN */
++      case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
++{yymsp[0].minor.yy70 = 0;}
+         break;
+-      case 183: /* between_op ::= BETWEEN */
+-      case 186: /* in_op ::= IN */ yytestcase(yyruleno==186);
+-{yymsp[0].minor.yy194 = 0;}
+-        break;
+-      case 185: /* expr ::= expr between_op expr AND expr */
++      case 199: /* 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;
++  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->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;
++  if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ }
+         break;
+-      case 188: /* expr ::= expr in_op LP exprlist RP */
++      case 202: /* expr ::= expr in_op LP exprlist RP */
+ {
+-    if( yymsp[-1].minor.yy148==0 ){
++    if( yymsp[-1].minor.yy420==0 ){
+       /* Expressions of the form
+       **
+       **      expr1 IN ()
+@@ -139608,9 +150394,9 @@
+       ** simplify to constants 0 (false) and 1 (true), respectively,
+       ** regardless of the value of expr1.
+       */
+-      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr);
+-      yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1);
+-    }else if( yymsp[-1].minor.yy148->nExpr==1 ){
++      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18);
++      yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1);
++    }else if( yymsp[-1].minor.yy420->nExpr==1 ){
+       /* Expressions of the form:
+       **
+       **      expr1 IN (?1)
+@@ -139627,9 +150413,9 @@
+       ** affinity or the collating sequence to use for comparison.  Otherwise,
+       ** the semantics would be subtly different from IN or NOT IN.
+       */
+-      Expr *pRHS = yymsp[-1].minor.yy148->a[0].pExpr;
+-      yymsp[-1].minor.yy148->a[0].pExpr = 0;
+-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
++      Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr;
++      yymsp[-1].minor.yy420->a[0].pExpr = 0;
++      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+       /* pRHS cannot be NULL because a malloc error would have been detected
+       ** before now and control would have never reached this point */
+       if( ALWAYS(pRHS) ){
+@@ -139636,192 +150422,190 @@
+         pRHS->flags &= ~EP_Collate;
+         pRHS->flags |= EP_Generic;
+       }
+-      yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS);
++      yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
+     }else{
+-      yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
+-      if( yymsp[-4].minor.yy190.pExpr ){
+-        yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
+-        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
++      yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++      if( yymsp[-4].minor.yy18 ){
++        yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420;
++        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+       }else{
+-        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
++        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+       }
+-      exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
++      if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+     }
+-    yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+   }
+         break;
+-      case 189: /* expr ::= LP select RP */
++      case 203: /* 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);
++    yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
+   }
+         break;
+-      case 190: /* expr ::= expr in_op LP select RP */
++      case 204: /* 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];
++    yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489);
++    if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+   }
+         break;
+-      case 191: /* expr ::= expr in_op nm dbnm paren_exprlist */
++      case 205: /* 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];
++    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
++    if( yymsp[0].minor.yy420 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420);
++    yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect);
++    if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+   }
+         break;
+-      case 192: /* expr ::= EXISTS LP select RP */
++      case 206: /* 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);
++    p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
++    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
+   }
+         break;
+-      case 193: /* expr ::= CASE case_operand case_exprlist case_else END */
++      case 207: /* 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);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420;
++    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+   }else{
+-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
+-    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
++    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
++    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
+   }
+ }
+         break;
+-      case 194: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
++      case 208: /* 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);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 195: /* case_exprlist ::= WHEN expr THEN expr */
++      case 209: /* 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);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 198: /* case_operand ::= expr */
+-{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
++      case 212: /* case_operand ::= expr */
++{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
+         break;
+-      case 201: /* nexprlist ::= nexprlist COMMA expr */
+-{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
++      case 215: /* nexprlist ::= nexprlist COMMA expr */
++{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
+         break;
+-      case 202: /* nexprlist ::= expr */
+-{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
++      case 216: /* nexprlist ::= expr */
++{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
+         break;
+-      case 204: /* paren_exprlist ::= LP exprlist RP */
+-      case 209: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==209);
+-{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
++      case 218: /* paren_exprlist ::= LP exprlist RP */
++      case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
++{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;}
+         break;
+-      case 205: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
++      case 219: /* 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);
++                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70,
++                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
++  if( IN_RENAME_OBJECT && pParse->pNewIndex ){
++    sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
++  }
+ }
+         break;
+-      case 206: /* uniqueflag ::= UNIQUE */
+-      case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246);
+-{yymsp[0].minor.yy194 = OE_Abort;}
++      case 220: /* uniqueflag ::= UNIQUE */
++      case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
++{yymsp[0].minor.yy70 = OE_Abort;}
+         break;
+-      case 207: /* uniqueflag ::= */
+-{yymsp[1].minor.yy194 = OE_None;}
++      case 221: /* uniqueflag ::= */
++{yymsp[1].minor.yy70 = OE_None;}
+         break;
+-      case 210: /* eidlist ::= eidlist COMMA nm collate sortorder */
++      case 224: /* 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);
++  yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
+ }
+         break;
+-      case 211: /* eidlist ::= nm collate sortorder */
++      case 225: /* 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*/
++  yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
+ }
+         break;
+-      case 214: /* cmd ::= DROP INDEX ifexists fullname */
+-{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
++      case 228: /* cmd ::= DROP INDEX ifexists fullname */
++{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
+         break;
+-      case 215: /* cmd ::= VACUUM */
++      case 229: /* cmd ::= VACUUM */
+ {sqlite3Vacuum(pParse,0);}
+         break;
+-      case 216: /* cmd ::= VACUUM nm */
++      case 230: /* cmd ::= VACUUM nm */
+ {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 217: /* cmd ::= PRAGMA nm dbnm */
++      case 231: /* cmd ::= PRAGMA nm dbnm */
+ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
+         break;
+-      case 218: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
++      case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
+         break;
+-      case 219: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
++      case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
+         break;
+-      case 220: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
++      case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
+         break;
+-      case 221: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
++      case 235: /* 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 224: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
++      case 238: /* 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);
++  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all);
+ }
+         break;
+-      case 225: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
++      case 239: /* 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);
++  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70);
+   yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
+ }
+         break;
+-      case 226: /* trigger_time ::= BEFORE|AFTER */
+-{ yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/ }
++      case 240: /* trigger_time ::= BEFORE|AFTER */
++{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
+         break;
+-      case 227: /* trigger_time ::= INSTEAD OF */
+-{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
++      case 241: /* trigger_time ::= INSTEAD OF */
++{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
+         break;
+-      case 228: /* trigger_time ::= */
+-{ yymsp[1].minor.yy194 = TK_BEFORE; }
++      case 242: /* trigger_time ::= */
++{ yymsp[1].minor.yy70 = TK_BEFORE; }
+         break;
+-      case 229: /* trigger_event ::= DELETE|INSERT */
+-      case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230);
+-{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
++      case 243: /* trigger_event ::= DELETE|INSERT */
++      case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244);
++{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;}
+         break;
+-      case 231: /* trigger_event ::= UPDATE OF idlist */
+-{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
++      case 245: /* trigger_event ::= UPDATE OF idlist */
++{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
+         break;
+-      case 232: /* when_clause ::= */
+-      case 251: /* key_opt ::= */ yytestcase(yyruleno==251);
+-{ yymsp[1].minor.yy72 = 0; }
++      case 246: /* when_clause ::= */
++      case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
++      case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
++{ yymsp[1].minor.yy18 = 0; }
+         break;
+-      case 233: /* when_clause ::= WHEN expr */
+-      case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252);
+-{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
++      case 247: /* when_clause ::= WHEN expr */
++      case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
++{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
+         break;
+-      case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
++      case 248: /* 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;
++  assert( yymsp[-2].minor.yy207!=0 );
++  yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207;
++  yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ }
+         break;
+-      case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */
++      case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ { 
+-  assert( yymsp[-1].minor.yy145!=0 );
+-  yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
++  assert( yymsp[-1].minor.yy207!=0 );
++  yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ }
+         break;
+-      case 236: /* trnm ::= nm DOT nm */
++      case 250: /* trnm ::= nm DOT nm */
+ {
+   yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
+   sqlite3ErrorMsg(pParse, 
+@@ -139829,7 +150613,7 @@
+         "statements within triggers");
+ }
+         break;
+-      case 237: /* tridxby ::= INDEXED BY nm */
++      case 251: /* tridxby ::= INDEXED BY nm */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
+@@ -139836,7 +150620,7 @@
+         "within triggers");
+ }
+         break;
+-      case 238: /* tridxby ::= NOT INDEXED */
++      case 252: /* tridxby ::= NOT INDEXED */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
+@@ -139843,182 +150627,292 @@
+         "within triggers");
+ }
+         break;
+-      case 239: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+-{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
++      case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
++{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);}
++  yymsp[-7].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 240: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+-{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
++      case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
++{
++   yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/
++}
++  yymsp[-7].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+-{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
++      case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
++{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);}
++  yymsp[-5].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 242: /* trigger_cmd ::= select */
+-{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
++      case 256: /* trigger_cmd ::= scanpt select scanpt */
++{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/}
++  yymsp[-2].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 243: /* expr ::= RAISE LP IGNORE RP */
++      case 257: /* 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;
++  yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
++  if( yymsp[-3].minor.yy18 ){
++    yymsp[-3].minor.yy18->affinity = OE_Ignore;
+   }
+ }
+         break;
+-      case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */
++      case 258: /* 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;
++  yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); 
++  if( yymsp[-5].minor.yy18 ) {
++    yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70;
+   }
+ }
+         break;
+-      case 245: /* raisetype ::= ROLLBACK */
+-{yymsp[0].minor.yy194 = OE_Rollback;}
++      case 259: /* raisetype ::= ROLLBACK */
++{yymsp[0].minor.yy70 = OE_Rollback;}
+         break;
+-      case 247: /* raisetype ::= FAIL */
+-{yymsp[0].minor.yy194 = OE_Fail;}
++      case 261: /* raisetype ::= FAIL */
++{yymsp[0].minor.yy70 = OE_Fail;}
+         break;
+-      case 248: /* cmd ::= DROP TRIGGER ifexists fullname */
++      case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
+ {
+-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
++  sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
+ }
+         break;
+-      case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
++      case 263: /* 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);
++  sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 250: /* cmd ::= DETACH database_kw_opt expr */
++      case 264: /* cmd ::= DETACH database_kw_opt expr */
+ {
+-  sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
++  sqlite3Detach(pParse, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 253: /* cmd ::= REINDEX */
++      case 267: /* cmd ::= REINDEX */
+ {sqlite3Reindex(pParse, 0, 0);}
+         break;
+-      case 254: /* cmd ::= REINDEX nm dbnm */
++      case 268: /* cmd ::= REINDEX nm dbnm */
+ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
+         break;
+-      case 255: /* cmd ::= ANALYZE */
++      case 269: /* cmd ::= ANALYZE */
+ {sqlite3Analyze(pParse, 0, 0);}
+         break;
+-      case 256: /* cmd ::= ANALYZE nm dbnm */
++      case 270: /* cmd ::= ANALYZE nm dbnm */
+ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
+         break;
+-      case 257: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
++      case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ {
+-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
++  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
+ }
+         break;
+-      case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
++      case 272: /* 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 259: /* add_column_fullname ::= fullname */
++      case 273: /* add_column_fullname ::= fullname */
+ {
+   disableLookaside(pParse);
+-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
++  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+ }
+         break;
+-      case 260: /* cmd ::= create_vtab */
++      case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
++{
++  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
++}
++        break;
++      case 275: /* cmd ::= create_vtab */
+ {sqlite3VtabFinishParse(pParse,0);}
+         break;
+-      case 261: /* cmd ::= create_vtab LP vtabarglist RP */
++      case 276: /* cmd ::= create_vtab LP vtabarglist RP */
+ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 262: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
++      case 277: /* 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);
++    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70);
+ }
+         break;
+-      case 263: /* vtabarg ::= */
++      case 278: /* vtabarg ::= */
+ {sqlite3VtabArgInit(pParse);}
+         break;
+-      case 264: /* vtabargtoken ::= ANY */
+-      case 265: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==265);
+-      case 266: /* lp ::= LP */ yytestcase(yyruleno==266);
++      case 279: /* vtabargtoken ::= ANY */
++      case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
++      case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
+ {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 267: /* with ::= */
+-{yymsp[1].minor.yy285 = 0;}
++      case 282: /* with ::= WITH wqlist */
++      case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
++{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+         break;
+-      case 268: /* with ::= WITH wqlist */
+-{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
++      case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
++{
++  yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/
++}
+         break;
+-      case 269: /* with ::= WITH RECURSIVE wqlist */
+-{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
++      case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
++{
++  yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489);
++}
+         break;
+-      case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */
++      case 286: /* windowdefn_list ::= windowdefn */
++{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
++  yymsp[0].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ {
+-  yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
++  assert( yymsp[0].minor.yy327!=0 );
++  yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327;
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
+ }
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+         break;
+-      case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
++      case 288: /* windowdefn ::= nm AS window */
+ {
+-  yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
++  if( ALWAYS(yymsp[0].minor.yy327) ){
++    yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
++  }
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
+ }
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+         break;
++      case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
++{
++  yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327;
++  if( ALWAYS(yymsp[-4].minor.yy327) ){
++    yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420;
++    yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420;
++  }
++}
++        break;
++      case 290: /* part_opt ::= PARTITION BY nexprlist */
++{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; }
++        break;
++      case 291: /* part_opt ::= */
++{ yymsp[1].minor.yy420 = 0; }
++        break;
++      case 292: /* frame_opt ::= */
++{ 
++  yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
++}
++        break;
++      case 293: /* frame_opt ::= range_or_rows frame_bound_s */
++{ 
++  yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0);
++}
++  yymsp[-1].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
++{ 
++  yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr);
++}
++  yymsp[-4].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 295: /* range_or_rows ::= RANGE */
++{ yymsp[0].minor.yy70 = TK_RANGE; }
++        break;
++      case 296: /* range_or_rows ::= ROWS */
++{ yymsp[0].minor.yy70 = TK_ROWS;  }
++        break;
++      case 297: /* frame_bound_s ::= frame_bound */
++      case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299);
++{ yylhsminor.yy119 = yymsp[0].minor.yy119; }
++  yymsp[0].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */
++      case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300);
++{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;}
++        break;
++      case 301: /* frame_bound ::= expr PRECEDING */
++{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
++  yymsp[-1].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 302: /* frame_bound ::= CURRENT ROW */
++{ yymsp[-1].minor.yy119.eType = TK_CURRENT  ; yymsp[-1].minor.yy119.pExpr = 0; }
++        break;
++      case 303: /* frame_bound ::= expr FOLLOWING */
++{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
++  yymsp[-1].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 304: /* window_clause ::= WINDOW windowdefn_list */
++{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; }
++        break;
++      case 305: /* over_clause ::= filter_opt OVER window */
++{
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
++  assert( yylhsminor.yy327!=0 );
++  yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 306: /* over_clause ::= filter_opt OVER nm */
++{
++  yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
++  if( yylhsminor.yy327 ){
++    yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
++    yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
++  }else{
++    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
++  }
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
++{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
++        break;
+       default:
+-      /* (272) input ::= cmdlist */ yytestcase(yyruleno==272);
+-      /* (273) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==273);
+-      /* (274) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=274);
+-      /* (275) ecmd ::= SEMI */ yytestcase(yyruleno==275);
+-      /* (276) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==276);
+-      /* (277) explain ::= */ yytestcase(yyruleno==277);
+-      /* (278) trans_opt ::= */ yytestcase(yyruleno==278);
+-      /* (279) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==279);
+-      /* (280) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==280);
+-      /* (281) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==281);
+-      /* (282) savepoint_opt ::= */ yytestcase(yyruleno==282);
+-      /* (283) cmd ::= create_table create_table_args */ yytestcase(yyruleno==283);
+-      /* (284) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==284);
+-      /* (285) columnlist ::= columnname carglist */ yytestcase(yyruleno==285);
+-      /* (286) nm ::= ID|INDEXED */ yytestcase(yyruleno==286);
+-      /* (287) nm ::= STRING */ yytestcase(yyruleno==287);
+-      /* (288) nm ::= JOIN_KW */ yytestcase(yyruleno==288);
+-      /* (289) typetoken ::= typename */ yytestcase(yyruleno==289);
+-      /* (290) typename ::= ID|STRING */ yytestcase(yyruleno==290);
+-      /* (291) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=291);
+-      /* (292) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=292);
+-      /* (293) carglist ::= carglist ccons */ yytestcase(yyruleno==293);
+-      /* (294) carglist ::= */ yytestcase(yyruleno==294);
+-      /* (295) ccons ::= NULL onconf */ yytestcase(yyruleno==295);
+-      /* (296) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==296);
+-      /* (297) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==297);
+-      /* (298) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=298);
+-      /* (299) tconscomma ::= */ yytestcase(yyruleno==299);
+-      /* (300) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=300);
+-      /* (301) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=301);
+-      /* (302) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=302);
+-      /* (303) oneselect ::= values */ yytestcase(yyruleno==303);
+-      /* (304) sclp ::= selcollist COMMA */ yytestcase(yyruleno==304);
+-      /* (305) as ::= ID|STRING */ yytestcase(yyruleno==305);
+-      /* (306) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=306);
+-      /* (307) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==307);
+-      /* (308) exprlist ::= nexprlist */ yytestcase(yyruleno==308);
+-      /* (309) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=309);
+-      /* (310) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=310);
+-      /* (311) nmnum ::= ON */ yytestcase(yyruleno==311);
+-      /* (312) nmnum ::= DELETE */ yytestcase(yyruleno==312);
+-      /* (313) nmnum ::= DEFAULT */ yytestcase(yyruleno==313);
+-      /* (314) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==314);
+-      /* (315) foreach_clause ::= */ yytestcase(yyruleno==315);
+-      /* (316) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==316);
+-      /* (317) trnm ::= nm */ yytestcase(yyruleno==317);
+-      /* (318) tridxby ::= */ yytestcase(yyruleno==318);
+-      /* (319) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==319);
+-      /* (320) database_kw_opt ::= */ yytestcase(yyruleno==320);
+-      /* (321) kwcolumn_opt ::= */ yytestcase(yyruleno==321);
+-      /* (322) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==322);
+-      /* (323) vtabarglist ::= vtabarg */ yytestcase(yyruleno==323);
+-      /* (324) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==324);
+-      /* (325) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==325);
+-      /* (326) anylist ::= */ yytestcase(yyruleno==326);
+-      /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
+-      /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
++      /* (309) input ::= cmdlist */ yytestcase(yyruleno==309);
++      /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310);
++      /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311);
++      /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312);
++      /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313);
++      /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314);
++      /* (315) trans_opt ::= */ yytestcase(yyruleno==315);
++      /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316);
++      /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317);
++      /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318);
++      /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319);
++      /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320);
++      /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321);
++      /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322);
++      /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323);
++      /* (324) nm ::= STRING */ yytestcase(yyruleno==324);
++      /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325);
++      /* (326) typetoken ::= typename */ yytestcase(yyruleno==326);
++      /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327);
++      /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328);
++      /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329);
++      /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330);
++      /* (331) carglist ::= */ yytestcase(yyruleno==331);
++      /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332);
++      /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333);
++      /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334);
++      /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335);
++      /* (336) tconscomma ::= */ yytestcase(yyruleno==336);
++      /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337);
++      /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338);
++      /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339);
++      /* (340) oneselect ::= values */ yytestcase(yyruleno==340);
++      /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341);
++      /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342);
++      /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343);
++      /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344);
++      /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345);
++      /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346);
++      /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347);
++      /* (348) nmnum ::= ON */ yytestcase(yyruleno==348);
++      /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349);
++      /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350);
++      /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351);
++      /* (352) foreach_clause ::= */ yytestcase(yyruleno==352);
++      /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353);
++      /* (354) trnm ::= nm */ yytestcase(yyruleno==354);
++      /* (355) tridxby ::= */ yytestcase(yyruleno==355);
++      /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356);
++      /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357);
++      /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358);
++      /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359);
++      /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360);
++      /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361);
++      /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362);
++      /* (363) anylist ::= */ yytestcase(yyruleno==363);
++      /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364);
++      /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365);
++      /* (366) with ::= */ yytestcase(yyruleno==366);
+         break;
+ /********** End reduce actions ************************************************/
+   };
+@@ -140034,16 +150928,12 @@
+   /* It is not possible for a REDUCE to be followed by an error */
+   assert( yyact!=YY_ERROR_ACTION );
+ 
+-  if( yyact==YY_ACCEPT_ACTION ){
+-    yypParser->yytos += yysize;
+-    yy_accept(yypParser);
+-  }else{
+-    yymsp += yysize+1;
+-    yypParser->yytos = yymsp;
+-    yymsp->stateno = (YYACTIONTYPE)yyact;
+-    yymsp->major = (YYCODETYPE)yygoto;
+-    yyTraceShift(yypParser, yyact);
+-  }
++  yymsp += yysize+1;
++  yypParser->yytos = yymsp;
++  yymsp->stateno = (YYACTIONTYPE)yyact;
++  yymsp->major = (YYCODETYPE)yygoto;
++  yyTraceShift(yypParser, yyact, "... then shift");
++  return yyact;
+ }
+ 
+ /*
+@@ -140053,7 +150943,8 @@
+ static void yy_parse_failed(
+   yyParser *yypParser           /* The parser */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+@@ -140064,7 +150955,8 @@
+   ** parser fails */
+ /************ Begin %parse_failure code ***************************************/
+ /************ End %parse_failure code *****************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ #endif /* YYNOERRORRECOVERY */
+ 
+@@ -140076,15 +150968,20 @@
+   int yymajor,                   /* The major type of the error token */
+   sqlite3ParserTOKENTYPE yyminor         /* The minor type of the error token */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #define TOKEN yyminor
+ /************ Begin %syntax_error code ****************************************/
+ 
+   UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
+-  assert( TOKEN.z[0] );  /* The tokenizer always gives us a token */
+-  sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
++  if( TOKEN.z[0] ){
++    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
++  }else{
++    sqlite3ErrorMsg(pParse, "incomplete input");
++  }
+ /************ End %syntax_error code ******************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ 
+ /*
+@@ -140093,7 +150990,8 @@
+ static void yy_accept(
+   yyParser *yypParser           /* The parser */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+@@ -140107,7 +151005,8 @@
+   ** parser accepts */
+ /*********** Begin %parse_accept code *****************************************/
+ /*********** End %parse_accept code *******************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ 
+ /* The main parser program.
+@@ -140136,7 +151035,7 @@
+   sqlite3ParserARG_PDECL               /* Optional %extra_argument parameter */
+ ){
+   YYMINORTYPE yyminorunion;
+-  unsigned int yyact;   /* The parser action. */
++  YYACTIONTYPE yyact;   /* The parser action. */
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   int yyendofinput;     /* True if we are at the end of input */
+ #endif
+@@ -140143,31 +151042,44 @@
+ #ifdef YYERRORSYMBOL
+   int yyerrorhit = 0;   /* True if yymajor has invoked an error */
+ #endif
+-  yyParser *yypParser;  /* The parser */
++  yyParser *yypParser = (yyParser*)yyp;  /* The parser */
++  sqlite3ParserCTX_FETCH
++  sqlite3ParserARG_STORE
+ 
+-  yypParser = (yyParser*)yyp;
+   assert( yypParser->yytos!=0 );
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   yyendofinput = (yymajor==0);
+ #endif
+-  sqlite3ParserARG_STORE;
+ 
++  yyact = yypParser->yytos->stateno;
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+-    fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
++    if( yyact < YY_MIN_REDUCE ){
++      fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
++              yyTracePrompt,yyTokenName[yymajor],yyact);
++    }else{
++      fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
++              yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
++    }
+   }
+ #endif
+ 
+   do{
+-    yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
+-    if( yyact <= YY_MAX_SHIFTREDUCE ){
+-      yy_shift(yypParser,yyact,yymajor,yyminor);
++    assert( yyact==yypParser->yytos->stateno );
++    yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
++    if( yyact >= YY_MIN_REDUCE ){
++      yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,
++                        yyminor sqlite3ParserCTX_PARAM);
++    }else if( yyact <= YY_MAX_SHIFTREDUCE ){
++      yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
+ #ifndef YYNOERRORRECOVERY
+       yypParser->yyerrcnt--;
+ #endif
+-      yymajor = YYNOCODE;
+-    }else if( yyact <= YY_MAX_REDUCE ){
+-      yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
++      break;
++    }else if( yyact==YY_ACCEPT_ACTION ){
++      yypParser->yytos--;
++      yy_accept(yypParser);
++      return;
+     }else{
+       assert( yyact == YY_ERROR_ACTION );
+       yyminorunion.yy0 = yyminor;
+@@ -140214,10 +151126,9 @@
+         yymajor = YYNOCODE;
+       }else{
+         while( yypParser->yytos >= yypParser->yystack
+-            && yymx != YYERRORSYMBOL
+             && (yyact = yy_find_reduce_action(
+                         yypParser->yytos->stateno,
+-                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
++                        YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
+         ){
+           yy_pop_parser_stack(yypParser);
+         }
+@@ -140234,6 +151145,8 @@
+       }
+       yypParser->yyerrcnt = 3;
+       yyerrorhit = 1;
++      if( yymajor==YYNOCODE ) break;
++      yyact = yypParser->yytos->stateno;
+ #elif defined(YYNOERRORRECOVERY)
+       /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+       ** do any kind of error recovery.  Instead, simply invoke the syntax
+@@ -140244,8 +151157,7 @@
+       */
+       yy_syntax_error(yypParser,yymajor, yyminor);
+       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+-      yymajor = YYNOCODE;
+-      
++      break;
+ #else  /* YYERRORSYMBOL is not defined */
+       /* This is what we do if the grammar does not define ERROR:
+       **
+@@ -140267,10 +151179,10 @@
+         yypParser->yyerrcnt = -1;
+ #endif
+       }
+-      yymajor = YYNOCODE;
++      break;
+ #endif
+     }
+-  }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
++  }while( yypParser->yytos>yypParser->yystack );
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     yyStackEntry *i;
+@@ -140286,6 +151198,21 @@
+   return;
+ }
+ 
++/*
++** Return the fallback token corresponding to canonical token iToken, or
++** 0 if iToken has no fallback.
++*/
++SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){
++#ifdef YYFALLBACK
++  if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){
++    return yyFallback[iToken];
++  }
++#else
++  (void)iToken;
++#endif
++  return 0;
++}
++
+ /************** End of parse.c ***********************************************/
+ /************** Begin file tokenize.c ****************************************/
+ /*
+@@ -140344,11 +151271,12 @@
+ #define CC_TILDA     25    /* '~' */
+ #define CC_DOT       26    /* '.' */
+ #define CC_ILLEGAL   27    /* Illegal character */
++#define CC_NUL       28    /* 0x00 */
+ 
+ static const unsigned char aiClass[] = {
+ #ifdef SQLITE_ASCII
+ /*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
+-/* 0x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
++/* 0x */   28, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
+ /* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ /* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
+ /* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
+@@ -140447,19 +151375,20 @@
+ ** is substantially reduced.  This is important for embedded applications
+ ** on platforms with limited memory.
+ */
+-/* Hash score: 182 */
+-/* zKWText[] encodes 834 bytes of keyword text in 554 bytes */
++/* Hash score: 208 */
++/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */
+ /*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
+ /*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
+ /*   XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY         */
+-/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE         */
+-/*   BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH     */
+-/*   IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN     */
+-/*   WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT         */
+-/*   CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL        */
+-/*   FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING        */
+-/*   VACUUMVIEWINITIALLY                                                */
+-static const char zKWText[553] = {
++/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN      */
++/*   OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH           */
++/*   IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT     */
++/*   WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST         */
++/*   COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED         */
++/*   ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL       */
++/*   ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW      */
++/*   INDOWINITIALLYPRIMARY                                              */
++static const char zKWText[613] = {
+   'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
+   'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
+   'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
+@@ -140472,83 +151401,90 @@
+   'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
+   'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
+   'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
+-  'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
+-  'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
+-  'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
+-  'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
+-  'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
+-  'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
+-  'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
+-  'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
+-  'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
+-  'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
+-  'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
+-  'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
+-  'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
+-  'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
+-  'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
+-  'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
+-  'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
+-  'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
+-  'V','I','E','W','I','N','I','T','I','A','L','L','Y',
++  'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W',
++  'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A',
++  'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
++  'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
++  'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
++  'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A',
++  'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
++  'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O',
++  'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A',
++  'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T',
++  'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C',
++  'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C',
++  'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E',
++  'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R',
++  'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E',
++  'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A',
++  'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L',
++  'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R',
++  'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C',
++  'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O',
++  'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N',
++  'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R',
++  'Y',
+ };
+ /* aKWHash[i] is the hash value for the i-th keyword */
+ static const unsigned char aKWHash[127] = {
+-    76, 105, 117,  74,   0,  45,   0,   0,  82,   0,  77,   0,   0,
+-    42,  12,  78,  15,   0, 116,  85,  54, 112,   0,  19,   0,   0,
+-   121,   0, 119, 115,   0,  22,  93,   0,   9,   0,   0,  70,  71,
+-     0,  69,   6,   0,  48,  90, 102,   0, 118, 101,   0,   0,  44,
+-     0, 103,  24,   0,  17,   0, 122,  53,  23,   0,   5, 110,  25,
+-    96,   0,   0, 124, 106,  60, 123,  57,  28,  55,   0,  91,   0,
+-   100,  26,   0,  99,   0,   0,   0,  95,  92,  97,  88, 109,  14,
+-    39, 108,   0,  81,   0,  18,  89, 111,  32,   0, 120,  80, 113,
+-    62,  46,  84,   0,   0,  94,  40,  59, 114,   0,  36,   0,   0,
+-    29,   0,  86,  63,  64,   0,  20,  61,   0,  56,
++    74, 109, 124,  72, 106,  45,   0,   0,  81,   0,  76,  61,   0,
++    42,  12,  77,  15,   0, 123,  84,  54, 118, 125,  19,   0,   0,
++   130,   0, 128, 121,   0,  22,  96,   0,   9,   0,   0, 115,  69,
++     0,  67,   6,   0,  48,  93, 136,   0, 126, 104,   0,   0,  44,
++     0, 107,  24,   0,  17,   0, 131,  53,  23,   0,   5,  62, 132,
++    99,   0,   0, 135, 110,  60, 134,  57, 113,  55,   0,  94,   0,
++   103,  26,   0, 102,   0,   0,   0,  98,  95, 100, 105, 117,  14,
++    39, 116,   0,  80,   0, 133, 114,  92,  59,   0, 129,  79, 119,
++    86,  46,  83,   0,   0,  97,  40, 122, 120,   0, 127,   0,   0,
++    29,   0,  89,  87,  88,   0,  20,  85, 111,  56,
+ };
+ /* aKWNext[] forms the hash collision chain.  If aKWHash[i]==0
+ ** then the i-th keyword has no more hash collisions.  Otherwise,
+ ** the next keyword with the same hash is aKWHash[i]-1. */
+-static const unsigned char aKWNext[124] = {
++static const unsigned char aKWNext[136] = {
+      0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   2,   0,   0,   0,   0,   0,   0,  13,   0,   0,   0,   0,
+      0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,  33,   0,  21,   0,   0,   0,   0,   0,  50,
+-     0,  43,   3,  47,   0,   0,   0,   0,  30,   0,  58,   0,  38,
+-     0,   0,   0,   1,  66,   0,   0,  67,   0,  41,   0,   0,   0,
+-     0,   0,   0,  49,  65,   0,   0,   0,   0,  31,  52,  16,  34,
+-    10,   0,   0,   0,   0,   0,   0,   0,  11,  72,  79,   0,   8,
+-     0, 104,  98,   0, 107,   0,  87,   0,  75,  51,   0,  27,  37,
+-    73,  83,   0,  35,  68,   0,   0,
++     0,  43,   3,  47,   0,   0,  32,   0,   0,   0,   0,   0,   0,
++     0,   1,  64,   0,   0,  65,   0,  41,   0,  38,   0,   0,   0,
++     0,   0,  49,  75,   0,   0,  30,   0,  58,   0,   0,   0,  31,
++    63,  16,  34,  10,   0,   0,   0,   0,   0,   0,   0,  11,  70,
++    91,   0,   0,   8,   0, 108,   0, 101,  28,  52,  68,   0, 112,
++     0,  73,  51,   0,  90,  27,  37,   0,  71,  36,  82,   0,  35,
++    66,  25,  18,   0,   0,  78,
+ };
+ /* aKWLen[i] is the length (in bytes) of the i-th keyword */
+-static const unsigned char aKWLen[124] = {
++static const unsigned char aKWLen[136] = {
+      7,   7,   5,   4,   6,   4,   5,   3,   6,   7,   3,   6,   6,
+      7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   6,
+     11,   6,   2,   7,   5,   5,   9,   6,   9,   9,   7,  10,  10,
+      4,   6,   2,   3,   9,   4,   2,   6,   5,   7,   4,   5,   7,
+-     6,   6,   5,   6,   5,   5,   9,   7,   7,   3,   2,   4,   4,
+-     7,   3,   6,   4,   7,   6,  12,   6,   9,   4,   6,   5,   4,
+-     7,   6,   5,   6,   7,   5,   4,   5,   6,   5,   7,   3,   7,
+-    13,   2,   2,   4,   6,   6,   8,   5,  17,  12,   7,   8,   8,
+-     2,   4,   4,   4,   4,   4,   2,   2,   6,   5,   8,   5,   8,
+-     3,   5,   5,   6,   4,   9,   3,
++     6,   6,   5,   6,   5,   5,   5,   7,   7,   4,   2,   7,   3,
++     6,   4,   7,   6,  12,   6,   9,   4,   6,   4,   5,   4,   7,
++     6,   5,   6,   7,   5,   4,   7,   3,   2,   4,   5,   9,   5,
++     6,   3,   7,  13,   2,   2,   4,   6,   6,   8,   5,  17,  12,
++     7,   9,   8,   8,   2,   4,   9,   4,   6,   7,   9,   4,   4,
++     2,   6,   5,   8,   4,   5,   8,   4,   3,   9,   5,   5,   6,
++     4,   6,   2,   9,   3,   7,
+ };
+ /* aKWOffset[i] is the index into zKWText[] of the start of
+ ** the text for the i-th keyword. */
+-static const unsigned short int aKWOffset[124] = {
++static const unsigned short int aKWOffset[136] = {
+      0,   2,   2,   8,   9,  14,  16,  20,  23,  25,  25,  29,  33,
+     36,  41,  46,  48,  53,  54,  59,  62,  65,  67,  69,  78,  81,
+     86,  91,  95,  96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
+    159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
+-   199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
+-   250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
+-   320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
+-   387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
+-   460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
+-   521, 524, 529, 534, 540, 544, 549,
++   199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248,
++   252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321,
++   328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377,
++   381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438,
++   438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519,
++   523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582,
++   588, 591, 594, 597, 602, 606,
+ };
+ /* aKWCode[i] is the parser symbol code for the i-th keyword */
+-static const unsigned char aKWCode[124] = {
++static const unsigned char aKWCode[136] = {
+   TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,     
+   TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,    
+   TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,    
+@@ -140560,20 +151496,23 @@
+   TK_OFFSET,     TK_OF,         TK_SET,        TK_TEMP,       TK_TEMP,       
+   TK_OR,         TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    TK_WITH,       
+   TK_JOIN_KW,    TK_RELEASE,    TK_ATTACH,     TK_HAVING,     TK_GROUP,      
+-  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RECURSIVE,  TK_BETWEEN,    
+-  TK_NOTNULL,    TK_NOT,        TK_NO,         TK_NULL,       TK_LIKE_KW,    
+-  TK_CASCADE,    TK_ASC,        TK_DELETE,     TK_CASE,       TK_COLLATE,    
+-  TK_CREATE,     TK_CTIME_KW,   TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       
+-  TK_INSERT,     TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     
+-  TK_ABORT,      TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       
+-  TK_WHERE,      TK_RENAME,     TK_AFTER,      TK_REPLACE,    TK_AND,        
+-  TK_DEFAULT,    TK_AUTOINCR,   TK_TO,         TK_IN,         TK_CAST,       
+-  TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   
+-  TK_CTIME_KW,   TK_PRIMARY,    TK_DEFERRED,   TK_DISTINCT,   TK_IS,         
+-  TK_DROP,       TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_LIKE_KW,    
+-  TK_BY,         TK_IF,         TK_ISNULL,     TK_ORDER,      TK_RESTRICT,   
+-  TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_UNION,      TK_USING,      
+-  TK_VACUUM,     TK_VIEW,       TK_INITIALLY,  TK_ALL,        
++  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RANGE,      TK_BETWEEN,    
++  TK_NOTHING,    TK_LIKE_KW,    TK_BY,         TK_CASCADE,    TK_ASC,        
++  TK_DELETE,     TK_CASE,       TK_COLLATE,    TK_CREATE,     TK_CTIME_KW,   
++  TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       TK_INSERT,     TK_LIKE_KW,    
++  TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     TK_ABORT,      
++  TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       TK_NOTNULL,    
++  TK_NOT,        TK_NO,         TK_NULL,       TK_WHERE,      TK_RECURSIVE,  
++  TK_AFTER,      TK_RENAME,     TK_AND,        TK_DEFAULT,    TK_AUTOINCR,   
++  TK_TO,         TK_IN,         TK_CAST,       TK_COLUMNKW,   TK_COMMIT,     
++  TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   TK_CTIME_KW,   TK_CURRENT,    
++  TK_PARTITION,  TK_DEFERRED,   TK_DISTINCT,   TK_IS,         TK_DROP,       
++  TK_PRECEDING,  TK_FAIL,       TK_FILTER,     TK_REPLACE,    TK_FOLLOWING,  
++  TK_FROM,       TK_JOIN_KW,    TK_IF,         TK_ISNULL,     TK_ORDER,      
++  TK_RESTRICT,   TK_OVER,       TK_JOIN_KW,    TK_ROLLBACK,   TK_ROWS,       
++  TK_ROW,        TK_UNBOUNDED,  TK_UNION,      TK_USING,      TK_VACUUM,     
++  TK_VIEW,       TK_WINDOW,     TK_DO,         TK_INITIALLY,  TK_ALL,        
++  TK_PRIMARY,    
+ };
+ /* Check to see if z[0..n-1] is a keyword. If it is, write the
+ ** parser symbol code for that keyword into *pType.  Always
+@@ -140652,72 +151591,84 @@
+       testcase( i==55 ); /* UPDATE */
+       testcase( i==56 ); /* BEGIN */
+       testcase( i==57 ); /* INNER */
+-      testcase( i==58 ); /* RECURSIVE */
++      testcase( i==58 ); /* RANGE */
+       testcase( i==59 ); /* BETWEEN */
+-      testcase( i==60 ); /* NOTNULL */
+-      testcase( i==61 ); /* NOT */
+-      testcase( i==62 ); /* NO */
+-      testcase( i==63 ); /* NULL */
+-      testcase( i==64 ); /* LIKE */
+-      testcase( i==65 ); /* CASCADE */
+-      testcase( i==66 ); /* ASC */
+-      testcase( i==67 ); /* DELETE */
+-      testcase( i==68 ); /* CASE */
+-      testcase( i==69 ); /* COLLATE */
+-      testcase( i==70 ); /* CREATE */
+-      testcase( i==71 ); /* CURRENT_DATE */
+-      testcase( i==72 ); /* DETACH */
+-      testcase( i==73 ); /* IMMEDIATE */
+-      testcase( i==74 ); /* JOIN */
+-      testcase( i==75 ); /* INSERT */
+-      testcase( i==76 ); /* MATCH */
+-      testcase( i==77 ); /* PLAN */
+-      testcase( i==78 ); /* ANALYZE */
+-      testcase( i==79 ); /* PRAGMA */
+-      testcase( i==80 ); /* ABORT */
+-      testcase( i==81 ); /* VALUES */
+-      testcase( i==82 ); /* VIRTUAL */
+-      testcase( i==83 ); /* LIMIT */
+-      testcase( i==84 ); /* WHEN */
+-      testcase( i==85 ); /* WHERE */
+-      testcase( i==86 ); /* RENAME */
+-      testcase( i==87 ); /* AFTER */
+-      testcase( i==88 ); /* REPLACE */
+-      testcase( i==89 ); /* AND */
+-      testcase( i==90 ); /* DEFAULT */
+-      testcase( i==91 ); /* AUTOINCREMENT */
+-      testcase( i==92 ); /* TO */
+-      testcase( i==93 ); /* IN */
+-      testcase( i==94 ); /* CAST */
+-      testcase( i==95 ); /* COLUMN */
+-      testcase( i==96 ); /* COMMIT */
+-      testcase( i==97 ); /* CONFLICT */
+-      testcase( i==98 ); /* CROSS */
+-      testcase( i==99 ); /* CURRENT_TIMESTAMP */
+-      testcase( i==100 ); /* CURRENT_TIME */
+-      testcase( i==101 ); /* PRIMARY */
+-      testcase( i==102 ); /* DEFERRED */
+-      testcase( i==103 ); /* DISTINCT */
+-      testcase( i==104 ); /* IS */
+-      testcase( i==105 ); /* DROP */
+-      testcase( i==106 ); /* FAIL */
+-      testcase( i==107 ); /* FROM */
+-      testcase( i==108 ); /* FULL */
+-      testcase( i==109 ); /* GLOB */
+-      testcase( i==110 ); /* BY */
+-      testcase( i==111 ); /* IF */
+-      testcase( i==112 ); /* ISNULL */
+-      testcase( i==113 ); /* ORDER */
+-      testcase( i==114 ); /* RESTRICT */
+-      testcase( i==115 ); /* RIGHT */
+-      testcase( i==116 ); /* ROLLBACK */
+-      testcase( i==117 ); /* ROW */
+-      testcase( i==118 ); /* UNION */
+-      testcase( i==119 ); /* USING */
+-      testcase( i==120 ); /* VACUUM */
+-      testcase( i==121 ); /* VIEW */
+-      testcase( i==122 ); /* INITIALLY */
+-      testcase( i==123 ); /* ALL */
++      testcase( i==60 ); /* NOTHING */
++      testcase( i==61 ); /* GLOB */
++      testcase( i==62 ); /* BY */
++      testcase( i==63 ); /* CASCADE */
++      testcase( i==64 ); /* ASC */
++      testcase( i==65 ); /* DELETE */
++      testcase( i==66 ); /* CASE */
++      testcase( i==67 ); /* COLLATE */
++      testcase( i==68 ); /* CREATE */
++      testcase( i==69 ); /* CURRENT_DATE */
++      testcase( i==70 ); /* DETACH */
++      testcase( i==71 ); /* IMMEDIATE */
++      testcase( i==72 ); /* JOIN */
++      testcase( i==73 ); /* INSERT */
++      testcase( i==74 ); /* LIKE */
++      testcase( i==75 ); /* MATCH */
++      testcase( i==76 ); /* PLAN */
++      testcase( i==77 ); /* ANALYZE */
++      testcase( i==78 ); /* PRAGMA */
++      testcase( i==79 ); /* ABORT */
++      testcase( i==80 ); /* VALUES */
++      testcase( i==81 ); /* VIRTUAL */
++      testcase( i==82 ); /* LIMIT */
++      testcase( i==83 ); /* WHEN */
++      testcase( i==84 ); /* NOTNULL */
++      testcase( i==85 ); /* NOT */
++      testcase( i==86 ); /* NO */
++      testcase( i==87 ); /* NULL */
++      testcase( i==88 ); /* WHERE */
++      testcase( i==89 ); /* RECURSIVE */
++      testcase( i==90 ); /* AFTER */
++      testcase( i==91 ); /* RENAME */
++      testcase( i==92 ); /* AND */
++      testcase( i==93 ); /* DEFAULT */
++      testcase( i==94 ); /* AUTOINCREMENT */
++      testcase( i==95 ); /* TO */
++      testcase( i==96 ); /* IN */
++      testcase( i==97 ); /* CAST */
++      testcase( i==98 ); /* COLUMN */
++      testcase( i==99 ); /* COMMIT */
++      testcase( i==100 ); /* CONFLICT */
++      testcase( i==101 ); /* CROSS */
++      testcase( i==102 ); /* CURRENT_TIMESTAMP */
++      testcase( i==103 ); /* CURRENT_TIME */
++      testcase( i==104 ); /* CURRENT */
++      testcase( i==105 ); /* PARTITION */
++      testcase( i==106 ); /* DEFERRED */
++      testcase( i==107 ); /* DISTINCT */
++      testcase( i==108 ); /* IS */
++      testcase( i==109 ); /* DROP */
++      testcase( i==110 ); /* PRECEDING */
++      testcase( i==111 ); /* FAIL */
++      testcase( i==112 ); /* FILTER */
++      testcase( i==113 ); /* REPLACE */
++      testcase( i==114 ); /* FOLLOWING */
++      testcase( i==115 ); /* FROM */
++      testcase( i==116 ); /* FULL */
++      testcase( i==117 ); /* IF */
++      testcase( i==118 ); /* ISNULL */
++      testcase( i==119 ); /* ORDER */
++      testcase( i==120 ); /* RESTRICT */
++      testcase( i==121 ); /* OVER */
++      testcase( i==122 ); /* RIGHT */
++      testcase( i==123 ); /* ROLLBACK */
++      testcase( i==124 ); /* ROWS */
++      testcase( i==125 ); /* ROW */
++      testcase( i==126 ); /* UNBOUNDED */
++      testcase( i==127 ); /* UNION */
++      testcase( i==128 ); /* USING */
++      testcase( i==129 ); /* VACUUM */
++      testcase( i==130 ); /* VIEW */
++      testcase( i==131 ); /* WINDOW */
++      testcase( i==132 ); /* DO */
++      testcase( i==133 ); /* INITIALLY */
++      testcase( i==134 ); /* ALL */
++      testcase( i==135 ); /* PRIMARY */
+       *pType = aKWCode[i];
+       break;
+     }
+@@ -140729,7 +151680,17 @@
+   keywordCode((char*)z, n, &id);
+   return id;
+ }
+-#define SQLITE_N_KEYWORD 124
++#define SQLITE_N_KEYWORD 136
++SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
++  if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;
++  *pzName = zKWText + aKWOffset[i];
++  *pnName = aKWLen[i];
++  return SQLITE_OK;
++}
++SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; }
++SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){
++  return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
++}
+ 
+ /************** End of keywordhash.h *****************************************/
+ /************** Continuing where we left off in tokenize.c *******************/
+@@ -140773,13 +151734,87 @@
+ #define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
+ #endif
+ 
+-/* Make the IdChar function accessible from ctime.c */
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
++/* Make the IdChar function accessible from ctime.c and alter.c */
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
+-#endif
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Return the id of the next token in string (*pz). Before returning, set
++** (*pz) to point to the byte following the parsed token.
++*/
++static int getToken(const unsigned char **pz){
++  const unsigned char *z = *pz;
++  int t;                          /* Token type to return */
++  do {
++    z += sqlite3GetToken(z, &t);
++  }while( t==TK_SPACE );
++  if( t==TK_ID 
++   || t==TK_STRING 
++   || t==TK_JOIN_KW 
++   || t==TK_WINDOW 
++   || t==TK_OVER 
++   || sqlite3ParserFallback(t)==TK_ID 
++  ){
++    t = TK_ID;
++  }
++  *pz = z;
++  return t;
++}
+ 
+ /*
++** The following three functions are called immediately after the tokenizer
++** reads the keywords WINDOW, OVER and FILTER, respectively, to determine
++** whether the token should be treated as a keyword or an SQL identifier.
++** This cannot be handled by the usual lemon %fallback method, due to
++** the ambiguity in some constructions. e.g.
++**
++**   SELECT sum(x) OVER ...
++**
++** In the above, "OVER" might be a keyword, or it might be an alias for the 
++** sum(x) expression. If a "%fallback ID OVER" directive were added to 
++** grammar, then SQLite would always treat "OVER" as an alias, making it
++** impossible to call a window-function without a FILTER clause.
++**
++** WINDOW is treated as a keyword if:
++**
++**   * the following token is an identifier, or a keyword that can fallback
++**     to being an identifier, and
++**   * the token after than one is TK_AS.
++**
++** OVER is a keyword if:
++**
++**   * the previous token was TK_RP, and
++**   * the next token is either TK_LP or an identifier.
++**
++** FILTER is a keyword if:
++**
++**   * the previous token was TK_RP, and
++**   * the next token is TK_LP.
++*/
++static int analyzeWindowKeyword(const unsigned char *z){
++  int t;
++  t = getToken(&z);
++  if( t!=TK_ID ) return TK_ID;
++  t = getToken(&z);
++  if( t!=TK_AS ) return TK_ID;
++  return TK_WINDOW;
++}
++static int analyzeOverKeyword(const unsigned char *z, int lastToken){
++  if( lastToken==TK_RP ){
++    int t = getToken(&z);
++    if( t==TK_LP || t==TK_ID ) return TK_OVER;
++  }
++  return TK_ID;
++}
++static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
++  if( lastToken==TK_RP && getToken(&z)==TK_LP ){
++    return TK_FILTER;
++  }
++  return TK_ID;
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** Return the length (in bytes) of the token that begins at z[0]. 
+ ** Store the token type in *tokenType before returning.
+ */
+@@ -141046,6 +152081,10 @@
+       i = 1;
+       break;
+     }
++    case CC_NUL: {
++      *tokenType = TK_ILLEGAL;
++      return 0;
++    }
+     default: {
+       *tokenType = TK_ILLEGAL;
+       return 1;
+@@ -141056,7 +152095,74 @@
+   return i;
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
+ /*
++** Return the length (in bytes) of the token that begins at z[0].
++** Store the token type in *tokenType before returning.  If flags has
++** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
++** for keywords.  Add SQLITE_TOKEN_QUOTED to flags if the token was
++** actually a quoted identifier.  Add SQLITE_TOKEN_KEYWORD to flags
++** if the token was recognized as a keyword; this is useful when the
++** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
++** to differentiate between a keyword being treated as an identifier
++** (for normalization purposes) and an actual identifier.
++*/
++SQLITE_PRIVATE int sqlite3GetTokenNormalized(
++  const unsigned char *z,
++  int *tokenType,
++  int *flags
++){
++  int n;
++  unsigned char iClass = aiClass[*z];
++  if( iClass==CC_KYWD ){
++    int i;
++    for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
++    if( IdChar(z[i]) ){
++      /* This token started out using characters that can appear in keywords,
++      ** but z[i] is a character not allowed within keywords, so this must
++      ** be an identifier instead */
++      i++;
++      while( IdChar(z[i]) ){ i++; }
++      *tokenType = TK_ID;
++      return i;
++    }
++    *tokenType = TK_ID;
++    n = keywordCode((char*)z, i, tokenType);
++    /* If the token is no longer considered to be an identifier, then it is a
++    ** keyword of some kind.  Make the token back into an identifier and then
++    ** set the SQLITE_TOKEN_KEYWORD flag.  Several non-identifier tokens are
++    ** used verbatim, including IN, IS, NOT, and NULL. */
++    switch( *tokenType ){
++      case TK_ID: {
++        /* do nothing, handled by caller */
++        break;
++      }
++      case TK_IN:
++      case TK_IS:
++      case TK_NOT:
++      case TK_NULL: {
++        *flags |= SQLITE_TOKEN_KEYWORD;
++        break;
++      }
++      default: {
++        *tokenType = TK_ID;
++        *flags |= SQLITE_TOKEN_KEYWORD;
++        break;
++      }
++    }
++  }else{
++    n = sqlite3GetToken(z, tokenType);
++    /* If the token is considered to be an identifier and the character class
++    ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
++    if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
++      *flags |= SQLITE_TOKEN_QUOTED;
++    }
++  }
++  return n;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
++/*
+ ** 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 
+@@ -141086,9 +152192,9 @@
+   /* sqlite3ParserTrace(stdout, "parser: "); */
+ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+   pEngine = &sEngine;
+-  sqlite3ParserInit(pEngine);
++  sqlite3ParserInit(pEngine, pParse);
+ #else
+-  pEngine = sqlite3ParserAlloc(sqlite3Malloc);
++  pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse);
+   if( pEngine==0 ){
+     sqlite3OomFault(db);
+     return SQLITE_NOMEM_BKPT;
+@@ -141099,47 +152205,64 @@
+   assert( pParse->nVar==0 );
+   assert( pParse->pVList==0 );
+   while( 1 ){
+-    if( zSql[0]!=0 ){
+-      n = sqlite3GetToken((u8*)zSql, &tokenType);
+-      mxSqlLen -= n;
+-      if( mxSqlLen<0 ){
+-        pParse->rc = SQLITE_TOOBIG;
+-        break;
+-      }
+-    }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;
++    n = sqlite3GetToken((u8*)zSql, &tokenType);
++    mxSqlLen -= n;
++    if( mxSqlLen<0 ){
++      pParse->rc = SQLITE_TOOBIG;
++      break;
+     }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( tokenType>=TK_WINDOW ){
++      assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
++           || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW 
++      );
++#else
+     if( tokenType>=TK_SPACE ){
+       assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+       if( db->u1.isInterrupted ){
+         pParse->rc = SQLITE_INTERRUPT;
+         break;
+       }
+-      if( tokenType==TK_ILLEGAL ){
++      if( tokenType==TK_SPACE ){
++        zSql += n;
++        continue;
++      }
++      if( zSql[0]==0 ){
++        /* 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;
++        }
++        n = 0;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      }else if( tokenType==TK_WINDOW ){
++        assert( n==6 );
++        tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
++      }else if( tokenType==TK_OVER ){
++        assert( n==4 );
++        tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
++      }else if( tokenType==TK_FILTER ){
++        assert( n==6 );
++        tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++      }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;
+     }
++    pParse->sLastToken.z = zSql;
++    pParse->sLastToken.n = n;
++    sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
++    lastTokenParsed = tokenType;
++    zSql += n;
++    if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+   }
+   assert( nErr==0 );
+-  pParse->zTail = zSql;
+ #ifdef YYTRACKMAXSTACKDEPTH
+   sqlite3_mutex_enter(sqlite3MallocMutex());
+   sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
+@@ -141161,10 +152284,12 @@
+   assert( pzErrMsg!=0 );
+   if( pParse->zErrMsg ){
+     *pzErrMsg = pParse->zErrMsg;
+-    sqlite3_log(pParse->rc, "%s", *pzErrMsg);
++    sqlite3_log(pParse->rc, "%s in \"%s\"", 
++                *pzErrMsg, pParse->zTail);
+     pParse->zErrMsg = 0;
+     nErr++;
+   }
++  pParse->zTail = zSql;
+   if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
+     sqlite3VdbeDelete(pParse->pVdbe);
+     pParse->pVdbe = 0;
+@@ -141180,7 +152305,7 @@
+   sqlite3_free(pParse->apVtabLock);
+ #endif
+ 
+-  if( !IN_DECLARE_VTAB ){
++  if( !IN_SPECIAL_PARSE ){
+     /* If the pParse->declareVtab flag is set, do not delete any table 
+     ** structure built up in pParse->pNewTable. The calling code (see vtab.c)
+     ** will take responsibility for freeing the Table structure.
+@@ -141187,9 +152312,11 @@
+     */
+     sqlite3DeleteTable(db, pParse->pNewTable);
+   }
++  if( !IN_RENAME_OBJECT ){
++    sqlite3DeleteTrigger(db, pParse->pNewTrigger);
++  }
+ 
+   if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
+-  sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+   sqlite3DbFree(db, pParse->pVList);
+   while( pParse->pAinc ){
+     AutoincInfo *p = pParse->pAinc;
+@@ -141571,6 +152698,10 @@
+ */
+ /* #include "sqlite3.h" */
+ 
++#ifdef SQLITE_OMIT_VIRTUALTABLE
++# undef SQLITE_ENABLE_RTREE
++#endif
++
+ #if 0
+ extern "C" {
+ #endif  /* __cplusplus */
+@@ -141584,7 +152715,7 @@
+ /************** End of rtree.h ***********************************************/
+ /************** Continuing where we left off in main.c ***********************/
+ #endif
+-#ifdef SQLITE_ENABLE_ICU
++#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+ /************** Include sqliteicu.h in the middle of main.c ******************/
+ /************** Begin file sqliteicu.h ***************************************/
+ /*
+@@ -141640,11 +152771,13 @@
+ */
+ SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
+ 
+-/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
++/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a
+ ** pointer to a string constant whose value is the same as the
+-** SQLITE_SOURCE_ID C preprocessor macro. 
++** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using
++** an edited copy of the amalgamation, then the last four characters of
++** the hash might be different from SQLITE_SOURCE_ID.
+ */
+-SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
++/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */
+ 
+ /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
+ ** returns an integer equal to SQLITE_VERSION_NUMBER.
+@@ -141830,7 +152963,12 @@
+       sqlite3GlobalConfig.isPCacheInit = 1;
+       rc = sqlite3OsInit();
+     }
++#ifdef SQLITE_ENABLE_DESERIALIZE
+     if( rc==SQLITE_OK ){
++      rc = sqlite3MemdbInit();
++    }
++#endif
++    if( rc==SQLITE_OK ){
+       sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
+           sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
+       sqlite3GlobalConfig.isInit = 1;
+@@ -141862,7 +153000,7 @@
+ #ifndef NDEBUG
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+   /* This section of code's only "output" is via assert() statements. */
+-  if ( rc==SQLITE_OK ){
++  if( rc==SQLITE_OK ){
+     u64 x = (((u64)1)<<63)-1;
+     double y;
+     assert(sizeof(x)==8);
+@@ -142029,14 +153167,8 @@
+       sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
+       break;
+     }
+-    case SQLITE_CONFIG_SCRATCH: {
+-      /* EVIDENCE-OF: R-08404-60887 There are three arguments to
+-      ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from
+-      ** which the scratch allocations will be drawn, the size of each scratch
+-      ** allocation (sz), and the maximum number of scratch allocations (N). */
+-      sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
+-      sqlite3GlobalConfig.szScratch = va_arg(ap, int);
+-      sqlite3GlobalConfig.nScratch = va_arg(ap, int);
++    case SQLITE_CONFIG_SMALL_MALLOC: {
++      sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int);
+       break;
+     }
+     case SQLITE_CONFIG_PAGECACHE: {
+@@ -142234,6 +153366,17 @@
+       break;
+     }
+ 
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    case SQLITE_CONFIG_SORTERREF_SIZE: {
++      int iVal = va_arg(ap, int);
++      if( iVal<0 ){
++        iVal = SQLITE_DEFAULT_SORTERREF_SIZE;
++      }
++      sqlite3GlobalConfig.szSorterRef = (u32)iVal;
++      break;
++    }
++#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
++
+     default: {
+       rc = SQLITE_ERROR;
+       break;
+@@ -142257,7 +153400,8 @@
+ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
+ #ifndef SQLITE_OMIT_LOOKASIDE
+   void *pStart;
+-  if( db->lookaside.nOut ){
++  
++  if( sqlite3LookasideUsed(db,0)>0 ){
+     return SQLITE_BUSY;
+   }
+   /* Free any existing lookaside buffer for this handle before
+@@ -142285,6 +153429,7 @@
+     pStart = pBuf;
+   }
+   db->lookaside.pStart = pStart;
++  db->lookaside.pInit = 0;
+   db->lookaside.pFree = 0;
+   db->lookaside.sz = (u16)sz;
+   if( pStart ){
+@@ -142291,10 +153436,11 @@
+     int i;
+     LookasideSlot *p;
+     assert( sz > (int)sizeof(LookasideSlot*) );
++    db->lookaside.nSlot = cnt;
+     p = (LookasideSlot*)pStart;
+     for(i=cnt-1; i>=0; i--){
+-      p->pNext = db->lookaside.pFree;
+-      db->lookaside.pFree = p;
++      p->pNext = db->lookaside.pInit;
++      db->lookaside.pInit = p;
+       p = (LookasideSlot*)&((u8*)p)[sz];
+     }
+     db->lookaside.pEnd = p;
+@@ -142305,6 +153451,7 @@
+     db->lookaside.pEnd = db;
+     db->lookaside.bDisable = 1;
+     db->lookaside.bMalloced = 0;
++    db->lookaside.nSlot = 0;
+   }
+ #endif /* SQLITE_OMIT_LOOKASIDE */
+   return SQLITE_OK;
+@@ -142410,6 +153557,9 @@
+         { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension  },
+         { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
+         { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
++        { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
++        { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
++        { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
+       };
+       unsigned int i;
+       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+@@ -142417,7 +153567,7 @@
+         if( aFlagOp[i].op==op ){
+           int onoff = va_arg(ap, int);
+           int *pRes = va_arg(ap, int*);
+-          int oldFlags = db->flags;
++          u32 oldFlags = db->flags;
+           if( onoff>0 ){
+             db->flags |= aFlagOp[i].mask;
+           }else if( onoff==0 ){
+@@ -142424,7 +153574,7 @@
+             db->flags &= ~aFlagOp[i].mask;
+           }
+           if( oldFlags!=db->flags ){
+-            sqlite3ExpirePreparedStatements(db);
++            sqlite3ExpirePreparedStatements(db, 0);
+           }
+           if( pRes ){
+             *pRes = (db->flags & aFlagOp[i].mask)!=0;
+@@ -142486,6 +153636,15 @@
+ }
+ 
+ /*
++** Return true if CollSeq is the default built-in BINARY.
++*/
++SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){
++  assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
++            || strcmp(p->zName,"BINARY")==0 );
++  return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
++}
++
++/*
+ ** Another built-in collating sequence: NOCASE. 
+ **
+ ** This collating sequence is intended to be used for "case independent
+@@ -142606,7 +153765,7 @@
+   sqlite3BtreeEnterAll(db);
+   for(i=0; i<db->nDb; i++){
+     Schema *pSchema = db->aDb[i].pSchema;
+-    if( db->aDb[i].pSchema ){
++    if( pSchema ){
+       for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
+         Table *pTab = (Table *)sqliteHashData(p);
+         if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
+@@ -142824,7 +153983,7 @@
+   sqlite3_mutex_leave(db->mutex);
+   db->magic = SQLITE_MAGIC_CLOSED;
+   sqlite3_mutex_free(db->mutex);
+-  assert( db->lookaside.nOut==0 );  /* Fails on a lookaside memory leak */
++  assert( sqlite3LookasideUsed(db,0)==0 );
+   if( db->lookaside.bMalloced ){
+     sqlite3_free(db->lookaside.pStart);
+   }
+@@ -142852,7 +154011,7 @@
+   ** the database rollback and schema reset, which can cause false
+   ** corruption reports in some cases.  */
+   sqlite3BtreeEnterAll(db);
+-  schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
++  schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;
+ 
+   for(i=0; i<db->nDb; i++){
+     Btree *p = db->aDb[i].pBt;
+@@ -142866,8 +154025,8 @@
+   sqlite3VtabRollback(db);
+   sqlite3EndBenignMalloc();
+ 
+-  if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
+-    sqlite3ExpirePreparedStatements(db);
++  if( schemaChange ){
++    sqlite3ExpirePreparedStatements(db, 0);
+     sqlite3ResetAllSchemasOfConnection(db);
+   }
+   sqlite3BtreeLeaveAll(db);
+@@ -142895,6 +154054,7 @@
+     switch( rc ){
+       case SQLITE_OK:                 zName = "SQLITE_OK";                break;
+       case SQLITE_ERROR:              zName = "SQLITE_ERROR";             break;
++      case SQLITE_ERROR_SNAPSHOT:     zName = "SQLITE_ERROR_SNAPSHOT";    break;
+       case SQLITE_INTERNAL:           zName = "SQLITE_INTERNAL";          break;
+       case SQLITE_PERM:               zName = "SQLITE_PERM";              break;
+       case SQLITE_ABORT:              zName = "SQLITE_ABORT";             break;
+@@ -142907,9 +154067,10 @@
+       case SQLITE_NOMEM:              zName = "SQLITE_NOMEM";             break;
+       case SQLITE_READONLY:           zName = "SQLITE_READONLY";          break;
+       case SQLITE_READONLY_RECOVERY:  zName = "SQLITE_READONLY_RECOVERY"; break;
+-      case SQLITE_READONLY_CANTLOCK:  zName = "SQLITE_READONLY_CANTLOCK"; break;
++      case SQLITE_READONLY_CANTINIT:  zName = "SQLITE_READONLY_CANTINIT"; break;
+       case SQLITE_READONLY_ROLLBACK:  zName = "SQLITE_READONLY_ROLLBACK"; break;
+       case SQLITE_READONLY_DBMOVED:   zName = "SQLITE_READONLY_DBMOVED";  break;
++      case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
+       case SQLITE_INTERRUPT:          zName = "SQLITE_INTERRUPT";         break;
+       case SQLITE_IOERR:              zName = "SQLITE_IOERR";             break;
+       case SQLITE_IOERR_READ:         zName = "SQLITE_IOERR_READ";        break;
+@@ -143029,6 +154190,8 @@
+     /* SQLITE_FORMAT      */ 0,
+     /* SQLITE_RANGE       */ "column index out of range",
+     /* SQLITE_NOTADB      */ "file is not a database",
++    /* SQLITE_NOTICE      */ "notification message",
++    /* SQLITE_WARNING     */ "warning message",
+   };
+   const char *zErr = "unknown error";
+   switch( rc ){
+@@ -143036,6 +154199,14 @@
+       zErr = "abort due to ROLLBACK";
+       break;
+     }
++    case SQLITE_ROW: {
++      zErr = "another row available";
++      break;
++    }
++    case SQLITE_DONE: {
++      zErr = "no more rows available";
++      break;
++    }
+     default: {
+       rc &= 0xff;
+       if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
+@@ -143052,12 +154223,18 @@
+ ** again until a timeout value is reached.  The timeout value is
+ ** an integer number of milliseconds passed in as the first
+ ** argument.
++**
++** Return non-zero to retry the lock.  Return zero to stop trying
++** and cause SQLite to return SQLITE_BUSY.
+ */
+ static int sqliteDefaultBusyCallback(
+- void *ptr,               /* Database connection */
+- int count                /* Number of times table has been busy */
++  void *ptr,               /* Database connection */
++  int count,               /* Number of times table has been busy */
++  sqlite3_file *pFile      /* The file on which the lock occurred */
+ ){
+ #if SQLITE_OS_WIN || HAVE_USLEEP
++  /* This case is for systems that have support for sleeping for fractions of
++  ** a second.  Examples:  All windows systems, unix systems with usleep() */
+   static const u8 delays[] =
+      { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
+   static const u8 totals[] =
+@@ -143064,9 +154241,22 @@
+      { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
+ # define NDELAY ArraySize(delays)
+   sqlite3 *db = (sqlite3 *)ptr;
+-  int timeout = db->busyTimeout;
++  int tmout = db->busyTimeout;
+   int delay, prior;
+ 
++#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
++  if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
++    if( count ){
++      tmout = 0;
++      sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
++      return 0;
++    }else{
++      return 1;
++    }
++  }
++#else
++  UNUSED_PARAMETER(pFile);
++#endif
+   assert( count>=0 );
+   if( count < NDELAY ){
+     delay = delays[count];
+@@ -143075,16 +154265,19 @@
+     delay = delays[NDELAY-1];
+     prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
+   }
+-  if( prior + delay > timeout ){
+-    delay = timeout - prior;
++  if( prior + delay > tmout ){
++    delay = tmout - prior;
+     if( delay<=0 ) return 0;
+   }
+   sqlite3OsSleep(db->pVfs, delay*1000);
+   return 1;
+ #else
++  /* This case for unix systems that lack usleep() support.  Sleeping
++  ** must be done in increments of whole seconds */
+   sqlite3 *db = (sqlite3 *)ptr;
+-  int timeout = ((sqlite3 *)ptr)->busyTimeout;
+-  if( (count+1)*1000 > timeout ){
++  int tmout = ((sqlite3 *)ptr)->busyTimeout;
++  UNUSED_PARAMETER(pFile);
++  if( (count+1)*1000 > tmout ){
+     return 0;
+   }
+   sqlite3OsSleep(db->pVfs, 1000000);
+@@ -143095,14 +154288,25 @@
+ /*
+ ** Invoke the given busy handler.
+ **
+-** This routine is called when an operation failed with a lock.
++** This routine is called when an operation failed to acquire a
++** lock on VFS file pFile.
++**
+ ** If this routine returns non-zero, the lock is retried.  If it
+ ** returns 0, the operation aborts with an SQLITE_BUSY error.
+ */
+-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
++SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
+   int rc;
+-  if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
+-  rc = p->xFunc(p->pArg, p->nBusy);
++  if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
++  if( p->bExtraFileArg ){
++    /* Add an extra parameter with the pFile pointer to the end of the
++    ** callback argument list */
++    int (*xTra)(void*,int,sqlite3_file*);
++    xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
++    rc = xTra(p->pBusyArg, p->nBusy, pFile);
++  }else{
++    /* Legacy style busy handler callback */
++    rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
++  }
+   if( rc==0 ){
+     p->nBusy = -1;
+   }else{
+@@ -143124,9 +154328,10 @@
+   if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+-  db->busyHandler.xFunc = xBusy;
+-  db->busyHandler.pArg = pArg;
++  db->busyHandler.xBusyHandler = xBusy;
++  db->busyHandler.pBusyArg = pArg;
+   db->busyHandler.nBusy = 0;
++  db->busyHandler.bExtraFileArg = 0;
+   db->busyTimeout = 0;
+   sqlite3_mutex_leave(db->mutex);
+   return SQLITE_OK;
+@@ -143174,8 +154379,10 @@
+   if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+ #endif
+   if( ms>0 ){
+-    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
++    sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
++                             (void*)db);
+     db->busyTimeout = ms;
++    db->busyHandler.bExtraFileArg = 1;
+   }else{
+     sqlite3_busy_handler(db, 0, 0);
+   }
+@@ -143211,6 +154418,8 @@
+   void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+   void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
+   FuncDestructor *pDestructor
+ ){
+   FuncDef *p;
+@@ -143218,12 +154427,14 @@
+   int extraFlags;
+ 
+   assert( sqlite3_mutex_held(db->mutex) );
+-  if( zFunctionName==0 ||
+-      (xSFunc && (xFinal || xStep)) || 
+-      (!xSFunc && (xFinal && !xStep)) ||
+-      (!xSFunc && (!xFinal && xStep)) ||
+-      (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
+-      (255<(nName = sqlite3Strlen30( zFunctionName))) ){
++  assert( xValue==0 || xSFunc==0 );
++  if( zFunctionName==0                /* Must have a valid name */
++   || (xSFunc!=0 && xFinal!=0)        /* Not both xSFunc and xFinal */
++   || ((xFinal==0)!=(xStep==0))       /* Both or neither of xFinal and xStep */
++   || ((xValue==0)!=(xInverse==0))    /* Both or neither of xValue, xInverse */
++   || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
++   || (255<(nName = sqlite3Strlen30( zFunctionName)))
++  ){
+     return SQLITE_MISUSE_BKPT;
+   }
+ 
+@@ -143244,10 +154455,10 @@
+   }else if( enc==SQLITE_ANY ){
+     int rc;
+     rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
+-         pUserData, xSFunc, xStep, xFinal, pDestructor);
++         pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
+     if( rc==SQLITE_OK ){
+       rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
+-          pUserData, xSFunc, xStep, xFinal, pDestructor);
++          pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
+     }
+     if( rc!=SQLITE_OK ){
+       return rc;
+@@ -143264,7 +154475,7 @@
+   ** operation to continue but invalidate all precompiled statements.
+   */
+   p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
+-  if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
++  if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){
+     if( db->nVdbeActive ){
+       sqlite3ErrorWithMsg(db, SQLITE_BUSY, 
+         "unable to delete/modify user-function due to active statements");
+@@ -143271,7 +154482,7 @@
+       assert( !db->mallocFailed );
+       return SQLITE_BUSY;
+     }else{
+-      sqlite3ExpirePreparedStatements(db);
++      sqlite3ExpirePreparedStatements(db, 0);
+     }
+   }
+ 
+@@ -143293,6 +154504,8 @@
+   testcase( p->funcFlags & SQLITE_DETERMINISTIC );
+   p->xSFunc = xSFunc ? xSFunc : xStep;
+   p->xFinalize = xFinal;
++  p->xValue = xValue;
++  p->xInverse = xInverse;
+   p->pUserData = pUserData;
+   p->nArg = (u16)nArg;
+   return SQLITE_OK;
+@@ -143299,32 +154512,24 @@
+ }
+ 
+ /*
+-** Create new user functions.
++** Worker function used by utf-8 APIs that create new functions:
++**
++**    sqlite3_create_function()
++**    sqlite3_create_function_v2()
++**    sqlite3_create_window_function()
+ */
+-SQLITE_API int sqlite3_create_function(
++static int createFunctionApi(
+   sqlite3 *db,
+   const char *zFunc,
+   int nArg,
+   int enc,
+   void *p,
+-  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xFinal)(sqlite3_context*)
+-){
+-  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
+-                                    xFinal, 0);
+-}
+-
+-SQLITE_API int sqlite3_create_function_v2(
+-  sqlite3 *db,
+-  const char *zFunc,
+-  int nArg,
+-  int enc,
+-  void *p,
+-  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*),
+-  void (*xDestroy)(void *)
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
+ ){
+   int rc = SQLITE_ERROR;
+   FuncDestructor *pArg = 0;
+@@ -143336,19 +154541,23 @@
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+   if( xDestroy ){
+-    pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
++    pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor));
+     if( !pArg ){
++      sqlite3OomFault(db);
+       xDestroy(p);
+       goto out;
+     }
++    pArg->nRef = 0;
+     pArg->xDestroy = xDestroy;
+     pArg->pUserData = p;
+   }
+-  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
++  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, 
++      xSFunc, xStep, xFinal, xValue, xInverse, pArg
++  );
+   if( pArg && pArg->nRef==0 ){
+     assert( rc!=SQLITE_OK );
+     xDestroy(p);
+-    sqlite3DbFree(db, pArg);
++    sqlite3_free(pArg);
+   }
+ 
+  out:
+@@ -143357,6 +154566,52 @@
+   return rc;
+ }
+ 
++/*
++** Create new user functions.
++*/
++SQLITE_API int sqlite3_create_function(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
++                                    xFinal, 0, 0, 0);
++}
++SQLITE_API int sqlite3_create_function_v2(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*),
++  void (*xDestroy)(void *)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
++                                    xFinal, 0, 0, xDestroy);
++}
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
++  void (*xDestroy)(void *)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep,
++                                    xFinal, xValue, xInverse, xDestroy);
++}
++
+ #ifndef SQLITE_OMIT_UTF16
+ SQLITE_API int sqlite3_create_function16(
+   sqlite3 *db,
+@@ -143377,7 +154632,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   assert( !db->mallocFailed );
+   zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
+-  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
++  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0);
+   sqlite3DbFree(db, zFunc8);
+   rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+@@ -143387,6 +154642,28 @@
+ 
+ 
+ /*
++** The following is the implementation of an SQL function that always
++** fails with an error message stating that the function is used in the
++** wrong context.  The sqlite3_overload_function() API might construct
++** SQL function that use this routine so that the functions will exist
++** for name resolution but are actually overloaded by the xFindFunction
++** method of virtual tables.
++*/
++static void sqlite3InvalidFunction(
++  sqlite3_context *context,  /* The function calling context */
++  int NotUsed,               /* Number of arguments to the function */
++  sqlite3_value **NotUsed2   /* Value of each argument */
++){
++  const char *zName = (const char*)sqlite3_user_data(context);
++  char *zErr;
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  zErr = sqlite3_mprintf(
++      "unable to use function %s in the requested context", zName);
++  sqlite3_result_error(context, zErr, -1);
++  sqlite3_free(zErr);
++}
++
++/*
+ ** Declare that a function has been overloaded by a virtual table.
+ **
+ ** If the function already exists as a regular global function, then
+@@ -143403,7 +154680,8 @@
+   const char *zName,
+   int nArg
+ ){
+-  int rc = SQLITE_OK;
++  int rc;
++  char *zCopy;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
+@@ -143411,13 +154689,13 @@
+   }
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+-  if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
+-    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+-                           0, sqlite3InvalidFunction, 0, 0, 0);
+-  }
+-  rc = sqlite3ApiExit(db, rc);
++  rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
+   sqlite3_mutex_leave(db->mutex);
+-  return rc;
++  if( rc ) return SQLITE_OK;
++  zCopy = sqlite3_mprintf(zName);
++  if( zCopy==0 ) return SQLITE_NOMEM;
++  return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
++                           zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
+ }
+ 
+ #ifndef SQLITE_OMIT_TRACE
+@@ -143768,7 +155046,8 @@
+ ** checkpointed. If an error is encountered it is returned immediately -
+ ** no attempt is made to checkpoint any remaining databases.
+ **
+-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
++** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
++** or TRUNCATE.
+ */
+ SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
+   int rc = SQLITE_OK;             /* Return code */
+@@ -143978,7 +155257,7 @@
+         "unable to delete/modify collation sequence due to active statements");
+       return SQLITE_BUSY;
+     }
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+ 
+     /* If collation sequence pColl was created directly by a call to
+     ** sqlite3_create_collation, and not generated by synthCollSeq(),
+@@ -144414,6 +155693,7 @@
+   }else{
+     isThreadsafe = sqlite3GlobalConfig.bFullMutex;
+   }
++
+   if( flags & SQLITE_OPEN_PRIVATECACHE ){
+     flags &= ~SQLITE_OPEN_SHAREDCACHE;
+   }else if( sqlite3GlobalConfig.sharedCacheEnabled ){
+@@ -144446,7 +155726,11 @@
+   /* Allocate the sqlite data structure */
+   db = sqlite3MallocZero( sizeof(sqlite3) );
+   if( db==0 ) goto opendb_out;
+-  if( isThreadsafe ){
++  if( isThreadsafe 
++#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
++   || sqlite3GlobalConfig.bCoreMutex
++#endif
++  ){
+     db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
+     if( db->mutex==0 ){
+       sqlite3_free(db);
+@@ -144453,6 +155737,9 @@
+       db = 0;
+       goto opendb_out;
+     }
++    if( isThreadsafe==0 ){
++      sqlite3MutexWarnOnContention(db->mutex);
++    }
+   }
+   sqlite3_mutex_enter(db->mutex);
+   db->errMask = 0xff;
+@@ -144459,6 +155746,7 @@
+   db->nDb = 2;
+   db->magic = SQLITE_MAGIC_BUSY;
+   db->aDb = db->aDbStatic;
++  db->lookaside.bDisable = 1;
+ 
+   assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
+   memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
+@@ -144499,6 +155787,9 @@
+ #if defined(SQLITE_ENABLE_QPSG)
+                  | SQLITE_EnableQPSG
+ #endif
++#if defined(SQLITE_DEFAULT_DEFENSIVE)
++                 | SQLITE_Defensive
++#endif
+       ;
+   sqlite3HashInit(&db->aCollSeq);
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+@@ -144634,7 +155925,7 @@
+   }
+ #endif
+ 
+-#ifdef SQLITE_ENABLE_ICU
++#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+   if( !db->mallocFailed && rc==SQLITE_OK ){
+     rc = sqlite3IcuInit(db);
+   }
+@@ -144646,6 +155937,12 @@
+   }
+ #endif
+ 
++#ifdef SQLITE_ENABLE_DBPAGE_VTAB
++  if( !db->mallocFailed && rc==SQLITE_OK){
++    rc = sqlite3DbpageRegister(db);
++  }
++#endif
++
+ #ifdef SQLITE_ENABLE_DBSTAT_VTAB
+   if( !db->mallocFailed && rc==SQLITE_OK){
+     rc = sqlite3DbstatRegister(db);
+@@ -144930,7 +156227,7 @@
+ **   2.  Invoke sqlite3_log() to provide the source code location where
+ **       a low-level error is first detected.
+ */
+-static int reportError(int iErr, int lineno, const char *zType){
++SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){
+   sqlite3_log(iErr, "%s at line %d of [%.10s]",
+               zType, lineno, 20+sqlite3_sourceid());
+   return iErr;
+@@ -144937,15 +156234,15 @@
+ }
+ SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_CORRUPT, lineno, "database corruption");
++  return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption");
+ }
+ SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_MISUSE, lineno, "misuse");
++  return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
+ }
+ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
++  return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
+ }
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
+@@ -144952,15 +156249,15 @@
+   char zMsg[100];
+   sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_CORRUPT, lineno, zMsg);
++  return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
+ }
+ SQLITE_PRIVATE int sqlite3NomemError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_NOMEM, lineno, "OOM");
++  return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
+ }
+ SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
+   testcase( sqlite3GlobalConfig.xLog!=0 );
+-  return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
++  return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+ }
+ #endif
+ 
+@@ -145153,10 +156450,11 @@
+     }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
+       *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
+       rc = SQLITE_OK;
+-    }else if( fd->pMethods ){
++    }else if( op==SQLITE_FCNTL_DATA_VERSION ){
++      *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
++      rc = SQLITE_OK;
++    }else{
+       rc = sqlite3OsFileControl(fd, op, pArg);
+-    }else{
+-      rc = SQLITE_NOTFOUND;
+     }
+     sqlite3BtreeLeave(pBtree);
+   }
+@@ -145305,7 +156603,7 @@
+     ** This action provides a run-time test to see how the ALWAYS and
+     ** NEVER macros were defined at compile-time.
+     **
+-    ** The return value is ALWAYS(X).  
++    ** The return value is ALWAYS(X) if X is true, or 0 if X is false.
+     **
+     ** The recommended test is X==2.  If the return value is 2, that means
+     ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
+@@ -145328,7 +156626,7 @@
+     */
+     case SQLITE_TESTCTRL_ALWAYS: {
+       int x = va_arg(ap,int);
+-      rc = ALWAYS(x);
++      rc = x ? ALWAYS(x) : 0;
+       break;
+     }
+ 
+@@ -145377,51 +156675,28 @@
+       break;
+     }
+ 
+-#ifdef SQLITE_N_KEYWORD
+-    /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
++    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
+     **
+-    ** If zWord is a keyword recognized by the parser, then return the
+-    ** number of keywords.  Or if zWord is not a keyword, return 0.
+-    ** 
+-    ** This test feature is only available in the amalgamation since
+-    ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
+-    ** is built using separate source files.
++    ** If parameter onoff is non-zero, subsequent calls to localtime()
++    ** and its variants fail. If onoff is zero, undo this setting.
+     */
+-    case SQLITE_TESTCTRL_ISKEYWORD: {
+-      const char *zWord = va_arg(ap, const char*);
+-      int n = sqlite3Strlen30(zWord);
+-      rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
++    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
++      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
+       break;
+     }
+-#endif 
+ 
+-    /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
++    /*   sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
+     **
+-    ** Pass pFree into sqlite3ScratchFree(). 
+-    ** If sz>0 then allocate a scratch buffer into pNew.  
++    ** If parameter onoff is non-zero, internal-use-only SQL functions
++    ** are visible to ordinary SQL.  This is useful for testing but is
++    ** unsafe because invalid parameters to those internal-use-only functions
++    ** can result in crashes or segfaults.
+     */
+-    case SQLITE_TESTCTRL_SCRATCHMALLOC: {
+-      void *pFree, **ppNew;
+-      int sz;
+-      sz = va_arg(ap, int);
+-      ppNew = va_arg(ap, void**);
+-      pFree = va_arg(ap, void*);
+-      if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
+-      sqlite3ScratchFree(pFree);
++    case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
++      sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
+       break;
+     }
+ 
+-    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
+-    **
+-    ** If parameter onoff is non-zero, configure the wrappers so that all
+-    ** subsequent calls to localtime() and variants fail. If onoff is zero,
+-    ** undo this setting.
+-    */
+-    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
+-      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
+-      break;
+-    }
+-
+     /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
+     **
+     ** Set or clear a flag that indicates that the database file is always well-
+@@ -145452,7 +156727,8 @@
+     */
+     case SQLITE_TESTCTRL_VDBE_COVERAGE: {
+ #ifdef SQLITE_VDBE_COVERAGE
+-      typedef void (*branch_callback)(void*,int,u8,u8);
++      typedef void (*branch_callback)(void*,unsigned int,
++                                      unsigned char,unsigned char);
+       sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
+       sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
+ #endif
+@@ -145504,6 +156780,22 @@
+       sqlite3_mutex_leave(db->mutex);
+       break;
+     }
++
++#if defined(YYCOVERAGE)
++    /*  sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out)
++    **
++    ** This test control (only available when SQLite is compiled with
++    ** -DYYCOVERAGE) writes a report onto "out" that shows all
++    ** state/lookahead combinations in the parser state machine
++    ** which are never exercised.  If any state is missed, make the
++    ** return code SQLITE_ERROR.
++    */
++    case SQLITE_TESTCTRL_PARSER_COVERAGE: {
++      FILE *out = va_arg(ap, FILE*);
++      if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
++      break;
++    }
++#endif /* defined(YYCOVERAGE) */
+   }
+   va_end(ap);
+ #endif /* SQLITE_UNTESTABLE */
+@@ -145552,7 +156844,7 @@
+ ){
+   const char *z = sqlite3_uri_parameter(zFilename, zParam);
+   sqlite3_int64 v;
+-  if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
++  if( z && sqlite3DecOrHexToI64(z, &v)==0 ){
+     bDflt = v;
+   }
+   return bDflt;
+@@ -145623,7 +156915,7 @@
+     if( iDb==0 || iDb>1 ){
+       Btree *pBt = db->aDb[iDb].pBt;
+       if( 0==sqlite3BtreeIsInTrans(pBt) ){
+-        rc = sqlite3BtreeBeginTrans(pBt, 0);
++        rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+         if( rc==SQLITE_OK ){
+           rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+         }
+@@ -145658,12 +156950,30 @@
+     iDb = sqlite3FindDbName(db, zDb);
+     if( iDb==0 || iDb>1 ){
+       Btree *pBt = db->aDb[iDb].pBt;
+-      if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+-        rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
++      if( sqlite3BtreeIsInTrans(pBt)==0 ){
++        Pager *pPager = sqlite3BtreePager(pBt);
++        int bUnlock = 0;
++        if( sqlite3BtreeIsInReadTrans(pBt) ){
++          if( db->nVdbeActive==0 ){
++            rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
++            if( rc==SQLITE_OK ){
++              bUnlock = 1;
++              rc = sqlite3BtreeCommit(pBt);
++            }
++          }
++        }else{
++          rc = SQLITE_OK;
++        }
+         if( rc==SQLITE_OK ){
+-          rc = sqlite3BtreeBeginTrans(pBt, 0);
+-          sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
++          rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot);
+         }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
++          sqlite3PagerSnapshotOpen(pPager, 0);
++        }
++        if( bUnlock ){
++          sqlite3PagerSnapshotUnlock(pPager);
++        }
+       }
+     }
+   }
+@@ -145693,7 +157003,7 @@
+   if( iDb==0 || iDb>1 ){
+     Btree *pBt = db->aDb[iDb].pBt;
+     if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+-      rc = sqlite3BtreeBeginTrans(pBt, 0);
++      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+       if( rc==SQLITE_OK ){
+         rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
+         sqlite3BtreeCommit(pBt);
+@@ -147261,7 +158571,7 @@
+ );
+ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
+ #ifdef SQLITE_TEST
+-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
++SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
+ SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
+ #endif
+ 
+@@ -148829,7 +160139,7 @@
+   const char *zCsr = zNode;       /* Cursor to iterate through node */
+   const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
+   char *zBuffer = 0;              /* Buffer to load terms into */
+-  int nAlloc = 0;                 /* Size of allocated buffer */
++  i64 nAlloc = 0;                 /* Size of allocated buffer */
+   int isFirstTerm = 1;            /* True when processing first term on page */
+   sqlite3_int64 iChild;           /* Block id of child node to descend to */
+ 
+@@ -148867,14 +160177,14 @@
+     zCsr += fts3GetVarint32(zCsr, &nSuffix);
+     
+     assert( nPrefix>=0 && nSuffix>=0 );
+-    if( &zCsr[nSuffix]>zEnd ){
++    if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
+       rc = FTS_CORRUPT_VTAB;
+       goto finish_scan;
+     }
+-    if( nPrefix+nSuffix>nAlloc ){
++    if( (i64)nPrefix+nSuffix>nAlloc ){
+       char *zNew;
+-      nAlloc = (nPrefix+nSuffix) * 2;
+-      zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
++      nAlloc = ((i64)nPrefix+nSuffix) * 2;
++      zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
+       if( !zNew ){
+         rc = SQLITE_NOMEM;
+         goto finish_scan;
+@@ -150816,7 +162126,7 @@
+   int rc = SQLITE_OK;
+   UNUSED_PARAMETER(iSavepoint);
+   assert( ((Fts3Table *)pVtab)->inTransaction );
+-  assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint );
++  assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint );
+   TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint );
+   if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){
+     rc = fts3SyncMethod(pVtab);
+@@ -150854,8 +162164,23 @@
+   return SQLITE_OK;
+ }
+ 
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int fts3ShadowName(const char *zName){
++  static const char *azName[] = {
++    "content", "docsize", "segdir", "segments", "stat", 
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static const sqlite3_module fts3Module = {
+-  /* iVersion      */ 2,
++  /* iVersion      */ 3,
+   /* xCreate       */ fts3CreateMethod,
+   /* xConnect      */ fts3ConnectMethod,
+   /* xBestIndex    */ fts3BestIndexMethod,
+@@ -150878,6 +162203,7 @@
+   /* xSavepoint    */ fts3SavepointMethod,
+   /* xRelease      */ fts3ReleaseMethod,
+   /* xRollbackTo   */ fts3RollbackToMethod,
++  /* xShadowName   */ fts3ShadowName,
+ };
+ 
+ /*
+@@ -150971,7 +162297,7 @@
+ 
+ #ifdef SQLITE_TEST
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3Fts3ExprInitTestInterface(db);
++    rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
+   }
+ #endif
+ 
+@@ -151158,6 +162484,7 @@
+   return rc;
+ }
+ 
++#ifndef SQLITE_DISABLE_FTS4_DEFERRED
+ /*
+ ** This function is called on each phrase after the position lists for
+ ** any deferred tokens have been loaded into memory. It updates the phrases
+@@ -151261,6 +162588,7 @@
+ 
+   return SQLITE_OK;
+ }
++#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
+ 
+ /*
+ ** Maximum number of tokens a phrase may have to be considered for the
+@@ -153509,7 +164837,8 @@
+      0,                           /* xRename       */
+      0,                           /* xSavepoint    */
+      0,                           /* xRelease      */
+-     0                            /* xRollbackTo   */
++     0,                           /* xRollbackTo   */
++     0                            /* xShadowName   */
+   };
+   int rc;                         /* Return code */
+ 
+@@ -154632,34 +165961,6 @@
+ /* #include <stdio.h> */
+ 
+ /*
+-** Function to query the hash-table of tokenizers (see README.tokenizers).
+-*/
+-static int queryTestTokenizer(
+-  sqlite3 *db, 
+-  const char *zName,  
+-  const sqlite3_tokenizer_module **pp
+-){
+-  int rc;
+-  sqlite3_stmt *pStmt;
+-  const char zSql[] = "SELECT fts3_tokenizer(?)";
+-
+-  *pp = 0;
+-  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+-  if( rc!=SQLITE_OK ){
+-    return rc;
+-  }
+-
+-  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
+-  if( SQLITE_ROW==sqlite3_step(pStmt) ){
+-    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
+-      memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
+-    }
+-  }
+-
+-  return sqlite3_finalize(pStmt);
+-}
+-
+-/*
+ ** Return a pointer to a buffer containing a text representation of the
+ ** expression passed as the first argument. The buffer is obtained from
+ ** sqlite3_malloc(). It is the responsibility of the caller to use 
+@@ -154726,12 +166027,12 @@
+ **
+ **   SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
+ */
+-static void fts3ExprTest(
++static void fts3ExprTestCommon(
++  int bRebalance,
+   sqlite3_context *context,
+   int argc,
+   sqlite3_value **argv
+ ){
+-  sqlite3_tokenizer_module const *pModule = 0;
+   sqlite3_tokenizer *pTokenizer = 0;
+   int rc;
+   char **azCol = 0;
+@@ -154741,7 +166042,9 @@
+   int ii;
+   Fts3Expr *pExpr;
+   char *zBuf = 0;
+-  sqlite3 *db = sqlite3_context_db_handle(context);
++  Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
++  const char *zTokenizer = 0;
++  char *zErr = 0;
+ 
+   if( argc<3 ){
+     sqlite3_result_error(context, 
+@@ -154750,24 +166053,18 @@
+     return;
+   }
+ 
+-  rc = queryTestTokenizer(db,
+-                          (const char *)sqlite3_value_text(argv[0]), &pModule);
+-  if( rc==SQLITE_NOMEM ){
+-    sqlite3_result_error_nomem(context);
+-    goto exprtest_out;
+-  }else if( !pModule ){
+-    sqlite3_result_error(context, "No such tokenizer module", -1);
+-    goto exprtest_out;
++  zTokenizer = (const char*)sqlite3_value_text(argv[0]);
++  rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
++  if( rc!=SQLITE_OK ){
++    if( rc==SQLITE_NOMEM ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_error(context, zErr, -1);
++    }
++    sqlite3_free(zErr);
++    return;
+   }
+ 
+-  rc = pModule->xCreate(0, 0, &pTokenizer);
+-  assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
+-  if( rc==SQLITE_NOMEM ){
+-    sqlite3_result_error_nomem(context);
+-    goto exprtest_out;
+-  }
+-  pTokenizer->pModule = pModule;
+-
+   zExpr = (const char *)sqlite3_value_text(argv[1]);
+   nExpr = sqlite3_value_bytes(argv[1]);
+   nCol = argc-2;
+@@ -154780,7 +166077,7 @@
+     azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
+   }
+ 
+-  if( sqlite3_user_data(context) ){
++  if( bRebalance ){
+     char *zDummy = 0;
+     rc = sqlite3Fts3ExprParse(
+         pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
+@@ -154806,23 +166103,38 @@
+   sqlite3Fts3ExprFree(pExpr);
+ 
+ exprtest_out:
+-  if( pModule && pTokenizer ){
+-    rc = pModule->xDestroy(pTokenizer);
++  if( pTokenizer ){
++    rc = pTokenizer->pModule->xDestroy(pTokenizer);
+   }
+   sqlite3_free(azCol);
+ }
+ 
++static void fts3ExprTest(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  fts3ExprTestCommon(0, context, argc, argv);
++}
++static void fts3ExprTestRebalance(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  fts3ExprTestCommon(1, context, argc, argv);
++}
++
+ /*
+ ** Register the query expression parser test function fts3_exprtest() 
+ ** with database connection db. 
+ */
+-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
++SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
+   int rc = sqlite3_create_function(
+-      db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
++      db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
+   );
+   if( rc==SQLITE_OK ){
+     rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", 
+-        -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
++        -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
+     );
+   }
+   return rc;
+@@ -157085,7 +168397,8 @@
+      0,                           /* xRename       */
+      0,                           /* xSavepoint    */
+      0,                           /* xRelease      */
+-     0                            /* xRollbackTo   */
++     0,                           /* xRollbackTo   */
++     0                            /* xShadowName   */
+   };
+   int rc;                         /* Return code */
+ 
+@@ -158473,15 +169786,19 @@
+   ** safe (no risk of overread) even if the node data is corrupted. */
+   pNext += fts3GetVarint32(pNext, &nPrefix);
+   pNext += fts3GetVarint32(pNext, &nSuffix);
+-  if( nPrefix<0 || nSuffix<=0 
+-   || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] 
++  if( nSuffix<=0 
++   || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
++   || nPrefix>pReader->nTermAlloc
+   ){
+     return FTS_CORRUPT_VTAB;
+   }
+ 
+-  if( nPrefix+nSuffix>pReader->nTermAlloc ){
+-    int nNew = (nPrefix+nSuffix)*2;
+-    char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
++  /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
++  ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
++  ** overflow - hence the (i64) casts.  */
++  if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
++    i64 nNew = ((i64)nPrefix+nSuffix)*2;
++    char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
+     if( !zNew ){
+       return SQLITE_NOMEM;
+     }
+@@ -158503,7 +169820,7 @@
+   ** b-tree node. And that the final byte of the doclist is 0x00. If either 
+   ** of these statements is untrue, then the data structure is corrupt.
+   */
+-  if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] 
++  if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
+    || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
+   ){
+     return FTS_CORRUPT_VTAB;
+@@ -159007,6 +170324,7 @@
+     sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
+     sqlite3_step(pStmt);
+     rc = sqlite3_reset(pStmt);
++    sqlite3_bind_null(pStmt, 2);
+   }
+   return rc;
+ }
+@@ -159063,6 +170381,7 @@
+     sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
+     sqlite3_step(pStmt);
+     rc = sqlite3_reset(pStmt);
++    sqlite3_bind_null(pStmt, 6);
+   }
+   return rc;
+ }
+@@ -160542,6 +171861,7 @@
+   sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC);
+   sqlite3_step(pStmt);
+   *pRC = sqlite3_reset(pStmt);
++  sqlite3_bind_null(pStmt, 2);
+   sqlite3_free(a);
+ }
+ 
+@@ -160826,6 +172146,9 @@
+     }
+     p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ 
++    if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
++      return SQLITE_CORRUPT_VTAB;
++    }
+     blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
+     if( rc==SQLITE_OK ){
+       memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
+@@ -160833,6 +172156,9 @@
+       p->iOff += nSuffix;
+       if( p->iChild==0 ){
+         p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
++        if( (p->nNode-p->iOff)<p->nDoclist ){
++          return SQLITE_CORRUPT_VTAB;
++        }
+         p->aDoclist = &p->aNode[p->iOff];
+         p->iOff += p->nDoclist;
+       }
+@@ -160840,7 +172166,6 @@
+   }
+ 
+   assert( p->iOff<=p->nNode );
+-
+   return rc;
+ }
+ 
+@@ -161730,6 +173055,7 @@
+       sqlite3_bind_int(pChomp, 4, iIdx);
+       sqlite3_step(pChomp);
+       rc = sqlite3_reset(pChomp);
++      sqlite3_bind_null(pChomp, 2);
+     }
+   }
+ 
+@@ -161809,6 +173135,7 @@
+     sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC);
+     sqlite3_step(pReplace);
+     rc = sqlite3_reset(pReplace);
++    sqlite3_bind_null(pReplace, 2);
+   }
+ 
+   return rc;
+@@ -162623,7 +173950,6 @@
+ ){
+   Fts3Table *p = (Fts3Table *)pVtab;
+   int rc = SQLITE_OK;             /* Return Code */
+-  int isRemove = 0;               /* True for an UPDATE or DELETE */
+   u32 *aSzIns = 0;                /* Sizes of inserted documents */
+   u32 *aSzDel = 0;                /* Sizes of deleted documents */
+   int nChng = 0;                  /* Net change in number of documents */
+@@ -162721,7 +174047,6 @@
+   if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
+     assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
+     rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
+-    isRemove = 1;
+   }
+   
+   /* If this is an INSERT or UPDATE operation, insert the new record. */
+@@ -162733,7 +174058,7 @@
+         rc = FTS_CORRUPT_VTAB;
+       }
+     }
+-    if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
++    if( rc==SQLITE_OK ){
+       rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
+     }
+     if( rc==SQLITE_OK ){
+@@ -165253,6 +176578,2550 @@
+ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
+ 
+ /************** End of fts3_unicode2.c ***************************************/
++/************** Begin file json1.c *******************************************/
++/*
++** 2015-08-12
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This SQLite extension implements JSON functions.  The interface is
++** modeled after MySQL JSON functions:
++**
++**     https://dev.mysql.com/doc/refman/5.7/en/json.html
++**
++** For the time being, all JSON is stored as pure text.  (We might add
++** a JSONB type in the future which stores a binary encoding of JSON in
++** a BLOB, but there is no support for JSONB in the current implementation.
++** This implementation parses JSON text at 250 MB/s, so it is hard to see
++** how JSONB might improve on that.)
++*/
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
++#if !defined(SQLITEINT_H)
++/* #include "sqlite3ext.h" */
++#endif
++SQLITE_EXTENSION_INIT1
++/* #include <assert.h> */
++/* #include <string.h> */
++/* #include <stdlib.h> */
++/* #include <stdarg.h> */
++
++/* Mark a function parameter as unused, to suppress nuisance compiler
++** warnings. */
++#ifndef UNUSED_PARAM
++# define UNUSED_PARAM(X)  (void)(X)
++#endif
++
++#ifndef LARGEST_INT64
++# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
++# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
++#endif
++
++/*
++** Versions of isspace(), isalnum() and isdigit() to which it is safe
++** to pass signed char values.
++*/
++#ifdef sqlite3Isdigit
++   /* Use the SQLite core versions if this routine is part of the
++   ** SQLite amalgamation */
++#  define safe_isdigit(x)  sqlite3Isdigit(x)
++#  define safe_isalnum(x)  sqlite3Isalnum(x)
++#  define safe_isxdigit(x) sqlite3Isxdigit(x)
++#else
++   /* Use the standard library for separate compilation */
++#include <ctype.h>  /* amalgamator: keep */
++#  define safe_isdigit(x)  isdigit((unsigned char)(x))
++#  define safe_isalnum(x)  isalnum((unsigned char)(x))
++#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
++#endif
++
++/*
++** Growing our own isspace() routine this way is twice as fast as
++** the library isspace() function, resulting in a 7% overall performance
++** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
++*/
++static const char jsonIsSpace[] = {
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++};
++#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
++
++#ifndef SQLITE_AMALGAMATION
++  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
++  ** but the definitions need to be repeated for separate compilation. */
++  typedef sqlite3_uint64 u64;
++  typedef unsigned int u32;
++  typedef unsigned short int u16;
++  typedef unsigned char u8;
++#endif
++
++/* Objects */
++typedef struct JsonString JsonString;
++typedef struct JsonNode JsonNode;
++typedef struct JsonParse JsonParse;
++
++/* An instance of this object represents a JSON string
++** under construction.  Really, this is a generic string accumulator
++** that can be and is used to create strings other than JSON.
++*/
++struct JsonString {
++  sqlite3_context *pCtx;   /* Function context - put error messages here */
++  char *zBuf;              /* Append JSON content here */
++  u64 nAlloc;              /* Bytes of storage available in zBuf[] */
++  u64 nUsed;               /* Bytes of zBuf[] currently used */
++  u8 bStatic;              /* True if zBuf is static space */
++  u8 bErr;                 /* True if an error has been encountered */
++  char zSpace[100];        /* Initial static space */
++};
++
++/* JSON type values
++*/
++#define JSON_NULL     0
++#define JSON_TRUE     1
++#define JSON_FALSE    2
++#define JSON_INT      3
++#define JSON_REAL     4
++#define JSON_STRING   5
++#define JSON_ARRAY    6
++#define JSON_OBJECT   7
++
++/* The "subtype" set for JSON values */
++#define JSON_SUBTYPE  74    /* Ascii for "J" */
++
++/*
++** Names of the various JSON types:
++*/
++static const char * const jsonType[] = {
++  "null", "true", "false", "integer", "real", "text", "array", "object"
++};
++
++/* Bit values for the JsonNode.jnFlag field
++*/
++#define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
++#define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
++#define JNODE_REMOVE  0x04         /* Do not output */
++#define JNODE_REPLACE 0x08         /* Replace with JsonNode.u.iReplace */
++#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
++#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
++#define JNODE_LABEL   0x40         /* Is a label of an object */
++
++
++/* A single node of parsed JSON
++*/
++struct JsonNode {
++  u8 eType;              /* One of the JSON_ type values */
++  u8 jnFlags;            /* JNODE flags */
++  u32 n;                 /* Bytes of content, or number of sub-nodes */
++  union {
++    const char *zJContent; /* Content for INT, REAL, and STRING */
++    u32 iAppend;           /* More terms for ARRAY and OBJECT */
++    u32 iKey;              /* Key for ARRAY objects in json_tree() */
++    u32 iReplace;          /* Replacement content for JNODE_REPLACE */
++    JsonNode *pPatch;      /* Node chain of patch for JNODE_PATCH */
++  } u;
++};
++
++/* A completely parsed JSON string
++*/
++struct JsonParse {
++  u32 nNode;         /* Number of slots of aNode[] used */
++  u32 nAlloc;        /* Number of slots of aNode[] allocated */
++  JsonNode *aNode;   /* Array of nodes containing the parse */
++  const char *zJson; /* Original JSON string */
++  u32 *aUp;          /* Index of parent of each node */
++  u8 oom;            /* Set to true if out of memory */
++  u8 nErr;           /* Number of errors seen */
++  u16 iDepth;        /* Nesting depth */
++  int nJson;         /* Length of the zJson string in bytes */
++  u32 iHold;         /* Replace cache line with the lowest iHold value */
++};
++
++/*
++** Maximum nesting depth of JSON for this implementation.
++**
++** This limit is needed to avoid a stack overflow in the recursive
++** descent parser.  A depth of 2000 is far deeper than any sane JSON
++** should go.
++*/
++#define JSON_MAX_DEPTH  2000
++
++/**************************************************************************
++** Utility routines for dealing with JsonString objects
++**************************************************************************/
++
++/* Set the JsonString object to an empty string
++*/
++static void jsonZero(JsonString *p){
++  p->zBuf = p->zSpace;
++  p->nAlloc = sizeof(p->zSpace);
++  p->nUsed = 0;
++  p->bStatic = 1;
++}
++
++/* Initialize the JsonString object
++*/
++static void jsonInit(JsonString *p, sqlite3_context *pCtx){
++  p->pCtx = pCtx;
++  p->bErr = 0;
++  jsonZero(p);
++}
++
++
++/* Free all allocated memory and reset the JsonString object back to its
++** initial state.
++*/
++static void jsonReset(JsonString *p){
++  if( !p->bStatic ) sqlite3_free(p->zBuf);
++  jsonZero(p);
++}
++
++
++/* Report an out-of-memory (OOM) condition 
++*/
++static void jsonOom(JsonString *p){
++  p->bErr = 1;
++  sqlite3_result_error_nomem(p->pCtx);
++  jsonReset(p);
++}
++
++/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
++** Return zero on success.  Return non-zero on an OOM error
++*/
++static int jsonGrow(JsonString *p, u32 N){
++  u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
++  char *zNew;
++  if( p->bStatic ){
++    if( p->bErr ) return 1;
++    zNew = sqlite3_malloc64(nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    memcpy(zNew, p->zBuf, (size_t)p->nUsed);
++    p->zBuf = zNew;
++    p->bStatic = 0;
++  }else{
++    zNew = sqlite3_realloc64(p->zBuf, nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    p->zBuf = zNew;
++  }
++  p->nAlloc = nTotal;
++  return SQLITE_OK;
++}
++
++/* Append N bytes from zIn onto the end of the JsonString string.
++*/
++static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
++  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
++  memcpy(p->zBuf+p->nUsed, zIn, N);
++  p->nUsed += N;
++}
++
++/* Append formatted text (not to exceed N bytes) to the JsonString.
++*/
++static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
++  va_list ap;
++  if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
++  va_start(ap, zFormat);
++  sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
++  va_end(ap);
++  p->nUsed += (int)strlen(p->zBuf+p->nUsed);
++}
++
++/* Append a single character
++*/
++static void jsonAppendChar(JsonString *p, char c){
++  if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
++  p->zBuf[p->nUsed++] = c;
++}
++
++/* Append a comma separator to the output buffer, if the previous
++** character is not '[' or '{'.
++*/
++static void jsonAppendSeparator(JsonString *p){
++  char c;
++  if( p->nUsed==0 ) return;
++  c = p->zBuf[p->nUsed-1];
++  if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
++}
++
++/* Append the N-byte string in zIn to the end of the JsonString string
++** under construction.  Enclose the string in "..." and escape
++** any double-quotes or backslash characters contained within the
++** string.
++*/
++static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
++  u32 i;
++  if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
++  p->zBuf[p->nUsed++] = '"';
++  for(i=0; i<N; i++){
++    unsigned char c = ((unsigned const char*)zIn)[i];
++    if( c=='"' || c=='\\' ){
++      json_simple_escape:
++      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++    }else if( c<=0x1f ){
++      static const char aSpecial[] = {
++         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
++         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
++      };
++      assert( sizeof(aSpecial)==32 );
++      assert( aSpecial['\b']=='b' );
++      assert( aSpecial['\f']=='f' );
++      assert( aSpecial['\n']=='n' );
++      assert( aSpecial['\r']=='r' );
++      assert( aSpecial['\t']=='t' );
++      if( aSpecial[c] ){
++        c = aSpecial[c];
++        goto json_simple_escape;
++      }
++      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++      p->zBuf[p->nUsed++] = 'u';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0' + (c>>4);
++      c = "0123456789abcdef"[c&0xf];
++    }
++    p->zBuf[p->nUsed++] = c;
++  }
++  p->zBuf[p->nUsed++] = '"';
++  assert( p->nUsed<p->nAlloc );
++}
++
++/*
++** Append a function parameter value to the JSON string under 
++** construction.
++*/
++static void jsonAppendValue(
++  JsonString *p,                 /* Append to this JSON string */
++  sqlite3_value *pValue          /* Value to append */
++){
++  switch( sqlite3_value_type(pValue) ){
++    case SQLITE_NULL: {
++      jsonAppendRaw(p, "null", 4);
++      break;
++    }
++    case SQLITE_INTEGER:
++    case SQLITE_FLOAT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      jsonAppendRaw(p, z, n);
++      break;
++    }
++    case SQLITE_TEXT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
++        jsonAppendRaw(p, z, n);
++      }else{
++        jsonAppendString(p, z, n);
++      }
++      break;
++    }
++    default: {
++      if( p->bErr==0 ){
++        sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
++        p->bErr = 2;
++        jsonReset(p);
++      }
++      break;
++    }
++  }
++}
++
++
++/* Make the JSON in p the result of the SQL function.
++*/
++static void jsonResult(JsonString *p){
++  if( p->bErr==0 ){
++    sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, 
++                          p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
++                          SQLITE_UTF8);
++    jsonZero(p);
++  }
++  assert( p->bStatic );
++}
++
++/**************************************************************************
++** Utility routines for dealing with JsonNode and JsonParse objects
++**************************************************************************/
++
++/*
++** Return the number of consecutive JsonNode slots need to represent
++** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
++** OBJECT types, the number might be larger.
++**
++** Appended elements are not counted.  The value returned is the number
++** by which the JsonNode counter should increment in order to go to the
++** next peer value.
++*/
++static u32 jsonNodeSize(JsonNode *pNode){
++  return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
++}
++
++/*
++** Reclaim all memory allocated by a JsonParse object.  But do not
++** delete the JsonParse object itself.
++*/
++static void jsonParseReset(JsonParse *pParse){
++  sqlite3_free(pParse->aNode);
++  pParse->aNode = 0;
++  pParse->nNode = 0;
++  pParse->nAlloc = 0;
++  sqlite3_free(pParse->aUp);
++  pParse->aUp = 0;
++}
++
++/*
++** Free a JsonParse object that was obtained from sqlite3_malloc().
++*/
++static void jsonParseFree(JsonParse *pParse){
++  jsonParseReset(pParse);
++  sqlite3_free(pParse);
++}
++
++/*
++** Convert the JsonNode pNode into a pure JSON string and
++** append to pOut.  Subsubstructure is also included.  Return
++** the number of JsonNode objects that are encoded.
++*/
++static void jsonRenderNode(
++  JsonNode *pNode,               /* The node to render */
++  JsonString *pOut,              /* Write JSON here */
++  sqlite3_value **aReplace       /* Replacement values */
++){
++  if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
++    if( pNode->jnFlags & JNODE_REPLACE ){
++      jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
++      return;
++    }
++    pNode = pNode->u.pPatch;
++  }
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      jsonAppendRaw(pOut, "null", 4);
++      break;
++    }
++    case JSON_TRUE: {
++      jsonAppendRaw(pOut, "true", 4);
++      break;
++    }
++    case JSON_FALSE: {
++      jsonAppendRaw(pOut, "false", 5);
++      break;
++    }
++    case JSON_STRING: {
++      if( pNode->jnFlags & JNODE_RAW ){
++        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
++        break;
++      }
++      /* Fall through into the next case */
++    }
++    case JSON_REAL:
++    case JSON_INT: {
++      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
++      break;
++    }
++    case JSON_ARRAY: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '[');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++          }
++          j += jsonNodeSize(&pNode[j]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, ']');
++      break;
++    }
++    case JSON_OBJECT: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '{');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++            jsonAppendChar(pOut, ':');
++            jsonRenderNode(&pNode[j+1], pOut, aReplace);
++          }
++          j += 1 + jsonNodeSize(&pNode[j+1]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, '}');
++      break;
++    }
++  }
++}
++
++/*
++** Return a JsonNode and all its descendents as a JSON string.
++*/
++static void jsonReturnJson(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  JsonString s;
++  jsonInit(&s, pCtx);
++  jsonRenderNode(pNode, &s, aReplace);
++  jsonResult(&s);
++  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
++}
++
++/*
++** Make the JsonNode the return value of the function.
++*/
++static void jsonReturn(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      sqlite3_result_null(pCtx);
++      break;
++    }
++    case JSON_TRUE: {
++      sqlite3_result_int(pCtx, 1);
++      break;
++    }
++    case JSON_FALSE: {
++      sqlite3_result_int(pCtx, 0);
++      break;
++    }
++    case JSON_INT: {
++      sqlite3_int64 i = 0;
++      const char *z = pNode->u.zJContent;
++      if( z[0]=='-' ){ z++; }
++      while( z[0]>='0' && z[0]<='9' ){
++        unsigned v = *(z++) - '0';
++        if( i>=LARGEST_INT64/10 ){
++          if( i>LARGEST_INT64/10 ) goto int_as_real;
++          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
++          if( v==9 ) goto int_as_real;
++          if( v==8 ){
++            if( pNode->u.zJContent[0]=='-' ){
++              sqlite3_result_int64(pCtx, SMALLEST_INT64);
++              goto int_done;
++            }else{
++              goto int_as_real;
++            }
++          }
++        }
++        i = i*10 + v;
++      }
++      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
++      sqlite3_result_int64(pCtx, i);
++      int_done:
++      break;
++      int_as_real: /* fall through to real */;
++    }
++    case JSON_REAL: {
++      double r;
++#ifdef SQLITE_AMALGAMATION
++      const char *z = pNode->u.zJContent;
++      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
++#else
++      r = strtod(pNode->u.zJContent, 0);
++#endif
++      sqlite3_result_double(pCtx, r);
++      break;
++    }
++    case JSON_STRING: {
++#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
++      ** json_insert() and json_replace() and those routines do not
++      ** call jsonReturn() */
++      if( pNode->jnFlags & JNODE_RAW ){
++        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
++                            SQLITE_TRANSIENT);
++      }else 
++#endif
++      assert( (pNode->jnFlags & JNODE_RAW)==0 );
++      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
++        /* JSON formatted without any backslash-escapes */
++        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
++                            SQLITE_TRANSIENT);
++      }else{
++        /* Translate JSON formatted string into raw text */
++        u32 i;
++        u32 n = pNode->n;
++        const char *z = pNode->u.zJContent;
++        char *zOut;
++        u32 j;
++        zOut = sqlite3_malloc( n+1 );
++        if( zOut==0 ){
++          sqlite3_result_error_nomem(pCtx);
++          break;
++        }
++        for(i=1, j=0; i<n-1; i++){
++          char c = z[i];
++          if( c!='\\' ){
++            zOut[j++] = c;
++          }else{
++            c = z[++i];
++            if( c=='u' ){
++              u32 v = 0, k;
++              for(k=0; k<4; i++, k++){
++                assert( i<n-2 );
++                c = z[i+1];
++                assert( safe_isxdigit(c) );
++                if( c<='9' ) v = v*16 + c - '0';
++                else if( c<='F' ) v = v*16 + c - 'A' + 10;
++                else v = v*16 + c - 'a' + 10;
++              }
++              if( v==0 ) break;
++              if( v<=0x7f ){
++                zOut[j++] = (char)v;
++              }else if( v<=0x7ff ){
++                zOut[j++] = (char)(0xc0 | (v>>6));
++                zOut[j++] = 0x80 | (v&0x3f);
++              }else{
++                zOut[j++] = (char)(0xe0 | (v>>12));
++                zOut[j++] = 0x80 | ((v>>6)&0x3f);
++                zOut[j++] = 0x80 | (v&0x3f);
++              }
++            }else{
++              if( c=='b' ){
++                c = '\b';
++              }else if( c=='f' ){
++                c = '\f';
++              }else if( c=='n' ){
++                c = '\n';
++              }else if( c=='r' ){
++                c = '\r';
++              }else if( c=='t' ){
++                c = '\t';
++              }
++              zOut[j++] = c;
++            }
++          }
++        }
++        zOut[j] = 0;
++        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
++      }
++      break;
++    }
++    case JSON_ARRAY:
++    case JSON_OBJECT: {
++      jsonReturnJson(pNode, pCtx, aReplace);
++      break;
++    }
++  }
++}
++
++/* Forward reference */
++static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
++
++/*
++** A macro to hint to the compiler that a function should not be
++** inlined.
++*/
++#if defined(__GNUC__)
++#  define JSON_NOINLINE  __attribute__((noinline))
++#elif defined(_MSC_VER) && _MSC_VER>=1310
++#  define JSON_NOINLINE  __declspec(noinline)
++#else
++#  define JSON_NOINLINE
++#endif
++
++
++static JSON_NOINLINE int jsonParseAddNodeExpand(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  u32 nNew;
++  JsonNode *pNew;
++  assert( pParse->nNode>=pParse->nAlloc );
++  if( pParse->oom ) return -1;
++  nNew = pParse->nAlloc*2 + 10;
++  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
++  if( pNew==0 ){
++    pParse->oom = 1;
++    return -1;
++  }
++  pParse->nAlloc = nNew;
++  pParse->aNode = pNew;
++  assert( pParse->nNode<pParse->nAlloc );
++  return jsonParseAddNode(pParse, eType, n, zContent);
++}
++
++/*
++** Create a new JsonNode instance based on the arguments and append that
++** instance to the JsonParse.  Return the index in pParse->aNode[] of the
++** new node, or -1 if a memory allocation fails.
++*/
++static int jsonParseAddNode(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  JsonNode *p;
++  if( pParse->nNode>=pParse->nAlloc ){
++    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
++  }
++  p = &pParse->aNode[pParse->nNode];
++  p->eType = (u8)eType;
++  p->jnFlags = 0;
++  p->n = n;
++  p->u.zJContent = zContent;
++  return pParse->nNode++;
++}
++
++/*
++** Return true if z[] begins with 4 (or more) hexadecimal digits
++*/
++static int jsonIs4Hex(const char *z){
++  int i;
++  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
++  return 1;
++}
++
++/*
++** Parse a single JSON value which begins at pParse->zJson[i].  Return the
++** index of the first character past the end of the value parsed.
++**
++** Return negative for a syntax error.  Special cases:  return -2 if the
++** first non-whitespace character is '}' and return -3 if the first
++** non-whitespace character is ']'.
++*/
++static int jsonParseValue(JsonParse *pParse, u32 i){
++  char c;
++  u32 j;
++  int iThis;
++  int x;
++  JsonNode *pNode;
++  const char *z = pParse->zJson;
++  while( safe_isspace(z[i]) ){ i++; }
++  if( (c = z[i])=='{' ){
++    /* Parse object */
++    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      if( x<0 ){
++        pParse->iDepth--;
++        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      if( pParse->oom ) return -1;
++      pNode = &pParse->aNode[pParse->nNode-1];
++      if( pNode->eType!=JSON_STRING ) return -1;
++      pNode->jnFlags |= JNODE_LABEL;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      if( z[j]!=':' ) return -1;
++      j++;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ) return -1;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!='}' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='[' ){
++    /* Parse array */
++    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ){
++        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!=']' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='"' ){
++    /* Parse string */
++    u8 jnFlags = 0;
++    j = i+1;
++    for(;;){
++      c = z[j];
++      if( (c & ~0x1f)==0 ){
++        /* Control characters are not allowed in strings */
++        return -1;
++      }
++      if( c=='\\' ){
++        c = z[++j];
++        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
++           || c=='n' || c=='r' || c=='t'
++           || (c=='u' && jsonIs4Hex(z+j+1)) ){
++          jnFlags = JNODE_ESCAPE;
++        }else{
++          return -1;
++        }
++      }else if( c=='"' ){
++        break;
++      }
++      j++;
++    }
++    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
++    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
++    return j+1;
++  }else if( c=='n'
++         && strncmp(z+i,"null",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return i+4;
++  }else if( c=='t'
++         && strncmp(z+i,"true",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++    return i+4;
++  }else if( c=='f'
++         && strncmp(z+i,"false",5)==0
++         && !safe_isalnum(z[i+5]) ){
++    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
++    return i+5;
++  }else if( c=='-' || (c>='0' && c<='9') ){
++    /* Parse number */
++    u8 seenDP = 0;
++    u8 seenE = 0;
++    assert( '-' < '0' );
++    if( c<='0' ){
++      j = c=='-' ? i+1 : i;
++      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
++    }
++    j = i+1;
++    for(;; j++){
++      c = z[j];
++      if( c>='0' && c<='9' ) continue;
++      if( c=='.' ){
++        if( z[j-1]=='-' ) return -1;
++        if( seenDP ) return -1;
++        seenDP = 1;
++        continue;
++      }
++      if( c=='e' || c=='E' ){
++        if( z[j-1]<'0' ) return -1;
++        if( seenE ) return -1;
++        seenDP = seenE = 1;
++        c = z[j+1];
++        if( c=='+' || c=='-' ){
++          j++;
++          c = z[j+1];
++        }
++        if( c<'0' || c>'9' ) return -1;
++        continue;
++      }
++      break;
++    }
++    if( z[j-1]<'0' ) return -1;
++    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
++                        j - i, &z[i]);
++    return j;
++  }else if( c=='}' ){
++    return -2;  /* End of {...} */
++  }else if( c==']' ){
++    return -3;  /* End of [...] */
++  }else if( c==0 ){
++    return 0;   /* End of file */
++  }else{
++    return -1;  /* Syntax error */
++  }
++}
++
++/*
++** Parse a complete JSON string.  Return 0 on success or non-zero if there
++** are any errors.  If an error occurs, free all memory associated with
++** pParse.
++**
++** pParse is uninitialized when this routine is called.
++*/
++static int jsonParse(
++  JsonParse *pParse,           /* Initialize and fill this JsonParse object */
++  sqlite3_context *pCtx,       /* Report errors here */
++  const char *zJson            /* Input JSON text to be parsed */
++){
++  int i;
++  memset(pParse, 0, sizeof(*pParse));
++  if( zJson==0 ) return 1;
++  pParse->zJson = zJson;
++  i = jsonParseValue(pParse, 0);
++  if( pParse->oom ) i = -1;
++  if( i>0 ){
++    assert( pParse->iDepth==0 );
++    while( safe_isspace(zJson[i]) ) i++;
++    if( zJson[i] ) i = -1;
++  }
++  if( i<=0 ){
++    if( pCtx!=0 ){
++      if( pParse->oom ){
++        sqlite3_result_error_nomem(pCtx);
++      }else{
++        sqlite3_result_error(pCtx, "malformed JSON", -1);
++      }
++    }
++    jsonParseReset(pParse);
++    return 1;
++  }
++  return 0;
++}
++
++/* Mark node i of pParse as being a child of iParent.  Call recursively
++** to fill in all the descendants of node i.
++*/
++static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
++  JsonNode *pNode = &pParse->aNode[i];
++  u32 j;
++  pParse->aUp[i] = iParent;
++  switch( pNode->eType ){
++    case JSON_ARRAY: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
++        jsonParseFillInParentage(pParse, i+j, i);
++      }
++      break;
++    }
++    case JSON_OBJECT: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
++        pParse->aUp[i+j] = i;
++        jsonParseFillInParentage(pParse, i+j+1, i);
++      }
++      break;
++    }
++    default: {
++      break;
++    }
++  }
++}
++
++/*
++** Compute the parentage of all nodes in a completed parse.
++*/
++static int jsonParseFindParents(JsonParse *pParse){
++  u32 *aUp;
++  assert( pParse->aUp==0 );
++  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
++  if( aUp==0 ){
++    pParse->oom = 1;
++    return SQLITE_NOMEM;
++  }
++  jsonParseFillInParentage(pParse, 0, 0);
++  return SQLITE_OK;
++}
++
++/*
++** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
++*/
++#define JSON_CACHE_ID  (-429938)  /* First cache entry */
++#define JSON_CACHE_SZ  4          /* Max number of cache entries */
++
++/*
++** Obtain a complete parse of the JSON found in the first argument
++** of the argv array.  Use the sqlite3_get_auxdata() cache for this
++** parse if it is available.  If the cache is not available or if it
++** is no longer valid, parse the JSON again and return the new parse,
++** and also register the new parse so that it will be available for
++** future sqlite3_get_auxdata() calls.
++*/
++static JsonParse *jsonParseCached(
++  sqlite3_context *pCtx,
++  sqlite3_value **argv,
++  sqlite3_context *pErrCtx
++){
++  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
++  int nJson = sqlite3_value_bytes(argv[0]);
++  JsonParse *p;
++  JsonParse *pMatch = 0;
++  int iKey;
++  int iMinKey = 0;
++  u32 iMinHold = 0xffffffff;
++  u32 iMaxHold = 0;
++  if( zJson==0 ) return 0;
++  for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
++    p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
++    if( p==0 ){
++      iMinKey = iKey;
++      break;
++    }
++    if( pMatch==0
++     && p->nJson==nJson
++     && memcmp(p->zJson,zJson,nJson)==0
++    ){
++      p->nErr = 0;
++      pMatch = p;
++    }else if( p->iHold<iMinHold ){
++      iMinHold = p->iHold;
++      iMinKey = iKey;
++    }
++    if( p->iHold>iMaxHold ){
++      iMaxHold = p->iHold;
++    }
++  }
++  if( pMatch ){
++    pMatch->nErr = 0;
++    pMatch->iHold = iMaxHold+1;
++    return pMatch;
++  }
++  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
++  if( p==0 ){
++    sqlite3_result_error_nomem(pCtx);
++    return 0;
++  }
++  memset(p, 0, sizeof(*p));
++  p->zJson = (char*)&p[1];
++  memcpy((char*)p->zJson, zJson, nJson+1);
++  if( jsonParse(p, pErrCtx, p->zJson) ){
++    sqlite3_free(p);
++    return 0;
++  }
++  p->nJson = nJson;
++  p->iHold = iMaxHold+1;
++  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
++                      (void(*)(void*))jsonParseFree);
++  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
++}
++
++/*
++** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
++** a match.
++*/
++static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
++  if( pNode->jnFlags & JNODE_RAW ){
++    if( pNode->n!=nKey ) return 0;
++    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
++  }else{
++    if( pNode->n!=nKey+2 ) return 0;
++    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
++  }
++}
++
++/* forward declaration */
++static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
++
++/*
++** Search along zPath to find the node specified.  Return a pointer
++** to that node, or NULL if zPath is malformed or if there is no such
++** node.
++**
++** If pApnd!=0, then try to append new nodes to complete zPath if it is
++** possible to do so and if no existing node corresponds to zPath.  If
++** new nodes are appended *pApnd is set to 1.
++*/
++static JsonNode *jsonLookupStep(
++  JsonParse *pParse,      /* The JSON to search */
++  u32 iRoot,              /* Begin the search at this node */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
++){
++  u32 i, j, nKey;
++  const char *zKey;
++  JsonNode *pRoot = &pParse->aNode[iRoot];
++  if( zPath[0]==0 ) return pRoot;
++  if( zPath[0]=='.' ){
++    if( pRoot->eType!=JSON_OBJECT ) return 0;
++    zPath++;
++    if( zPath[0]=='"' ){
++      zKey = zPath + 1;
++      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
++      nKey = i-1;
++      if( zPath[i] ){
++        i++;
++      }else{
++        *pzErr = zPath;
++        return 0;
++      }
++    }else{
++      zKey = zPath;
++      for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
++      nKey = i;
++    }
++    if( nKey==0 ){
++      *pzErr = zPath;
++      return 0;
++    }
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n ){
++        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
++          return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
++        }
++        j++;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( pApnd ){
++      u32 iStart, iLabel;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
++      zPath += i;
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
++      }
++      return pNode;
++    }
++  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
++    if( pRoot->eType!=JSON_ARRAY ) return 0;
++    i = 0;
++    j = 1;
++    while( safe_isdigit(zPath[j]) ){
++      i = i*10 + zPath[j] - '0';
++      j++;
++    }
++    if( zPath[j]!=']' ){
++      *pzErr = zPath;
++      return 0;
++    }
++    zPath += j + 1;
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
++        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( j<=pRoot->n ){
++      return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
++    }
++    if( i==0 && pApnd ){
++      u32 iStart;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++      }
++      return pNode;
++    }
++  }else{
++    *pzErr = zPath;
++  }
++  return 0;
++}
++
++/*
++** Append content to pParse that will complete zPath.  Return a pointer
++** to the inserted node, or return NULL if the append fails.
++*/
++static JsonNode *jsonLookupAppend(
++  JsonParse *pParse,     /* Append content to the JSON parse */
++  const char *zPath,     /* Description of content to append */
++  int *pApnd,            /* Set this flag to 1 */
++  const char **pzErr     /* Make this point to any syntax error */
++){
++  *pApnd = 1;
++  if( zPath[0]==0 ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
++  }
++  if( zPath[0]=='.' ){
++    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++  }else if( strncmp(zPath,"[0]",3)==0 ){
++    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++  }else{
++    return 0;
++  }
++  if( pParse->oom ) return 0;
++  return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
++}
++
++/*
++** Return the text of a syntax error message on a JSON path.  Space is
++** obtained from sqlite3_malloc().
++*/
++static char *jsonPathSyntaxError(const char *zErr){
++  return sqlite3_mprintf("JSON path error near '%q'", zErr);
++}
++
++/*
++** Do a node lookup using zPath.  Return a pointer to the node on success.
++** Return NULL if not found or if there is an error.
++**
++** On an error, write an error message into pCtx and increment the
++** pParse->nErr counter.
++**
++** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
++** nodes are appended.
++*/
++static JsonNode *jsonLookup(
++  JsonParse *pParse,      /* The JSON to search */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  sqlite3_context *pCtx   /* Report errors here, if not NULL */
++){
++  const char *zErr = 0;
++  JsonNode *pNode = 0;
++  char *zMsg;
++
++  if( zPath==0 ) return 0;
++  if( zPath[0]!='$' ){
++    zErr = zPath;
++    goto lookup_err;
++  }
++  zPath++;
++  pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
++  if( zErr==0 ) return pNode;
++
++lookup_err:
++  pParse->nErr++;
++  assert( zErr!=0 && pCtx!=0 );
++  zMsg = jsonPathSyntaxError(zErr);
++  if( zMsg ){
++    sqlite3_result_error(pCtx, zMsg, -1);
++    sqlite3_free(zMsg);
++  }else{
++    sqlite3_result_error_nomem(pCtx);
++  }
++  return 0;
++}
++
++
++/*
++** Report the wrong number of arguments for json_insert(), json_replace()
++** or json_set().
++*/
++static void jsonWrongNumArgs(
++  sqlite3_context *pCtx,
++  const char *zFuncName
++){
++  char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
++                               zFuncName);
++  sqlite3_result_error(pCtx, zMsg, -1);
++  sqlite3_free(zMsg);     
++}
++
++/*
++** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
++*/
++static void jsonRemoveAllNulls(JsonNode *pNode){
++  int i, n;
++  assert( pNode->eType==JSON_OBJECT );
++  n = pNode->n;
++  for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
++    switch( pNode[i].eType ){
++      case JSON_NULL:
++        pNode[i].jnFlags |= JNODE_REMOVE;
++        break;
++      case JSON_OBJECT:
++        jsonRemoveAllNulls(&pNode[i]);
++        break;
++    }
++  }
++}
++
++
++/****************************************************************************
++** SQL functions used for testing and debugging
++****************************************************************************/
++
++#ifdef SQLITE_DEBUG
++/*
++** The json_parse(JSON) function returns a string which describes
++** a parse of the JSON provided.  Or it returns NULL if JSON is not
++** well-formed.
++*/
++static void jsonParseFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString s;       /* Output string - not real JSON */
++  JsonParse x;        /* The parse */
++  u32 i;
++
++  assert( argc==1 );
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  jsonParseFindParents(&x);
++  jsonInit(&s, ctx);
++  for(i=0; i<x.nNode; i++){
++    const char *zType;
++    if( x.aNode[i].jnFlags & JNODE_LABEL ){
++      assert( x.aNode[i].eType==JSON_STRING );
++      zType = "label";
++    }else{
++      zType = jsonType[x.aNode[i].eType];
++    }
++    jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
++               i, zType, x.aNode[i].n, x.aUp[i]);
++    if( x.aNode[i].u.zJContent!=0 ){
++      jsonAppendRaw(&s, " ", 1);
++      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
++    }
++    jsonAppendRaw(&s, "\n", 1);
++  }
++  jsonParseReset(&x);
++  jsonResult(&s);
++}
++
++/*
++** The json_test1(JSON) function return true (1) if the input is JSON
++** text generated by another json function.  It returns (0) if the input
++** is not known to be JSON.
++*/
++static void jsonTest1Func(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  UNUSED_PARAM(argc);
++  sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
++}
++#endif /* SQLITE_DEBUG */
++
++/****************************************************************************
++** Scalar SQL function implementations
++****************************************************************************/
++
++/*
++** Implementation of the json_QUOTE(VALUE) function.  Return a JSON value
++** corresponding to the SQL value input.  Mostly this means putting 
++** double-quotes around strings and returning the unquoted string "null"
++** when given a NULL input.
++*/
++static void jsonQuoteFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString jx;
++  UNUSED_PARAM(argc);
++
++  jsonInit(&jx, ctx);
++  jsonAppendValue(&jx, argv[0]);
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++/*
++** Implementation of the json_array(VALUE,...) function.  Return a JSON
++** array that contains all values given in arguments.  Or if any argument
++** is a BLOB, throw an error.
++*/
++static void jsonArrayFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=0; i<argc; i++){
++    jsonAppendSeparator(&jx);
++    jsonAppendValue(&jx, argv[i]);
++  }
++  jsonAppendChar(&jx, ']');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_array_length(JSON)
++** json_array_length(JSON, PATH)
++**
++** Return the number of elements in the top-level JSON array.  
++** Return 0 if the input is not a well-formed JSON array.
++*/
++static void jsonArrayLengthFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  sqlite3_int64 n = 0;
++  u32 i;
++  JsonNode *pNode;
++
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  assert( p->nNode );
++  if( argc==2 ){
++    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++  }else{
++    pNode = p->aNode;
++  }
++  if( pNode==0 ){
++    return;
++  }
++  if( pNode->eType==JSON_ARRAY ){
++    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
++    for(i=1; i<=pNode->n; n++){
++      i += jsonNodeSize(&pNode[i]);
++    }
++  }
++  sqlite3_result_int64(ctx, n);
++}
++
++/*
++** json_extract(JSON, PATH, ...)
++**
++** Return the element described by PATH.  Return NULL if there is no
++** PATH element.  If there are multiple PATHs, then return a JSON array
++** with the result from each path.  Throw an error if the JSON or any PATH
++** is malformed.
++*/
++static void jsonExtractFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  JsonString jx;
++  int i;
++
++  if( argc<2 ) return;
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=1; i<argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++    if( p->nErr ) break;
++    if( argc>2 ){
++      jsonAppendSeparator(&jx);
++      if( pNode ){
++        jsonRenderNode(pNode, &jx, 0);
++      }else{
++        jsonAppendRaw(&jx, "null", 4);
++      }
++    }else if( pNode ){
++      jsonReturn(pNode, ctx, 0);
++    }
++  }
++  if( argc>2 && i==argc ){
++    jsonAppendChar(&jx, ']');
++    jsonResult(&jx);
++    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++  }
++  jsonReset(&jx);
++}
++
++/* This is the RFC 7396 MergePatch algorithm.
++*/
++static JsonNode *jsonMergePatch(
++  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
++  u32 iTarget,         /* Node of the TARGET in pParse */
++  JsonNode *pPatch     /* The PATCH */
++){
++  u32 i, j;
++  u32 iRoot;
++  JsonNode *pTarget;
++  if( pPatch->eType!=JSON_OBJECT ){
++    return pPatch;
++  }
++  assert( iTarget>=0 && iTarget<pParse->nNode );
++  pTarget = &pParse->aNode[iTarget];
++  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
++  if( pTarget->eType!=JSON_OBJECT ){
++    jsonRemoveAllNulls(pPatch);
++    return pPatch;
++  }
++  iRoot = iTarget;
++  for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
++    u32 nKey;
++    const char *zKey;
++    assert( pPatch[i].eType==JSON_STRING );
++    assert( pPatch[i].jnFlags & JNODE_LABEL );
++    nKey = pPatch[i].n;
++    zKey = pPatch[i].u.zJContent;
++    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
++      assert( pTarget[j].eType==JSON_STRING );
++      assert( pTarget[j].jnFlags & JNODE_LABEL );
++      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
++        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
++        if( pPatch[i+1].eType==JSON_NULL ){
++          pTarget[j+1].jnFlags |= JNODE_REMOVE;
++        }else{
++          JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
++          if( pNew==0 ) return 0;
++          pTarget = &pParse->aNode[iTarget];
++          if( pNew!=&pTarget[j+1] ){
++            pTarget[j+1].u.pPatch = pNew;
++            pTarget[j+1].jnFlags |= JNODE_PATCH;
++          }
++        }
++        break;
++      }
++    }
++    if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
++      int iStart, iPatch;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
++      iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++      if( pParse->oom ) return 0;
++      jsonRemoveAllNulls(pPatch);
++      pTarget = &pParse->aNode[iTarget];
++      pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
++      pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
++      iRoot = iStart;
++      pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
++      pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
++    }
++  }
++  return pTarget;
++}
++
++/*
++** Implementation of the json_mergepatch(JSON1,JSON2) function.  Return a JSON
++** object that is the result of running the RFC 7396 MergePatch() algorithm
++** on the two arguments.
++*/
++static void jsonPatchFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;     /* The JSON that is being patched */
++  JsonParse y;     /* The patch */
++  JsonNode *pResult;   /* The result of the merge */
++
++  UNUSED_PARAM(argc);
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
++    jsonParseReset(&x);
++    return;
++  }
++  pResult = jsonMergePatch(&x, 0, y.aNode);
++  assert( pResult!=0 || x.oom );
++  if( pResult ){
++    jsonReturnJson(pResult, ctx, 0);
++  }else{
++    sqlite3_result_error_nomem(ctx);
++  }
++  jsonParseReset(&x);
++  jsonParseReset(&y);
++}
++
++
++/*
++** Implementation of the json_object(NAME,VALUE,...) function.  Return a JSON
++** object that contains all name/value given in arguments.  Or if any name
++** is not a string or if any value is a BLOB, throw an error.
++*/
++static void jsonObjectFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++  const char *z;
++  u32 n;
++
++  if( argc&1 ){
++    sqlite3_result_error(ctx, "json_object() requires an even number "
++                                  "of arguments", -1);
++    return;
++  }
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '{');
++  for(i=0; i<argc; i+=2){
++    if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
++      sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
++      jsonReset(&jx);
++      return;
++    }
++    jsonAppendSeparator(&jx);
++    z = (const char*)sqlite3_value_text(argv[i]);
++    n = (u32)sqlite3_value_bytes(argv[i]);
++    jsonAppendString(&jx, z, n);
++    jsonAppendChar(&jx, ':');
++    jsonAppendValue(&jx, argv[i+1]);
++  }
++  jsonAppendChar(&jx, '}');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_remove(JSON, PATH, ...)
++**
++** Remove the named elements from JSON and return the result.  malformed
++** JSON or PATH arguments result in an error.
++*/
++static void jsonRemoveFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    if( zPath==0 ) goto remove_done;
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto remove_done;
++    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
++  }
++  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
++    jsonReturnJson(x.aNode, ctx, 0);
++  }
++remove_done:
++  jsonParseReset(&x);
++}
++
++/*
++** json_replace(JSON, PATH, VALUE, ...)
++**
++** Replace the value at PATH with VALUE.  If PATH does not already exist,
++** this routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonReplaceFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, "replace");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto replace_err;
++    if( pNode ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++replace_err:
++  jsonParseReset(&x);
++}
++
++/*
++** json_set(JSON, PATH, VALUE, ...)
++**
++** Set the value at PATH to VALUE.  Create the PATH if it does not already
++** exist.  Overwrite existing values that do exist.
++** If JSON or PATH is malformed, throw an error.
++**
++** json_insert(JSON, PATH, VALUE, ...)
++**
++** Create PATH and initialize it to VALUE.  If PATH already exists, this
++** routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonSetFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++  int bApnd;
++  int bIsSet = *(int*)sqlite3_user_data(ctx);
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    bApnd = 0;
++    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
++    if( x.oom ){
++      sqlite3_result_error_nomem(ctx);
++      goto jsonSetDone;
++    }else if( x.nErr ){
++      goto jsonSetDone;
++    }else if( pNode && (bApnd || bIsSet) ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++jsonSetDone:
++  jsonParseReset(&x);
++}
++
++/*
++** json_type(JSON)
++** json_type(JSON, PATH)
++**
++** Return the top-level "type" of a JSON string.  Throw an error if
++** either the JSON or PATH inputs are not well-formed.
++*/
++static void jsonTypeFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  const char *zPath;
++  JsonNode *pNode;
++
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  if( argc==2 ){
++    zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++  }else{
++    pNode = p->aNode;
++  }
++  if( pNode ){
++    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
++  }
++}
++
++/*
++** json_valid(JSON)
++**
++** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
++** Return 0 otherwise.
++*/
++static void jsonValidFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  UNUSED_PARAM(argc);
++  p = jsonParseCached(ctx, argv, 0);
++  sqlite3_result_int(ctx, p!=0);
++}
++
++
++/****************************************************************************
++** Aggregate SQL function implementations
++****************************************************************************/
++/*
++** json_group_array(VALUE)
++**
++** Return a JSON array composed of all values in the aggregate.
++*/
++static void jsonArrayStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '[');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    jsonAppendValue(pStr, argv[0]);
++  }
++}
++static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    pStr->pCtx = ctx;
++    jsonAppendChar(pStr, ']');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else if( isFinal ){
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
++      pStr->nUsed--;
++    }
++  }else{
++    sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++static void jsonArrayValue(sqlite3_context *ctx){
++  jsonArrayCompute(ctx, 0);
++}
++static void jsonArrayFinal(sqlite3_context *ctx){
++  jsonArrayCompute(ctx, 1);
++}
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** This method works for both json_group_array() and json_group_object().
++** It works by removing the first element of the group by searching forward
++** to the first comma (",") that is not within a string and deleting all
++** text through that comma.
++*/
++static void jsonGroupInverse(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  int inStr = 0;
++  char *z;
++  JsonString *pStr;
++  UNUSED_PARAM(argc);
++  UNUSED_PARAM(argv);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++#ifdef NEVER
++  /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
++  ** always have been called to initalize it */
++  if( NEVER(!pStr) ) return;
++#endif
++  z = pStr->zBuf;
++  for(i=1; z[i]!=',' || inStr; i++){
++    assert( i<pStr->nUsed );
++    if( z[i]=='"' ){
++      inStr = !inStr;
++    }else if( z[i]=='\\' ){
++      i++;
++    }
++  }
++  pStr->nUsed -= i;      
++  memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
++}
++#else
++# define jsonGroupInverse 0
++#endif
++
++
++/*
++** json_group_obj(NAME,VALUE)
++**
++** Return a JSON object composed of all names and values in the aggregate.
++*/
++static void jsonObjectStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  const char *z;
++  u32 n;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '{');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    z = (const char*)sqlite3_value_text(argv[0]);
++    n = (u32)sqlite3_value_bytes(argv[0]);
++    jsonAppendString(pStr, z, n);
++    jsonAppendChar(pStr, ':');
++    jsonAppendValue(pStr, argv[1]);
++  }
++}
++static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    jsonAppendChar(pStr, '}');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else if( isFinal ){
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
++      pStr->nUsed--;
++    }
++  }else{
++    sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++static void jsonObjectValue(sqlite3_context *ctx){
++  jsonObjectCompute(ctx, 0);
++}
++static void jsonObjectFinal(sqlite3_context *ctx){
++  jsonObjectCompute(ctx, 1);
++}
++
++
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++/****************************************************************************
++** The json_each virtual table
++****************************************************************************/
++typedef struct JsonEachCursor JsonEachCursor;
++struct JsonEachCursor {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++  u32 iRowid;                /* The rowid */
++  u32 iBegin;                /* The first node of the scan */
++  u32 i;                     /* Index in sParse.aNode[] of current row */
++  u32 iEnd;                  /* EOF when i equals or exceeds this value */
++  u8 eType;                  /* Type of top-level element */
++  u8 bRecursive;             /* True for json_tree().  False for json_each() */
++  char *zJson;               /* Input JSON */
++  char *zRoot;               /* Path by which to filter zJson */
++  JsonParse sParse;          /* Parse of the input JSON */
++};
++
++/* Constructor for the json_each virtual table */
++static int jsonEachConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  sqlite3_vtab *pNew;
++  int rc;
++
++/* Column numbers */
++#define JEACH_KEY     0
++#define JEACH_VALUE   1
++#define JEACH_TYPE    2
++#define JEACH_ATOM    3
++#define JEACH_ID      4
++#define JEACH_PARENT  5
++#define JEACH_FULLKEY 6
++#define JEACH_PATH    7
++/* The xBestIndex method assumes that the JSON and ROOT columns are
++** the last two columns in the table.  Should this ever changes, be
++** sure to update the xBestIndex method. */
++#define JEACH_JSON    8
++#define JEACH_ROOT    9
++
++  UNUSED_PARAM(pzErr);
++  UNUSED_PARAM(argv);
++  UNUSED_PARAM(argc);
++  UNUSED_PARAM(pAux);
++  rc = sqlite3_declare_vtab(db, 
++     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
++                    "json HIDDEN,root HIDDEN)");
++  if( rc==SQLITE_OK ){
++    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, sizeof(*pNew));
++  }
++  return rc;
++}
++
++/* destructor for json_each virtual table */
++static int jsonEachDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_each(). */
++static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  JsonEachCursor *pCur;
++
++  UNUSED_PARAM(p);
++  pCur = sqlite3_malloc( sizeof(*pCur) );
++  if( pCur==0 ) return SQLITE_NOMEM;
++  memset(pCur, 0, sizeof(*pCur));
++  *ppCursor = &pCur->base;
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_tree(). */
++static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  int rc = jsonEachOpenEach(p, ppCursor);
++  if( rc==SQLITE_OK ){
++    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
++    pCur->bRecursive = 1;
++  }
++  return rc;
++}
++
++/* Reset a JsonEachCursor back to its original state.  Free any memory
++** held. */
++static void jsonEachCursorReset(JsonEachCursor *p){
++  sqlite3_free(p->zJson);
++  sqlite3_free(p->zRoot);
++  jsonParseReset(&p->sParse);
++  p->iRowid = 0;
++  p->i = 0;
++  p->iEnd = 0;
++  p->eType = 0;
++  p->zJson = 0;
++  p->zRoot = 0;
++}
++
++/* Destructor for a jsonEachCursor object */
++static int jsonEachClose(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  jsonEachCursorReset(p);
++  sqlite3_free(cur);
++  return SQLITE_OK;
++}
++
++/* Return TRUE if the jsonEachCursor object has been advanced off the end
++** of the JSON object */
++static int jsonEachEof(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  return p->i >= p->iEnd;
++}
++
++/* Advance the cursor to the next element for json_tree() */
++static int jsonEachNext(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  if( p->bRecursive ){
++    if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
++    p->i++;
++    p->iRowid++;
++    if( p->i<p->iEnd ){
++      u32 iUp = p->sParse.aUp[p->i];
++      JsonNode *pUp = &p->sParse.aNode[iUp];
++      p->eType = pUp->eType;
++      if( pUp->eType==JSON_ARRAY ){
++        if( iUp==p->i-1 ){
++          pUp->u.iKey = 0;
++        }else{
++          pUp->u.iKey++;
++        }
++      }
++    }
++  }else{
++    switch( p->eType ){
++      case JSON_ARRAY: {
++        p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
++        p->iRowid++;
++        break;
++      }
++      case JSON_OBJECT: {
++        p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
++        p->iRowid++;
++        break;
++      }
++      default: {
++        p->i = p->iEnd;
++        break;
++      }
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Append the name of the path for element i to pStr
++*/
++static void jsonEachComputePath(
++  JsonEachCursor *p,       /* The cursor */
++  JsonString *pStr,        /* Write the path here */
++  u32 i                    /* Path to this element */
++){
++  JsonNode *pNode, *pUp;
++  u32 iUp;
++  if( i==0 ){
++    jsonAppendChar(pStr, '$');
++    return;
++  }
++  iUp = p->sParse.aUp[i];
++  jsonEachComputePath(p, pStr, iUp);
++  pNode = &p->sParse.aNode[i];
++  pUp = &p->sParse.aNode[iUp];
++  if( pUp->eType==JSON_ARRAY ){
++    jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
++  }else{
++    assert( pUp->eType==JSON_OBJECT );
++    if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
++    assert( pNode->eType==JSON_STRING );
++    assert( pNode->jnFlags & JNODE_LABEL );
++    jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
++  }
++}
++
++/* Return the value of a column */
++static int jsonEachColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  JsonNode *pThis = &p->sParse.aNode[p->i];
++  switch( i ){
++    case JEACH_KEY: {
++      if( p->i==0 ) break;
++      if( p->eType==JSON_OBJECT ){
++        jsonReturn(pThis, ctx, 0);
++      }else if( p->eType==JSON_ARRAY ){
++        u32 iKey;
++        if( p->bRecursive ){
++          if( p->iRowid==0 ) break;
++          iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
++        }else{
++          iKey = p->iRowid;
++        }
++        sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
++      }
++      break;
++    }
++    case JEACH_VALUE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_TYPE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_ATOM: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      if( pThis->eType>=JSON_ARRAY ) break;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_ID: {
++      sqlite3_result_int64(ctx, 
++         (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
++      break;
++    }
++    case JEACH_PARENT: {
++      if( p->i>p->iBegin && p->bRecursive ){
++        sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
++      }
++      break;
++    }
++    case JEACH_FULLKEY: {
++      JsonString x;
++      jsonInit(&x, ctx);
++      if( p->bRecursive ){
++        jsonEachComputePath(p, &x, p->i);
++      }else{
++        if( p->zRoot ){
++          jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
++        }else{
++          jsonAppendChar(&x, '$');
++        }
++        if( p->eType==JSON_ARRAY ){
++          jsonPrintf(30, &x, "[%d]", p->iRowid);
++        }else if( p->eType==JSON_OBJECT ){
++          jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
++        }
++      }
++      jsonResult(&x);
++      break;
++    }
++    case JEACH_PATH: {
++      if( p->bRecursive ){
++        JsonString x;
++        jsonInit(&x, ctx);
++        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
++        jsonResult(&x);
++        break;
++      }
++      /* For json_each() path and root are the same so fall through
++      ** into the root case */
++    }
++    default: {
++      const char *zRoot = p->zRoot;
++      if( zRoot==0 ) zRoot = "$";
++      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_JSON: {
++      assert( i==JEACH_JSON );
++      sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Return the current rowid value */
++static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  *pRowid = p->iRowid;
++  return SQLITE_OK;
++}
++
++/* The query strategy is to look for an equality constraint on the json
++** column.  Without such a constraint, the table cannot operate.  idxNum is
++** 1 if the constraint is found, 3 if the constraint and zRoot are found,
++** and 0 otherwise.
++*/
++static int jsonEachBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  int i;                     /* Loop counter or computed array index */
++  int aIdx[2];               /* Index of constraints for JSON and ROOT */
++  int unusableMask = 0;      /* Mask of unusable JSON and ROOT constraints */
++  int idxMask = 0;           /* Mask of usable == constraints JSON and ROOT */
++  const struct sqlite3_index_constraint *pConstraint;
++
++  /* This implementation assumes that JSON and ROOT are the last two
++  ** columns in the table */
++  assert( JEACH_ROOT == JEACH_JSON+1 );
++  UNUSED_PARAM(tab);
++  aIdx[0] = aIdx[1] = -1;
++  pConstraint = pIdxInfo->aConstraint;
++  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
++    int iCol;
++    int iMask;
++    if( pConstraint->iColumn < JEACH_JSON ) continue;
++    iCol = pConstraint->iColumn - JEACH_JSON;
++    assert( iCol==0 || iCol==1 );
++    iMask = 1 << iCol;
++    if( pConstraint->usable==0 ){
++      unusableMask |= iMask;
++    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++      aIdx[iCol] = i;
++      idxMask |= iMask;
++    }
++  }
++  if( (unusableMask & ~idxMask)!=0 ){
++    /* If there are any unusable constraints on JSON or ROOT, then reject
++    ** this entire plan */
++    return SQLITE_CONSTRAINT;
++  }
++  if( aIdx[0]<0 ){
++    /* No JSON input.  Leave estimatedCost at the huge value that it was
++    ** initialized to to discourage the query planner from selecting this
++    ** plan. */
++    pIdxInfo->idxNum = 0;
++  }else{
++    pIdxInfo->estimatedCost = 1.0;
++    i = aIdx[0];
++    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[i].omit = 1;
++    if( aIdx[1]<0 ){
++      pIdxInfo->idxNum = 1;  /* Only JSON supplied.  Plan 1 */
++    }else{
++      i = aIdx[1];
++      pIdxInfo->aConstraintUsage[i].argvIndex = 2;
++      pIdxInfo->aConstraintUsage[i].omit = 1;
++      pIdxInfo->idxNum = 3;  /* Both JSON and ROOT are supplied.  Plan 3 */
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Start a search on a new JSON string */
++static int jsonEachFilter(
++  sqlite3_vtab_cursor *cur,
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  const char *z;
++  const char *zRoot = 0;
++  sqlite3_int64 n;
++
++  UNUSED_PARAM(idxStr);
++  UNUSED_PARAM(argc);
++  jsonEachCursorReset(p);
++  if( idxNum==0 ) return SQLITE_OK;
++  z = (const char*)sqlite3_value_text(argv[0]);
++  if( z==0 ) return SQLITE_OK;
++  n = sqlite3_value_bytes(argv[0]);
++  p->zJson = sqlite3_malloc64( n+1 );
++  if( p->zJson==0 ) return SQLITE_NOMEM;
++  memcpy(p->zJson, z, (size_t)n+1);
++  if( jsonParse(&p->sParse, 0, p->zJson) ){
++    int rc = SQLITE_NOMEM;
++    if( p->sParse.oom==0 ){
++      sqlite3_free(cur->pVtab->zErrMsg);
++      cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
++      if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
++    }
++    jsonEachCursorReset(p);
++    return rc;
++  }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
++    jsonEachCursorReset(p);
++    return SQLITE_NOMEM;
++  }else{
++    JsonNode *pNode = 0;
++    if( idxNum==3 ){
++      const char *zErr = 0;
++      zRoot = (const char*)sqlite3_value_text(argv[1]);
++      if( zRoot==0 ) return SQLITE_OK;
++      n = sqlite3_value_bytes(argv[1]);
++      p->zRoot = sqlite3_malloc64( n+1 );
++      if( p->zRoot==0 ) return SQLITE_NOMEM;
++      memcpy(p->zRoot, zRoot, (size_t)n+1);
++      if( zRoot[0]!='$' ){
++        zErr = zRoot;
++      }else{
++        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
++      }
++      if( zErr ){
++        sqlite3_free(cur->pVtab->zErrMsg);
++        cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
++        jsonEachCursorReset(p);
++        return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
++      }else if( pNode==0 ){
++        return SQLITE_OK;
++      }
++    }else{
++      pNode = p->sParse.aNode;
++    }
++    p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
++    p->eType = pNode->eType;
++    if( p->eType>=JSON_ARRAY ){
++      pNode->u.iKey = 0;
++      p->iEnd = p->i + pNode->n + 1;
++      if( p->bRecursive ){
++        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
++        if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
++          p->i--;
++        }
++      }else{
++        p->i++;
++      }
++    }else{
++      p->iEnd = p->i+1;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* The methods of the json_each virtual table */
++static sqlite3_module jsonEachModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenEach,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
++};
++
++/* The methods of the json_tree virtual table. */
++static sqlite3_module jsonTreeModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenTree,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
++};
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++
++/****************************************************************************
++** The following routines are the only publically visible identifiers in this
++** file.  Call the following routines in order to register the various SQL
++** functions and the virtual table implemented by this file.
++****************************************************************************/
++
++SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
++  int rc = SQLITE_OK;
++  unsigned int i;
++  static const struct {
++     const char *zName;
++     int nArg;
++     int flag;
++     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
++  } aFunc[] = {
++    { "json",                 1, 0,   jsonRemoveFunc        },
++    { "json_array",          -1, 0,   jsonArrayFunc         },
++    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
++    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
++    { "json_extract",        -1, 0,   jsonExtractFunc       },
++    { "json_insert",         -1, 0,   jsonSetFunc           },
++    { "json_object",         -1, 0,   jsonObjectFunc        },
++    { "json_patch",           2, 0,   jsonPatchFunc         },
++    { "json_quote",           1, 0,   jsonQuoteFunc         },
++    { "json_remove",         -1, 0,   jsonRemoveFunc        },
++    { "json_replace",        -1, 0,   jsonReplaceFunc       },
++    { "json_set",            -1, 1,   jsonSetFunc           },
++    { "json_type",            1, 0,   jsonTypeFunc          },
++    { "json_type",            2, 0,   jsonTypeFunc          },
++    { "json_valid",           1, 0,   jsonValidFunc         },
++
++#if SQLITE_DEBUG
++    /* DEBUG and TESTING functions */
++    { "json_parse",           1, 0,   jsonParseFunc         },
++    { "json_test1",           1, 0,   jsonTest1Func         },
++#endif
++  };
++  static const struct {
++     const char *zName;
++     int nArg;
++     void (*xStep)(sqlite3_context*,int,sqlite3_value**);
++     void (*xFinal)(sqlite3_context*);
++     void (*xValue)(sqlite3_context*);
++  } aAgg[] = {
++    { "json_group_array",     1,
++      jsonArrayStep,   jsonArrayFinal,  jsonArrayValue  },
++    { "json_group_object",    2,
++      jsonObjectStep,  jsonObjectFinal, jsonObjectValue },
++  };
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  static const struct {
++     const char *zName;
++     sqlite3_module *pModule;
++  } aMod[] = {
++    { "json_each",            &jsonEachModule               },
++    { "json_tree",            &jsonTreeModule               },
++  };
++#endif
++  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
++                                 (void*)&aFunc[i].flag,
++                                 aFunc[i].xFunc, 0, 0);
++  }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
++                                 aAgg[i].xStep, aAgg[i].xFinal,
++                                 aAgg[i].xValue, jsonGroupInverse, 0);
++  }
++#endif
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
++  }
++#endif
++  return rc;
++}
++
++
++#ifndef SQLITE_CORE
++#ifdef _WIN32
++__declspec(dllexport)
++#endif
++SQLITE_API int sqlite3_json_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return sqlite3Json1Init(db);
++}
++#endif
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
++
++/************** End of json1.c ***********************************************/
+ /************** Begin file rtree.c *******************************************/
+ /*
+ ** 2001 September 15
+@@ -165280,7 +179149,7 @@
+ **
+ **   CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
+ **   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+-**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
++**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
+ **
+ ** The data for each node of the r-tree structure is stored in the %_node
+ ** table. For each node that is not the root node of the r-tree, there is
+@@ -165287,7 +179156,8 @@
+ ** an entry in the %_parent table associating the node with its parent.
+ ** And for each row of data in the table, there is an entry in the %_rowid
+ ** table that maps from the entries rowid to the id of the node that it
+-** is stored on.
++** is stored on.  If the r-tree contains auxiliary columns, those are stored
++** on the end of the %_rowid table.
+ **
+ ** The root node of an r-tree always exists, even if the r-tree table is
+ ** empty. The nodeno of the root node is always 1. All other nodes in the
+@@ -165308,7 +179178,8 @@
+ **      child page.
+ */
+ 
+-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
++#if !defined(SQLITE_CORE) \
++  || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
+ 
+ #ifndef SQLITE_CORE
+ /*   #include "sqlite3ext.h" */
+@@ -165349,6 +179220,9 @@
+ /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
+ #define RTREE_MAX_DIMENSIONS 5
+ 
++/* Maximum number of auxiliary columns */
++#define RTREE_MAX_AUX_COLUMN 100
++
+ /* Size of hash table Rtree.aHash. This hash table is not expected to
+ ** ever contain very many entries, so a fixed number of buckets is 
+ ** used.
+@@ -165377,6 +179251,8 @@
+   u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
+   u8 nBytesPerCell;           /* Bytes consumed per cell */
+   u8 inWrTrans;               /* True if inside write transaction */
++  u8 nAux;                    /* # of auxiliary columns in %_rowid */
++  u8 nAuxNotNull;             /* Number of initial not-null aux columns */
+   int iDepth;                 /* Current depth of the r-tree structure */
+   char *zDb;                  /* Name of database containing r-tree table */
+   char *zName;                /* Name of r-tree table */ 
+@@ -165383,6 +179259,8 @@
+   u32 nBusy;                  /* Current number of users of this structure */
+   i64 nRowEst;                /* Estimated number of rows in this table */
+   u32 nCursor;                /* Number of open cursors */
++  u32 nNodeRef;               /* Number RtreeNodes with positive nRef */
++  char *zReadAuxSql;          /* SQL for statement to read aux data */
+ 
+   /* List of nodes removed during a CondenseTree operation. List is
+   ** linked together via the pointer normally used for hash chains -
+@@ -165409,6 +179287,9 @@
+   sqlite3_stmt *pWriteParent;
+   sqlite3_stmt *pDeleteParent;
+ 
++  /* Statement for writing to the "aux:" fields, if there are any */
++  sqlite3_stmt *pWriteAux;
++
+   RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
+ };
+ 
+@@ -165465,7 +179346,7 @@
+ ** The smallest possible node-size is (512-64)==448 bytes. And the largest
+ ** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
+ ** Therefore all non-root nodes must contain at least 3 entries. Since 
+-** 2^40 is greater than 2^64, an r-tree structure always has a depth of
++** 3^40 is greater than 2^64, an r-tree structure always has a depth of
+ ** 40 or less.
+ */
+ #define RTREE_MAX_DEPTH 40
+@@ -165485,6 +179366,7 @@
+   sqlite3_vtab_cursor base;         /* Base class.  Must be first */
+   u8 atEOF;                         /* True if at end of search */
+   u8 bPoint;                        /* True if sPoint is valid */
++  u8 bAuxValid;                     /* True if pReadAux is valid */
+   int iStrategy;                    /* Copy of idxNum search parameter */
+   int nConstraint;                  /* Number of entries in aConstraint */
+   RtreeConstraint *aConstraint;     /* Search constraints. */
+@@ -165492,6 +179374,7 @@
+   int nPoint;                       /* Number of slots used in aPoint[] */
+   int mxLevel;                      /* iLevel value for root of the tree */
+   RtreeSearchPoint *aPoint;         /* Priority queue for search points */
++  sqlite3_stmt *pReadAux;           /* Statement to read aux-data */
+   RtreeSearchPoint sPoint;          /* Cached next search point */
+   RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */
+   u32 anQueue[RTREE_MAX_DEPTH+1];   /* Number of queued entries by iLevel */
+@@ -165778,6 +179661,7 @@
+ */
+ static void nodeReference(RtreeNode *p){
+   if( p ){
++    assert( p->nRef>0 );
+     p->nRef++;
+   }
+ }
+@@ -165845,6 +179729,7 @@
+     memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
+     pNode->zData = (u8 *)&pNode[1];
+     pNode->nRef = 1;
++    pRtree->nNodeRef++;
+     pNode->pParent = pParent;
+     pNode->isDirty = 1;
+     nodeReference(pParent);
+@@ -165878,10 +179763,10 @@
+   /* Check if the requested node is already in the hash table. If so,
+   ** increase its reference count and return it.
+   */
+-  if( (pNode = nodeHashLookup(pRtree, iNode)) ){
++  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
+     assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
+     if( pParent && !pNode->pParent ){
+-      nodeReference(pParent);
++      pParent->nRef++;
+       pNode->pParent = pParent;
+     }
+     pNode->nRef++;
+@@ -165920,6 +179805,7 @@
+       pNode->pParent = pParent;
+       pNode->zData = (u8 *)&pNode[1];
+       pNode->nRef = 1;
++      pRtree->nNodeRef++;
+       pNode->iNode = iNode;
+       pNode->isDirty = 0;
+       pNode->pNext = 0;
+@@ -165960,7 +179846,10 @@
+     }
+     *ppNode = pNode;
+   }else{
+-    sqlite3_free(pNode);
++    if( pNode ){
++      pRtree->nNodeRef--;
++      sqlite3_free(pNode);
++    }
+     *ppNode = 0;
+   }
+ 
+@@ -166040,6 +179929,7 @@
+     sqlite3_step(p);
+     pNode->isDirty = 0;
+     rc = sqlite3_reset(p);
++    sqlite3_bind_null(p, 2);
+     if( pNode->iNode==0 && rc==SQLITE_OK ){
+       pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
+       nodeHashInsert(pRtree, pNode);
+@@ -166056,8 +179946,10 @@
+   int rc = SQLITE_OK;
+   if( pNode ){
+     assert( pNode->nRef>0 );
++    assert( pRtree->nNodeRef>0 );
+     pNode->nRef--;
+     if( pNode->nRef==0 ){
++      pRtree->nNodeRef--;
+       if( pNode->iNode==1 ){
+         pRtree->iDepth = -1;
+       }
+@@ -166174,8 +180066,9 @@
+   pRtree->nBusy--;
+   if( pRtree->nBusy==0 ){
+     pRtree->inWrTrans = 0;
+-    pRtree->nCursor = 0;
++    assert( pRtree->nCursor==0 );
+     nodeBlobReset(pRtree);
++    assert( pRtree->nNodeRef==0 );
+     sqlite3_finalize(pRtree->pWriteNode);
+     sqlite3_finalize(pRtree->pDeleteNode);
+     sqlite3_finalize(pRtree->pReadRowid);
+@@ -166184,6 +180077,8 @@
+     sqlite3_finalize(pRtree->pReadParent);
+     sqlite3_finalize(pRtree->pWriteParent);
+     sqlite3_finalize(pRtree->pDeleteParent);
++    sqlite3_finalize(pRtree->pWriteAux);
++    sqlite3_free(pRtree->zReadAuxSql);
+     sqlite3_free(pRtree);
+   }
+ }
+@@ -166272,6 +180167,7 @@
+   RtreeCursor *pCsr = (RtreeCursor *)cur;
+   assert( pRtree->nCursor>0 );
+   freeCursorConstraints(pCsr);
++  sqlite3_finalize(pCsr->pReadAux);
+   sqlite3_free(pCsr->aPoint);
+   for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
+   sqlite3_free(pCsr);
+@@ -166643,7 +180539,7 @@
+       if( ii<RTREE_CACHE_SZ ){
+         assert( pCur->aNode[ii]==0 );
+         pCur->aNode[ii] = pCur->aNode[0];
+-       }else{
++      }else{
+         nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
+       }
+       pCur->aNode[0] = 0;
+@@ -166814,6 +180710,10 @@
+ 
+   /* Move to the next entry that matches the configured constraints. */
+   RTREE_QUEUE_TRACE(pCsr, "POP-Nx:");
++  if( pCsr->bAuxValid ){
++    pCsr->bAuxValid = 0;
++    sqlite3_reset(pCsr->pReadAux);
++  }
+   rtreeSearchPointPop(pCsr);
+   rc = rtreeStepToLeaf(pCsr);
+   return rc;
+@@ -166848,7 +180748,7 @@
+   if( p==0 ) return SQLITE_OK;
+   if( i==0 ){
+     sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
+-  }else{
++  }else if( i<=pRtree->nDim2 ){
+     nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+@@ -166859,7 +180759,27 @@
+       assert( pRtree->eCoordType==RTREE_COORD_INT32 );
+       sqlite3_result_int(ctx, c.i);
+     }
+-  }
++  }else{
++    if( !pCsr->bAuxValid ){
++      if( pCsr->pReadAux==0 ){
++        rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
++                                &pCsr->pReadAux, 0);
++        if( rc ) return rc;
++      }
++      sqlite3_bind_int64(pCsr->pReadAux, 1, 
++          nodeGetRowid(pRtree, pNode, p->iCell));
++      rc = sqlite3_step(pCsr->pReadAux);
++      if( rc==SQLITE_ROW ){
++        pCsr->bAuxValid = 1;
++      }else{
++        sqlite3_reset(pCsr->pReadAux);
++        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++        return rc;
++      }
++    }
++    sqlite3_result_value(ctx,
++         sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1));
++  }  
+   return SQLITE_OK;
+ }
+ 
+@@ -166937,6 +180857,7 @@
+   int ii;
+   int rc = SQLITE_OK;
+   int iCell = 0;
++  sqlite3_stmt *pStmt;
+ 
+   rtreeReference(pRtree);
+ 
+@@ -166943,8 +180864,10 @@
+   /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
+   freeCursorConstraints(pCsr);
+   sqlite3_free(pCsr->aPoint);
++  pStmt = pCsr->pReadAux;
+   memset(pCsr, 0, sizeof(RtreeCursor));
+   pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
++  pCsr->pReadAux = pStmt;
+ 
+   pCsr->iStrategy = idxNum;
+   if( idxNum==1 ){
+@@ -167107,10 +181030,14 @@
+       */ 
+       pIdxInfo->estimatedCost = 30.0;
+       pIdxInfo->estimatedRows = 1;
++      pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
+       return SQLITE_OK;
+     }
+ 
+-    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
++    if( p->usable
++    && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
++        || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
++    ){
+       u8 op;
+       switch( p->op ){
+         case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
+@@ -167277,7 +181204,7 @@
+ ){
+   int rc;
+   int ii;
+-  RtreeNode *pNode;
++  RtreeNode *pNode = 0;
+   rc = nodeAcquire(pRtree, 1, 0, &pNode);
+ 
+   for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
+@@ -167683,7 +181610,7 @@
+   }else{
+     pLeft = pNode;
+     pRight = nodeNew(pRtree, pLeft->pParent);
+-    nodeReference(pLeft);
++    pLeft->nRef++;
+   }
+ 
+   if( !pLeft || !pRight ){
+@@ -168092,7 +182019,7 @@
+ /*
+ ** Select a currently unused rowid for a new r-tree record.
+ */
+-static int newRowid(Rtree *pRtree, i64 *piRowid){
++static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){
+   int rc;
+   sqlite3_bind_null(pRtree->pWriteRowid, 1);
+   sqlite3_bind_null(pRtree->pWriteRowid, 2);
+@@ -168109,7 +182036,7 @@
+   int rc;                         /* Return code */
+   RtreeNode *pLeaf = 0;           /* Leaf node containing record iDelete */
+   int iCell;                      /* Index of iDelete cell in pLeaf */
+-  RtreeNode *pRoot;               /* Root node of rtree structure */
++  RtreeNode *pRoot = 0;           /* Root node of rtree structure */
+ 
+ 
+   /* Obtain a reference to the root node to initialize Rtree.iDepth */
+@@ -168152,7 +182079,7 @@
+   */
+   if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
+     int rc2;
+-    RtreeNode *pChild;
++    RtreeNode *pChild = 0;
+     i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
+     rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
+     if( rc==SQLITE_OK ){
+@@ -168173,6 +182100,7 @@
+       rc = reinsertNodeContent(pRtree, pLeaf);
+     }
+     pRtree->pDeleted = pLeaf->pNext;
++    pRtree->nNodeRef--;
+     sqlite3_free(pLeaf);
+   }
+ 
+@@ -168269,7 +182197,7 @@
+ static int rtreeUpdate(
+   sqlite3_vtab *pVtab, 
+   int nData, 
+-  sqlite3_value **azData, 
++  sqlite3_value **aData, 
+   sqlite_int64 *pRowid
+ ){
+   Rtree *pRtree = (Rtree *)pVtab;
+@@ -168277,6 +182205,12 @@
+   RtreeCell cell;                 /* New cell to insert if nData>1 */
+   int bHaveRowid = 0;             /* Set to 1 after new rowid is determined */
+ 
++  if( pRtree->nNodeRef ){
++    /* Unable to write to the btree while another cursor is reading from it,
++    ** since the write might do a rebalance which would disrupt the read
++    ** cursor. */
++    return SQLITE_LOCKED_VTAB;
++  }
+   rtreeReference(pRtree);
+   assert(nData>=1);
+ 
+@@ -168295,8 +182229,10 @@
+   */
+   if( nData>1 ){
+     int ii;
++    int nn = nData - 4;
+ 
+-    /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
++    if( nn > pRtree->nDim2 ) nn = pRtree->nDim2;
++    /* Populate the cell.aCoord[] array. The first coordinate is aData[3].
+     **
+     ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
+     ** with "column" that are interpreted as table constraints.
+@@ -168304,13 +182240,12 @@
+     ** This problem was discovered after years of use, so we silently ignore
+     ** these kinds of misdeclared tables to avoid breaking any legacy.
+     */
+-    assert( nData<=(pRtree->nDim2 + 3) );
+ 
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+-      for(ii=0; ii<nData-4; ii+=2){
+-        cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
+-        cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
++      for(ii=0; ii<nn; ii+=2){
++        cell.aCoord[ii].f = rtreeValueDown(aData[ii+3]);
++        cell.aCoord[ii+1].f = rtreeValueUp(aData[ii+4]);
+         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
+           rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+@@ -168319,9 +182254,9 @@
+     }else
+ #endif
+     {
+-      for(ii=0; ii<nData-4; ii+=2){
+-        cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
+-        cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
++      for(ii=0; ii<nn; ii+=2){
++        cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]);
++        cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]);
+         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
+           rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+@@ -168331,10 +182266,10 @@
+ 
+     /* If a rowid value was supplied, check if it is already present in 
+     ** the table. If so, the constraint has failed. */
+-    if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){
+-      cell.iRowid = sqlite3_value_int64(azData[2]);
+-      if( sqlite3_value_type(azData[0])==SQLITE_NULL
+-       || sqlite3_value_int64(azData[0])!=cell.iRowid
++    if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){
++      cell.iRowid = sqlite3_value_int64(aData[2]);
++      if( sqlite3_value_type(aData[0])==SQLITE_NULL
++       || sqlite3_value_int64(aData[0])!=cell.iRowid
+       ){
+         int steprc;
+         sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
+@@ -168353,16 +182288,16 @@
+     }
+   }
+ 
+-  /* If azData[0] is not an SQL NULL value, it is the rowid of a
++  /* If aData[0] is not an SQL NULL value, it is the rowid of a
+   ** record to delete from the r-tree table. The following block does
+   ** just that.
+   */
+-  if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
+-    rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0]));
++  if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){
++    rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0]));
+   }
+ 
+-  /* If the azData[] array contains more than one element, elements
+-  ** (azData[2]..azData[argc-1]) contain a new record to insert into
++  /* If the aData[] array contains more than one element, elements
++  ** (aData[2]..aData[argc-1]) contain a new record to insert into
+   ** the r-tree structure.
+   */
+   if( rc==SQLITE_OK && nData>1 ){
+@@ -168371,7 +182306,7 @@
+ 
+     /* Figure out the rowid of the new row. */
+     if( bHaveRowid==0 ){
+-      rc = newRowid(pRtree, &cell.iRowid);
++      rc = rtreeNewRowid(pRtree, &cell.iRowid);
+     }
+     *pRowid = cell.iRowid;
+ 
+@@ -168387,6 +182322,16 @@
+         rc = rc2;
+       }
+     }
++    if( pRtree->nAux ){
++      sqlite3_stmt *pUp = pRtree->pWriteAux;
++      int jj;
++      sqlite3_bind_int64(pUp, 1, *pRowid);
++      for(jj=0; jj<pRtree->nAux; jj++){
++        sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
++      }
++      sqlite3_step(pUp);
++      rc = sqlite3_reset(pUp);
++    }
+   }
+ 
+ constraint:
+@@ -168453,7 +182398,7 @@
+ */
+ static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
+   Rtree *pRtree = (Rtree *)pVtab;
+-  int iwt = pRtree->inWrTrans;
++  u8 iwt = pRtree->inWrTrans;
+   UNUSED_PARAMETER(iSavepoint);
+   pRtree->inWrTrans = 0;
+   nodeBlobReset(pRtree);
+@@ -168505,8 +182450,24 @@
+   return rc;
+ }
+ 
++
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int rtreeShadowName(const char *zName){
++  static const char *azName[] = {
++    "node", "parent", "rowid"
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static sqlite3_module rtreeModule = {
+-  2,                          /* iVersion */
++  3,                          /* iVersion */
+   rtreeCreate,                /* xCreate - create a table */
+   rtreeConnect,               /* xConnect - connect to an existing table */
+   rtreeBestIndex,             /* xBestIndex - Determine search strategy */
+@@ -168529,6 +182490,7 @@
+   rtreeSavepoint,             /* xSavepoint */
+   0,                          /* xRelease */
+   0,                          /* xRollbackTo */
++  rtreeShadowName             /* xShadowName */
+ };
+ 
+ static int rtreeSqlInit(
+@@ -168543,18 +182505,18 @@
+   #define N_STATEMENT 8
+   static const char *azSql[N_STATEMENT] = {
+     /* Write the xxx_node table */
+-    "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
++    "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1",
+ 
+     /* Read and write the xxx_rowid table */
+-    "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
+-    "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
++    "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = ?1",
++    "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_rowid' WHERE rowid = ?1",
+ 
+     /* Read and write the xxx_parent table */
+-    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
+-    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
++    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
++    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
+   };
+   sqlite3_stmt **appStmt[N_STATEMENT];
+   int i;
+@@ -168562,14 +182524,25 @@
+   pRtree->db = db;
+ 
+   if( isCreate ){
+-    char *zCreate = sqlite3_mprintf(
+-"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
+-"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
+-"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,"
+-                                  " parentnode INTEGER);"
+-"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
+-      zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
+-    );
++    char *zCreate;
++    sqlite3_str *p = sqlite3_str_new(db);
++    int ii;
++    sqlite3_str_appendf(p,
++       "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno",
++       zDb, zPrefix);
++    for(ii=0; ii<pRtree->nAux; ii++){
++      sqlite3_str_appendf(p,",a%d",ii);
++    }
++    sqlite3_str_appendf(p,
++      ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);",
++      zDb, zPrefix);
++    sqlite3_str_appendf(p,
++    "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);",
++      zDb, zPrefix);
++    sqlite3_str_appendf(p,
++       "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))",
++       zDb, zPrefix, pRtree->iNodeSize);
++    zCreate = sqlite3_str_finish(p);
+     if( !zCreate ){
+       return SQLITE_NOMEM;
+     }
+@@ -168591,7 +182564,17 @@
+ 
+   rc = rtreeQueryStat1(db, pRtree);
+   for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
+-    char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
++    char *zSql;
++    const char *zFormat;
++    if( i!=3 || pRtree->nAux==0 ){
++       zFormat = azSql[i];
++    }else {
++       /* An UPSERT is very slightly slower than REPLACE, but it is needed
++       ** if there are auxiliary columns */
++       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
++                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
++    }
++    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
+     if( zSql ){
+       rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
+                               appStmt[i], 0); 
+@@ -168600,6 +182583,36 @@
+     }
+     sqlite3_free(zSql);
+   }
++  if( pRtree->nAux ){
++    pRtree->zReadAuxSql = sqlite3_mprintf(
++       "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1",
++       zDb, zPrefix);
++    if( pRtree->zReadAuxSql==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      sqlite3_str *p = sqlite3_str_new(db);
++      int ii;
++      char *zSql;
++      sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
++      for(ii=0; ii<pRtree->nAux; ii++){
++        if( ii ) sqlite3_str_append(p, ",", 1);
++        if( ii<pRtree->nAuxNotNull ){
++          sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
++        }else{
++          sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
++        }
++      }
++      sqlite3_str_appendf(p, " WHERE rowid=?1");
++      zSql = sqlite3_str_finish(p);
++      if( zSql==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
++                                &pRtree->pWriteAux, 0); 
++        sqlite3_free(zSql);
++      }
++    }
++  }
+ 
+   return rc;
+ }
+@@ -168670,7 +182683,7 @@
+     if( rc!=SQLITE_OK ){
+       *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+     }else if( pRtree->iNodeSize<(512-64) ){
+-      rc = SQLITE_CORRUPT;
++      rc = SQLITE_CORRUPT_VTAB;
+       *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
+                                pRtree->zName);
+     }
+@@ -168702,17 +182715,22 @@
+   int nDb;              /* Length of string argv[1] */
+   int nName;            /* Length of string argv[2] */
+   int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32);
++  sqlite3_str *pSql;
++  char *zSql;
++  int ii = 4;
++  int iErr;
+ 
+   const char *aErrMsg[] = {
+     0,                                                    /* 0 */
+     "Wrong number of columns for an rtree table",         /* 1 */
+     "Too few columns for an rtree table",                 /* 2 */
+-    "Too many columns for an rtree table"                 /* 3 */
++    "Too many columns for an rtree table",                /* 3 */
++    "Auxiliary rtree columns must be last"                /* 4 */
+   };
+ 
+-  int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
+-  if( aErrMsg[iErr] ){
+-    *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
++  assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */
++  if( argc>RTREE_MAX_AUX_COLUMN+3 ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[3]);
+     return SQLITE_ERROR;
+   }
+ 
+@@ -168730,53 +182748,73 @@
+   pRtree->base.pModule = &rtreeModule;
+   pRtree->zDb = (char *)&pRtree[1];
+   pRtree->zName = &pRtree->zDb[nDb+1];
+-  pRtree->nDim = (u8)((argc-4)/2);
+-  pRtree->nDim2 = pRtree->nDim*2;
+-  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
+   pRtree->eCoordType = (u8)eCoordType;
+   memcpy(pRtree->zDb, argv[1], nDb);
+   memcpy(pRtree->zName, argv[2], nName);
+ 
+-  /* Figure out the node size to use. */
+-  rc = getNodeSize(db, pRtree, isCreate, pzErr);
+ 
+   /* Create/Connect to the underlying relational database schema. If
+   ** that is successful, call sqlite3_declare_vtab() to configure
+   ** the r-tree table schema.
+   */
+-  if( rc==SQLITE_OK ){
+-    if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
+-      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  pSql = sqlite3_str_new(db);
++  sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
++  for(ii=4; ii<argc; ii++){
++    if( argv[ii][0]=='+' ){
++      pRtree->nAux++;
++      sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
++    }else if( pRtree->nAux>0 ){
++      break;
+     }else{
+-      char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
+-      char *zTmp;
+-      int ii;
+-      for(ii=4; zSql && ii<argc; ii++){
+-        zTmp = zSql;
+-        zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
+-        sqlite3_free(zTmp);
+-      }
+-      if( zSql ){
+-        zTmp = zSql;
+-        zSql = sqlite3_mprintf("%s);", zTmp);
+-        sqlite3_free(zTmp);
+-      }
+-      if( !zSql ){
+-        rc = SQLITE_NOMEM;
+-      }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
+-        *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+-      }
+-      sqlite3_free(zSql);
++      pRtree->nDim2++;
++      sqlite3_str_appendf(pSql, ",%s", argv[ii]);
+     }
+   }
+-
+-  if( rc==SQLITE_OK ){
+-    *ppVtab = (sqlite3_vtab *)pRtree;
++  sqlite3_str_appendf(pSql, ");");
++  zSql = sqlite3_str_finish(pSql);
++  if( !zSql ){
++    rc = SQLITE_NOMEM;
++  }else if( ii<argc ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[4]);
++    rc = SQLITE_ERROR;
++  }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++  sqlite3_free(zSql);
++  if( rc ) goto rtreeInit_fail;
++  pRtree->nDim = pRtree->nDim2/2;
++  if( pRtree->nDim<1 ){
++    iErr = 2;
++  }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){
++    iErr = 3;
++  }else if( pRtree->nDim2 % 2 ){
++    iErr = 1;
+   }else{
+-    assert( *ppVtab==0 );
+-    assert( pRtree->nBusy==1 );
+-    rtreeRelease(pRtree);
++    iErr = 0;
+   }
++  if( iErr ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
++    goto rtreeInit_fail;
++  }
++  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
++
++  /* Figure out the node size to use. */
++  rc = getNodeSize(db, pRtree, isCreate, pzErr);
++  if( rc ) goto rtreeInit_fail;
++  rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
++  if( rc ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    goto rtreeInit_fail;
++  }
++
++  *ppVtab = (sqlite3_vtab *)pRtree;
++  return SQLITE_OK;
++
++rtreeInit_fail:
++  if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
++  assert( *ppVtab==0 );
++  assert( pRtree->nBusy==1 );
++  rtreeRelease(pRtree);
+   return rc;
+ }
+ 
+@@ -168865,6 +182903,2279 @@
+ }
+ 
+ /*
++** Context object passed between the various routines that make up the
++** implementation of integrity-check function rtreecheck().
++*/
++typedef struct RtreeCheck RtreeCheck;
++struct RtreeCheck {
++  sqlite3 *db;                    /* Database handle */
++  const char *zDb;                /* Database containing rtree table */
++  const char *zTab;               /* Name of rtree table */
++  int bInt;                       /* True for rtree_i32 table */
++  int nDim;                       /* Number of dimensions for this rtree tbl */
++  sqlite3_stmt *pGetNode;         /* Statement used to retrieve nodes */
++  sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */
++  int nLeaf;                      /* Number of leaf cells in table */
++  int nNonLeaf;                   /* Number of non-leaf cells in table */
++  int rc;                         /* Return code */
++  char *zReport;                  /* Message to report */
++  int nErr;                       /* Number of lines in zReport */
++};
++
++#define RTREE_CHECK_MAX_ERROR 100
++
++/*
++** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error,
++** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code.
++*/
++static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){
++  int rc = sqlite3_reset(pStmt);
++  if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc;
++}
++
++/*
++** The second and subsequent arguments to this function are a format string
++** and printf style arguments. This function formats the string and attempts
++** to compile it as an SQL statement.
++**
++** If successful, a pointer to the new SQL statement is returned. Otherwise,
++** NULL is returned and an error code left in RtreeCheck.rc.
++*/
++static sqlite3_stmt *rtreeCheckPrepare(
++  RtreeCheck *pCheck,             /* RtreeCheck object */
++  const char *zFmt, ...           /* Format string and trailing args */
++){
++  va_list ap;
++  char *z;
++  sqlite3_stmt *pRet = 0;
++
++  va_start(ap, zFmt);
++  z = sqlite3_vmprintf(zFmt, ap);
++
++  if( pCheck->rc==SQLITE_OK ){
++    if( z==0 ){
++      pCheck->rc = SQLITE_NOMEM;
++    }else{
++      pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0);
++    }
++  }
++
++  sqlite3_free(z);
++  va_end(ap);
++  return pRet;
++}
++
++/*
++** The second and subsequent arguments to this function are a printf()
++** style format string and arguments. This function formats the string and
++** appends it to the report being accumuated in pCheck.
++*/
++static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
++  va_list ap;
++  va_start(ap, zFmt);
++  if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){
++    char *z = sqlite3_vmprintf(zFmt, ap);
++    if( z==0 ){
++      pCheck->rc = SQLITE_NOMEM;
++    }else{
++      pCheck->zReport = sqlite3_mprintf("%z%s%z", 
++          pCheck->zReport, (pCheck->zReport ? "\n" : ""), z
++      );
++      if( pCheck->zReport==0 ){
++        pCheck->rc = SQLITE_NOMEM;
++      }
++    }
++    pCheck->nErr++;
++  }
++  va_end(ap);
++}
++
++/*
++** This function is a no-op if there is already an error code stored
++** in the RtreeCheck object indicated by the first argument. NULL is
++** returned in this case.
++**
++** Otherwise, the contents of rtree table node iNode are loaded from
++** the database and copied into a buffer obtained from sqlite3_malloc().
++** If no error occurs, a pointer to the buffer is returned and (*pnNode)
++** is set to the size of the buffer in bytes.
++**
++** Or, if an error does occur, NULL is returned and an error code left
++** in the RtreeCheck object. The final value of *pnNode is undefined in
++** this case.
++*/
++static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
++  u8 *pRet = 0;                   /* Return value */
++
++  assert( pCheck->rc==SQLITE_OK );
++  if( pCheck->pGetNode==0 ){
++    pCheck->pGetNode = rtreeCheckPrepare(pCheck,
++        "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", 
++        pCheck->zDb, pCheck->zTab
++    );
++  }
++
++  if( pCheck->rc==SQLITE_OK ){
++    sqlite3_bind_int64(pCheck->pGetNode, 1, iNode);
++    if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
++      int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
++      const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
++      pRet = sqlite3_malloc(nNode);
++      if( pRet==0 ){
++        pCheck->rc = SQLITE_NOMEM;
++      }else{
++        memcpy(pRet, pNode, nNode);
++        *pnNode = nNode;
++      }
++    }
++    rtreeCheckReset(pCheck, pCheck->pGetNode);
++    if( pCheck->rc==SQLITE_OK && pRet==0 ){
++      rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode);
++    }
++  }
++
++  return pRet;
++}
++
++/*
++** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
++** (if bLeaf==1) table contains a specified entry. The schemas of the
++** two tables are:
++**
++**   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
++**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
++**
++** In both cases, this function checks that there exists an entry with
++** IPK value iKey and the second column set to iVal.
++**
++*/
++static void rtreeCheckMapping(
++  RtreeCheck *pCheck,             /* RtreeCheck object */
++  int bLeaf,                      /* True for a leaf cell, false for interior */
++  i64 iKey,                       /* Key for mapping */
++  i64 iVal                        /* Expected value for mapping */
++){
++  int rc;
++  sqlite3_stmt *pStmt;
++  const char *azSql[2] = {
++    "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1",
++    "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1"
++  };
++
++  assert( bLeaf==0 || bLeaf==1 );
++  if( pCheck->aCheckMapping[bLeaf]==0 ){
++    pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck,
++        azSql[bLeaf], pCheck->zDb, pCheck->zTab
++    );
++  }
++  if( pCheck->rc!=SQLITE_OK ) return;
++
++  pStmt = pCheck->aCheckMapping[bLeaf];
++  sqlite3_bind_int64(pStmt, 1, iKey);
++  rc = sqlite3_step(pStmt);
++  if( rc==SQLITE_DONE ){
++    rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table",
++        iKey, iVal, (bLeaf ? "%_rowid" : "%_parent")
++    );
++  }else if( rc==SQLITE_ROW ){
++    i64 ii = sqlite3_column_int64(pStmt, 0);
++    if( ii!=iVal ){
++      rtreeCheckAppendMsg(pCheck, 
++          "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)",
++          iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal
++      );
++    }
++  }
++  rtreeCheckReset(pCheck, pStmt);
++}
++
++/*
++** Argument pCell points to an array of coordinates stored on an rtree page.
++** This function checks that the coordinates are internally consistent (no
++** x1>x2 conditions) and adds an error message to the RtreeCheck object
++** if they are not.
++**
++** Additionally, if pParent is not NULL, then it is assumed to point to
++** the array of coordinates on the parent page that bound the page 
++** containing pCell. In this case it is also verified that the two
++** sets of coordinates are mutually consistent and an error message added
++** to the RtreeCheck object if they are not.
++*/
++static void rtreeCheckCellCoord(
++  RtreeCheck *pCheck, 
++  i64 iNode,                      /* Node id to use in error messages */
++  int iCell,                      /* Cell number to use in error messages */
++  u8 *pCell,                      /* Pointer to cell coordinates */
++  u8 *pParent                     /* Pointer to parent coordinates */
++){
++  RtreeCoord c1, c2;
++  RtreeCoord p1, p2;
++  int i;
++
++  for(i=0; i<pCheck->nDim; i++){
++    readCoord(&pCell[4*2*i], &c1);
++    readCoord(&pCell[4*(2*i + 1)], &c2);
++
++    /* printf("%e, %e\n", c1.u.f, c2.u.f); */
++    if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){
++      rtreeCheckAppendMsg(pCheck, 
++          "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode
++      );
++    }
++
++    if( pParent ){
++      readCoord(&pParent[4*2*i], &p1);
++      readCoord(&pParent[4*(2*i + 1)], &p2);
++
++      if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f) 
++       || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f)
++      ){
++        rtreeCheckAppendMsg(pCheck, 
++            "Dimension %d of cell %d on node %lld is corrupt relative to parent"
++            , i, iCell, iNode
++        );
++      }
++    }
++  }
++}
++
++/*
++** Run rtreecheck() checks on node iNode, which is at depth iDepth within
++** the r-tree structure. Argument aParent points to the array of coordinates
++** that bound node iNode on the parent node.
++**
++** If any problems are discovered, an error message is appended to the
++** report accumulated in the RtreeCheck object.
++*/
++static void rtreeCheckNode(
++  RtreeCheck *pCheck,
++  int iDepth,                     /* Depth of iNode (0==leaf) */
++  u8 *aParent,                    /* Buffer containing parent coords */
++  i64 iNode                       /* Node to check */
++){
++  u8 *aNode = 0;
++  int nNode = 0;
++
++  assert( iNode==1 || aParent!=0 );
++  assert( pCheck->nDim>0 );
++
++  aNode = rtreeCheckGetNode(pCheck, iNode, &nNode);
++  if( aNode ){
++    if( nNode<4 ){
++      rtreeCheckAppendMsg(pCheck, 
++          "Node %lld is too small (%d bytes)", iNode, nNode
++      );
++    }else{
++      int nCell;                  /* Number of cells on page */
++      int i;                      /* Used to iterate through cells */
++      if( aParent==0 ){
++        iDepth = readInt16(aNode);
++        if( iDepth>RTREE_MAX_DEPTH ){
++          rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth);
++          sqlite3_free(aNode);
++          return;
++        }
++      }
++      nCell = readInt16(&aNode[2]);
++      if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){
++        rtreeCheckAppendMsg(pCheck, 
++            "Node %lld is too small for cell count of %d (%d bytes)", 
++            iNode, nCell, nNode
++        );
++      }else{
++        for(i=0; i<nCell; i++){
++          u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)];
++          i64 iVal = readInt64(pCell);
++          rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent);
++
++          if( iDepth>0 ){
++            rtreeCheckMapping(pCheck, 0, iVal, iNode);
++            rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal);
++            pCheck->nNonLeaf++;
++          }else{
++            rtreeCheckMapping(pCheck, 1, iVal, iNode);
++            pCheck->nLeaf++;
++          }
++        }
++      }
++    }
++    sqlite3_free(aNode);
++  }
++}
++
++/*
++** The second argument to this function must be either "_rowid" or
++** "_parent". This function checks that the number of entries in the
++** %_rowid or %_parent table is exactly nExpect. If not, it adds
++** an error message to the report in the RtreeCheck object indicated
++** by the first argument.
++*/
++static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){
++  if( pCheck->rc==SQLITE_OK ){
++    sqlite3_stmt *pCount;
++    pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'",
++        pCheck->zDb, pCheck->zTab, zTbl
++    );
++    if( pCount ){
++      if( sqlite3_step(pCount)==SQLITE_ROW ){
++        i64 nActual = sqlite3_column_int64(pCount, 0);
++        if( nActual!=nExpect ){
++          rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table"
++              " - expected %lld, actual %lld" , zTbl, nExpect, nActual
++          );
++        }
++      }
++      pCheck->rc = sqlite3_finalize(pCount);
++    }
++  }
++}
++
++/*
++** This function does the bulk of the work for the rtree integrity-check.
++** It is called by rtreecheck(), which is the SQL function implementation.
++*/
++static int rtreeCheckTable(
++  sqlite3 *db,                    /* Database handle to access db through */
++  const char *zDb,                /* Name of db ("main", "temp" etc.) */
++  const char *zTab,               /* Name of rtree table to check */
++  char **pzReport                 /* OUT: sqlite3_malloc'd report text */
++){
++  RtreeCheck check;               /* Common context for various routines */
++  sqlite3_stmt *pStmt = 0;        /* Used to find column count of rtree table */
++  int bEnd = 0;                   /* True if transaction should be closed */
++  int nAux = 0;                   /* Number of extra columns. */
++
++  /* Initialize the context object */
++  memset(&check, 0, sizeof(check));
++  check.db = db;
++  check.zDb = zDb;
++  check.zTab = zTab;
++
++  /* If there is not already an open transaction, open one now. This is
++  ** to ensure that the queries run as part of this integrity-check operate
++  ** on a consistent snapshot.  */
++  if( sqlite3_get_autocommit(db) ){
++    check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
++    bEnd = 1;
++  }
++
++  /* Find the number of auxiliary columns */
++  if( check.rc==SQLITE_OK ){
++    pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
++    if( pStmt ){
++      nAux = sqlite3_column_count(pStmt) - 2;
++      sqlite3_finalize(pStmt);
++    }
++    check.rc = SQLITE_OK;
++  }
++
++  /* Find number of dimensions in the rtree table. */
++  pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
++  if( pStmt ){
++    int rc;
++    check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;
++    if( check.nDim<1 ){
++      rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
++    }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
++      check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER);
++    }
++    rc = sqlite3_finalize(pStmt);
++    if( rc!=SQLITE_CORRUPT ) check.rc = rc;
++  }
++
++  /* Do the actual integrity-check */
++  if( check.nDim>=1 ){
++    if( check.rc==SQLITE_OK ){
++      rtreeCheckNode(&check, 0, 0, 1);
++    }
++    rtreeCheckCount(&check, "_rowid", check.nLeaf);
++    rtreeCheckCount(&check, "_parent", check.nNonLeaf);
++  }
++
++  /* Finalize SQL statements used by the integrity-check */
++  sqlite3_finalize(check.pGetNode);
++  sqlite3_finalize(check.aCheckMapping[0]);
++  sqlite3_finalize(check.aCheckMapping[1]);
++
++  /* If one was opened, close the transaction */
++  if( bEnd ){
++    int rc = sqlite3_exec(db, "END", 0, 0, 0);
++    if( check.rc==SQLITE_OK ) check.rc = rc;
++  }
++  *pzReport = check.zReport;
++  return check.rc;
++}
++
++/*
++** Usage:
++**
++**   rtreecheck(<rtree-table>);
++**   rtreecheck(<database>, <rtree-table>);
++**
++** Invoking this SQL function runs an integrity-check on the named rtree
++** table. The integrity-check verifies the following:
++**
++**   1. For each cell in the r-tree structure (%_node table), that:
++**
++**       a) for each dimension, (coord1 <= coord2).
++**
++**       b) unless the cell is on the root node, that the cell is bounded
++**          by the parent cell on the parent node.
++**
++**       c) for leaf nodes, that there is an entry in the %_rowid 
++**          table corresponding to the cell's rowid value that 
++**          points to the correct node.
++**
++**       d) for cells on non-leaf nodes, that there is an entry in the 
++**          %_parent table mapping from the cell's child node to the
++**          node that it resides on.
++**
++**   2. That there are the same number of entries in the %_rowid table
++**      as there are leaf cells in the r-tree structure, and that there
++**      is a leaf cell that corresponds to each entry in the %_rowid table.
++**
++**   3. That there are the same number of entries in the %_parent table
++**      as there are non-leaf cells in the r-tree structure, and that 
++**      there is a non-leaf cell that corresponds to each entry in the 
++**      %_parent table.
++*/
++static void rtreecheck(
++  sqlite3_context *ctx, 
++  int nArg, 
++  sqlite3_value **apArg
++){
++  if( nArg!=1 && nArg!=2 ){
++    sqlite3_result_error(ctx, 
++        "wrong number of arguments to function rtreecheck()", -1
++    );
++  }else{
++    int rc;
++    char *zReport = 0;
++    const char *zDb = (const char*)sqlite3_value_text(apArg[0]);
++    const char *zTab;
++    if( nArg==1 ){
++      zTab = zDb;
++      zDb = "main";
++    }else{
++      zTab = (const char*)sqlite3_value_text(apArg[1]);
++    }
++    rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport);
++    if( rc==SQLITE_OK ){
++      sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT);
++    }else{
++      sqlite3_result_error_code(ctx, rc);
++    }
++    sqlite3_free(zReport);
++  }
++}
++
++/* Conditionally include the geopoly code */
++#ifdef SQLITE_ENABLE_GEOPOLY
++/************** Include geopoly.c in the middle of rtree.c *******************/
++/************** Begin file geopoly.c *****************************************/
++/*
++** 2018-05-25
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file implements an alternative R-Tree virtual table that
++** uses polygons to express the boundaries of 2-dimensional objects.
++**
++** This file is #include-ed onto the end of "rtree.c" so that it has
++** access to all of the R-Tree internals.
++*/
++/* #include <stdlib.h> */
++
++/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
++#ifdef GEOPOLY_ENABLE_DEBUG
++  static int geo_debug = 0;
++# define GEODEBUG(X) if(geo_debug)printf X
++#else
++# define GEODEBUG(X)
++#endif
++
++#ifndef JSON_NULL   /* The following stuff repeats things found in json1 */
++/*
++** Versions of isspace(), isalnum() and isdigit() to which it is safe
++** to pass signed char values.
++*/
++#ifdef sqlite3Isdigit
++   /* Use the SQLite core versions if this routine is part of the
++   ** SQLite amalgamation */
++#  define safe_isdigit(x)  sqlite3Isdigit(x)
++#  define safe_isalnum(x)  sqlite3Isalnum(x)
++#  define safe_isxdigit(x) sqlite3Isxdigit(x)
++#else
++   /* Use the standard library for separate compilation */
++#include <ctype.h>  /* amalgamator: keep */
++#  define safe_isdigit(x)  isdigit((unsigned char)(x))
++#  define safe_isalnum(x)  isalnum((unsigned char)(x))
++#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
++#endif
++
++/*
++** Growing our own isspace() routine this way is twice as fast as
++** the library isspace() function.
++*/
++static const char geopolyIsSpace[] = {
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++};
++#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x])
++#endif /* JSON NULL - back to original code */
++
++/* Compiler and version */
++#ifndef GCC_VERSION
++#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
++#else
++# define GCC_VERSION 0
++#endif
++#endif
++#ifndef MSVC_VERSION
++#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define MSVC_VERSION _MSC_VER
++#else
++# define MSVC_VERSION 0
++#endif
++#endif
++
++/* Datatype for coordinates
++*/
++typedef float GeoCoord;
++
++/*
++** Internal representation of a polygon.
++**
++** The polygon consists of a sequence of vertexes.  There is a line
++** segment between each pair of vertexes, and one final segment from
++** the last vertex back to the first.  (This differs from the GeoJSON
++** standard in which the final vertex is a repeat of the first.)
++**
++** The polygon follows the right-hand rule.  The area to the right of
++** each segment is "outside" and the area to the left is "inside".
++**
++** The on-disk representation consists of a 4-byte header followed by
++** the values.  The 4-byte header is:
++**
++**      encoding    (1 byte)   0=big-endian, 1=little-endian
++**      nvertex     (3 bytes)  Number of vertexes as a big-endian integer
++**
++** Enough space is allocated for 4 coordinates, to work around over-zealous
++** warnings coming from some compiler (notably, clang). In reality, the size
++** of each GeoPoly memory allocate is adjusted as necessary so that the
++** GeoPoly.a[] array at the end is the appropriate size.
++*/
++typedef struct GeoPoly GeoPoly;
++struct GeoPoly {
++  int nVertex;          /* Number of vertexes */
++  unsigned char hdr[4]; /* Header for on-disk representation */
++  GeoCoord a[8];        /* 2*nVertex values. X (longitude) first, then Y */
++};
++
++/* The size of a memory allocation needed for a GeoPoly object sufficient
++** to hold N coordinate pairs.
++*/
++#define GEOPOLY_SZ(N)  (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
++
++/*
++** State of a parse of a GeoJSON input.
++*/
++typedef struct GeoParse GeoParse;
++struct GeoParse {
++  const unsigned char *z;   /* Unparsed input */
++  int nVertex;              /* Number of vertexes in a[] */
++  int nAlloc;               /* Space allocated to a[] */
++  int nErr;                 /* Number of errors encountered */
++  GeoCoord *a;          /* Array of vertexes.  From sqlite3_malloc64() */
++};
++
++/* Do a 4-byte byte swap */
++static void geopolySwab32(unsigned char *a){
++  unsigned char t = a[0];
++  a[0] = a[3];
++  a[3] = t;
++  t = a[1];
++  a[1] = a[2];
++  a[2] = t;
++}
++
++/* Skip whitespace.  Return the next non-whitespace character. */
++static char geopolySkipSpace(GeoParse *p){
++  while( safe_isspace(p->z[0]) ) p->z++;
++  return p->z[0];
++}
++
++/* Parse out a number.  Write the value into *pVal if pVal!=0.
++** return non-zero on success and zero if the next token is not a number.
++*/
++static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
++  char c = geopolySkipSpace(p);
++  const unsigned char *z = p->z;
++  int j = 0;
++  int seenDP = 0;
++  int seenE = 0;
++  if( c=='-' ){
++    j = 1;
++    c = z[j];
++  }
++  if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
++  for(;; j++){
++    c = z[j];
++    if( safe_isdigit(c) ) continue;
++    if( c=='.' ){
++      if( z[j-1]=='-' ) return 0;
++      if( seenDP ) return 0;
++      seenDP = 1;
++      continue;
++    }
++    if( c=='e' || c=='E' ){
++      if( z[j-1]<'0' ) return 0;
++      if( seenE ) return -1;
++      seenDP = seenE = 1;
++      c = z[j+1];
++      if( c=='+' || c=='-' ){
++        j++;
++        c = z[j+1];
++      }
++      if( c<'0' || c>'9' ) return 0;
++      continue;
++    }
++    break;
++  }
++  if( z[j-1]<'0' ) return 0;
++  if( pVal ){
++#ifdef SQLITE_AMALGAMATION
++     /* The sqlite3AtoF() routine is much much faster than atof(), if it
++     ** is available */
++     double r;
++     (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
++     *pVal = r;
++#else
++     *pVal = (GeoCoord)atof((const char*)p->z);
++#endif
++  }
++  p->z += j;
++  return 1;
++}
++
++/*
++** If the input is a well-formed JSON array of coordinates with at least
++** four coordinates and where each coordinate is itself a two-value array,
++** then convert the JSON into a GeoPoly object and return a pointer to
++** that object.
++**
++** If any error occurs, return NULL.
++*/
++static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
++  GeoParse s;
++  int rc = SQLITE_OK;
++  memset(&s, 0, sizeof(s));
++  s.z = z;
++  if( geopolySkipSpace(&s)=='[' ){
++    s.z++;
++    while( geopolySkipSpace(&s)=='[' ){
++      int ii = 0;
++      char c;
++      s.z++;
++      if( s.nVertex>=s.nAlloc ){
++        GeoCoord *aNew;
++        s.nAlloc = s.nAlloc*2 + 16;
++        aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 );
++        if( aNew==0 ){
++          rc = SQLITE_NOMEM;
++          s.nErr++;
++          break;
++        }
++        s.a = aNew;
++      }
++      while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){
++        ii++;
++        if( ii==2 ) s.nVertex++;
++        c = geopolySkipSpace(&s);
++        s.z++;
++        if( c==',' ) continue;
++        if( c==']' && ii>=2 ) break;
++        s.nErr++;
++        rc = SQLITE_ERROR;
++        goto parse_json_err;
++      }
++      if( geopolySkipSpace(&s)==',' ){
++        s.z++;
++        continue;
++      }
++      break;
++    }
++    if( geopolySkipSpace(&s)==']'
++     && s.nVertex>=4
++     && s.a[0]==s.a[s.nVertex*2-2]
++     && s.a[1]==s.a[s.nVertex*2-1]
++     && (s.z++, geopolySkipSpace(&s)==0)
++    ){
++      GeoPoly *pOut;
++      int x = 1;
++      s.nVertex--;  /* Remove the redundant vertex at the end */
++      pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
++      x = 1;
++      if( pOut==0 ) goto parse_json_err;
++      pOut->nVertex = s.nVertex;
++      memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
++      pOut->hdr[0] = *(unsigned char*)&x;
++      pOut->hdr[1] = (s.nVertex>>16)&0xff;
++      pOut->hdr[2] = (s.nVertex>>8)&0xff;
++      pOut->hdr[3] = s.nVertex&0xff;
++      sqlite3_free(s.a);
++      if( pRc ) *pRc = SQLITE_OK;
++      return pOut;
++    }else{
++      s.nErr++;
++      rc = SQLITE_ERROR;
++    }
++  }
++parse_json_err:
++  if( pRc ) *pRc = rc;
++  sqlite3_free(s.a);
++  return 0;
++}
++
++/*
++** Given a function parameter, try to interpret it as a polygon, either
++** in the binary format or JSON text.  Compute a GeoPoly object and
++** return a pointer to that object.  Or if the input is not a well-formed
++** polygon, put an error message in sqlite3_context and return NULL.
++*/
++static GeoPoly *geopolyFuncParam(
++  sqlite3_context *pCtx,      /* Context for error messages */
++  sqlite3_value *pVal,        /* The value to decode */
++  int *pRc                    /* Write error here */
++){
++  GeoPoly *p = 0;
++  int nByte;
++  if( sqlite3_value_type(pVal)==SQLITE_BLOB
++   && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
++  ){
++    const unsigned char *a = sqlite3_value_blob(pVal);
++    int nVertex;
++    nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
++    if( (a[0]==0 || a[0]==1)
++     && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
++    ){
++      p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) );
++      if( p==0 ){
++        if( pRc ) *pRc = SQLITE_NOMEM;
++        if( pCtx ) sqlite3_result_error_nomem(pCtx);
++      }else{
++        int x = 1;
++        p->nVertex = nVertex;
++        memcpy(p->hdr, a, nByte);
++        if( a[0] != *(unsigned char*)&x ){
++          int ii;
++          for(ii=0; ii<nVertex*2; ii++){
++            geopolySwab32((unsigned char*)&p->a[ii]);
++          }
++          p->hdr[0] ^= 1;
++        }
++      }
++    }
++    if( pRc ) *pRc = SQLITE_OK;
++    return p;
++  }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){
++    const unsigned char *zJson = sqlite3_value_text(pVal);
++    if( zJson==0 ){
++      if( pRc ) *pRc = SQLITE_NOMEM;
++      return 0;
++    }
++    return geopolyParseJson(zJson, pRc);
++  }else{
++    if( pRc ) *pRc = SQLITE_ERROR;
++    return 0;
++  }
++}
++
++/*
++** Implementation of the geopoly_blob(X) function.
++**
++** If the input is a well-formed Geopoly BLOB or JSON string
++** then return the BLOB representation of the polygon.  Otherwise
++** return NULL.
++*/
++static void geopolyBlobFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL function:     geopoly_json(X)
++**
++** Interpret X as a polygon and render it as a JSON array
++** of coordinates.  Or, if X is not a valid polygon, return NULL.
++*/
++static void geopolyJsonFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3 *db = sqlite3_context_db_handle(context);
++    sqlite3_str *x = sqlite3_str_new(db);
++    int i;
++    sqlite3_str_append(x, "[", 1);
++    for(i=0; i<p->nVertex; i++){
++      sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
++    }
++    sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
++    sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL function:     geopoly_svg(X, ....)
++**
++** Interpret X as a polygon and render it as a SVG <polyline>.
++** Additional arguments are added as attributes to the <polyline>.
++*/
++static void geopolySvgFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3 *db = sqlite3_context_db_handle(context);
++    sqlite3_str *x = sqlite3_str_new(db);
++    int i;
++    char cSep = '\'';
++    sqlite3_str_appendf(x, "<polyline points=");
++    for(i=0; i<p->nVertex; i++){
++      sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]);
++      cSep = ' ';
++    }
++    sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
++    for(i=1; i<argc; i++){
++      const char *z = (const char*)sqlite3_value_text(argv[i]);
++      if( z && z[0] ){
++        sqlite3_str_appendf(x, " %s", z);
++      }
++    }
++    sqlite3_str_appendf(x, "></polyline>");
++    sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL Function:      geopoly_xform(poly, A, B, C, D, E, F)
++**
++** Transform and/or translate a polygon as follows:
++**
++**      x1 = A*x0 + B*y0 + E
++**      y1 = C*x0 + D*y0 + F
++**
++** For a translation:
++**
++**      geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset)
++**
++** Rotate by R around the point (0,0):
++**
++**      geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0)
++*/
++static void geopolyXformFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  double A = sqlite3_value_double(argv[1]);
++  double B = sqlite3_value_double(argv[2]);
++  double C = sqlite3_value_double(argv[3]);
++  double D = sqlite3_value_double(argv[4]);
++  double E = sqlite3_value_double(argv[5]);
++  double F = sqlite3_value_double(argv[6]);
++  GeoCoord x1, y1, x0, y0;
++  int ii;
++  if( p ){
++    for(ii=0; ii<p->nVertex; ii++){
++      x0 = p->a[ii*2];
++      y0 = p->a[ii*2+1];
++      x1 = (GeoCoord)(A*x0 + B*y0 + E);
++      y1 = (GeoCoord)(C*x0 + D*y0 + F);
++      p->a[ii*2] = x1;
++      p->a[ii*2+1] = y1;
++    }
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Compute the area enclosed by the polygon.
++**
++** This routine can also be used to detect polygons that rotate in
++** the wrong direction.  Polygons are suppose to be counter-clockwise (CCW).
++** This routine returns a negative value for clockwise (CW) polygons.
++*/
++static double geopolyArea(GeoPoly *p){
++  double rArea = 0.0;
++  int ii;
++  for(ii=0; ii<p->nVertex-1; ii++){
++    rArea += (p->a[ii*2] - p->a[ii*2+2])           /* (x0 - x1) */
++              * (p->a[ii*2+1] + p->a[ii*2+3])      /* (y0 + y1) */
++              * 0.5;
++  }
++  rArea += (p->a[ii*2] - p->a[0])                  /* (xN - x0) */
++           * (p->a[ii*2+1] + p->a[1])              /* (yN + y0) */
++           * 0.5;
++  return rArea;
++}
++
++/*
++** Implementation of the geopoly_area(X) function.
++**
++** If the input is a well-formed Geopoly BLOB then return the area
++** enclosed by the polygon.  If the polygon circulates clockwise instead
++** of counterclockwise (as it should) then return the negative of the
++** enclosed area.  Otherwise return NULL.
++*/
++static void geopolyAreaFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3_result_double(context, geopolyArea(p));
++    sqlite3_free(p);
++  }            
++}
++
++/*
++** Implementation of the geopoly_ccw(X) function.
++**
++** If the rotation of polygon X is clockwise (incorrect) instead of
++** counter-clockwise (the correct winding order according to RFC7946)
++** then reverse the order of the vertexes in polygon X.  
++**
++** In other words, this routine returns a CCW polygon regardless of the
++** winding order of its input.
++**
++** Use this routine to sanitize historical inputs that that sometimes
++** contain polygons that wind in the wrong direction.
++*/
++static void geopolyCcwFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    if( geopolyArea(p)<0.0 ){
++      int ii, jj;
++      for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
++        GeoCoord t = p->a[ii];
++        p->a[ii] = p->a[jj];
++        p->a[jj] = t;
++        t = p->a[ii+1];
++        p->a[ii+1] = p->a[jj+1];
++        p->a[jj+1] = t;
++      }
++    }
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }            
++}
++
++#define GEOPOLY_PI 3.1415926535897932385
++
++/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
++*/
++static double geopolySine(double r){
++  assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
++  if( r>=1.5*GEOPOLY_PI ){
++    r -= 2.0*GEOPOLY_PI;
++  }
++  if( r>=0.5*GEOPOLY_PI ){
++    return -geopolySine(r-GEOPOLY_PI);
++  }else{
++    double r2 = r*r;
++    double r3 = r2*r;
++    double r5 = r3*r2;
++    return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
++  }
++}
++
++/*
++** Function:   geopoly_regular(X,Y,R,N)
++**
++** Construct a simple, convex, regular polygon centered at X, Y
++** with circumradius R and with N sides.
++*/
++static void geopolyRegularFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  double x = sqlite3_value_double(argv[0]);
++  double y = sqlite3_value_double(argv[1]);
++  double r = sqlite3_value_double(argv[2]);
++  int n = sqlite3_value_int(argv[3]);
++  int i;
++  GeoPoly *p;
++
++  if( n<3 || r<=0.0 ) return;
++  if( n>1000 ) n = 1000;
++  p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
++  if( p==0 ){
++    sqlite3_result_error_nomem(context);
++    return;
++  }
++  i = 1;
++  p->hdr[0] = *(unsigned char*)&i;
++  p->hdr[1] = 0;
++  p->hdr[2] = (n>>8)&0xff;
++  p->hdr[3] = n&0xff;
++  for(i=0; i<n; i++){
++    double rAngle = 2.0*GEOPOLY_PI*i/n;
++    p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
++    p->a[i*2+1] = y + r*geopolySine(rAngle);
++  }
++  sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
++  sqlite3_free(p);
++}
++
++/*
++** If pPoly is a polygon, compute its bounding box. Then:
++**
++**    (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
++**    (2) otherwise, compute a GeoPoly for the bounding box and return the
++**        new GeoPoly
++**
++** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from
++** the bounding box in aCoord and return a pointer to that GeoPoly.
++*/
++static GeoPoly *geopolyBBox(
++  sqlite3_context *context,   /* For recording the error */
++  sqlite3_value *pPoly,       /* The polygon */
++  RtreeCoord *aCoord,         /* Results here */
++  int *pRc                    /* Error code here */
++){
++  GeoPoly *pOut = 0;
++  GeoPoly *p;
++  float mnX, mxX, mnY, mxY;
++  if( pPoly==0 && aCoord!=0 ){
++    p = 0;
++    mnX = aCoord[0].f;
++    mxX = aCoord[1].f;
++    mnY = aCoord[2].f;
++    mxY = aCoord[3].f;
++    goto geopolyBboxFill;
++  }else{
++    p = geopolyFuncParam(context, pPoly, pRc);
++  }
++  if( p ){
++    int ii;
++    mnX = mxX = p->a[0];
++    mnY = mxY = p->a[1];
++    for(ii=1; ii<p->nVertex; ii++){
++      double r = p->a[ii*2];
++      if( r<mnX ) mnX = (float)r;
++      else if( r>mxX ) mxX = (float)r;
++      r = p->a[ii*2+1];
++      if( r<mnY ) mnY = (float)r;
++      else if( r>mxY ) mxY = (float)r;
++    }
++    if( pRc ) *pRc = SQLITE_OK;
++    if( aCoord==0 ){
++      geopolyBboxFill:
++      pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
++      if( pOut==0 ){
++        sqlite3_free(p);
++        if( context ) sqlite3_result_error_nomem(context);
++        if( pRc ) *pRc = SQLITE_NOMEM;
++        return 0;
++      }
++      pOut->nVertex = 4;
++      ii = 1;
++      pOut->hdr[0] = *(unsigned char*)&ii;
++      pOut->hdr[1] = 0;
++      pOut->hdr[2] = 0;
++      pOut->hdr[3] = 4;
++      pOut->a[0] = mnX;
++      pOut->a[1] = mnY;
++      pOut->a[2] = mxX;
++      pOut->a[3] = mnY;
++      pOut->a[4] = mxX;
++      pOut->a[5] = mxY;
++      pOut->a[6] = mnX;
++      pOut->a[7] = mxY;
++    }else{
++      sqlite3_free(p);
++      aCoord[0].f = mnX;
++      aCoord[1].f = mxX;
++      aCoord[2].f = mnY;
++      aCoord[3].f = mxY;
++    }
++  }
++  return pOut;
++}
++
++/*
++** Implementation of the geopoly_bbox(X) SQL function.
++*/
++static void geopolyBBoxFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyBBox(context, argv[0], 0, 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** State vector for the geopoly_group_bbox() aggregate function.
++*/
++typedef struct GeoBBox GeoBBox;
++struct GeoBBox {
++  int isInit;
++  RtreeCoord a[4];
++};
++
++
++/*
++** Implementation of the geopoly_group_bbox(X) aggregate SQL function.
++*/
++static void geopolyBBoxStep(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  RtreeCoord a[4];
++  int rc = SQLITE_OK;
++  (void)geopolyBBox(context, argv[0], a, &rc);
++  if( rc==SQLITE_OK ){
++    GeoBBox *pBBox;
++    pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox));
++    if( pBBox==0 ) return;
++    if( pBBox->isInit==0 ){
++      pBBox->isInit = 1;
++      memcpy(pBBox->a, a, sizeof(RtreeCoord)*4);
++    }else{
++      if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0];
++      if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1];
++      if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2];
++      if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3];
++    }
++  }
++}
++static void geopolyBBoxFinal(
++  sqlite3_context *context
++){
++  GeoPoly *p;
++  GeoBBox *pBBox;
++  pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0);
++  if( pBBox==0 ) return;
++  p = geopolyBBox(context, 0, pBBox->a, 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++
++/*
++** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2).
++** Returns:
++**
++**    +2  x0,y0 is on the line segement
++**
++**    +1  x0,y0 is beneath line segment
++**
++**    0   x0,y0 is not on or beneath the line segment or the line segment
++**        is vertical and x0,y0 is not on the line segment
++**
++** The left-most coordinate min(x1,x2) is not considered to be part of
++** the line segment for the purposes of this analysis.
++*/
++static int pointBeneathLine(
++  double x0, double y0,
++  double x1, double y1,
++  double x2, double y2
++){
++  double y;
++  if( x0==x1 && y0==y1 ) return 2;
++  if( x1<x2 ){
++    if( x0<=x1 || x0>x2 ) return 0;
++  }else if( x1>x2 ){
++    if( x0<=x2 || x0>x1 ) return 0;
++  }else{
++    /* Vertical line segment */
++    if( x0!=x1 ) return 0;
++    if( y0<y1 && y0<y2 ) return 0;
++    if( y0>y1 && y0>y2 ) return 0;
++    return 2;
++  }
++  y = y1 + (y2-y1)*(x0-x1)/(x2-x1);
++  if( y0==y ) return 2;
++  if( y0<y ) return 1;
++  return 0;
++}
++
++/*
++** SQL function:    geopoly_contains_point(P,X,Y)
++**
++** Return +2 if point X,Y is within polygon P.
++** Return +1 if point X,Y is on the polygon boundary.
++** Return 0 if point X,Y is outside the polygon
++*/
++static void geopolyContainsPointFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  double x0 = sqlite3_value_double(argv[1]);
++  double y0 = sqlite3_value_double(argv[2]);
++  int v = 0;
++  int cnt = 0;
++  int ii;
++  if( p1==0 ) return;
++  for(ii=0; ii<p1->nVertex-1; ii++){
++    v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
++                               p1->a[ii*2+2],p1->a[ii*2+3]);
++    if( v==2 ) break;
++    cnt += v;
++  }
++  if( v!=2 ){
++    v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
++                               p1->a[0],p1->a[1]);
++  }
++  if( v==2 ){
++    sqlite3_result_int(context, 1);
++  }else if( ((v+cnt)&1)==0 ){
++    sqlite3_result_int(context, 0);
++  }else{
++    sqlite3_result_int(context, 2);
++  }
++  sqlite3_free(p1);
++}
++
++/* Forward declaration */
++static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
++
++/*
++** SQL function:    geopoly_within(P1,P2)
++**
++** Return +2 if P1 and P2 are the same polygon
++** Return +1 if P2 is contained within P1
++** Return 0 if any part of P2 is on the outside of P1
++**
++*/
++static void geopolyWithinFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
++  if( p1 && p2 ){
++    int x = geopolyOverlap(p1, p2);
++    if( x<0 ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
++    }
++  }
++  sqlite3_free(p1);
++  sqlite3_free(p2);
++}
++
++/* Objects used by the overlap algorihm. */
++typedef struct GeoEvent GeoEvent;
++typedef struct GeoSegment GeoSegment;
++typedef struct GeoOverlap GeoOverlap;
++struct GeoEvent {
++  double x;              /* X coordinate at which event occurs */
++  int eType;             /* 0 for ADD, 1 for REMOVE */
++  GeoSegment *pSeg;      /* The segment to be added or removed */
++  GeoEvent *pNext;       /* Next event in the sorted list */
++};
++struct GeoSegment {
++  double C, B;           /* y = C*x + B */
++  double y;              /* Current y value */
++  float y0;              /* Initial y value */
++  unsigned char side;    /* 1 for p1, 2 for p2 */
++  unsigned int idx;      /* Which segment within the side */
++  GeoSegment *pNext;     /* Next segment in a list sorted by y */
++};
++struct GeoOverlap {
++  GeoEvent *aEvent;          /* Array of all events */
++  GeoSegment *aSegment;      /* Array of all segments */
++  int nEvent;                /* Number of events */
++  int nSegment;              /* Number of segments */
++};
++
++/*
++** Add a single segment and its associated events.
++*/
++static void geopolyAddOneSegment(
++  GeoOverlap *p,
++  GeoCoord x0,
++  GeoCoord y0,
++  GeoCoord x1,
++  GeoCoord y1,
++  unsigned char side,
++  unsigned int idx
++){
++  GeoSegment *pSeg;
++  GeoEvent *pEvent;
++  if( x0==x1 ) return;  /* Ignore vertical segments */
++  if( x0>x1 ){
++    GeoCoord t = x0;
++    x0 = x1;
++    x1 = t;
++    t = y0;
++    y0 = y1;
++    y1 = t;
++  }
++  pSeg = p->aSegment + p->nSegment;
++  p->nSegment++;
++  pSeg->C = (y1-y0)/(x1-x0);
++  pSeg->B = y1 - x1*pSeg->C;
++  pSeg->y0 = y0;
++  pSeg->side = side;
++  pSeg->idx = idx;
++  pEvent = p->aEvent + p->nEvent;
++  p->nEvent++;
++  pEvent->x = x0;
++  pEvent->eType = 0;
++  pEvent->pSeg = pSeg;
++  pEvent = p->aEvent + p->nEvent;
++  p->nEvent++;
++  pEvent->x = x1;
++  pEvent->eType = 1;
++  pEvent->pSeg = pSeg;
++}
++  
++
++
++/*
++** Insert all segments and events for polygon pPoly.
++*/
++static void geopolyAddSegments(
++  GeoOverlap *p,          /* Add segments to this Overlap object */
++  GeoPoly *pPoly,         /* Take all segments from this polygon */
++  unsigned char side      /* The side of pPoly */
++){
++  unsigned int i;
++  GeoCoord *x;
++  for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
++    x = pPoly->a + (i*2);
++    geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
++  }
++  x = pPoly->a + (i*2);
++  geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
++}
++
++/*
++** Merge two lists of sorted events by X coordinate
++*/
++static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){
++  GeoEvent head, *pLast;
++  head.pNext = 0;
++  pLast = &head;
++  while( pRight && pLeft ){
++    if( pRight->x <= pLeft->x ){
++      pLast->pNext = pRight;
++      pLast = pRight;
++      pRight = pRight->pNext;
++    }else{
++      pLast->pNext = pLeft;
++      pLast = pLeft;
++      pLeft = pLeft->pNext;
++    }
++  }
++  pLast->pNext = pRight ? pRight : pLeft;
++  return head.pNext;  
++}
++
++/*
++** Sort an array of nEvent event objects into a list.
++*/
++static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){
++  int mx = 0;
++  int i, j;
++  GeoEvent *p;
++  GeoEvent *a[50];
++  for(i=0; i<nEvent; i++){
++    p = &aEvent[i];
++    p->pNext = 0;
++    for(j=0; j<mx && a[j]; j++){
++      p = geopolyEventMerge(a[j], p);
++      a[j] = 0;
++    }
++    a[j] = p;
++    if( j>=mx ) mx = j+1;
++  }
++  p = 0;
++  for(i=0; i<mx; i++){
++    p = geopolyEventMerge(a[i], p);
++  }
++  return p;
++}
++
++/*
++** Merge two lists of sorted segments by Y, and then by C.
++*/
++static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){
++  GeoSegment head, *pLast;
++  head.pNext = 0;
++  pLast = &head;
++  while( pRight && pLeft ){
++    double r = pRight->y - pLeft->y;
++    if( r==0.0 ) r = pRight->C - pLeft->C;
++    if( r<0.0 ){
++      pLast->pNext = pRight;
++      pLast = pRight;
++      pRight = pRight->pNext;
++    }else{
++      pLast->pNext = pLeft;
++      pLast = pLeft;
++      pLeft = pLeft->pNext;
++    }
++  }
++  pLast->pNext = pRight ? pRight : pLeft;
++  return head.pNext;  
++}
++
++/*
++** Sort a list of GeoSegments in order of increasing Y and in the event of
++** a tie, increasing C (slope).
++*/
++static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
++  int mx = 0;
++  int i;
++  GeoSegment *p;
++  GeoSegment *a[50];
++  while( pList ){
++    p = pList;
++    pList = pList->pNext;
++    p->pNext = 0;
++    for(i=0; i<mx && a[i]; i++){
++      p = geopolySegmentMerge(a[i], p);
++      a[i] = 0;
++    }
++    a[i] = p;
++    if( i>=mx ) mx = i+1;
++  }
++  p = 0;
++  for(i=0; i<mx; i++){
++    p = geopolySegmentMerge(a[i], p);
++  }
++  return p;
++}
++
++/*
++** Determine the overlap between two polygons
++*/
++static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
++  int nVertex = p1->nVertex + p2->nVertex + 2;
++  GeoOverlap *p;
++  int nByte;
++  GeoEvent *pThisEvent;
++  double rX;
++  int rc = 0;
++  int needSort = 0;
++  GeoSegment *pActive = 0;
++  GeoSegment *pSeg;
++  unsigned char aOverlap[4];
++
++  nByte = sizeof(GeoEvent)*nVertex*2 
++           + sizeof(GeoSegment)*nVertex 
++           + sizeof(GeoOverlap);
++  p = sqlite3_malloc( nByte );
++  if( p==0 ) return -1;
++  p->aEvent = (GeoEvent*)&p[1];
++  p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
++  p->nEvent = p->nSegment = 0;
++  geopolyAddSegments(p, p1, 1);
++  geopolyAddSegments(p, p2, 2);
++  pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
++  rX = pThisEvent->x==0.0 ? -1.0 : 0.0;
++  memset(aOverlap, 0, sizeof(aOverlap));
++  while( pThisEvent ){
++    if( pThisEvent->x!=rX ){
++      GeoSegment *pPrev = 0;
++      int iMask = 0;
++      GEODEBUG(("Distinct X: %g\n", pThisEvent->x));
++      rX = pThisEvent->x;
++      if( needSort ){
++        GEODEBUG(("SORT\n"));
++        pActive = geopolySortSegmentsByYAndC(pActive);
++        needSort = 0;
++      }
++      for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++        if( pPrev ){
++          if( pPrev->y!=pSeg->y ){
++            GEODEBUG(("MASK: %d\n", iMask));
++            aOverlap[iMask] = 1;
++          }
++        }
++        iMask ^= pSeg->side;
++        pPrev = pSeg;
++      }
++      pPrev = 0;
++      for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++        double y = pSeg->C*rX + pSeg->B;
++        GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y));
++        pSeg->y = y;
++        if( pPrev ){
++          if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){
++            rc = 1;
++            GEODEBUG(("Crossing: %d.%d and %d.%d\n",
++                    pPrev->side, pPrev->idx,
++                    pSeg->side, pSeg->idx));
++            goto geopolyOverlapDone;
++          }else if( pPrev->y!=pSeg->y ){
++            GEODEBUG(("MASK: %d\n", iMask));
++            aOverlap[iMask] = 1;
++          }
++        }
++        iMask ^= pSeg->side;
++        pPrev = pSeg;
++      }
++    }
++    GEODEBUG(("%s %d.%d C=%g B=%g\n",
++      pThisEvent->eType ? "RM " : "ADD",
++      pThisEvent->pSeg->side, pThisEvent->pSeg->idx,
++      pThisEvent->pSeg->C,
++      pThisEvent->pSeg->B));
++    if( pThisEvent->eType==0 ){
++      /* Add a segment */
++      pSeg = pThisEvent->pSeg;
++      pSeg->y = pSeg->y0;
++      pSeg->pNext = pActive;
++      pActive = pSeg;
++      needSort = 1;
++    }else{
++      /* Remove a segment */
++      if( pActive==pThisEvent->pSeg ){
++        pActive = pActive->pNext;
++      }else{
++        for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++          if( pSeg->pNext==pThisEvent->pSeg ){
++            pSeg->pNext = pSeg->pNext->pNext;
++            break;
++          }
++        }
++      }
++    }
++    pThisEvent = pThisEvent->pNext;
++  }
++  if( aOverlap[3]==0 ){
++    rc = 0;
++  }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){
++    rc = 3;
++  }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){
++    rc = 2;
++  }else if( aOverlap[1]==0 && aOverlap[2]==0 ){
++    rc = 4;
++  }else{
++    rc = 1;
++  }
++
++geopolyOverlapDone:
++  sqlite3_free(p);
++  return rc;
++}
++
++/*
++** SQL function:    geopoly_overlap(P1,P2)
++**
++** Determine whether or not P1 and P2 overlap. Return value:
++**
++**   0     The two polygons are disjoint
++**   1     They overlap
++**   2     P1 is completely contained within P2
++**   3     P2 is completely contained within P1
++**   4     P1 and P2 are the same polygon
++**   NULL  Either P1 or P2 or both are not valid polygons
++*/
++static void geopolyOverlapFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
++  if( p1 && p2 ){
++    int x = geopolyOverlap(p1, p2);
++    if( x<0 ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_int(context, x);
++    }
++  }
++  sqlite3_free(p1);
++  sqlite3_free(p2);
++}
++
++/*
++** Enable or disable debugging output
++*/
++static void geopolyDebugFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++#ifdef GEOPOLY_ENABLE_DEBUG
++  geo_debug = sqlite3_value_int(argv[0]);
++#endif
++}
++
++/* 
++** This function is the implementation of both the xConnect and xCreate
++** methods of the geopoly virtual table.
++**
++**   argv[0]   -> module name
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**   argv[...] -> column names...
++*/
++static int geopolyInit(
++  sqlite3 *db,                        /* Database connection */
++  void *pAux,                         /* One of the RTREE_COORD_* constants */
++  int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */
++  sqlite3_vtab **ppVtab,              /* OUT: New virtual table */
++  char **pzErr,                       /* OUT: Error message, if any */
++  int isCreate                        /* True for xCreate, false for xConnect */
++){
++  int rc = SQLITE_OK;
++  Rtree *pRtree;
++  int nDb;              /* Length of string argv[1] */
++  int nName;            /* Length of string argv[2] */
++  sqlite3_str *pSql;
++  char *zSql;
++  int ii;
++
++  sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
++
++  /* Allocate the sqlite3_vtab structure */
++  nDb = (int)strlen(argv[1]);
++  nName = (int)strlen(argv[2]);
++  pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
++  if( !pRtree ){
++    return SQLITE_NOMEM;
++  }
++  memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
++  pRtree->nBusy = 1;
++  pRtree->base.pModule = &rtreeModule;
++  pRtree->zDb = (char *)&pRtree[1];
++  pRtree->zName = &pRtree->zDb[nDb+1];
++  pRtree->eCoordType = RTREE_COORD_REAL32;
++  pRtree->nDim = 2;
++  pRtree->nDim2 = 4;
++  memcpy(pRtree->zDb, argv[1], nDb);
++  memcpy(pRtree->zName, argv[2], nName);
++
++
++  /* Create/Connect to the underlying relational database schema. If
++  ** that is successful, call sqlite3_declare_vtab() to configure
++  ** the r-tree table schema.
++  */
++  pSql = sqlite3_str_new(db);
++  sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape");
++  pRtree->nAux = 1;         /* Add one for _shape */
++  pRtree->nAuxNotNull = 1;  /* The _shape column is always not-null */
++  for(ii=3; ii<argc; ii++){
++    pRtree->nAux++;
++    sqlite3_str_appendf(pSql, ",%s", argv[ii]);
++  }
++  sqlite3_str_appendf(pSql, ");");
++  zSql = sqlite3_str_finish(pSql);
++  if( !zSql ){
++    rc = SQLITE_NOMEM;
++  }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++  sqlite3_free(zSql);
++  if( rc ) goto geopolyInit_fail;
++  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
++
++  /* Figure out the node size to use. */
++  rc = getNodeSize(db, pRtree, isCreate, pzErr);
++  if( rc ) goto geopolyInit_fail;
++  rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
++  if( rc ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    goto geopolyInit_fail;
++  }
++
++  *ppVtab = (sqlite3_vtab *)pRtree;
++  return SQLITE_OK;
++
++geopolyInit_fail:
++  if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
++  assert( *ppVtab==0 );
++  assert( pRtree->nBusy==1 );
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++
++/* 
++** GEOPOLY virtual table module xCreate method.
++*/
++static int geopolyCreate(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
++}
++
++/* 
++** GEOPOLY virtual table module xConnect method.
++*/
++static int geopolyConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
++}
++
++
++/* 
++** GEOPOLY virtual table module xFilter method.
++**
++** Query plans:
++**
++**      1         rowid lookup
++**      2         search for objects overlapping the same bounding box
++**                that contains polygon argv[0]
++**      3         search for objects overlapping the same bounding box
++**                that contains polygon argv[0]
++**      4         full table scan
++*/
++static int geopolyFilter(
++  sqlite3_vtab_cursor *pVtabCursor,     /* The cursor to initialize */
++  int idxNum,                           /* Query plan */
++  const char *idxStr,                   /* Not Used */
++  int argc, sqlite3_value **argv        /* Parameters to the query plan */
++){
++  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
++  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
++  RtreeNode *pRoot = 0;
++  int rc = SQLITE_OK;
++  int iCell = 0;
++  sqlite3_stmt *pStmt;
++
++  rtreeReference(pRtree);
++
++  /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
++  freeCursorConstraints(pCsr);
++  sqlite3_free(pCsr->aPoint);
++  pStmt = pCsr->pReadAux;
++  memset(pCsr, 0, sizeof(RtreeCursor));
++  pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
++  pCsr->pReadAux = pStmt;
++
++  pCsr->iStrategy = idxNum;
++  if( idxNum==1 ){
++    /* Special case - lookup by rowid. */
++    RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
++    RtreeSearchPoint *p;     /* Search point for the leaf */
++    i64 iRowid = sqlite3_value_int64(argv[0]);
++    i64 iNode = 0;
++    rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
++    if( rc==SQLITE_OK && pLeaf!=0 ){
++      p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
++      assert( p!=0 );  /* Always returns pCsr->sPoint */
++      pCsr->aNode[0] = pLeaf;
++      p->id = iNode;
++      p->eWithin = PARTLY_WITHIN;
++      rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
++      p->iCell = (u8)iCell;
++      RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
++    }else{
++      pCsr->atEOF = 1;
++    }
++  }else{
++    /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array 
++    ** with the configured constraints. 
++    */
++    rc = nodeAcquire(pRtree, 1, 0, &pRoot);
++    if( rc==SQLITE_OK && idxNum<=3 ){
++      RtreeCoord bbox[4];
++      RtreeConstraint *p;
++      assert( argc==1 );
++      geopolyBBox(0, argv[0], bbox, &rc);
++      if( rc ){
++        goto geopoly_filter_end;
++      }
++      pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
++      pCsr->nConstraint = 4;
++      if( p==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4);
++        memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
++        if( idxNum==2 ){
++          /* Overlap query */
++          p->op = 'B';
++          p->iCoord = 0;
++          p->u.rValue = bbox[1].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 1;
++          p->u.rValue = bbox[0].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 2;
++          p->u.rValue = bbox[3].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 3;
++          p->u.rValue = bbox[2].f;
++        }else{
++          /* Within query */
++          p->op = 'D';
++          p->iCoord = 0;
++          p->u.rValue = bbox[0].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 1;
++          p->u.rValue = bbox[1].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 2;
++          p->u.rValue = bbox[2].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 3;
++          p->u.rValue = bbox[3].f;
++        }
++      }
++    }
++    if( rc==SQLITE_OK ){
++      RtreeSearchPoint *pNew;
++      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
++        goto geopoly_filter_end;
++      }
++      pNew->id = 1;
++      pNew->iCell = 0;
++      pNew->eWithin = PARTLY_WITHIN;
++      assert( pCsr->bPoint==1 );
++      pCsr->aNode[0] = pRoot;
++      pRoot = 0;
++      RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
++      rc = rtreeStepToLeaf(pCsr);
++    }
++  }
++
++geopoly_filter_end:
++  nodeRelease(pRtree, pRoot);
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++/*
++** Rtree virtual table module xBestIndex method. There are three
++** table scan strategies to choose from (in order from most to 
++** least desirable):
++**
++**   idxNum     idxStr        Strategy
++**   ------------------------------------------------
++**     1        "rowid"       Direct lookup by rowid.
++**     2        "rtree"       R-tree overlap query using geopoly_overlap()
++**     3        "rtree"       R-tree within query using geopoly_within()
++**     4        "fullscan"    full-table scan.
++**   ------------------------------------------------
++*/
++static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
++  int ii;
++  int iRowidTerm = -1;
++  int iFuncTerm = -1;
++  int idxNum = 0;
++
++  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
++    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
++    if( !p->usable ) continue;
++    if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ  ){
++      iRowidTerm = ii;
++      break;
++    }
++    if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
++      /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap()
++      ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within().
++      ** See geopolyFindFunction() */
++      iFuncTerm = ii;
++      idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2;
++    }
++  }
++
++  if( iRowidTerm>=0 ){
++    pIdxInfo->idxNum = 1;
++    pIdxInfo->idxStr = "rowid";
++    pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
++    pIdxInfo->estimatedCost = 30.0;
++    pIdxInfo->estimatedRows = 1;
++    pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
++    return SQLITE_OK;
++  }
++  if( iFuncTerm>=0 ){
++    pIdxInfo->idxNum = idxNum;
++    pIdxInfo->idxStr = "rtree";
++    pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0;
++    pIdxInfo->estimatedCost = 300.0;
++    pIdxInfo->estimatedRows = 10;
++    return SQLITE_OK;
++  }
++  pIdxInfo->idxNum = 4;
++  pIdxInfo->idxStr = "fullscan";
++  pIdxInfo->estimatedCost = 3000000.0;
++  pIdxInfo->estimatedRows = 100000;
++  return SQLITE_OK;
++}
++
++
++/* 
++** GEOPOLY virtual table module xColumn method.
++*/
++static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
++  Rtree *pRtree = (Rtree *)cur->pVtab;
++  RtreeCursor *pCsr = (RtreeCursor *)cur;
++  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
++  int rc = SQLITE_OK;
++  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
++
++  if( rc ) return rc;
++  if( p==0 ) return SQLITE_OK;
++  if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK;
++  if( i<=pRtree->nAux ){
++    if( !pCsr->bAuxValid ){
++      if( pCsr->pReadAux==0 ){
++        rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
++                                &pCsr->pReadAux, 0);
++        if( rc ) return rc;
++      }
++      sqlite3_bind_int64(pCsr->pReadAux, 1, 
++          nodeGetRowid(pRtree, pNode, p->iCell));
++      rc = sqlite3_step(pCsr->pReadAux);
++      if( rc==SQLITE_ROW ){
++        pCsr->bAuxValid = 1;
++      }else{
++        sqlite3_reset(pCsr->pReadAux);
++        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++        return rc;
++      }
++    }
++    sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2));
++  }
++  return SQLITE_OK;
++}
++
++
++/*
++** The xUpdate method for GEOPOLY module virtual tables.
++**
++** For DELETE:
++**
++**     argv[0] = the rowid to be deleted
++**
++** For INSERT:
++**
++**     argv[0] = SQL NULL
++**     argv[1] = rowid to insert, or an SQL NULL to select automatically
++**     argv[2] = _shape column
++**     argv[3] = first application-defined column....
++**
++** For UPDATE:
++**
++**     argv[0] = rowid to modify.  Never NULL
++**     argv[1] = rowid after the change.  Never NULL
++**     argv[2] = new value for _shape
++**     argv[3] = new value for first application-defined column....
++*/
++static int geopolyUpdate(
++  sqlite3_vtab *pVtab, 
++  int nData, 
++  sqlite3_value **aData, 
++  sqlite_int64 *pRowid
++){
++  Rtree *pRtree = (Rtree *)pVtab;
++  int rc = SQLITE_OK;
++  RtreeCell cell;                 /* New cell to insert if nData>1 */
++  i64 oldRowid;                   /* The old rowid */
++  int oldRowidValid;              /* True if oldRowid is valid */
++  i64 newRowid;                   /* The new rowid */
++  int newRowidValid;              /* True if newRowid is valid */
++  int coordChange = 0;            /* Change in coordinates */
++
++  if( pRtree->nNodeRef ){
++    /* Unable to write to the btree while another cursor is reading from it,
++    ** since the write might do a rebalance which would disrupt the read
++    ** cursor. */
++    return SQLITE_LOCKED_VTAB;
++  }
++  rtreeReference(pRtree);
++  assert(nData>=1);
++
++  oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;;
++  oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0;
++  newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL;
++  newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0;
++  cell.iRowid = newRowid;
++
++  if( nData>1                                 /* not a DELETE */
++   && (!oldRowidValid                         /* INSERT */
++        || !sqlite3_value_nochange(aData[2])  /* UPDATE _shape */
++        || oldRowid!=newRowid)                /* Rowid change */
++  ){
++    geopolyBBox(0, aData[2], cell.aCoord, &rc);
++    if( rc ){
++      if( rc==SQLITE_ERROR ){
++        pVtab->zErrMsg =
++          sqlite3_mprintf("_shape does not contain a valid polygon");
++      }
++      goto geopoly_update_end;
++    }
++    coordChange = 1;
++
++    /* If a rowid value was supplied, check if it is already present in 
++    ** the table. If so, the constraint has failed. */
++    if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){
++      int steprc;
++      sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
++      steprc = sqlite3_step(pRtree->pReadRowid);
++      rc = sqlite3_reset(pRtree->pReadRowid);
++      if( SQLITE_ROW==steprc ){
++        if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
++          rc = rtreeDeleteRowid(pRtree, cell.iRowid);
++        }else{
++          rc = rtreeConstraintError(pRtree, 0);
++        }
++      }
++    }
++  }
++
++  /* If aData[0] is not an SQL NULL value, it is the rowid of a
++  ** record to delete from the r-tree table. The following block does
++  ** just that.
++  */
++  if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){
++    rc = rtreeDeleteRowid(pRtree, oldRowid);
++  }
++
++  /* If the aData[] array contains more than one element, elements
++  ** (aData[2]..aData[argc-1]) contain a new record to insert into
++  ** the r-tree structure.
++  */
++  if( rc==SQLITE_OK && nData>1 && coordChange ){
++    /* Insert the new record into the r-tree */
++    RtreeNode *pLeaf = 0;
++    if( !newRowidValid ){
++      rc = rtreeNewRowid(pRtree, &cell.iRowid);
++    }
++    *pRowid = cell.iRowid;
++    if( rc==SQLITE_OK ){
++      rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
++    }
++    if( rc==SQLITE_OK ){
++      int rc2;
++      pRtree->iReinsertHeight = -1;
++      rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
++      rc2 = nodeRelease(pRtree, pLeaf);
++      if( rc==SQLITE_OK ){
++        rc = rc2;
++      }
++    }
++  }
++
++  /* Change the data */
++  if( rc==SQLITE_OK && nData>1 ){
++    sqlite3_stmt *pUp = pRtree->pWriteAux;
++    int jj;
++    int nChange = 0;
++    sqlite3_bind_int64(pUp, 1, cell.iRowid);
++    assert( pRtree->nAux>=1 );
++    if( sqlite3_value_nochange(aData[2]) ){
++      sqlite3_bind_null(pUp, 2);
++    }else{
++      GeoPoly *p = 0;
++      if( sqlite3_value_type(aData[2])==SQLITE_TEXT
++       && (p = geopolyFuncParam(0, aData[2], &rc))!=0
++       && rc==SQLITE_OK
++      ){
++        sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
++      }else{
++        sqlite3_bind_value(pUp, 2, aData[2]);
++      }
++      sqlite3_free(p);
++      nChange = 1;
++    }
++    for(jj=1; jj<pRtree->nAux; jj++){
++      nChange++;
++      sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
++    }
++    if( nChange ){
++      sqlite3_step(pUp);
++      rc = sqlite3_reset(pUp);
++    }
++  }
++
++geopoly_update_end:
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++/*
++** Report that geopoly_overlap() is an overloaded function suitable
++** for use in xBestIndex.
++*/
++static int geopolyFindFunction(
++  sqlite3_vtab *pVtab,
++  int nArg,
++  const char *zName,
++  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
++  void **ppArg
++){
++  if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){
++    *pxFunc = geopolyOverlapFunc;
++    *ppArg = 0;
++    return SQLITE_INDEX_CONSTRAINT_FUNCTION;
++  }
++  if( sqlite3_stricmp(zName, "geopoly_within")==0 ){
++    *pxFunc = geopolyWithinFunc;
++    *ppArg = 0;
++    return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
++  }
++  return 0;
++}
++
++
++static sqlite3_module geopolyModule = {
++  3,                          /* iVersion */
++  geopolyCreate,              /* xCreate - create a table */
++  geopolyConnect,             /* xConnect - connect to an existing table */
++  geopolyBestIndex,           /* xBestIndex - Determine search strategy */
++  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
++  rtreeDestroy,               /* xDestroy - Drop a table */
++  rtreeOpen,                  /* xOpen - open a cursor */
++  rtreeClose,                 /* xClose - close a cursor */
++  geopolyFilter,              /* xFilter - configure scan constraints */
++  rtreeNext,                  /* xNext - advance a cursor */
++  rtreeEof,                   /* xEof */
++  geopolyColumn,              /* xColumn - read data */
++  rtreeRowid,                 /* xRowid - read data */
++  geopolyUpdate,              /* xUpdate - write data */
++  rtreeBeginTransaction,      /* xBegin - begin transaction */
++  rtreeEndTransaction,        /* xSync - sync transaction */
++  rtreeEndTransaction,        /* xCommit - commit transaction */
++  rtreeEndTransaction,        /* xRollback - rollback transaction */
++  geopolyFindFunction,        /* xFindFunction - function overloading */
++  rtreeRename,                /* xRename - rename the table */
++  rtreeSavepoint,             /* xSavepoint */
++  0,                          /* xRelease */
++  0,                          /* xRollbackTo */
++  rtreeShadowName             /* xShadowName */
++};
++
++static int sqlite3_geopoly_init(sqlite3 *db){
++  int rc = SQLITE_OK;
++  static const struct {
++    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
++    signed char nArg;
++    unsigned char bPure;
++    const char *zName;
++  } aFunc[] = {
++     { geopolyAreaFunc,          1, 1,    "geopoly_area"             },
++     { geopolyBlobFunc,          1, 1,    "geopoly_blob"             },
++     { geopolyJsonFunc,          1, 1,    "geopoly_json"             },
++     { geopolySvgFunc,          -1, 1,    "geopoly_svg"              },
++     { geopolyWithinFunc,        2, 1,    "geopoly_within"           },
++     { geopolyContainsPointFunc, 3, 1,    "geopoly_contains_point"   },
++     { geopolyOverlapFunc,       2, 1,    "geopoly_overlap"          },
++     { geopolyDebugFunc,         1, 0,    "geopoly_debug"            },
++     { geopolyBBoxFunc,          1, 1,    "geopoly_bbox"             },
++     { geopolyXformFunc,         7, 1,    "geopoly_xform"            },
++     { geopolyRegularFunc,       4, 1,    "geopoly_regular"          },
++     { geopolyCcwFunc,           1, 1,    "geopoly_ccw"              },
++  };
++  static const struct {
++    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
++    void (*xFinal)(sqlite3_context*);
++    const char *zName;
++  } aAgg[] = {
++     { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox"    },
++  };
++  int i;
++  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
++    int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
++    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
++                                 enc, 0,
++                                 aFunc[i].xFunc, 0, 0);
++  }
++  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
++                                 0, aAgg[i].xStep, aAgg[i].xFinal);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0);
++  }
++  return rc;
++}
++
++/************** End of geopoly.c *********************************************/
++/************** Continuing where we left off in rtree.c **********************/
++#endif
++
++/*
+ ** Register the r-tree module with database handle db. This creates the
+ ** virtual table module "rtree" and the debugging/analysis scalar 
+ ** function "rtreenode".
+@@ -168878,6 +185189,9 @@
+     rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
+   }
+   if( rc==SQLITE_OK ){
++    rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0);
++  }
++  if( rc==SQLITE_OK ){
+ #ifdef SQLITE_RTREE_INT_ONLY
+     void *c = (void *)RTREE_COORD_INT32;
+ #else
+@@ -168889,6 +185203,11 @@
+     void *c = (void *)RTREE_COORD_INT32;
+     rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
+   }
++#ifdef SQLITE_ENABLE_GEOPOLY
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_geopoly_init(db);
++  }
++#endif
+ 
+   return rc;
+ }
+@@ -169063,7 +185382,9 @@
+ **     provide case-independent matching.
+ */
+ 
+-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
++#if !defined(SQLITE_CORE)                  \
++ || defined(SQLITE_ENABLE_ICU)             \
++ || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+ 
+ /* Include ICU headers */
+ #include <unicode/utypes.h>
+@@ -169081,6 +185402,26 @@
+ #endif
+ 
+ /*
++** This function is called when an ICU function called from within
++** the implementation of an SQL scalar function returns an error.
++**
++** The scalar function context passed as the first argument is 
++** loaded with an error message based on the following two args.
++*/
++static void icuFunctionError(
++  sqlite3_context *pCtx,       /* SQLite scalar function context */
++  const char *zName,           /* Name of ICU function that failed */
++  UErrorCode e                 /* Error code returned by ICU function */
++){
++  char zBuf[128];
++  sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
++  zBuf[127] = '\0';
++  sqlite3_result_error(pCtx, zBuf, -1);
++}
++
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
++
++/*
+ ** Maximum length (in bytes) of the pattern in a LIKE or GLOB
+ ** operator.
+ */
+@@ -169137,8 +185478,8 @@
+   const uint8_t *zString,    /* The UTF-8 string to compare against */
+   const UChar32 uEsc         /* The escape character */
+ ){
+-  static const int MATCH_ONE = (UChar32)'_';
+-  static const int MATCH_ALL = (UChar32)'%';
++  static const uint32_t MATCH_ONE = (uint32_t)'_';
++  static const uint32_t MATCH_ALL = (uint32_t)'%';
+ 
+   int prevEscape = 0;     /* True if the previous character was uEsc */
+ 
+@@ -169145,7 +185486,7 @@
+   while( 1 ){
+ 
+     /* Read (and consume) the next character from the input pattern. */
+-    UChar32 uPattern;
++    uint32_t uPattern;
+     SQLITE_ICU_READ_UTF8(zPattern, uPattern);
+     if( uPattern==0 ) break;
+ 
+@@ -169187,16 +185528,16 @@
+       if( *zString==0 ) return 0;
+       SQLITE_ICU_SKIP_UTF8(zString);
+ 
+-    }else if( !prevEscape && uPattern==uEsc){
++    }else if( !prevEscape && uPattern==(uint32_t)uEsc){
+       /* Case 3. */
+       prevEscape = 1;
+ 
+     }else{
+       /* Case 4. */
+-      UChar32 uString;
++      uint32_t uString;
+       SQLITE_ICU_READ_UTF8(zString, uString);
+-      uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
+-      uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
++      uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT);
++      uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT);
+       if( uString!=uPattern ){
+         return 0;
+       }
+@@ -169260,24 +185601,6 @@
+ }
+ 
+ /*
+-** This function is called when an ICU function called from within
+-** the implementation of an SQL scalar function returns an error.
+-**
+-** The scalar function context passed as the first argument is 
+-** loaded with an error message based on the following two args.
+-*/
+-static void icuFunctionError(
+-  sqlite3_context *pCtx,       /* SQLite scalar function context */
+-  const char *zName,           /* Name of ICU function that failed */
+-  UErrorCode e                 /* Error code returned by ICU function */
+-){
+-  char zBuf[128];
+-  sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
+-  zBuf[127] = '\0';
+-  sqlite3_result_error(pCtx, zBuf, -1);
+-}
+-
+-/*
+ ** Function to delete compiled regexp objects. Registered as
+ ** a destructor function with sqlite3_set_auxdata().
+ */
+@@ -169442,6 +185765,8 @@
+   assert( 0 );     /* Unreachable */
+ }
+ 
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
++
+ /*
+ ** Collation sequence destructor function. The pCtx argument points to
+ ** a UCollator structure previously allocated using ucol_open().
+@@ -169536,6 +185861,7 @@
+     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+   } scalars[] = {
+     {"icu_load_collation",  2, SQLITE_UTF8,                1, icuLoadCollation},
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+     {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC,         0, icuRegexpFunc},
+     {"lower",  1, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
+     {"lower",  2, SQLITE_UTF16|SQLITE_DETERMINISTIC,       0, icuCaseFunc16},
+@@ -169547,10 +185873,10 @@
+     {"upper",  2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        1, icuCaseFunc16},
+     {"like",   2, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
+     {"like",   3, SQLITE_UTF8|SQLITE_DETERMINISTIC,        0, icuLikeFunc},
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
+   };
+   int rc = SQLITE_OK;
+   int i;
+-
+   
+   for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
+     const struct IcuScalar *p = &scalars[i];
+@@ -170293,6 +186619,28 @@
+ );
+ 
+ /*
++** Configure a limit for the amount of temp space that may be used by
++** the RBU handle passed as the first argument. The new limit is specified
++** in bytes by the second parameter. If it is positive, the limit is updated.
++** If the second parameter to this function is passed zero, then the limit
++** is removed entirely. If the second parameter is negative, the limit is
++** not modified (this is useful for querying the current limit).
++**
++** In all cases the returned value is the current limit in bytes (zero 
++** indicates unlimited).
++**
++** If the temp space limit is exceeded during operation, an SQLITE_FULL
++** error is returned.
++*/
++SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64);
++
++/*
++** Return the current amount of temp file space, in bytes, currently used by 
++** the RBU handle passed as the only argument.
++*/
++SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*);
++
++/*
+ ** Internally, each RBU connection uses a separate SQLite database 
+ ** connection to access the target and rbu update databases. This
+ ** API allows the application direct access to these database handles.
+@@ -170418,7 +186766,7 @@
+ ** table exists but is not correctly populated, the value of the *pnOne
+ ** output variable during stage 1 is undefined.
+ */
+-SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
++SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo);
+ 
+ /*
+ ** Obtain an indication as to the current stage of an RBU update or vacuum.
+@@ -170528,6 +186876,13 @@
+ /* Maximum number of prepared UPDATE statements held by this module */
+ #define SQLITE_RBU_UPDATE_CACHESIZE 16
+ 
++/* Delta checksums disabled by default.  Compile with -DRBU_ENABLE_DELTA_CKSUM
++** to enable checksum verification.
++*/
++#ifndef RBU_ENABLE_DELTA_CKSUM
++# define RBU_ENABLE_DELTA_CKSUM 0
++#endif
++
+ /*
+ ** Swap two objects of type TYPE.
+ */
+@@ -170578,6 +186933,10 @@
+ **
+ ** RBU_STATE_OALSZ:
+ **   Valid if STAGE==1. The size in bytes of the *-oal file.
++**
++** RBU_STATE_DATATBL:
++**   Only valid if STAGE==1. The RBU database name of the table 
++**   currently being read.
+ */
+ #define RBU_STATE_STAGE        1
+ #define RBU_STATE_TBL          2
+@@ -170588,6 +186947,7 @@
+ #define RBU_STATE_COOKIE       7
+ #define RBU_STATE_OALSZ        8
+ #define RBU_STATE_PHASEONESTEP 9
++#define RBU_STATE_DATATBL     10
+ 
+ #define RBU_STAGE_OAL         1
+ #define RBU_STAGE_MOVE        2
+@@ -170630,6 +186990,7 @@
+ struct RbuState {
+   int eStage;
+   char *zTbl;
++  char *zDataTbl;
+   char *zIdx;
+   i64 iWalCksum;
+   int nRow;
+@@ -170803,6 +187164,8 @@
+   int pgsz;
+   u8 *aBuf;
+   i64 iWalCksum;
++  i64 szTemp;                     /* Current size of all temp files in use */
++  i64 szTempLimit;                /* Total size limit for temp files */
+ 
+   /* Used in RBU vacuum mode only */
+   int nRbu;                       /* Number of RBU VFS in the stack */
+@@ -170811,17 +187174,27 @@
+ 
+ /*
+ ** An rbu VFS is implemented using an instance of this structure.
++**
++** Variable pRbu is only non-NULL for automatically created RBU VFS objects.
++** It is NULL for RBU VFS objects created explicitly using
++** sqlite3rbu_create_vfs(). It is used to track the total amount of temp
++** space used by the RBU handle.
+ */
+ struct rbu_vfs {
+   sqlite3_vfs base;               /* rbu VFS shim methods */
+   sqlite3_vfs *pRealVfs;          /* Underlying VFS */
+   sqlite3_mutex *mutex;           /* Mutex to protect pMain */
+-  rbu_file *pMain;                /* Linked list of main db files */
++  sqlite3rbu *pRbu;               /* Owner RBU object */
++  rbu_file *pMain;                /* List of main db files */
++  rbu_file *pMainRbu;             /* List of main db files with pRbu!=0 */
+ };
+ 
+ /*
+ ** Each file opened by an rbu VFS is represented by an instance of
+ ** the following structure.
++**
++** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable
++** "sz" is set to the current size of the database file.
+ */
+ struct rbu_file {
+   sqlite3_file base;              /* sqlite3_file methods */
+@@ -170828,6 +187201,7 @@
+   sqlite3_file *pReal;            /* Underlying file handle */
+   rbu_vfs *pRbuVfs;               /* Pointer to the rbu_vfs object */
+   sqlite3rbu *pRbu;               /* Pointer to rbu object (rbu target only) */
++  i64 sz;                         /* Size of file in bytes (temp only) */
+ 
+   int openFlags;                  /* Flags this file was opened with */
+   u32 iCookie;                    /* Cookie value for main db files */
+@@ -170841,6 +187215,7 @@
+   const char *zWal;               /* Wal filename for this main db file */
+   rbu_file *pWalFd;               /* Wal file descriptor for this main db */
+   rbu_file *pMainNext;            /* Next MAIN_DB file */
++  rbu_file *pMainRbuNext;         /* Next MAIN_DB file with pRbu!=0 */
+ };
+ 
+ /*
+@@ -170890,6 +187265,7 @@
+   return v;
+ }
+ 
++#if RBU_ENABLE_DELTA_CKSUM
+ /*
+ ** Compute a 32-bit checksum on the N-byte buffer.  Return the result.
+ */
+@@ -170924,6 +187300,7 @@
+   }
+   return sum3;
+ }
++#endif
+ 
+ /*
+ ** Apply a delta.
+@@ -170954,7 +187331,7 @@
+ ){
+   unsigned int limit;
+   unsigned int total = 0;
+-#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
++#if RBU_ENABLE_DELTA_CKSUM
+   char *zOrigOut = zOut;
+ #endif
+ 
+@@ -171009,7 +187386,7 @@
+       case ';': {
+         zDelta++; lenDelta--;
+         zOut[0] = 0;
+-#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
++#if RBU_ENABLE_DELTA_CKSUM
+         if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
+           /* ERROR:  bad checksum */
+           return -1;
+@@ -172217,7 +188594,7 @@
+         int iCid = sqlite3_column_int(pXInfo, 1);
+         int bDesc = sqlite3_column_int(pXInfo, 3);
+         const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+-        zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, 
++        zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, 
+             iCid, pIter->azTblType[iCid], zCollate
+         );
+         zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
+@@ -172278,7 +188655,7 @@
+         ** "PRIMARY KEY" to the imposter table column declaration. */
+         zPk = "PRIMARY KEY ";
+       }
+-      zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", 
++      zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", 
+           zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
+           (pIter->abNotNull[iCol] ? " NOT NULL" : "")
+       );
+@@ -172679,6 +189056,7 @@
+ static void rbuFreeState(RbuState *p){
+   if( p ){
+     sqlite3_free(p->zTbl);
++    sqlite3_free(p->zDataTbl);
+     sqlite3_free(p->zIdx);
+     sqlite3_free(p);
+   }
+@@ -172749,6 +189127,10 @@
+         pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
+         break;
+ 
++      case RBU_STATE_DATATBL:
++        pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
++        break;
++
+       default:
+         rc = SQLITE_CORRUPT;
+         break;
+@@ -173523,7 +189905,8 @@
+           "(%d, %lld), "
+           "(%d, %lld), "
+           "(%d, %lld), "
+-          "(%d, %lld) ",
++          "(%d, %lld), "
++          "(%d, %Q)  ",
+           p->zStateDb,
+           RBU_STATE_STAGE, eStage,
+           RBU_STATE_TBL, p->objiter.zTbl, 
+@@ -173533,7 +189916,8 @@
+           RBU_STATE_CKPT, p->iWalCksum,
+           RBU_STATE_COOKIE, (i64)pFd->iCookie,
+           RBU_STATE_OALSZ, p->iOalSz,
+-          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
++          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
++          RBU_STATE_DATATBL, p->objiter.zDataTbl
+       )
+     );
+     assert( pInsert==0 || rc==SQLITE_OK );
+@@ -173789,7 +190173,8 @@
+ 
+     while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
+        || rbuStrCompare(pIter->zIdx, pState->zIdx)
+-       || rbuStrCompare(pIter->zTbl, pState->zTbl) 
++       || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl))
++       || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl))
+     )){
+       rc = rbuObjIterNext(p, pIter);
+     }
+@@ -173841,6 +190226,7 @@
+     sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
+     assert( pVfs );
+     p->zVfsName = pVfs->zName;
++    ((rbu_vfs*)pVfs)->pRbu = p;
+   }
+ }
+ 
+@@ -174213,6 +190599,7 @@
+     /* Close the open database handle and VFS object. */
+     sqlite3_close(p->dbRbu);
+     sqlite3_close(p->dbMain);
++    assert( p->szTemp==0 );
+     rbuDeleteVfs(p);
+     sqlite3_free(p->aBuf);
+     sqlite3_free(p->aFrame);
+@@ -174400,6 +190787,7 @@
+ */
+ 
+ static void rbuUnlockShm(rbu_file *p){
++  assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
+   if( p->pRbu ){
+     int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
+     int i;
+@@ -174413,6 +190801,81 @@
+ }
+ 
+ /*
++*/
++static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
++  sqlite3rbu *pRbu = pFd->pRbu;
++  i64 nDiff = nNew - pFd->sz;
++  pRbu->szTemp += nDiff;
++  pFd->sz = nNew;
++  assert( pRbu->szTemp>=0 );
++  if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
++  return SQLITE_OK;
++}
++
++/*
++** Add an item to the main-db lists, if it is not already present.
++**
++** There are two main-db lists. One for all file descriptors, and one
++** for all file descriptors with rbu_file.pDb!=0. If the argument has
++** rbu_file.pDb!=0, then it is assumed to already be present on the
++** main list and is only added to the pDb!=0 list.
++*/
++static void rbuMainlistAdd(rbu_file *p){
++  rbu_vfs *pRbuVfs = p->pRbuVfs;
++  rbu_file *pIter;
++  assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
++  sqlite3_mutex_enter(pRbuVfs->mutex);
++  if( p->pRbu==0 ){
++    for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
++    p->pMainNext = pRbuVfs->pMain;
++    pRbuVfs->pMain = p;
++  }else{
++    for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
++    if( pIter==0 ){
++      p->pMainRbuNext = pRbuVfs->pMainRbu;
++      pRbuVfs->pMainRbu = p;
++    }
++  }
++  sqlite3_mutex_leave(pRbuVfs->mutex);
++}
++
++/*
++** Remove an item from the main-db lists.
++*/
++static void rbuMainlistRemove(rbu_file *p){
++  rbu_file **pp;
++  sqlite3_mutex_enter(p->pRbuVfs->mutex);
++  for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
++  if( *pp ) *pp = p->pMainNext;
++  p->pMainNext = 0;
++  for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
++  if( *pp ) *pp = p->pMainRbuNext;
++  p->pMainRbuNext = 0;
++  sqlite3_mutex_leave(p->pRbuVfs->mutex);
++}
++
++/*
++** Given that zWal points to a buffer containing a wal file name passed to 
++** either the xOpen() or xAccess() VFS method, search the main-db list for
++** a file-handle opened by the same database connection on the corresponding
++** database file.
++**
++** If parameter bRbu is true, only search for file-descriptors with
++** rbu_file.pDb!=0.
++*/
++static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
++  rbu_file *pDb;
++  sqlite3_mutex_enter(pRbuVfs->mutex);
++  if( bRbu ){
++    for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
++  }else{
++    for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
++  }
++  sqlite3_mutex_leave(pRbuVfs->mutex);
++  return pDb;
++}
++
++/*
+ ** Close an rbu file.
+ */
+ static int rbuVfsClose(sqlite3_file *pFile){
+@@ -174429,14 +190892,14 @@
+   sqlite3_free(p->zDel);
+ 
+   if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+-    rbu_file **pp;
+-    sqlite3_mutex_enter(p->pRbuVfs->mutex);
+-    for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
+-    *pp = p->pMainNext;
+-    sqlite3_mutex_leave(p->pRbuVfs->mutex);
++    rbuMainlistRemove(p);
+     rbuUnlockShm(p);
+     p->pReal->pMethods->xShmUnmap(p->pReal, 0);
+   }
++  else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
++    rbuUpdateTempSize(p, 0);
++  }
++  assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
+ 
+   /* Close the underlying file handle */
+   rc = p->pReal->pMethods->xClose(p->pReal);
+@@ -174554,11 +191017,19 @@
+     assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
+     rc = rbuCaptureDbWrite(p->pRbu, iOfst);
+   }else{
+-    if( pRbu && pRbu->eStage==RBU_STAGE_OAL 
+-     && (p->openFlags & SQLITE_OPEN_WAL) 
+-     && iOfst>=pRbu->iOalSz
+-    ){
+-      pRbu->iOalSz = iAmt + iOfst;
++    if( pRbu ){
++      if( pRbu->eStage==RBU_STAGE_OAL 
++       && (p->openFlags & SQLITE_OPEN_WAL) 
++       && iOfst>=pRbu->iOalSz
++      ){
++        pRbu->iOalSz = iAmt + iOfst;
++      }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){
++        i64 szNew = iAmt+iOfst;
++        if( szNew>p->sz ){
++          rc = rbuUpdateTempSize(p, szNew);
++          if( rc!=SQLITE_OK ) return rc;
++        }
++      }
+     }
+     rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
+     if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
+@@ -174577,6 +191048,10 @@
+ */
+ static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
+   rbu_file *p = (rbu_file*)pFile;
++  if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
++    int rc = rbuUpdateTempSize(p, size);
++    if( rc!=SQLITE_OK ) return rc;
++  }
+   return p->pReal->pMethods->xTruncate(p->pReal, size);
+ }
+ 
+@@ -174683,6 +191158,9 @@
+       }else if( rc==SQLITE_NOTFOUND ){
+         pRbu->pTargetFd = p;
+         p->pRbu = pRbu;
++        if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
++          rbuMainlistAdd(p);
++        }
+         if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
+         rc = SQLITE_OK;
+       }
+@@ -174844,20 +191322,6 @@
+   return rc;
+ }
+ 
+-/*
+-** Given that zWal points to a buffer containing a wal file name passed to 
+-** either the xOpen() or xAccess() VFS method, return a pointer to the
+-** file-handle opened by the same database connection on the corresponding
+-** database file.
+-*/
+-static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
+-  rbu_file *pDb;
+-  sqlite3_mutex_enter(pRbuVfs->mutex);
+-  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
+-  sqlite3_mutex_leave(pRbuVfs->mutex);
+-  return pDb;
+-}
+-
+ /* 
+ ** A main database named zName has just been opened. The following 
+ ** function returns a pointer to a buffer owned by SQLite that contains
+@@ -174936,7 +191400,7 @@
+       pFd->zWal = rbuMainToWal(zName, flags);
+     }
+     else if( flags & SQLITE_OPEN_WAL ){
+-      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
++      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
+       if( pDb ){
+         if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+           /* This call is to open a *-wal file. Intead, open the *-oal. This
+@@ -174966,6 +191430,8 @@
+         pDb->pWalFd = pFd;
+       }
+     }
++  }else{
++    pFd->pRbu = pRbuVfs->pRbu;
+   }
+ 
+   if( oflags & SQLITE_OPEN_MAIN_DB 
+@@ -174986,10 +191452,7 @@
+     ** mutex protected linked list of all such files.  */
+     pFile->pMethods = &rbuvfs_io_methods;
+     if( flags & SQLITE_OPEN_MAIN_DB ){
+-      sqlite3_mutex_enter(pRbuVfs->mutex);
+-      pFd->pMainNext = pRbuVfs->pMain;
+-      pRbuVfs->pMain = pFd;
+-      sqlite3_mutex_leave(pRbuVfs->mutex);
++      rbuMainlistAdd(pFd);
+     }
+   }else{
+     sqlite3_free(pFd->zDel);
+@@ -175037,12 +191500,14 @@
+   **      file opened instead.
+   */
+   if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
+-    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
++    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
+     if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+       if( *pResOut ){
+         rc = SQLITE_CANTOPEN;
+       }else{
+-        *pResOut = 1;
++        sqlite3_int64 sz = 0;
++        rc = rbuVfsFileSize(&pDb->base, &sz);
++        *pResOut = (sz>0);
+       }
+     }
+   }
+@@ -175231,7 +191696,21 @@
+   return rc;
+ }
+ 
++/*
++** Configure the aggregate temp file size limit for this RBU handle.
++*/
++SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){
++  if( n>=0 ){
++    pRbu->szTempLimit = n;
++  }
++  return pRbu->szTempLimit;
++}
+ 
++SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){
++  return pRbu->szTemp;
++}
++
++
+ /**************************************************************************/
+ 
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */
+@@ -175434,8 +191913,6 @@
+ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+   int i;
+ 
+-  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
+-
+   /* Look for a valid schema=? constraint.  If found, change the idxNum to
+   ** 1 and request the value of that constraint be sent to xFilter.  And
+   ** lower the cost estimate to encourage the constrained version to be
+@@ -175442,9 +191919,9 @@
+   ** used.
+   */
+   for(i=0; i<pIdxInfo->nConstraint; i++){
+-    if( pIdxInfo->aConstraint[i].usable==0 ) continue;
++    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
++    if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
+     if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+-    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+     pIdxInfo->idxNum = 1;
+     pIdxInfo->estimatedCost = 1.0;
+     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+@@ -175494,7 +191971,7 @@
+   return SQLITE_OK;
+ }
+ 
+-static void statClearPage(StatPage *p){
++static void statClearCells(StatPage *p){
+   int i;
+   if( p->aCell ){
+     for(i=0; i<p->nCell; i++){
+@@ -175502,6 +191979,12 @@
+     }
+     sqlite3_free(p->aCell);
+   }
++  p->nCell = 0;
++  p->aCell = 0;
++}
++
++static void statClearPage(StatPage *p){
++  statClearCells(p);
+   sqlite3PagerUnref(p->pPg);
+   sqlite3_free(p->zPath);
+   memset(p, 0, sizeof(StatPage));
+@@ -175564,22 +192047,33 @@
+   u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
+ 
+   p->flags = aHdr[0];
++  if( p->flags==0x0A || p->flags==0x0D ){
++    isLeaf = 1;
++    nHdr = 8;
++  }else if( p->flags==0x05 || p->flags==0x02 ){
++    isLeaf = 0;
++    nHdr = 12;
++  }else{
++    goto statPageIsCorrupt;
++  }
++  if( p->iPgno==1 ) nHdr += 100;
+   p->nCell = get2byte(&aHdr[3]);
+   p->nMxPayload = 0;
++  szPage = sqlite3BtreeGetPageSize(pBt);
+ 
+-  isLeaf = (p->flags==0x0A || p->flags==0x0D);
+-  nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+-
+   nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
+   nUnused += (int)aHdr[7];
+   iOff = get2byte(&aHdr[1]);
+   while( iOff ){
++    int iNext;
++    if( iOff>=szPage ) goto statPageIsCorrupt;
+     nUnused += get2byte(&aData[iOff+2]);
+-    iOff = get2byte(&aData[iOff]);
++    iNext = get2byte(&aData[iOff]);
++    if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
++    iOff = iNext;
+   }
+   p->nUnused = nUnused;
+   p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
+-  szPage = sqlite3BtreeGetPageSize(pBt);
+ 
+   if( p->nCell ){
+     int i;                        /* Used to iterate through cells */
+@@ -175596,6 +192090,7 @@
+       StatCell *pCell = &p->aCell[i];
+ 
+       iOff = get2byte(&aData[nHdr+i*2]);
++      if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
+       if( !isLeaf ){
+         pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
+         iOff += 4;
+@@ -175612,13 +192107,14 @@
+         }
+         if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
+         getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
++        if( nLocal<0 ) goto statPageIsCorrupt;
+         pCell->nLocal = nLocal;
+-        assert( nLocal>=0 );
+         assert( nPayload>=(u32)nLocal );
+         assert( nLocal<=(nUsable-35) );
+         if( nPayload>(u32)nLocal ){
+           int j;
+           int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
++          if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
+           pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
+           pCell->nOvfl = nOvfl;
+           pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+@@ -175642,6 +192138,11 @@
+   }
+ 
+   return SQLITE_OK;
++
++statPageIsCorrupt:
++  p->flags = 0;
++  statClearCells(p);
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -175664,7 +192165,7 @@
+   */
+   fd = sqlite3PagerFile(pPager);
+   x[0] = pCsr->iPageno;
+-  if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
++  if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
+     pCsr->iOffset = x[0];
+     pCsr->szPage = (int)x[1];
+   }
+@@ -175937,6 +192438,7 @@
+     0,                            /* xSavepoint */
+     0,                            /* xRelease */
+     0,                            /* xRollbackTo */
++    0                             /* xShadowName */
+   };
+   return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
+ }
+@@ -175945,6 +192447,424 @@
+ #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
+ 
+ /************** End of dbstat.c **********************************************/
++/************** Begin file dbpage.c ******************************************/
++/*
++** 2017-10-11
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file contains an implementation of the "sqlite_dbpage" virtual table.
++**
++** The sqlite_dbpage virtual table is used to read or write whole raw
++** pages of the database file.  The pager interface is used so that 
++** uncommitted changes and changes recorded in the WAL file are correctly
++** retrieved.
++**
++** Usage example:
++**
++**    SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
++**
++** This is an eponymous virtual table so it does not need to be created before
++** use.  The optional argument to the sqlite_dbpage() table name is the
++** schema for the database file that is to be read.  The default schema is
++** "main".
++**
++** The data field of sqlite_dbpage table can be updated.  The new
++** value must be a BLOB which is the correct page size, otherwise the
++** update fails.  Rows may not be deleted or inserted.
++*/
++
++/* #include "sqliteInt.h"   ** Requires access to internal data structures ** */
++#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
++    && !defined(SQLITE_OMIT_VIRTUALTABLE)
++
++typedef struct DbpageTable DbpageTable;
++typedef struct DbpageCursor DbpageCursor;
++
++struct DbpageCursor {
++  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
++  int pgno;                       /* Current page number */
++  int mxPgno;                     /* Last page to visit on this scan */
++  Pager *pPager;                  /* Pager being read/written */
++  DbPage *pPage1;                 /* Page 1 of the database */
++  int iDb;                        /* Index of database to analyze */
++  int szPage;                     /* Size of each page in bytes */
++};
++
++struct DbpageTable {
++  sqlite3_vtab base;              /* Base class.  Must be first */
++  sqlite3 *db;                    /* The database */
++};
++
++/* Columns */
++#define DBPAGE_COLUMN_PGNO    0
++#define DBPAGE_COLUMN_DATA    1
++#define DBPAGE_COLUMN_SCHEMA  2
++
++
++
++/*
++** Connect to or create a dbpagevfs virtual table.
++*/
++static int dbpageConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  DbpageTable *pTab = 0;
++  int rc = SQLITE_OK;
++
++  rc = sqlite3_declare_vtab(db, 
++          "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
++  if( rc==SQLITE_OK ){
++    pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
++    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
++  }
++
++  assert( rc==SQLITE_OK || pTab==0 );
++  if( rc==SQLITE_OK ){
++    memset(pTab, 0, sizeof(DbpageTable));
++    pTab->db = db;
++  }
++
++  *ppVtab = (sqlite3_vtab*)pTab;
++  return rc;
++}
++
++/*
++** Disconnect from or destroy a dbpagevfs virtual table.
++*/
++static int dbpageDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/*
++** idxNum:
++**
++**     0     schema=main, full table scan
++**     1     schema=main, pgno=?1
++**     2     schema=?1, full table scan
++**     3     schema=?1, pgno=?2
++*/
++static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
++  int i;
++  int iPlan = 0;
++
++  /* If there is a schema= constraint, it must be honored.  Report a
++  ** ridiculously large estimated cost if the schema= constraint is
++  ** unavailable
++  */
++  for(i=0; i<pIdxInfo->nConstraint; i++){
++    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
++    if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
++    if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
++    if( !p->usable ){
++      /* No solution. */
++      return SQLITE_CONSTRAINT;
++    }
++    iPlan = 2;
++    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[i].omit = 1;
++    break;
++  }
++
++  /* If we reach this point, it means that either there is no schema=
++  ** constraint (in which case we use the "main" schema) or else the
++  ** schema constraint was accepted.  Lower the estimated cost accordingly
++  */
++  pIdxInfo->estimatedCost = 1.0e6;
++
++  /* Check for constraints against pgno */
++  for(i=0; i<pIdxInfo->nConstraint; i++){
++    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
++    if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++      pIdxInfo->estimatedRows = 1;
++      pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
++      pIdxInfo->estimatedCost = 1.0;
++      pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1;
++      pIdxInfo->aConstraintUsage[i].omit = 1;
++      iPlan |= 1;
++      break;
++    }
++  }
++  pIdxInfo->idxNum = iPlan;
++
++  if( pIdxInfo->nOrderBy>=1
++   && pIdxInfo->aOrderBy[0].iColumn<=0
++   && pIdxInfo->aOrderBy[0].desc==0
++  ){
++    pIdxInfo->orderByConsumed = 1;
++  }
++  return SQLITE_OK;
++}
++
++/*
++** Open a new dbpagevfs cursor.
++*/
++static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
++  DbpageCursor *pCsr;
++
++  pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
++  if( pCsr==0 ){
++    return SQLITE_NOMEM_BKPT;
++  }else{
++    memset(pCsr, 0, sizeof(DbpageCursor));
++    pCsr->base.pVtab = pVTab;
++    pCsr->pgno = -1;
++  }
++
++  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
++  return SQLITE_OK;
++}
++
++/*
++** Close a dbpagevfs cursor.
++*/
++static int dbpageClose(sqlite3_vtab_cursor *pCursor){
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
++  sqlite3_free(pCsr);
++  return SQLITE_OK;
++}
++
++/*
++** Move a dbpagevfs cursor to the next entry in the file.
++*/
++static int dbpageNext(sqlite3_vtab_cursor *pCursor){
++  int rc = SQLITE_OK;
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  pCsr->pgno++;
++  return rc;
++}
++
++static int dbpageEof(sqlite3_vtab_cursor *pCursor){
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  return pCsr->pgno > pCsr->mxPgno;
++}
++
++/*
++** idxNum:
++**
++**     0     schema=main, full table scan
++**     1     schema=main, pgno=?1
++**     2     schema=?1, full table scan
++**     3     schema=?1, pgno=?2
++**
++** idxStr is not used
++*/
++static int dbpageFilter(
++  sqlite3_vtab_cursor *pCursor, 
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
++  int rc;
++  sqlite3 *db = pTab->db;
++  Btree *pBt;
++
++  /* Default setting is no rows of result */
++  pCsr->pgno = 1; 
++  pCsr->mxPgno = 0;
++
++  if( idxNum & 2 ){
++    const char *zSchema;
++    assert( argc>=1 );
++    zSchema = (const char*)sqlite3_value_text(argv[0]);
++    pCsr->iDb = sqlite3FindDbName(db, zSchema);
++    if( pCsr->iDb<0 ) return SQLITE_OK;
++  }else{
++    pCsr->iDb = 0;
++  }
++  pBt = db->aDb[pCsr->iDb].pBt;
++  if( pBt==0 ) return SQLITE_OK;
++  pCsr->pPager = sqlite3BtreePager(pBt);
++  pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
++  pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
++  if( idxNum & 1 ){
++    assert( argc>(idxNum>>1) );
++    pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]);
++    if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
++      pCsr->pgno = 1;
++      pCsr->mxPgno = 0;
++    }else{
++      pCsr->mxPgno = pCsr->pgno;
++    }
++  }else{
++    assert( pCsr->pgno==1 );
++  }
++  if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
++  rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0);
++  return rc;
++}
++
++static int dbpageColumn(
++  sqlite3_vtab_cursor *pCursor, 
++  sqlite3_context *ctx, 
++  int i
++){
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  int rc = SQLITE_OK;
++  switch( i ){
++    case 0: {           /* pgno */
++      sqlite3_result_int(ctx, pCsr->pgno);
++      break;
++    }
++    case 1: {           /* data */
++      DbPage *pDbPage = 0;
++      rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
++      if( rc==SQLITE_OK ){
++        sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage,
++                            SQLITE_TRANSIENT);
++      }
++      sqlite3PagerUnref(pDbPage);
++      break;
++    }
++    default: {          /* schema */
++      sqlite3 *db = sqlite3_context_db_handle(ctx);
++      sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC);
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
++  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
++  *pRowid = pCsr->pgno;
++  return SQLITE_OK;
++}
++
++static int dbpageUpdate(
++  sqlite3_vtab *pVtab,
++  int argc,
++  sqlite3_value **argv,
++  sqlite_int64 *pRowid
++){
++  DbpageTable *pTab = (DbpageTable *)pVtab;
++  Pgno pgno;
++  DbPage *pDbPage = 0;
++  int rc = SQLITE_OK;
++  char *zErr = 0;
++  const char *zSchema;
++  int iDb;
++  Btree *pBt;
++  Pager *pPager;
++  int szPage;
++
++  if( pTab->db->flags & SQLITE_Defensive ){
++    zErr = "read-only";
++    goto update_fail;
++  }
++  if( argc==1 ){
++    zErr = "cannot delete";
++    goto update_fail;
++  }
++  pgno = sqlite3_value_int(argv[0]);
++  if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
++    zErr = "cannot insert";
++    goto update_fail;
++  }
++  zSchema = (const char*)sqlite3_value_text(argv[4]);
++  iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
++  if( iDb<0 ){
++    zErr = "no such schema";
++    goto update_fail;
++  }
++  pBt = pTab->db->aDb[iDb].pBt;
++  if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
++    zErr = "bad page number";
++    goto update_fail;
++  }
++  szPage = sqlite3BtreeGetPageSize(pBt);
++  if( sqlite3_value_type(argv[3])!=SQLITE_BLOB 
++   || sqlite3_value_bytes(argv[3])!=szPage
++  ){
++    zErr = "bad page value";
++    goto update_fail;
++  }
++  pPager = sqlite3BtreePager(pBt);
++  rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
++  if( rc==SQLITE_OK ){
++    rc = sqlite3PagerWrite(pDbPage);
++    if( rc==SQLITE_OK ){
++      memcpy(sqlite3PagerGetData(pDbPage),
++             sqlite3_value_blob(argv[3]),
++             szPage);
++    }
++  }
++  sqlite3PagerUnref(pDbPage);
++  return rc;
++
++update_fail:
++  sqlite3_free(pVtab->zErrMsg);
++  pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
++  return SQLITE_ERROR;
++}
++
++/* Since we do not know in advance which database files will be
++** written by the sqlite_dbpage virtual table, start a write transaction
++** on them all.
++*/
++static int dbpageBegin(sqlite3_vtab *pVtab){
++  DbpageTable *pTab = (DbpageTable *)pVtab;
++  sqlite3 *db = pTab->db;
++  int i;
++  for(i=0; i<db->nDb; i++){
++    Btree *pBt = db->aDb[i].pBt;
++    if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0);
++  }
++  return SQLITE_OK;
++}
++
++
++/*
++** Invoke this routine to register the "dbpage" virtual table module
++*/
++SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
++  static sqlite3_module dbpage_module = {
++    0,                            /* iVersion */
++    dbpageConnect,                /* xCreate */
++    dbpageConnect,                /* xConnect */
++    dbpageBestIndex,              /* xBestIndex */
++    dbpageDisconnect,             /* xDisconnect */
++    dbpageDisconnect,             /* xDestroy */
++    dbpageOpen,                   /* xOpen - open a cursor */
++    dbpageClose,                  /* xClose - close a cursor */
++    dbpageFilter,                 /* xFilter - configure scan constraints */
++    dbpageNext,                   /* xNext - advance a cursor */
++    dbpageEof,                    /* xEof - check for end of scan */
++    dbpageColumn,                 /* xColumn - read data */
++    dbpageRowid,                  /* xRowid - read data */
++    dbpageUpdate,                 /* xUpdate */
++    dbpageBegin,                  /* xBegin */
++    0,                            /* xSync */
++    0,                            /* xCommit */
++    0,                            /* xRollback */
++    0,                            /* xFindMethod */
++    0,                            /* xRename */
++    0,                            /* xSavepoint */
++    0,                            /* xRelease */
++    0,                            /* xRollbackTo */
++    0                             /* xShadowName */
++  };
++  return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
++}
++#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
++SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
++#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
++
++/************** End of dbpage.c **********************************************/
+ /************** Begin file sqlite3session.c **********************************/
+ 
+ #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+@@ -175973,6 +192893,8 @@
+ # endif
+ #endif
+ 
++static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
++
+ typedef struct SessionHook SessionHook;
+ struct SessionHook {
+   void *pCtx;
+@@ -175994,6 +192916,7 @@
+   int rc;                         /* Non-zero if an error has occurred */
+   void *pFilterCtx;               /* First argument to pass to xTableFilter */
+   int (*xTableFilter)(void *pCtx, const char *zTab);
++  sqlite3_value *pZeroBlob;       /* Value containing X'' */
+   sqlite3_session *pNext;         /* Next session object on same db. */
+   SessionTable *pTable;           /* List of attached tables */
+   SessionHook hook;               /* APIs to grab new and old data with */
+@@ -176015,7 +192938,7 @@
+ **  sqlite3changeset_start_strm()).
+ */
+ struct SessionInput {
+-  int bNoDiscard;                 /* If true, discard no data */
++  int bNoDiscard;                 /* If true, do not discard in InputBuffer() */
+   int iCurrent;                   /* Offset in aData[] of current change */
+   int iNext;                      /* Offset in aData[] of next change */
+   u8 *aData;                      /* Pointer to buffer containing changeset */
+@@ -176034,6 +192957,7 @@
+   SessionInput in;                /* Input buffer or stream */
+   SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
+   int bPatchset;                  /* True if this is a patchset */
++  int bInvert;                    /* True to invert changeset */
+   int rc;                         /* Iterator error code */
+   sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
+   char *zTab;                     /* Current table */
+@@ -176061,6 +192985,7 @@
+   SessionTable *pNext;
+   char *zName;                    /* Local name of table */
+   int nCol;                       /* Number of columns in table zName */
++  int bStat1;                     /* True if this is sqlite_stat1 */
+   const char **azCol;             /* Column names */
+   u8 *abPK;                       /* Array of primary key flags */
+   int nEntry;                     /* Total number of entries in hash table */
+@@ -176178,8 +193103,8 @@
+ ** statement.
+ **
+ ** For a DELETE change, all fields within the record except those associated
+-** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields
+-** contain the values identifying the row to delete.
++** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the
++** values identifying the row to delete.
+ **
+ ** For an UPDATE change, all fields except those associated with PRIMARY KEY
+ ** columns and columns that are modified by the UPDATE are set to "undefined".
+@@ -176189,6 +193114,42 @@
+ ** The records associated with INSERT changes are in the same format as for
+ ** changesets. It is not possible for a record associated with an INSERT
+ ** change to contain a field set to "undefined".
++**
++** REBASE BLOB FORMAT:
++**
++** A rebase blob may be output by sqlite3changeset_apply_v2() and its 
++** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
++** existing changesets. A rebase blob contains one entry for each conflict
++** resolved using either the OMIT or REPLACE strategies within the apply_v2()
++** call.
++**
++** The format used for a rebase blob is very similar to that used for
++** changesets. All entries related to a single table are grouped together.
++**
++** Each group of entries begins with a table header in changeset format:
++**
++**   1 byte: Constant 0x54 (capital 'T')
++**   Varint: Number of columns in the table.
++**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
++**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
++**
++** Followed by one or more entries associated with the table.
++**
++**   1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
++**   1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
++**   record: (in the record format defined above).
++**
++** In a rebase blob, the first field is set to SQLITE_INSERT if the change
++** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
++** it was a DELETE. The second field is set to 0x01 if the conflict 
++** resolution strategy was REPLACE, or 0x00 if it was OMIT.
++**
++** If the change that caused the conflict was a DELETE, then the single
++** record is a copy of the old.* record from the original changeset. If it
++** was an INSERT, then the single record is a copy of the new.* record. If
++** the conflicting change was an UPDATE, then the single record is a copy
++** of the new.* record with the PK fields filled in based on the original
++** old.* record.
+ */
+ 
+ /*
+@@ -176444,6 +193405,7 @@
+         h = sessionHashAppendBlob(h, n, z);
+       }else{
+         assert( eType==SQLITE_NULL );
++        assert( pTab->bStat1==0 || i!=1 );
+         *pbNullPK = 1;
+       }
+     }
+@@ -176461,7 +193423,7 @@
+ static int sessionSerialLen(u8 *a){
+   int e = *a;
+   int n;
+-  if( e==0 ) return 1;
++  if( e==0 || e==0xFF ) return 1;
+   if( e==SQLITE_NULL ) return 1;
+   if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
+   return sessionVarintGet(&a[1], &n) + 1 + n;
+@@ -176541,7 +193503,7 @@
+       int n1 = sessionSerialLen(a1);
+       int n2 = sessionSerialLen(a2);
+ 
+-      if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
++      if( n1!=n2 || memcmp(a1, a2, n1) ){
+         return 0;
+       }
+       a1 += n1;
+@@ -176784,9 +193746,8 @@
+         }else{
+           z = sqlite3_value_blob(pVal);
+         }
+-        if( memcmp(a, z, n) ) return 0;
++        if( n>0 && memcmp(a, z, n) ) return 0;
+         a += n;
+-        break;
+       }
+     }
+   }
+@@ -176842,9 +193803,7 @@
+ 
+ /*
+ ** This function queries the database for the names of the columns of table
+-** zThis, in schema zDb. It is expected that the table has nCol columns. If
+-** not, SQLITE_SCHEMA is returned and none of the output variables are
+-** populated.
++** zThis, in schema zDb.
+ **
+ ** Otherwise, if they are not NULL, variable *pnCol is set to the number
+ ** of columns in the database table and variable *pzTab is set to point to a
+@@ -176865,9 +193824,7 @@
+ **     *pabPK  = {1, 0, 0, 1}
+ **
+ ** All returned buffers are part of the same single allocation, which must
+-** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
+-** pointer *pazCol should be freed to release all memory. Otherwise, pointer
+-** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
++** be freed using sqlite3_free() by the caller
+ */
+ static int sessionTableInfo(
+   sqlite3 *db,                    /* Database connection */
+@@ -176892,7 +193849,23 @@
+   assert( pazCol && pabPK );
+ 
+   nThis = sqlite3Strlen30(zThis);
+-  zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
++  if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
++    rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
++    if( rc==SQLITE_OK ){
++      /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
++      zPragma = sqlite3_mprintf(
++          "SELECT 0, 'tbl',  '', 0, '', 1     UNION ALL "
++          "SELECT 1, 'idx',  '', 0, '', 2     UNION ALL "
++          "SELECT 2, 'stat', '', 0, '', 0"
++      );
++    }else if( rc==SQLITE_ERROR ){
++      zPragma = sqlite3_mprintf("");
++    }else{
++      return rc;
++    }
++  }else{
++    zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
++  }
+   if( !zPragma ) return SQLITE_NOMEM;
+ 
+   rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
+@@ -176984,6 +193957,9 @@
+           break;
+         }
+       }
++      if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
++        pTab->bStat1 = 1;
++      }
+     }
+   }
+   return (pSession->rc || pTab->abPK==0);
+@@ -176990,6 +193966,47 @@
+ }
+ 
+ /*
++** Versions of the four methods in object SessionHook for use with the
++** sqlite_stat1 table. The purpose of this is to substitute a zero-length
++** blob each time a NULL value is read from the "idx" column of the
++** sqlite_stat1 table.
++*/
++typedef struct SessionStat1Ctx SessionStat1Ctx;
++struct SessionStat1Ctx {
++  SessionHook hook;
++  sqlite3_session *pSession;
++};
++static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
++  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
++  sqlite3_value *pVal = 0;
++  int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
++  if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
++    pVal = p->pSession->pZeroBlob;
++  }
++  *ppVal = pVal;
++  return rc;
++}
++static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
++  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
++  sqlite3_value *pVal = 0;
++  int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
++  if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
++    pVal = p->pSession->pZeroBlob;
++  }
++  *ppVal = pVal;
++  return rc;
++}
++static int sessionStat1Count(void *pCtx){
++  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
++  return p->hook.xCount(p->hook.pCtx);
++}
++static int sessionStat1Depth(void *pCtx){
++  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
++  return p->hook.xDepth(p->hook.pCtx);
++}
++
++
++/*
+ ** This function is only called from with a pre-update-hook reporting a 
+ ** change on table pTab (attached to session pSession). The type of change
+ ** (UPDATE, INSERT, DELETE) is specified by the first argument.
+@@ -177005,6 +194022,7 @@
+   int iHash; 
+   int bNull = 0; 
+   int rc = SQLITE_OK;
++  SessionStat1Ctx stat1 = {0};
+ 
+   if( pSession->rc ) return;
+ 
+@@ -177024,6 +194042,25 @@
+     return;
+   }
+ 
++  if( pTab->bStat1 ){
++    stat1.hook = pSession->hook;
++    stat1.pSession = pSession;
++    pSession->hook.pCtx = (void*)&stat1;
++    pSession->hook.xNew = sessionStat1New;
++    pSession->hook.xOld = sessionStat1Old;
++    pSession->hook.xCount = sessionStat1Count;
++    pSession->hook.xDepth = sessionStat1Depth;
++    if( pSession->pZeroBlob==0 ){
++      sqlite3_value *p = sqlite3ValueNew(0);
++      if( p==0 ){
++        rc = SQLITE_NOMEM;
++        goto error_out;
++      }
++      sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
++      pSession->pZeroBlob = p;
++    }
++  }
++
+   /* Calculate the hash-key for this change. If the primary key of the row
+   ** includes a NULL value, exit early. Such changes are ignored by the
+   ** session module. */
+@@ -177113,6 +194150,9 @@
+ 
+   /* If an error has occurred, mark the session object as failed. */
+  error_out:
++  if( pTab->bStat1 ){
++    pSession->hook = stat1.hook;
++  }
+   if( rc!=SQLITE_OK ){
+     pSession->rc = rc;
+   }
+@@ -177449,7 +194489,6 @@
+             if( abPK[i] ) bHasPk = 1;
+           }
+         }
+-
+       }
+       sqlite3_free((char*)azCol);
+       if( bMismatch ){
+@@ -177575,6 +194614,7 @@
+     }
+   }
+   sqlite3_mutex_leave(sqlite3_db_mutex(db));
++  sqlite3ValueFree(pSession->pZeroBlob);
+ 
+   /* Delete all attached table objects. And the contents of their 
+   ** associated hash-tables. */
+@@ -177660,12 +194700,12 @@
+ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
+   if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
+     u8 *aNew;
+-    int nNew = p->nAlloc ? p->nAlloc : 128;
++    i64 nNew = p->nAlloc ? p->nAlloc : 128;
+     do {
+       nNew = nNew*2;
+-    }while( nNew<(p->nBuf+nByte) );
++    }while( (nNew-p->nBuf)<nByte );
+ 
+-    aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
++    aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
+     if( 0==aNew ){
+       *pRc = SQLITE_NOMEM;
+     }else{
+@@ -178042,28 +195082,42 @@
+   sqlite3_stmt **ppStmt           /* OUT: Prepared SELECT statement */
+ ){
+   int rc = SQLITE_OK;
+-  int i;
+-  const char *zSep = "";
+-  SessionBuffer buf = {0, 0, 0};
++  char *zSql = 0;
++  int nSql = -1;
+ 
+-  sessionAppendStr(&buf, "SELECT * FROM ", &rc);
+-  sessionAppendIdent(&buf, zDb, &rc);
+-  sessionAppendStr(&buf, ".", &rc);
+-  sessionAppendIdent(&buf, zTab, &rc);
+-  sessionAppendStr(&buf, " WHERE ", &rc);
+-  for(i=0; i<nCol; i++){
+-    if( abPK[i] ){
+-      sessionAppendStr(&buf, zSep, &rc);
+-      sessionAppendIdent(&buf, azCol[i], &rc);
+-      sessionAppendStr(&buf, " = ?", &rc);
+-      sessionAppendInteger(&buf, i+1, &rc);
+-      zSep = " AND ";
++  if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
++    zSql = sqlite3_mprintf(
++        "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
++        "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
++    );
++    if( zSql==0 ) rc = SQLITE_NOMEM;
++  }else{
++    int i;
++    const char *zSep = "";
++    SessionBuffer buf = {0, 0, 0};
++
++    sessionAppendStr(&buf, "SELECT * FROM ", &rc);
++    sessionAppendIdent(&buf, zDb, &rc);
++    sessionAppendStr(&buf, ".", &rc);
++    sessionAppendIdent(&buf, zTab, &rc);
++    sessionAppendStr(&buf, " WHERE ", &rc);
++    for(i=0; i<nCol; i++){
++      if( abPK[i] ){
++        sessionAppendStr(&buf, zSep, &rc);
++        sessionAppendIdent(&buf, azCol[i], &rc);
++        sessionAppendStr(&buf, " IS ?", &rc);
++        sessionAppendInteger(&buf, i+1, &rc);
++        zSep = " AND ";
++      }
+     }
++    zSql = (char*)buf.aBuf;
++    nSql = buf.nBuf;
+   }
++
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
++    rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
+   }
+-  sqlite3_free(buf.aBuf);
++  sqlite3_free(zSql);
+   return rc;
+ }
+ 
+@@ -178249,12 +195303,12 @@
+             rc = sqlite3_reset(pSel);
+           }
+ 
+-          /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
++          /* If the buffer is now larger than sessions_strm_chunk_size, pass
+           ** its contents to the xOutput() callback. */
+           if( xOutput 
+            && rc==SQLITE_OK 
+            && buf.nBuf>nNoop 
+-           && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE 
++           && buf.nBuf>sessions_strm_chunk_size 
+           ){
+             rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+             nNoop = -1;
+@@ -178393,7 +195447,8 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn,
+   int nChangeset,                 /* Size of buffer pChangeset in bytes */
+-  void *pChangeset                /* Pointer to buffer containing changeset */
++  void *pChangeset,               /* Pointer to buffer containing changeset */
++  int bInvert                     /* True to invert changeset */
+ ){
+   sqlite3_changeset_iter *pRet;   /* Iterator to return */
+   int nByte;                      /* Number of bytes to allocate for iterator */
+@@ -178413,6 +195468,7 @@
+   pRet->in.xInput = xInput;
+   pRet->in.pIn = pIn;
+   pRet->in.bEof = (xInput ? 0 : 1);
++  pRet->bInvert = bInvert;
+ 
+   /* Populate the output variable and return success. */
+   *pp = pRet;
+@@ -178427,8 +195483,17 @@
+   int nChangeset,                 /* Size of buffer pChangeset in bytes */
+   void *pChangeset                /* Pointer to buffer containing changeset */
+ ){
+-  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
++  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
+ }
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int nChangeset,                 /* Size of buffer pChangeset in bytes */
++  void *pChangeset,               /* Pointer to buffer containing changeset */
++  int flags
++){
++  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
++  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
++}
+ 
+ /*
+ ** Streaming version of sqlite3changeset_start().
+@@ -178438,8 +195503,17 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ ){
+-  return sessionChangesetStart(pp, xInput, pIn, 0, 0);
++  return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
+ }
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++){
++  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
++  return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
++}
+ 
+ /*
+ ** If the SessionInput object passed as the only argument is a streaming
+@@ -178446,7 +195520,7 @@
+ ** object and the buffer is full, discard some data to free up space.
+ */
+ static void sessionDiscardData(SessionInput *pIn){
+-  if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
++  if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
+     int nMove = pIn->buf.nBuf - pIn->iNext;
+     assert( nMove>=0 );
+     if( nMove>0 ){
+@@ -178469,7 +195543,7 @@
+   int rc = SQLITE_OK;
+   if( pIn->xInput ){
+     while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
+-      int nNew = SESSIONS_STRM_CHUNK_SIZE;
++      int nNew = sessions_strm_chunk_size;
+ 
+       if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
+       if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
+@@ -178574,15 +195648,18 @@
+     if( abPK && abPK[i]==0 ) continue;
+     rc = sessionInputBuffer(pIn, 9);
+     if( rc==SQLITE_OK ){
+-      eType = pIn->aData[pIn->iNext++];
++      if( pIn->iNext>=pIn->nData ){
++        rc = SQLITE_CORRUPT_BKPT;
++      }else{
++        eType = pIn->aData[pIn->iNext++];
++        assert( apOut[i]==0 );
++        if( eType ){
++          apOut[i] = sqlite3ValueNew(0);
++          if( !apOut[i] ) rc = SQLITE_NOMEM;
++        }
++      }
+     }
+ 
+-    assert( apOut[i]==0 );
+-    if( eType ){
+-      apOut[i] = sqlite3ValueNew(0);
+-      if( !apOut[i] ) rc = SQLITE_NOMEM;
+-    }
+-
+     if( rc==SQLITE_OK ){
+       u8 *aVal = &pIn->aData[pIn->iNext];
+       if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+@@ -178590,10 +195667,14 @@
+         pIn->iNext += sessionVarintGet(aVal, &nByte);
+         rc = sessionInputBuffer(pIn, nByte);
+         if( rc==SQLITE_OK ){
+-          u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
+-          rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
++          if( nByte<0 || nByte>pIn->nData-pIn->iNext ){
++            rc = SQLITE_CORRUPT_BKPT;
++          }else{
++            u8 enc = (eType==SQLITE_TEXT ? SQLITE_UTF8 : 0);
++            rc = sessionValueSetStr(apOut[i],&pIn->aData[pIn->iNext],nByte,enc);
++            pIn->iNext += nByte;
++          }
+         }
+-        pIn->iNext += nByte;
+       }
+       if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+         sqlite3_int64 v = sessionGetI64(aVal);
+@@ -178633,8 +195714,19 @@
+   rc = sessionInputBuffer(pIn, 9);
+   if( rc==SQLITE_OK ){
+     nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol);
+-    rc = sessionInputBuffer(pIn, nRead+nCol+100);
+-    nRead += nCol;
++    /* The hard upper limit for the number of columns in an SQLite
++    ** database table is, according to sqliteLimit.h, 32676. So 
++    ** consider any table-header that purports to have more than 65536 
++    ** columns to be corrupt. This is convenient because otherwise, 
++    ** if the (nCol>65536) condition below were omitted, a sufficiently 
++    ** large value for nCol may cause nRead to wrap around and become 
++    ** negative. Leading to a crash. */
++    if( nCol<0 || nCol>65536 ){
++      rc = SQLITE_CORRUPT_BKPT;
++    }else{
++      rc = sessionInputBuffer(pIn, nRead+nCol+100);
++      nRead += nCol;
++    }
+   }
+ 
+   while( rc==SQLITE_OK ){
+@@ -178711,11 +195803,15 @@
+     int nByte;
+     int nVarint;
+     nVarint = sessionVarintGet(&p->in.aData[p->in.iNext], &p->nCol);
+-    nCopy -= nVarint;
+-    p->in.iNext += nVarint;
+-    nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
+-    p->tblhdr.nBuf = 0;
+-    sessionBufferGrow(&p->tblhdr, nByte, &rc);
++    if( p->nCol>0 ){
++      nCopy -= nVarint;
++      p->in.iNext += nVarint;
++      nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy;
++      p->tblhdr.nBuf = 0;
++      sessionBufferGrow(&p->tblhdr, nByte, &rc);
++    }else{
++      rc = SQLITE_CORRUPT_BKPT;
++    }
+   }
+ 
+   if( rc==SQLITE_OK ){
+@@ -178750,7 +195846,8 @@
+ static int sessionChangesetNext(
+   sqlite3_changeset_iter *p,      /* Changeset iterator */
+   u8 **paRec,                     /* If non-NULL, store record pointer here */
+-  int *pnRec                      /* If non-NULL, store size of record here */
++  int *pnRec,                     /* If non-NULL, store size of record here */
++  int *pbNew                      /* If non-NULL, true if new table */
+ ){
+   int i;
+   u8 op;
+@@ -178785,6 +195882,7 @@
+ 
+   op = p->in.aData[p->in.iNext++];
+   while( op=='T' || op=='P' ){
++    if( pbNew ) *pbNew = 1;
+     p->bPatchset = (op=='P');
+     if( sessionChangesetReadTblhdr(p) ) return p->rc;
+     if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
+@@ -178793,6 +195891,13 @@
+     op = p->in.aData[p->in.iNext++];
+   }
+ 
++  if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
++    /* The first record in the changeset is not a table header. Must be a
++    ** corrupt changeset. */
++    assert( p->in.iNext==1 || p->zTab );
++    return (p->rc = SQLITE_CORRUPT_BKPT);
++  }
++
+   p->op = op;
+   p->bIndirect = p->in.aData[p->in.iNext++];
+   if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){
+@@ -178814,33 +195919,39 @@
+     *paRec = &p->in.aData[p->in.iNext];
+     p->in.iNext += *pnRec;
+   }else{
++    sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
++    sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
+ 
+     /* If this is an UPDATE or DELETE, read the old.* record. */
+     if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
+       u8 *abPK = p->bPatchset ? p->abPK : 0;
+-      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
++      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
+       if( p->rc!=SQLITE_OK ) return p->rc;
+     }
+ 
+     /* If this is an INSERT or UPDATE, read the new.* record. */
+     if( p->op!=SQLITE_DELETE ){
+-      p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
++      p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
+       if( p->rc!=SQLITE_OK ) return p->rc;
+     }
+ 
+-    if( p->bPatchset && p->op==SQLITE_UPDATE ){
++    if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
+       /* If this is an UPDATE that is part of a patchset, then all PK and
+       ** modified fields are present in the new.* record. The old.* record
+       ** is currently completely empty. This block shifts the PK fields from
+       ** new.* to old.*, to accommodate the code that reads these arrays.  */
+       for(i=0; i<p->nCol; i++){
+-        assert( p->apValue[i]==0 );
+-        assert( p->abPK[i]==0 || p->apValue[i+p->nCol] );
++        assert( p->bPatchset==0 || p->apValue[i]==0 );
+         if( p->abPK[i] ){
++          assert( p->apValue[i]==0 );
+           p->apValue[i] = p->apValue[i+p->nCol];
++          if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
+           p->apValue[i+p->nCol] = 0;
+         }
+       }
++    }else if( p->bInvert ){
++      if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
++      else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
+     }
+   }
+ 
+@@ -178856,7 +195967,7 @@
+ ** callback by changeset_apply().
+ */
+ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
+-  return sessionChangesetNext(p, 0, 0);
++  return sessionChangesetNext(p, 0, 0, 0);
+ }
+ 
+ /*
+@@ -179157,7 +196268,7 @@
+     }
+ 
+     assert( rc==SQLITE_OK );
+-    if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
++    if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
+       rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+       sOut.nBuf = 0;
+       if( rc!=SQLITE_OK ) goto finished_invert;
+@@ -179232,9 +196343,12 @@
+   int nCol;                       /* Size of azCol[] and abPK[] arrays */
+   const char **azCol;             /* Array of column names */
+   u8 *abPK;                       /* Boolean array - true if column is in PK */
+-
++  int bStat1;                     /* True if table is sqlite_stat1 */
+   int bDeferConstraints;          /* True to defer constraints */
+   SessionBuffer constraints;      /* Deferred constraints are stored here */
++  SessionBuffer rebase;           /* Rebase information (if any) here */
++  u8 bRebaseStarted;              /* If table header is already in rebase */
++  u8 bRebase;                     /* True to collect rebase information */
+ };
+ 
+ /*
+@@ -179402,6 +196516,7 @@
+   return rc;
+ }
+ 
++
+ /*
+ ** Formulate and prepare an SQL statement to query table zTab by primary
+ ** key. Assuming the following table structure:
+@@ -179463,7 +196578,47 @@
+   return rc;
+ }
+ 
++static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
++  return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
++}
++
+ /*
++** Prepare statements for applying changes to the sqlite_stat1 table.
++** These are similar to those created by sessionSelectRow(),
++** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for 
++** other tables.
++*/
++static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
++  int rc = sessionSelectRow(db, "sqlite_stat1", p);
++  if( rc==SQLITE_OK ){
++    rc = sessionPrepare(db, &p->pInsert,
++        "INSERT INTO main.sqlite_stat1 VALUES(?1, "
++        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
++        "?3)"
++    );
++  }
++  if( rc==SQLITE_OK ){
++    rc = sessionPrepare(db, &p->pUpdate,
++        "UPDATE main.sqlite_stat1 SET "
++        "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
++        "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
++        "stat = CASE WHEN ?8 THEN ?9 ELSE stat END  "
++        "WHERE tbl=?1 AND idx IS "
++        "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
++        "AND (?10 OR ?8=0 OR stat IS ?7)"
++    );
++  }
++  if( rc==SQLITE_OK ){
++    rc = sessionPrepare(db, &p->pDelete,
++        "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
++        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
++        "AND (?4 OR stat IS ?3)"
++    );
++  }
++  return rc;
++}
++
++/*
+ ** A wrapper around sqlite3_bind_value() that detects an extra problem. 
+ ** See comments in the body of this function for details.
+ */
+@@ -179520,7 +196675,13 @@
+     if( !abPK || abPK[i] ){
+       sqlite3_value *pVal;
+       (void)xValue(pIter, i, &pVal);
+-      rc = sessionBindValue(pStmt, i+1, pVal);
++      if( pVal==0 ){
++        /* The value in the changeset was "undefined". This indicates a
++        ** corrupt changeset blob.  */
++        rc = SQLITE_CORRUPT_BKPT;
++      }else{
++        rc = sessionBindValue(pStmt, i+1, pVal);
++      }
+     }
+   }
+   return rc;
+@@ -179569,6 +196730,55 @@
+ }
+ 
+ /*
++** This function is called from within sqlite3changset_apply_v2() when
++** a conflict is encountered and resolved using conflict resolution
++** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
++** It adds a conflict resolution record to the buffer in 
++** SessionApplyCtx.rebase, which will eventually be returned to the caller
++** of apply_v2() as the "rebase" buffer.
++**
++** Return SQLITE_OK if successful, or an SQLite error code otherwise.
++*/
++static int sessionRebaseAdd(
++  SessionApplyCtx *p,             /* Apply context */
++  int eType,                      /* Conflict resolution (OMIT or REPLACE) */
++  sqlite3_changeset_iter *pIter   /* Iterator pointing at current change */
++){
++  int rc = SQLITE_OK;
++  if( p->bRebase ){
++    int i;
++    int eOp = pIter->op;
++    if( p->bRebaseStarted==0 ){
++      /* Append a table-header to the rebase buffer */
++      const char *zTab = pIter->zTab;
++      sessionAppendByte(&p->rebase, 'T', &rc);
++      sessionAppendVarint(&p->rebase, p->nCol, &rc);
++      sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
++      sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
++      p->bRebaseStarted = 1;
++    }
++
++    assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
++    assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
++
++    sessionAppendByte(&p->rebase, 
++        (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
++        );
++    sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
++    for(i=0; i<p->nCol; i++){
++      sqlite3_value *pVal = 0;
++      if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
++        sqlite3changeset_old(pIter, i, &pVal);
++      }else{
++        sqlite3changeset_new(pIter, i, &pVal);
++      }
++      sessionAppendValue(&p->rebase, pVal, &rc);
++    }
++  }
++  return rc;
++}
++
++/*
+ ** Invoke the conflict handler for the change that the changeset iterator
+ ** currently points to.
+ **
+@@ -179643,7 +196853,7 @@
+       u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
+       int nBlob = pIter->in.iNext - pIter->in.iCurrent;
+       sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
+-      res = SQLITE_CHANGESET_OMIT;
++      return SQLITE_OK;
+     }else{
+       /* No other row with the new.* primary key. */
+       res = xConflict(pCtx, eType+1, pIter);
+@@ -179669,6 +196879,9 @@
+         rc = SQLITE_MISUSE;
+         break;
+     }
++    if( rc==SQLITE_OK ){
++      rc = sessionRebaseAdd(p, res, pIter);
++    }
+   }
+ 
+   return rc;
+@@ -179793,11 +197006,25 @@
+ 
+   }else{
+     assert( op==SQLITE_INSERT );
+-    rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+-    if( rc!=SQLITE_OK ) return rc;
++    if( p->bStat1 ){
++      /* Check if there is a conflicting row. For sqlite_stat1, this needs
++      ** to be done using a SELECT, as there is no PRIMARY KEY in the 
++      ** database schema to throw an exception if a duplicate is inserted.  */
++      rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
++      if( rc==SQLITE_ROW ){
++        rc = SQLITE_CONSTRAINT;
++        sqlite3_reset(p->pSelect);
++      }
++    }
+ 
+-    sqlite3_step(p->pInsert);
+-    rc = sqlite3_reset(p->pInsert);
++    if( rc==SQLITE_OK ){
++      rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
++      if( rc!=SQLITE_OK ) return rc;
++
++      sqlite3_step(p->pInsert);
++      rc = sqlite3_reset(p->pInsert);
++    }
++
+     if( (rc&0xff)==SQLITE_CONSTRAINT ){
+       rc = sessionConflictHandler(
+           SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
+@@ -179830,42 +197057,42 @@
+   int rc;
+ 
+   rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
+-  assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) );
+-
+-  /* If the bRetry flag is set, the change has not been applied due to an
+-  ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
+-  ** a row with the correct PK is present in the db, but one or more other
+-  ** fields do not contain the expected values) and the conflict handler 
+-  ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
+-  ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
+-  ** the SQLITE_CHANGESET_DATA problem.  */
+-  if( bRetry ){
+-    assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
+-    rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
+-  }
+-
+-  /* If the bReplace flag is set, the change is an INSERT that has not
+-  ** been performed because the database already contains a row with the
+-  ** specified primary key and the conflict handler returned
+-  ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
+-  ** before reattempting the INSERT.  */
+-  else if( bReplace ){
+-    assert( pIter->op==SQLITE_INSERT );
+-    rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
+-    if( rc==SQLITE_OK ){
+-      rc = sessionBindRow(pIter, 
+-          sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
+-      sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
+-    }
+-    if( rc==SQLITE_OK ){
+-      sqlite3_step(pApply->pDelete);
+-      rc = sqlite3_reset(pApply->pDelete);
+-    }
+-    if( rc==SQLITE_OK ){
++  if( rc==SQLITE_OK ){
++    /* If the bRetry flag is set, the change has not been applied due to an
++    ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
++    ** a row with the correct PK is present in the db, but one or more other
++    ** fields do not contain the expected values) and the conflict handler 
++    ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
++    ** but pass NULL as the final argument so that sessionApplyOneOp() ignores
++    ** the SQLITE_CHANGESET_DATA problem.  */
++    if( bRetry ){
++      assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
+       rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
+     }
+-    if( rc==SQLITE_OK ){
+-      rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
++
++    /* If the bReplace flag is set, the change is an INSERT that has not
++    ** been performed because the database already contains a row with the
++    ** specified primary key and the conflict handler returned
++    ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
++    ** before reattempting the INSERT.  */
++    else if( bReplace ){
++      assert( pIter->op==SQLITE_INSERT );
++      rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
++      if( rc==SQLITE_OK ){
++        rc = sessionBindRow(pIter, 
++            sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
++        sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
++      }
++      if( rc==SQLITE_OK ){
++        sqlite3_step(pApply->pDelete);
++        rc = sqlite3_reset(pApply->pDelete);
++      }
++      if( rc==SQLITE_OK ){
++        rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
++      }
++      if( rc==SQLITE_OK ){
++        rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
++      }
+     }
+   }
+ 
+@@ -179890,7 +197117,7 @@
+     SessionBuffer cons = pApply->constraints;
+     memset(&pApply->constraints, 0, sizeof(SessionBuffer));
+ 
+-    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
++    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
+     if( rc==SQLITE_OK ){
+       int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
+       int rc2;
+@@ -179941,10 +197168,12 @@
+     int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+     sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+   ),
+-  void *pCtx                      /* First argument passed to xConflict */
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase, /* OUT: Rebase information */
++  int flags                       /* SESSION_APPLY_XXX flags */
+ ){
+   int schemaMismatch = 0;
+-  int rc;                         /* Return code */
++  int rc = SQLITE_OK;             /* Return code */
+   const char *zTab = 0;           /* Name of current table */
+   int nTab = 0;                   /* Result of sqlite3Strlen30(zTab) */
+   SessionApplyCtx sApply;         /* changeset_apply() context object */
+@@ -179954,8 +197183,11 @@
+ 
+   pIter->in.bNoDiscard = 1;
+   memset(&sApply, 0, sizeof(sApply));
++  sApply.bRebase = (ppRebase && pnRebase);
+   sqlite3_mutex_enter(sqlite3_db_mutex(db));
+-  rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
++  if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
++    rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
++  }
+   if( rc==SQLITE_OK ){
+     rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0);
+   }
+@@ -179979,9 +197211,18 @@
+       sqlite3_finalize(sApply.pUpdate); 
+       sqlite3_finalize(sApply.pInsert);
+       sqlite3_finalize(sApply.pSelect);
+-      memset(&sApply, 0, sizeof(sApply));
+       sApply.db = db;
++      sApply.pDelete = 0;
++      sApply.pUpdate = 0;
++      sApply.pInsert = 0;
++      sApply.pSelect = 0;
++      sApply.nCol = 0;
++      sApply.azCol = 0;
++      sApply.abPK = 0;
++      sApply.bStat1 = 0;
+       sApply.bDeferConstraints = 1;
++      sApply.bRebaseStarted = 0;
++      memset(&sApply.constraints, 0, sizeof(SessionBuffer));
+ 
+       /* If an xFilter() callback was specified, invoke it now. If the 
+       ** xFilter callback returns zero, skip this table. If it returns
+@@ -180030,12 +197271,20 @@
+         }
+         else{
+           sApply.nCol = nCol;
+-          if((rc = sessionSelectRow(db, zTab, &sApply))
+-          || (rc = sessionUpdateRow(db, zTab, &sApply))
+-          || (rc = sessionDeleteRow(db, zTab, &sApply))
+-          || (rc = sessionInsertRow(db, zTab, &sApply))
+-          ){
+-            break;
++          if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
++            if( (rc = sessionStat1Sql(db, &sApply) ) ){
++              break;
++            }
++            sApply.bStat1 = 1;
++          }else{
++            if((rc = sessionSelectRow(db, zTab, &sApply))
++                || (rc = sessionUpdateRow(db, zTab, &sApply))
++                || (rc = sessionDeleteRow(db, zTab, &sApply))
++                || (rc = sessionInsertRow(db, zTab, &sApply))
++              ){
++              break;
++            }
++            sApply.bStat1 = 0;
+           }
+         }
+         nTab = sqlite3Strlen30(zTab);
+@@ -180076,13 +197325,21 @@
+   }
+   sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
+ 
+-  if( rc==SQLITE_OK ){
+-    rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
+-  }else{
+-    sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
+-    sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
++  if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
++    if( rc==SQLITE_OK ){
++      rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
++    }else{
++      sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
++      sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
++    }
+   }
+ 
++  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
++  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
++    *ppRebase = (void*)sApply.rebase.aBuf;
++    *pnRebase = sApply.rebase.nBuf;
++    sApply.rebase.aBuf = 0;
++  }
+   sqlite3_finalize(sApply.pInsert);
+   sqlite3_finalize(sApply.pDelete);
+   sqlite3_finalize(sApply.pUpdate);
+@@ -180089,11 +197346,44 @@
+   sqlite3_finalize(sApply.pSelect);
+   sqlite3_free((char*)sApply.azCol);  /* cast works around VC++ bug */
+   sqlite3_free((char*)sApply.constraints.aBuf);
++  sqlite3_free((char*)sApply.rebase.aBuf);
+   sqlite3_mutex_leave(sqlite3_db_mutex(db));
+   return rc;
+ }
+ 
+ /*
++** Apply the changeset passed via pChangeset/nChangeset to the main 
++** database attached to handle "db".
++*/
++SQLITE_API int sqlite3changeset_apply_v2(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase,
++  int flags
++){
++  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
++  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
++  int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetApply(
++        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
++    );
++  }
++  return rc;
++}
++
++/*
+ ** Apply the changeset passed via pChangeset/nChangeset to the main database
+ ** attached to handle "db". Invoke the supplied conflict handler callback
+ ** to resolve any conflicts encountered while applying the change.
+@@ -180113,12 +197403,9 @@
+   ),
+   void *pCtx                      /* First argument passed to xConflict */
+ ){
+-  sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+-  int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
+-  if( rc==SQLITE_OK ){
+-    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
+-  }
+-  return rc;
++  return sqlite3changeset_apply_v2(
++      db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
++  );
+ }
+ 
+ /*
+@@ -180126,7 +197413,7 @@
+ ** attached to handle "db". Invoke the supplied conflict handler callback
+ ** to resolve any conflicts encountered while applying the change.
+ */
+-SQLITE_API int sqlite3changeset_apply_strm(
++SQLITE_API int sqlite3changeset_apply_v2_strm(
+   sqlite3 *db,                    /* Apply change to "main" db of this handle */
+   int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
+   void *pIn,                                          /* First arg for xInput */
+@@ -180139,15 +197426,39 @@
+     int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
+     sqlite3_changeset_iter *p     /* Handle describing change and conflict */
+   ),
+-  void *pCtx                      /* First argument passed to xConflict */
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase,
++  int flags
+ ){
+   sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+-  int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
++  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
++  int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
+   if( rc==SQLITE_OK ){
+-    rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
++    rc = sessionChangesetApply(
++        db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
++    );
+   }
+   return rc;
+ }
++SQLITE_API int sqlite3changeset_apply_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx                      /* First argument passed to xConflict */
++){
++  return sqlite3changeset_apply_v2_strm(
++      db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
++  );
++}
+ 
+ /*
+ ** sqlite3_changegroup handle.
+@@ -180165,6 +197476,7 @@
+ */
+ static int sessionChangeMerge(
+   SessionTable *pTab,             /* Table structure */
++  int bRebase,                    /* True for a rebase hash-table */
+   int bPatchset,                  /* True for patchsets */
+   SessionChange *pExist,          /* Existing change */
+   int op2,                        /* Second change operation */
+@@ -180174,6 +197486,7 @@
+   SessionChange **ppNew           /* OUT: Merged change */
+ ){
+   SessionChange *pNew = 0;
++  int rc = SQLITE_OK;
+ 
+   if( !pExist ){
+     pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
+@@ -180183,9 +197496,66 @@
+     memset(pNew, 0, sizeof(SessionChange));
+     pNew->op = op2;
+     pNew->bIndirect = bIndirect;
+-    pNew->nRecord = nRec;
+     pNew->aRecord = (u8*)&pNew[1];
+-    memcpy(pNew->aRecord, aRec, nRec);
++    if( bIndirect==0 || bRebase==0 ){
++      pNew->nRecord = nRec;
++      memcpy(pNew->aRecord, aRec, nRec);
++    }else{
++      int i;
++      u8 *pIn = aRec;
++      u8 *pOut = pNew->aRecord;
++      for(i=0; i<pTab->nCol; i++){
++        int nIn = sessionSerialLen(pIn);
++        if( *pIn==0 ){
++          *pOut++ = 0;
++        }else if( pTab->abPK[i]==0 ){
++          *pOut++ = 0xFF;
++        }else{
++          memcpy(pOut, pIn, nIn);
++          pOut += nIn;
++        }
++        pIn += nIn;
++      }
++      pNew->nRecord = pOut - pNew->aRecord;
++    }
++  }else if( bRebase ){
++    if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
++      *ppNew = pExist;
++    }else{
++      int nByte = nRec + pExist->nRecord + sizeof(SessionChange);
++      pNew = (SessionChange*)sqlite3_malloc(nByte);
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        int i;
++        u8 *a1 = pExist->aRecord;
++        u8 *a2 = aRec;
++        u8 *pOut;
++
++        memset(pNew, 0, nByte);
++        pNew->bIndirect = bIndirect || pExist->bIndirect;
++        pNew->op = op2;
++        pOut = pNew->aRecord = (u8*)&pNew[1];
++
++        for(i=0; i<pTab->nCol; i++){
++          int n1 = sessionSerialLen(a1);
++          int n2 = sessionSerialLen(a2);
++          if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){
++            *pOut++ = 0xFF;
++          }else if( *a2==0 ){
++            memcpy(pOut, a1, n1);
++            pOut += n1;
++          }else{
++            memcpy(pOut, a2, n2);
++            pOut += n2;
++          }
++          a1 += n1;
++          a2 += n2;
++        }
++        pNew->nRecord = pOut - pNew->aRecord;
++      }
++      sqlite3_free(pExist);
++    }
+   }else{
+     int op1 = pExist->op;
+ 
+@@ -180279,7 +197649,7 @@
+   }
+ 
+   *ppNew = pNew;
+-  return SQLITE_OK;
++  return rc;
+ }
+ 
+ /*
+@@ -180288,7 +197658,8 @@
+ */
+ static int sessionChangesetToHash(
+   sqlite3_changeset_iter *pIter,   /* Iterator to read from */
+-  sqlite3_changegroup *pGrp        /* Changegroup object to add changeset to */
++  sqlite3_changegroup *pGrp,       /* Changegroup object to add changeset to */
++  int bRebase                      /* True if hash table is for rebasing */
+ ){
+   u8 *aRec;
+   int nRec;
+@@ -180295,8 +197666,7 @@
+   int rc = SQLITE_OK;
+   SessionTable *pTab = 0;
+ 
+-
+-  while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){
++  while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
+     const char *zNew;
+     int nCol;
+     int op;
+@@ -180376,7 +197746,7 @@
+       }
+     }
+ 
+-    rc = sessionChangeMerge(pTab, 
++    rc = sessionChangeMerge(pTab, bRebase, 
+         pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
+     );
+     if( rc ) break;
+@@ -180435,13 +197805,12 @@
+         sessionAppendByte(&buf, p->op, &rc);
+         sessionAppendByte(&buf, p->bIndirect, &rc);
+         sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
++        if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
++          rc = xOutput(pOut, buf.aBuf, buf.nBuf);
++          buf.nBuf = 0;
++        }
+       }
+     }
+-
+-    if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
+-      rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+-      buf.nBuf = 0;
+-    }
+   }
+ 
+   if( rc==SQLITE_OK ){
+@@ -180484,7 +197853,7 @@
+ 
+   rc = sqlite3changeset_start(&pIter, nData, pData);
+   if( rc==SQLITE_OK ){
+-    rc = sessionChangesetToHash(pIter, pGrp);
++    rc = sessionChangesetToHash(pIter, pGrp, 0);
+   }
+   sqlite3changeset_finalize(pIter);
+   return rc;
+@@ -180515,7 +197884,7 @@
+ 
+   rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+   if( rc==SQLITE_OK ){
+-    rc = sessionChangesetToHash(pIter, pGrp);
++    rc = sessionChangesetToHash(pIter, pGrp, 0);
+   }
+   sqlite3changeset_finalize(pIter);
+   return rc;
+@@ -180600,2439 +197969,373 @@
+   return rc;
+ }
+ 
+-#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+-
+-/************** End of sqlite3session.c **************************************/
+-/************** Begin file json1.c *******************************************/
+ /*
+-** 2015-08-12
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-******************************************************************************
+-**
+-** This SQLite extension implements JSON functions.  The interface is
+-** modeled after MySQL JSON functions:
+-**
+-**     https://dev.mysql.com/doc/refman/5.7/en/json.html
+-**
+-** For the time being, all JSON is stored as pure text.  (We might add
+-** a JSONB type in the future which stores a binary encoding of JSON in
+-** a BLOB, but there is no support for JSONB in the current implementation.
+-** This implementation parses JSON text at 250 MB/s, so it is hard to see
+-** how JSONB might improve on that.)
++** Changeset rebaser handle.
+ */
+-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
+-#if !defined(SQLITEINT_H)
+-/* #include "sqlite3ext.h" */
+-#endif
+-SQLITE_EXTENSION_INIT1
+-/* #include <assert.h> */
+-/* #include <string.h> */
+-/* #include <stdlib.h> */
+-/* #include <stdarg.h> */
+-
+-/* Mark a function parameter as unused, to suppress nuisance compiler
+-** warnings. */
+-#ifndef UNUSED_PARAM
+-# define UNUSED_PARAM(X)  (void)(X)
+-#endif
+-
+-#ifndef LARGEST_INT64
+-# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+-# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+-#endif
+-
+-/*
+-** Versions of isspace(), isalnum() and isdigit() to which it is safe
+-** to pass signed char values.
+-*/
+-#ifdef sqlite3Isdigit
+-   /* Use the SQLite core versions if this routine is part of the
+-   ** SQLite amalgamation */
+-#  define safe_isdigit(x)  sqlite3Isdigit(x)
+-#  define safe_isalnum(x)  sqlite3Isalnum(x)
+-#  define safe_isxdigit(x) sqlite3Isxdigit(x)
+-#else
+-   /* Use the standard library for separate compilation */
+-#include <ctype.h>  /* amalgamator: keep */
+-#  define safe_isdigit(x)  isdigit((unsigned char)(x))
+-#  define safe_isalnum(x)  isalnum((unsigned char)(x))
+-#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
+-#endif
+-
+-/*
+-** Growing our own isspace() routine this way is twice as fast as
+-** the library isspace() function, resulting in a 7% overall performance
+-** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
+-*/
+-static const char jsonIsSpace[] = {
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++struct sqlite3_rebaser {
++  sqlite3_changegroup grp;        /* Hash table */
+ };
+-#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
+ 
+-#ifndef SQLITE_AMALGAMATION
+-  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
+-  ** but the definitions need to be repeated for separate compilation. */
+-  typedef sqlite3_uint64 u64;
+-  typedef unsigned int u32;
+-  typedef unsigned short int u16;
+-  typedef unsigned char u8;
+-#endif
+-
+-/* Objects */
+-typedef struct JsonString JsonString;
+-typedef struct JsonNode JsonNode;
+-typedef struct JsonParse JsonParse;
+-
+-/* An instance of this object represents a JSON string
+-** under construction.  Really, this is a generic string accumulator
+-** that can be and is used to create strings other than JSON.
+-*/
+-struct JsonString {
+-  sqlite3_context *pCtx;   /* Function context - put error messages here */
+-  char *zBuf;              /* Append JSON content here */
+-  u64 nAlloc;              /* Bytes of storage available in zBuf[] */
+-  u64 nUsed;               /* Bytes of zBuf[] currently used */
+-  u8 bStatic;              /* True if zBuf is static space */
+-  u8 bErr;                 /* True if an error has been encountered */
+-  char zSpace[100];        /* Initial static space */
+-};
+-
+-/* JSON type values
+-*/
+-#define JSON_NULL     0
+-#define JSON_TRUE     1
+-#define JSON_FALSE    2
+-#define JSON_INT      3
+-#define JSON_REAL     4
+-#define JSON_STRING   5
+-#define JSON_ARRAY    6
+-#define JSON_OBJECT   7
+-
+-/* The "subtype" set for JSON values */
+-#define JSON_SUBTYPE  74    /* Ascii for "J" */
+-
+ /*
+-** Names of the various JSON types:
++** Buffers a1 and a2 must both contain a sessions module record nCol
++** fields in size. This function appends an nCol sessions module 
++** record to buffer pBuf that is a copy of a1, except that for
++** each field that is undefined in a1[], swap in the field from a2[].
+ */
+-static const char * const jsonType[] = {
+-  "null", "true", "false", "integer", "real", "text", "array", "object"
+-};
+-
+-/* Bit values for the JsonNode.jnFlag field
+-*/
+-#define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
+-#define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
+-#define JNODE_REMOVE  0x04         /* Do not output */
+-#define JNODE_REPLACE 0x08         /* Replace with JsonNode.u.iReplace */
+-#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
+-#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
+-#define JNODE_LABEL   0x40         /* Is a label of an object */
+-
+-
+-/* A single node of parsed JSON
+-*/
+-struct JsonNode {
+-  u8 eType;              /* One of the JSON_ type values */
+-  u8 jnFlags;            /* JNODE flags */
+-  u32 n;                 /* Bytes of content, or number of sub-nodes */
+-  union {
+-    const char *zJContent; /* Content for INT, REAL, and STRING */
+-    u32 iAppend;           /* More terms for ARRAY and OBJECT */
+-    u32 iKey;              /* Key for ARRAY objects in json_tree() */
+-    u32 iReplace;          /* Replacement content for JNODE_REPLACE */
+-    JsonNode *pPatch;      /* Node chain of patch for JNODE_PATCH */
+-  } u;
+-};
+-
+-/* A completely parsed JSON string
+-*/
+-struct JsonParse {
+-  u32 nNode;         /* Number of slots of aNode[] used */
+-  u32 nAlloc;        /* Number of slots of aNode[] allocated */
+-  JsonNode *aNode;   /* Array of nodes containing the parse */
+-  const char *zJson; /* Original JSON string */
+-  u32 *aUp;          /* Index of parent of each node */
+-  u8 oom;            /* Set to true if out of memory */
+-  u8 nErr;           /* Number of errors seen */
+-  u16 iDepth;        /* Nesting depth */
+-  int nJson;         /* Length of the zJson string in bytes */
+-};
+-
+-/*
+-** Maximum nesting depth of JSON for this implementation.
+-**
+-** This limit is needed to avoid a stack overflow in the recursive
+-** descent parser.  A depth of 2000 is far deeper than any sane JSON
+-** should go.
+-*/
+-#define JSON_MAX_DEPTH  2000
+-
+-/**************************************************************************
+-** Utility routines for dealing with JsonString objects
+-**************************************************************************/
+-
+-/* Set the JsonString object to an empty string
+-*/
+-static void jsonZero(JsonString *p){
+-  p->zBuf = p->zSpace;
+-  p->nAlloc = sizeof(p->zSpace);
+-  p->nUsed = 0;
+-  p->bStatic = 1;
+-}
+-
+-/* Initialize the JsonString object
+-*/
+-static void jsonInit(JsonString *p, sqlite3_context *pCtx){
+-  p->pCtx = pCtx;
+-  p->bErr = 0;
+-  jsonZero(p);
+-}
+-
+-
+-/* Free all allocated memory and reset the JsonString object back to its
+-** initial state.
+-*/
+-static void jsonReset(JsonString *p){
+-  if( !p->bStatic ) sqlite3_free(p->zBuf);
+-  jsonZero(p);
+-}
+-
+-
+-/* Report an out-of-memory (OOM) condition 
+-*/
+-static void jsonOom(JsonString *p){
+-  p->bErr = 1;
+-  sqlite3_result_error_nomem(p->pCtx);
+-  jsonReset(p);
+-}
+-
+-/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
+-** Return zero on success.  Return non-zero on an OOM error
+-*/
+-static int jsonGrow(JsonString *p, u32 N){
+-  u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
+-  char *zNew;
+-  if( p->bStatic ){
+-    if( p->bErr ) return 1;
+-    zNew = sqlite3_malloc64(nTotal);
+-    if( zNew==0 ){
+-      jsonOom(p);
+-      return SQLITE_NOMEM;
+-    }
+-    memcpy(zNew, p->zBuf, (size_t)p->nUsed);
+-    p->zBuf = zNew;
+-    p->bStatic = 0;
+-  }else{
+-    zNew = sqlite3_realloc64(p->zBuf, nTotal);
+-    if( zNew==0 ){
+-      jsonOom(p);
+-      return SQLITE_NOMEM;
+-    }
+-    p->zBuf = zNew;
+-  }
+-  p->nAlloc = nTotal;
+-  return SQLITE_OK;
+-}
+-
+-/* Append N bytes from zIn onto the end of the JsonString string.
+-*/
+-static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
+-  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
+-  memcpy(p->zBuf+p->nUsed, zIn, N);
+-  p->nUsed += N;
+-}
+-
+-/* Append formatted text (not to exceed N bytes) to the JsonString.
+-*/
+-static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
+-  va_list ap;
+-  if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
+-  va_start(ap, zFormat);
+-  sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
+-  va_end(ap);
+-  p->nUsed += (int)strlen(p->zBuf+p->nUsed);
+-}
+-
+-/* Append a single character
+-*/
+-static void jsonAppendChar(JsonString *p, char c){
+-  if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
+-  p->zBuf[p->nUsed++] = c;
+-}
+-
+-/* Append a comma separator to the output buffer, if the previous
+-** character is not '[' or '{'.
+-*/
+-static void jsonAppendSeparator(JsonString *p){
+-  char c;
+-  if( p->nUsed==0 ) return;
+-  c = p->zBuf[p->nUsed-1];
+-  if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
+-}
+-
+-/* Append the N-byte string in zIn to the end of the JsonString string
+-** under construction.  Enclose the string in "..." and escape
+-** any double-quotes or backslash characters contained within the
+-** string.
+-*/
+-static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
+-  u32 i;
+-  if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
+-  p->zBuf[p->nUsed++] = '"';
+-  for(i=0; i<N; i++){
+-    unsigned char c = ((unsigned const char*)zIn)[i];
+-    if( c=='"' || c=='\\' ){
+-      json_simple_escape:
+-      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
+-      p->zBuf[p->nUsed++] = '\\';
+-    }else if( c<=0x1f ){
+-      static const char aSpecial[] = {
+-         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
+-         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
+-      };
+-      assert( sizeof(aSpecial)==32 );
+-      assert( aSpecial['\b']=='b' );
+-      assert( aSpecial['\f']=='f' );
+-      assert( aSpecial['\n']=='n' );
+-      assert( aSpecial['\r']=='r' );
+-      assert( aSpecial['\t']=='t' );
+-      if( aSpecial[c] ){
+-        c = aSpecial[c];
+-        goto json_simple_escape;
+-      }
+-      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
+-      p->zBuf[p->nUsed++] = '\\';
+-      p->zBuf[p->nUsed++] = 'u';
+-      p->zBuf[p->nUsed++] = '0';
+-      p->zBuf[p->nUsed++] = '0';
+-      p->zBuf[p->nUsed++] = '0' + (c>>4);
+-      c = "0123456789abcdef"[c&0xf];
+-    }
+-    p->zBuf[p->nUsed++] = c;
+-  }
+-  p->zBuf[p->nUsed++] = '"';
+-  assert( p->nUsed<p->nAlloc );
+-}
+-
+-/*
+-** Append a function parameter value to the JSON string under 
+-** construction.
+-*/
+-static void jsonAppendValue(
+-  JsonString *p,                 /* Append to this JSON string */
+-  sqlite3_value *pValue          /* Value to append */
++static void sessionAppendRecordMerge(
++  SessionBuffer *pBuf,            /* Buffer to append to */
++  int nCol,                       /* Number of columns in each record */
++  u8 *a1, int n1,                 /* Record 1 */
++  u8 *a2, int n2,                 /* Record 2 */
++  int *pRc                        /* IN/OUT: error code */
+ ){
+-  switch( sqlite3_value_type(pValue) ){
+-    case SQLITE_NULL: {
+-      jsonAppendRaw(p, "null", 4);
+-      break;
+-    }
+-    case SQLITE_INTEGER:
+-    case SQLITE_FLOAT: {
+-      const char *z = (const char*)sqlite3_value_text(pValue);
+-      u32 n = (u32)sqlite3_value_bytes(pValue);
+-      jsonAppendRaw(p, z, n);
+-      break;
+-    }
+-    case SQLITE_TEXT: {
+-      const char *z = (const char*)sqlite3_value_text(pValue);
+-      u32 n = (u32)sqlite3_value_bytes(pValue);
+-      if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
+-        jsonAppendRaw(p, z, n);
++  sessionBufferGrow(pBuf, n1+n2, pRc);
++  if( *pRc==SQLITE_OK ){
++    int i;
++    u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
++    for(i=0; i<nCol; i++){
++      int nn1 = sessionSerialLen(a1);
++      int nn2 = sessionSerialLen(a2);
++      if( *a1==0 || *a1==0xFF ){
++        memcpy(pOut, a2, nn2);
++        pOut += nn2;
+       }else{
+-        jsonAppendString(p, z, n);
++        memcpy(pOut, a1, nn1);
++        pOut += nn1;
+       }
+-      break;
++      a1 += nn1;
++      a2 += nn2;
+     }
+-    default: {
+-      if( p->bErr==0 ){
+-        sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
+-        p->bErr = 2;
+-        jsonReset(p);
+-      }
+-      break;
+-    }
+-  }
+-}
+ 
+-
+-/* Make the JSON in p the result of the SQL function.
+-*/
+-static void jsonResult(JsonString *p){
+-  if( p->bErr==0 ){
+-    sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, 
+-                          p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
+-                          SQLITE_UTF8);
+-    jsonZero(p);
++    pBuf->nBuf = pOut-pBuf->aBuf;
++    assert( pBuf->nBuf<=pBuf->nAlloc );
+   }
+-  assert( p->bStatic );
+ }
+ 
+-/**************************************************************************
+-** Utility routines for dealing with JsonNode and JsonParse objects
+-**************************************************************************/
+-
+ /*
+-** Return the number of consecutive JsonNode slots need to represent
+-** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
+-** OBJECT types, the number might be larger.
++** This function is called when rebasing a local UPDATE change against one 
++** or more remote UPDATE changes. The aRec/nRec buffer contains the current
++** old.* and new.* records for the change. The rebase buffer (a single
++** record) is in aChange/nChange. The rebased change is appended to buffer
++** pBuf.
+ **
+-** Appended elements are not counted.  The value returned is the number
+-** by which the JsonNode counter should increment in order to go to the
+-** next peer value.
++** Rebasing the UPDATE involves: 
++**
++**   * Removing any changes to fields for which the corresponding field
++**     in the rebase buffer is set to "replaced" (type 0xFF). If this
++**     means the UPDATE change updates no fields, nothing is appended
++**     to the output buffer.
++**
++**   * For each field modified by the local change for which the 
++**     corresponding field in the rebase buffer is not "undefined" (0x00)
++**     or "replaced" (0xFF), the old.* value is replaced by the value
++**     in the rebase buffer.
+ */
+-static u32 jsonNodeSize(JsonNode *pNode){
+-  return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
+-}
+-
+-/*
+-** Reclaim all memory allocated by a JsonParse object.  But do not
+-** delete the JsonParse object itself.
+-*/
+-static void jsonParseReset(JsonParse *pParse){
+-  sqlite3_free(pParse->aNode);
+-  pParse->aNode = 0;
+-  pParse->nNode = 0;
+-  pParse->nAlloc = 0;
+-  sqlite3_free(pParse->aUp);
+-  pParse->aUp = 0;
+-}
+-
+-/*
+-** Free a JsonParse object that was obtained from sqlite3_malloc().
+-*/
+-static void jsonParseFree(JsonParse *pParse){
+-  jsonParseReset(pParse);
+-  sqlite3_free(pParse);
+-}
+-
+-/*
+-** Convert the JsonNode pNode into a pure JSON string and
+-** append to pOut.  Subsubstructure is also included.  Return
+-** the number of JsonNode objects that are encoded.
+-*/
+-static void jsonRenderNode(
+-  JsonNode *pNode,               /* The node to render */
+-  JsonString *pOut,              /* Write JSON here */
+-  sqlite3_value **aReplace       /* Replacement values */
++static void sessionAppendPartialUpdate(
++  SessionBuffer *pBuf,            /* Append record here */
++  sqlite3_changeset_iter *pIter,  /* Iterator pointed at local change */
++  u8 *aRec, int nRec,             /* Local change */
++  u8 *aChange, int nChange,       /* Record to rebase against */
++  int *pRc                        /* IN/OUT: Return Code */
+ ){
+-  if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
+-    if( pNode->jnFlags & JNODE_REPLACE ){
+-      jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
+-      return;
+-    }
+-    pNode = pNode->u.pPatch;
+-  }
+-  switch( pNode->eType ){
+-    default: {
+-      assert( pNode->eType==JSON_NULL );
+-      jsonAppendRaw(pOut, "null", 4);
+-      break;
+-    }
+-    case JSON_TRUE: {
+-      jsonAppendRaw(pOut, "true", 4);
+-      break;
+-    }
+-    case JSON_FALSE: {
+-      jsonAppendRaw(pOut, "false", 5);
+-      break;
+-    }
+-    case JSON_STRING: {
+-      if( pNode->jnFlags & JNODE_RAW ){
+-        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
+-        break;
+-      }
+-      /* Fall through into the next case */
+-    }
+-    case JSON_REAL:
+-    case JSON_INT: {
+-      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+-      break;
+-    }
+-    case JSON_ARRAY: {
+-      u32 j = 1;
+-      jsonAppendChar(pOut, '[');
+-      for(;;){
+-        while( j<=pNode->n ){
+-          if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
+-            jsonAppendSeparator(pOut);
+-            jsonRenderNode(&pNode[j], pOut, aReplace);
+-          }
+-          j += jsonNodeSize(&pNode[j]);
+-        }
+-        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+-        pNode = &pNode[pNode->u.iAppend];
+-        j = 1;
+-      }
+-      jsonAppendChar(pOut, ']');
+-      break;
+-    }
+-    case JSON_OBJECT: {
+-      u32 j = 1;
+-      jsonAppendChar(pOut, '{');
+-      for(;;){
+-        while( j<=pNode->n ){
+-          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
+-            jsonAppendSeparator(pOut);
+-            jsonRenderNode(&pNode[j], pOut, aReplace);
+-            jsonAppendChar(pOut, ':');
+-            jsonRenderNode(&pNode[j+1], pOut, aReplace);
+-          }
+-          j += 1 + jsonNodeSize(&pNode[j+1]);
+-        }
+-        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+-        pNode = &pNode[pNode->u.iAppend];
+-        j = 1;
+-      }
+-      jsonAppendChar(pOut, '}');
+-      break;
+-    }
+-  }
+-}
++  sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
++  if( *pRc==SQLITE_OK ){
++    int bData = 0;
++    u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
++    int i;
++    u8 *a1 = aRec;
++    u8 *a2 = aChange;
+ 
+-/*
+-** Return a JsonNode and all its descendents as a JSON string.
+-*/
+-static void jsonReturnJson(
+-  JsonNode *pNode,            /* Node to return */
+-  sqlite3_context *pCtx,      /* Return value for this function */
+-  sqlite3_value **aReplace    /* Array of replacement values */
+-){
+-  JsonString s;
+-  jsonInit(&s, pCtx);
+-  jsonRenderNode(pNode, &s, aReplace);
+-  jsonResult(&s);
+-  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** Make the JsonNode the return value of the function.
+-*/
+-static void jsonReturn(
+-  JsonNode *pNode,            /* Node to return */
+-  sqlite3_context *pCtx,      /* Return value for this function */
+-  sqlite3_value **aReplace    /* Array of replacement values */
+-){
+-  switch( pNode->eType ){
+-    default: {
+-      assert( pNode->eType==JSON_NULL );
+-      sqlite3_result_null(pCtx);
+-      break;
+-    }
+-    case JSON_TRUE: {
+-      sqlite3_result_int(pCtx, 1);
+-      break;
+-    }
+-    case JSON_FALSE: {
+-      sqlite3_result_int(pCtx, 0);
+-      break;
+-    }
+-    case JSON_INT: {
+-      sqlite3_int64 i = 0;
+-      const char *z = pNode->u.zJContent;
+-      if( z[0]=='-' ){ z++; }
+-      while( z[0]>='0' && z[0]<='9' ){
+-        unsigned v = *(z++) - '0';
+-        if( i>=LARGEST_INT64/10 ){
+-          if( i>LARGEST_INT64/10 ) goto int_as_real;
+-          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
+-          if( v==9 ) goto int_as_real;
+-          if( v==8 ){
+-            if( pNode->u.zJContent[0]=='-' ){
+-              sqlite3_result_int64(pCtx, SMALLEST_INT64);
+-              goto int_done;
+-            }else{
+-              goto int_as_real;
+-            }
+-          }
+-        }
+-        i = i*10 + v;
++    *pOut++ = SQLITE_UPDATE;
++    *pOut++ = pIter->bIndirect;
++    for(i=0; i<pIter->nCol; i++){
++      int n1 = sessionSerialLen(a1);
++      int n2 = sessionSerialLen(a2);
++      if( pIter->abPK[i] || a2[0]==0 ){
++        if( !pIter->abPK[i] ) bData = 1;
++        memcpy(pOut, a1, n1);
++        pOut += n1;
++      }else if( a2[0]!=0xFF ){
++        bData = 1;
++        memcpy(pOut, a2, n2);
++        pOut += n2;
++      }else{
++        *pOut++ = '\0';
+       }
+-      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
+-      sqlite3_result_int64(pCtx, i);
+-      int_done:
+-      break;
+-      int_as_real: /* fall through to real */;
++      a1 += n1;
++      a2 += n2;
+     }
+-    case JSON_REAL: {
+-      double r;
+-#ifdef SQLITE_AMALGAMATION
+-      const char *z = pNode->u.zJContent;
+-      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
+-#else
+-      r = strtod(pNode->u.zJContent, 0);
+-#endif
+-      sqlite3_result_double(pCtx, r);
+-      break;
+-    }
+-    case JSON_STRING: {
+-#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
+-      ** json_insert() and json_replace() and those routines do not
+-      ** call jsonReturn() */
+-      if( pNode->jnFlags & JNODE_RAW ){
+-        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
+-                            SQLITE_TRANSIENT);
+-      }else 
+-#endif
+-      assert( (pNode->jnFlags & JNODE_RAW)==0 );
+-      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+-        /* JSON formatted without any backslash-escapes */
+-        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
+-                            SQLITE_TRANSIENT);
+-      }else{
+-        /* Translate JSON formatted string into raw text */
+-        u32 i;
+-        u32 n = pNode->n;
+-        const char *z = pNode->u.zJContent;
+-        char *zOut;
+-        u32 j;
+-        zOut = sqlite3_malloc( n+1 );
+-        if( zOut==0 ){
+-          sqlite3_result_error_nomem(pCtx);
+-          break;
++    if( bData ){
++      a2 = aChange;
++      for(i=0; i<pIter->nCol; i++){
++        int n1 = sessionSerialLen(a1);
++        int n2 = sessionSerialLen(a2);
++        if( pIter->abPK[i] || a2[0]!=0xFF ){
++          memcpy(pOut, a1, n1);
++          pOut += n1;
++        }else{
++          *pOut++ = '\0';
+         }
+-        for(i=1, j=0; i<n-1; i++){
+-          char c = z[i];
+-          if( c!='\\' ){
+-            zOut[j++] = c;
+-          }else{
+-            c = z[++i];
+-            if( c=='u' ){
+-              u32 v = 0, k;
+-              for(k=0; k<4; i++, k++){
+-                assert( i<n-2 );
+-                c = z[i+1];
+-                assert( safe_isxdigit(c) );
+-                if( c<='9' ) v = v*16 + c - '0';
+-                else if( c<='F' ) v = v*16 + c - 'A' + 10;
+-                else v = v*16 + c - 'a' + 10;
+-              }
+-              if( v==0 ) break;
+-              if( v<=0x7f ){
+-                zOut[j++] = (char)v;
+-              }else if( v<=0x7ff ){
+-                zOut[j++] = (char)(0xc0 | (v>>6));
+-                zOut[j++] = 0x80 | (v&0x3f);
+-              }else{
+-                zOut[j++] = (char)(0xe0 | (v>>12));
+-                zOut[j++] = 0x80 | ((v>>6)&0x3f);
+-                zOut[j++] = 0x80 | (v&0x3f);
+-              }
+-            }else{
+-              if( c=='b' ){
+-                c = '\b';
+-              }else if( c=='f' ){
+-                c = '\f';
+-              }else if( c=='n' ){
+-                c = '\n';
+-              }else if( c=='r' ){
+-                c = '\r';
+-              }else if( c=='t' ){
+-                c = '\t';
+-              }
+-              zOut[j++] = c;
+-            }
+-          }
+-        }
+-        zOut[j] = 0;
+-        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
++        a1 += n1;
++        a2 += n2;
+       }
+-      break;
++      pBuf->nBuf = (pOut - pBuf->aBuf);
+     }
+-    case JSON_ARRAY:
+-    case JSON_OBJECT: {
+-      jsonReturnJson(pNode, pCtx, aReplace);
+-      break;
+-    }
+   }
+ }
+ 
+-/* Forward reference */
+-static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
+-
+ /*
+-** A macro to hint to the compiler that a function should not be
+-** inlined.
++** pIter is configured to iterate through a changeset. This function rebases 
++** that changeset according to the current configuration of the rebaser 
++** object passed as the first argument. If no error occurs and argument xOutput
++** is not NULL, then the changeset is returned to the caller by invoking
++** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
++** then (*ppOut) is set to point to a buffer containing the rebased changeset
++** before this function returns. In this case (*pnOut) is set to the size of
++** the buffer in bytes.  It is the responsibility of the caller to eventually
++** free the (*ppOut) buffer using sqlite3_free(). 
++**
++** If an error occurs, an SQLite error code is returned. If ppOut and
++** pnOut are not NULL, then the two output parameters are set to 0 before
++** returning.
+ */
+-#if defined(__GNUC__)
+-#  define JSON_NOINLINE  __attribute__((noinline))
+-#elif defined(_MSC_VER) && _MSC_VER>=1310
+-#  define JSON_NOINLINE  __declspec(noinline)
+-#else
+-#  define JSON_NOINLINE
+-#endif
+-
+-
+-static JSON_NOINLINE int jsonParseAddNodeExpand(
+-  JsonParse *pParse,        /* Append the node to this object */
+-  u32 eType,                /* Node type */
+-  u32 n,                    /* Content size or sub-node count */
+-  const char *zContent      /* Content */
++static int sessionRebase(
++  sqlite3_rebaser *p,             /* Rebaser hash table */
++  sqlite3_changeset_iter *pIter,  /* Input data */
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut,                     /* Context for xOutput callback */
++  int *pnOut,                     /* OUT: Number of bytes in output changeset */
++  void **ppOut                    /* OUT: Inverse of pChangeset */
+ ){
+-  u32 nNew;
+-  JsonNode *pNew;
+-  assert( pParse->nNode>=pParse->nAlloc );
+-  if( pParse->oom ) return -1;
+-  nNew = pParse->nAlloc*2 + 10;
+-  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+-  if( pNew==0 ){
+-    pParse->oom = 1;
+-    return -1;
+-  }
+-  pParse->nAlloc = nNew;
+-  pParse->aNode = pNew;
+-  assert( pParse->nNode<pParse->nAlloc );
+-  return jsonParseAddNode(pParse, eType, n, zContent);
+-}
++  int rc = SQLITE_OK;
++  u8 *aRec = 0;
++  int nRec = 0;
++  int bNew = 0;
++  SessionTable *pTab = 0;
++  SessionBuffer sOut = {0,0,0};
+ 
+-/*
+-** Create a new JsonNode instance based on the arguments and append that
+-** instance to the JsonParse.  Return the index in pParse->aNode[] of the
+-** new node, or -1 if a memory allocation fails.
+-*/
+-static int jsonParseAddNode(
+-  JsonParse *pParse,        /* Append the node to this object */
+-  u32 eType,                /* Node type */
+-  u32 n,                    /* Content size or sub-node count */
+-  const char *zContent      /* Content */
+-){
+-  JsonNode *p;
+-  if( pParse->nNode>=pParse->nAlloc ){
+-    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
+-  }
+-  p = &pParse->aNode[pParse->nNode];
+-  p->eType = (u8)eType;
+-  p->jnFlags = 0;
+-  p->n = n;
+-  p->u.zJContent = zContent;
+-  return pParse->nNode++;
+-}
++  while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
++    SessionChange *pChange = 0;
++    int bDone = 0;
+ 
+-/*
+-** Return true if z[] begins with 4 (or more) hexadecimal digits
+-*/
+-static int jsonIs4Hex(const char *z){
+-  int i;
+-  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
+-  return 1;
+-}
+-
+-/*
+-** Parse a single JSON value which begins at pParse->zJson[i].  Return the
+-** index of the first character past the end of the value parsed.
+-**
+-** Return negative for a syntax error.  Special cases:  return -2 if the
+-** first non-whitespace character is '}' and return -3 if the first
+-** non-whitespace character is ']'.
+-*/
+-static int jsonParseValue(JsonParse *pParse, u32 i){
+-  char c;
+-  u32 j;
+-  int iThis;
+-  int x;
+-  JsonNode *pNode;
+-  const char *z = pParse->zJson;
+-  while( safe_isspace(z[i]) ){ i++; }
+-  if( (c = z[i])=='{' ){
+-    /* Parse object */
+-    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+-    if( iThis<0 ) return -1;
+-    for(j=i+1;;j++){
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+-      x = jsonParseValue(pParse, j);
+-      if( x<0 ){
+-        pParse->iDepth--;
+-        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
+-        return -1;
++    if( bNew ){
++      const char *zTab = pIter->zTab;
++      for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
++        if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
+       }
+-      if( pParse->oom ) return -1;
+-      pNode = &pParse->aNode[pParse->nNode-1];
+-      if( pNode->eType!=JSON_STRING ) return -1;
+-      pNode->jnFlags |= JNODE_LABEL;
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( z[j]!=':' ) return -1;
+-      j++;
+-      x = jsonParseValue(pParse, j);
+-      pParse->iDepth--;
+-      if( x<0 ) return -1;
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      c = z[j];
+-      if( c==',' ) continue;
+-      if( c!='}' ) return -1;
+-      break;
+-    }
+-    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+-    return j+1;
+-  }else if( c=='[' ){
+-    /* Parse array */
+-    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+-    if( iThis<0 ) return -1;
+-    for(j=i+1;;j++){
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+-      x = jsonParseValue(pParse, j);
+-      pParse->iDepth--;
+-      if( x<0 ){
+-        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+-        return -1;
+-      }
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      c = z[j];
+-      if( c==',' ) continue;
+-      if( c!=']' ) return -1;
+-      break;
+-    }
+-    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+-    return j+1;
+-  }else if( c=='"' ){
+-    /* Parse string */
+-    u8 jnFlags = 0;
+-    j = i+1;
+-    for(;;){
+-      c = z[j];
+-      if( (c & ~0x1f)==0 ){
+-        /* Control characters are not allowed in strings */
+-        return -1;
+-      }
+-      if( c=='\\' ){
+-        c = z[++j];
+-        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
+-           || c=='n' || c=='r' || c=='t'
+-           || (c=='u' && jsonIs4Hex(z+j+1)) ){
+-          jnFlags = JNODE_ESCAPE;
+-        }else{
+-          return -1;
+-        }
+-      }else if( c=='"' ){
+-        break;
+-      }
+-      j++;
+-    }
+-    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
+-    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
+-    return j+1;
+-  }else if( c=='n'
+-         && strncmp(z+i,"null",4)==0
+-         && !safe_isalnum(z[i+4]) ){
+-    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+-    return i+4;
+-  }else if( c=='t'
+-         && strncmp(z+i,"true",4)==0
+-         && !safe_isalnum(z[i+4]) ){
+-    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+-    return i+4;
+-  }else if( c=='f'
+-         && strncmp(z+i,"false",5)==0
+-         && !safe_isalnum(z[i+5]) ){
+-    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+-    return i+5;
+-  }else if( c=='-' || (c>='0' && c<='9') ){
+-    /* Parse number */
+-    u8 seenDP = 0;
+-    u8 seenE = 0;
+-    assert( '-' < '0' );
+-    if( c<='0' ){
+-      j = c=='-' ? i+1 : i;
+-      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+-    }
+-    j = i+1;
+-    for(;; j++){
+-      c = z[j];
+-      if( c>='0' && c<='9' ) continue;
+-      if( c=='.' ){
+-        if( z[j-1]=='-' ) return -1;
+-        if( seenDP ) return -1;
+-        seenDP = 1;
+-        continue;
+-      }
+-      if( c=='e' || c=='E' ){
+-        if( z[j-1]<'0' ) return -1;
+-        if( seenE ) return -1;
+-        seenDP = seenE = 1;
+-        c = z[j+1];
+-        if( c=='+' || c=='-' ){
+-          j++;
+-          c = z[j+1];
+-        }
+-        if( c<'0' || c>'9' ) return -1;
+-        continue;
+-      }
+-      break;
+-    }
+-    if( z[j-1]<'0' ) return -1;
+-    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
+-                        j - i, &z[i]);
+-    return j;
+-  }else if( c=='}' ){
+-    return -2;  /* End of {...} */
+-  }else if( c==']' ){
+-    return -3;  /* End of [...] */
+-  }else if( c==0 ){
+-    return 0;   /* End of file */
+-  }else{
+-    return -1;  /* Syntax error */
+-  }
+-}
++      bNew = 0;
+ 
+-/*
+-** Parse a complete JSON string.  Return 0 on success or non-zero if there
+-** are any errors.  If an error occurs, free all memory associated with
+-** pParse.
+-**
+-** pParse is uninitialized when this routine is called.
+-*/
+-static int jsonParse(
+-  JsonParse *pParse,           /* Initialize and fill this JsonParse object */
+-  sqlite3_context *pCtx,       /* Report errors here */
+-  const char *zJson            /* Input JSON text to be parsed */
+-){
+-  int i;
+-  memset(pParse, 0, sizeof(*pParse));
+-  if( zJson==0 ) return 1;
+-  pParse->zJson = zJson;
+-  i = jsonParseValue(pParse, 0);
+-  if( pParse->oom ) i = -1;
+-  if( i>0 ){
+-    assert( pParse->iDepth==0 );
+-    while( safe_isspace(zJson[i]) ) i++;
+-    if( zJson[i] ) i = -1;
+-  }
+-  if( i<=0 ){
+-    if( pCtx!=0 ){
+-      if( pParse->oom ){
+-        sqlite3_result_error_nomem(pCtx);
+-      }else{
+-        sqlite3_result_error(pCtx, "malformed JSON", -1);
++      /* A patchset may not be rebased */
++      if( pIter->bPatchset ){
++        rc = SQLITE_ERROR;
+       }
+-    }
+-    jsonParseReset(pParse);
+-    return 1;
+-  }
+-  return 0;
+-}
+ 
+-/* Mark node i of pParse as being a child of iParent.  Call recursively
+-** to fill in all the descendants of node i.
+-*/
+-static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
+-  JsonNode *pNode = &pParse->aNode[i];
+-  u32 j;
+-  pParse->aUp[i] = iParent;
+-  switch( pNode->eType ){
+-    case JSON_ARRAY: {
+-      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
+-        jsonParseFillInParentage(pParse, i+j, i);
+-      }
+-      break;
++      /* Append a table header to the output for this new table */
++      sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
++      sessionAppendVarint(&sOut, pIter->nCol, &rc);
++      sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
++      sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
+     }
+-    case JSON_OBJECT: {
+-      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
+-        pParse->aUp[i+j] = i;
+-        jsonParseFillInParentage(pParse, i+j+1, i);
+-      }
+-      break;
+-    }
+-    default: {
+-      break;
+-    }
+-  }
+-}
+ 
+-/*
+-** Compute the parentage of all nodes in a completed parse.
+-*/
+-static int jsonParseFindParents(JsonParse *pParse){
+-  u32 *aUp;
+-  assert( pParse->aUp==0 );
+-  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+-  if( aUp==0 ){
+-    pParse->oom = 1;
+-    return SQLITE_NOMEM;
+-  }
+-  jsonParseFillInParentage(pParse, 0, 0);
+-  return SQLITE_OK;
+-}
++    if( pTab && rc==SQLITE_OK ){
++      int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
+ 
+-/*
+-** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
+-*/
+-#define JSON_CACHE_ID  (-429938)
+-
+-/*
+-** Obtain a complete parse of the JSON found in the first argument
+-** of the argv array.  Use the sqlite3_get_auxdata() cache for this
+-** parse if it is available.  If the cache is not available or if it
+-** is no longer valid, parse the JSON again and return the new parse,
+-** and also register the new parse so that it will be available for
+-** future sqlite3_get_auxdata() calls.
+-*/
+-static JsonParse *jsonParseCached(
+-  sqlite3_context *pCtx,
+-  sqlite3_value **argv
+-){
+-  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
+-  int nJson = sqlite3_value_bytes(argv[0]);
+-  JsonParse *p;
+-  if( zJson==0 ) return 0;
+-  p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+-  if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
+-    p->nErr = 0;
+-    return p; /* The cached entry matches, so return it */
+-  }
+-  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+-  if( p==0 ){
+-    sqlite3_result_error_nomem(pCtx);
+-    return 0;
+-  }
+-  memset(p, 0, sizeof(*p));
+-  p->zJson = (char*)&p[1];
+-  memcpy((char*)p->zJson, zJson, nJson+1);
+-  if( jsonParse(p, pCtx, p->zJson) ){
+-    sqlite3_free(p);
+-    return 0;
+-  }
+-  p->nJson = nJson;
+-  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
+-  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+-}
+-
+-/*
+-** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
+-** a match.
+-*/
+-static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
+-  if( pNode->jnFlags & JNODE_RAW ){
+-    if( pNode->n!=nKey ) return 0;
+-    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
+-  }else{
+-    if( pNode->n!=nKey+2 ) return 0;
+-    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
+-  }
+-}
+-
+-/* forward declaration */
+-static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
+-
+-/*
+-** Search along zPath to find the node specified.  Return a pointer
+-** to that node, or NULL if zPath is malformed or if there is no such
+-** node.
+-**
+-** If pApnd!=0, then try to append new nodes to complete zPath if it is
+-** possible to do so and if no existing node corresponds to zPath.  If
+-** new nodes are appended *pApnd is set to 1.
+-*/
+-static JsonNode *jsonLookupStep(
+-  JsonParse *pParse,      /* The JSON to search */
+-  u32 iRoot,              /* Begin the search at this node */
+-  const char *zPath,      /* The path to search */
+-  int *pApnd,             /* Append nodes to complete path if not NULL */
+-  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
+-){
+-  u32 i, j, nKey;
+-  const char *zKey;
+-  JsonNode *pRoot = &pParse->aNode[iRoot];
+-  if( zPath[0]==0 ) return pRoot;
+-  if( zPath[0]=='.' ){
+-    if( pRoot->eType!=JSON_OBJECT ) return 0;
+-    zPath++;
+-    if( zPath[0]=='"' ){
+-      zKey = zPath + 1;
+-      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
+-      nKey = i-1;
+-      if( zPath[i] ){
+-        i++;
+-      }else{
+-        *pzErr = zPath;
+-        return 0;
+-      }
+-    }else{
+-      zKey = zPath;
+-      for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
+-      nKey = i;
+-    }
+-    if( nKey==0 ){
+-      *pzErr = zPath;
+-      return 0;
+-    }
+-    j = 1;
+-    for(;;){
+-      while( j<=pRoot->n ){
+-        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
+-          return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
++      for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
++        if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
++          break;
+         }
+-        j++;
+-        j += jsonNodeSize(&pRoot[j]);
+       }
+-      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+-      iRoot += pRoot->u.iAppend;
+-      pRoot = &pParse->aNode[iRoot];
+-      j = 1;
+     }
+-    if( pApnd ){
+-      u32 iStart, iLabel;
+-      JsonNode *pNode;
+-      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+-      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+-      zPath += i;
+-      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+-      if( pParse->oom ) return 0;
+-      if( pNode ){
+-        pRoot = &pParse->aNode[iRoot];
+-        pRoot->u.iAppend = iStart - iRoot;
+-        pRoot->jnFlags |= JNODE_APPEND;
+-        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
+-      }
+-      return pNode;
+-    }
+-  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
+-    if( pRoot->eType!=JSON_ARRAY ) return 0;
+-    i = 0;
+-    j = 1;
+-    while( safe_isdigit(zPath[j]) ){
+-      i = i*10 + zPath[j] - '0';
+-      j++;
+-    }
+-    if( zPath[j]!=']' ){
+-      *pzErr = zPath;
+-      return 0;
+-    }
+-    zPath += j + 1;
+-    j = 1;
+-    for(;;){
+-      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
+-        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
+-        j += jsonNodeSize(&pRoot[j]);
+-      }
+-      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+-      iRoot += pRoot->u.iAppend;
+-      pRoot = &pParse->aNode[iRoot];
+-      j = 1;
+-    }
+-    if( j<=pRoot->n ){
+-      return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
+-    }
+-    if( i==0 && pApnd ){
+-      u32 iStart;
+-      JsonNode *pNode;
+-      iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
+-      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+-      if( pParse->oom ) return 0;
+-      if( pNode ){
+-        pRoot = &pParse->aNode[iRoot];
+-        pRoot->u.iAppend = iStart - iRoot;
+-        pRoot->jnFlags |= JNODE_APPEND;
+-      }
+-      return pNode;
+-    }
+-  }else{
+-    *pzErr = zPath;
+-  }
+-  return 0;
+-}
+ 
+-/*
+-** Append content to pParse that will complete zPath.  Return a pointer
+-** to the inserted node, or return NULL if the append fails.
+-*/
+-static JsonNode *jsonLookupAppend(
+-  JsonParse *pParse,     /* Append content to the JSON parse */
+-  const char *zPath,     /* Description of content to append */
+-  int *pApnd,            /* Set this flag to 1 */
+-  const char **pzErr     /* Make this point to any syntax error */
+-){
+-  *pApnd = 1;
+-  if( zPath[0]==0 ){
+-    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+-    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
+-  }
+-  if( zPath[0]=='.' ){
+-    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+-  }else if( strncmp(zPath,"[0]",3)==0 ){
+-    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+-  }else{
+-    return 0;
+-  }
+-  if( pParse->oom ) return 0;
+-  return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
+-}
++    if( pChange ){
++      assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
++      switch( pIter->op ){
++        case SQLITE_INSERT:
++          if( pChange->op==SQLITE_INSERT ){
++            bDone = 1;
++            if( pChange->bIndirect==0 ){
++              sessionAppendByte(&sOut, SQLITE_UPDATE, &rc);
++              sessionAppendByte(&sOut, pIter->bIndirect, &rc);
++              sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc);
++              sessionAppendBlob(&sOut, aRec, nRec, &rc);
++            }
++          }
++          break;
+ 
+-/*
+-** Return the text of a syntax error message on a JSON path.  Space is
+-** obtained from sqlite3_malloc().
+-*/
+-static char *jsonPathSyntaxError(const char *zErr){
+-  return sqlite3_mprintf("JSON path error near '%q'", zErr);
+-}
++        case SQLITE_UPDATE:
++          bDone = 1;
++          if( pChange->op==SQLITE_DELETE ){
++            if( pChange->bIndirect==0 ){
++              u8 *pCsr = aRec;
++              sessionSkipRecord(&pCsr, pIter->nCol);
++              sessionAppendByte(&sOut, SQLITE_INSERT, &rc);
++              sessionAppendByte(&sOut, pIter->bIndirect, &rc);
++              sessionAppendRecordMerge(&sOut, pIter->nCol,
++                  pCsr, nRec-(pCsr-aRec), 
++                  pChange->aRecord, pChange->nRecord, &rc
++              );
++            }
++          }else{
++            sessionAppendPartialUpdate(&sOut, pIter,
++                aRec, nRec, pChange->aRecord, pChange->nRecord, &rc
++            );
++          }
++          break;
+ 
+-/*
+-** Do a node lookup using zPath.  Return a pointer to the node on success.
+-** Return NULL if not found or if there is an error.
+-**
+-** On an error, write an error message into pCtx and increment the
+-** pParse->nErr counter.
+-**
+-** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
+-** nodes are appended.
+-*/
+-static JsonNode *jsonLookup(
+-  JsonParse *pParse,      /* The JSON to search */
+-  const char *zPath,      /* The path to search */
+-  int *pApnd,             /* Append nodes to complete path if not NULL */
+-  sqlite3_context *pCtx   /* Report errors here, if not NULL */
+-){
+-  const char *zErr = 0;
+-  JsonNode *pNode = 0;
+-  char *zMsg;
+-
+-  if( zPath==0 ) return 0;
+-  if( zPath[0]!='$' ){
+-    zErr = zPath;
+-    goto lookup_err;
+-  }
+-  zPath++;
+-  pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
+-  if( zErr==0 ) return pNode;
+-
+-lookup_err:
+-  pParse->nErr++;
+-  assert( zErr!=0 && pCtx!=0 );
+-  zMsg = jsonPathSyntaxError(zErr);
+-  if( zMsg ){
+-    sqlite3_result_error(pCtx, zMsg, -1);
+-    sqlite3_free(zMsg);
+-  }else{
+-    sqlite3_result_error_nomem(pCtx);
+-  }
+-  return 0;
+-}
+-
+-
+-/*
+-** Report the wrong number of arguments for json_insert(), json_replace()
+-** or json_set().
+-*/
+-static void jsonWrongNumArgs(
+-  sqlite3_context *pCtx,
+-  const char *zFuncName
+-){
+-  char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
+-                               zFuncName);
+-  sqlite3_result_error(pCtx, zMsg, -1);
+-  sqlite3_free(zMsg);     
+-}
+-
+-/*
+-** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
+-*/
+-static void jsonRemoveAllNulls(JsonNode *pNode){
+-  int i, n;
+-  assert( pNode->eType==JSON_OBJECT );
+-  n = pNode->n;
+-  for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
+-    switch( pNode[i].eType ){
+-      case JSON_NULL:
+-        pNode[i].jnFlags |= JNODE_REMOVE;
+-        break;
+-      case JSON_OBJECT:
+-        jsonRemoveAllNulls(&pNode[i]);
+-        break;
++        default:
++          assert( pIter->op==SQLITE_DELETE );
++          bDone = 1;
++          if( pChange->op==SQLITE_INSERT ){
++            sessionAppendByte(&sOut, SQLITE_DELETE, &rc);
++            sessionAppendByte(&sOut, pIter->bIndirect, &rc);
++            sessionAppendRecordMerge(&sOut, pIter->nCol,
++                pChange->aRecord, pChange->nRecord, aRec, nRec, &rc
++            );
++          }
++          break;
++      }
+     }
+-  }
+-}
+ 
+-
+-/****************************************************************************
+-** SQL functions used for testing and debugging
+-****************************************************************************/
+-
+-#ifdef SQLITE_DEBUG
+-/*
+-** The json_parse(JSON) function returns a string which describes
+-** a parse of the JSON provided.  Or it returns NULL if JSON is not
+-** well-formed.
+-*/
+-static void jsonParseFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString s;       /* Output string - not real JSON */
+-  JsonParse x;        /* The parse */
+-  u32 i;
+-
+-  assert( argc==1 );
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  jsonParseFindParents(&x);
+-  jsonInit(&s, ctx);
+-  for(i=0; i<x.nNode; i++){
+-    const char *zType;
+-    if( x.aNode[i].jnFlags & JNODE_LABEL ){
+-      assert( x.aNode[i].eType==JSON_STRING );
+-      zType = "label";
+-    }else{
+-      zType = jsonType[x.aNode[i].eType];
++    if( bDone==0 ){
++      sessionAppendByte(&sOut, pIter->op, &rc);
++      sessionAppendByte(&sOut, pIter->bIndirect, &rc);
++      sessionAppendBlob(&sOut, aRec, nRec, &rc);
+     }
+-    jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
+-               i, zType, x.aNode[i].n, x.aUp[i]);
+-    if( x.aNode[i].u.zJContent!=0 ){
+-      jsonAppendRaw(&s, " ", 1);
+-      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
++    if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
++      rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
++      sOut.nBuf = 0;
+     }
+-    jsonAppendRaw(&s, "\n", 1);
++    if( rc ) break;
+   }
+-  jsonParseReset(&x);
+-  jsonResult(&s);
+-}
+ 
+-/*
+-** The json_test1(JSON) function return true (1) if the input is JSON
+-** text generated by another json function.  It returns (0) if the input
+-** is not known to be JSON.
+-*/
+-static void jsonTest1Func(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  UNUSED_PARAM(argc);
+-  sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
+-}
+-#endif /* SQLITE_DEBUG */
+-
+-/****************************************************************************
+-** Scalar SQL function implementations
+-****************************************************************************/
+-
+-/*
+-** Implementation of the json_QUOTE(VALUE) function.  Return a JSON value
+-** corresponding to the SQL value input.  Mostly this means putting 
+-** double-quotes around strings and returning the unquoted string "null"
+-** when given a NULL input.
+-*/
+-static void jsonQuoteFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString jx;
+-  UNUSED_PARAM(argc);
+-
+-  jsonInit(&jx, ctx);
+-  jsonAppendValue(&jx, argv[0]);
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** Implementation of the json_array(VALUE,...) function.  Return a JSON
+-** array that contains all values given in arguments.  Or if any argument
+-** is a BLOB, throw an error.
+-*/
+-static void jsonArrayFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  int i;
+-  JsonString jx;
+-
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '[');
+-  for(i=0; i<argc; i++){
+-    jsonAppendSeparator(&jx);
+-    jsonAppendValue(&jx, argv[i]);
++  if( rc!=SQLITE_OK ){
++    sqlite3_free(sOut.aBuf);
++    memset(&sOut, 0, sizeof(sOut));
+   }
+-  jsonAppendChar(&jx, ']');
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+ 
+-
+-/*
+-** json_array_length(JSON)
+-** json_array_length(JSON, PATH)
+-**
+-** Return the number of elements in the top-level JSON array.  
+-** Return 0 if the input is not a well-formed JSON array.
+-*/
+-static void jsonArrayLengthFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse *p;          /* The parse */
+-  sqlite3_int64 n = 0;
+-  u32 i;
+-  JsonNode *pNode;
+-
+-  p = jsonParseCached(ctx, argv);
+-  if( p==0 ) return;
+-  assert( p->nNode );
+-  if( argc==2 ){
+-    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
+-    pNode = jsonLookup(p, zPath, 0, ctx);
+-  }else{
+-    pNode = p->aNode;
+-  }
+-  if( pNode==0 ){
+-    return;
+-  }
+-  if( pNode->eType==JSON_ARRAY ){
+-    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
+-    for(i=1; i<=pNode->n; n++){
+-      i += jsonNodeSize(&pNode[i]);
+-    }
+-  }
+-  sqlite3_result_int64(ctx, n);
+-}
+-
+-/*
+-** json_extract(JSON, PATH, ...)
+-**
+-** Return the element described by PATH.  Return NULL if there is no
+-** PATH element.  If there are multiple PATHs, then return a JSON array
+-** with the result from each path.  Throw an error if the JSON or any PATH
+-** is malformed.
+-*/
+-static void jsonExtractFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse *p;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  JsonString jx;
+-  int i;
+-
+-  if( argc<2 ) return;
+-  p = jsonParseCached(ctx, argv);
+-  if( p==0 ) return;
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '[');
+-  for(i=1; i<argc; i++){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    pNode = jsonLookup(p, zPath, 0, ctx);
+-    if( p->nErr ) break;
+-    if( argc>2 ){
+-      jsonAppendSeparator(&jx);
+-      if( pNode ){
+-        jsonRenderNode(pNode, &jx, 0);
+-      }else{
+-        jsonAppendRaw(&jx, "null", 4);
++  if( rc==SQLITE_OK ){
++    if( xOutput ){
++      if( sOut.nBuf>0 ){
++        rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+       }
+-    }else if( pNode ){
+-      jsonReturn(pNode, ctx, 0);
++    }else{
++      *ppOut = (void*)sOut.aBuf;
++      *pnOut = sOut.nBuf;
++      sOut.aBuf = 0;
+     }
+   }
+-  if( argc>2 && i==argc ){
+-    jsonAppendChar(&jx, ']');
+-    jsonResult(&jx);
+-    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-  }
+-  jsonReset(&jx);
++  sqlite3_free(sOut.aBuf);
++  return rc;
+ }
+ 
+-/* This is the RFC 7396 MergePatch algorithm.
++/* 
++** Create a new rebaser object.
+ */
+-static JsonNode *jsonMergePatch(
+-  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
+-  u32 iTarget,         /* Node of the TARGET in pParse */
+-  JsonNode *pPatch     /* The PATCH */
+-){
+-  u32 i, j;
+-  u32 iRoot;
+-  JsonNode *pTarget;
+-  if( pPatch->eType!=JSON_OBJECT ){
+-    return pPatch;
+-  }
+-  assert( iTarget>=0 && iTarget<pParse->nNode );
+-  pTarget = &pParse->aNode[iTarget];
+-  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
+-  if( pTarget->eType!=JSON_OBJECT ){
+-    jsonRemoveAllNulls(pPatch);
+-    return pPatch;
+-  }
+-  iRoot = iTarget;
+-  for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
+-    u32 nKey;
+-    const char *zKey;
+-    assert( pPatch[i].eType==JSON_STRING );
+-    assert( pPatch[i].jnFlags & JNODE_LABEL );
+-    nKey = pPatch[i].n;
+-    zKey = pPatch[i].u.zJContent;
+-    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+-    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
+-      assert( pTarget[j].eType==JSON_STRING );
+-      assert( pTarget[j].jnFlags & JNODE_LABEL );
+-      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+-      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+-        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
+-        if( pPatch[i+1].eType==JSON_NULL ){
+-          pTarget[j+1].jnFlags |= JNODE_REMOVE;
+-        }else{
+-          JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
+-          if( pNew==0 ) return 0;
+-          pTarget = &pParse->aNode[iTarget];
+-          if( pNew!=&pTarget[j+1] ){
+-            pTarget[j+1].u.pPatch = pNew;
+-            pTarget[j+1].jnFlags |= JNODE_PATCH;
+-          }
+-        }
+-        break;
+-      }
+-    }
+-    if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
+-      int iStart, iPatch;
+-      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+-      jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+-      iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+-      if( pParse->oom ) return 0;
+-      jsonRemoveAllNulls(pPatch);
+-      pTarget = &pParse->aNode[iTarget];
+-      pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
+-      pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
+-      iRoot = iStart;
+-      pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
+-      pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
+-    }
+-  }
+-  return pTarget;
+-}
++SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
++  int rc = SQLITE_OK;
++  sqlite3_rebaser *pNew;
+ 
+-/*
+-** 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);
++  pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
++  if( pNew==0 ){
++    rc = SQLITE_NOMEM;
+   }else{
+-    sqlite3_result_error_nomem(ctx);
++    memset(pNew, 0, sizeof(sqlite3_rebaser));
+   }
+-  jsonParseReset(&x);
+-  jsonParseReset(&y);
++  *ppNew = pNew;
++  return rc;
+ }
+ 
+-
+-/*
+-** 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.
++/* 
++** Call this one or more times to configure a rebaser.
+ */
+-static void jsonObjectFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
++SQLITE_API int sqlite3rebaser_configure(
++  sqlite3_rebaser *p, 
++  int nRebase, const void *pRebase
+ ){
+-  int i;
+-  JsonString jx;
+-  const char *z;
+-  u32 n;
+-
+-  if( argc&1 ){
+-    sqlite3_result_error(ctx, "json_object() requires an even number "
+-                                  "of arguments", -1);
+-    return;
++  sqlite3_changeset_iter *pIter = 0;   /* Iterator opened on pData/nData */
++  int rc;                              /* Return code */
++  rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
++  if( rc==SQLITE_OK ){
++    rc = sessionChangesetToHash(pIter, &p->grp, 1);
+   }
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '{');
+-  for(i=0; i<argc; i+=2){
+-    if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
+-      sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
+-      jsonReset(&jx);
+-      return;
+-    }
+-    jsonAppendSeparator(&jx);
+-    z = (const char*)sqlite3_value_text(argv[i]);
+-    n = (u32)sqlite3_value_bytes(argv[i]);
+-    jsonAppendString(&jx, z, n);
+-    jsonAppendChar(&jx, ':');
+-    jsonAppendValue(&jx, argv[i+1]);
+-  }
+-  jsonAppendChar(&jx, '}');
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++  sqlite3changeset_finalize(pIter);
++  return rc;
+ }
+ 
+-
+-/*
+-** json_remove(JSON, PATH, ...)
+-**
+-** Remove the named elements from JSON and return the result.  malformed
+-** JSON or PATH arguments result in an error.
++/* 
++** Rebase a changeset according to current rebaser configuration 
+ */
+-static void jsonRemoveFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
++SQLITE_API int sqlite3rebaser_rebase(
++  sqlite3_rebaser *p,
++  int nIn, const void *pIn, 
++  int *pnOut, void **ppOut 
+ ){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
++  sqlite3_changeset_iter *pIter = 0;   /* Iterator to skip through input */  
++  int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
+ 
+-  if( argc<1 ) return;
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i++){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    if( zPath==0 ) goto remove_done;
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-    if( x.nErr ) goto remove_done;
+-    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
++  if( rc==SQLITE_OK ){
++    rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
++    sqlite3changeset_finalize(pIter);
+   }
+-  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
+-    jsonReturnJson(x.aNode, ctx, 0);
+-  }
+-remove_done:
+-  jsonParseReset(&x);
+-}
+ 
+-/*
+-** json_replace(JSON, PATH, VALUE, ...)
+-**
+-** Replace the value at PATH with VALUE.  If PATH does not already exist,
+-** this routine is a no-op.  If JSON or PATH is malformed, throw an error.
+-*/
+-static void jsonReplaceFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
+-
+-  if( argc<1 ) return;
+-  if( (argc&1)==0 ) {
+-    jsonWrongNumArgs(ctx, "replace");
+-    return;
+-  }
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i+=2){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-    if( x.nErr ) goto replace_err;
+-    if( pNode ){
+-      pNode->jnFlags |= (u8)JNODE_REPLACE;
+-      pNode->u.iReplace = i + 1;
+-    }
+-  }
+-  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+-    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+-  }else{
+-    jsonReturnJson(x.aNode, ctx, argv);
+-  }
+-replace_err:
+-  jsonParseReset(&x);
++  return rc;
+ }
+ 
+-/*
+-** json_set(JSON, PATH, VALUE, ...)
+-**
+-** Set the value at PATH to VALUE.  Create the PATH if it does not already
+-** exist.  Overwrite existing values that do exist.
+-** If JSON or PATH is malformed, throw an error.
+-**
+-** json_insert(JSON, PATH, VALUE, ...)
+-**
+-** Create PATH and initialize it to VALUE.  If PATH already exists, this
+-** routine is a no-op.  If JSON or PATH is malformed, throw an error.
++/* 
++** Rebase a changeset according to current rebaser configuration 
+ */
+-static void jsonSetFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
++SQLITE_API int sqlite3rebaser_rebase_strm(
++  sqlite3_rebaser *p,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
+ ){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
+-  int bApnd;
+-  int bIsSet = *(int*)sqlite3_user_data(ctx);
++  sqlite3_changeset_iter *pIter = 0;   /* Iterator to skip through input */  
++  int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+ 
+-  if( argc<1 ) return;
+-  if( (argc&1)==0 ) {
+-    jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
+-    return;
+-  }
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i+=2){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    bApnd = 0;
+-    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
+-    if( x.oom ){
+-      sqlite3_result_error_nomem(ctx);
+-      goto jsonSetDone;
+-    }else if( x.nErr ){
+-      goto jsonSetDone;
+-    }else if( pNode && (bApnd || bIsSet) ){
+-      pNode->jnFlags |= (u8)JNODE_REPLACE;
+-      pNode->u.iReplace = i + 1;
+-    }
+-  }
+-  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+-    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+-  }else{
+-    jsonReturnJson(x.aNode, ctx, argv);
+-  }
+-jsonSetDone:
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_type(JSON)
+-** json_type(JSON, PATH)
+-**
+-** Return the top-level "type" of a JSON string.  Throw an error if
+-** either the JSON or PATH inputs are not well-formed.
+-*/
+-static void jsonTypeFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  const char *zPath;
+-  JsonNode *pNode;
+-
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  if( argc==2 ){
+-    zPath = (const char*)sqlite3_value_text(argv[1]);
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-  }else{
+-    pNode = x.aNode;
+-  }
+-  if( pNode ){
+-    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
+-  }
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_valid(JSON)
+-**
+-** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
+-** Return 0 otherwise.
+-*/
+-static void jsonValidFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  int rc = 0;
+-
+-  UNUSED_PARAM(argc);
+-  if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
+-    rc = 1;
+-  }
+-  jsonParseReset(&x);
+-  sqlite3_result_int(ctx, rc);
+-}
+-
+-
+-/****************************************************************************
+-** Aggregate SQL function implementations
+-****************************************************************************/
+-/*
+-** json_group_array(VALUE)
+-**
+-** Return a JSON array composed of all values in the aggregate.
+-*/
+-static void jsonArrayStep(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString *pStr;
+-  UNUSED_PARAM(argc);
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+-  if( pStr ){
+-    if( pStr->zBuf==0 ){
+-      jsonInit(pStr, ctx);
+-      jsonAppendChar(pStr, '[');
+-    }else{
+-      jsonAppendChar(pStr, ',');
+-      pStr->pCtx = ctx;
+-    }
+-    jsonAppendValue(pStr, argv[0]);
+-  }
+-}
+-static void jsonArrayFinal(sqlite3_context *ctx){
+-  JsonString *pStr;
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+-  if( pStr ){
+-    pStr->pCtx = ctx;
+-    jsonAppendChar(pStr, ']');
+-    if( pStr->bErr ){
+-      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+-      assert( pStr->bStatic );
+-    }else{
+-      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+-                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+-      pStr->bStatic = 1;
+-    }
+-  }else{
+-    sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+-  }
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** json_group_obj(NAME,VALUE)
+-**
+-** Return a JSON object composed of all names and values in the aggregate.
+-*/
+-static void jsonObjectStep(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString *pStr;
+-  const char *z;
+-  u32 n;
+-  UNUSED_PARAM(argc);
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+-  if( pStr ){
+-    if( pStr->zBuf==0 ){
+-      jsonInit(pStr, ctx);
+-      jsonAppendChar(pStr, '{');
+-    }else{
+-      jsonAppendChar(pStr, ',');
+-      pStr->pCtx = ctx;
+-    }
+-    z = (const char*)sqlite3_value_text(argv[0]);
+-    n = (u32)sqlite3_value_bytes(argv[0]);
+-    jsonAppendString(pStr, z, n);
+-    jsonAppendChar(pStr, ':');
+-    jsonAppendValue(pStr, argv[1]);
+-  }
+-}
+-static void jsonObjectFinal(sqlite3_context *ctx){
+-  JsonString *pStr;
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+-  if( pStr ){
+-    jsonAppendChar(pStr, '}');
+-    if( pStr->bErr ){
+-      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+-      assert( pStr->bStatic );
+-    }else{
+-      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+-                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+-      pStr->bStatic = 1;
+-    }
+-  }else{
+-    sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
+-  }
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-/****************************************************************************
+-** The json_each virtual table
+-****************************************************************************/
+-typedef struct JsonEachCursor JsonEachCursor;
+-struct JsonEachCursor {
+-  sqlite3_vtab_cursor base;  /* Base class - must be first */
+-  u32 iRowid;                /* The rowid */
+-  u32 iBegin;                /* The first node of the scan */
+-  u32 i;                     /* Index in sParse.aNode[] of current row */
+-  u32 iEnd;                  /* EOF when i equals or exceeds this value */
+-  u8 eType;                  /* Type of top-level element */
+-  u8 bRecursive;             /* True for json_tree().  False for json_each() */
+-  char *zJson;               /* Input JSON */
+-  char *zRoot;               /* Path by which to filter zJson */
+-  JsonParse sParse;          /* Parse of the input JSON */
+-};
+-
+-/* Constructor for the json_each virtual table */
+-static int jsonEachConnect(
+-  sqlite3 *db,
+-  void *pAux,
+-  int argc, const char *const*argv,
+-  sqlite3_vtab **ppVtab,
+-  char **pzErr
+-){
+-  sqlite3_vtab *pNew;
+-  int rc;
+-
+-/* Column numbers */
+-#define JEACH_KEY     0
+-#define JEACH_VALUE   1
+-#define JEACH_TYPE    2
+-#define JEACH_ATOM    3
+-#define JEACH_ID      4
+-#define JEACH_PARENT  5
+-#define JEACH_FULLKEY 6
+-#define JEACH_PATH    7
+-#define JEACH_JSON    8
+-#define JEACH_ROOT    9
+-
+-  UNUSED_PARAM(pzErr);
+-  UNUSED_PARAM(argv);
+-  UNUSED_PARAM(argc);
+-  UNUSED_PARAM(pAux);
+-  rc = sqlite3_declare_vtab(db, 
+-     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
+-                    "json HIDDEN,root HIDDEN)");
+   if( rc==SQLITE_OK ){
+-    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+-    if( pNew==0 ) return SQLITE_NOMEM;
+-    memset(pNew, 0, sizeof(*pNew));
++    rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
++    sqlite3changeset_finalize(pIter);
+   }
+-  return rc;
+-}
+ 
+-/* destructor for json_each virtual table */
+-static int jsonEachDisconnect(sqlite3_vtab *pVtab){
+-  sqlite3_free(pVtab);
+-  return SQLITE_OK;
+-}
+-
+-/* constructor for a JsonEachCursor object for json_each(). */
+-static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+-  JsonEachCursor *pCur;
+-
+-  UNUSED_PARAM(p);
+-  pCur = sqlite3_malloc( sizeof(*pCur) );
+-  if( pCur==0 ) return SQLITE_NOMEM;
+-  memset(pCur, 0, sizeof(*pCur));
+-  *ppCursor = &pCur->base;
+-  return SQLITE_OK;
+-}
+-
+-/* constructor for a JsonEachCursor object for json_tree(). */
+-static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+-  int rc = jsonEachOpenEach(p, ppCursor);
+-  if( rc==SQLITE_OK ){
+-    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
+-    pCur->bRecursive = 1;
+-  }
+   return rc;
+ }
+ 
+-/* Reset a JsonEachCursor back to its original state.  Free any memory
+-** held. */
+-static void jsonEachCursorReset(JsonEachCursor *p){
+-  sqlite3_free(p->zJson);
+-  sqlite3_free(p->zRoot);
+-  jsonParseReset(&p->sParse);
+-  p->iRowid = 0;
+-  p->i = 0;
+-  p->iEnd = 0;
+-  p->eType = 0;
+-  p->zJson = 0;
+-  p->zRoot = 0;
+-}
+-
+-/* Destructor for a jsonEachCursor object */
+-static int jsonEachClose(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  jsonEachCursorReset(p);
+-  sqlite3_free(cur);
+-  return SQLITE_OK;
+-}
+-
+-/* Return TRUE if the jsonEachCursor object has been advanced off the end
+-** of the JSON object */
+-static int jsonEachEof(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  return p->i >= p->iEnd;
+-}
+-
+-/* Advance the cursor to the next element for json_tree() */
+-static int jsonEachNext(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  if( p->bRecursive ){
+-    if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
+-    p->i++;
+-    p->iRowid++;
+-    if( p->i<p->iEnd ){
+-      u32 iUp = p->sParse.aUp[p->i];
+-      JsonNode *pUp = &p->sParse.aNode[iUp];
+-      p->eType = pUp->eType;
+-      if( pUp->eType==JSON_ARRAY ){
+-        if( iUp==p->i-1 ){
+-          pUp->u.iKey = 0;
+-        }else{
+-          pUp->u.iKey++;
+-        }
+-      }
+-    }
+-  }else{
+-    switch( p->eType ){
+-      case JSON_ARRAY: {
+-        p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
+-        p->iRowid++;
+-        break;
+-      }
+-      case JSON_OBJECT: {
+-        p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
+-        p->iRowid++;
+-        break;
+-      }
+-      default: {
+-        p->i = p->iEnd;
+-        break;
+-      }
+-    }
++/* 
++** Destroy a rebaser object 
++*/
++SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){
++  if( p ){
++    sessionDeleteTable(p->grp.pList);
++    sqlite3_free(p);
+   }
+-  return SQLITE_OK;
+ }
+ 
+-/* Append the name of the path for element i to pStr
++/* 
++** Global configuration
+ */
+-static void jsonEachComputePath(
+-  JsonEachCursor *p,       /* The cursor */
+-  JsonString *pStr,        /* Write the path here */
+-  u32 i                    /* Path to this element */
+-){
+-  JsonNode *pNode, *pUp;
+-  u32 iUp;
+-  if( i==0 ){
+-    jsonAppendChar(pStr, '$');
+-    return;
+-  }
+-  iUp = p->sParse.aUp[i];
+-  jsonEachComputePath(p, pStr, iUp);
+-  pNode = &p->sParse.aNode[i];
+-  pUp = &p->sParse.aNode[iUp];
+-  if( pUp->eType==JSON_ARRAY ){
+-    jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
+-  }else{
+-    assert( pUp->eType==JSON_OBJECT );
+-    if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
+-    assert( pNode->eType==JSON_STRING );
+-    assert( pNode->jnFlags & JNODE_LABEL );
+-    jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
+-  }
+-}
+-
+-/* Return the value of a column */
+-static int jsonEachColumn(
+-  sqlite3_vtab_cursor *cur,   /* The cursor */
+-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
+-  int i                       /* Which column to return */
+-){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  JsonNode *pThis = &p->sParse.aNode[p->i];
+-  switch( i ){
+-    case JEACH_KEY: {
+-      if( p->i==0 ) break;
+-      if( p->eType==JSON_OBJECT ){
+-        jsonReturn(pThis, ctx, 0);
+-      }else if( p->eType==JSON_ARRAY ){
+-        u32 iKey;
+-        if( p->bRecursive ){
+-          if( p->iRowid==0 ) break;
+-          iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
+-        }else{
+-          iKey = p->iRowid;
+-        }
+-        sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
++SQLITE_API int sqlite3session_config(int op, void *pArg){
++  int rc = SQLITE_OK;
++  switch( op ){
++    case SQLITE_SESSION_CONFIG_STRMSIZE: {
++      int *pInt = (int*)pArg;
++      if( *pInt>0 ){
++        sessions_strm_chunk_size = *pInt;
+       }
++      *pInt = sessions_strm_chunk_size;
+       break;
+     }
+-    case JEACH_VALUE: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      jsonReturn(pThis, ctx, 0);
++    default:
++      rc = SQLITE_MISUSE;
+       break;
+-    }
+-    case JEACH_TYPE: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
+-      break;
+-    }
+-    case JEACH_ATOM: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      if( pThis->eType>=JSON_ARRAY ) break;
+-      jsonReturn(pThis, ctx, 0);
+-      break;
+-    }
+-    case JEACH_ID: {
+-      sqlite3_result_int64(ctx, 
+-         (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
+-      break;
+-    }
+-    case JEACH_PARENT: {
+-      if( p->i>p->iBegin && p->bRecursive ){
+-        sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
+-      }
+-      break;
+-    }
+-    case JEACH_FULLKEY: {
+-      JsonString x;
+-      jsonInit(&x, ctx);
+-      if( p->bRecursive ){
+-        jsonEachComputePath(p, &x, p->i);
+-      }else{
+-        if( p->zRoot ){
+-          jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
+-        }else{
+-          jsonAppendChar(&x, '$');
+-        }
+-        if( p->eType==JSON_ARRAY ){
+-          jsonPrintf(30, &x, "[%d]", p->iRowid);
+-        }else{
+-          jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
+-        }
+-      }
+-      jsonResult(&x);
+-      break;
+-    }
+-    case JEACH_PATH: {
+-      if( p->bRecursive ){
+-        JsonString x;
+-        jsonInit(&x, ctx);
+-        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
+-        jsonResult(&x);
+-        break;
+-      }
+-      /* For json_each() path and root are the same so fall through
+-      ** into the root case */
+-    }
+-    default: {
+-      const char *zRoot = p->zRoot;
+-      if( zRoot==0 ) zRoot = "$";
+-      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
+-      break;
+-    }
+-    case JEACH_JSON: {
+-      assert( i==JEACH_JSON );
+-      sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
+-      break;
+-    }
+   }
+-  return SQLITE_OK;
+-}
+-
+-/* Return the current rowid value */
+-static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  *pRowid = p->iRowid;
+-  return SQLITE_OK;
+-}
+-
+-/* The query strategy is to look for an equality constraint on the json
+-** column.  Without such a constraint, the table cannot operate.  idxNum is
+-** 1 if the constraint is found, 3 if the constraint and zRoot are found,
+-** and 0 otherwise.
+-*/
+-static int jsonEachBestIndex(
+-  sqlite3_vtab *tab,
+-  sqlite3_index_info *pIdxInfo
+-){
+-  int i;
+-  int jsonIdx = -1;
+-  int rootIdx = -1;
+-  const struct sqlite3_index_constraint *pConstraint;
+-
+-  UNUSED_PARAM(tab);
+-  pConstraint = pIdxInfo->aConstraint;
+-  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+-    if( pConstraint->usable==0 ) continue;
+-    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+-    switch( pConstraint->iColumn ){
+-      case JEACH_JSON:   jsonIdx = i;    break;
+-      case JEACH_ROOT:   rootIdx = i;    break;
+-      default:           /* no-op */     break;
+-    }
+-  }
+-  if( jsonIdx<0 ){
+-    pIdxInfo->idxNum = 0;
+-    pIdxInfo->estimatedCost = 1e99;
+-  }else{
+-    pIdxInfo->estimatedCost = 1.0;
+-    pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
+-    pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
+-    if( rootIdx<0 ){
+-      pIdxInfo->idxNum = 1;
+-    }else{
+-      pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
+-      pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
+-      pIdxInfo->idxNum = 3;
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* Start a search on a new JSON string */
+-static int jsonEachFilter(
+-  sqlite3_vtab_cursor *cur,
+-  int idxNum, const char *idxStr,
+-  int argc, sqlite3_value **argv
+-){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  const char *z;
+-  const char *zRoot = 0;
+-  sqlite3_int64 n;
+-
+-  UNUSED_PARAM(idxStr);
+-  UNUSED_PARAM(argc);
+-  jsonEachCursorReset(p);
+-  if( idxNum==0 ) return SQLITE_OK;
+-  z = (const char*)sqlite3_value_text(argv[0]);
+-  if( z==0 ) return SQLITE_OK;
+-  n = sqlite3_value_bytes(argv[0]);
+-  p->zJson = sqlite3_malloc64( n+1 );
+-  if( p->zJson==0 ) return SQLITE_NOMEM;
+-  memcpy(p->zJson, z, (size_t)n+1);
+-  if( jsonParse(&p->sParse, 0, p->zJson) ){
+-    int rc = SQLITE_NOMEM;
+-    if( p->sParse.oom==0 ){
+-      sqlite3_free(cur->pVtab->zErrMsg);
+-      cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
+-      if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
+-    }
+-    jsonEachCursorReset(p);
+-    return rc;
+-  }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
+-    jsonEachCursorReset(p);
+-    return SQLITE_NOMEM;
+-  }else{
+-    JsonNode *pNode = 0;
+-    if( idxNum==3 ){
+-      const char *zErr = 0;
+-      zRoot = (const char*)sqlite3_value_text(argv[1]);
+-      if( zRoot==0 ) return SQLITE_OK;
+-      n = sqlite3_value_bytes(argv[1]);
+-      p->zRoot = sqlite3_malloc64( n+1 );
+-      if( p->zRoot==0 ) return SQLITE_NOMEM;
+-      memcpy(p->zRoot, zRoot, (size_t)n+1);
+-      if( zRoot[0]!='$' ){
+-        zErr = zRoot;
+-      }else{
+-        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
+-      }
+-      if( zErr ){
+-        sqlite3_free(cur->pVtab->zErrMsg);
+-        cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
+-        jsonEachCursorReset(p);
+-        return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+-      }else if( pNode==0 ){
+-        return SQLITE_OK;
+-      }
+-    }else{
+-      pNode = p->sParse.aNode;
+-    }
+-    p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
+-    p->eType = pNode->eType;
+-    if( p->eType>=JSON_ARRAY ){
+-      pNode->u.iKey = 0;
+-      p->iEnd = p->i + pNode->n + 1;
+-      if( p->bRecursive ){
+-        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
+-        if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
+-          p->i--;
+-        }
+-      }else{
+-        p->i++;
+-      }
+-    }else{
+-      p->iEnd = p->i+1;
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* The methods of the json_each virtual table */
+-static sqlite3_module jsonEachModule = {
+-  0,                         /* iVersion */
+-  0,                         /* xCreate */
+-  jsonEachConnect,           /* xConnect */
+-  jsonEachBestIndex,         /* xBestIndex */
+-  jsonEachDisconnect,        /* xDisconnect */
+-  0,                         /* xDestroy */
+-  jsonEachOpenEach,          /* xOpen - open a cursor */
+-  jsonEachClose,             /* xClose - close a cursor */
+-  jsonEachFilter,            /* xFilter - configure scan constraints */
+-  jsonEachNext,              /* xNext - advance a cursor */
+-  jsonEachEof,               /* xEof - check for end of scan */
+-  jsonEachColumn,            /* xColumn - read data */
+-  jsonEachRowid,             /* xRowid - read data */
+-  0,                         /* xUpdate */
+-  0,                         /* xBegin */
+-  0,                         /* xSync */
+-  0,                         /* xCommit */
+-  0,                         /* xRollback */
+-  0,                         /* xFindMethod */
+-  0,                         /* xRename */
+-  0,                         /* xSavepoint */
+-  0,                         /* xRelease */
+-  0                          /* xRollbackTo */
+-};
+-
+-/* The methods of the json_tree virtual table. */
+-static sqlite3_module jsonTreeModule = {
+-  0,                         /* iVersion */
+-  0,                         /* xCreate */
+-  jsonEachConnect,           /* xConnect */
+-  jsonEachBestIndex,         /* xBestIndex */
+-  jsonEachDisconnect,        /* xDisconnect */
+-  0,                         /* xDestroy */
+-  jsonEachOpenTree,          /* xOpen - open a cursor */
+-  jsonEachClose,             /* xClose - close a cursor */
+-  jsonEachFilter,            /* xFilter - configure scan constraints */
+-  jsonEachNext,              /* xNext - advance a cursor */
+-  jsonEachEof,               /* xEof - check for end of scan */
+-  jsonEachColumn,            /* xColumn - read data */
+-  jsonEachRowid,             /* xRowid - read data */
+-  0,                         /* xUpdate */
+-  0,                         /* xBegin */
+-  0,                         /* xSync */
+-  0,                         /* xCommit */
+-  0,                         /* xRollback */
+-  0,                         /* xFindMethod */
+-  0,                         /* xRename */
+-  0,                         /* xSavepoint */
+-  0,                         /* xRelease */
+-  0                          /* xRollbackTo */
+-};
+-#endif /* SQLITE_OMIT_VIRTUALTABLE */
+-
+-/****************************************************************************
+-** The following routines are the only publically visible identifiers in this
+-** file.  Call the following routines in order to register the various SQL
+-** functions and the virtual table implemented by this file.
+-****************************************************************************/
+-
+-SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
+-  int rc = SQLITE_OK;
+-  unsigned int i;
+-  static const struct {
+-     const char *zName;
+-     int nArg;
+-     int flag;
+-     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+-  } aFunc[] = {
+-    { "json",                 1, 0,   jsonRemoveFunc        },
+-    { "json_array",          -1, 0,   jsonArrayFunc         },
+-    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
+-    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
+-    { "json_extract",        -1, 0,   jsonExtractFunc       },
+-    { "json_insert",         -1, 0,   jsonSetFunc           },
+-    { "json_object",         -1, 0,   jsonObjectFunc        },
+-    { "json_patch",           2, 0,   jsonPatchFunc         },
+-    { "json_quote",           1, 0,   jsonQuoteFunc         },
+-    { "json_remove",         -1, 0,   jsonRemoveFunc        },
+-    { "json_replace",        -1, 0,   jsonReplaceFunc       },
+-    { "json_set",            -1, 1,   jsonSetFunc           },
+-    { "json_type",            1, 0,   jsonTypeFunc          },
+-    { "json_type",            2, 0,   jsonTypeFunc          },
+-    { "json_valid",           1, 0,   jsonValidFunc         },
+-
+-#if SQLITE_DEBUG
+-    /* DEBUG and TESTING functions */
+-    { "json_parse",           1, 0,   jsonParseFunc         },
+-    { "json_test1",           1, 0,   jsonTest1Func         },
+-#endif
+-  };
+-  static const struct {
+-     const char *zName;
+-     int nArg;
+-     void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+-     void (*xFinal)(sqlite3_context*);
+-  } aAgg[] = {
+-    { "json_group_array",     1,   jsonArrayStep,   jsonArrayFinal  },
+-    { "json_group_object",    2,   jsonObjectStep,  jsonObjectFinal },
+-  };
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  static const struct {
+-     const char *zName;
+-     sqlite3_module *pModule;
+-  } aMod[] = {
+-    { "json_each",            &jsonEachModule               },
+-    { "json_tree",            &jsonTreeModule               },
+-  };
+-#endif
+-  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
+-                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
+-                                 (void*)&aFunc[i].flag,
+-                                 aFunc[i].xFunc, 0, 0);
+-  }
+-  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
+-                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+-                                 0, aAgg[i].xStep, aAgg[i].xFinal);
+-  }
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+-  }
+-#endif
+   return rc;
+ }
+ 
++#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+ 
+-#ifndef SQLITE_CORE
+-#ifdef _WIN32
+-__declspec(dllexport)
+-#endif
+-SQLITE_API int sqlite3_json_init(
+-  sqlite3 *db, 
+-  char **pzErrMsg, 
+-  const sqlite3_api_routines *pApi
+-){
+-  SQLITE_EXTENSION_INIT2(pApi);
+-  (void)pzErrMsg;  /* Unused parameter */
+-  return sqlite3Json1Init(db);
+-}
+-#endif
+-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
+-
+-/************** End of json1.c ***********************************************/
++/************** End of sqlite3session.c **************************************/
+ /************** Begin file fts5.c ********************************************/
+ 
+ 
+@@ -183491,7 +198794,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -183519,7 +198822,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+@@ -184349,6 +199652,8 @@
+   int bPrefix
+ );
+ 
++static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
++
+ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
+   Fts5Parse*, 
+   Fts5ExprNearset*,
+@@ -184409,9 +199714,12 @@
+ /**************************************************************************
+ ** Interface to automatically generated code in fts5_unicode2.c. 
+ */
+-static int sqlite3Fts5UnicodeIsalnum(int c);
+ static int sqlite3Fts5UnicodeIsdiacritic(int c);
+ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
++
++static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
++static int sqlite3Fts5UnicodeCategory(int iCode);
++static void sqlite3Fts5UnicodeAscii(u8*, u8*);
+ /*
+ ** End of interface to code in fts5_unicode2.c.
+ **************************************************************************/
+@@ -184429,9 +199737,10 @@
+ #define FTS5_STRING                           9
+ #define FTS5_LP                              10
+ #define FTS5_RP                              11
+-#define FTS5_COMMA                           12
+-#define FTS5_PLUS                            13
+-#define FTS5_STAR                            14
++#define FTS5_CARET                           12
++#define FTS5_COMMA                           13
++#define FTS5_PLUS                            14
++#define FTS5_STAR                            15
+ 
+ /*
+ ** 2000-05-29
+@@ -184458,6 +199767,7 @@
+ ** input grammar file:
+ */
+ /* #include <stdio.h> */
++/* #include <assert.h> */
+ /************ Begin %include sections from the grammar ************************/
+ 
+ /* #include "fts5Int.h" */
+@@ -184526,19 +199836,23 @@
+ **                       zero the stack is dynamically sized using realloc()
+ **    sqlite3Fts5ParserARG_SDECL     A static variable declaration for the %extra_argument
+ **    sqlite3Fts5ParserARG_PDECL     A parameter declaration for the %extra_argument
++**    sqlite3Fts5ParserARG_PARAM     Code to pass %extra_argument as a subroutine parameter
+ **    sqlite3Fts5ParserARG_STORE     Code to store %extra_argument into fts5yypParser
+ **    sqlite3Fts5ParserARG_FETCH     Code to extract %extra_argument from fts5yypParser
++**    sqlite3Fts5ParserCTX_*         As sqlite3Fts5ParserARG_ except for %extra_context
+ **    fts5YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
+ **    fts5YYNSTATE           the combined number of states.
+ **    fts5YYNRULE            the number of rules in the grammar
++**    fts5YYNFTS5TOKEN           Number of terminal symbols
+ **    fts5YY_MAX_SHIFT       Maximum value for shift actions
+ **    fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
+ **    fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
+-**    fts5YY_MIN_REDUCE      Maximum value for reduce actions
+ **    fts5YY_ERROR_ACTION    The fts5yy_action[] code for syntax error
+ **    fts5YY_ACCEPT_ACTION   The fts5yy_action[] code for accept
+ **    fts5YY_NO_ACTION       The fts5yy_action[] code for no-op
++**    fts5YY_MIN_REDUCE      Minimum value for reduce actions
++**    fts5YY_MAX_REDUCE      Maximum value for reduce actions
+ */
+ #ifndef INTERFACE
+ # define INTERFACE 1
+@@ -184545,7 +199859,7 @@
+ #endif
+ /************* Begin control #defines *****************************************/
+ #define fts5YYCODETYPE unsigned char
+-#define fts5YYNOCODE 28
++#define fts5YYNOCODE 27
+ #define fts5YYACTIONTYPE unsigned char
+ #define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
+ typedef union {
+@@ -184562,19 +199876,27 @@
+ #endif
+ #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
+ #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
+-#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
+-#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
+-#define fts5YYNSTATE             33
+-#define fts5YYNRULE              27
+-#define fts5YY_MAX_SHIFT         32
+-#define fts5YY_MIN_SHIFTREDUCE   50
+-#define fts5YY_MAX_SHIFTREDUCE   76
+-#define fts5YY_MIN_REDUCE        77
+-#define fts5YY_MAX_REDUCE        103
+-#define fts5YY_ERROR_ACTION      104
+-#define fts5YY_ACCEPT_ACTION     105
+-#define fts5YY_NO_ACTION         106
++#define sqlite3Fts5ParserARG_PARAM ,pParse
++#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
++#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
++#define sqlite3Fts5ParserCTX_SDECL
++#define sqlite3Fts5ParserCTX_PDECL
++#define sqlite3Fts5ParserCTX_PARAM
++#define sqlite3Fts5ParserCTX_FETCH
++#define sqlite3Fts5ParserCTX_STORE
++#define fts5YYNSTATE             35
++#define fts5YYNRULE              28
++#define fts5YYNFTS5TOKEN             16
++#define fts5YY_MAX_SHIFT         34
++#define fts5YY_MIN_SHIFTREDUCE   52
++#define fts5YY_MAX_SHIFTREDUCE   79
++#define fts5YY_ERROR_ACTION      80
++#define fts5YY_ACCEPT_ACTION     81
++#define fts5YY_NO_ACTION         82
++#define fts5YY_MIN_REDUCE        83
++#define fts5YY_MAX_REDUCE        110
+ /************* End control #defines *******************************************/
++#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
+ 
+ /* Define the fts5yytestcase() macro to be a no-op if is not already defined
+ ** otherwise.
+@@ -184603,9 +199925,6 @@
+ **   N between fts5YY_MIN_SHIFTREDUCE       Shift to an arbitrary state then
+ **     and fts5YY_MAX_SHIFTREDUCE           reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
+ **
+-**   N between fts5YY_MIN_REDUCE            Reduce by rule N-fts5YY_MIN_REDUCE
+-**     and fts5YY_MAX_REDUCE
+-**
+ **   N == fts5YY_ERROR_ACTION               A syntax error has occurred.
+ **
+ **   N == fts5YY_ACCEPT_ACTION              The parser accepts its input.
+@@ -184613,6 +199932,9 @@
+ **   N == fts5YY_NO_ACTION                  No such action.  Denotes unused
+ **                                      slots in the fts5yy_action[] table.
+ **
++**   N between fts5YY_MIN_REDUCE            Reduce by rule N-fts5YY_MIN_REDUCE
++**     and fts5YY_MAX_REDUCE
++**
+ ** The action table is constructed as a single large table named fts5yy_action[].
+ ** Given state S and lookahead X, the action is computed as either:
+ **
+@@ -184619,19 +199941,13 @@
+ **    (A)   N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
+ **    (B)   N = fts5yy_default[S]
+ **
+-** The (A) formula is preferred.  The B formula is used instead if:
+-**    (1)  The fts5yy_shift_ofst[S]+X value is out of range, or
+-**    (2)  fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or
+-**    (3)  fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT.
+-** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that
+-** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
+-** Hence only tests (1) and (2) need to be evaluated.)
++** The (A) formula is preferred.  The B formula is used instead if
++** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
+ **
+ ** The formulas above are for computing the action when the lookahead is
+ ** a terminal symbol.  If the lookahead is a non-terminal (as occurs after
+ ** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
+-** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
+-** fts5YY_SHIFT_USE_DFLT.
++** the fts5yy_shift_ofst[] array.
+ **
+ ** The following are the tables generated in this section:
+ **
+@@ -184645,54 +199961,56 @@
+ **  fts5yy_default[]       Default action for each state.
+ **
+ *********** Begin parsing tables **********************************************/
+-#define fts5YY_ACTTAB_COUNT (98)
++#define fts5YY_ACTTAB_COUNT (105)
+ static const fts5YYACTIONTYPE fts5yy_action[] = {
+- /*     0 */   105,   19,   90,    6,   26,   93,   92,   24,   24,   17,
+- /*    10 */    90,    6,   26,   16,   92,   54,   24,   18,   90,    6,
+- /*    20 */    26,   10,   92,   12,   24,   75,   86,   90,    6,   26,
+- /*    30 */    13,   92,   75,   24,   20,   90,    6,   26,  101,   92,
+- /*    40 */    56,   24,   27,   90,    6,   26,  100,   92,   21,   24,
+- /*    50 */    23,   15,   30,   11,    1,   91,   22,   25,    9,   92,
+- /*    60 */     7,   24,    3,    4,    5,    3,    4,    5,    3,   77,
+- /*    70 */     4,    5,    3,   61,   23,   15,   60,   11,   80,   12,
+- /*    80 */     2,   13,   68,   10,   29,   52,   55,   75,   31,   32,
+- /*    90 */     8,   28,    5,    3,   51,   55,   72,   14,
++ /*     0 */    81,   20,   96,    6,   28,   99,   98,   26,   26,   18,
++ /*    10 */    96,    6,   28,   17,   98,   56,   26,   19,   96,    6,
++ /*    20 */    28,   14,   98,   14,   26,   31,   92,   96,    6,   28,
++ /*    30 */   108,   98,   25,   26,   21,   96,    6,   28,   78,   98,
++ /*    40 */    58,   26,   29,   96,    6,   28,  107,   98,   22,   26,
++ /*    50 */    24,   16,   12,   11,    1,   13,   13,   24,   16,   23,
++ /*    60 */    11,   33,   34,   13,   97,    8,   27,   32,   98,    7,
++ /*    70 */    26,    3,    4,    5,    3,    4,    5,    3,   83,    4,
++ /*    80 */     5,    3,   63,    5,    3,   62,   12,    2,   86,   13,
++ /*    90 */     9,   30,   10,   10,   54,   57,   75,   78,   78,   53,
++ /*   100 */    57,   15,   82,   82,   71,
+ };
+ static const fts5YYCODETYPE fts5yy_lookahead[] = {
+  /*     0 */    16,   17,   18,   19,   20,   22,   22,   24,   24,   17,
+  /*    10 */    18,   19,   20,    7,   22,    9,   24,   17,   18,   19,
+- /*    20 */    20,   10,   22,    9,   24,   14,   17,   18,   19,   20,
+- /*    30 */     9,   22,   14,   24,   17,   18,   19,   20,   26,   22,
++ /*    20 */    20,    9,   22,    9,   24,   13,   17,   18,   19,   20,
++ /*    30 */    26,   22,   24,   24,   17,   18,   19,   20,   15,   22,
+  /*    40 */     9,   24,   17,   18,   19,   20,   26,   22,   21,   24,
+- /*    50 */     6,    7,   13,    9,   10,   18,   21,   20,    5,   22,
+- /*    60 */     5,   24,    3,    1,    2,    3,    1,    2,    3,    0,
+- /*    70 */     1,    2,    3,   11,    6,    7,   11,    9,    5,    9,
+- /*    80 */    10,    9,   11,   10,   12,    8,    9,   14,   24,   25,
+- /*    90 */    23,   24,    2,    3,    8,    9,    9,    9,
++ /*    50 */     6,    7,    9,    9,   10,   12,   12,    6,    7,   21,
++ /*    60 */     9,   24,   25,   12,   18,    5,   20,   14,   22,    5,
++ /*    70 */    24,    3,    1,    2,    3,    1,    2,    3,    0,    1,
++ /*    80 */     2,    3,   11,    2,    3,   11,    9,   10,    5,   12,
++ /*    90 */    23,   24,   10,   10,    8,    9,    9,   15,   15,    8,
++ /*   100 */     9,    9,   27,   27,   11,   27,   27,   27,   27,   27,
++ /*   110 */    27,   27,   27,   27,   27,   27,   27,   27,   27,   27,
++ /*   120 */    27,
+ };
+-#define fts5YY_SHIFT_USE_DFLT (98)
+-#define fts5YY_SHIFT_COUNT    (32)
++#define fts5YY_SHIFT_COUNT    (34)
+ #define fts5YY_SHIFT_MIN      (0)
+-#define fts5YY_SHIFT_MAX      (90)
++#define fts5YY_SHIFT_MAX      (93)
+ static const unsigned char fts5yy_shift_ofst[] = {
+- /*     0 */    44,   44,   44,   44,   44,   44,   68,   70,   72,   14,
+- /*    10 */    21,   73,   11,   18,   18,   31,   31,   62,   65,   69,
+- /*    20 */    90,   77,   86,    6,   39,   53,   55,   59,   39,   87,
+- /*    30 */    88,   39,   71,
++ /*     0 */    44,   44,   44,   44,   44,   44,   51,   77,   43,   12,
++ /*    10 */    14,   83,   82,   14,   23,   23,   31,   31,   71,   74,
++ /*    20 */    78,   81,   86,   91,    6,   53,   53,   60,   64,   68,
++ /*    30 */    53,   87,   92,   53,   93,
+ };
+-#define fts5YY_REDUCE_USE_DFLT (-18)
+-#define fts5YY_REDUCE_COUNT (16)
++#define fts5YY_REDUCE_COUNT (17)
+ #define fts5YY_REDUCE_MIN   (-17)
+ #define fts5YY_REDUCE_MAX   (67)
+ static const signed char fts5yy_reduce_ofst[] = {
+- /*     0 */   -16,   -8,    0,    9,   17,   25,   37,  -17,   64,  -17,
+- /*    10 */    67,   12,   12,   12,   20,   27,   35,
++ /*     0 */   -16,   -8,    0,    9,   17,   25,   46,  -17,  -17,   37,
++ /*    10 */    67,    4,    4,    8,    4,   20,   27,   38,
+ };
+ static const fts5YYACTIONTYPE fts5yy_default[] = {
+- /*     0 */   104,  104,  104,  104,  104,  104,   89,  104,   98,  104,
+- /*    10 */   104,  103,  103,  103,  103,  104,  104,  104,  104,  104,
+- /*    20 */    85,  104,  104,  104,   94,  104,  104,   84,   96,  104,
+- /*    30 */   104,   97,  104,
++ /*     0 */    80,   80,   80,   80,   80,   80,   95,   80,   80,  105,
++ /*    10 */    80,  110,  110,   80,  110,  110,   80,   80,   80,   80,
++ /*    20 */    80,   91,   80,   80,   80,  101,  100,   80,   80,   90,
++ /*    30 */   103,   80,   80,  104,   80,
+ };
+ /********** End of lemon-generated parsing tables *****************************/
+ 
+@@ -184751,6 +200069,7 @@
+   int fts5yyerrcnt;                 /* Shifts left before out of the error */
+ #endif
+   sqlite3Fts5ParserARG_SDECL                /* A place to hold %extra_argument */
++  sqlite3Fts5ParserCTX_SDECL                /* A place to hold %extra_context */
+ #if fts5YYSTACKDEPTH<=0
+   int fts5yystksz;                  /* Current side of the stack */
+   fts5yyStackEntry *fts5yystack;        /* The parser's stack */
+@@ -184794,19 +200113,39 @@
+ }
+ #endif /* NDEBUG */
+ 
+-#ifndef NDEBUG
++#if defined(fts5YYCOVERAGE) || !defined(NDEBUG)
+ /* For tracing shifts, the names of all terminals and nonterminals
+ ** are required.  The following table supplies these names */
+ static const char *const fts5yyTokenName[] = { 
+-  "$",             "OR",            "AND",           "NOT",         
+-  "TERM",          "COLON",         "MINUS",         "LCP",         
+-  "RCP",           "STRING",        "LP",            "RP",          
+-  "COMMA",         "PLUS",          "STAR",          "error",       
+-  "input",         "expr",          "cnearset",      "exprlist",    
+-  "colset",        "colsetlist",    "nearset",       "nearphrases", 
+-  "phrase",        "neardist_opt",  "star_opt",    
++  /*    0 */ "$",
++  /*    1 */ "OR",
++  /*    2 */ "AND",
++  /*    3 */ "NOT",
++  /*    4 */ "TERM",
++  /*    5 */ "COLON",
++  /*    6 */ "MINUS",
++  /*    7 */ "LCP",
++  /*    8 */ "RCP",
++  /*    9 */ "STRING",
++  /*   10 */ "LP",
++  /*   11 */ "RP",
++  /*   12 */ "CARET",
++  /*   13 */ "COMMA",
++  /*   14 */ "PLUS",
++  /*   15 */ "STAR",
++  /*   16 */ "input",
++  /*   17 */ "expr",
++  /*   18 */ "cnearset",
++  /*   19 */ "exprlist",
++  /*   20 */ "colset",
++  /*   21 */ "colsetlist",
++  /*   22 */ "nearset",
++  /*   23 */ "nearphrases",
++  /*   24 */ "phrase",
++  /*   25 */ "neardist_opt",
++  /*   26 */ "star_opt",
+ };
+-#endif /* NDEBUG */
++#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
+ 
+ #ifndef NDEBUG
+ /* For tracing reduce actions, the names of all rules are required.
+@@ -184830,15 +200169,16 @@
+  /*  15 */ "cnearset ::= nearset",
+  /*  16 */ "cnearset ::= colset COLON nearset",
+  /*  17 */ "nearset ::= phrase",
+- /*  18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+- /*  19 */ "nearphrases ::= phrase",
+- /*  20 */ "nearphrases ::= nearphrases phrase",
+- /*  21 */ "neardist_opt ::=",
+- /*  22 */ "neardist_opt ::= COMMA STRING",
+- /*  23 */ "phrase ::= phrase PLUS STRING star_opt",
+- /*  24 */ "phrase ::= STRING star_opt",
+- /*  25 */ "star_opt ::= STAR",
+- /*  26 */ "star_opt ::=",
++ /*  18 */ "nearset ::= CARET phrase",
++ /*  19 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
++ /*  20 */ "nearphrases ::= phrase",
++ /*  21 */ "nearphrases ::= nearphrases phrase",
++ /*  22 */ "neardist_opt ::=",
++ /*  23 */ "neardist_opt ::= COMMA STRING",
++ /*  24 */ "phrase ::= phrase PLUS STRING star_opt",
++ /*  25 */ "phrase ::= STRING star_opt",
++ /*  26 */ "star_opt ::= STAR",
++ /*  27 */ "star_opt ::=",
+ };
+ #endif /* NDEBUG */
+ 
+@@ -184887,28 +200227,29 @@
+ 
+ /* Initialize a new parser that has already been allocated.
+ */
+-static void sqlite3Fts5ParserInit(void *fts5yypParser){
+-  fts5yyParser *pParser = (fts5yyParser*)fts5yypParser;
++static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){
++  fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser;
++  sqlite3Fts5ParserCTX_STORE
+ #ifdef fts5YYTRACKMAXSTACKDEPTH
+-  pParser->fts5yyhwm = 0;
++  fts5yypParser->fts5yyhwm = 0;
+ #endif
+ #if fts5YYSTACKDEPTH<=0
+-  pParser->fts5yytos = NULL;
+-  pParser->fts5yystack = NULL;
+-  pParser->fts5yystksz = 0;
+-  if( fts5yyGrowStack(pParser) ){
+-    pParser->fts5yystack = &pParser->fts5yystk0;
+-    pParser->fts5yystksz = 1;
++  fts5yypParser->fts5yytos = NULL;
++  fts5yypParser->fts5yystack = NULL;
++  fts5yypParser->fts5yystksz = 0;
++  if( fts5yyGrowStack(fts5yypParser) ){
++    fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0;
++    fts5yypParser->fts5yystksz = 1;
+   }
+ #endif
+ #ifndef fts5YYNOERRORRECOVERY
+-  pParser->fts5yyerrcnt = -1;
++  fts5yypParser->fts5yyerrcnt = -1;
+ #endif
+-  pParser->fts5yytos = pParser->fts5yystack;
+-  pParser->fts5yystack[0].stateno = 0;
+-  pParser->fts5yystack[0].major = 0;
++  fts5yypParser->fts5yytos = fts5yypParser->fts5yystack;
++  fts5yypParser->fts5yystack[0].stateno = 0;
++  fts5yypParser->fts5yystack[0].major = 0;
+ #if fts5YYSTACKDEPTH>0
+-  pParser->fts5yystackEnd = &pParser->fts5yystack[fts5YYSTACKDEPTH-1];
++  fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
+ #endif
+ }
+ 
+@@ -184925,11 +200266,14 @@
+ ** A pointer to a parser.  This pointer is used in subsequent calls
+ ** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
+ */
+-static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
+-  fts5yyParser *pParser;
+-  pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
+-  if( pParser ) sqlite3Fts5ParserInit(pParser);
+-  return pParser;
++static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){
++  fts5yyParser *fts5yypParser;
++  fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
++  if( fts5yypParser ){
++    sqlite3Fts5ParserCTX_STORE
++    sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM);
++  }
++  return (void*)fts5yypParser;
+ }
+ #endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
+ 
+@@ -184946,7 +200290,8 @@
+   fts5YYCODETYPE fts5yymajor,     /* Type code for object to destroy */
+   fts5YYMINORTYPE *fts5yypminor   /* The object to be destroyed */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+   switch( fts5yymajor ){
+     /* Here is inserted the actions which take place when a
+     ** terminal or non-terminal is destroyed.  This can happen
+@@ -185056,24 +200401,66 @@
+ }
+ #endif
+ 
++/* This array of booleans keeps track of the parser statement
++** coverage.  The element fts5yycoverage[X][Y] is set when the parser
++** is in state X and has a lookahead token Y.  In a well-tested
++** systems, every element of this matrix should end up being set.
++*/
++#if defined(fts5YYCOVERAGE)
++static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN];
++#endif
++
+ /*
++** Write into out a description of every state/lookahead combination that
++**
++**   (1)  has not been used by the parser, and
++**   (2)  is not a syntax error.
++**
++** Return the number of missed state/lookahead combinations.
++*/
++#if defined(fts5YYCOVERAGE)
++static int sqlite3Fts5ParserCoverage(FILE *out){
++  int stateno, iLookAhead, i;
++  int nMissed = 0;
++  for(stateno=0; stateno<fts5YYNSTATE; stateno++){
++    i = fts5yy_shift_ofst[stateno];
++    for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){
++      if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
++      if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++;
++      if( out ){
++        fprintf(out,"State %d lookahead %s %s\n", stateno,
++                fts5yyTokenName[iLookAhead],
++                fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed");
++      }
++    }
++  }
++  return nMissed;
++}
++#endif
++
++/*
+ ** Find the appropriate action for a parser given the terminal
+ ** look-ahead token iLookAhead.
+ */
+-static unsigned int fts5yy_find_shift_action(
+-  fts5yyParser *pParser,        /* The parser */
+-  fts5YYCODETYPE iLookAhead     /* The look-ahead token */
++static fts5YYACTIONTYPE fts5yy_find_shift_action(
++  fts5YYCODETYPE iLookAhead,    /* The look-ahead token */
++  fts5YYACTIONTYPE stateno      /* Current state number */
+ ){
+   int i;
+-  int stateno = pParser->fts5yytos->stateno;
+- 
+-  if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
++
++  if( stateno>fts5YY_MAX_SHIFT ) return stateno;
+   assert( stateno <= fts5YY_SHIFT_COUNT );
++#if defined(fts5YYCOVERAGE)
++  fts5yycoverage[stateno][iLookAhead] = 1;
++#endif
+   do{
+     i = fts5yy_shift_ofst[stateno];
++    assert( i>=0 );
++    /* assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD ); */
+     assert( iLookAhead!=fts5YYNOCODE );
++    assert( iLookAhead < fts5YYNFTS5TOKEN );
+     i += iLookAhead;
+-    if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
++    if( i>=fts5YY_NLOOKAHEAD || fts5yy_lookahead[i]!=iLookAhead ){
+ #ifdef fts5YYFALLBACK
+       fts5YYCODETYPE iFallback;            /* Fallback token */
+       if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
+@@ -185099,6 +200486,7 @@
+ #if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
+           j<fts5YY_ACTTAB_COUNT &&
+ #endif
++          j<(int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])) &&
+           fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
+         ){
+ #ifndef NDEBUG
+@@ -185123,8 +200511,8 @@
+ ** Find the appropriate action for a parser given the non-terminal
+ ** look-ahead token iLookAhead.
+ */
+-static int fts5yy_find_reduce_action(
+-  int stateno,              /* Current state number */
++static fts5YYACTIONTYPE fts5yy_find_reduce_action(
++  fts5YYACTIONTYPE stateno,     /* Current state number */
+   fts5YYCODETYPE iLookAhead     /* The look-ahead token */
+ ){
+   int i;
+@@ -185136,7 +200524,6 @@
+   assert( stateno<=fts5YY_REDUCE_COUNT );
+ #endif
+   i = fts5yy_reduce_ofst[stateno];
+-  assert( i!=fts5YY_REDUCE_USE_DFLT );
+   assert( iLookAhead!=fts5YYNOCODE );
+   i += iLookAhead;
+ #ifdef fts5YYERRORSYMBOL
+@@ -185154,7 +200541,8 @@
+ ** The following routine is called if the stack overflows.
+ */
+ static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
+-   sqlite3Fts5ParserARG_FETCH;
++   sqlite3Fts5ParserARG_FETCH
++   sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+    if( fts5yyTraceFILE ){
+      fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
+@@ -185167,7 +200555,8 @@
+ 
+   sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
+ /******** End %stack_overflow code ********************************************/
+-   sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
++   sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
++   sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /*
+@@ -185174,20 +200563,21 @@
+ ** Print tracing information for a SHIFT action
+ */
+ #ifndef NDEBUG
+-static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
++static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){
+   if( fts5yyTraceFILE ){
+     if( fts5yyNewState<fts5YYNSTATE ){
+-      fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n",
+-         fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major],
++      fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n",
++         fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
+          fts5yyNewState);
+     }else{
+-      fprintf(fts5yyTraceFILE,"%sShift '%s'\n",
+-         fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major]);
++      fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n",
++         fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
++         fts5yyNewState - fts5YY_MIN_REDUCE);
+     }
+   }
+ }
+ #else
+-# define fts5yyTraceShift(X,Y)
++# define fts5yyTraceShift(X,Y,Z)
+ #endif
+ 
+ /*
+@@ -185195,8 +200585,8 @@
+ */
+ static void fts5yy_shift(
+   fts5yyParser *fts5yypParser,          /* The parser to be shifted */
+-  int fts5yyNewState,               /* The new state to shift in */
+-  int fts5yyMajor,                  /* The major token to shift in */
++  fts5YYACTIONTYPE fts5yyNewState,      /* The new state to shift in */
++  fts5YYCODETYPE fts5yyMajor,           /* The major token to shift in */
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor        /* The minor token to shift in */
+ ){
+   fts5yyStackEntry *fts5yytos;
+@@ -185226,10 +200616,10 @@
+     fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+   }
+   fts5yytos = fts5yypParser->fts5yytos;
+-  fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
+-  fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
++  fts5yytos->stateno = fts5yyNewState;
++  fts5yytos->major = fts5yyMajor;
+   fts5yytos->minor.fts5yy0 = fts5yyMinor;
+-  fts5yyTraceShift(fts5yypParser, fts5yyNewState);
++  fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
+ }
+ 
+ /* The following table contains information about every rule that
+@@ -185239,33 +200629,34 @@
+   fts5YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
+   signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
+ } fts5yyRuleInfo[] = {
+-  { 16, -1 },
+-  { 20, -4 },
+-  { 20, -3 },
+-  { 20, -1 },
+-  { 20, -2 },
+-  { 21, -2 },
+-  { 21, -1 },
+-  { 17, -3 },
+-  { 17, -3 },
+-  { 17, -3 },
+-  { 17, -5 },
+-  { 17, -3 },
+-  { 17, -1 },
+-  { 19, -1 },
+-  { 19, -2 },
+-  { 18, -1 },
+-  { 18, -3 },
+-  { 22, -1 },
+-  { 22, -5 },
+-  { 23, -1 },
+-  { 23, -2 },
+-  { 25, 0 },
+-  { 25, -2 },
+-  { 24, -4 },
+-  { 24, -2 },
+-  { 26, -1 },
+-  { 26, 0 },
++  {   16,   -1 }, /* (0) input ::= expr */
++  {   20,   -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
++  {   20,   -3 }, /* (2) colset ::= LCP colsetlist RCP */
++  {   20,   -1 }, /* (3) colset ::= STRING */
++  {   20,   -2 }, /* (4) colset ::= MINUS STRING */
++  {   21,   -2 }, /* (5) colsetlist ::= colsetlist STRING */
++  {   21,   -1 }, /* (6) colsetlist ::= STRING */
++  {   17,   -3 }, /* (7) expr ::= expr AND expr */
++  {   17,   -3 }, /* (8) expr ::= expr OR expr */
++  {   17,   -3 }, /* (9) expr ::= expr NOT expr */
++  {   17,   -5 }, /* (10) expr ::= colset COLON LP expr RP */
++  {   17,   -3 }, /* (11) expr ::= LP expr RP */
++  {   17,   -1 }, /* (12) expr ::= exprlist */
++  {   19,   -1 }, /* (13) exprlist ::= cnearset */
++  {   19,   -2 }, /* (14) exprlist ::= exprlist cnearset */
++  {   18,   -1 }, /* (15) cnearset ::= nearset */
++  {   18,   -3 }, /* (16) cnearset ::= colset COLON nearset */
++  {   22,   -1 }, /* (17) nearset ::= phrase */
++  {   22,   -2 }, /* (18) nearset ::= CARET phrase */
++  {   22,   -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
++  {   23,   -1 }, /* (20) nearphrases ::= phrase */
++  {   23,   -2 }, /* (21) nearphrases ::= nearphrases phrase */
++  {   25,    0 }, /* (22) neardist_opt ::= */
++  {   25,   -2 }, /* (23) neardist_opt ::= COMMA STRING */
++  {   24,   -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
++  {   24,   -2 }, /* (25) phrase ::= STRING star_opt */
++  {   26,   -1 }, /* (26) star_opt ::= STAR */
++  {   26,    0 }, /* (27) star_opt ::= */
+ };
+ 
+ static void fts5yy_accept(fts5yyParser*);  /* Forward Declaration */
+@@ -185273,22 +200664,39 @@
+ /*
+ ** Perform a reduce action and the shift that must immediately
+ ** follow the reduce.
++**
++** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions
++** access to the lookahead token (if any).  The fts5yyLookahead will be fts5YYNOCODE
++** if the lookahead token has already been consumed.  As this procedure is
++** only called from one place, optimizing compilers will in-line it, which
++** means that the extra parameters have no performance impact.
+ */
+-static void fts5yy_reduce(
++static fts5YYACTIONTYPE fts5yy_reduce(
+   fts5yyParser *fts5yypParser,         /* The parser */
+-  unsigned int fts5yyruleno        /* Number of the rule by which to reduce */
++  unsigned int fts5yyruleno,       /* Number of the rule by which to reduce */
++  int fts5yyLookahead,             /* Lookahead token, or fts5YYNOCODE if none */
++  sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken  /* Value of the lookahead token */
++  sqlite3Fts5ParserCTX_PDECL                   /* %extra_context */
+ ){
+   int fts5yygoto;                     /* The next state */
+-  int fts5yyact;                      /* The next action */
++  fts5YYACTIONTYPE fts5yyact;             /* The next action */
+   fts5yyStackEntry *fts5yymsp;            /* The top of the parser's stack */
+   int fts5yysize;                     /* Amount to pop the stack */
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  (void)fts5yyLookahead;
++  (void)fts5yyLookaheadToken;
+   fts5yymsp = fts5yypParser->fts5yytos;
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
+     fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+-    fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt,
+-      fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
++    if( fts5yysize ){
++      fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
++        fts5yyTracePrompt,
++        fts5yyruleno, fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
++    }else{
++      fprintf(fts5yyTraceFILE, "%sReduce %d [%s].\n",
++        fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno]);
++    }
+   }
+ #endif /* NDEBUG */
+ 
+@@ -185305,13 +200713,19 @@
+ #if fts5YYSTACKDEPTH>0 
+     if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){
+       fts5yyStackOverflow(fts5yypParser);
+-      return;
++      /* The call to fts5yyStackOverflow() above pops the stack until it is
++      ** empty, causing the main parser loop to exit.  So the return value
++      ** is never used and does not matter. */
++      return 0;
+     }
+ #else
+     if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){
+       if( fts5yyGrowStack(fts5yypParser) ){
+         fts5yyStackOverflow(fts5yypParser);
+-        return;
++        /* The call to fts5yyStackOverflow() above pops the stack until it is
++        ** empty, causing the main parser loop to exit.  So the return value
++        ** is never used and does not matter. */
++        return 0;
+       }
+       fts5yymsp = fts5yypParser->fts5yytos;
+     }
+@@ -185419,7 +200833,13 @@
+ { fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
+   fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+-      case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
++      case 18: /* nearset ::= CARET phrase */
++{ 
++  sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
++  fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); 
++}
++        break;
++      case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ {
+   sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
+   sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
+@@ -185427,40 +200847,40 @@
+ }
+   fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+-      case 19: /* nearphrases ::= phrase */
++      case 20: /* nearphrases ::= phrase */
+ { 
+   fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); 
+ }
+   fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+-      case 20: /* nearphrases ::= nearphrases phrase */
++      case 21: /* nearphrases ::= nearphrases phrase */
+ {
+   fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
+ }
+   fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+-      case 21: /* neardist_opt ::= */
++      case 22: /* neardist_opt ::= */
+ { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
+         break;
+-      case 22: /* neardist_opt ::= COMMA STRING */
++      case 23: /* neardist_opt ::= COMMA STRING */
+ { fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
+         break;
+-      case 23: /* phrase ::= phrase PLUS STRING star_opt */
++      case 24: /* phrase ::= phrase PLUS STRING star_opt */
+ { 
+   fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ }
+   fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+         break;
+-      case 24: /* phrase ::= STRING star_opt */
++      case 25: /* phrase ::= STRING star_opt */
+ { 
+   fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ }
+   fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+         break;
+-      case 25: /* star_opt ::= STAR */
++      case 26: /* star_opt ::= STAR */
+ { fts5yymsp[0].minor.fts5yy4 = 1; }
+         break;
+-      case 26: /* star_opt ::= */
++      case 27: /* star_opt ::= */
+ { fts5yymsp[1].minor.fts5yy4 = 0; }
+         break;
+       default:
+@@ -185479,16 +200899,12 @@
+   /* It is not possible for a REDUCE to be followed by an error */
+   assert( fts5yyact!=fts5YY_ERROR_ACTION );
+ 
+-  if( fts5yyact==fts5YY_ACCEPT_ACTION ){
+-    fts5yypParser->fts5yytos += fts5yysize;
+-    fts5yy_accept(fts5yypParser);
+-  }else{
+-    fts5yymsp += fts5yysize+1;
+-    fts5yypParser->fts5yytos = fts5yymsp;
+-    fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+-    fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+-    fts5yyTraceShift(fts5yypParser, fts5yyact);
+-  }
++  fts5yymsp += fts5yysize+1;
++  fts5yypParser->fts5yytos = fts5yymsp;
++  fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
++  fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
++  fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
++  return fts5yyact;
+ }
+ 
+ /*
+@@ -185498,7 +200914,8 @@
+ static void fts5yy_parse_failed(
+   fts5yyParser *fts5yypParser           /* The parser */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
+@@ -185509,7 +200926,8 @@
+   ** parser fails */
+ /************ Begin %parse_failure code ***************************************/
+ /************ End %parse_failure code *****************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ #endif /* fts5YYNOERRORRECOVERY */
+ 
+@@ -185521,7 +200939,8 @@
+   int fts5yymajor,                   /* The major type of the error token */
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor         /* The minor type of the error token */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #define FTS5TOKEN fts5yyminor
+ /************ Begin %syntax_error code ****************************************/
+ 
+@@ -185530,7 +200949,8 @@
+     pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
+   );
+ /************ End %syntax_error code ******************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /*
+@@ -185539,7 +200959,8 @@
+ static void fts5yy_accept(
+   fts5yyParser *fts5yypParser           /* The parser */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
+@@ -185553,7 +200974,8 @@
+   ** parser accepts */
+ /*********** Begin %parse_accept code *****************************************/
+ /*********** End %parse_accept code *******************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /* The main parser program.
+@@ -185582,7 +201004,7 @@
+   sqlite3Fts5ParserARG_PDECL               /* Optional %extra_argument parameter */
+ ){
+   fts5YYMINORTYPE fts5yyminorunion;
+-  unsigned int fts5yyact;   /* The parser action. */
++  fts5YYACTIONTYPE fts5yyact;   /* The parser action. */
+ #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+   int fts5yyendofinput;     /* True if we are at the end of input */
+ #endif
+@@ -185589,31 +201011,44 @@
+ #ifdef fts5YYERRORSYMBOL
+   int fts5yyerrorhit = 0;   /* True if fts5yymajor has invoked an error */
+ #endif
+-  fts5yyParser *fts5yypParser;  /* The parser */
++  fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp;  /* The parser */
++  sqlite3Fts5ParserCTX_FETCH
++  sqlite3Fts5ParserARG_STORE
+ 
+-  fts5yypParser = (fts5yyParser*)fts5yyp;
+   assert( fts5yypParser->fts5yytos!=0 );
+ #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+   fts5yyendofinput = (fts5yymajor==0);
+ #endif
+-  sqlite3Fts5ParserARG_STORE;
+ 
++  fts5yyact = fts5yypParser->fts5yytos->stateno;
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+-    fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
++    if( fts5yyact < fts5YY_MIN_REDUCE ){
++      fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
++              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact);
++    }else{
++      fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
++              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact-fts5YY_MIN_REDUCE);
++    }
+   }
+ #endif
+ 
+   do{
+-    fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
+-    if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+-      fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
++    assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
++    fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
++    if( fts5yyact >= fts5YY_MIN_REDUCE ){
++      fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor,
++                        fts5yyminor sqlite3Fts5ParserCTX_PARAM);
++    }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
++      fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor);
+ #ifndef fts5YYNOERRORRECOVERY
+       fts5yypParser->fts5yyerrcnt--;
+ #endif
+-      fts5yymajor = fts5YYNOCODE;
+-    }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
+-      fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
++      break;
++    }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
++      fts5yypParser->fts5yytos--;
++      fts5yy_accept(fts5yypParser);
++      return;
+     }else{
+       assert( fts5yyact == fts5YY_ERROR_ACTION );
+       fts5yyminorunion.fts5yy0 = fts5yyminor;
+@@ -185660,10 +201095,9 @@
+         fts5yymajor = fts5YYNOCODE;
+       }else{
+         while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
+-            && fts5yymx != fts5YYERRORSYMBOL
+             && (fts5yyact = fts5yy_find_reduce_action(
+                         fts5yypParser->fts5yytos->stateno,
+-                        fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
++                        fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE
+         ){
+           fts5yy_pop_parser_stack(fts5yypParser);
+         }
+@@ -185680,6 +201114,8 @@
+       }
+       fts5yypParser->fts5yyerrcnt = 3;
+       fts5yyerrorhit = 1;
++      if( fts5yymajor==fts5YYNOCODE ) break;
++      fts5yyact = fts5yypParser->fts5yytos->stateno;
+ #elif defined(fts5YYNOERRORRECOVERY)
+       /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
+       ** do any kind of error recovery.  Instead, simply invoke the syntax
+@@ -185690,8 +201126,7 @@
+       */
+       fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
+       fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+-      fts5yymajor = fts5YYNOCODE;
+-      
++      break;
+ #else  /* fts5YYERRORSYMBOL is not defined */
+       /* This is what we do if the grammar does not define ERROR:
+       **
+@@ -185713,10 +201148,10 @@
+         fts5yypParser->fts5yyerrcnt = -1;
+ #endif
+       }
+-      fts5yymajor = fts5YYNOCODE;
++      break;
+ #endif
+     }
+-  }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
++  }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fts5yyStackEntry *i;
+@@ -185733,6 +201168,21 @@
+ }
+ 
+ /*
++** Return the fallback token corresponding to canonical token iToken, or
++** 0 if iToken has no fallback.
++*/
++static int sqlite3Fts5ParserFallback(int iToken){
++#ifdef fts5YYFALLBACK
++  if( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ){
++    return fts5yyFallback[iToken];
++  }
++#else
++  (void)iToken;
++#endif
++  return 0;
++}
++
++/*
+ ** 2014 May 31
+ **
+ ** The author disclaims copyright to this source code.  In place of
+@@ -186093,6 +201543,16 @@
+ }
+ 
+ /*
++** Return the value in pVal interpreted as utf-8 text. Except, if pVal 
++** contains a NULL value, return a pointer to a static string zero
++** bytes in length instead of a NULL pointer.
++*/
++static const char *fts5ValueToText(sqlite3_value *pVal){
++  const char *zRet = (const char*)sqlite3_value_text(pVal);
++  return zRet ? zRet : "";
++}
++
++/*
+ ** Implementation of snippet() function.
+ */
+ static void fts5SnippetFunction(
+@@ -186127,9 +201587,9 @@
+   nCol = pApi->xColumnCount(pFts);
+   memset(&ctx, 0, sizeof(HighlightContext));
+   iCol = sqlite3_value_int(apVal[0]);
+-  ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
+-  ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
+-  zEllips = (const char*)sqlite3_value_text(apVal[3]);
++  ctx.zOpen = fts5ValueToText(apVal[1]);
++  ctx.zClose = fts5ValueToText(apVal[2]);
++  zEllips = fts5ValueToText(apVal[3]);
+   nToken = sqlite3_value_int(apVal[4]);
+ 
+   iBestCol = (iCol>=0 ? iCol : 0);
+@@ -187832,6 +203292,7 @@
+ /* #include <stdio.h> */
+ static void sqlite3Fts5ParserTrace(FILE*, char*);
+ #endif
++static int sqlite3Fts5ParserFallback(int);
+ 
+ 
+ struct Fts5Expr {
+@@ -187883,7 +203344,8 @@
+ ** or term prefix.
+ */
+ struct Fts5ExprTerm {
+-  int bPrefix;                    /* True for a prefix term */
++  u8 bPrefix;                     /* True for a prefix term */
++  u8 bFirst;                      /* True if token must be first in column */
+   char *zTerm;                    /* nul-terminated term */
+   Fts5IndexIter *pIter;           /* Iterator for this term */
+   Fts5ExprTerm *pSynonym;         /* Pointer to first in list of synonyms */
+@@ -187964,6 +203426,7 @@
+     case '+':  tok = FTS5_PLUS;  break;
+     case '*':  tok = FTS5_STAR;  break;
+     case '-':  tok = FTS5_MINUS; break;
++    case '^':  tok = FTS5_CARET; break;
+     case '\0': tok = FTS5_EOF;   break;
+ 
+     case '"': {
+@@ -188223,6 +203686,7 @@
+   Fts5PoslistReader *aIter = aStatic;
+   int i;
+   int rc = SQLITE_OK;
++  int bFirst = pPhrase->aTerm[0].bFirst;
+   
+   fts5BufferZero(&pPhrase->poslist);
+ 
+@@ -188277,8 +203741,10 @@
+     }while( bMatch==0 );
+ 
+     /* Append position iPos to the output */
+-    rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
+-    if( rc!=SQLITE_OK ) goto ismatch_out;
++    if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
++      rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
++      if( rc!=SQLITE_OK ) goto ismatch_out;
++    }
+ 
+     for(i=0; i<pPhrase->nTerm; i++){
+       if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
+@@ -188532,7 +203998,9 @@
+     ** phrase is not a match, break out of the loop early.  */
+     for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
+       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+-      if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
++      if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym 
++       || pNear->pColset || pPhrase->aTerm[0].bFirst
++      ){
+         int bMatch = 0;
+         rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
+         if( bMatch==0 ) break;
+@@ -188713,6 +204181,7 @@
+   assert( pNear->nPhrase>1 
+        || pNear->apPhrase[0]->nTerm>1 
+        || pNear->apPhrase[0]->aTerm[0].pSynonym
++       || pNear->apPhrase[0]->aTerm[0].bFirst
+   );
+ 
+   /* Initialize iLast, the "lastest" rowid any iterator points to. If the
+@@ -189238,6 +204707,16 @@
+ }
+ 
+ /*
++** Set the "bFirst" flag on the first token of the phrase passed as the
++** only argument.
++*/
++static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
++  if( pPhrase && pPhrase->nTerm ){
++    pPhrase->aTerm[0].bFirst = 1;
++  }
++}
++
++/*
+ ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
+ ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
+ ** appended to it and the results returned.
+@@ -189454,7 +204933,7 @@
+       ** no token characters at all. (e.g ... MATCH '""'). */
+       sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
+     }else if( sCtx.pPhrase->nTerm ){
+-      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
++      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
+     }
+     pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
+   }
+@@ -189515,6 +204994,7 @@
+       }
+       if( rc==SQLITE_OK ){
+         sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
++        sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
+       }
+     }
+   }else{
+@@ -189533,7 +205013,10 @@
+     pNew->pRoot->pNear->nPhrase = 1;
+     sCtx.pPhrase->pNode = pNew->pRoot;
+ 
+-    if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
++    if( pOrig->nTerm==1 
++     && pOrig->aTerm[0].pSynonym==0 
++     && pOrig->aTerm[0].bFirst==0 
++    ){
+       pNew->pRoot->eType = FTS5_TERM;
+       pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
+     }else{
+@@ -189807,6 +205290,7 @@
+       Fts5ExprNearset *pNear = pNode->pNear;
+       if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 
+        && pNear->apPhrase[0]->aTerm[0].pSynonym==0
++       && pNear->apPhrase[0]->aTerm[0].bFirst==0
+       ){
+         pNode->eType = FTS5_TERM;
+         pNode->xNext = fts5ExprNodeNext_TERM;
+@@ -189893,20 +205377,23 @@
+           }
+         }
+ 
+-        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL 
+-         && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
+-        ){
+-          assert( pParse->rc==SQLITE_OK );
+-          pParse->rc = SQLITE_ERROR;
+-          assert( pParse->zErr==0 );
+-          pParse->zErr = sqlite3_mprintf(
+-              "fts5: %s queries are not supported (detail!=full)", 
+-              pNear->nPhrase==1 ? "phrase": "NEAR"
+-          );
+-          sqlite3_free(pRet);
+-          pRet = 0;
++        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
++          Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
++          if( pNear->nPhrase!=1 
++           || pPhrase->nTerm>1
++           || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
++          ){
++            assert( pParse->rc==SQLITE_OK );
++            pParse->rc = SQLITE_ERROR;
++            assert( pParse->zErr==0 );
++            pParse->zErr = sqlite3_mprintf(
++                "fts5: %s queries are not supported (detail!=full)", 
++                pNear->nPhrase==1 ? "phrase": "NEAR"
++                );
++            sqlite3_free(pRet);
++            pRet = 0;
++          }
+         }
+-
+       }else{
+         fts5ExprAddChildren(pRet, pLeft);
+         fts5ExprAddChildren(pRet, pRight);
+@@ -190310,6 +205797,7 @@
+   sqlite3_value **apVal           /* Function arguments */
+ ){
+   int iCode;
++  u8 aArr[32];
+   if( nArg!=1 ){
+     sqlite3_result_error(pCtx, 
+         "wrong number of arguments to function fts5_isalnum", -1
+@@ -190316,8 +205804,12 @@
+     );
+     return;
+   }
++  memset(aArr, 0, sizeof(aArr));
++  sqlite3Fts5UnicodeCatParse("L*", aArr);
++  sqlite3Fts5UnicodeCatParse("N*", aArr);
++  sqlite3Fts5UnicodeCatParse("Co", aArr);
+   iCode = sqlite3_value_int(apVal[0]);
+-  sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
++  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
+ }
+ 
+ static void fts5ExprFold(
+@@ -190361,10 +205853,12 @@
+     rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
+   }
+ 
+-  /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
++  /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
++  ** sqlite3Fts5ParserFallback() are unused */
+ #ifndef NDEBUG
+   (void)sqlite3Fts5ParserTrace;
+ #endif
++  (void)sqlite3Fts5ParserFallback;
+ 
+   return rc;
+ }
+@@ -191909,6 +207403,7 @@
+   sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
+   sqlite3_step(p->pWriter);
+   p->rc = sqlite3_reset(p->pWriter);
++  sqlite3_bind_null(p->pWriter, 2);
+ }
+ 
+ /*
+@@ -193537,6 +209032,7 @@
+     bDlidx = (val & 0x0001);
+   }
+   p->rc = sqlite3_reset(pIdxSelect);
++  sqlite3_bind_null(pIdxSelect, 2);
+ 
+   if( iPg<pSeg->pgnoFirst ){
+     iPg = pSeg->pgnoFirst;
+@@ -194749,6 +210245,7 @@
+           sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
+           assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
+           p->rc = sqlite3_reset(pIdxSelect);
++          sqlite3_bind_null(pIdxSelect, 2);
+         }
+       }
+ #endif
+@@ -194875,6 +210372,7 @@
+     sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
+     sqlite3_step(p->pIdxWriter);
+     p->rc = sqlite3_reset(p->pIdxWriter);
++    sqlite3_bind_null(p->pIdxWriter, 2);
+   }
+   pWriter->iBtPage = 0;
+ }
+@@ -196060,7 +211558,13 @@
+     Fts5Buffer out = {0, 0, 0};
+     Fts5Buffer tmp = {0, 0, 0};
+ 
+-    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
++    /* The maximum size of the output is equal to the sum of the two 
++    ** input sizes + 1 varint (9 bytes). The extra varint is because if the
++    ** first rowid in one input is a large negative number, and the first in
++    ** the other a non-negative number, the delta for the non-negative
++    ** number will be larger on disk than the literal integer value
++    ** was.  */
++    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
+     fts5DoclistIterInit(p1, &i1);
+     fts5DoclistIterInit(p2, &i2);
+ 
+@@ -196154,6 +211658,7 @@
+       fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
+       fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
+     }
++    assert( out.n<=(p1->n+p2->n+9) );
+ 
+     fts5BufferSet(&p->rc, p1, out.n, out.p);
+     fts5BufferFree(&tmp);
+@@ -196401,7 +211906,10 @@
+   for(i=0; i<nChar; i++){
+     if( n>=nByte ) return 0;      /* Input contains fewer than nChar chars */
+     if( (unsigned char)p[n++]>=0xc0 ){
+-      while( (p[n] & 0xc0)==0x80 ) n++;
++      while( (p[n] & 0xc0)==0x80 ){
++        n++;
++        if( n>=nByte ) break;
++      }
+     }
+   }
+   return n;
+@@ -196539,7 +212047,7 @@
+       fts5CloseReader(p);
+     }
+ 
+-    *ppIter = &pRet->base;
++    *ppIter = (Fts5IndexIter*)pRet;
+     sqlite3Fts5BufferFree(&buf);
+   }
+   return fts5IndexReturn(p);
+@@ -197926,7 +213434,7 @@
+     case FTS5_SAVEPOINT:
+       assert( p->ts.eState==1 );
+       assert( iSavepoint>=0 );
+-      assert( iSavepoint>p->ts.iSavepoint );
++      assert( iSavepoint>=p->ts.iSavepoint );
+       p->ts.iSavepoint = iSavepoint;
+       break;
+       
+@@ -198181,6 +213689,12 @@
+   aColMap[1] = nCol;
+   aColMap[2] = nCol+1;
+ 
++  assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
++  assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
++  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
++  assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
++  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
++
+   /* Set idxFlags flags for all WHERE clause terms that will be used. */
+   for(i=0; i<pInfo->nConstraint; i++){
+     struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
+@@ -198199,11 +213713,11 @@
+         pInfo->estimatedCost = 1e50;
+         return SQLITE_OK;
+       }
+-    }else{
++    }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
+       int j;
+       for(j=1; j<ArraySize(aConstraint); j++){
+         struct Constraint *pC = &aConstraint[j];
+-        if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
++        if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
+           pC->iConsIndex = i;
+           idxFlags |= pC->fts5op;
+         }
+@@ -198845,6 +214359,13 @@
+     assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
+     assert( pCsr->iLastRowid==LARGEST_INT64 );
+     assert( pCsr->iFirstRowid==SMALLEST_INT64 );
++    if( pTab->pSortCsr->bDesc ){
++      pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
++      pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
++    }else{
++      pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
++      pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
++    }
+     pCsr->ePlan = FTS5_PLAN_SOURCE;
+     pCsr->pExpr = pTab->pSortCsr->pExpr;
+     rc = fts5CursorFirst(pTab, pCsr, bDesc);
+@@ -200275,12 +215796,27 @@
+ ){
+   assert( nArg==0 );
+   UNUSED_PARAM2(nArg, apUnused);
+-  sqlite3_result_text(pCtx, "fts5: 2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8", -1, SQLITE_TRANSIENT);
++  sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
+ }
+ 
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int fts5ShadowName(const char *zName){
++  static const char *azName[] = {
++    "config", "content", "data", "docsize", "idx"
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static int fts5Init(sqlite3 *db){
+   static const sqlite3_module fts5Mod = {
+-    /* iVersion      */ 2,
++    /* iVersion      */ 3,
+     /* xCreate       */ fts5CreateMethod,
+     /* xConnect      */ fts5ConnectMethod,
+     /* xBestIndex    */ fts5BestIndexMethod,
+@@ -200303,6 +215839,7 @@
+     /* xSavepoint    */ fts5SavepointMethod,
+     /* xRelease      */ fts5ReleaseMethod,
+     /* xRollbackTo   */ fts5RollbackToMethod,
++    /* xShadowName   */ fts5ShadowName
+   };
+ 
+   int rc;
+@@ -200851,6 +216388,7 @@
+       sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
+       sqlite3_step(pReplace);
+       rc = sqlite3_reset(pReplace);
++      sqlite3_bind_null(pReplace, 2);
+     }
+   }
+   return rc;
+@@ -201511,6 +217049,7 @@
+     }
+     sqlite3_step(pReplace);
+     rc = sqlite3_reset(pReplace);
++    sqlite3_bind_null(pReplace, 1);
+   }
+   if( rc==SQLITE_OK && pVal ){
+     int iNew = p->pConfig->iCookie + 1;
+@@ -201761,6 +217300,8 @@
+   int bRemoveDiacritic;           /* True if remove_diacritics=1 is set */
+   int nException;
+   int *aiException;
++
++  unsigned char aCategory[32];    /* True for token char categories */
+ };
+ 
+ static int fts5UnicodeAddExceptions(
+@@ -201785,7 +217326,7 @@
+         if( iCode<128 ){
+           p->aTokenChar[iCode] = (unsigned char)bTokenChars;
+         }else{
+-          bToken = sqlite3Fts5UnicodeIsalnum(iCode);
++          bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
+           assert( (bToken==0 || bToken==1) ); 
+           assert( (bTokenChars==0 || bTokenChars==1) );
+           if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
+@@ -201846,6 +217387,21 @@
+   return;
+ }
+ 
++static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
++  const char *z = zCat;
++
++  while( *z ){
++    while( *z==' ' || *z=='\t' ) z++;
++    if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){
++      return SQLITE_ERROR;
++    }
++    while( *z!=' ' && *z!='\t' && *z!='\0' ) z++;
++  }
++
++  sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar);
++  return SQLITE_OK;
++}
++
+ /*
+ ** Create a "unicode61" tokenizer.
+ */
+@@ -201864,9 +217420,10 @@
+   }else{
+     p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
+     if( p ){
++      const char *zCat = "L* N* Co";
+       int i;
+       memset(p, 0, sizeof(Unicode61Tokenizer));
+-      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
++
+       p->bRemoveDiacritic = 1;
+       p->nFold = 64;
+       p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
+@@ -201873,7 +217430,19 @@
+       if( p->aFold==0 ){
+         rc = SQLITE_NOMEM;
+       }
++
++      /* Search for a "categories" argument */
+       for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
++        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
++          zCat = azArg[i+1];
++        }
++      }
++
++      if( rc==SQLITE_OK ){
++        rc = unicodeSetCategories(p, zCat);
++      }
++
++      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+         const char *zArg = azArg[i+1];
+         if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
+           if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
+@@ -201886,10 +217455,14 @@
+         }else
+         if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+           rc = fts5UnicodeAddExceptions(p, zArg, 0);
++        }else
++        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
++          /* no-op */
+         }else{
+           rc = SQLITE_ERROR;
+         }
+       }
++
+     }else{
+       rc = SQLITE_NOMEM;
+     }
+@@ -201908,8 +217481,10 @@
+ ** character (not a separator).
+ */
+ static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
+-  assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
+-  return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
++  return (
++    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
++    ^ fts5UnicodeIsException(p, iCode)
++  );
+ }
+ 
+ static int fts5UnicodeTokenize(
+@@ -202785,137 +218360,8 @@
+ 
+ /* #include <assert.h> */
+ 
+-/*
+-** Return true if the argument corresponds to a unicode codepoint
+-** classified as either a letter or a number. Otherwise false.
+-**
+-** The results are undefined if the value passed to this function
+-** is less than zero.
+-*/
+-static int sqlite3Fts5UnicodeIsalnum(int c){
+-  /* Each unsigned integer in the following array corresponds to a contiguous
+-  ** range of unicode codepoints that are not either letters or numbers (i.e.
+-  ** codepoints for which this function should return 0).
+-  **
+-  ** The most significant 22 bits in each 32-bit value contain the first 
+-  ** codepoint in the range. The least significant 10 bits are used to store
+-  ** the size of the range (always at least 1). In other words, the value 
+-  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
+-  ** C. It is not possible to represent a range larger than 1023 codepoints 
+-  ** using this format.
+-  */
+-  static const unsigned int aEntry[] = {
+-    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
+-    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
+-    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
+-    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
+-    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
+-    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
+-    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
+-    0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
+-    0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
+-    0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
+-    0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
+-    0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
+-    0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
+-    0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
+-    0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
+-    0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
+-    0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
+-    0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
+-    0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
+-    0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
+-    0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
+-    0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
+-    0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
+-    0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
+-    0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
+-    0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
+-    0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
+-    0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
+-    0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
+-    0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
+-    0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
+-    0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
+-    0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
+-    0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
+-    0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
+-    0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
+-    0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
+-    0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
+-    0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
+-    0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
+-    0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
+-    0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
+-    0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
+-    0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
+-    0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
+-    0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
+-    0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
+-    0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
+-    0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
+-    0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
+-    0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
+-    0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
+-    0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
+-    0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
+-    0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
+-    0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
+-    0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
+-    0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
+-    0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
+-    0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
+-    0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
+-    0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
+-    0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
+-    0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
+-    0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
+-    0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
+-    0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
+-    0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
+-    0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
+-    0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
+-    0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
+-    0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
+-    0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
+-    0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
+-    0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
+-    0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
+-    0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
+-    0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
+-    0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
+-    0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
+-    0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
+-    0x380400F0,
+-  };
+-  static const unsigned int aAscii[4] = {
+-    0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
+-  };
+ 
+-  if( (unsigned int)c<128 ){
+-    return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
+-  }else if( (unsigned int)c<(1<<22) ){
+-    unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
+-    int iRes = 0;
+-    int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+-    int iLo = 0;
+-    while( iHi>=iLo ){
+-      int iTest = (iHi + iLo) / 2;
+-      if( key >= aEntry[iTest] ){
+-        iRes = iTest;
+-        iLo = iTest+1;
+-      }else{
+-        iHi = iTest-1;
+-      }
+-    }
+-    assert( aEntry[0]<key );
+-    assert( key>=aEntry[iRes] );
+-    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
+-  }
+-  return 1;
+-}
+ 
+-
+ /*
+ ** If the argument is a codepoint corresponding to a lowercase letter
+ ** in the ASCII range with a diacritic added, return the codepoint
+@@ -203126,6 +218572,539 @@
+   return ret;
+ }
+ 
++
++#if 0
++static int sqlite3Fts5UnicodeNCat(void) { 
++  return 32;
++}
++#endif
++
++static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
++  aArray[0] = 1;
++  switch( zCat[0] ){
++    case 'C':
++          switch( zCat[1] ){
++            case 'c': aArray[1] = 1; break;
++            case 'f': aArray[2] = 1; break;
++            case 'n': aArray[3] = 1; break;
++            case 's': aArray[4] = 1; break;
++            case 'o': aArray[31] = 1; break;
++            case '*': 
++              aArray[1] = 1;
++              aArray[2] = 1;
++              aArray[3] = 1;
++              aArray[4] = 1;
++              aArray[31] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'L':
++          switch( zCat[1] ){
++            case 'l': aArray[5] = 1; break;
++            case 'm': aArray[6] = 1; break;
++            case 'o': aArray[7] = 1; break;
++            case 't': aArray[8] = 1; break;
++            case 'u': aArray[9] = 1; break;
++            case 'C': aArray[30] = 1; break;
++            case '*': 
++              aArray[5] = 1;
++              aArray[6] = 1;
++              aArray[7] = 1;
++              aArray[8] = 1;
++              aArray[9] = 1;
++              aArray[30] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'M':
++          switch( zCat[1] ){
++            case 'c': aArray[10] = 1; break;
++            case 'e': aArray[11] = 1; break;
++            case 'n': aArray[12] = 1; break;
++            case '*': 
++              aArray[10] = 1;
++              aArray[11] = 1;
++              aArray[12] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'N':
++          switch( zCat[1] ){
++            case 'd': aArray[13] = 1; break;
++            case 'l': aArray[14] = 1; break;
++            case 'o': aArray[15] = 1; break;
++            case '*': 
++              aArray[13] = 1;
++              aArray[14] = 1;
++              aArray[15] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'P':
++          switch( zCat[1] ){
++            case 'c': aArray[16] = 1; break;
++            case 'd': aArray[17] = 1; break;
++            case 'e': aArray[18] = 1; break;
++            case 'f': aArray[19] = 1; break;
++            case 'i': aArray[20] = 1; break;
++            case 'o': aArray[21] = 1; break;
++            case 's': aArray[22] = 1; break;
++            case '*': 
++              aArray[16] = 1;
++              aArray[17] = 1;
++              aArray[18] = 1;
++              aArray[19] = 1;
++              aArray[20] = 1;
++              aArray[21] = 1;
++              aArray[22] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'S':
++          switch( zCat[1] ){
++            case 'c': aArray[23] = 1; break;
++            case 'k': aArray[24] = 1; break;
++            case 'm': aArray[25] = 1; break;
++            case 'o': aArray[26] = 1; break;
++            case '*': 
++              aArray[23] = 1;
++              aArray[24] = 1;
++              aArray[25] = 1;
++              aArray[26] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'Z':
++          switch( zCat[1] ){
++            case 'l': aArray[27] = 1; break;
++            case 'p': aArray[28] = 1; break;
++            case 's': aArray[29] = 1; break;
++            case '*': 
++              aArray[27] = 1;
++              aArray[28] = 1;
++              aArray[29] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++  }
++  return 0;
++}
++
++static u16 aFts5UnicodeBlock[] = {
++    0,     1471,  1753,  1760,  1760,  1760,  1760,  1760,  1760,  1760,  
++    1760,  1760,  1760,  1760,  1760,  1763,  1765,  
++  };
++static u16 aFts5UnicodeMap[] = {
++    0,     32,    33,    36,    37,    40,    41,    42,    43,    44,    
++    45,    46,    48,    58,    60,    63,    65,    91,    92,    93,    
++    94,    95,    96,    97,    123,   124,   125,   126,   127,   160,   
++    161,   162,   166,   167,   168,   169,   170,   171,   172,   173,   
++    174,   175,   176,   177,   178,   180,   181,   182,   184,   185,   
++    186,   187,   188,   191,   192,   215,   216,   223,   247,   248,   
++    256,   312,   313,   329,   330,   377,   383,   385,   387,   388,   
++    391,   394,   396,   398,   402,   403,   405,   406,   409,   412,   
++    414,   415,   417,   418,   423,   427,   428,   431,   434,   436,   
++    437,   440,   442,   443,   444,   446,   448,   452,   453,   454,   
++    455,   456,   457,   458,   459,   460,   461,   477,   478,   496,   
++    497,   498,   499,   500,   503,   505,   506,   564,   570,   572,   
++    573,   575,   577,   580,   583,   584,   592,   660,   661,   688,   
++    706,   710,   722,   736,   741,   748,   749,   750,   751,   768,   
++    880,   884,   885,   886,   890,   891,   894,   900,   902,   903,   
++    904,   908,   910,   912,   913,   931,   940,   975,   977,   978,   
++    981,   984,   1008,  1012,  1014,  1015,  1018,  1020,  1021,  1072,  
++    1120,  1154,  1155,  1160,  1162,  1217,  1231,  1232,  1329,  1369,  
++    1370,  1377,  1417,  1418,  1423,  1425,  1470,  1471,  1472,  1473,  
++    1475,  1476,  1478,  1479,  1488,  1520,  1523,  1536,  1542,  1545,  
++    1547,  1548,  1550,  1552,  1563,  1566,  1568,  1600,  1601,  1611,  
++    1632,  1642,  1646,  1648,  1649,  1748,  1749,  1750,  1757,  1758,  
++    1759,  1765,  1767,  1769,  1770,  1774,  1776,  1786,  1789,  1791,  
++    1792,  1807,  1808,  1809,  1810,  1840,  1869,  1958,  1969,  1984,  
++    1994,  2027,  2036,  2038,  2039,  2042,  2048,  2070,  2074,  2075,  
++    2084,  2085,  2088,  2089,  2096,  2112,  2137,  2142,  2208,  2210,  
++    2276,  2304,  2307,  2308,  2362,  2363,  2364,  2365,  2366,  2369,  
++    2377,  2381,  2382,  2384,  2385,  2392,  2402,  2404,  2406,  2416,  
++    2417,  2418,  2425,  2433,  2434,  2437,  2447,  2451,  2474,  2482,  
++    2486,  2492,  2493,  2494,  2497,  2503,  2507,  2509,  2510,  2519,  
++    2524,  2527,  2530,  2534,  2544,  2546,  2548,  2554,  2555,  2561,  
++    2563,  2565,  2575,  2579,  2602,  2610,  2613,  2616,  2620,  2622,  
++    2625,  2631,  2635,  2641,  2649,  2654,  2662,  2672,  2674,  2677,  
++    2689,  2691,  2693,  2703,  2707,  2730,  2738,  2741,  2748,  2749,  
++    2750,  2753,  2759,  2761,  2763,  2765,  2768,  2784,  2786,  2790,  
++    2800,  2801,  2817,  2818,  2821,  2831,  2835,  2858,  2866,  2869,  
++    2876,  2877,  2878,  2879,  2880,  2881,  2887,  2891,  2893,  2902,  
++    2903,  2908,  2911,  2914,  2918,  2928,  2929,  2930,  2946,  2947,  
++    2949,  2958,  2962,  2969,  2972,  2974,  2979,  2984,  2990,  3006,  
++    3008,  3009,  3014,  3018,  3021,  3024,  3031,  3046,  3056,  3059,  
++    3065,  3066,  3073,  3077,  3086,  3090,  3114,  3125,  3133,  3134,  
++    3137,  3142,  3146,  3157,  3160,  3168,  3170,  3174,  3192,  3199,  
++    3202,  3205,  3214,  3218,  3242,  3253,  3260,  3261,  3262,  3263,  
++    3264,  3270,  3271,  3274,  3276,  3285,  3294,  3296,  3298,  3302,  
++    3313,  3330,  3333,  3342,  3346,  3389,  3390,  3393,  3398,  3402,  
++    3405,  3406,  3415,  3424,  3426,  3430,  3440,  3449,  3450,  3458,  
++    3461,  3482,  3507,  3517,  3520,  3530,  3535,  3538,  3542,  3544,  
++    3570,  3572,  3585,  3633,  3634,  3636,  3647,  3648,  3654,  3655,  
++    3663,  3664,  3674,  3713,  3716,  3719,  3722,  3725,  3732,  3737,  
++    3745,  3749,  3751,  3754,  3757,  3761,  3762,  3764,  3771,  3773,  
++    3776,  3782,  3784,  3792,  3804,  3840,  3841,  3844,  3859,  3860,  
++    3861,  3864,  3866,  3872,  3882,  3892,  3893,  3894,  3895,  3896,  
++    3897,  3898,  3899,  3900,  3901,  3902,  3904,  3913,  3953,  3967,  
++    3968,  3973,  3974,  3976,  3981,  3993,  4030,  4038,  4039,  4046,  
++    4048,  4053,  4057,  4096,  4139,  4141,  4145,  4146,  4152,  4153,  
++    4155,  4157,  4159,  4160,  4170,  4176,  4182,  4184,  4186,  4190,  
++    4193,  4194,  4197,  4199,  4206,  4209,  4213,  4226,  4227,  4229,  
++    4231,  4237,  4238,  4239,  4240,  4250,  4253,  4254,  4256,  4295,  
++    4301,  4304,  4347,  4348,  4349,  4682,  4688,  4696,  4698,  4704,  
++    4746,  4752,  4786,  4792,  4800,  4802,  4808,  4824,  4882,  4888,  
++    4957,  4960,  4969,  4992,  5008,  5024,  5120,  5121,  5741,  5743,  
++    5760,  5761,  5787,  5788,  5792,  5867,  5870,  5888,  5902,  5906,  
++    5920,  5938,  5941,  5952,  5970,  5984,  5998,  6002,  6016,  6068,  
++    6070,  6071,  6078,  6086,  6087,  6089,  6100,  6103,  6104,  6107,  
++    6108,  6109,  6112,  6128,  6144,  6150,  6151,  6155,  6158,  6160,  
++    6176,  6211,  6212,  6272,  6313,  6314,  6320,  6400,  6432,  6435,  
++    6439,  6441,  6448,  6450,  6451,  6457,  6464,  6468,  6470,  6480,  
++    6512,  6528,  6576,  6593,  6600,  6608,  6618,  6622,  6656,  6679,  
++    6681,  6686,  6688,  6741,  6742,  6743,  6744,  6752,  6753,  6754,  
++    6755,  6757,  6765,  6771,  6783,  6784,  6800,  6816,  6823,  6824,  
++    6912,  6916,  6917,  6964,  6965,  6966,  6971,  6972,  6973,  6978,  
++    6979,  6981,  6992,  7002,  7009,  7019,  7028,  7040,  7042,  7043,  
++    7073,  7074,  7078,  7080,  7082,  7083,  7084,  7086,  7088,  7098,  
++    7142,  7143,  7144,  7146,  7149,  7150,  7151,  7154,  7164,  7168,  
++    7204,  7212,  7220,  7222,  7227,  7232,  7245,  7248,  7258,  7288,  
++    7294,  7360,  7376,  7379,  7380,  7393,  7394,  7401,  7405,  7406,  
++    7410,  7412,  7413,  7424,  7468,  7531,  7544,  7545,  7579,  7616,  
++    7676,  7680,  7830,  7838,  7936,  7944,  7952,  7960,  7968,  7976,  
++    7984,  7992,  8000,  8008,  8016,  8025,  8027,  8029,  8031,  8033,  
++    8040,  8048,  8064,  8072,  8080,  8088,  8096,  8104,  8112,  8118,  
++    8120,  8124,  8125,  8126,  8127,  8130,  8134,  8136,  8140,  8141,  
++    8144,  8150,  8152,  8157,  8160,  8168,  8173,  8178,  8182,  8184,  
++    8188,  8189,  8192,  8203,  8208,  8214,  8216,  8217,  8218,  8219,  
++    8221,  8222,  8223,  8224,  8232,  8233,  8234,  8239,  8240,  8249,  
++    8250,  8251,  8255,  8257,  8260,  8261,  8262,  8263,  8274,  8275,  
++    8276,  8277,  8287,  8288,  8298,  8304,  8305,  8308,  8314,  8317,  
++    8318,  8319,  8320,  8330,  8333,  8334,  8336,  8352,  8400,  8413,  
++    8417,  8418,  8421,  8448,  8450,  8451,  8455,  8456,  8458,  8459,  
++    8462,  8464,  8467,  8468,  8469,  8470,  8472,  8473,  8478,  8484,  
++    8485,  8486,  8487,  8488,  8489,  8490,  8494,  8495,  8496,  8500,  
++    8501,  8505,  8506,  8508,  8510,  8512,  8517,  8519,  8522,  8523,  
++    8524,  8526,  8527,  8528,  8544,  8579,  8581,  8585,  8592,  8597,  
++    8602,  8604,  8608,  8609,  8611,  8612,  8614,  8615,  8622,  8623,  
++    8654,  8656,  8658,  8659,  8660,  8661,  8692,  8960,  8968,  8972,  
++    8992,  8994,  9001,  9002,  9003,  9084,  9085,  9115,  9140,  9180,  
++    9186,  9216,  9280,  9312,  9372,  9450,  9472,  9655,  9656,  9665,  
++    9666,  9720,  9728,  9839,  9840,  9985,  10088, 10089, 10090, 10091, 
++    10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, 
++    10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, 
++    10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, 
++    10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, 
++    10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, 
++    10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, 
++    11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, 
++    11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, 
++    11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, 
++    11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, 
++    11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, 
++    11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, 
++    11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, 
++    11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, 
++    11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, 
++    12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, 
++    12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, 
++    12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, 
++    12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, 
++    12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, 
++    12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, 
++    12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, 
++    40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, 
++    42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, 
++    42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, 
++    42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, 
++    43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, 
++    43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, 
++    43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, 
++    43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, 
++    43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, 
++    43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, 
++    43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, 
++    43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, 
++    43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, 
++    43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, 
++    44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, 
++    55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, 
++    64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, 
++    64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, 
++    65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, 
++    65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, 
++    65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, 
++    65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, 
++    65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, 
++    65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, 
++    65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, 
++    65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 
++    65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, 
++    65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, 
++    65532, 0,     13,    40,    60,    63,    80,    128,   256,   263,   
++    311,   320,   373,   377,   394,   400,   464,   509,   640,   672,   
++    768,   800,   816,   833,   834,   842,   896,   927,   928,   968,   
++    976,   977,   1024,  1064,  1104,  1184,  2048,  2056,  2058,  2103,  
++    2108,  2111,  2135,  2136,  2304,  2326,  2335,  2336,  2367,  2432,  
++    2494,  2560,  2561,  2565,  2572,  2576,  2581,  2585,  2616,  2623,  
++    2624,  2640,  2656,  2685,  2687,  2816,  2873,  2880,  2904,  2912,  
++    2936,  3072,  3680,  4096,  4097,  4098,  4099,  4152,  4167,  4178,  
++    4198,  4224,  4226,  4227,  4272,  4275,  4279,  4281,  4283,  4285,  
++    4286,  4304,  4336,  4352,  4355,  4391,  4396,  4397,  4406,  4416,  
++    4480,  4482,  4483,  4531,  4534,  4543,  4545,  4549,  4560,  5760,  
++    5803,  5804,  5805,  5806,  5808,  5814,  5815,  5824,  8192,  9216,  
++    9328,  12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, 
++    53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, 
++    53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, 
++    54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, 
++    54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, 
++    54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, 
++    54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, 
++    54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, 
++    55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, 
++    55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, 
++    60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, 
++    61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, 
++    61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, 
++    61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, 
++    61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, 
++    62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, 
++    63045, 63104, 63232, 0,     42710, 42752, 46900, 46912, 47133, 63488, 
++    1,     32,    256,   0,     65533, 
++  };
++static u16 aFts5UnicodeData[] = {
++    1025,  61,    117,   55,    117,   54,    50,    53,    57,    53,    
++    49,    85,    333,   85,    121,   85,    841,   54,    53,    50,    
++    56,    48,    56,    837,   54,    57,    50,    57,    1057,  61,    
++    53,    151,   58,    53,    56,    58,    39,    52,    57,    34,    
++    58,    56,    58,    57,    79,    56,    37,    85,    56,    47,    
++    39,    51,    111,   53,    745,   57,    233,   773,   57,    261,   
++    1822,  37,    542,   37,    1534,  222,   69,    73,    37,    126,   
++    126,   73,    69,    137,   37,    73,    37,    105,   101,   73,    
++    37,    73,    37,    190,   158,   37,    126,   126,   73,    37,    
++    126,   94,    37,    39,    94,    69,    135,   41,    40,    37,    
++    41,    40,    37,    41,    40,    37,    542,   37,    606,   37,    
++    41,    40,    37,    126,   73,    37,    1886,  197,   73,    37,    
++    73,    69,    126,   105,   37,    286,   2181,  39,    869,   582,   
++    152,   390,   472,   166,   248,   38,    56,    38,    568,   3596,  
++    158,   38,    56,    94,    38,    101,   53,    88,    41,    53,    
++    105,   41,    73,    37,    553,   297,   1125,  94,    37,    105,   
++    101,   798,   133,   94,    57,    126,   94,    37,    1641,  1541,  
++    1118,  58,    172,   75,    1790,  478,   37,    2846,  1225,  38,    
++    213,   1253,  53,    49,    55,    1452,  49,    44,    53,    76,    
++    53,    76,    53,    44,    871,   103,   85,    162,   121,   85,    
++    55,    85,    90,    364,   53,    85,    1031,  38,    327,   684,   
++    333,   149,   71,    44,    3175,  53,    39,    236,   34,    58,    
++    204,   70,    76,    58,    140,   71,    333,   103,   90,    39,    
++    469,   34,    39,    44,    967,   876,   2855,  364,   39,    333,   
++    1063,  300,   70,    58,    117,   38,    711,   140,   38,    300,   
++    38,    108,   38,    172,   501,   807,   108,   53,    39,    359,   
++    876,   108,   42,    1735,  44,    42,    44,    39,    106,   268,   
++    138,   44,    74,    39,    236,   327,   76,    85,    333,   53,    
++    38,    199,   231,   44,    74,    263,   71,    711,   231,   39,    
++    135,   44,    39,    106,   140,   74,    74,    44,    39,    42,    
++    71,    103,   76,    333,   71,    87,    207,   58,    55,    76,    
++    42,    199,   71,    711,   231,   71,    71,    71,    44,    106,   
++    76,    76,    108,   44,    135,   39,    333,   76,    103,   44,    
++    76,    42,    295,   103,   711,   231,   71,    167,   44,    39,    
++    106,   172,   76,    42,    74,    44,    39,    71,    76,    333,   
++    53,    55,    44,    74,    263,   71,    711,   231,   71,    167,   
++    44,    39,    42,    44,    42,    140,   74,    74,    44,    44,    
++    42,    71,    103,   76,    333,   58,    39,    207,   44,    39,    
++    199,   103,   135,   71,    39,    71,    71,    103,   391,   74,    
++    44,    74,    106,   106,   44,    39,    42,    333,   111,   218,   
++    55,    58,    106,   263,   103,   743,   327,   167,   39,    108,   
++    138,   108,   140,   76,    71,    71,    76,    333,   239,   58,    
++    74,    263,   103,   743,   327,   167,   44,    39,    42,    44,    
++    170,   44,    74,    74,    76,    74,    39,    71,    76,    333,   
++    71,    74,    263,   103,   1319,  39,    106,   140,   106,   106,   
++    44,    39,    42,    71,    76,    333,   207,   58,    199,   74,    
++    583,   775,   295,   39,    231,   44,    106,   108,   44,    266,   
++    74,    53,    1543,  44,    71,    236,   55,    199,   38,    268,   
++    53,    333,   85,    71,    39,    71,    39,    39,    135,   231,   
++    103,   39,    39,    71,    135,   44,    71,    204,   76,    39,    
++    167,   38,    204,   333,   135,   39,    122,   501,   58,    53,    
++    122,   76,    218,   333,   335,   58,    44,    58,    44,    58,    
++    44,    54,    50,    54,    50,    74,    263,   1159,  460,   42,    
++    172,   53,    76,    167,   364,   1164,  282,   44,    218,   90,    
++    181,   154,   85,    1383,  74,    140,   42,    204,   42,    76,    
++    74,    76,    39,    333,   213,   199,   74,    76,    135,   108,   
++    39,    106,   71,    234,   103,   140,   423,   44,    74,    76,    
++    202,   44,    39,    42,    333,   106,   44,    90,    1225,  41,    
++    41,    1383,  53,    38,    10631, 135,   231,   39,    135,   1319,  
++    135,   1063,  135,   231,   39,    135,   487,   1831,  135,   2151,  
++    108,   309,   655,   519,   346,   2727,  49,    19847, 85,    551,   
++    61,    839,   54,    50,    2407,  117,   110,   423,   135,   108,   
++    583,   108,   85,    583,   76,    423,   103,   76,    1671,  76,    
++    42,    236,   266,   44,    74,    364,   117,   38,    117,   55,    
++    39,    44,    333,   335,   213,   49,    149,   108,   61,    333,   
++    1127,  38,    1671,  1319,  44,    39,    2247,  935,   108,   138,   
++    76,    106,   74,    44,    202,   108,   58,    85,    333,   967,   
++    167,   1415,  554,   231,   74,    333,   47,    1114,  743,   76,    
++    106,   85,    1703,  42,    44,    42,    236,   44,    42,    44,    
++    74,    268,   202,   332,   44,    333,   333,   245,   38,    213,   
++    140,   42,    1511,  44,    42,    172,   42,    44,    170,   44,    
++    74,    231,   333,   245,   346,   300,   314,   76,    42,    967,   
++    42,    140,   74,    76,    42,    44,    74,    71,    333,   1415,  
++    44,    42,    76,    106,   44,    42,    108,   74,    149,   1159,  
++    266,   268,   74,    76,    181,   333,   103,   333,   967,   198,   
++    85,    277,   108,   53,    428,   42,    236,   135,   44,    135,   
++    74,    44,    71,    1413,  2022,  421,   38,    1093,  1190,  1260,  
++    140,   4830,  261,   3166,  261,   265,   197,   201,   261,   265,   
++    261,   265,   197,   201,   261,   41,    41,    41,    94,    229,   
++    265,   453,   261,   264,   261,   264,   261,   264,   165,   69,    
++    137,   40,    56,    37,    120,   101,   69,    137,   40,    120,   
++    133,   69,    137,   120,   261,   169,   120,   101,   69,    137,   
++    40,    88,    381,   162,   209,   85,    52,    51,    54,    84,    
++    51,    54,    52,    277,   59,    60,    162,   61,    309,   52,    
++    51,    149,   80,    117,   57,    54,    50,    373,   57,    53,    
++    48,    341,   61,    162,   194,   47,    38,    207,   121,   54,    
++    50,    38,    335,   121,   54,    50,    422,   855,   428,   139,   
++    44,    107,   396,   90,    41,    154,   41,    90,    37,    105,   
++    69,    105,   37,    58,    41,    90,    57,    169,   218,   41,    
++    58,    41,    58,    41,    58,    137,   58,    37,    137,   37,    
++    135,   37,    90,    69,    73,    185,   94,    101,   58,    57,    
++    90,    37,    58,    527,   1134,  94,    142,   47,    185,   186,   
++    89,    154,   57,    90,    57,    90,    57,    250,   57,    1018,  
++    89,    90,    57,    58,    57,    1018,  8601,  282,   153,   666,   
++    89,    250,   54,    50,    2618,  57,    986,   825,   1306,  217,   
++    602,   1274,  378,   1935,  2522,  719,   5882,  57,    314,   57,    
++    1754,  281,   3578,  57,    4634,  3322,  54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
++    975,   1434,  185,   54,    50,    1017,  54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    537,   8218,  4217,  54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
++    50,    2041,  54,    50,    54,    50,    1049,  54,    50,    8281,  
++    1562,  697,   90,    217,   346,   1513,  1509,  126,   73,    69,    
++    254,   105,   37,    94,    37,    94,    165,   70,    105,   37,    
++    3166,  37,    218,   158,   108,   94,    149,   47,    85,    1221,  
++    37,    37,    1799,  38,    53,    44,    743,   231,   231,   231,   
++    231,   231,   231,   231,   231,   1036,  85,    52,    51,    52,    
++    51,    117,   52,    51,    53,    52,    51,    309,   49,    85,    
++    49,    53,    52,    51,    85,    52,    51,    54,    50,    54,    
++    50,    54,    50,    54,    50,    181,   38,    341,   81,    858,   
++    2874,  6874,  410,   61,    117,   58,    38,    39,    46,    54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    90,    
++    54,    50,    54,    50,    54,    50,    54,    50,    49,    54,    
++    82,    58,    302,   140,   74,    49,    166,   90,    110,   38,    
++    39,    53,    90,    2759,  76,    88,    70,    39,    49,    2887,  
++    53,    102,   39,    1319,  3015,  90,    143,   346,   871,   1178,  
++    519,   1018,  335,   986,   271,   58,    495,   1050,  335,   1274,  
++    495,   2042,  8218,  39,    39,    2074,  39,    39,    679,   38,    
++    36583, 1786,  1287,  198,   85,    8583,  38,    117,   519,   333,   
++    71,    1502,  39,    44,    107,   53,    332,   53,    38,    798,   
++    44,    2247,  334,   76,    213,   760,   294,   88,    478,   69,    
++    2014,  38,    261,   190,   350,   38,    88,    158,   158,   382,   
++    70,    37,    231,   44,    103,   44,    135,   44,    743,   74,    
++    76,    42,    154,   207,   90,    55,    58,    1671,  149,   74,    
++    1607,  522,   44,    85,    333,   588,   199,   117,   39,    333,   
++    903,   268,   85,    743,   364,   74,    53,    935,   108,   42,    
++    1511,  44,    74,    140,   74,    44,    138,   437,   38,    333,   
++    85,    1319,  204,   74,    76,    74,    76,    103,   44,    263,   
++    44,    42,    333,   149,   519,   38,    199,   122,   39,    42,    
++    1543,  44,    39,    108,   71,    76,    167,   76,    39,    44,    
++    39,    71,    38,    85,    359,   42,    76,    74,    85,    39,    
++    70,    42,    44,    199,   199,   199,   231,   231,   1127,  74,    
++    44,    74,    44,    74,    53,    42,    44,    333,   39,    39,    
++    743,   1575,  36,    68,    68,    36,    63,    63,    11719, 3399,  
++    229,   165,   39,    44,    327,   57,    423,   167,   39,    71,    
++    71,    3463,  536,   11623, 54,    50,    2055,  1735,  391,   55,    
++    58,    524,   245,   54,    50,    53,    236,   53,    81,    80,    
++    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    85,    54,    50,    149,   
++    112,   117,   149,   49,    54,    50,    54,    50,    54,    50,    
++    117,   57,    49,    121,   53,    55,    85,    167,   4327,  34,    
++    117,   55,    117,   54,    50,    53,    57,    53,    49,    85,    
++    333,   85,    121,   85,    841,   54,    53,    50,    56,    48,    
++    56,    837,   54,    57,    50,    57,    54,    50,    53,    54,    
++    50,    85,    327,   38,    1447,  70,    999,   199,   199,   199,   
++    103,   87,    57,    56,    58,    87,    58,    153,   90,    98,    
++    90,    391,   839,   615,   71,    487,   455,   3943,  117,   1455,  
++    314,   1710,  143,   570,   47,    410,   1466,  44,    935,   1575,  
++    999,   143,   551,   46,    263,   46,    967,   53,    1159,  263,   
++    53,    174,   1289,  1285,  2503,  333,   199,   39,    1415,  71,    
++    39,    743,   53,    271,   711,   207,   53,    839,   53,    1799,  
++    71,    39,    108,   76,    140,   135,   103,   871,   108,   44,    
++    271,   309,   935,   79,    53,    1735,  245,   711,   271,   615,   
++    271,   2343,  1007,  42,    44,    42,    1703,  492,   245,   655,   
++    333,   76,    42,    1447,  106,   140,   74,    76,    85,    34,    
++    149,   807,   333,   108,   1159,  172,   42,    268,   333,   149,   
++    76,    42,    1543,  106,   300,   74,    135,   149,   333,   1383,  
++    44,    42,    44,    74,    204,   42,    44,    333,   28135, 3182,  
++    149,   34279, 18215, 2215,  39,    1482,  140,   422,   71,    7898,  
++    1274,  1946,  74,    108,   122,   202,   258,   268,   90,    236,   
++    986,   140,   1562,  2138,  108,   58,    2810,  591,   841,   837,   
++    841,   229,   581,   841,   837,   41,    73,    41,    73,    137,   
++    265,   133,   37,    229,   357,   841,   837,   73,    137,   265,   
++    233,   837,   73,    137,   169,   41,    233,   837,   841,   837,   
++    841,   837,   841,   837,   841,   837,   841,   837,   841,   901,   
++    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
++    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
++    809,   57,    805,   57,    197,   94,    1613,  135,   871,   71,    
++    39,    39,    327,   135,   39,    39,    39,    39,    39,    39,    
++    103,   71,    39,    39,    39,    39,    39,    39,    71,    39,    
++    135,   231,   135,   135,   39,    327,   551,   103,   167,   551,   
++    89,    1434,  3226,  506,   474,   506,   506,   367,   1018,  1946,  
++    1402,  954,   1402,  314,   90,    1082,  218,   2266,  666,   1210,  
++    186,   570,   2042,  58,    5850,  154,   2010,  154,   794,   2266,  
++    378,   2266,  3738,  39,    39,    39,    39,    39,    39,    17351, 
++    34,    3074,  7692,  63,    63,    
++  };
++
++static int sqlite3Fts5UnicodeCategory(int iCode) { 
++  int iRes = -1;
++  int iHi;
++  int iLo;
++  int ret;
++  u16 iKey;
++
++  if( iCode>=(1<<20) ){
++    return 0;
++  }
++  iLo = aFts5UnicodeBlock[(iCode>>16)];
++  iHi = aFts5UnicodeBlock[1+(iCode>>16)];
++  iKey = (iCode & 0xFFFF);
++  while( iHi>iLo ){
++    int iTest = (iHi + iLo) / 2;
++    assert( iTest>=iLo && iTest<iHi );
++    if( iKey>=aFts5UnicodeMap[iTest] ){
++      iRes = iTest;
++      iLo = iTest+1;
++    }else{
++      iHi = iTest;
++    }
++  }
++
++  if( iRes<0 ) return 0;
++  if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
++  ret = aFts5UnicodeData[iRes] & 0x1F;
++  if( ret!=30 ) return ret;
++  return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9;
++}
++
++static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
++  int i = 0;
++  int iTbl = 0;
++  while( i<128 ){
++    int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
++    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
++    for(; i<128 && i<n; i++){
++      aAscii[i] = (u8)bToken;
++    }
++    iTbl++;
++  }
++}
++
++
+ /*
+ ** 2015 May 30
+ **
+@@ -203503,6 +219482,11 @@
+ **   the number of fts5 rows that contain at least one instance of term
+ **   $term. Field $cnt is set to the total number of instances of term 
+ **   $term in the database.
++**
++** instance:
++**     CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
++**
++**   One row for each term instance in the database. 
+ */
+ 
+ 
+@@ -203518,7 +219502,7 @@
+   char *zFts5Db;                  /* Db containing fts5 table */
+   sqlite3 *db;                    /* Database handle */
+   Fts5Global *pGlobal;            /* FTS5 global object for this database */
+-  int eType;                      /* FTS5_VOCAB_COL or ROW */
++  int eType;                      /* FTS5_VOCAB_COL, ROW or INSTANCE */
+ };
+ 
+ struct Fts5VocabCursor {
+@@ -203538,16 +219522,22 @@
+   i64 *aCnt;
+   i64 *aDoc;
+ 
+-  /* Output values used by 'row' and 'col' tables */
++  /* Output values used by all tables. */
+   i64 rowid;                      /* This table's current rowid value */
+   Fts5Buffer term;                /* Current value of 'term' column */
++
++  /* Output values Used by 'instance' tables only */
++  i64 iInstPos;
++  int iInstOff;
+ };
+ 
+-#define FTS5_VOCAB_COL    0
+-#define FTS5_VOCAB_ROW    1
++#define FTS5_VOCAB_COL      0
++#define FTS5_VOCAB_ROW      1
++#define FTS5_VOCAB_INSTANCE 2
+ 
+ #define FTS5_VOCAB_COL_SCHEMA  "term, col, doc, cnt"
+ #define FTS5_VOCAB_ROW_SCHEMA  "term, doc, cnt"
++#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset"
+ 
+ /*
+ ** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
+@@ -203575,6 +219565,9 @@
+     if( sqlite3_stricmp(zCopy, "row")==0 ){
+       *peType = FTS5_VOCAB_ROW;
+     }else
++    if( sqlite3_stricmp(zCopy, "instance")==0 ){
++      *peType = FTS5_VOCAB_INSTANCE;
++    }else
+     {
+       *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
+       rc = SQLITE_ERROR;
+@@ -203635,7 +219628,8 @@
+ ){
+   const char *azSchema[] = { 
+     "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA  ")", 
+-    "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA  ")"
++    "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA  ")",
++    "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")"
+   };
+ 
+   Fts5VocabTable *pRet = 0;
+@@ -203709,6 +219703,15 @@
+ 
+ /* 
+ ** Implementation of the xBestIndex method.
++**
++** Only constraints of the form:
++**
++**     term <= ?
++**     term == ?
++**     term >= ?
++**
++** are interpreted. Less-than and less-than-or-equal are treated 
++** identically, as are greater-than and greater-than-or-equal.
+ */
+ static int fts5VocabBestIndexMethod(
+   sqlite3_vtab *pUnused,
+@@ -203852,7 +219855,57 @@
+   return SQLITE_OK;
+ }
+ 
++static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
++  int rc = SQLITE_OK;
++  
++  if( sqlite3Fts5IterEof(pCsr->pIter) ){
++    pCsr->bEof = 1;
++  }else{
++    const char *zTerm;
++    int nTerm;
++    zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
++    if( pCsr->nLeTerm>=0 ){
++      int nCmp = MIN(nTerm, pCsr->nLeTerm);
++      int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
++      if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
++        pCsr->bEof = 1;
++      }
++    }
+ 
++    sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
++  }
++  return rc;
++}
++
++static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
++  int eDetail = pCsr->pConfig->eDetail;
++  int rc = SQLITE_OK;
++  Fts5IndexIter *pIter = pCsr->pIter;
++  i64 *pp = &pCsr->iInstPos;
++  int *po = &pCsr->iInstOff;
++  
++  assert( sqlite3Fts5IterEof(pIter)==0 );
++  assert( pCsr->bEof==0 );
++  while( eDetail==FTS5_DETAIL_NONE
++      || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) 
++  ){
++    pCsr->iInstPos = 0;
++    pCsr->iInstOff = 0;
++
++    rc = sqlite3Fts5IterNextScan(pCsr->pIter);
++    if( rc==SQLITE_OK ){
++      rc = fts5VocabInstanceNewTerm(pCsr);
++      if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
++    }
++    if( rc ){
++      pCsr->bEof = 1;
++      break;
++    }
++  }
++
++  return rc;
++}
++
+ /*
+ ** Advance the cursor to the next row in the table.
+ */
+@@ -203864,6 +219917,10 @@
+ 
+   pCsr->rowid++;
+ 
++  if( pTab->eType==FTS5_VOCAB_INSTANCE ){
++    return fts5VocabInstanceNext(pCsr);
++  }
++
+   if( pTab->eType==FTS5_VOCAB_COL ){
+     for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
+       if( pCsr->aDoc[pCsr->iCol] ) break;
+@@ -203870,7 +219927,7 @@
+     }
+   }
+ 
+-  if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
++  if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){
+     if( sqlite3Fts5IterEof(pCsr->pIter) ){
+       pCsr->bEof = 1;
+     }else{
+@@ -203894,6 +219951,7 @@
+ 
+       assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
+       while( rc==SQLITE_OK ){
++        int eDetail = pCsr->pConfig->eDetail;
+         const u8 *pPos; int nPos;   /* Position list */
+         i64 iPos = 0;               /* 64-bit position read from poslist */
+         int iOff = 0;               /* Current offset within position list */
+@@ -203900,16 +219958,19 @@
+ 
+         pPos = pCsr->pIter->pData;
+         nPos = pCsr->pIter->nData;
+-        switch( pCsr->pConfig->eDetail ){
+-          case FTS5_DETAIL_FULL:
+-            pPos = pCsr->pIter->pData;
+-            nPos = pCsr->pIter->nData;
+-            if( pTab->eType==FTS5_VOCAB_ROW ){
++
++        switch( pTab->eType ){
++          case FTS5_VOCAB_ROW:
++            if( eDetail==FTS5_DETAIL_FULL ){
+               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+                 pCsr->aCnt[0]++;
+               }
+-              pCsr->aDoc[0]++;
+-            }else{
++            }
++            pCsr->aDoc[0]++;
++            break;
++
++          case FTS5_VOCAB_COL:
++            if( eDetail==FTS5_DETAIL_FULL ){
+               int iCol = -1;
+               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
+                 int ii = FTS5_POS2COLUMN(iPos);
+@@ -203923,13 +219984,7 @@
+                   iCol = ii;
+                 }
+               }
+-            }
+-            break;
+-
+-          case FTS5_DETAIL_COLUMNS:
+-            if( pTab->eType==FTS5_VOCAB_ROW ){
+-              pCsr->aDoc[0]++;
+-            }else{
++            }else if( eDetail==FTS5_DETAIL_COLUMNS ){
+               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
+                 assert_nc( iPos>=0 && iPos<nCol );
+                 if( iPos>=nCol ){
+@@ -203938,12 +219993,14 @@
+                 }
+                 pCsr->aDoc[iPos]++;
+               }
++            }else{
++              assert( eDetail==FTS5_DETAIL_NONE );
++              pCsr->aDoc[0]++;
+             }
+             break;
+ 
+-          default: 
+-            assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
+-            pCsr->aDoc[0]++;
++          default:
++            assert( pTab->eType==FTS5_VOCAB_INSTANCE );
+             break;
+         }
+ 
+@@ -203950,6 +220007,7 @@
+         if( rc==SQLITE_OK ){
+           rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+         }
++        if( pTab->eType==FTS5_VOCAB_INSTANCE ) break;
+ 
+         if( rc==SQLITE_OK ){
+           zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+@@ -203979,7 +220037,9 @@
+   int nUnused,                    /* Number of elements in apVal */
+   sqlite3_value **apVal           /* Arguments for the indexing scheme */
+ ){
++  Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
+   Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
++  int eType = pTab->eType;
+   int rc = SQLITE_OK;
+ 
+   int iVal = 0;
+@@ -204019,11 +220079,16 @@
+     }
+   }
+ 
+-
+   if( rc==SQLITE_OK ){
+     rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
+   }
+-  if( rc==SQLITE_OK ){
++  if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
++    rc = fts5VocabInstanceNewTerm(pCsr);
++  }
++  if( rc==SQLITE_OK 
++   && !pCsr->bEof 
++   && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
++  ){
+     rc = fts5VocabNextMethod(pCursor);
+   }
+ 
+@@ -204065,7 +220130,7 @@
+     }else{
+       iVal = pCsr->aCnt[pCsr->iCol];
+     }
+-  }else{
++  }else if( eType==FTS5_VOCAB_ROW ){
+     assert( iCol==1 || iCol==2 );
+     if( iCol==1 ){
+       iVal = pCsr->aDoc[0];
+@@ -204072,6 +220137,34 @@
+     }else{
+       iVal = pCsr->aCnt[0];
+     }
++  }else{
++    assert( eType==FTS5_VOCAB_INSTANCE );
++    switch( iCol ){
++      case 1:
++        sqlite3_result_int64(pCtx, pCsr->pIter->iRowid);
++        break;
++      case 2: {
++        int ii = -1;
++        if( eDetail==FTS5_DETAIL_FULL ){
++          ii = FTS5_POS2COLUMN(pCsr->iInstPos);
++        }else if( eDetail==FTS5_DETAIL_COLUMNS ){
++          ii = (int)pCsr->iInstPos;
++        }
++        if( ii>=0 && ii<pCsr->pConfig->nCol ){
++          const char *z = pCsr->pConfig->azCol[ii];
++          sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
++        }
++        break;
++      }
++      default: {
++        assert( iCol==3 );
++        if( eDetail==FTS5_DETAIL_FULL ){
++          int ii = FTS5_POS2OFFSET(pCsr->iInstPos);
++          sqlite3_result_int(pCtx, ii);
++        }
++        break;
++      }
++    }
+   }
+ 
+   if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
+@@ -204117,6 +220210,7 @@
+     /* xSavepoint    */ 0,
+     /* xRelease      */ 0,
+     /* xRollbackTo   */ 0,
++    /* xShadowName   */ 0
+   };
+   void *p = (void*)pGlobal;
+ 
+@@ -204124,8 +220218,6 @@
+ }
+ 
+ 
+-
+-
+     
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
+ 
+@@ -204399,6 +220491,7 @@
+   0,                         /* xSavepoint */
+   0,                         /* xRelease */
+   0,                         /* xRollbackTo */
++  0,                         /* xShadowName */
+ };
+ 
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -204431,3 +220524,10 @@
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
+ 
+ /************** End of stmt.c ************************************************/
++#if __LINE__!=220527
++#undef SQLITE_SOURCE_ID
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
++#endif
++/* Return the source-id for this library */
++SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
++/************************** End of sqlite3.c ******************************/
+--- contrib/sqlite3/sqlite3.h.orig
++++ contrib/sqlite3/sqlite3.h
+@@ -115,15 +115,17 @@
+ ** 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 a SHA1
+-** or SHA3-256 hash of the entire source tree.
++** or SHA3-256 hash of the entire source tree.  If the source code has
++** been edited in any way since it was last checked in, then the last
++** four hexadecimal digits of the hash may be modified.
+ **
+ ** See also: [sqlite3_libversion()],
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.20.0"
+-#define SQLITE_VERSION_NUMBER 3020000
+-#define SQLITE_SOURCE_ID      "2017-08-01 13:24:15 9501e22dfeebdcefa783575e47c60b514d7c2e0cad73b2a496c0bc4b680900a8"
++#define SQLITE_VERSION        "3.26.0"
++#define SQLITE_VERSION_NUMBER 3026000
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+@@ -139,7 +141,7 @@
+ **
+ ** <blockquote><pre>
+ ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
++** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+ ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
+ ** </pre></blockquote>)^
+ **
+@@ -149,9 +151,11 @@
+ ** function is provided for use in DLLs since DLL users usually do not have
+ ** direct access to string constants within the DLL.  ^The
+ ** sqlite3_libversion_number() function returns an integer equal to
+-** [SQLITE_VERSION_NUMBER].  ^The sqlite3_sourceid() function returns 
++** [SQLITE_VERSION_NUMBER].  ^(The sqlite3_sourceid() function returns 
+ ** a pointer to a string constant whose value is the same as the 
+-** [SQLITE_SOURCE_ID] C preprocessor macro.
++** [SQLITE_SOURCE_ID] C preprocessor macro.  Except if SQLite is built
++** using an edited copy of [the amalgamation], then the last four characters
++** of the hash might be different from [SQLITE_SOURCE_ID].)^
+ **
+ ** See also: [sqlite_version()] and [sqlite_source_id()].
+ */
+@@ -432,7 +436,7 @@
+ #define SQLITE_FULL        13   /* Insertion failed because database is full */
+ #define SQLITE_CANTOPEN    14   /* Unable to open the database file */
+ #define SQLITE_PROTOCOL    15   /* Database lock protocol error */
+-#define SQLITE_EMPTY       16   /* Not used */
++#define SQLITE_EMPTY       16   /* Internal use only */
+ #define SQLITE_SCHEMA      17   /* The database schema changed */
+ #define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */
+ #define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */
+@@ -466,6 +470,9 @@
+ ** the most recent error can be obtained using
+ ** [sqlite3_extended_errcode()].
+ */
++#define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
++#define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
++#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+ #define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+ #define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+ #define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+@@ -494,7 +501,11 @@
+ #define SQLITE_IOERR_CONVPATH          (SQLITE_IOERR | (26<<8))
+ #define SQLITE_IOERR_VNODE             (SQLITE_IOERR | (27<<8))
+ #define SQLITE_IOERR_AUTH              (SQLITE_IOERR | (28<<8))
++#define SQLITE_IOERR_BEGIN_ATOMIC      (SQLITE_IOERR | (29<<8))
++#define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
++#define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
++#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+ #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+@@ -501,11 +512,15 @@
+ #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
+ #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+ #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
++#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+ #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
++#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
+ #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
+ #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+ #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+ #define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
++#define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
++#define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
+ #define SQLITE_ABORT_ROLLBACK          (SQLITE_ABORT | (2<<8))
+ #define SQLITE_CONSTRAINT_CHECK        (SQLITE_CONSTRAINT | (1<<8))
+ #define SQLITE_CONSTRAINT_COMMITHOOK   (SQLITE_CONSTRAINT | (2<<8))
+@@ -580,6 +595,11 @@
+ ** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
+ ** read-only media and cannot be changed even by processes with
+ ** elevated privileges.
++**
++** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
++** filesystem supports doing multiple write operations atomically when those
++** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
++** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+ */
+ #define SQLITE_IOCAP_ATOMIC                 0x00000001
+ #define SQLITE_IOCAP_ATOMIC512              0x00000002
+@@ -595,6 +615,7 @@
+ #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
+ #define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
+ #define SQLITE_IOCAP_IMMUTABLE              0x00002000
++#define SQLITE_IOCAP_BATCH_ATOMIC           0x00004000
+ 
+ /*
+ ** CAPI3REF: File Locking Levels
+@@ -729,6 +750,7 @@
+ ** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+ ** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+ ** <li> [SQLITE_IOCAP_IMMUTABLE]
++** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
+ ** </ul>
+ **
+ ** The SQLITE_IOCAP_ATOMIC property means that all writes of
+@@ -866,7 +888,8 @@
+ ** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
+ ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+ ** persistent [WAL | Write Ahead Log] setting.  By default, the auxiliary
+-** write ahead log and shared memory files used for transaction control
++** write ahead log ([WAL file]) and shared memory
++** files used for transaction control
+ ** are automatically deleted when the latest connection to the database
+ ** closes.  Setting persistent WAL mode causes those files to persist after
+ ** close.  Persisting the files is useful when other processes that do not
+@@ -1012,6 +1035,66 @@
+ ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
+ ** the RBU extension only.  All other VFS should return SQLITE_NOTFOUND for
+ ** this opcode.  
++**
++** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
++** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
++** the file descriptor is placed in "batch write mode", which
++** means all subsequent write operations will be deferred and done
++** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].  Systems
++** that do not support batch atomic writes will return SQLITE_NOTFOUND.
++** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
++** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
++** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
++** no VFS interface calls on the same [sqlite3_file] file descriptor
++** except for calls to the xWrite method and the xFileControl method
++** with [SQLITE_FCNTL_SIZE_HINT].
++**
++** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
++** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
++** operations since the previous successful call to 
++** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
++** This file control returns [SQLITE_OK] if and only if the writes were
++** all performed successfully and have been committed to persistent storage.
++** ^Regardless of whether or not it is successful, this file control takes
++** the file descriptor out of batch write mode so that all subsequent
++** write operations are independent.
++** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
++** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
++**
++** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
++** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
++** operations since the previous successful call to 
++** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
++** ^This file control takes the file descriptor out of batch write mode
++** so that all subsequent write operations are independent.
++** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
++** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
++**
++** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
++** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
++** a file lock using the xLock or xShmLock methods of the VFS to wait
++** for up to M milliseconds before failing, where M is the single 
++** unsigned integer parameter.
++**
++** <li>[[SQLITE_FCNTL_DATA_VERSION]]
++** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
++** a database file.  The argument is a pointer to a 32-bit unsigned integer.
++** The "data version" for the pager is written into the pointer.  The
++** "data version" changes whenever any change occurs to the corresponding
++** database file, either through SQL statements on the same database
++** connection or through transactions committed by separate database
++** connections possibly in other processes. The [sqlite3_total_changes()]
++** interface can be used to find if any database on the connection has changed,
++** but that interface responds to changes on TEMP as well as MAIN and does
++** not provide a mechanism to detect changes to MAIN only.  Also, the
++** [sqlite3_total_changes()] interface responds to internal changes only and
++** omits changes made by other database connections.  The
++** [PRAGMA data_version] command provide a mechanism to detect changes to
++** a single attached database that occur due to other database connections,
++** but omits changes implemented by the database connection on which it is
++** called.  This file control is the only mechanism to detect changes that
++** happen either internally or externally and that are associated with
++** a particular attached database.
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -1043,6 +1126,11 @@
+ #define SQLITE_FCNTL_JOURNAL_POINTER        28
+ #define SQLITE_FCNTL_WIN32_GET_HANDLE       29
+ #define SQLITE_FCNTL_PDB                    30
++#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
++#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
++#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
++#define SQLITE_FCNTL_LOCK_TIMEOUT           34
++#define SQLITE_FCNTL_DATA_VERSION           35
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -1080,12 +1168,18 @@
+ ** in the name of the object stands for "virtual file system".  See
+ ** the [VFS | VFS documentation] for further information.
+ **
+-** The value of the iVersion field is initially 1 but may be larger in
+-** future versions of SQLite.  Additional fields may be appended to this
+-** object when the iVersion value is increased.  Note that the structure
+-** of the sqlite3_vfs object changes in the transaction between
+-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
+-** modified.
++** The VFS interface is sometimes extended by adding new methods onto
++** the end.  Each time such an extension occurs, the iVersion field
++** is incremented.  The iVersion value started out as 1 in
++** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
++** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
++** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6].  Additional fields
++** may be appended to the sqlite3_vfs object and the iVersion value
++** may increase again in future versions of SQLite.
++** Note that the structure
++** of the sqlite3_vfs object changes in the transition from
++** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
++** and yet the iVersion field was not modified.
+ **
+ ** The szOsFile field is the size of the subclassed [sqlite3_file]
+ ** structure used by this VFS.  mxPathname is the maximum length of
+@@ -1613,6 +1707,16 @@
+ ** routines with a wrapper that simulations memory allocation failure or
+ ** tracks memory usage, for example. </dd>
+ **
++** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
++** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
++** type int, interpreted as a boolean, which if true provides a hint to
++** SQLite that it should avoid large memory allocations if possible.
++** SQLite will run faster if it is free to make large memory allocations,
++** but some application might prefer to run slower in exchange for
++** guarantees about memory fragmentation that are possible if large
++** allocations are avoided.  This hint is normally off.
++** </dd>
++**
+ ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
+ ** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
+ ** interpreted as a boolean, which enables or disables the collection of
+@@ -1630,25 +1734,7 @@
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
+-** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+-** that SQLite can use for scratch memory.  ^(There are three arguments
+-** to SQLITE_CONFIG_SCRATCH:  A pointer an 8-byte
+-** aligned memory buffer from which the scratch allocations will be
+-** drawn, the size of each scratch allocation (sz),
+-** and the maximum number of scratch allocations (N).)^
+-** The first argument must be a pointer to an 8-byte aligned buffer
+-** of at least sz*N bytes of memory.
+-** ^SQLite will not use more than one scratch buffers per thread.
+-** ^SQLite will never request a scratch buffer that is more than 6
+-** times the database page size.
+-** ^If SQLite needs needs additional
+-** scratch memory beyond what is provided by this configuration option, then 
+-** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+-** ^When the application provides any amount of scratch memory using
+-** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+-** [sqlite3_malloc|heap allocations].
+-** This can help [Robson proof|prevent memory allocation failures] due to heap
+-** fragmentation in low-memory embedded systems.
++** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
+ ** </dd>
+ **
+ ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
+@@ -1684,8 +1770,7 @@
+ ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
+ ** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+ ** that SQLite will use for all of its dynamic memory allocation needs
+-** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
+-** [SQLITE_CONFIG_PAGECACHE].
++** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
+ ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
+ ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
+ ** [SQLITE_ERROR] if invoked otherwise.
+@@ -1871,6 +1956,22 @@
+ ** I/O required to support statement rollback.
+ ** The default value for this setting is controlled by the
+ ** [SQLITE_STMTJRNL_SPILL] compile-time option.
++**
++** [[SQLITE_CONFIG_SORTERREF_SIZE]]
++** <dt>SQLITE_CONFIG_SORTERREF_SIZE
++** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
++** of type (int) - the new value of the sorter-reference size threshold.
++** Usually, when SQLite uses an external sort to order records according
++** to an ORDER BY clause, all fields required by the caller are present in the
++** sorted records. However, if SQLite determines based on the declared type
++** of a table column that its values are likely to be very large - larger
++** than the configured sorter-reference size threshold - then a reference
++** is stored in each sorted record and the required column values loaded
++** from the database as records are returned in sorted order. The default
++** value for this option is to never use this optimization. Specifying a 
++** negative value for this option restores the default behaviour.
++** This option is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -1878,7 +1979,7 @@
+ #define SQLITE_CONFIG_SERIALIZED    3  /* nil */
+ #define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
+ #define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
+-#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
++#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
+ #define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
+ #define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
+ #define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
+@@ -1899,6 +2000,8 @@
+ #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+ #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
++#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
++#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -1914,6 +2017,7 @@
+ ** is invoked.
+ **
+ ** <dl>
++** [[SQLITE_DBCONFIG_LOOKASIDE]]
+ ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+ ** <dd> ^This option takes three additional arguments that determine the 
+ ** [lookaside memory allocator] configuration for the [database connection].
+@@ -1936,6 +2040,7 @@
+ ** memory is in use leaves the configuration unchanged and returns 
+ ** [SQLITE_BUSY].)^</dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
+ ** <dd> ^This option is used to enable or disable the enforcement of
+ ** [foreign key constraints].  There should be two additional arguments.
+@@ -1946,6 +2051,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the FK enforcement setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
+ ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
+ ** There should be two additional arguments.
+@@ -1956,6 +2062,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+ ** <dd> ^This option is used to enable or disable the two-argument
+ ** version of the [fts3_tokenizer()] function which is part of the
+@@ -1969,6 +2076,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the new setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+ ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+ ** interface independently of the [load_extension()] SQL function.
+@@ -1986,7 +2094,7 @@
+ ** be a NULL pointer, in which case the new setting is not reported back.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+ ** <dd> ^This option is used to change the name of the "main" database
+ ** schema.  ^The sole argument is a pointer to a constant UTF8 string
+ ** which will become the new schema name in place of "main".  ^SQLite
+@@ -1995,6 +2103,7 @@
+ ** until after the database connection closes.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] 
+ ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+ ** <dd> Usually, when a database in wal mode is closed or detached from a 
+ ** database handle, SQLite checks if this will mean that there are now no 
+@@ -2001,13 +2110,14 @@
+ ** connections at all to the database. If so, it performs a checkpoint 
+ ** operation before closing the connection. This option may be used to
+ ** override this behaviour. The first parameter passed to this operation
+-** is an integer - non-zero to disable checkpoints-on-close, or zero (the
+-** default) to enable them. The second parameter is a pointer to an integer
++** is an integer - positive to disable checkpoints-on-close, or zero (the
++** default) to enable them, and negative to leave the setting unchanged.
++** The second parameter is a pointer to an integer
+ ** into which is written 0 or 1 to indicate whether checkpoints-on-close
+ ** have been disabled - 0 if they are not disabled, 1 if they are.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+ ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+ ** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+ ** a single SQL query statement will always use the same algorithm regardless
+@@ -2016,8 +2126,57 @@
+ ** slower.  But the QPSG has the advantage of more predictable behavior.  With
+ ** the QPSG active, SQLite will always use the same query plan in the field as
+ ** was used during testing in the lab.
++** The first argument to this setting is an integer which is 0 to disable 
++** the QPSG, positive to enable QPSG, or negative to leave the setting
++** unchanged. The second parameter is a pointer to an integer into which
++** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
++** following this call.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
++** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 
++** include output for any operations performed by trigger programs. This
++** option is used to set or clear (the default) a flag that governs this
++** behavior. The first parameter passed to this operation is an integer -
++** positive to enable output for trigger programs, or zero to disable it,
++** or negative to leave the setting unchanged.
++** The second parameter is a pointer to an integer into which is written 
++** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
++** it is not disabled, 1 if it is.  
++** </dd>
++**
++** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
++** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
++** [VACUUM] in order to reset a database back to an empty database
++** with no schema and no content. The following process works even for
++** a badly corrupted database file:
++** <ol>
++** <li> If the database connection is newly opened, make sure it has read the
++**      database schema by preparing then discarding some query against the
++**      database, or calling sqlite3_table_column_metadata(), ignoring any
++**      errors.  This step is only necessary if the application desires to keep
++**      the database in WAL mode after the reset if it was in WAL mode before
++**      the reset.  
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
++** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
++** </ol>
++** Because resetting a database is destructive and irreversible, the
++** process requires the use of this obscure API and multiple steps to help
++** ensure that it does not happen by accident.
++**
++** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
++** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
++** "defensive" flag for a database connection.  When the defensive
++** flag is enabled, language features that allow ordinary SQL to 
++** deliberately corrupt the database file are disabled.  The disabled
++** features include but are not limited to the following:
++** <ul>
++** <li> The [PRAGMA writable_schema=ON] statement.
++** <li> Writes to the [sqlite_dbpage] virtual table.
++** <li> Direct writes to [shadow tables].
++** </ul>
++** </dd>
+ ** </dl>
+ */
+ #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
+@@ -2028,8 +2187,11 @@
+ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+ #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
++#define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
++#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
++#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
++#define SQLITE_DBCONFIG_MAX                   1010 /* Largest DBCONFIG */
+ 
+-
+ /*
+ ** CAPI3REF: Enable Or Disable Extended Result Codes
+ ** METHOD: sqlite3
+@@ -2156,12 +2318,17 @@
+ ** program, the value returned reflects the number of rows modified by the 
+ ** previous INSERT, UPDATE or DELETE statement within the same trigger.
+ **
+-** See also the [sqlite3_total_changes()] interface, the
+-** [count_changes pragma], and the [changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_total_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** </ul>
+ */
+ SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+@@ -2179,13 +2346,26 @@
+ ** count, but those made as part of REPLACE constraint resolution are
+ ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+ ** are not counted.
++**
++** This the [sqlite3_total_changes(D)] interface only reports the number
++** of rows that changed due to SQL statement run against database
++** connection D.  Any changes by other database connections are ignored.
++** To detect changes against a database file from other database
++** connections use the [PRAGMA data_version] command or the
++** [SQLITE_FCNTL_DATA_VERSION] [file control].
+ ** 
+-** See also the [sqlite3_changes()] interface, the
+-** [count_changes pragma], and the [total_changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
++** </ul>
+ */
+ SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+@@ -2434,16 +2614,16 @@
+ **
+ ** These routines are work-alikes of the "printf()" family of functions
+ ** from the standard C library.
+-** These routines understand most of the common K&R formatting options,
+-** plus some additional non-standard formats, detailed below.
+-** Note that some of the more obscure formatting options from recent
+-** C-library standards are omitted from this implementation.
++** These routines understand most of the common formatting options from
++** the standard library printf() 
++** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
++** See the [built-in printf()] documentation for details.
+ **
+ ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
+-** results into memory obtained from [sqlite3_malloc()].
++** results into memory obtained from [sqlite3_malloc64()].
+ ** The strings returned by these two routines should be
+ ** released by [sqlite3_free()].  ^Both routines return a
+-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
++** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
+ ** memory to hold the resulting string.
+ **
+ ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
+@@ -2467,71 +2647,7 @@
+ **
+ ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
+ **
+-** These routines all implement some additional formatting
+-** options that are useful for constructing SQL statements.
+-** All of the usual printf() formatting options apply.  In addition, there
+-** is are "%q", "%Q", "%w" and "%z" options.
+-**
+-** ^(The %q option works like %s in that it substitutes a nul-terminated
+-** string from the argument list.  But %q also doubles every '\'' character.
+-** %q is designed for use inside a string literal.)^  By doubling each '\''
+-** character it escapes that character and allows it to be inserted into
+-** the string.
+-**
+-** For example, assume the string variable zText contains text as follows:
+-**
+-** <blockquote><pre>
+-**  char *zText = "It's a happy day!";
+-** </pre></blockquote>
+-**
+-** One can use this text in an SQL statement as follows:
+-**
+-** <blockquote><pre>
+-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
+-**  sqlite3_exec(db, zSQL, 0, 0, 0);
+-**  sqlite3_free(zSQL);
+-** </pre></blockquote>
+-**
+-** Because the %q format string is used, the '\'' character in zText
+-** is escaped and the SQL generated is as follows:
+-**
+-** <blockquote><pre>
+-**  INSERT INTO table1 VALUES('It''s a happy day!')
+-** </pre></blockquote>
+-**
+-** This is correct.  Had we used %s instead of %q, the generated SQL
+-** would have looked like this:
+-**
+-** <blockquote><pre>
+-**  INSERT INTO table1 VALUES('It's a happy day!');
+-** </pre></blockquote>
+-**
+-** This second example is an SQL syntax error.  As a general rule you should
+-** always use %q instead of %s when inserting text into a string literal.
+-**
+-** ^(The %Q option works like %q except it also adds single quotes around
+-** the outside of the total string.  Additionally, if the parameter in the
+-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
+-** single quotes).)^  So, for example, one could say:
+-**
+-** <blockquote><pre>
+-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
+-**  sqlite3_exec(db, zSQL, 0, 0, 0);
+-**  sqlite3_free(zSQL);
+-** </pre></blockquote>
+-**
+-** The code above will render a correct SQL statement in the zSQL
+-** variable even if the zText variable is a NULL pointer.
+-**
+-** ^(The "%w" formatting option is like "%q" except that it expects to
+-** be contained within double-quotes instead of single quotes, and it
+-** escapes the double-quote character instead of the single-quote
+-** character.)^  The "%w" formatting option is intended for safely inserting
+-** table and column names into a constructed SQL statement.
+-**
+-** ^(The "%z" formatting option works like "%s" but with the
+-** addition that after the string has been read and copied into
+-** the result, [sqlite3_free()] is called on the input string.)^
++** See also:  [built-in printf()], [printf() SQL function]
+ */
+ SQLITE_API char *sqlite3_mprintf(const char*,...);
+ SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+@@ -2889,8 +3005,8 @@
+ ** KEYWORDS: SQLITE_TRACE
+ **
+ ** These constants identify classes of events that can be monitored
+-** using the [sqlite3_trace_v2()] tracing logic.  The third argument
+-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
++** using the [sqlite3_trace_v2()] tracing logic.  The M argument
++** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
+ ** the following constants.  ^The first argument to the trace callback
+ ** is one of the following constants.
+ **
+@@ -3099,10 +3215,10 @@
+ ** ^If [URI filename] interpretation is enabled, and the filename argument
+ ** begins with "file:", then the filename is interpreted as a URI. ^URI
+ ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
+-** set in the fourth argument to sqlite3_open_v2(), or if it has
++** set in the third argument to sqlite3_open_v2(), or if it has
+ ** been enabled globally using the [SQLITE_CONFIG_URI] option with the
+ ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
+-** As of SQLite version 3.7.7, URI filename interpretation is turned off
++** URI filename interpretation is turned off
+ ** by default, but future releases of SQLite might enable URI filename
+ ** interpretation by default.  See "[URI filenames]" for additional
+ ** information.
+@@ -3305,13 +3421,24 @@
+ ** [database connection] D failed, then the sqlite3_errcode(D) interface
+ ** returns the numeric [result code] or [extended result code] for that
+ ** API call.
+-** If the most recent API call was successful,
+-** then the return value from sqlite3_errcode() is undefined.
+ ** ^The sqlite3_extended_errcode()
+ ** interface is the same except that it always returns the 
+ ** [extended result code] even when extended result codes are
+ ** disabled.
+ **
++** The values returned by sqlite3_errcode() and/or
++** sqlite3_extended_errcode() might change with each API call.
++** Except, there are some interfaces that are guaranteed to never
++** change the value of the error code.  The error-code preserving
++** interfaces are:
++**
++** <ul>
++** <li> sqlite3_errcode()
++** <li> sqlite3_extended_errcode()
++** <li> sqlite3_errmsg()
++** <li> sqlite3_errmsg16()
++** </ul>
++**
+ ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+ ** text that describes the error, as either UTF-8 or UTF-16 respectively.
+ ** ^(Memory to hold the error message string is managed internally.
+@@ -3501,9 +3628,19 @@
+ ** on this hint by avoiding the use of [lookaside memory] so as not to
+ ** deplete the limited store of lookaside memory. Future versions of
+ ** SQLite may act on this hint differently.
++**
++** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
++** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
++** representation of the SQL statement should be calculated and then
++** associated with the prepared statement, which can be obtained via
++** the [sqlite3_normalized_sql()] interface.)^  The semantics used to
++** normalize a SQL statement are unspecified and subject to change.
++** At a minimum, literal values will be replaced with suitable
++** placeholders.
+ ** </dl>
+ */
+ #define SQLITE_PREPARE_PERSISTENT              0x01
++#define SQLITE_PREPARE_NORMALIZE               0x02
+ 
+ /*
+ ** CAPI3REF: Compiling An SQL Statement
+@@ -3597,6 +3734,7 @@
+ ** or [GLOB] operator or if the parameter is compared to an indexed column
+ ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
+ ** </li>
++** </ol>
+ **
+ ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
+ ** the extra prepFlags parameter, which is a bit array consisting of zero or
+@@ -3603,7 +3741,6 @@
+ ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
+ ** sqlite3_prepare_v2() interface works exactly the same as
+ ** sqlite3_prepare_v3() with a zero prepFlags parameter.
+-** </ol>
+ */
+ SQLITE_API int sqlite3_prepare(
+   sqlite3 *db,            /* Database handle */
+@@ -3661,6 +3798,11 @@
+ ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+ ** string containing the SQL text of prepared statement P with
+ ** [bound parameters] expanded.
++** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
++** string containing the normalized SQL text of prepared statement P.  The
++** semantics used to normalize a SQL statement are unspecified and subject
++** to change.  At a minimum, literal values will be replaced with suitable
++** placeholders.
+ **
+ ** ^(For example, if a prepared statement is created using the SQL
+ ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+@@ -3676,8 +3818,9 @@
+ ** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+ ** option causes sqlite3_expanded_sql() to always return NULL.
+ **
+-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
+-** automatically freed when the prepared statement is finalized.
++** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
++** are managed by SQLite and are automatically freed when the prepared
++** statement is finalized.
+ ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+ ** is obtained from [sqlite3_malloc()] and must be free by the application
+ ** by passing it to [sqlite3_free()].
+@@ -3684,6 +3827,7 @@
+ */
+ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -3776,8 +3920,9 @@
+ ** implementation of [application-defined SQL functions] are protected.
+ ** ^The sqlite3_value object returned by
+ ** [sqlite3_column_value()] is unprotected.
+-** Unprotected sqlite3_value objects may only be used with
+-** [sqlite3_result_value()] and [sqlite3_bind_value()].
++** Unprotected sqlite3_value objects may only be used as arguments
++** to [sqlite3_result_value()], [sqlite3_bind_value()], and
++** [sqlite3_value_dup()].
+ ** The [sqlite3_value_blob | sqlite3_value_type()] family of
+ ** interfaces require protected sqlite3_value objects.
+ */
+@@ -4199,7 +4344,7 @@
+ ** other than [SQLITE_ROW] before any subsequent invocation of
+ ** sqlite3_step().  Failure to reset the prepared statement using 
+ ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
+-** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1]),
++** sqlite3_step().  But after [version 3.6.23.1] ([dateof:3.6.23.1],
+ ** sqlite3_step() began
+ ** calling [sqlite3_reset()] automatically in this circumstance rather
+ ** than returning [SQLITE_MISUSE].  This is not considered a compatibility
+@@ -4464,11 +4609,25 @@
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+-** ^(If a memory allocation error occurs during the evaluation of any
+-** of these routines, a default value is returned.  The default value
+-** is either the integer 0, the floating point number 0.0, or a NULL
+-** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+-** [SQLITE_NOMEM].)^
++** As long as the input parameters are correct, these routines will only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_column_blob()
++** <li> sqlite3_column_text()
++** <li> sqlite3_column_text16()
++** <li> sqlite3_column_bytes()
++** <li> sqlite3_column_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+ SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+@@ -4545,11 +4704,13 @@
+ **
+ ** ^These functions (collectively known as "function creation routines")
+ ** are used to add SQL functions or aggregates or to redefine the behavior
+-** of existing SQL functions or aggregates.  The only differences between
+-** these routines are the text encoding expected for
+-** the second parameter (the name of the function being created)
+-** and the presence or absence of a destructor callback for
+-** the application data pointer.
++** of existing SQL functions or aggregates. The only differences between
++** the three "sqlite3_create_function*" routines are the text encoding 
++** expected for the second parameter (the name of the function being 
++** created) and the presence or absence of a destructor callback for
++** the application data pointer. Function sqlite3_create_window_function()
++** is similar, but allows the user to supply the extra callback functions
++** needed by [aggregate window functions].
+ **
+ ** ^The first parameter is the [database connection] to which the SQL
+ ** function is to be added.  ^If an application uses more than one database
+@@ -4595,7 +4756,8 @@
+ ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+ ** function can gain access to this pointer using [sqlite3_user_data()].)^
+ **
+-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
++** ^The sixth, seventh and eighth parameters passed to the three
++** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+ ** pointers to C-language functions that implement the SQL function or
+ ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
+ ** callback only; NULL pointers must be passed as the xStep and xFinal
+@@ -4604,16 +4766,25 @@
+ ** SQL function or aggregate, pass NULL pointers for all three function
+ ** callbacks.
+ **
+-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
+-** then it is destructor for the application data pointer. 
+-** The destructor is invoked when the function is deleted, either by being
+-** overloaded or when the database connection closes.)^
+-** ^The destructor is also invoked if the call to
+-** sqlite3_create_function_v2() fails.
+-** ^When the destructor callback of the tenth parameter is invoked, it
+-** is passed a single argument which is a copy of the application data 
+-** pointer which was the fifth parameter to sqlite3_create_function_v2().
++** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
++** and xInverse) passed to sqlite3_create_window_function are pointers to
++** C-language callbacks that implement the new function. xStep and xFinal
++** must both be non-NULL. xValue and xInverse may either both be NULL, in
++** which case a regular aggregate function is created, or must both be 
++** non-NULL, in which case the new function may be used as either an aggregate
++** or aggregate window function. More details regarding the implementation
++** of aggregate window functions are 
++** [user-defined window functions|available here].
+ **
++** ^(If the final parameter to sqlite3_create_function_v2() or
++** sqlite3_create_window_function() is not NULL, then it is destructor for
++** the application data pointer. The destructor is invoked when the function 
++** is deleted, either by being overloaded or when the database connection 
++** closes.)^ ^The destructor is also invoked if the call to 
++** sqlite3_create_function_v2() fails.  ^When the destructor callback is
++** invoked, it is passed a single argument which is a copy of the application
++** data pointer which was the fifth parameter to sqlite3_create_function_v2().
++**
+ ** ^It is permitted to register multiple implementations of the same
+ ** functions with the same name but with either differing numbers of
+ ** arguments or differing preferred text encodings.  ^SQLite will use
+@@ -4665,6 +4836,18 @@
+   void (*xFinal)(sqlite3_context*),
+   void(*xDestroy)(void*)
+ );
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunctionName,
++  int nArg,
++  int eTextRep,
++  void *pApp,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
++);
+ 
+ /*
+ ** CAPI3REF: Text Encodings
+@@ -4735,6 +4918,9 @@
+ ** datatype of the value
+ ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
+ ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
++** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
++** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
++** against a virtual table.
+ ** </table></blockquote>
+ **
+ ** <b>Details:</b>
+@@ -4783,6 +4969,19 @@
+ ** then the conversion is performed.  Otherwise no conversion occurs.
+ ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
+ **
++** ^Within the [xUpdate] method of a [virtual table], the
++** sqlite3_value_nochange(X) interface returns true if and only if
++** the column corresponding to X is unchanged by the UPDATE operation
++** that the xUpdate method call was invoked to implement and if
++** and the prior [xColumn] method call that was invoked to extracted
++** the value for that column returned without setting a result (probably
++** because it queried [sqlite3_vtab_nochange()] and found that the column
++** was unchanging).  ^Within an [xUpdate] method, any value for which
++** sqlite3_value_nochange(X) is true will in all other respects appear
++** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
++** than within an [xUpdate] method call for an UPDATE statement, then
++** the return value is arbitrary and meaningless.
++**
+ ** Please pay particular attention to the fact that the pointer returned
+ ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
+ ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
+@@ -4791,6 +4990,28 @@
+ **
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
++**
++** As long as the input parameter is correct, these routines can only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_value_blob()
++** <li> sqlite3_value_text()
++** <li> sqlite3_value_text16()
++** <li> sqlite3_value_text16le()
++** <li> sqlite3_value_text16be()
++** <li> sqlite3_value_bytes()
++** <li> sqlite3_value_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+ SQLITE_API double sqlite3_value_double(sqlite3_value*);
+@@ -4805,6 +5026,7 @@
+ SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+ SQLITE_API int sqlite3_value_type(sqlite3_value*);
+ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
++SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+ 
+ /*
+ ** CAPI3REF: Finding The Subtype Of SQL Values
+@@ -5461,6 +5683,41 @@
+ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
+ 
+ /*
++** CAPI3REF: Win32 Specific Interface
++**
++** These interfaces are available only on Windows.  The
++** [sqlite3_win32_set_directory] interface is used to set the value associated
++** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
++** zValue, depending on the value of the type parameter.  The zValue parameter
++** should be NULL to cause the previous value to be freed via [sqlite3_free];
++** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
++** prior to being used.  The [sqlite3_win32_set_directory] interface returns
++** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
++** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
++** [sqlite3_data_directory] variable is intended to act as a replacement for
++** the current directory on the sub-platforms of Win32 where that concept is
++** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
++** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
++** sqlite3_win32_set_directory interface except the string parameter must be
++** UTF-8 or UTF-16, respectively.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++);
++SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
++SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
++
++/*
++** CAPI3REF: Win32 Directory Types
++**
++** These macros are only available on Windows.  They define the allowed values
++** for the type argument to the [sqlite3_win32_set_directory] interface.
++*/
++#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
++#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
++
++/*
+ ** CAPI3REF: Test For Auto-Commit Mode
+ ** KEYWORDS: {autocommit mode}
+ ** METHOD: sqlite3
+@@ -6060,6 +6317,9 @@
+   int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+   int (*xRelease)(sqlite3_vtab *pVTab, int);
+   int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
++  /* The methods above are in versions 1 and 2 of the sqlite_module object.
++  ** Those below are for version 3 and greater. */
++  int (*xShadowName)(const char*);
+ };
+ 
+ /*
+@@ -6192,6 +6452,10 @@
+ 
+ /*
+ ** CAPI3REF: Virtual Table Scan Flags
++**
++** Virtual table implementations are allowed to set the 
++** [sqlite3_index_info].idxFlags field to some combination of
++** these bits.
+ */
+ #define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
+ 
+@@ -6203,15 +6467,21 @@
+ ** an operator that is part of a constraint term in the wHERE clause of
+ ** a query that uses a [virtual table].
+ */
+-#define SQLITE_INDEX_CONSTRAINT_EQ      2
+-#define SQLITE_INDEX_CONSTRAINT_GT      4
+-#define SQLITE_INDEX_CONSTRAINT_LE      8
+-#define SQLITE_INDEX_CONSTRAINT_LT     16
+-#define SQLITE_INDEX_CONSTRAINT_GE     32
+-#define SQLITE_INDEX_CONSTRAINT_MATCH  64
+-#define SQLITE_INDEX_CONSTRAINT_LIKE   65
+-#define SQLITE_INDEX_CONSTRAINT_GLOB   66
+-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
++#define SQLITE_INDEX_CONSTRAINT_EQ         2
++#define SQLITE_INDEX_CONSTRAINT_GT         4
++#define SQLITE_INDEX_CONSTRAINT_LE         8
++#define SQLITE_INDEX_CONSTRAINT_LT        16
++#define SQLITE_INDEX_CONSTRAINT_GE        32
++#define SQLITE_INDEX_CONSTRAINT_MATCH     64
++#define SQLITE_INDEX_CONSTRAINT_LIKE      65
++#define SQLITE_INDEX_CONSTRAINT_GLOB      66
++#define SQLITE_INDEX_CONSTRAINT_REGEXP    67
++#define SQLITE_INDEX_CONSTRAINT_NE        68
++#define SQLITE_INDEX_CONSTRAINT_ISNOT     69
++#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
++#define SQLITE_INDEX_CONSTRAINT_ISNULL    71
++#define SQLITE_INDEX_CONSTRAINT_IS        72
++#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -6888,6 +7158,7 @@
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+ ** METHOD: sqlite3
++** KEYWORDS: {file control}
+ **
+ ** ^The [sqlite3_file_control()] interface makes a direct call to the
+ ** xFileControl method for the [sqlite3_io_methods] object associated
+@@ -6902,11 +7173,18 @@
+ ** the xFileControl method.  ^The return value of the xFileControl
+ ** method becomes the return value of this routine.
+ **
+-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
++** A few opcodes for [sqlite3_file_control()] are handled directly
++** by the SQLite core and never invoke the 
++** sqlite3_io_methods.xFileControl method.
++** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+ ** a pointer to the underlying [sqlite3_file] object to be written into
+-** the space pointed to by the 4th parameter.  ^The SQLITE_FCNTL_FILE_POINTER
+-** case is a short-circuit path which does not actually invoke the
+-** underlying sqlite3_io_methods.xFileControl method.
++** the space pointed to by the 4th parameter.  The
++** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
++** the [sqlite3_file] object associated with the journal file instead of
++** the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
++** a pointer to the underlying [sqlite3_vfs] object for the file.
++** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
++** from the pager.
+ **
+ ** ^If the second parameter (zDbName) does not match the name of any
+ ** open database file, then SQLITE_ERROR is returned.  ^This error
+@@ -6916,7 +7194,7 @@
+ ** an incorrect zDbName and an SQLITE_ERROR return from the underlying
+ ** xFileControl method.
+ **
+-** See also: [SQLITE_FCNTL_LOCKSTATE]
++** See also: [file control opcodes]
+ */
+ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+ 
+@@ -6962,8 +7240,9 @@
+ #define SQLITE_TESTCTRL_ALWAYS                  13
+ #define SQLITE_TESTCTRL_RESERVE                 14
+ #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
+-#define SQLITE_TESTCTRL_ISKEYWORD               16
+-#define SQLITE_TESTCTRL_SCRATCHMALLOC           17
++#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
++#define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
++#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
+ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+@@ -6973,9 +7252,193 @@
+ #define SQLITE_TESTCTRL_ISINIT                  23
+ #define SQLITE_TESTCTRL_SORTER_MMAP             24
+ #define SQLITE_TESTCTRL_IMPOSTER                25
+-#define SQLITE_TESTCTRL_LAST                    25
++#define SQLITE_TESTCTRL_PARSER_COVERAGE         26
++#define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+ 
+ /*
++** CAPI3REF: SQL Keyword Checking
++**
++** These routines provide access to the set of SQL language keywords 
++** recognized by SQLite.  Applications can uses these routines to determine
++** whether or not a specific identifier needs to be escaped (for example,
++** by enclosing in double-quotes) so as not to confuse the parser.
++**
++** The sqlite3_keyword_count() interface returns the number of distinct
++** keywords understood by SQLite.
++**
++** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
++** makes *Z point to that keyword expressed as UTF8 and writes the number
++** of bytes in the keyword into *L.  The string that *Z points to is not
++** zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
++** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
++** or L are NULL or invalid pointers then calls to
++** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
++**
++** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
++** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
++** if it is and zero if not.
++**
++** The parser used by SQLite is forgiving.  It is often possible to use
++** a keyword as an identifier as long as such use does not result in a
++** parsing ambiguity.  For example, the statement
++** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
++** creates a new table named "BEGIN" with three columns named
++** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
++** using keywords as identifiers.  Common techniques used to avoid keyword
++** name collisions include:
++** <ul>
++** <li> Put all identifier names inside double-quotes.  This is the official
++**      SQL way to escape identifier names.
++** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
++**      but it is what SQL Server does and so lots of programmers use this
++**      technique.
++** <li> Begin every identifier with the letter "Z" as no SQL keywords start
++**      with "Z".
++** <li> Include a digit somewhere in every identifier name.
++** </ul>
++**
++** Note that the number of keywords understood by SQLite can depend on
++** compile-time options.  For example, "VACUUM" is not a keyword if
++** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
++** new keywords may be added to future releases of SQLite.
++*/
++SQLITE_API int sqlite3_keyword_count(void);
++SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
++SQLITE_API int sqlite3_keyword_check(const char*,int);
++
++/*
++** CAPI3REF: Dynamic String Object
++** KEYWORDS: {dynamic string}
++**
++** An instance of the sqlite3_str object contains a dynamically-sized
++** string under construction.
++**
++** The lifecycle of an sqlite3_str object is as follows:
++** <ol>
++** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
++** <li> ^Text is appended to the sqlite3_str object using various
++** methods, such as [sqlite3_str_appendf()].
++** <li> ^The sqlite3_str object is destroyed and the string it created
++** is returned using the [sqlite3_str_finish()] interface.
++** </ol>
++*/
++typedef struct sqlite3_str sqlite3_str;
++
++/*
++** CAPI3REF: Create A New Dynamic String Object
++** CONSTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_new(D)] interface allocates and initializes
++** a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
++** [sqlite3_str_new()] must be freed by a subsequent call to 
++** [sqlite3_str_finish(X)].
++**
++** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
++** valid [sqlite3_str] object, though in the event of an out-of-memory
++** error the returned object might be a special singleton that will
++** silently reject new text, always return SQLITE_NOMEM from 
++** [sqlite3_str_errcode()], always return 0 for 
++** [sqlite3_str_length()], and always return NULL from
++** [sqlite3_str_finish(X)].  It is always safe to use the value
++** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
++** to any of the other [sqlite3_str] methods.
++**
++** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
++** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
++** length of the string contained in the [sqlite3_str] object will be
++** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
++** of [SQLITE_MAX_LENGTH].
++*/
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
++
++/*
++** CAPI3REF: Finalize A Dynamic String
++** DESTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
++** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
++** that contains the constructed string.  The calling application should
++** pass the returned value to [sqlite3_free()] to avoid a memory leak.
++** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
++** errors were encountered during construction of the string.  ^The
++** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
++** string in [sqlite3_str] object X is zero bytes long.
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
++
++/*
++** CAPI3REF: Add Content To A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces add content to an sqlite3_str object previously obtained
++** from [sqlite3_str_new()].
++**
++** ^The [sqlite3_str_appendf(X,F,...)] and 
++** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
++** functionality of SQLite to append formatted text onto the end of 
++** [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
++** onto the end of the [sqlite3_str] object X.  N must be non-negative.
++** S must contain at least N non-zero bytes of content.  To append a
++** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
++** method instead.
++**
++** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
++** zero-terminated string S onto the end of [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
++** single-byte character C onto the end of [sqlite3_str] object X.
++** ^This method can be used, for example, to add whitespace indentation.
++**
++** ^The [sqlite3_str_reset(X)] method resets the string under construction
++** inside [sqlite3_str] object X back to zero bytes in length.  
++**
++** These methods do not return a result code.  ^If an error occurs, that fact
++** is recorded in the [sqlite3_str] object and can be recovered by a
++** subsequent call to [sqlite3_str_errcode(X)].
++*/
++SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
++SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
++SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
++SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
++SQLITE_API void sqlite3_str_reset(sqlite3_str*);
++
++/*
++** CAPI3REF: Status Of A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces return the current status of an [sqlite3_str] object.
++**
++** ^If any prior errors have occurred while constructing the dynamic string
++** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
++** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
++** [SQLITE_NOMEM] following any out-of-memory error, or
++** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
++** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
++**
++** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
++** of the dynamic string under construction in [sqlite3_str] object X.
++** ^The length returned by [sqlite3_str_length(X)] does not include the
++** zero-termination byte.
++**
++** ^The [sqlite3_str_value(X)] method returns a pointer to the current
++** content of the dynamic string under construction in X.  The value
++** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
++** and might be freed or altered by any subsequent method on the same
++** [sqlite3_str] object.  Applications must not used the pointer returned
++** [sqlite3_str_value(X)] after any subsequent method call on the same
++** object.  ^Applications may change the content of the string returned
++** by [sqlite3_str_value(X)] as long as they do not write into any bytes
++** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
++** write any byte after any subsequent sqlite3_str method call.
++*/
++SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
++SQLITE_API int sqlite3_str_length(sqlite3_str*);
++SQLITE_API char *sqlite3_str_value(sqlite3_str*);
++
++/*
+ ** CAPI3REF: SQLite Runtime Status
+ **
+ ** ^These interfaces are used to retrieve runtime status information
+@@ -7022,8 +7485,7 @@
+ ** <dd>This parameter is the current amount of memory checked out
+ ** using [sqlite3_malloc()], either directly or indirectly.  The
+ ** figure includes calls made to [sqlite3_malloc()] by the application
+-** and internal memory usage by the SQLite library.  Scratch memory
+-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
++** and internal memory usage by the SQLite library.  Auxiliary page-cache
+ ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
+ ** this parameter.  The amount returned is the sum of the allocation
+ ** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
+@@ -7061,29 +7523,14 @@
+ ** *pHighwater parameter to [sqlite3_status()] is of interest.  
+ ** The value written into the *pCurrent parameter is undefined.</dd>)^
+ **
+-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
+-** <dd>This parameter returns the number of allocations used out of the
+-** [scratch memory allocator] configured using
+-** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
+-** in bytes.  Since a single thread may only have one scratch allocation
+-** outstanding at time, this parameter also reports the number of threads
+-** using scratch memory at the same time.</dd>)^
++** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
++** <dd>No longer used.</dd>
+ **
+ ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
+-** <dd>This parameter returns the number of bytes of scratch memory
+-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
+-** buffer and where forced to overflow to [sqlite3_malloc()].  The values
+-** returned include overflows because the requested allocation was too
+-** larger (that is, because the requested allocation was larger than the
+-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
+-** slots were available.
+-** </dd>)^
++** <dd>No longer used.</dd>
+ **
+-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+-** <dd>This parameter records the largest memory allocation request
+-** handed to [scratch memory allocator].  Only the value returned in the
+-** *pHighwater parameter to [sqlite3_status()] is of interest.  
+-** The value written into the *pCurrent parameter is undefined.</dd>)^
++** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
++** <dd>No longer used.</dd>
+ **
+ ** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
+ ** <dd>The *pHighwater parameter records the deepest parser stack. 
+@@ -7096,12 +7543,12 @@
+ #define SQLITE_STATUS_MEMORY_USED          0
+ #define SQLITE_STATUS_PAGECACHE_USED       1
+ #define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
+-#define SQLITE_STATUS_SCRATCH_USED         3
+-#define SQLITE_STATUS_SCRATCH_OVERFLOW     4
++#define SQLITE_STATUS_SCRATCH_USED         3  /* NOT USED */
++#define SQLITE_STATUS_SCRATCH_OVERFLOW     4  /* NOT USED */
+ #define SQLITE_STATUS_MALLOC_SIZE          5
+ #define SQLITE_STATUS_PARSER_STACK         6
+ #define SQLITE_STATUS_PAGECACHE_SIZE       7
+-#define SQLITE_STATUS_SCRATCH_SIZE         8
++#define SQLITE_STATUS_SCRATCH_SIZE         8  /* NOT USED */
+ #define SQLITE_STATUS_MALLOC_COUNT         9
+ 
+ /*
+@@ -7224,6 +7671,15 @@
+ ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
+ ** </dd>
+ **
++** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
++** <dd>This parameter returns the number of dirty cache entries that have
++** been written to disk in the middle of a transaction due to the page
++** cache overflowing. Transactions are more efficient if they are written
++** to disk all at once. When pages spill mid-transaction, that introduces
++** additional overhead. This parameter can be used help identify
++** inefficiencies that can be resolve by increasing the cache size.
++** </dd>
++**
+ ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+ ** <dd>This parameter returns zero for the current value if and only if
+ ** all foreign key constraints (deferred or immediate) have been
+@@ -7243,7 +7699,8 @@
+ #define SQLITE_DBSTATUS_CACHE_WRITE          9
+ #define SQLITE_DBSTATUS_DEFERRED_FKS        10
+ #define SQLITE_DBSTATUS_CACHE_USED_SHARED   11
+-#define SQLITE_DBSTATUS_MAX                 11   /* Largest defined DBSTATUS */
++#define SQLITE_DBSTATUS_CACHE_SPILL         12
++#define SQLITE_DBSTATUS_MAX                 12   /* Largest defined DBSTATUS */
+ 
+ 
+ /*
+@@ -8198,6 +8655,7 @@
+ ** can use to customize and optimize their behavior.
+ **
+ ** <dl>
++** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
+ ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
+ ** <dd>Calls of the form
+ ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
+@@ -8244,6 +8702,40 @@
+ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+ 
+ /*
++** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
++**
++** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
++** method of a [virtual table], then it returns true if and only if the
++** column is being fetched as part of an UPDATE operation during which the
++** column value will not change.  Applications might use this to substitute
++** a return value that is less expensive to compute and that the corresponding
++** [xUpdate] method understands as a "no-change" value.
++**
++** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
++** the column is not changed by the UPDATE statement, then the xColumn
++** method can optionally return without setting a result, without calling
++** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
++** In that case, [sqlite3_value_nochange(X)] will return true for the
++** same column in the [xUpdate] method.
++*/
++SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
++
++/*
++** CAPI3REF: Determine The Collation For a Virtual Table Constraint
++**
++** This function may only be called from within a call to the [xBestIndex]
++** method of a [virtual table]. 
++**
++** The first argument must be the sqlite3_index_info object that is the
++** first parameter to the xBestIndex() method. The second argument must be
++** an index into the aConstraint[] array belonging to the sqlite3_index_info
++** structure passed to xBestIndex. This function returns a pointer to a buffer 
++** containing the name of the collation sequence for the corresponding
++** constraint.
++*/
++SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
++
++/*
+ ** CAPI3REF: Conflict resolution modes
+ ** KEYWORDS: {conflict resolution mode}
+ **
+@@ -8513,7 +9005,6 @@
+ /*
+ ** CAPI3REF: Database Snapshot
+ ** KEYWORDS: {snapshot} {sqlite3_snapshot}
+-** EXPERIMENTAL
+ **
+ ** An instance of the snapshot object records the state of a [WAL mode]
+ ** database for some specific point in history.
+@@ -8530,11 +9021,6 @@
+ ** version of the database file so that it is possible to later open a new read
+ ** transaction that sees that historical version of the database rather than
+ ** the most recent version.
+-**
+-** The constructor for this object is [sqlite3_snapshot_get()].  The
+-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+-** to an historical snapshot (if possible).  The destructor for 
+-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+ */
+ typedef struct sqlite3_snapshot {
+   unsigned char hidden[48];
+@@ -8542,7 +9028,7 @@
+ 
+ /*
+ ** CAPI3REF: Record A Database Snapshot
+-** EXPERIMENTAL
++** CONSTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+ ** new [sqlite3_snapshot] object that records the current state of
+@@ -8558,7 +9044,7 @@
+ ** in this case. 
+ **
+ ** <ul>
+-**   <li> The database handle must be in [autocommit mode].
++**   <li> The database handle must not be in [autocommit mode].
+ **
+ **   <li> Schema S of [database connection] D must be a [WAL mode] database.
+ **
+@@ -8581,7 +9067,7 @@
+ ** to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_get()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+   sqlite3 *db,
+@@ -8591,24 +9077,35 @@
+ 
+ /*
+ ** CAPI3REF: Start a read transaction on an historical snapshot
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+-** read transaction for schema S of
+-** [database connection] D such that the read transaction
+-** refers to historical [snapshot] P, rather than the most
+-** recent change to the database.
+-** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+-** or an appropriate [error code] if it fails.
++** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read 
++** transaction or upgrades an existing one for schema S of 
++** [database connection] D such that the read transaction refers to 
++** historical [snapshot] P, rather than the most recent change to the 
++** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK 
++** on success or an appropriate [error code] if it fails.
+ **
+-** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+-** the first operation following the [BEGIN] that takes the schema S
+-** out of [autocommit mode].
+-** ^In other words, schema S must not currently be in
+-** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+-** database connection D must be out of [autocommit mode].
+-** ^A [snapshot] will fail to open if it has been overwritten by a
+-** [checkpoint].
++** ^In order to succeed, the database connection must not be in 
++** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
++** is already a read transaction open on schema S, then the database handle
++** must have no active statements (SELECT statements that have been passed
++** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). 
++** SQLITE_ERROR is returned if either of these conditions is violated, or
++** if schema S does not exist, or if the snapshot object is invalid.
++**
++** ^A call to sqlite3_snapshot_open() will fail to open if the specified
++** snapshot has been overwritten by a [checkpoint]. In this case 
++** SQLITE_ERROR_SNAPSHOT is returned.
++**
++** If there is already a read transaction open when this function is 
++** invoked, then the same read transaction remains open (on the same
++** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
++** is returned. If another error code - for example SQLITE_PROTOCOL or an
++** SQLITE_IOERR error code - is returned, then the final state of the
++** read transaction is undefined. If SQLITE_OK is returned, then the 
++** read transaction is now open on database snapshot P.
++**
+ ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+ ** database connection D does not know that the database file for
+ ** schema S is in [WAL mode].  A database connection might not know
+@@ -8619,7 +9116,7 @@
+ ** database connection in order to make it ready to use snapshots.)
+ **
+ ** The [sqlite3_snapshot_open()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+   sqlite3 *db,
+@@ -8629,7 +9126,7 @@
+ 
+ /*
+ ** CAPI3REF: Destroy a snapshot
+-** EXPERIMENTAL
++** DESTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+ ** The application must eventually free every [sqlite3_snapshot] object
+@@ -8636,13 +9133,13 @@
+ ** using this routine to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_free()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+ 
+ /*
+ ** CAPI3REF: Compare the ages of two snapshot handles.
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+ ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+ ** of two valid snapshot handles. 
+@@ -8661,6 +9158,9 @@
+ ** Otherwise, this API returns a negative value if P1 refers to an older
+ ** snapshot than P2, zero if the two handles refer to the same database
+ ** snapshot, and a positive value if P1 is a newer snapshot than P2.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+   sqlite3_snapshot *p1,
+@@ -8669,27 +9169,152 @@
+ 
+ /*
+ ** CAPI3REF: Recover snapshots from a wal file
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** If all connections disconnect from a database file but do not perform
+-** a checkpoint, the existing wal file is opened along with the database
+-** file the next time the database is opened. At this point it is only
+-** possible to successfully call sqlite3_snapshot_open() to open the most
+-** recent snapshot of the database (the one at the head of the wal file),
+-** even though the wal file may contain other valid snapshots for which
+-** clients have sqlite3_snapshot handles.
++** If a [WAL file] remains on disk after all database connections close
++** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
++** or because the last process to have the database opened exited without
++** calling [sqlite3_close()]) and a new connection is subsequently opened
++** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
++** will only be able to open the last transaction added to the WAL file
++** even though the WAL file contains other valid transactions.
+ **
+-** This function attempts to scan the wal file associated with database zDb
++** This function attempts to scan the WAL file associated with database zDb
+ ** of database handle db and make all valid snapshots available to
+ ** sqlite3_snapshot_open(). It is an error if there is already a read
+-** transaction open on the database, or if the database is not a wal mode
++** transaction open on the database, or if the database is not a WAL mode
+ ** database.
+ **
+ ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+ /*
++** CAPI3REF: Serialize a database
++**
++** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
++** that is a serialization of the S database on [database connection] D.
++** If P is not a NULL pointer, then the size of the database in bytes
++** is written into *P.
++**
++** For an ordinary on-disk database file, the serialization is just a
++** copy of the disk file.  For an in-memory database or a "TEMP" database,
++** the serialization is the same sequence of bytes which would be written
++** to disk if that database where backed up to disk.
++**
++** The usual case is that sqlite3_serialize() copies the serialization of
++** the database into memory obtained from [sqlite3_malloc64()] and returns
++** a pointer to that memory.  The caller is responsible for freeing the
++** returned value to avoid a memory leak.  However, if the F argument
++** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
++** are made, and the sqlite3_serialize() function will return a pointer
++** to the contiguous memory representation of the database that SQLite
++** is currently using for that database, or NULL if the no such contiguous
++** memory representation of the database exists.  A contiguous memory
++** representation of the database will usually only exist if there has
++** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
++** values of D and S.
++** The size of the database is written into *P even if the 
++** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
++** of the database exists.
++**
++** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
++** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
++** allocation error occurs.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_DESERIALIZE] option.
++*/
++SQLITE_API unsigned char *sqlite3_serialize(
++  sqlite3 *db,           /* The database connection */
++  const char *zSchema,   /* Which DB to serialize. ex: "main", "temp", ... */
++  sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
++  unsigned int mFlags    /* Zero or more SQLITE_SERIALIZE_* flags */
++);
++
++/*
++** CAPI3REF: Flags for sqlite3_serialize
++**
++** Zero or more of the following constants can be OR-ed together for
++** the F argument to [sqlite3_serialize(D,S,P,F)].
++**
++** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
++** a pointer to contiguous in-memory database that it is currently using,
++** without making a copy of the database.  If SQLite is not currently using
++** a contiguous in-memory database, then this option causes
++** [sqlite3_serialize()] to return a NULL pointer.  SQLite will only be
++** using a contiguous in-memory database if it has been initialized by a
++** prior call to [sqlite3_deserialize()].
++*/
++#define SQLITE_SERIALIZE_NOCOPY 0x001   /* Do no memory allocations */
++
++/*
++** CAPI3REF: Deserialize a database
++**
++** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the 
++** [database connection] D to disconnect from database S and then
++** reopen S as an in-memory database based on the serialization contained
++** in P.  The serialized database P is N bytes in size.  M is the size of
++** the buffer P, which might be larger than N.  If M is larger than N, and
++** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
++** permitted to add content to the in-memory database as long as the total
++** size does not exceed M bytes.
++**
++** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
++** invoke sqlite3_free() on the serialization buffer when the database
++** connection closes.  If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
++** SQLite will try to increase the buffer size using sqlite3_realloc64()
++** if writes on the database cause it to grow larger than M bytes.
++**
++** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
++** database is currently in a read transaction or is involved in a backup
++** operation.
++**
++** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the 
++** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
++** [sqlite3_free()] is invoked on argument P prior to returning.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_DESERIALIZE] option.
++*/
++SQLITE_API int sqlite3_deserialize(
++  sqlite3 *db,            /* The database connection */
++  const char *zSchema,    /* Which DB to reopen with the deserialization */
++  unsigned char *pData,   /* The serialized database content */
++  sqlite3_int64 szDb,     /* Number bytes in the deserialization */
++  sqlite3_int64 szBuf,    /* Total size of buffer pData[] */
++  unsigned mFlags         /* Zero or more SQLITE_DESERIALIZE_* flags */
++);
++
++/*
++** CAPI3REF: Flags for sqlite3_deserialize()
++**
++** The following are allowed values for 6th argument (the F argument) to
++** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
++**
++** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
++** in the P argument is held in memory obtained from [sqlite3_malloc64()]
++** and that SQLite should take ownership of this memory and automatically
++** free it when it has finished using it.  Without this flag, the caller
++** is responsible for freeing any dynamically allocated memory.
++**
++** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
++** grow the size of the database using calls to [sqlite3_realloc64()].  This
++** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
++** Without this flag, the deserialized database cannot increase in size beyond
++** the number of bytes specified by the M parameter.
++**
++** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
++** should be treated as read-only.
++*/
++#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
++#define SQLITE_DESERIALIZE_RESIZEABLE  2 /* Resize using sqlite3_realloc64() */
++#define SQLITE_DESERIALIZE_READONLY    4 /* Database is read-only */
++
++/*
+ ** Undo the hack that converts floating point types to integer for
+ ** builds on processors without floating point support.
+ */
+@@ -8800,7 +9425,7 @@
+   sqlite3_int64 iRowid;             /* Rowid for current entry */
+   sqlite3_rtree_dbl rParentScore;   /* Score of parent node */
+   int eParentWithin;                /* Visibility of parent node */
+-  int eWithin;                      /* OUT: Visiblity */
++  int eWithin;                      /* OUT: Visibility */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
+   /* The following fields are only available in 3.8.11 and later */
+   sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+@@ -8836,16 +9461,23 @@
+ 
+ /*
+ ** CAPI3REF: Session Object Handle
++**
++** An instance of this object is a [session] that can be used to
++** record changes to a database.
+ */
+ typedef struct sqlite3_session sqlite3_session;
+ 
+ /*
+ ** CAPI3REF: Changeset Iterator Handle
++**
++** An instance of this object acts as a cursor for iterating
++** over the elements of a [changeset] or [patchset].
+ */
+ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
+ 
+ /*
+ ** CAPI3REF: Create A New Session Object
++** CONSTRUCTOR: sqlite3_session
+ **
+ ** Create a new session object attached to database handle db. If successful,
+ ** a pointer to the new object is written to *ppSession and SQLITE_OK is
+@@ -8882,6 +9514,7 @@
+ 
+ /*
+ ** CAPI3REF: Delete A Session Object
++** DESTRUCTOR: sqlite3_session
+ **
+ ** Delete a session object previously allocated using 
+ ** [sqlite3session_create()]. Once a session object has been deleted, the
+@@ -8897,6 +9530,7 @@
+ 
+ /*
+ ** CAPI3REF: Enable Or Disable A Session Object
++** METHOD: sqlite3_session
+ **
+ ** Enable or disable the recording of changes by a session object. When
+ ** enabled, a session object records changes made to the database. When
+@@ -8916,6 +9550,7 @@
+ 
+ /*
+ ** CAPI3REF: Set Or Clear the Indirect Change Flag
++** METHOD: sqlite3_session
+ **
+ ** Each change recorded by a session object is marked as either direct or
+ ** indirect. A change is marked as indirect if either:
+@@ -8945,6 +9580,7 @@
+ 
+ /*
+ ** CAPI3REF: Attach A Table To A Session Object
++** METHOD: sqlite3_session
+ **
+ ** If argument zTab is not NULL, then it is the name of a table to attach
+ ** to the session object passed as the first argument. All subsequent changes 
+@@ -8970,6 +9606,35 @@
+ **
+ ** SQLITE_OK is returned if the call completes without error. Or, if an error 
+ ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
++**
++** <h3>Special sqlite_stat1 Handling</h3>
++**
++** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to 
++** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
++**  <pre>
++**  &nbsp;     CREATE TABLE sqlite_stat1(tbl,idx,stat)  
++**  </pre>
++**
++** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are 
++** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes 
++** are recorded for rows for which (idx IS NULL) is true. However, for such
++** rows a zero-length blob (SQL value X'') is stored in the changeset or
++** patchset instead of a NULL value. This allows such changesets to be
++** manipulated by legacy implementations of sqlite3changeset_invert(),
++** concat() and similar.
++**
++** The sqlite3changeset_apply() function automatically converts the 
++** zero-length blob back to a NULL value when updating the sqlite_stat1
++** table. However, if the application calls sqlite3changeset_new(),
++** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset 
++** iterator directly (including on a changeset iterator passed to a
++** conflict-handler callback) then the X'' value is returned. The application
++** must translate X'' to NULL itself if required.
++**
++** Legacy (older than 3.22.0) versions of the sessions module cannot capture
++** changes made to the sqlite_stat1 table. Legacy versions of the
++** sqlite3changeset_apply() function silently ignore any modifications to the
++** sqlite_stat1 table that are part of a changeset or patchset.
+ */
+ SQLITE_API int sqlite3session_attach(
+   sqlite3_session *pSession,      /* Session object */
+@@ -8978,6 +9643,7 @@
+ 
+ /*
+ ** CAPI3REF: Set a table filter on a Session Object.
++** METHOD: sqlite3_session
+ **
+ ** The second argument (xFilter) is the "filter callback". For changes to rows 
+ ** in tables that are not attached to the Session object, the filter is called
+@@ -8996,6 +9662,7 @@
+ 
+ /*
+ ** CAPI3REF: Generate A Changeset From A Session Object
++** METHOD: sqlite3_session
+ **
+ ** Obtain a changeset containing changes to the tables attached to the 
+ ** session object passed as the first argument. If successful, 
+@@ -9105,7 +9772,8 @@
+ );
+ 
+ /*
+-** CAPI3REF: Load The Difference Between Tables Into A Session 
++** CAPI3REF: Load The Difference Between Tables Into A Session
++** METHOD: sqlite3_session
+ **
+ ** If it is not already attached to the session object passed as the first
+ ** argument, this function attaches table zTbl in the same manner as the
+@@ -9170,6 +9838,7 @@
+ 
+ /*
+ ** CAPI3REF: Generate A Patchset From A Session Object
++** METHOD: sqlite3_session
+ **
+ ** The differences between a patchset and a changeset are that:
+ **
+@@ -9198,8 +9867,8 @@
+ */
+ SQLITE_API int sqlite3session_patchset(
+   sqlite3_session *pSession,      /* Session object */
+-  int *pnPatchset,                /* OUT: Size of buffer at *ppChangeset */
+-  void **ppPatchset               /* OUT: Buffer containing changeset */
++  int *pnPatchset,                /* OUT: Size of buffer at *ppPatchset */
++  void **ppPatchset               /* OUT: Buffer containing patchset */
+ );
+ 
+ /*
+@@ -9221,6 +9890,7 @@
+ 
+ /*
+ ** CAPI3REF: Create An Iterator To Traverse A Changeset 
++** CONSTRUCTOR: sqlite3_changeset_iter
+ **
+ ** Create an iterator used to iterate through the contents of a changeset.
+ ** If successful, *pp is set to point to the iterator handle and SQLITE_OK
+@@ -9251,6 +9921,13 @@
+ ** consecutively. There is no chance that the iterator will visit a change 
+ ** the applies to table X, then one for table Y, and then later on visit 
+ ** another change for table X.
++**
++** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
++**
++** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_start(
+   sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+@@ -9257,10 +9934,30 @@
+   int nChangeset,                 /* Size of changeset blob in bytes */
+   void *pChangeset                /* Pointer to blob containing changeset */
+ );
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset,               /* Pointer to blob containing changeset */
++  int flags                       /* SESSION_CHANGESETSTART_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_start_v2
++**
++** The following flags may passed via the 4th parameter to
++** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset while iterating through it. This is equivalent to
++**   inverting a changeset using sqlite3changeset_invert() before applying it.
++**   It is an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETSTART_INVERT        0x0002
+ 
++
+ /*
+ ** CAPI3REF: Advance A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function may only be used with iterators created by function
+ ** [sqlite3changeset_start()]. If it is called on an iterator passed to
+@@ -9285,6 +9982,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -9319,6 +10017,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain The Primary Key Definition Of A Table
++** METHOD: sqlite3_changeset_iter
+ **
+ ** For each modified table, a changeset includes the following:
+ **
+@@ -9350,6 +10049,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain old.* Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -9380,6 +10080,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain new.* Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** The pIter argument passed to this function may either be an iterator
+ ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
+@@ -9413,6 +10114,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function should only be used with iterator objects passed to a
+ ** conflict-handler callback by [sqlite3changeset_apply()] with either
+@@ -9440,6 +10142,7 @@
+ 
+ /*
+ ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function may only be called with an iterator passed to an
+ ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
+@@ -9456,6 +10159,7 @@
+ 
+ /*
+ ** CAPI3REF: Finalize A Changeset Iterator
++** METHOD: sqlite3_changeset_iter
+ **
+ ** This function is used to finalize an iterator allocated with
+ ** [sqlite3changeset_start()].
+@@ -9472,6 +10176,7 @@
+ ** to that error is returned by this function. Otherwise, SQLITE_OK is
+ ** returned. This is to allow the following pattern (pseudo-code):
+ **
++** <pre>
+ **   sqlite3changeset_start();
+ **   while( SQLITE_ROW==sqlite3changeset_next() ){
+ **     // Do something with change.
+@@ -9480,6 +10185,7 @@
+ **   if( rc!=SQLITE_OK ){
+ **     // An error has occurred 
+ **   }
++** </pre>
+ */
+ SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+ 
+@@ -9527,6 +10233,7 @@
+ ** sqlite3_changegroup object. Calling it produces similar results as the
+ ** following code fragment:
+ **
++** <pre>
+ **   sqlite3_changegroup *pGrp;
+ **   rc = sqlite3_changegroup_new(&pGrp);
+ **   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+@@ -9537,6 +10244,7 @@
+ **     *ppOut = 0;
+ **     *pnOut = 0;
+ **   }
++** </pre>
+ **
+ ** Refer to the sqlite3_changegroup documentation below for details.
+ */
+@@ -9552,11 +10260,15 @@
+ 
+ /*
+ ** CAPI3REF: Changegroup Handle
++**
++** A changegroup is an object used to combine two or more 
++** [changesets] or [patchsets]
+ */
+ typedef struct sqlite3_changegroup sqlite3_changegroup;
+ 
+ /*
+ ** CAPI3REF: Create A New Changegroup Object
++** CONSTRUCTOR: sqlite3_changegroup
+ **
+ ** An sqlite3_changegroup object is used to combine two or more changesets
+ ** (or patchsets) into a single changeset (or patchset). A single changegroup
+@@ -9594,6 +10306,7 @@
+ 
+ /*
+ ** CAPI3REF: Add A Changeset To A Changegroup
++** METHOD: sqlite3_changegroup
+ **
+ ** Add all changes within the changeset (or patchset) in buffer pData (size
+ ** nData bytes) to the changegroup. 
+@@ -9671,6 +10384,7 @@
+ 
+ /*
+ ** CAPI3REF: Obtain A Composite Changeset From A Changegroup
++** METHOD: sqlite3_changegroup
+ **
+ ** Obtain a buffer containing a changeset (or patchset) representing the
+ ** current contents of the changegroup. If the inputs to the changegroup
+@@ -9701,6 +10415,7 @@
+ 
+ /*
+ ** CAPI3REF: Delete A Changegroup Object
++** DESTRUCTOR: sqlite3_changegroup
+ */
+ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
+ 
+@@ -9707,19 +10422,18 @@
+ /*
+ ** CAPI3REF: Apply A Changeset To A Database
+ **
+-** Apply a changeset to a database. This function attempts to update the
+-** "main" database attached to handle db with the changes found in the
+-** changeset passed via the second and third arguments.
++** Apply a changeset or patchset to a database. These functions attempt to
++** update the "main" database attached to handle db with the changes found in
++** the changeset passed via the second and third arguments. 
+ **
+-** The fourth argument (xFilter) passed to this function is the "filter
++** The fourth argument (xFilter) passed to these functions is the "filter
+ ** callback". If it is not NULL, then for each table affected by at least one
+ ** change in the changeset, the filter callback is invoked with
+ ** the table name as the second argument, and a copy of the context pointer
+-** passed as the sixth argument to this function as the first. If the "filter
+-** callback" returns zero, then no attempt is made to apply any changes to 
+-** the table. Otherwise, if the return value is non-zero or the xFilter
+-** argument to this function is NULL, all changes related to the table are
+-** attempted.
++** passed as the sixth argument as the first. If the "filter callback"
++** returns zero, then no attempt is made to apply any changes to the table.
++** Otherwise, if the return value is non-zero or the xFilter argument to
++** is NULL, all changes related to the table are attempted.
+ **
+ ** For each table that is not excluded by the filter callback, this function 
+ ** tests that the target database contains a compatible table. A table is 
+@@ -9764,7 +10478,7 @@
+ **
+ ** <dl>
+ ** <dt>DELETE Changes<dd>
+-**   For each DELETE change, this function checks if the target database 
++**   For each DELETE change, the function checks if the target database 
+ **   contains a row with the same primary key value (or values) as the 
+ **   original row values stored in the changeset. If it does, and the values 
+ **   stored in all non-primary key columns also match the values stored in 
+@@ -9809,7 +10523,7 @@
+ **   [SQLITE_CHANGESET_REPLACE].
+ **
+ ** <dt>UPDATE Changes<dd>
+-**   For each UPDATE change, this function checks if the target database 
++**   For each UPDATE change, the function checks if the target database 
+ **   contains a row with the same primary key value (or values) as the 
+ **   original row values stored in the changeset. If it does, and the values 
+ **   stored in all modified non-primary key columns also match the values
+@@ -9840,11 +10554,28 @@
+ ** This can be used to further customize the applications conflict
+ ** resolution strategy.
+ **
+-** All changes made by this function are enclosed in a savepoint transaction.
++** All changes made by these functions are enclosed in a savepoint transaction.
+ ** If any other error (aside from a constraint failure when attempting to
+ ** write to the target database) occurs, then the savepoint transaction is
+ ** rolled back, restoring the target database to its original state, and an 
+ ** SQLite error code returned.
++**
++** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
++** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
++** may set (*ppRebase) to point to a "rebase" that may be used with the 
++** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
++** is set to the size of the buffer in bytes. It is the responsibility of the
++** caller to eventually free any such buffer using sqlite3_free(). The buffer
++** is only allocated and populated if one or more conflicts were encountered
++** while applying the patchset. See comments surrounding the sqlite3_rebaser
++** APIs for further details.
++**
++** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
++**
++** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_apply(
+   sqlite3 *db,                    /* Apply change to "main" db of this handle */
+@@ -9861,7 +10592,48 @@
+   ),
+   void *pCtx                      /* First argument passed to xConflict */
+ );
++SQLITE_API int sqlite3changeset_apply_v2(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int nChangeset,                 /* Size of changeset in bytes */
++  void *pChangeset,               /* Changeset blob */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase, /* OUT: Rebase data */
++  int flags                       /* SESSION_CHANGESETAPPLY_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_apply_v2
++**
++** The following flags may passed via the 9th parameter to
++** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
++**
++** <dl>
++** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
++**   Usually, the sessions module encloses all operations performed by
++**   a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
++**   SAVEPOINT is committed if the changeset or patchset is successfully
++**   applied, or rolled back if an error occurs. Specifying this flag
++**   causes the sessions module to omit this savepoint. In this case, if the
++**   caller has an open transaction or savepoint when apply_v2() is called, 
++**   it may revert the partially applied changeset by rolling it back.
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset before applying it. This is equivalent to inverting
++**   a changeset using sqlite3changeset_invert() before applying it. It is
++**   an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
++#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
++
+ /* 
+ ** CAPI3REF: Constants Passed To The Conflict Handler
+ **
+@@ -9958,7 +10730,162 @@
+ #define SQLITE_CHANGESET_REPLACE    1
+ #define SQLITE_CHANGESET_ABORT      2
+ 
++/* 
++** CAPI3REF: Rebasing changesets
++** EXPERIMENTAL
++**
++** Suppose there is a site hosting a database in state S0. And that
++** modifications are made that move that database to state S1 and a
++** changeset recorded (the "local" changeset). Then, a changeset based
++** on S0 is received from another site (the "remote" changeset) and 
++** applied to the database. The database is then in state 
++** (S1+"remote"), where the exact state depends on any conflict
++** resolution decisions (OMIT or REPLACE) made while applying "remote".
++** Rebasing a changeset is to update it to take those conflict 
++** resolution decisions into account, so that the same conflicts
++** do not have to be resolved elsewhere in the network. 
++**
++** For example, if both the local and remote changesets contain an
++** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
++**
++**   local:  INSERT INTO t1 VALUES(1, 'v1');
++**   remote: INSERT INTO t1 VALUES(1, 'v2');
++**
++** and the conflict resolution is REPLACE, then the INSERT change is
++** removed from the local changeset (it was overridden). Or, if the
++** conflict resolution was "OMIT", then the local changeset is modified
++** to instead contain:
++**
++**           UPDATE t1 SET b = 'v2' WHERE a=1;
++**
++** Changes within the local changeset are rebased as follows:
++**
++** <dl>
++** <dt>Local INSERT<dd>
++**   This may only conflict with a remote INSERT. If the conflict 
++**   resolution was OMIT, then add an UPDATE change to the rebased
++**   changeset. Or, if the conflict resolution was REPLACE, add
++**   nothing to the rebased changeset.
++**
++** <dt>Local DELETE<dd>
++**   This may conflict with a remote UPDATE or DELETE. In both cases the
++**   only possible resolution is OMIT. If the remote operation was a
++**   DELETE, then add no change to the rebased changeset. If the remote
++**   operation was an UPDATE, then the old.* fields of change are updated
++**   to reflect the new.* values in the UPDATE.
++**
++** <dt>Local UPDATE<dd>
++**   This may conflict with a remote UPDATE or DELETE. If it conflicts
++**   with a DELETE, and the conflict resolution was OMIT, then the update
++**   is changed into an INSERT. Any undefined values in the new.* record
++**   from the update change are filled in using the old.* values from
++**   the conflicting DELETE. Or, if the conflict resolution was REPLACE,
++**   the UPDATE change is simply omitted from the rebased changeset.
++**
++**   If conflict is with a remote UPDATE and the resolution is OMIT, then
++**   the old.* values are rebased using the new.* values in the remote
++**   change. Or, if the resolution is REPLACE, then the change is copied
++**   into the rebased changeset with updates to columns also updated by
++**   the conflicting remote UPDATE removed. If this means no columns would 
++**   be updated, the change is omitted.
++** </dl>
++**
++** A local change may be rebased against multiple remote changes 
++** simultaneously. If a single key is modified by multiple remote 
++** changesets, they are combined as follows before the local changeset
++** is rebased:
++**
++** <ul>
++**    <li> If there has been one or more REPLACE resolutions on a
++**         key, it is rebased according to a REPLACE.
++**
++**    <li> If there have been no REPLACE resolutions on a key, then
++**         the local changeset is rebased according to the most recent
++**         of the OMIT resolutions.
++** </ul>
++**
++** Note that conflict resolutions from multiple remote changesets are 
++** combined on a per-field basis, not per-row. This means that in the 
++** case of multiple remote UPDATE operations, some fields of a single 
++** local change may be rebased for REPLACE while others are rebased for 
++** OMIT.
++**
++** In order to rebase a local changeset, the remote changeset must first
++** be applied to the local database using sqlite3changeset_apply_v2() and
++** the buffer of rebase information captured. Then:
++**
++** <ol>
++**   <li> An sqlite3_rebaser object is created by calling 
++**        sqlite3rebaser_create().
++**   <li> The new object is configured with the rebase buffer obtained from
++**        sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
++**        If the local changeset is to be rebased against multiple remote
++**        changesets, then sqlite3rebaser_configure() should be called
++**        multiple times, in the same order that the multiple
++**        sqlite3changeset_apply_v2() calls were made.
++**   <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
++**   <li> The sqlite3_rebaser object is deleted by calling
++**        sqlite3rebaser_delete().
++** </ol>
++*/
++typedef struct sqlite3_rebaser sqlite3_rebaser;
++
+ /*
++** CAPI3REF: Create a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
++** point to the new object and return SQLITE_OK. Otherwise, if an error
++** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) 
++** to NULL. 
++*/
++SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
++
++/*
++** CAPI3REF: Configure a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Configure the changeset rebaser object to rebase changesets according
++** to the conflict resolutions described by buffer pRebase (size nRebase
++** bytes), which must have been obtained from a previous call to
++** sqlite3changeset_apply_v2().
++*/
++SQLITE_API int sqlite3rebaser_configure(
++  sqlite3_rebaser*, 
++  int nRebase, const void *pRebase
++); 
++
++/*
++** CAPI3REF: Rebase a changeset
++** EXPERIMENTAL
++**
++** Argument pIn must point to a buffer containing a changeset nIn bytes
++** in size. This function allocates and populates a buffer with a copy
++** of the changeset rebased rebased according to the configuration of the
++** rebaser object passed as the first argument. If successful, (*ppOut)
++** is set to point to the new buffer containing the rebased changset and 
++** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
++** responsibility of the caller to eventually free the new buffer using
++** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
++** are set to zero and an SQLite error code returned.
++*/
++SQLITE_API int sqlite3rebaser_rebase(
++  sqlite3_rebaser*,
++  int nIn, const void *pIn, 
++  int *pnOut, void **ppOut 
++);
++
++/*
++** CAPI3REF: Delete a changeset rebaser object.
++** EXPERIMENTAL
++**
++** Delete the changeset rebaser object and all associated resources. There
++** should be one call to this function for each successful invocation
++** of sqlite3rebaser_create().
++*/
++SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); 
++
++/*
+ ** CAPI3REF: Streaming Versions of API functions.
+ **
+ ** The six streaming API xxx_strm() functions serve similar purposes to the 
+@@ -9966,12 +10893,13 @@
+ **
+ ** <table border=1 style="margin-left:8ex;margin-right:8ex">
+ **   <tr><th>Streaming function<th>Non-streaming equivalent</th>
+-**   <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply] 
+-**   <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat] 
+-**   <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert] 
+-**   <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start] 
+-**   <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset] 
+-**   <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset] 
++**   <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] 
++**   <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] 
++**   <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] 
++**   <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] 
++**   <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] 
++**   <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] 
++**   <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] 
+ ** </table>
+ **
+ ** Non-streaming functions that accept changesets (or patchsets) as input
+@@ -10062,6 +10990,23 @@
+   ),
+   void *pCtx                      /* First argument passed to xConflict */
+ );
++SQLITE_API int sqlite3changeset_apply_v2_strm(
++  sqlite3 *db,                    /* Apply change to "main" db of this handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
++  void *pIn,                                          /* First arg for xInput */
++  int(*xFilter)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    const char *zTab              /* Table name */
++  ),
++  int(*xConflict)(
++    void *pCtx,                   /* Copy of sixth arg to _apply() */
++    int eConflict,                /* DATA, MISSING, CONFLICT, CONSTRAINT */
++    sqlite3_changeset_iter *p     /* Handle describing change and conflict */
++  ),
++  void *pCtx,                     /* First argument passed to xConflict */
++  void **ppRebase, int *pnRebase,
++  int flags
++);
+ SQLITE_API int sqlite3changeset_concat_strm(
+   int (*xInputA)(void *pIn, void *pData, int *pnData),
+   void *pInA,
+@@ -10081,6 +11026,12 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ );
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++);
+ SQLITE_API int sqlite3session_changeset_strm(
+   sqlite3_session *pSession,
+   int (*xOutput)(void *pOut, const void *pData, int nData),
+@@ -10099,9 +11050,55 @@
+     int (*xOutput)(void *pOut, const void *pData, int nData), 
+     void *pOut
+ );
++SQLITE_API int sqlite3rebaser_rebase_strm(
++  sqlite3_rebaser *pRebaser,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int (*xOutput)(void *pOut, const void *pData, int nData),
++  void *pOut
++);
+ 
++/*
++** CAPI3REF: Configure global parameters
++**
++** The sqlite3session_config() interface is used to make global configuration
++** changes to the sessions module in order to tune it to the specific needs 
++** of the application.
++**
++** The sqlite3session_config() interface is not threadsafe. If it is invoked
++** while any other thread is inside any other sessions method then the
++** results are undefined. Furthermore, if it is invoked after any sessions
++** related objects have been created, the results are also undefined. 
++**
++** The first argument to the sqlite3session_config() function must be one
++** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The 
++** interpretation of the (void*) value passed as the second parameter and
++** the effect of calling this function depends on the value of the first
++** parameter.
++**
++** <dl>
++** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
++**    By default, the sessions module streaming interfaces attempt to input
++**    and output data in approximately 1 KiB chunks. This operand may be used
++**    to set and query the value of this configuration setting. The pointer
++**    passed as the second argument must point to a value of type (int).
++**    If this value is greater than 0, it is used as the new streaming data
++**    chunk size for both input and output. Before returning, the (int) value
++**    pointed to by pArg is set to the final value of the streaming interface
++**    chunk size.
++** </dl>
++**
++** This function returns SQLITE_OK if successful, or an SQLite error code
++** otherwise.
++*/
++SQLITE_API int sqlite3session_config(int op, void *pArg);
+ 
+ /*
++** CAPI3REF: Values for sqlite3session_config().
++*/
++#define SQLITE_SESSION_CONFIG_STRMSIZE 1
++
++/*
+ ** Make sure we can call this stuff from C++.
+ */
+ #ifdef __cplusplus
+@@ -10557,7 +11554,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -10585,7 +11582,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+--- contrib/sqlite3/sqlite3ext.h.orig
++++ contrib/sqlite3/sqlite3ext.h
+@@ -134,7 +134,7 @@
+   int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
+                          const char*,const char*),void*);
+   void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
+-  char * (*snprintf)(int,char*,const char*,...);
++  char * (*xsnprintf)(int,char*,const char*,...);
+   int  (*step)(sqlite3_stmt*);
+   int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
+                                 char const**,char const**,int*,int*,int*);
+@@ -246,7 +246,7 @@
+   int (*uri_boolean)(const char*,const char*,int);
+   sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
+   const char *(*uri_parameter)(const char*,const char*);
+-  char *(*vsnprintf)(int,char*,const char*,va_list);
++  char *(*xvsnprintf)(int,char*,const char*,va_list);
+   int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+   /* Version 3.8.7 and later */
+   int (*auto_extension)(void(*)(void));
+@@ -292,6 +292,33 @@
+   int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+   void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
+   void *(*value_pointer)(sqlite3_value*,const char*);
++  int (*vtab_nochange)(sqlite3_context*);
++  int (*value_nochange)(sqlite3_value*);
++  const char *(*vtab_collation)(sqlite3_index_info*,int);
++  /* Version 3.24.0 and later */
++  int (*keyword_count)(void);
++  int (*keyword_name)(int,const char**,int*);
++  int (*keyword_check)(const char*,int);
++  sqlite3_str *(*str_new)(sqlite3*);
++  char *(*str_finish)(sqlite3_str*);
++  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
++  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
++  void (*str_append)(sqlite3_str*, const char *zIn, int N);
++  void (*str_appendall)(sqlite3_str*, const char *zIn);
++  void (*str_appendchar)(sqlite3_str*, int N, char C);
++  void (*str_reset)(sqlite3_str*);
++  int (*str_errcode)(sqlite3_str*);
++  int (*str_length)(sqlite3_str*);
++  char *(*str_value)(sqlite3_str*);
++  /* Version 3.25.0 and later */
++  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
++                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++                            void (*xFinal)(sqlite3_context*),
++                            void (*xValue)(sqlite3_context*),
++                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
++                            void(*xDestroy)(void*));
++  /* Version 3.26.0 and later */
++  const char *(*normalized_sql)(sqlite3_stmt*);
+ };
+ 
+ /*
+@@ -418,7 +445,7 @@
+ #define sqlite3_rollback_hook          sqlite3_api->rollback_hook
+ #define sqlite3_set_authorizer         sqlite3_api->set_authorizer
+ #define sqlite3_set_auxdata            sqlite3_api->set_auxdata
+-#define sqlite3_snprintf               sqlite3_api->snprintf
++#define sqlite3_snprintf               sqlite3_api->xsnprintf
+ #define sqlite3_step                   sqlite3_api->step
+ #define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
+ #define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
+@@ -442,7 +469,7 @@
+ #define sqlite3_value_text16le         sqlite3_api->value_text16le
+ #define sqlite3_value_type             sqlite3_api->value_type
+ #define sqlite3_vmprintf               sqlite3_api->vmprintf
+-#define sqlite3_vsnprintf              sqlite3_api->vsnprintf
++#define sqlite3_vsnprintf              sqlite3_api->xvsnprintf
+ #define sqlite3_overload_function      sqlite3_api->overload_function
+ #define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+ #define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+@@ -518,7 +545,7 @@
+ #define sqlite3_uri_boolean            sqlite3_api->uri_boolean
+ #define sqlite3_uri_int64              sqlite3_api->uri_int64
+ #define sqlite3_uri_parameter          sqlite3_api->uri_parameter
+-#define sqlite3_uri_vsnprintf          sqlite3_api->vsnprintf
++#define sqlite3_uri_vsnprintf          sqlite3_api->xvsnprintf
+ #define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
+ /* Version 3.8.7 and later */
+ #define sqlite3_auto_extension         sqlite3_api->auto_extension
+@@ -558,6 +585,29 @@
+ #define sqlite3_bind_pointer           sqlite3_api->bind_pointer
+ #define sqlite3_result_pointer         sqlite3_api->result_pointer
+ #define sqlite3_value_pointer          sqlite3_api->value_pointer
++/* Version 3.22.0 and later */
++#define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
++#define sqlite3_value_nochange         sqlite3_api->value_nochange
++#define sqlite3_vtab_collation         sqlite3_api->vtab_collation
++/* Version 3.24.0 and later */
++#define sqlite3_keyword_count          sqlite3_api->keyword_count
++#define sqlite3_keyword_name           sqlite3_api->keyword_name
++#define sqlite3_keyword_check          sqlite3_api->keyword_check
++#define sqlite3_str_new                sqlite3_api->str_new
++#define sqlite3_str_finish             sqlite3_api->str_finish
++#define sqlite3_str_appendf            sqlite3_api->str_appendf
++#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
++#define sqlite3_str_append             sqlite3_api->str_append
++#define sqlite3_str_appendall          sqlite3_api->str_appendall
++#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
++#define sqlite3_str_reset              sqlite3_api->str_reset
++#define sqlite3_str_errcode            sqlite3_api->str_errcode
++#define sqlite3_str_length             sqlite3_api->str_length
++#define sqlite3_str_value              sqlite3_api->str_value
++/* Version 3.25.0 and later */
++#define sqlite3_create_window_function sqlite3_api->create_window_function
++/* Version 3.26.0 and later */
++#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
+ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+ 
+ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+--- contrib/sqlite3/tea/configure.orig
++++ contrib/sqlite3/tea/configure
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.69 for sqlite 3.20.0.
++# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
+ #
+ #
+ # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+@@ -577,8 +577,8 @@
+ # Identity of this package.
+ PACKAGE_NAME='sqlite'
+ PACKAGE_TARNAME='sqlite'
+-PACKAGE_VERSION='3.20.0'
+-PACKAGE_STRING='sqlite 3.20.0'
++PACKAGE_VERSION='3.26.0'
++PACKAGE_STRING='sqlite 3.26.0'
+ PACKAGE_BUGREPORT=''
+ PACKAGE_URL=''
+ 
+@@ -1292,7 +1292,7 @@
+   # Omit some internal or obsolete options to make the list less imposing.
+   # This message is too long to be a string in the A/UX 3.1 sh.
+   cat <<_ACEOF
+-\`configure' configures sqlite 3.20.0 to adapt to many kinds of systems.
++\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
+ 
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+ 
+@@ -1353,7 +1353,7 @@
+ 
+ if test -n "$ac_init_help"; then
+   case $ac_init_help in
+-     short | recursive ) echo "Configuration of sqlite 3.20.0:";;
++     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
+    esac
+   cat <<\_ACEOF
+ 
+@@ -1455,7 +1455,7 @@
+ test -n "$ac_init_help" && exit $ac_status
+ if $ac_init_version; then
+   cat <<\_ACEOF
+-sqlite configure 3.20.0
++sqlite configure 3.26.0
+ generated by GNU Autoconf 2.69
+ 
+ Copyright (C) 2012 Free Software Foundation, Inc.
+@@ -1866,7 +1866,7 @@
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+ 
+-It was created by sqlite $as_me 3.20.0, which was
++It was created by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   $ $0 $@
+@@ -9361,7 +9361,7 @@
+ # report actual input values of CONFIG_FILES etc. instead of their
+ # values after options handling.
+ ac_log="
+-This file was extended by sqlite $as_me 3.20.0, which was
++This file was extended by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   CONFIG_FILES    = $CONFIG_FILES
+@@ -9414,7 +9414,7 @@
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ ac_cs_version="\\
+-sqlite config.status 3.20.0
++sqlite config.status 3.26.0
+ configured by $0, generated by GNU Autoconf 2.69,
+   with options \\"\$ac_cs_config\\"
+ 
+--- contrib/sqlite3/tea/configure.ac.orig
++++ contrib/sqlite3/tea/configure.ac
+@@ -19,7 +19,7 @@
+ # so you can encode the package version directly into the source files.
+ #-----------------------------------------------------------------------
+ 
+-AC_INIT([sqlite], [3.20.0])
++AC_INIT([sqlite], [3.26.0])
+ 
+ #--------------------------------------------------------------------
+ # Call TEA_INIT as the first TEA_ macro to set up initial vars.
+--- contrib/sqlite3/tea/generic/tclsqlite3.c.orig
++++ contrib/sqlite3/tea/generic/tclsqlite3.c
+@@ -19,17 +19,19 @@
+ **
+ ** Compile-time options:
+ **
+-**  -DTCLSH=1             Add a "main()" routine that works as a tclsh.
++**  -DTCLSH         Add a "main()" routine that works as a tclsh.
+ **
+-**  -DSQLITE_TCLMD5       When used in conjuction with -DTCLSH=1, add
+-**                        four new commands to the TCL interpreter for
+-**                        generating MD5 checksums:  md5, md5file,
+-**                        md5-10x8, and md5file-10x8.
++**  -DTCLSH_INIT_PROC=name
+ **
+-**  -DSQLITE_TEST         When used in conjuction with -DTCLSH=1, add
+-**                        hundreds of new commands used for testing
+-**                        SQLite.  This option implies -DSQLITE_TCLMD5.
++**                  Invoke name(interp) to initialize the Tcl interpreter.
++**                  If name(interp) returns a non-NULL string, then run
++**                  that string as a Tcl script to launch the application.
++**                  If name(interp) returns NULL, then run the regular
++**                  tclsh-emulator code.
+ */
++#ifdef TCLSH_INIT_PROC
++# define TCLSH 1
++#endif
+ 
+ /*
+ ** If requested, include the SQLite compiler options file for MSVC.
+@@ -63,13 +65,18 @@
+ 
+ /* Used to get the current process ID */
+ #if !defined(_WIN32)
++# include <signal.h>
+ # include <unistd.h>
+ # define GETPID getpid
+ #elif !defined(_WIN32_WCE)
+ # ifndef SQLITE_AMALGAMATION
+-#  define WIN32_LEAN_AND_MEAN
++#  ifndef WIN32_LEAN_AND_MEAN
++#   define WIN32_LEAN_AND_MEAN
++#  endif
+ #  include <windows.h>
+ # endif
++# include <io.h>
++# define isatty(h) _isatty(h)
+ # define GETPID (int)GetCurrentProcessId
+ #endif
+ 
+@@ -649,7 +656,7 @@
+     }
+     case SQLITE_TRACE_PROFILE: {
+       sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
+-      sqlite3_int64 ns = (sqlite3_int64)xd;
++      sqlite3_int64 ns = *(sqlite3_int64*)xd;
+ 
+       pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
+       Tcl_IncrRefCount(pCmd);
+@@ -1849,35 +1856,35 @@
+   int choice;
+   int rc = TCL_OK;
+   static const char *DB_strs[] = {
+-    "authorizer",         "backup",            "busy",
+-    "cache",              "changes",           "close",
+-    "collate",            "collation_needed",  "commit_hook",
+-    "complete",           "copy",              "enable_load_extension",
+-    "errorcode",          "eval",              "exists",
+-    "function",           "incrblob",          "interrupt",
+-    "last_insert_rowid",  "nullvalue",         "onecolumn",
+-    "preupdate",          "profile",           "progress",
+-    "rekey",              "restore",           "rollback_hook",
+-    "status",             "timeout",           "total_changes",
+-    "trace",              "trace_v2",          "transaction",
+-    "unlock_notify",      "update_hook",       "version",
+-    "wal_hook",
+-    0
++    "authorizer",             "backup",                "busy",
++    "cache",                  "changes",               "close",
++    "collate",                "collation_needed",      "commit_hook",
++    "complete",               "copy",                  "deserialize",
++    "enable_load_extension",  "errorcode",             "eval",
++    "exists",                 "function",              "incrblob",
++    "interrupt",              "last_insert_rowid",     "nullvalue",
++    "onecolumn",              "preupdate",             "profile",
++    "progress",               "rekey",                 "restore",
++    "rollback_hook",          "serialize",             "status",
++    "timeout",                "total_changes",         "trace",
++    "trace_v2",               "transaction",           "unlock_notify",
++    "update_hook",            "version",               "wal_hook",
++    0                        
+   };
+   enum DB_enum {
+-    DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
+-    DB_CACHE,             DB_CHANGES,          DB_CLOSE,
+-    DB_COLLATE,           DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
+-    DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION,
+-    DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
+-    DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
+-    DB_LAST_INSERT_ROWID, DB_NULLVALUE,        DB_ONECOLUMN,
+-    DB_PREUPDATE,         DB_PROFILE,          DB_PROGRESS,
+-    DB_REKEY,             DB_RESTORE,          DB_ROLLBACK_HOOK,
+-    DB_STATUS,            DB_TIMEOUT,          DB_TOTAL_CHANGES,
+-    DB_TRACE,             DB_TRACE_V2,         DB_TRANSACTION,
+-    DB_UNLOCK_NOTIFY,     DB_UPDATE_HOOK,      DB_VERSION,
+-    DB_WAL_HOOK,
++    DB_AUTHORIZER,            DB_BACKUP,               DB_BUSY,
++    DB_CACHE,                 DB_CHANGES,              DB_CLOSE,
++    DB_COLLATE,               DB_COLLATION_NEEDED,     DB_COMMIT_HOOK,
++    DB_COMPLETE,              DB_COPY,                 DB_DESERIALIZE,
++    DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE,            DB_EVAL,
++    DB_EXISTS,                DB_FUNCTION,             DB_INCRBLOB,
++    DB_INTERRUPT,             DB_LAST_INSERT_ROWID,    DB_NULLVALUE,
++    DB_ONECOLUMN,             DB_PREUPDATE,            DB_PROFILE,
++    DB_PROGRESS,              DB_REKEY,                DB_RESTORE,
++    DB_ROLLBACK_HOOK,         DB_SERIALIZE,            DB_STATUS,
++    DB_TIMEOUT,               DB_TOTAL_CHANGES,        DB_TRACE,
++    DB_TRACE_V2,              DB_TRANSACTION,          DB_UNLOCK_NOTIFY,
++    DB_UPDATE_HOOK,           DB_VERSION,              DB_WAL_HOOK
+   };
+   /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
+ 
+@@ -2416,6 +2423,53 @@
+   }
+ 
+   /*
++  **     $db deserialize ?DATABASE? VALUE
++  **
++  ** Reopen DATABASE (default "main") using the content in $VALUE
++  */
++  case DB_DESERIALIZE: {
++#ifndef SQLITE_ENABLE_DESERIALIZE
++    Tcl_AppendResult(interp, "MEMDB not available in this build",
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    const char *zSchema;
++    Tcl_Obj *pValue;
++    unsigned char *pBA;
++    unsigned char *pData;
++    int len, xrc;
++    
++    if( objc==3 ){
++      zSchema = 0;
++      pValue = objv[2];
++    }else if( objc==4 ){
++      zSchema = Tcl_GetString(objv[2]);
++      pValue = objv[3];
++    }else{
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
++      rc = TCL_ERROR;
++      break;
++    }
++    pBA = Tcl_GetByteArrayFromObj(pValue, &len);
++    pData = sqlite3_malloc64( len );
++    if( pData==0 && len>0 ){
++      Tcl_AppendResult(interp, "out of memory", (char*)0);
++      rc = TCL_ERROR;
++    }else{
++      if( len>0 ) memcpy(pData, pBA, len);
++      xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
++                SQLITE_DESERIALIZE_FREEONCLOSE |
++                SQLITE_DESERIALIZE_RESIZEABLE);
++      if( xrc ){
++        Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
++        rc = TCL_ERROR;
++      }
++    }
++#endif
++    break; 
++  }
++
++  /*
+   **    $db enable_load_extension BOOLEAN
+   **
+   ** Turn the extension loading feature on or off.  It if off by
+@@ -2891,6 +2945,39 @@
+   }
+ 
+   /*
++  **     $db serialize ?DATABASE?
++  **
++  ** Return a serialization of a database.  
++  */
++  case DB_SERIALIZE: {
++#ifndef SQLITE_ENABLE_DESERIALIZE
++    Tcl_AppendResult(interp, "MEMDB not available in this build",
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
++    sqlite3_int64 sz = 0;
++    unsigned char *pData;
++    if( objc!=2 && objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
++      rc = TCL_ERROR;
++    }else{
++      int needFree;
++      pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
++      if( pData ){
++        needFree = 0;
++      }else{
++        pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
++        needFree = 1;
++      }
++      Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
++      if( needFree ) sqlite3_free(pData);
++    }
++#endif
++    break;
++  }
++
++  /*
+   **     $db status (step|sort|autoindex|vmstep)
+   **
+   ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
+@@ -3291,7 +3378,42 @@
+   ** Return the version string for this database.
+   */
+   case DB_VERSION: {
+-    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
++    int i;
++    for(i=2; i<objc; i++){
++      const char *zArg = Tcl_GetString(objv[i]);
++      /* Optional arguments to $db version are used for testing purpose */
++#ifdef SQLITE_TEST
++      /* $db version -use-legacy-prepare BOOLEAN
++      **
++      ** Turn the use of legacy sqlite3_prepare() on or off.
++      */
++      if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
++        i++;
++        if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
++          return TCL_ERROR;
++        }
++      }else
++
++      /* $db version -last-stmt-ptr
++      **
++      ** Return a string which is a hex encoding of the pointer to the
++      ** most recent sqlite3_stmt in the statement cache.
++      */
++      if( strcmp(zArg, "-last-stmt-ptr")==0 ){
++        char zBuf[100];
++        sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
++                         pDb->stmtList ? pDb->stmtList->pStmt: 0);
++        Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
++      }else
++#endif /* SQLITE_TEST */
++      {
++        Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
++        return TCL_ERROR;
++      }
++    }
++    if( i==2 ){   
++      Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
++    }
+     break;
+   }
+ 
+@@ -3316,6 +3438,24 @@
+ #endif /* SQLITE_TCL_NRE */
+ 
+ /*
++** Issue the usage message when the "sqlite3" command arguments are
++** incorrect.
++*/
++static int sqliteCmdUsage(
++  Tcl_Interp *interp,
++  Tcl_Obj *const*objv
++){
++  Tcl_WrongNumArgs(interp, 1, objv,
++    "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
++    " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++    " ?-key CODECKEY?"
++#endif
++  );
++  return TCL_ERROR;
++}
++
++/*
+ **   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
+ **                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
+ **
+@@ -3340,7 +3480,7 @@
+   const char *zArg;
+   char *zErrMsg;
+   int i;
+-  const char *zFile;
++  const char *zFile = 0;
+   const char *zVfs = 0;
+   int flags;
+   Tcl_DString translatedFilename;
+@@ -3351,7 +3491,7 @@
+   int rc;
+ 
+   /* In normal use, each TCL interpreter runs in a single thread.  So
+-  ** by default, we can turn of mutexing on SQLite database connections.
++  ** by default, we can turn off mutexing on SQLite database connections.
+   ** However, for testing purposes it is useful to have mutexes turned
+   ** on.  So, by default, mutexes default off.  But if compiled with
+   ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
+@@ -3362,6 +3502,7 @@
+   flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
+ #endif
+ 
++  if( objc==1 ) return sqliteCmdUsage(interp, objv);
+   if( objc==2 ){
+     zArg = Tcl_GetStringFromObj(objv[1], 0);
+     if( strcmp(zArg,"-version")==0 ){
+@@ -3380,18 +3521,26 @@
+ #endif
+       return TCL_OK;
+     }
++    if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
+   }
+-  for(i=3; i+1<objc; i+=2){
++  for(i=2; i<objc; i++){
+     zArg = Tcl_GetString(objv[i]);
++    if( zArg[0]!='-' ){
++      if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
++      zFile = zArg;
++      continue;
++    }
++    if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
++    i++;
+     if( strcmp(zArg,"-key")==0 ){
+ #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
+-      pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
++      pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
+ #endif
+     }else if( strcmp(zArg, "-vfs")==0 ){
+-      zVfs = Tcl_GetString(objv[i+1]);
++      zVfs = Tcl_GetString(objv[i]);
+     }else if( strcmp(zArg, "-readonly")==0 ){
+       int b;
+-      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
+       if( b ){
+         flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+         flags |= SQLITE_OPEN_READONLY;
+@@ -3401,7 +3550,7 @@
+       }
+     }else if( strcmp(zArg, "-create")==0 ){
+       int b;
+-      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
+       if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
+         flags |= SQLITE_OPEN_CREATE;
+       }else{
+@@ -3409,7 +3558,7 @@
+       }
+     }else if( strcmp(zArg, "-nomutex")==0 ){
+       int b;
+-      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
+       if( b ){
+         flags |= SQLITE_OPEN_NOMUTEX;
+         flags &= ~SQLITE_OPEN_FULLMUTEX;
+@@ -3418,7 +3567,7 @@
+       }
+     }else if( strcmp(zArg, "-fullmutex")==0 ){
+       int b;
+-      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
+       if( b ){
+         flags |= SQLITE_OPEN_FULLMUTEX;
+         flags &= ~SQLITE_OPEN_NOMUTEX;
+@@ -3427,7 +3576,7 @@
+       }
+     }else if( strcmp(zArg, "-uri")==0 ){
+       int b;
+-      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
+       if( b ){
+         flags |= SQLITE_OPEN_URI;
+       }else{
+@@ -3438,20 +3587,10 @@
+       return TCL_ERROR;
+     }
+   }
+-  if( objc<3 || (objc&1)!=1 ){
+-    Tcl_WrongNumArgs(interp, 1, objv,
+-      "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
+-      " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
+-#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
+-      " ?-key CODECKEY?"
+-#endif
+-    );
+-    return TCL_ERROR;
+-  }
+   zErrMsg = 0;
+   p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
+   memset(p, 0, sizeof(*p));
+-  zFile = Tcl_GetStringFromObj(objv[2], 0);
++  if( zFile==0 ) zFile = "";
+   zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
+   rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
+   Tcl_DStringFree(&translatedFilename);
+@@ -3551,731 +3690,74 @@
+ int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
+ #endif
+ 
+-#ifdef TCLSH
+-/*****************************************************************************
+-** All of the code that follows is used to build standalone TCL interpreters
+-** that are statically linked with SQLite.  Enable these by compiling
+-** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
+-** tclsh but with SQLite built in.  An n of 2 generates the SQLite space
+-** analysis program.
+-*/
+-
+-#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
+ /*
+- * This code implements the MD5 message-digest algorithm.
+- * The algorithm is due to Ron Rivest.  This code was
+- * written by Colin Plumb in 1993, no copyright is claimed.
+- * This code is in the public domain; do with it what you wish.
+- *
+- * Equivalent code is available from RSA Data Security, Inc.
+- * This code has been tested against that, and is equivalent,
+- * except that you don't need to include two pages of legalese
+- * with every copy.
+- *
+- * To compute the message digest of a chunk of bytes, declare an
+- * MD5Context structure, pass it to MD5Init, call MD5Update as
+- * needed on buffers full of bytes, and then call MD5Final, which
+- * will fill a supplied 16-byte array with the digest.
+- */
+-
+-/*
+- * If compiled on a machine that doesn't have a 32-bit integer,
+- * you just set "uint32" to the appropriate datatype for an
+- * unsigned 32-bit integer.  For example:
+- *
+- *       cc -Duint32='unsigned long' md5.c
+- *
+- */
+-#ifndef uint32
+-#  define uint32 unsigned int
+-#endif
+-
+-struct MD5Context {
+-  int isInit;
+-  uint32 buf[4];
+-  uint32 bits[2];
+-  unsigned char in[64];
+-};
+-typedef struct MD5Context MD5Context;
+-
+-/*
+- * Note: this code is harmless on little-endian machines.
+- */
+-static void byteReverse (unsigned char *buf, unsigned longs){
+-        uint32 t;
+-        do {
+-                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
+-                            ((unsigned)buf[1]<<8 | buf[0]);
+-                *(uint32 *)buf = t;
+-                buf += 4;
+-        } while (--longs);
+-}
+-/* The four core functions - F1 is optimized somewhat */
+-
+-/* #define F1(x, y, z) (x & y | ~x & z) */
+-#define F1(x, y, z) (z ^ (x & (y ^ z)))
+-#define F2(x, y, z) F1(z, x, y)
+-#define F3(x, y, z) (x ^ y ^ z)
+-#define F4(x, y, z) (y ^ (x | ~z))
+-
+-/* This is the central step in the MD5 algorithm. */
+-#define MD5STEP(f, w, x, y, z, data, s) \
+-        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+-
+-/*
+- * The core of the MD5 algorithm, this alters an existing MD5 hash to
+- * reflect the addition of 16 longwords of new data.  MD5Update blocks
+- * the data and converts bytes into longwords for this routine.
+- */
+-static void MD5Transform(uint32 buf[4], const uint32 in[16]){
+-        register uint32 a, b, c, d;
+-
+-        a = buf[0];
+-        b = buf[1];
+-        c = buf[2];
+-        d = buf[3];
+-
+-        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
+-        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
+-        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
+-        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
+-        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
+-        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
+-        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
+-        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
+-        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
+-        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
+-        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
+-        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
+-        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
+-        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
+-        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
+-        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
+-
+-        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
+-        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
+-        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
+-        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
+-        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
+-        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
+-        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
+-        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
+-        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
+-        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
+-        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
+-        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
+-        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
+-        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
+-        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
+-        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
+-
+-        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
+-        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
+-        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
+-        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
+-        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
+-        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
+-        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
+-        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
+-        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
+-        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
+-        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
+-        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
+-        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
+-        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
+-        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
+-        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
+-
+-        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
+-        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
+-        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
+-        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
+-        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
+-        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
+-        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
+-        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
+-        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
+-        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
+-        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
+-        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
+-        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
+-        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
+-        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
+-        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
+-
+-        buf[0] += a;
+-        buf[1] += b;
+-        buf[2] += c;
+-        buf[3] += d;
+-}
+-
+-/*
+- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+- * initialization constants.
+- */
+-static void MD5Init(MD5Context *ctx){
+-        ctx->isInit = 1;
+-        ctx->buf[0] = 0x67452301;
+-        ctx->buf[1] = 0xefcdab89;
+-        ctx->buf[2] = 0x98badcfe;
+-        ctx->buf[3] = 0x10325476;
+-        ctx->bits[0] = 0;
+-        ctx->bits[1] = 0;
+-}
+-
+-/*
+- * Update context to reflect the concatenation of another buffer full
+- * of bytes.
+- */
+-static
+-void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
+-        uint32 t;
+-
+-        /* Update bitcount */
+-
+-        t = ctx->bits[0];
+-        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
+-                ctx->bits[1]++; /* Carry from low to high */
+-        ctx->bits[1] += len >> 29;
+-
+-        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
+-
+-        /* Handle any leading odd-sized chunks */
+-
+-        if ( t ) {
+-                unsigned char *p = (unsigned char *)ctx->in + t;
+-
+-                t = 64-t;
+-                if (len < t) {
+-                        memcpy(p, buf, len);
+-                        return;
+-                }
+-                memcpy(p, buf, t);
+-                byteReverse(ctx->in, 16);
+-                MD5Transform(ctx->buf, (uint32 *)ctx->in);
+-                buf += t;
+-                len -= t;
+-        }
+-
+-        /* Process data in 64-byte chunks */
+-
+-        while (len >= 64) {
+-                memcpy(ctx->in, buf, 64);
+-                byteReverse(ctx->in, 16);
+-                MD5Transform(ctx->buf, (uint32 *)ctx->in);
+-                buf += 64;
+-                len -= 64;
+-        }
+-
+-        /* Handle any remaining bytes of data. */
+-
+-        memcpy(ctx->in, buf, len);
+-}
+-
+-/*
+- * Final wrapup - pad to 64-byte boundary with the bit pattern
+- * 1 0* (64-bit count of bits processed, MSB-first)
+- */
+-static void MD5Final(unsigned char digest[16], MD5Context *ctx){
+-        unsigned count;
+-        unsigned char *p;
+-
+-        /* Compute number of bytes mod 64 */
+-        count = (ctx->bits[0] >> 3) & 0x3F;
+-
+-        /* Set the first char of padding to 0x80.  This is safe since there is
+-           always at least one byte free */
+-        p = ctx->in + count;
+-        *p++ = 0x80;
+-
+-        /* Bytes of padding needed to make 64 bytes */
+-        count = 64 - 1 - count;
+-
+-        /* Pad out to 56 mod 64 */
+-        if (count < 8) {
+-                /* Two lots of padding:  Pad the first block to 64 bytes */
+-                memset(p, 0, count);
+-                byteReverse(ctx->in, 16);
+-                MD5Transform(ctx->buf, (uint32 *)ctx->in);
+-
+-                /* Now fill the next block with 56 bytes */
+-                memset(ctx->in, 0, 56);
+-        } else {
+-                /* Pad block to 56 bytes */
+-                memset(p, 0, count-8);
+-        }
+-        byteReverse(ctx->in, 14);
+-
+-        /* Append length in bits and transform */
+-        memcpy(ctx->in + 14*4, ctx->bits, 8);
+-
+-        MD5Transform(ctx->buf, (uint32 *)ctx->in);
+-        byteReverse((unsigned char *)ctx->buf, 4);
+-        memcpy(digest, ctx->buf, 16);
+-}
+-
+-/*
+-** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
++** If the TCLSH macro is defined, add code to make a stand-alone program.
+ */
+-static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
+-  static char const zEncode[] = "0123456789abcdef";
+-  int i, j;
++#if defined(TCLSH)
+ 
+-  for(j=i=0; i<16; i++){
+-    int a = digest[i];
+-    zBuf[j++] = zEncode[(a>>4)&0xf];
+-    zBuf[j++] = zEncode[a & 0xf];
+-  }
+-  zBuf[j] = 0;
+-}
+-
+-
+-/*
+-** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
+-** each representing 16 bits of the digest and separated from each
+-** other by a "-" character.
++/* This is the main routine for an ordinary TCL shell.  If there are
++** are arguments, run the first argument as a script.  Otherwise,
++** read TCL commands from standard input
+ */
+-static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
+-  int i, j;
+-  unsigned int x;
+-  for(i=j=0; i<16; i+=2){
+-    x = digest[i]*256 + digest[i+1];
+-    if( i>0 ) zDigest[j++] = '-';
+-    sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
+-    j += 5;
+-  }
+-  zDigest[j] = 0;
+-}
+-
+-/*
+-** A TCL command for md5.  The argument is the text to be hashed.  The
+-** Result is the hash in base64.
+-*/
+-static int SQLITE_TCLAPI md5_cmd(
+-  void*cd,
+-  Tcl_Interp *interp,
+-  int argc,
+-  const char **argv
+-){
+-  MD5Context ctx;
+-  unsigned char digest[16];
+-  char zBuf[50];
+-  void (*converter)(unsigned char*, char*);
+-
+-  if( argc!=2 ){
+-    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
+-        " TEXT\"", (char*)0);
+-    return TCL_ERROR;
+-  }
+-  MD5Init(&ctx);
+-  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
+-  MD5Final(digest, &ctx);
+-  converter = (void(*)(unsigned char*,char*))cd;
+-  converter(digest, zBuf);
+-  Tcl_AppendResult(interp, zBuf, (char*)0);
+-  return TCL_OK;
+-}
+-
+-/*
+-** A TCL command to take the md5 hash of a file.  The argument is the
+-** name of the file.
+-*/
+-static int SQLITE_TCLAPI md5file_cmd(
+-  void*cd,
+-  Tcl_Interp *interp,
+-  int argc,
+-  const char **argv
+-){
+-  FILE *in;
+-  MD5Context ctx;
+-  void (*converter)(unsigned char*, char*);
+-  unsigned char digest[16];
+-  char zBuf[10240];
+-
+-  if( argc!=2 ){
+-    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
+-        " FILENAME\"", (char*)0);
+-    return TCL_ERROR;
+-  }
+-  in = fopen(argv[1],"rb");
+-  if( in==0 ){
+-    Tcl_AppendResult(interp,"unable to open file \"", argv[1],
+-         "\" for reading", (char*)0);
+-    return TCL_ERROR;
+-  }
+-  MD5Init(&ctx);
+-  for(;;){
+-    int n;
+-    n = (int)fread(zBuf, 1, sizeof(zBuf), in);
+-    if( n<=0 ) break;
+-    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
+-  }
+-  fclose(in);
+-  MD5Final(digest, &ctx);
+-  converter = (void(*)(unsigned char*,char*))cd;
+-  converter(digest, zBuf);
+-  Tcl_AppendResult(interp, zBuf, (char*)0);
+-  return TCL_OK;
+-}
+-
+-/*
+-** Register the four new TCL commands for generating MD5 checksums
+-** with the TCL interpreter.
+-*/
+-int Md5_Init(Tcl_Interp *interp){
+-  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
+-                    MD5DigestToBase16, 0);
+-  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
+-                    MD5DigestToBase10x8, 0);
+-  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
+-                    MD5DigestToBase16, 0);
+-  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
+-                    MD5DigestToBase10x8, 0);
+-  return TCL_OK;
+-}
+-#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
+-
+-#if defined(SQLITE_TEST)
+-/*
+-** During testing, the special md5sum() aggregate function is available.
+-** inside SQLite.  The following routines implement that function.
+-*/
+-static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
+-  MD5Context *p;
+-  int i;
+-  if( argc<1 ) return;
+-  p = sqlite3_aggregate_context(context, sizeof(*p));
+-  if( p==0 ) return;
+-  if( !p->isInit ){
+-    MD5Init(p);
+-  }
+-  for(i=0; i<argc; i++){
+-    const char *zData = (char*)sqlite3_value_text(argv[i]);
+-    if( zData ){
+-      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
+-    }
+-  }
+-}
+-static void md5finalize(sqlite3_context *context){
+-  MD5Context *p;
+-  unsigned char digest[16];
+-  char zBuf[33];
+-  p = sqlite3_aggregate_context(context, sizeof(*p));
+-  MD5Final(digest,p);
+-  MD5DigestToBase16(digest, zBuf);
+-  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-}
+-int Md5_Register(
+-  sqlite3 *db,
+-  char **pzErrMsg,
+-  const sqlite3_api_routines *pThunk
+-){
+-  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
+-                                 md5step, md5finalize);
+-  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
+-  return rc;
+-}
+-#endif /* defined(SQLITE_TEST) */
+-
+-
+-/*
+-** If the macro TCLSH is one, then put in code this for the
+-** "main" routine that will initialize Tcl and take input from
+-** standard input, or if a file is named on the command line
+-** the TCL interpreter reads and evaluates that file.
+-*/
+-#if TCLSH==1
+ static const char *tclsh_main_loop(void){
+   static const char zMainloop[] =
+-    "set line {}\n"
+-    "while {![eof stdin]} {\n"
+-      "if {$line!=\"\"} {\n"
+-        "puts -nonewline \"> \"\n"
+-      "} else {\n"
+-        "puts -nonewline \"% \"\n"
+-      "}\n"
+-      "flush stdout\n"
+-      "append line [gets stdin]\n"
+-      "if {[info complete $line]} {\n"
+-        "if {[catch {uplevel #0 $line} result]} {\n"
+-          "puts stderr \"Error: $result\"\n"
+-        "} elseif {$result!=\"\"} {\n"
+-          "puts $result\n"
++    "if {[llength $argv]>=1} {\n"
++      "set argv0 [lindex $argv 0]\n"
++      "set argv [lrange $argv 1 end]\n"
++      "source $argv0\n"
++    "} else {\n"
++      "set line {}\n"
++      "while {![eof stdin]} {\n"
++        "if {$line!=\"\"} {\n"
++          "puts -nonewline \"> \"\n"
++        "} else {\n"
++          "puts -nonewline \"% \"\n"
+         "}\n"
+-        "set line {}\n"
+-      "} else {\n"
+-        "append line \\n\n"
++        "flush stdout\n"
++        "append line [gets stdin]\n"
++        "if {[info complete $line]} {\n"
++          "if {[catch {uplevel #0 $line} result]} {\n"
++            "puts stderr \"Error: $result\"\n"
++          "} elseif {$result!=\"\"} {\n"
++            "puts $result\n"
++          "}\n"
++          "set line {}\n"
++        "} else {\n"
++          "append line \\n\n"
++        "}\n"
+       "}\n"
+     "}\n"
+   ;
+   return zMainloop;
+ }
+-#endif
+-#if TCLSH==2
+-static const char *tclsh_main_loop(void);
+-#endif
+ 
+-#ifdef SQLITE_TEST
+-static void init_all(Tcl_Interp *);
+-static int SQLITE_TCLAPI init_all_cmd(
+-  ClientData cd,
+-  Tcl_Interp *interp,
+-  int objc,
+-  Tcl_Obj *CONST objv[]
+-){
+-
+-  Tcl_Interp *slave;
+-  if( objc!=2 ){
+-    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
+-    return TCL_ERROR;
+-  }
+-
+-  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
+-  if( !slave ){
+-    return TCL_ERROR;
+-  }
+-
+-  init_all(slave);
+-  return TCL_OK;
+-}
+-
+-/*
+-** Tclcmd: db_use_legacy_prepare DB BOOLEAN
+-**
+-**   The first argument to this command must be a database command created by
+-**   [sqlite3]. If the second argument is true, then the handle is configured
+-**   to use the sqlite3_prepare_v2() function to prepare statements. If it
+-**   is false, sqlite3_prepare().
+-*/
+-static int SQLITE_TCLAPI db_use_legacy_prepare_cmd(
+-  ClientData cd,
+-  Tcl_Interp *interp,
+-  int objc,
+-  Tcl_Obj *CONST objv[]
+-){
+-  Tcl_CmdInfo cmdInfo;
+-  SqliteDb *pDb;
+-  int bPrepare;
+-
+-  if( objc!=3 ){
+-    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
+-    return TCL_ERROR;
+-  }
+-
+-  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
+-    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
+-    return TCL_ERROR;
+-  }
+-  pDb = (SqliteDb*)cmdInfo.objClientData;
+-  if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
+-    return TCL_ERROR;
+-  }
+-
+-  pDb->bLegacyPrepare = bPrepare;
+-
+-  Tcl_ResetResult(interp);
+-  return TCL_OK;
+-}
+-
+-/*
+-** Tclcmd: db_last_stmt_ptr DB
+-**
+-**   If the statement cache associated with database DB is not empty,
+-**   return the text representation of the most recently used statement
+-**   handle.
+-*/
+-static int SQLITE_TCLAPI db_last_stmt_ptr(
+-  ClientData cd,
+-  Tcl_Interp *interp,
+-  int objc,
+-  Tcl_Obj *CONST objv[]
+-){
+-  extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
+-  Tcl_CmdInfo cmdInfo;
+-  SqliteDb *pDb;
+-  sqlite3_stmt *pStmt = 0;
+-  char zBuf[100];
+-
+-  if( objc!=2 ){
+-    Tcl_WrongNumArgs(interp, 1, objv, "DB");
+-    return TCL_ERROR;
+-  }
+-
+-  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
+-    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
+-    return TCL_ERROR;
+-  }
+-  pDb = (SqliteDb*)cmdInfo.objClientData;
+-
+-  if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt;
+-  if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){
+-    return TCL_ERROR;
+-  }
+-  Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
+-
+-  return TCL_OK;
+-}
+-#endif /* SQLITE_TEST */
+-
+-/*
+-** Configure the interpreter passed as the first argument to have access
+-** to the commands and linked variables that make up:
+-**
+-**   * the [sqlite3] extension itself,
+-**
+-**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
+-**
+-**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
+-**     test suite.
+-*/
+-static void init_all(Tcl_Interp *interp){
+-  Sqlite3_Init(interp);
+-
+-#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
+-  Md5_Init(interp);
+-#endif
+-
+-#ifdef SQLITE_TEST
+-  {
+-    extern int Sqliteconfig_Init(Tcl_Interp*);
+-    extern int Sqlitetest1_Init(Tcl_Interp*);
+-    extern int Sqlitetest2_Init(Tcl_Interp*);
+-    extern int Sqlitetest3_Init(Tcl_Interp*);
+-    extern int Sqlitetest4_Init(Tcl_Interp*);
+-    extern int Sqlitetest5_Init(Tcl_Interp*);
+-    extern int Sqlitetest6_Init(Tcl_Interp*);
+-    extern int Sqlitetest7_Init(Tcl_Interp*);
+-    extern int Sqlitetest8_Init(Tcl_Interp*);
+-    extern int Sqlitetest9_Init(Tcl_Interp*);
+-    extern int Sqlitetestasync_Init(Tcl_Interp*);
+-    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
+-    extern int Sqlitetest_blob_Init(Tcl_Interp*);
+-    extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
+-    extern int Sqlitetest_func_Init(Tcl_Interp*);
+-    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
+-    extern int Sqlitetest_init_Init(Tcl_Interp*);
+-    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
+-    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
+-    extern int Sqlitetestschema_Init(Tcl_Interp*);
+-    extern int Sqlitetestsse_Init(Tcl_Interp*);
+-    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
+-    extern int Sqlitetestfs_Init(Tcl_Interp*);
+-    extern int SqlitetestThread_Init(Tcl_Interp*);
+-    extern int SqlitetestOnefile_Init();
+-    extern int SqlitetestOsinst_Init(Tcl_Interp*);
+-    extern int Sqlitetestbackup_Init(Tcl_Interp*);
+-    extern int Sqlitetestintarray_Init(Tcl_Interp*);
+-    extern int Sqlitetestvfs_Init(Tcl_Interp *);
+-    extern int Sqlitetestrtree_Init(Tcl_Interp*);
+-    extern int Sqlitequota_Init(Tcl_Interp*);
+-    extern int Sqlitemultiplex_Init(Tcl_Interp*);
+-    extern int SqliteSuperlock_Init(Tcl_Interp*);
+-    extern int SqlitetestSyscall_Init(Tcl_Interp*);
+-#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+-    extern int TestSession_Init(Tcl_Interp*);
+-#endif
+-    extern int Fts5tcl_Init(Tcl_Interp *);
+-    extern int SqliteRbu_Init(Tcl_Interp*);
+-    extern int Sqlitetesttcl_Init(Tcl_Interp*);
+-#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
+-    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
+-#endif
+-
+-#ifdef SQLITE_ENABLE_ZIPVFS
+-    extern int Zipvfs_Init(Tcl_Interp*);
+-    Zipvfs_Init(interp);
+-#endif
+-
+-    Sqliteconfig_Init(interp);
+-    Sqlitetest1_Init(interp);
+-    Sqlitetest2_Init(interp);
+-    Sqlitetest3_Init(interp);
+-    Sqlitetest4_Init(interp);
+-    Sqlitetest5_Init(interp);
+-    Sqlitetest6_Init(interp);
+-    Sqlitetest7_Init(interp);
+-    Sqlitetest8_Init(interp);
+-    Sqlitetest9_Init(interp);
+-    Sqlitetestasync_Init(interp);
+-    Sqlitetest_autoext_Init(interp);
+-    Sqlitetest_blob_Init(interp);
+-    Sqlitetest_demovfs_Init(interp);
+-    Sqlitetest_func_Init(interp);
+-    Sqlitetest_hexio_Init(interp);
+-    Sqlitetest_init_Init(interp);
+-    Sqlitetest_malloc_Init(interp);
+-    Sqlitetest_mutex_Init(interp);
+-    Sqlitetestschema_Init(interp);
+-    Sqlitetesttclvar_Init(interp);
+-    Sqlitetestfs_Init(interp);
+-    SqlitetestThread_Init(interp);
+-    SqlitetestOnefile_Init();
+-    SqlitetestOsinst_Init(interp);
+-    Sqlitetestbackup_Init(interp);
+-    Sqlitetestintarray_Init(interp);
+-    Sqlitetestvfs_Init(interp);
+-    Sqlitetestrtree_Init(interp);
+-    Sqlitequota_Init(interp);
+-    Sqlitemultiplex_Init(interp);
+-    SqliteSuperlock_Init(interp);
+-    SqlitetestSyscall_Init(interp);
+-#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+-    TestSession_Init(interp);
+-#endif
+-    Fts5tcl_Init(interp);
+-    SqliteRbu_Init(interp);
+-    Sqlitetesttcl_Init(interp);
+-
+-#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
+-    Sqlitetestfts3_Init(interp);
+-#endif
+-
+-    Tcl_CreateObjCommand(
+-        interp, "load_testfixture_extensions", init_all_cmd, 0, 0
+-    );
+-    Tcl_CreateObjCommand(
+-        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
+-    );
+-    Tcl_CreateObjCommand(
+-        interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
+-    );
+-
+-#ifdef SQLITE_SSE
+-    Sqlitetestsse_Init(interp);
+-#endif
+-  }
+-#endif
+-}
+-
+-/* Needed for the setrlimit() system call on unix */
+-#if defined(unix)
+-#include <sys/resource.h>
+-#endif
+-
+ #define TCLSH_MAIN main   /* Needed to fake out mktclapp */
+ int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
+   Tcl_Interp *interp;
++  int i;
++  const char *zScript = 0;
++  char zArgc[32];
++#if defined(TCLSH_INIT_PROC)
++  extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
++#endif
+ 
+ #if !defined(_WIN32_WCE)
+-  if( getenv("BREAK") ){
+-    fprintf(stderr,
+-        "attach debugger to process %d and press any key to continue.\n",
+-        GETPID());
+-    fgetc(stdin);
++  if( getenv("SQLITE_DEBUG_BREAK") ){
++    if( isatty(0) && isatty(2) ){
++      fprintf(stderr,
++          "attach debugger to process %d and press any key to continue.\n",
++          GETPID());
++      fgetc(stdin);
++    }else{
++#if defined(_WIN32) || defined(WIN32)
++      DebugBreak();
++#elif defined(SIGTRAP)
++      raise(SIGTRAP);
++#endif
++    }
+   }
+ #endif
+ 
+-  /* Since the primary use case for this binary is testing of SQLite,
+-  ** be sure to generate core files if we crash */
+-#if defined(SQLITE_TEST) && defined(unix)
+-  { struct rlimit x;
+-    getrlimit(RLIMIT_CORE, &x);
+-    x.rlim_cur = x.rlim_max;
+-    setrlimit(RLIMIT_CORE, &x);
+-  }
+-#endif /* SQLITE_TEST && unix */
+-
+-
+   /* Call sqlite3_shutdown() once before doing anything else. This is to
+   ** test that sqlite3_shutdown() can be safely called by a process before
+   ** sqlite3_initialize() is. */
+@@ -4284,32 +3766,27 @@
+   Tcl_FindExecutable(argv[0]);
+   Tcl_SetSystemEncoding(NULL, "utf-8");
+   interp = Tcl_CreateInterp();
++  Sqlite3_Init(interp);
+ 
+-#if TCLSH==2
+-  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
++  sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
++  Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
++  Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
++  Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
++  for(i=1; i<argc; i++){
++    Tcl_SetVar(interp, "argv", argv[i],
++        TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
++  }
++#if defined(TCLSH_INIT_PROC)
++  zScript = TCLSH_INIT_PROC(interp);
+ #endif
+-
+-  init_all(interp);
+-  if( argc>=2 ){
+-    int i;
+-    char zArgc[32];
+-    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
+-    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
+-    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
+-    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
+-    for(i=3-TCLSH; i<argc; i++){
+-      Tcl_SetVar(interp, "argv", argv[i],
+-          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
+-    }
+-    if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
+-      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+-      if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
+-      fprintf(stderr,"%s: %s\n", *argv, zInfo);
+-      return 1;
+-    }
++  if( zScript==0 ){
++    zScript = tclsh_main_loop();
+   }
+-  if( TCLSH==2 || argc<=1 ){
+-    Tcl_GlobalEval(interp, tclsh_main_loop());
++  if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
++    const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
++    if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
++    fprintf(stderr,"%s: %s\n", *argv, zInfo);
++    return 1;
+   }
+   return 0;
+ }
diff --git a/share/security/patches/EN-19:03/sqlite-11.patch.asc b/share/security/patches/EN-19:03/sqlite-11.patch.asc
new file mode 100644
index 0000000000..53594fbae7
--- /dev/null
+++ b/share/security/patches/EN-19:03/sqlite-11.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RiJfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJUcA//Sbp6kYL6InxUHPlQYO+MSTT+vc8bnzo7pW2sGs9VP+mnseZUQLO8pp29
+cCYNOC+4W2aIRP236IgeyPWSWUFSQ2MY+TSBxwa2kbIQW6Dts3ZvJNGT2MrMFqfx
+4mXMf8bgrsgGHymJ7qTgudeQzgsl0OPSzXSVzp/KVT+VQb9gIok3Dx7gGzTj/u2O
+5NIok6oBxUUcuoFfMV5z1fVS3Ny/gK80BVQy0f8ZlutkVZ2H09zu1pnHSLUCnUYT
+psE5QlJZ/baCkPBioComDJsy8YqEf9E4W4rm/Ds/tzV+IA5s7RzH/HvfHp3j7t8l
+ODNBr13lAlV6hQ71CwAPJEH5R8tmzRTKBQInAIS3xKiNBWqhshWf//ZSobHCPqJT
+BDEnE/9XF1GHaa4vb5RTZRIEhTU0zJ+o1CQOR6McdJ4IxOc1P23hOvRwkylQB84S
+E/3Yy42bde5RLnDYdQuxCW/c6S3PRo1jSMYjS7DnQ2PS8k+wAeAzHgj575UpcpDl
+5pSuzejvobSd0qyqwmBjKVWqAhkrRcUw/Yy/wt62RyHepEtpLat6U9deq481eart
+IC3eDJAaPW06mnmT9nfAqSh2CKvFUxTQ1XwZh0R+ZltdtjWFVWsU1XMc5fsfiQKU
+aD3o/huTvc2MhYTexvqYQcWZYndMgnXgWQt2LqLoe0YZAgMX5ZU=
+=I2kE
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:03/sqlite-12.patch b/share/security/patches/EN-19:03/sqlite-12.patch
new file mode 100644
index 0000000000..d6dc834a44
--- /dev/null
+++ b/share/security/patches/EN-19:03/sqlite-12.patch
@@ -0,0 +1,65012 @@
+--- contrib/sqlite3/Makefile.am.orig
++++ contrib/sqlite3/Makefile.am
+@@ -1,6 +1,5 @@
+ 
+-AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
+-
++AM_CFLAGS = @BUILD_CFLAGS@ 
+ lib_LTLIBRARIES = libsqlite3.la
+ libsqlite3_la_SOURCES = sqlite3.c
+ libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
+@@ -14,7 +13,7 @@
+ 
+ include_HEADERS = sqlite3.h sqlite3ext.h
+ 
+-EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
++EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
+ pkgconfigdir = ${libdir}/pkgconfig
+ pkgconfig_DATA = sqlite3.pc
+ 
+--- contrib/sqlite3/Makefile.fallback.orig
++++ contrib/sqlite3/Makefile.fallback
+@@ -0,0 +1,19 @@
++#!/usr/bin/make
++#
++# If the configure script does not work, then this Makefile is available
++# as a backup.  Manually configure the variables below.
++#
++# Note:  This makefile works out-of-the-box on MacOS 10.2 (Jaguar)
++#
++CC = gcc
++CFLAGS = -O0 -I.
++LIBS = -lz
++COPTS += -D_BSD_SOURCE
++COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0
++COPTS += -DSQLITE_THREADSAFE=0
++COPTS += -DSQLITE_OMIT_LOAD_EXTENSION
++COPTS += -DSQLITE_WITHOUT_ZONEMALLOC
++COPTS += -DSQLITE_ENABLE_RTREE
++
++sqlite3:	shell.c sqlite3.c
++	$(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS)
+--- contrib/sqlite3/Makefile.in.orig
++++ contrib/sqlite3/Makefile.in
+@@ -260,7 +260,6 @@
+ DLLTOOL = @DLLTOOL@
+ DSYMUTIL = @DSYMUTIL@
+ DUMPBIN = @DUMPBIN@
+-DYNAMIC_EXTENSION_FLAGS = @DYNAMIC_EXTENSION_FLAGS@
+ ECHO_C = @ECHO_C@
+ ECHO_N = @ECHO_N@
+ ECHO_T = @ECHO_T@
+@@ -268,7 +267,6 @@
+ EXEEXT = @EXEEXT@
+ EXTRA_SHELL_OBJ = @EXTRA_SHELL_OBJ@
+ FGREP = @FGREP@
+-FTS5_FLAGS = @FTS5_FLAGS@
+ GREP = @GREP@
+ INSTALL = @INSTALL@
+ INSTALL_DATA = @INSTALL_DATA@
+@@ -275,7 +273,6 @@
+ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
+ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+-JSON1_FLAGS = @JSON1_FLAGS@
+ LD = @LD@
+ LDFLAGS = @LDFLAGS@
+ LIBOBJS = @LIBOBJS@
+@@ -305,14 +302,11 @@
+ RANLIB = @RANLIB@
+ READLINE_LIBS = @READLINE_LIBS@
+ SED = @SED@
+-SESSION_FLAGS = @SESSION_FLAGS@
+ SET_MAKE = @SET_MAKE@
+ SHELL = @SHELL@
+ SHELL_CFLAGS = @SHELL_CFLAGS@
+ STRIP = @STRIP@
+-THREADSAFE_FLAGS = @THREADSAFE_FLAGS@
+ VERSION = @VERSION@
+-ZLIB_FLAGS = @ZLIB_FLAGS@
+ abs_builddir = @abs_builddir@
+ abs_srcdir = @abs_srcdir@
+ abs_top_builddir = @abs_top_builddir@
+@@ -365,7 +359,7 @@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
++AM_CFLAGS = @BUILD_CFLAGS@ 
+ lib_LTLIBRARIES = libsqlite3.la
+ libsqlite3_la_SOURCES = sqlite3.c
+ libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
+@@ -375,7 +369,7 @@
+ sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
+ sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
+ include_HEADERS = sqlite3.h sqlite3ext.h
+-EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
++EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
+ pkgconfigdir = ${libdir}/pkgconfig
+ pkgconfig_DATA = sqlite3.pc
+ man_MANS = sqlite3.1
+--- contrib/sqlite3/Makefile.msc.orig
++++ contrib/sqlite3/Makefile.msc
+@@ -277,6 +277,12 @@
+ !IF $(MINIMAL_AMALGAMATION)==0
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
++OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
+ !ENDIF
+ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
+ !ENDIF
+@@ -928,10 +934,9 @@
+ # when the shell is not being dynamically linked.
+ #
+ !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
+-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
+-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
+-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
+-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
++SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
+ !ENDIF
+ 
+ 
+@@ -966,7 +971,7 @@
+ sqlite3.def:	Replace.exe $(LIBOBJ)
+ 	echo EXPORTS > sqlite3.def
+ 	dumpbin /all $(LIBOBJ) \
+-		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
++		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
+ 		| sort >> sqlite3.def
+ 
+ $(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
+--- contrib/sqlite3/configure.orig
++++ contrib/sqlite3/configure
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.69 for sqlite 3.23.1.
++# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
+ #
+ # Report bugs to <http://www.sqlite.org>.
+ #
+@@ -590,8 +590,8 @@
+ # Identity of this package.
+ PACKAGE_NAME='sqlite'
+ PACKAGE_TARNAME='sqlite'
+-PACKAGE_VERSION='3.23.1'
+-PACKAGE_STRING='sqlite 3.23.1'
++PACKAGE_VERSION='3.26.0'
++PACKAGE_STRING='sqlite 3.26.0'
+ PACKAGE_BUGREPORT='http://www.sqlite.org'
+ PACKAGE_URL=''
+ 
+@@ -637,13 +637,7 @@
+ LTLIBOBJS
+ LIBOBJS
+ SHELL_CFLAGS
+-ZLIB_FLAGS
+ EXTRA_SHELL_OBJ
+-SESSION_FLAGS
+-JSON1_FLAGS
+-FTS5_FLAGS
+-DYNAMIC_EXTENSION_FLAGS
+-THREADSAFE_FLAGS
+ READLINE_LIBS
+ BUILD_CFLAGS
+ CPP
+@@ -777,9 +771,13 @@
+ enable_readline
+ enable_threadsafe
+ enable_dynamic_extensions
++enable_fts4
++enable_fts3
+ enable_fts5
+ enable_json1
++enable_rtree
+ enable_session
++enable_debug
+ enable_static_shell
+ '
+       ac_precious_vars='build_alias
+@@ -1332,7 +1330,7 @@
+   # Omit some internal or obsolete options to make the list less imposing.
+   # This message is too long to be a string in the A/UX 3.1 sh.
+   cat <<_ACEOF
+-\`configure' configures sqlite 3.23.1 to adapt to many kinds of systems.
++\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
+ 
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+ 
+@@ -1402,7 +1400,7 @@
+ 
+ if test -n "$ac_init_help"; then
+   case $ac_init_help in
+-     short | recursive ) echo "Configuration of sqlite 3.23.1:";;
++     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
+    esac
+   cat <<\_ACEOF
+ 
+@@ -1427,9 +1425,13 @@
+   --enable-threadsafe     build a thread-safe library [default=yes]
+   --enable-dynamic-extensions
+                           support loadable extensions [default=yes]
+-  --enable-fts5           include fts5 support [default=no]
+-  --enable-json1          include json1 support [default=no]
++  --enable-fts4           include fts4 support [default=yes]
++  --enable-fts3           include fts3 support [default=no]
++  --enable-fts5           include fts5 support [default=yes]
++  --enable-json1          include json1 support [default=yes]
++  --enable-rtree          include rtree support [default=yes]
+   --enable-session        enable the session extension [default=no]
++  --enable-debug          build with debugging features enabled [default=no]
+   --enable-static-shell   statically link libsqlite3 into shell tool
+                           [default=yes]
+ 
+@@ -1523,7 +1525,7 @@
+ test -n "$ac_init_help" && exit $ac_status
+ if $ac_init_version; then
+   cat <<\_ACEOF
+-sqlite configure 3.23.1
++sqlite configure 3.26.0
+ generated by GNU Autoconf 2.69
+ 
+ Copyright (C) 2012 Free Software Foundation, Inc.
+@@ -1938,7 +1940,7 @@
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+ 
+-It was created by sqlite $as_me 3.23.1, which was
++It was created by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   $ $0 $@
+@@ -2804,7 +2806,7 @@
+ 
+ # Define the identity of the package.
+  PACKAGE='sqlite'
+- VERSION='3.23.1'
++ VERSION='3.26.0'
+ 
+ 
+ cat >>confdefs.h <<_ACEOF
+@@ -13040,6 +13042,7 @@
+ 
+ ac_config_files="$ac_config_files Makefile sqlite3.pc"
+ 
++BUILD_CFLAGS=
+ 
+ 
+ #-------------------------------------------------------------------------
+@@ -13304,9 +13307,8 @@
+   enable_threadsafe=yes
+ fi
+ 
+-THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
+ if test x"$enable_threadsafe" != "xno"; then
+-  THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
++  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5
+ $as_echo_n "checking for library containing pthread_create... " >&6; }
+ if ${ac_cv_search_pthread_create+:} false; then :
+@@ -13420,7 +13422,6 @@
+ fi
+ 
+ fi
+-
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -13491,16 +13492,43 @@
+ fi
+ 
+ else
+-  DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether to support dynamic extensions" >&5
+ $as_echo_n "checking for whether to support dynamic extensions... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_dynamic_extensions" >&5
+ $as_echo "$enable_dynamic_extensions" >&6; }
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-fts4
++#
++# Check whether --enable-fts4 was given.
++if test "${enable_fts4+set}" = set; then :
++  enableval=$enable_fts4;
++else
++  enable_fts4=yes
++fi
+ 
++if test x"$enable_fts4" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
++#   --enable-fts3
++#
++# Check whether --enable-fts3 was given.
++if test "${enable_fts3+set}" = set; then :
++  enableval=$enable_fts3;
++fi
++
++if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-fts5
+ #
+ # Check whether --enable-fts5 was given.
+@@ -13507,7 +13535,7 @@
+ if test "${enable_fts5+set}" = set; then :
+   enableval=$enable_fts5;
+ else
+-  enable_fts5=no
++  enable_fts5=yes
+ fi
+ 
+ if test x"$enable_fts5" = "xyes"; then
+@@ -13567,9 +13595,8 @@
+ 
+ fi
+ 
+-  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+ fi
+-
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -13579,32 +13606,57 @@
+ if test "${enable_json1+set}" = set; then :
+   enableval=$enable_json1;
+ else
+-  enable_json1=no
++  enable_json1=yes
+ fi
+ 
+ if test x"$enable_json1" = "xyes"; then
+-  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ fi
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-rtree
++#
++# Check whether --enable-rtree was given.
++if test "${enable_rtree+set}" = set; then :
++  enableval=$enable_rtree;
++else
++  enable_rtree=yes
++fi
+ 
++if test x"$enable_rtree" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-session
+ #
+ # Check whether --enable-session was given.
+ if test "${enable_session+set}" = set; then :
+   enableval=$enable_session;
+-else
+-  enable_session=no
+ fi
+ 
+ if test x"$enable_session" = "xyes"; then
+-  SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ fi
++#-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-debug
++#
++# Check whether --enable-debug was given.
++if test "${enable_debug+set}" = set; then :
++  enableval=$enable_debug;
++fi
+ 
++if test x"$enable_debug" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
++  CFLAGS="-g -O0"
++fi
+ #-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-static-shell
+ #
+ # Check whether --enable-static-shell was given.
+@@ -13694,7 +13746,7 @@
+ ac_res=$ac_cv_search_deflate
+ if test "$ac_res" != no; then :
+   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+-  ZLIB_FLAGS="-DSQLITE_HAVE_ZLIB"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"
+ fi
+ 
+ 
+@@ -13703,7 +13755,6 @@
+ done
+ 
+ 
+-
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing system" >&5
+ $as_echo_n "checking for library containing system... " >&6; }
+ if ${ac_cv_search_system+:} false; then :
+@@ -14359,7 +14410,7 @@
+ # report actual input values of CONFIG_FILES etc. instead of their
+ # values after options handling.
+ ac_log="
+-This file was extended by sqlite $as_me 3.23.1, which was
++This file was extended by sqlite $as_me 3.26.0, which was
+ generated by GNU Autoconf 2.69.  Invocation command line was
+ 
+   CONFIG_FILES    = $CONFIG_FILES
+@@ -14416,7 +14467,7 @@
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ ac_cs_version="\\
+-sqlite config.status 3.23.1
++sqlite config.status 3.26.0
+ configured by $0, generated by GNU Autoconf 2.69,
+   with options \\"\$ac_cs_config\\"
+ 
+--- contrib/sqlite3/configure.ac.orig
++++ contrib/sqlite3/configure.ac
+@@ -10,7 +10,7 @@
+ #
+ 
+ AC_PREREQ(2.61)
+-AC_INIT(sqlite, 3.23.1, http://www.sqlite.org)
++AC_INIT(sqlite, 3.26.0, http://www.sqlite.org)
+ AC_CONFIG_SRCDIR([sqlite3.c])
+ AC_CONFIG_AUX_DIR([.])
+ 
+@@ -29,6 +29,7 @@
+ AC_FUNC_STRERROR_R
+ 
+ AC_CONFIG_FILES([Makefile sqlite3.pc])
++BUILD_CFLAGS=
+ AC_SUBST(BUILD_CFLAGS)
+ 
+ #-------------------------------------------------------------------------
+@@ -86,13 +87,11 @@
+ AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
+   [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
+   [], [enable_threadsafe=yes])
+-THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
+ if test x"$enable_threadsafe" != "xno"; then
+-  THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
++  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
+   AC_SEARCH_LIBS(pthread_create, pthread)
+   AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
+ fi
+-AC_SUBST(THREADSAFE_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -104,24 +103,44 @@
+ if test x"$enable_dynamic_extensions" != "xno"; then
+   AC_SEARCH_LIBS(dlopen, dl)
+ else
+-  DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
+ fi
+ AC_MSG_CHECKING([for whether to support dynamic extensions])
+ AC_MSG_RESULT($enable_dynamic_extensions)
+-AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-fts4
++#
++AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
++  [--enable-fts4], [include fts4 support [default=yes]])], 
++  [], [enable_fts4=yes])
++if test x"$enable_fts4" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
++#   --enable-fts3
++#
++AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
++  [--enable-fts3], [include fts3 support [default=no]])], 
++  [], [])
++if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-fts5
+ #
+ AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
+-  [--enable-fts5], [include fts5 support [default=no]])], 
+-  [], [enable_fts5=no])
++  [--enable-fts5], [include fts5 support [default=yes]])], 
++  [], [enable_fts5=yes])
+ if test x"$enable_fts5" = "xyes"; then
+   AC_SEARCH_LIBS(log, m)
+-  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+ fi
+-AC_SUBST(FTS5_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
+@@ -128,27 +147,48 @@
+ #   --enable-json1
+ #
+ AC_ARG_ENABLE(json1, [AS_HELP_STRING(
+-  [--enable-json1], [include json1 support [default=no]])], 
+-  [], [enable_json1=no])
++  [--enable-json1], [include json1 support [default=yes]])], 
++  [],[enable_json1=yes])
+ if test x"$enable_json1" = "xyes"; then
+-  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ fi
+-AC_SUBST(JSON1_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-rtree
++#
++AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
++  [--enable-rtree], [include rtree support [default=yes]])], 
++  [], [enable_rtree=yes])
++if test x"$enable_rtree" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-session
+ #
+ AC_ARG_ENABLE(session, [AS_HELP_STRING(
+   [--enable-session], [enable the session extension [default=no]])], 
+-  [], [enable_session=no])
++  [], [])
+ if test x"$enable_session" = "xyes"; then
+-  SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ fi
+-AC_SUBST(SESSION_FLAGS)
+ #-----------------------------------------------------------------------
+ 
+ #-----------------------------------------------------------------------
++#   --enable-debug
++#
++AC_ARG_ENABLE(debug, [AS_HELP_STRING(
++  [--enable-debug], [build with debugging features enabled [default=no]])], 
++  [], [])
++if test x"$enable_debug" = "xyes"; then
++  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
++  CFLAGS="-g -O0"
++fi
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
+ #   --enable-static-shell
+ #
+ AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
+@@ -165,9 +205,8 @@
+ 
+ AC_CHECK_FUNCS(posix_fallocate)
+ AC_CHECK_HEADERS(zlib.h,[
+-  AC_SEARCH_LIBS(deflate,z,[ZLIB_FLAGS="-DSQLITE_HAVE_ZLIB"])
++  AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"])
+ ])
+-AC_SUBST(ZLIB_FLAGS)
+ 
+ AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"])
+ AC_SUBST(SHELL_CFLAGS)
+--- contrib/sqlite3/shell.c.orig
++++ contrib/sqlite3/shell.c
+@@ -97,6 +97,7 @@
+ #if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
+ # include <unistd.h>
+ # include <dirent.h>
++# define GETPID getpid
+ # if defined(__MINGW32__)
+ #  define DIRENT dirent
+ #  ifndef S_ISLNK
+@@ -103,6 +104,8 @@
+ #   define S_ISLNK(mode) (0)
+ #  endif
+ # endif
++#else
++# define GETPID (int)GetCurrentProcessId
+ #endif
+ #include <sys/types.h>
+ #include <sys/stat.h>
+@@ -454,6 +457,12 @@
+ # define raw_printf fprintf
+ #endif
+ 
++/* Indicate out-of-memory and exit. */
++static void shell_out_of_memory(void){
++  raw_printf(stderr,"Error: out of memory\n");
++  exit(1);
++}
++
+ /*
+ ** Write I/O traces to the following stream.
+ */
+@@ -577,7 +586,7 @@
+     if( n+100>nLine ){
+       nLine = nLine*2 + 100;
+       zLine = realloc(zLine, nLine);
+-      if( zLine==0 ) return 0;
++      if( zLine==0 ) shell_out_of_memory();
+     }
+     if( fgets(&zLine[n], nLine - n, in)==0 ){
+       if( n==0 ){
+@@ -604,10 +613,7 @@
+       int nTrans = strlen30(zTrans)+1;
+       if( nTrans>nLine ){
+         zLine = realloc(zLine, nTrans);
+-        if( zLine==0 ){
+-          sqlite3_free(zTrans);
+-          return 0;
+-        }
++        if( zLine==0 ) shell_out_of_memory();
+       }
+       memcpy(zLine, zTrans, nTrans);
+       sqlite3_free(zTrans);
+@@ -754,10 +760,7 @@
+   if( p->n+len>=p->nAlloc ){
+     p->nAlloc = p->nAlloc*2 + len + 20;
+     p->z = realloc(p->z, p->nAlloc);
+-    if( p->z==0 ){
+-      memset(p, 0, sizeof(*p));
+-      return;
+-    }
++    if( p->z==0 ) shell_out_of_memory();
+   }
+ 
+   if( quote ){
+@@ -786,45 +789,12 @@
+ ** Return '"' if quoting is required.  Return 0 if no quoting is required.
+ */
+ static char quoteChar(const char *zName){
+-  /* All SQLite keywords, in alphabetical order */
+-  static const char *azKeywords[] = {
+-    "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
+-    "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
+-    "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
+-    "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
+-    "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
+-    "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
+-    "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
+-    "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
+-    "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
+-    "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
+-    "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
+-    "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
+-    "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
+-    "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
+-    "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
+-    "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
+-    "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
+-    "WITH", "WITHOUT",
+-  };
+-  int i, lwr, upr, mid, c;
++  int i;
+   if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
+   for(i=0; zName[i]; i++){
+     if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
+   }
+-  lwr = 0;
+-  upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
+-  while( lwr<=upr ){
+-    mid = (lwr+upr)/2;
+-    c = sqlite3_stricmp(azKeywords[mid], zName);
+-    if( c==0 ) return '"';
+-    if( c<0 ){
+-      lwr = mid+1;
+-    }else{
+-      upr = mid-1;
+-    }
+-  }
+-  return 0;
++  return sqlite3_keyword_check(zName, i) ? '"' : 0;
+ }
+ 
+ /*
+@@ -1347,7 +1317,7 @@
+ **
+ ******************************************************************************
+ **
+-** This SQLite extension implements a functions that compute SHA1 hashes.
++** This SQLite extension implements functions that compute SHA3 hashes.
+ ** Two SQL functions are implemented:
+ **
+ **     sha3(X,SIZE)
+@@ -2158,8 +2128,19 @@
+ #include <errno.h>
+ 
+ 
++/*
++** Structure of the fsdir() table-valued function
++*/
++                 /*    0    1    2     3    4           5             */
+ #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
++#define FSDIR_COLUMN_NAME     0     /* Name of the file */
++#define FSDIR_COLUMN_MODE     1     /* Access mode */
++#define FSDIR_COLUMN_MTIME    2     /* Last modification time */
++#define FSDIR_COLUMN_DATA     3     /* File content */
++#define FSDIR_COLUMN_PATH     4     /* Path to top of search */
++#define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */
+ 
++
+ /*
+ ** Set the result stored by context ctx to a blob containing the 
+ ** contents of file zName.
+@@ -2256,7 +2237,7 @@
+   extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
+   zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
+   if( zUnicodeName ){
+-    memset(&fd, 0, sizeof(WIN32_FIND_DATA));
++    memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
+     hFindFile = FindFirstFileW(zUnicodeName, &fd);
+     if( hFindFile!=NULL ){
+       pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
+@@ -2747,20 +2728,20 @@
+ ){
+   fsdir_cursor *pCur = (fsdir_cursor*)cur;
+   switch( i ){
+-    case 0: { /* name */
++    case FSDIR_COLUMN_NAME: {
+       sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
+       break;
+     }
+ 
+-    case 1: /* mode */
++    case FSDIR_COLUMN_MODE:
+       sqlite3_result_int64(ctx, pCur->sStat.st_mode);
+       break;
+ 
+-    case 2: /* mtime */
++    case FSDIR_COLUMN_MTIME:
+       sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
+       break;
+ 
+-    case 3: { /* data */
++    case FSDIR_COLUMN_DATA: {
+       mode_t m = pCur->sStat.st_mode;
+       if( S_ISDIR(m) ){
+         sqlite3_result_null(ctx);
+@@ -2790,6 +2771,12 @@
+         readFileContents(ctx, pCur->zPath);
+       }
+     }
++    case FSDIR_COLUMN_PATH:
++    default: {
++      /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
++      ** always return their values as NULL */
++      break;
++    }
+   }
+   return SQLITE_OK;
+ }
+@@ -2816,6 +2803,9 @@
+ 
+ /*
+ ** xFilter callback.
++**
++** idxNum==1   PATH parameter only
++** idxNum==2   Both PATH and DIR supplied
+ */
+ static int fsdirFilter(
+   sqlite3_vtab_cursor *cur, 
+@@ -2868,12 +2858,10 @@
+ ** In this implementation idxNum is used to represent the
+ ** query plan.  idxStr is unused.
+ **
+-** The query plan is represented by bits in idxNum:
++** The query plan is represented by values of idxNum:
+ **
+-**  (1)  start = $value  -- constraint exists
+-**  (2)  stop = $value   -- constraint exists
+-**  (4)  step = $value   -- constraint exists
+-**  (8)  output in descending order
++**  (1)  The path value is supplied by argv[0]
++**  (2)  Path is in argv[0] and dir is in argv[1]
+ */
+ static int fsdirBestIndex(
+   sqlite3_vtab *tab,
+@@ -2880,28 +2868,53 @@
+   sqlite3_index_info *pIdxInfo
+ ){
+   int i;                 /* Loop over constraints */
+-  int idx4 = -1;
+-  int idx5 = -1;
++  int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
++  int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
++  int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
++  int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
+   const struct sqlite3_index_constraint *pConstraint;
+ 
+   (void)tab;
+   pConstraint = pIdxInfo->aConstraint;
+   for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+-    if( pConstraint->usable==0 ) continue;
+     if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+-    if( pConstraint->iColumn==4 ) idx4 = i;
+-    if( pConstraint->iColumn==5 ) idx5 = i;
++    switch( pConstraint->iColumn ){
++      case FSDIR_COLUMN_PATH: {
++        if( pConstraint->usable ){
++          idxPath = i;
++          seenPath = 0;
++        }else if( idxPath<0 ){
++          seenPath = 1;
++        }
++        break;
++      }
++      case FSDIR_COLUMN_DIR: {
++        if( pConstraint->usable ){
++          idxDir = i;
++          seenDir = 0;
++        }else if( idxDir<0 ){
++          seenDir = 1;
++        }
++        break;
++      }
++    } 
+   }
++  if( seenPath || seenDir ){
++    /* If input parameters are unusable, disallow this plan */
++    return SQLITE_CONSTRAINT;
++  }
+ 
+-  if( idx4<0 ){
++  if( idxPath<0 ){
+     pIdxInfo->idxNum = 0;
+-    pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
++    /* The pIdxInfo->estimatedCost should have been initialized to a huge
++    ** number.  Leave it unchanged. */
++    pIdxInfo->estimatedRows = 0x7fffffff;
+   }else{
+-    pIdxInfo->aConstraintUsage[idx4].omit = 1;
+-    pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
+-    if( idx5>=0 ){
+-      pIdxInfo->aConstraintUsage[idx5].omit = 1;
+-      pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
++    pIdxInfo->aConstraintUsage[idxPath].omit = 1;
++    pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
++    if( idxDir>=0 ){
++      pIdxInfo->aConstraintUsage[idxDir].omit = 1;
++      pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
+       pIdxInfo->idxNum = 2;
+       pIdxInfo->estimatedCost = 10.0;
+     }else{
+@@ -2940,7 +2953,8 @@
+     0,                         /* xRename */
+     0,                         /* xSavepoint */
+     0,                         /* xRelease */
+-    0                          /* xRollbackTo */
++    0,                         /* xRollbackTo */
++    0,                         /* xShadowName */
+   };
+ 
+   int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
+@@ -3042,6 +3056,7 @@
+   char *zPrefix;             /* The prefix for the word we want to complete */
+   char *zLine;               /* The whole that we want to complete */
+   const char *zCurrentRow;   /* Current output row */
++  int szRow;                 /* Length of the zCurrentRow string */
+   sqlite3_stmt *pStmt;       /* Current statement */
+   sqlite3_int64 iRowid;      /* The rowid */
+   int ePhase;                /* Current phase */
+@@ -3155,32 +3170,6 @@
+ }
+ 
+ /*
+-** All SQL keywords understood by SQLite
+-*/
+-static const char *completionKwrds[] = {
+-  "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
+-  "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
+-  "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
+-  "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
+-  "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
+-  "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
+-  "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
+-  "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
+-  "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
+-  "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
+-  "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
+-  "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
+-  "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
+-  "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
+-  "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
+-  "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
+-  "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
+-  "WITH", "WITHOUT",
+-};
+-#define completionKwCount \
+-   (int)(sizeof(completionKwrds)/sizeof(completionKwrds[0]))
+-
+-/*
+ ** Advance a completion_cursor to its next row of output.
+ **
+ ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
+@@ -3202,11 +3191,11 @@
+   while( pCur->ePhase!=COMPLETION_EOF ){
+     switch( pCur->ePhase ){
+       case COMPLETION_KEYWORDS: {
+-        if( pCur->j >= completionKwCount ){
++        if( pCur->j >= sqlite3_keyword_count() ){
+           pCur->zCurrentRow = 0;
+           pCur->ePhase = COMPLETION_DATABASES;
+         }else{
+-          pCur->zCurrentRow = completionKwrds[pCur->j++];
++          sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
+         }
+         iCol = -1;
+         break;
+@@ -3278,6 +3267,7 @@
+       if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
+         /* Extract the next row of content */
+         pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
++        pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
+       }else{
+         /* When all rows are finished, advance to the next phase */
+         sqlite3_finalize(pCur->pStmt);
+@@ -3287,7 +3277,9 @@
+       }
+     }
+     if( pCur->nPrefix==0 ) break;
+-    if( sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 ){
++    if( pCur->nPrefix<=pCur->szRow
++     && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
++    ){
+       break;
+     }
+   }
+@@ -3307,7 +3299,7 @@
+   completion_cursor *pCur = (completion_cursor*)cur;
+   switch( i ){
+     case COMPLETION_COLUMN_CANDIDATE: {
+-      sqlite3_result_text(ctx, pCur->zCurrentRow, -1, SQLITE_TRANSIENT);
++      sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
+       break;
+     }
+     case COMPLETION_COLUMN_PREFIX: {
+@@ -3367,7 +3359,7 @@
+       pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+       if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+     }
+-    iArg++;
++    iArg = 1;
+   }
+   if( idxNum & 2 ){
+     pCur->nLine = sqlite3_value_bytes(argv[iArg]);
+@@ -3375,7 +3367,6 @@
+       pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+       if( pCur->zLine==0 ) return SQLITE_NOMEM;
+     }
+-    iArg++;
+   }
+   if( pCur->zLine!=0 && pCur->zPrefix==0 ){
+     int i = pCur->nLine;
+@@ -3471,7 +3462,8 @@
+   0,                         /* xRename */
+   0,                         /* xSavepoint */
+   0,                         /* xRelease */
+-  0                          /* xRollbackTo */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
+ };
+ 
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -5368,25 +5360,26 @@
+   sqlite3_index_info *pIdxInfo
+ ){
+   int i;
++  int idx = -1;
++  int unusable = 0;
+ 
+   for(i=0; i<pIdxInfo->nConstraint; i++){
+     const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
+-    if( pCons->usable==0 ) continue;
+-    if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+     if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
+-    break;
++    if( pCons->usable==0 ){
++      unusable = 1;
++    }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++      idx = i;
++    }
+   }
+-
+-  if( i<pIdxInfo->nConstraint ){
+-    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+-    pIdxInfo->aConstraintUsage[i].omit = 1;
++  if( idx>=0 ){
++    pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[idx].omit = 1;
+     pIdxInfo->estimatedCost = 1000.0;
+     pIdxInfo->idxNum = 1;
+-  }else{
+-    pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
+-    pIdxInfo->idxNum = 0;
++  }else if( unusable ){
++    return SQLITE_CONSTRAINT;
+   }
+-
+   return SQLITE_OK;
+ }
+ 
+@@ -7189,6 +7182,7 @@
+     0,                            /* xSavepoint */
+     0,                            /* xRelease */
+     0,                            /* xRollbackTo */
++    0,                            /* xShadowName */
+   };
+ 
+   return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
+@@ -7668,9 +7662,9 @@
+         "EXPLAIN QUERY PLAN %s", pStmt->zSql
+     );
+     while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
+-      int iSelectid = sqlite3_column_int(pExplain, 0);
+-      int iOrder = sqlite3_column_int(pExplain, 1);
+-      int iFrom = sqlite3_column_int(pExplain, 2);
++      /* int iId = sqlite3_column_int(pExplain, 0); */
++      /* int iParent = sqlite3_column_int(pExplain, 1); */
++      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
+       const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
+       int nDetail = STRLEN(zDetail);
+       int i;
+@@ -7697,9 +7691,9 @@
+         }
+       }
+ 
+-      pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n", 
+-          iSelectid, iOrder, iFrom, zDetail
+-      );
++      if( zDetail[0]!='-' ){
++        pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
++      }
+     }
+ 
+     for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
+@@ -8529,6 +8523,23 @@
+   int bVerbose;
+ };
+ 
++/* A single line in the EQP output */
++typedef struct EQPGraphRow EQPGraphRow;
++struct EQPGraphRow {
++  int iEqpId;           /* ID for this row */
++  int iParentId;        /* ID of the parent row */
++  EQPGraphRow *pNext;   /* Next row in sequence */
++  char zText[1];        /* Text to display for this row */
++};
++
++/* All EQP output is collected into an instance of the following */
++typedef struct EQPGraph EQPGraph;
++struct EQPGraph {
++  EQPGraphRow *pRow;    /* Linked list of all rows of the EQP output */
++  EQPGraphRow *pLast;   /* Last element of the pRow list */
++  char zPrefix[100];    /* Graph prefix */
++};
++
+ /*
+ ** State information about the database connection is contained in an
+ ** instance of the following structure.
+@@ -8538,10 +8549,13 @@
+   sqlite3 *db;           /* The database */
+   u8 autoExplain;        /* Automatically turn on .explain mode */
+   u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
++  u8 autoEQPtest;        /* autoEQP is in test mode */
+   u8 statsOn;            /* True to display memory stats before each finalize */
+   u8 scanstatsOn;        /* True to display scan stats before each finalize */
+   u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
+   u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
++  u8 nEqpLevel;          /* Depth of the EQP output graph */
++  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
+   int outCount;          /* Revert to stdout when reaching zero */
+   int cnt;               /* Number of records displayed so far */
+   FILE *out;             /* Write results here */
+@@ -8575,6 +8589,7 @@
+   int *aiIndent;         /* Array of indents used in MODE_Explain */
+   int nIndent;           /* Size of array aiIndent[] */
+   int iIndent;           /* Index of current op in aiIndent[] */
++  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
+ #if defined(SQLITE_ENABLE_SESSION)
+   int nSession;             /* Number of active sessions */
+   OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
+@@ -8585,18 +8600,19 @@
+ 
+ /* Allowed values for ShellState.autoEQP
+ */
+-#define AUTOEQP_off      0
+-#define AUTOEQP_on       1
+-#define AUTOEQP_trigger  2
+-#define AUTOEQP_full     3
++#define AUTOEQP_off      0           /* Automatic EXPLAIN QUERY PLAN is off */
++#define AUTOEQP_on       1           /* Automatic EQP is on */
++#define AUTOEQP_trigger  2           /* On and also show plans for triggers */
++#define AUTOEQP_full     3           /* Show full EXPLAIN */
+ 
+ /* Allowed values for ShellState.openMode
+ */
+-#define SHELL_OPEN_UNSPEC     0      /* No open-mode specified */
+-#define SHELL_OPEN_NORMAL     1      /* Normal database file */
+-#define SHELL_OPEN_APPENDVFS  2      /* Use appendvfs */
+-#define SHELL_OPEN_ZIPFILE    3      /* Use the zipfile virtual table */
+-#define SHELL_OPEN_READONLY   4      /* Open a normal database read-only */
++#define SHELL_OPEN_UNSPEC      0      /* No open-mode specified */
++#define SHELL_OPEN_NORMAL      1      /* Normal database file */
++#define SHELL_OPEN_APPENDVFS   2      /* Use appendvfs */
++#define SHELL_OPEN_ZIPFILE     3      /* Use the zipfile virtual table */
++#define SHELL_OPEN_READONLY    4      /* Open a normal database read-only */
++#define SHELL_OPEN_DESERIALIZE 5      /* Open using sqlite3_deserialize() */
+ 
+ /*
+ ** These are the allowed shellFlgs values
+@@ -8631,6 +8647,7 @@
+ #define MODE_Explain  9  /* Like MODE_Column, but do not truncate data */
+ #define MODE_Ascii   10  /* Use ASCII unit and record separators (0x1F/0x1E) */
+ #define MODE_Pretty  11  /* Pretty-print schemas */
++#define MODE_EQP     12  /* Converts EXPLAIN QUERY PLAN output into a graph */
+ 
+ static const char *modeDescr[] = {
+   "line",
+@@ -8645,6 +8662,7 @@
+   "explain",
+   "ascii",
+   "prettyprint",
++  "eqp"
+ };
+ 
+ /*
+@@ -8715,6 +8733,7 @@
+   char *zCmd = 0;
+   int bBin;
+   int rc;
++  int hasCRNL = 0;
+   FILE *f = 0;
+   sqlite3_int64 sz;
+   sqlite3_int64 x;
+@@ -8746,6 +8765,8 @@
+     }
+   }
+   bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
++  /* When writing the file to be edited, do \n to \r\n conversions on systems
++  ** that want \r\n line endings */
+   f = fopen(zTempFile, bBin ? "wb" : "w");
+   if( f==0 ){
+     sqlite3_result_error(context, "edit() cannot open temp file", -1);
+@@ -8755,6 +8776,9 @@
+   if( bBin ){
+     x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
+   }else{
++    const char *z = (const char*)sqlite3_value_text(argv[0]);
++    /* Remember whether or not the value originally contained \r\n */
++    if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
+     x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
+   }
+   fclose(f);
+@@ -8774,7 +8798,7 @@
+     sqlite3_result_error(context, "EDITOR returned non-zero", -1);
+     goto edit_func_end;
+   }
+-  f = fopen(zTempFile, bBin ? "rb" : "r");
++  f = fopen(zTempFile, "rb");
+   if( f==0 ){
+     sqlite3_result_error(context,
+       "edit() cannot reopen temp file after edit", -1);
+@@ -8788,12 +8812,7 @@
+     sqlite3_result_error_nomem(context);
+     goto edit_func_end;
+   }
+-  if( bBin ){
+-    x = fread(p, 1, sz, f);
+-  }else{
+-    x = fread(p, 1, sz, f);
+-    p[sz] = 0;
+-  }
++  x = fread(p, 1, sz, f);
+   fclose(f);
+   f = 0;
+   if( x!=sz ){
+@@ -8803,6 +8822,20 @@
+   if( bBin ){
+     sqlite3_result_blob64(context, p, sz, sqlite3_free);
+   }else{
++    sqlite3_int64 i, j;
++    if( hasCRNL ){
++      /* If the original contains \r\n then do no conversions back to \n */
++      j = sz;
++    }else{
++      /* If the file did not originally contain \r\n then convert any new
++      ** \r\n back into \n */
++      for(i=j=0; i<sz; i++){
++        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
++        p[j++] = p[i];
++      }
++      sz = j;
++      p[sz] = 0;
++    } 
+     sqlite3_result_text64(context, (const char*)p, sz,
+                           sqlite3_free, SQLITE_UTF8);
+   }
+@@ -9193,9 +9226,95 @@
+   }
+   return 1;
+ }
+-    
+ 
+ /*
++** Add a new entry to the EXPLAIN QUERY PLAN data
++*/
++static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
++  EQPGraphRow *pNew;
++  int nText = strlen30(zText);
++  if( p->autoEQPtest ){
++    utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
++  }
++  pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
++  if( pNew==0 ) shell_out_of_memory();
++  pNew->iEqpId = iEqpId;
++  pNew->iParentId = p2;
++  memcpy(pNew->zText, zText, nText+1);
++  pNew->pNext = 0;
++  if( p->sGraph.pLast ){
++    p->sGraph.pLast->pNext = pNew;
++  }else{
++    p->sGraph.pRow = pNew;
++  }
++  p->sGraph.pLast = pNew;
++}
++
++/*
++** Free and reset the EXPLAIN QUERY PLAN data that has been collected
++** in p->sGraph.
++*/
++static void eqp_reset(ShellState *p){
++  EQPGraphRow *pRow, *pNext;
++  for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
++    pNext = pRow->pNext;
++    sqlite3_free(pRow);
++  }
++  memset(&p->sGraph, 0, sizeof(p->sGraph));
++}
++
++/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
++** pOld, or return the first such line if pOld is NULL
++*/
++static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
++  EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
++  while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
++  return pRow;
++}
++
++/* Render a single level of the graph that has iEqpId as its parent.  Called
++** recursively to render sublevels.
++*/
++static void eqp_render_level(ShellState *p, int iEqpId){
++  EQPGraphRow *pRow, *pNext;
++  int n = strlen30(p->sGraph.zPrefix);
++  char *z;
++  for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
++    pNext = eqp_next_row(p, iEqpId, pRow);
++    z = pRow->zText;
++    utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
++    if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
++      memcpy(&p->sGraph.zPrefix[n], pNext ? "|  " : "   ", 4);
++      eqp_render_level(p, pRow->iEqpId);
++      p->sGraph.zPrefix[n] = 0;
++    }
++  }
++}
++
++/*
++** Display and reset the EXPLAIN QUERY PLAN data
++*/
++static void eqp_render(ShellState *p){
++  EQPGraphRow *pRow = p->sGraph.pRow;
++  if( pRow ){
++    if( pRow->zText[0]=='-' ){
++      if( pRow->pNext==0 ){
++        eqp_reset(p);
++        return;
++      }
++      utf8_printf(p->out, "%s\n", pRow->zText+3);
++      p->sGraph.pRow = pRow->pNext;
++      sqlite3_free(pRow);
++    }else{
++      utf8_printf(p->out, "QUERY PLAN\n");
++    }
++    p->sGraph.zPrefix[0] = 0;
++    eqp_render_level(p, 0);
++    eqp_reset(p);
++  }
++}
++
++/*
+ ** This is the callback routine that the shell
+ ** invokes for each row of a query result.
+ */
+@@ -9475,8 +9594,16 @@
+         }else if( aiType && aiType[i]==SQLITE_FLOAT ){
+           char z[50];
+           double r = sqlite3_column_double(p->pStmt, i);
+-          sqlite3_snprintf(50,z,"%!.20g", r);
+-          raw_printf(p->out, "%s", z);
++          sqlite3_uint64 ur;
++          memcpy(&ur,&r,sizeof(r));
++          if( ur==0x7ff0000000000000LL ){
++            raw_printf(p->out, "1e999");
++          }else if( ur==0xfff0000000000000LL ){
++            raw_printf(p->out, "-1e999");
++          }else{
++            sqlite3_snprintf(50,z,"%!.20g", r);
++            raw_printf(p->out, "%s", z);
++          }
+         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
+           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
+           int nBlob = sqlite3_column_bytes(p->pStmt, i);
+@@ -9544,6 +9671,10 @@
+       utf8_printf(p->out, "%s", p->rowSeparator);
+       break;
+     }
++    case MODE_EQP: {
++      eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
++      break;
++    }
+   }
+   return 0;
+ }
+@@ -9642,10 +9773,7 @@
+   n = strlen30(zName);
+   if( cQuote ) n += n+2;
+   z = p->zDestTable = malloc( n+1 );
+-  if( z==0 ){
+-    raw_printf(stderr,"Error: out of memory\n");
+-    exit(1);
+-  }
++  if( z==0 ) shell_out_of_memory();
+   n = 0;
+   if( cQuote ) z[n++] = cQuote;
+   for(i=0; zName[i]; i++){
+@@ -10008,8 +10136,7 @@
+   int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
+   int iOp;                        /* Index of operation in p->aiIndent[] */
+ 
+-  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
+-                           "NextIfOpen", "PrevIfOpen", 0 };
++  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
+   const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
+                             "Rewind", 0 };
+   const char *azGoto[] = { "Goto", 0 };
+@@ -10059,7 +10186,9 @@
+       }
+       nAlloc += 100;
+       p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
++      if( p->aiIndent==0 ) shell_out_of_memory();
+       abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
++      if( abYield==0 ) shell_out_of_memory();
+     }
+     abYield[iOp] = str_in_array(zOp, azYield);
+     p->aiIndent[iOp] = 0;
+@@ -10385,11 +10514,13 @@
+         rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+         if( rc==SQLITE_OK ){
+           while( sqlite3_step(pExplain)==SQLITE_ROW ){
+-            raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
+-            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
+-            raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
+-            utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
++            const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
++            int iEqpId = sqlite3_column_int(pExplain, 0);
++            int iParentId = sqlite3_column_int(pExplain, 1);
++            if( zEQPLine[0]=='-' ) eqp_render(pArg);
++            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
+           }
++          eqp_render(pArg);
+         }
+         sqlite3_finalize(pExplain);
+         sqlite3_free(zEQP);
+@@ -10411,6 +10542,7 @@
+           /* Reprepare pStmt before reactiving trace modes */
+           sqlite3_finalize(pStmt);
+           sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
++          if( pArg ) pArg->pStmt = pStmt;
+         }
+         restore_debug_trace_modes();
+       }
+@@ -10417,11 +10549,16 @@
+ 
+       if( pArg ){
+         pArg->cMode = pArg->mode;
+-        if( pArg->autoExplain
+-         && sqlite3_column_count(pStmt)==8
+-         && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
+-        ){
+-          pArg->cMode = MODE_Explain;
++        if( pArg->autoExplain ){
++          if( sqlite3_column_count(pStmt)==8
++           && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
++          ){
++            pArg->cMode = MODE_Explain;
++          }
++          if( sqlite3_column_count(pStmt)==4
++           && sqlite3_strlike("EXPLAIN QUERY PLAN%", zStmtSql,0)==0 ){
++            pArg->cMode = MODE_EQP;
++          }
+         }
+ 
+         /* If the shell is currently in ".explain" mode, gather the extra
+@@ -10433,6 +10570,7 @@
+ 
+       exec_prepared_stmt(pArg, pStmt);
+       explain_data_delete(pArg);
++      eqp_render(pArg);
+ 
+       /* print usage stats if stats on */
+       if( pArg && pArg->statsOn ){
+@@ -10510,10 +10648,7 @@
+     if( nCol>=nAlloc-2 ){
+       nAlloc = nAlloc*2 + nCol + 10;
+       azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
+-      if( azCol==0 ){
+-        raw_printf(stderr, "Error: out of memory\n");
+-        exit(1);
+-      }
++      if( azCol==0 ) shell_out_of_memory();
+     }
+     azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
+     if( sqlite3_column_int(pStmt, 5) ){
+@@ -10749,136 +10884,239 @@
+ }
+ 
+ /*
+-** Text of a help message
++** Text of help messages.
++**
++** The help text for each individual command begins with a line that starts
++** with ".".  Subsequent lines are supplimental information.
++**
++** There must be two or more spaces between the end of the command and the
++** start of the description of what that command does.
+ */
+-static char zHelp[] =
++static const char *(azHelp[]) = {
+ #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+-  ".archive ...           Manage SQL archives: \".archive --help\" for details\n"
++  ".archive ...             Manage SQL archives",
++  "   Each command must have exactly one of the following options:",
++  "     -c, --create               Create a new archive",
++  "     -u, --update               Update or add files to an existing archive",
++  "     -t, --list                 List contents of archive",
++  "     -x, --extract              Extract files from archive",
++  "   Optional arguments:",
++  "     -v, --verbose              Print each filename as it is processed",
++  "     -f FILE, --file FILE       Operate on archive FILE (default is current db)",
++  "     -a FILE, --append FILE     Operate on FILE opened using the apndvfs VFS",
++  "     -C DIR, --directory DIR    Change to directory DIR to read/extract files",
++  "     -n, --dryrun               Show the SQL that would have occurred",
++  "   Examples:",
++  "     .ar -cf archive.sar foo bar  # Create archive.sar from files foo and bar",
++  "     .ar -tf archive.sar          # List members of archive.sar",
++  "     .ar -xvf archive.sar         # Verbosely extract files from archive.sar",
++  "   See also:",
++  "      http://sqlite.org/cli.html#sqlar_archive_support",
+ #endif
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  ".auth ON|OFF           Show authorizer callbacks\n"
++  ".auth ON|OFF             Show authorizer callbacks",
+ #endif
+-  ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
+-  ".bail on|off           Stop after hitting an error.  Default OFF\n"
+-  ".binary on|off         Turn binary output on or off.  Default OFF\n"
+-  ".cd DIRECTORY          Change the working directory to DIRECTORY\n"
+-  ".changes on|off        Show number of rows changed by SQL\n"
+-  ".check GLOB            Fail if output since .testcase does not match\n"
+-  ".clone NEWDB           Clone data into NEWDB from the existing database\n"
+-  ".databases             List names and files of attached databases\n"
+-  ".dbinfo ?DB?           Show status information about the database\n"
+-  ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
+-  "                         If TABLE specified, only dump tables matching\n"
+-  "                         LIKE pattern TABLE.\n"
+-  ".echo on|off           Turn command echo on or off\n"
+-  ".eqp on|off|full       Enable or disable automatic EXPLAIN QUERY PLAN\n"
+-  ".excel                 Display the output of next command in a spreadsheet\n"
+-  ".exit                  Exit this program\n"
+-  ".expert                EXPERIMENTAL. Suggest indexes for specified queries\n"
++  ".backup ?DB? FILE        Backup DB (default \"main\") to FILE",
++  "       --append            Use the appendvfs",
++  ".bail on|off             Stop after hitting an error.  Default OFF",
++  ".binary on|off           Turn binary output on or off.  Default OFF",
++  ".cd DIRECTORY            Change the working directory to DIRECTORY",
++  ".changes on|off          Show number of rows changed by SQL",
++  ".check GLOB              Fail if output since .testcase does not match",
++  ".clone NEWDB             Clone data into NEWDB from the existing database",
++  ".databases               List names and files of attached databases",
++  ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
++  ".dbinfo ?DB?             Show status information about the database",
++  ".dump ?TABLE? ...        Render all database content as SQL",
++  "   Options:",
++  "     --preserve-rowids      Include ROWID values in the output",
++  "     --newlines             Allow unescaped newline characters in output",
++  "   TABLE is LIKE pattern for the tables to dump",
++  ".echo on|off             Turn command echo on or off",
++  ".eqp on|off|full         Enable or disable automatic EXPLAIN QUERY PLAN",
++  ".excel                   Display the output of next command in a spreadsheet",
++  ".exit ?CODE?             Exit this program with return-code CODE",
++  ".expert                  EXPERIMENTAL. Suggest indexes for specified queries",
+ /* Because explain mode comes on automatically now, the ".explain" mode
+ ** is removed from the help screen.  It is still supported for legacy, however */
+-/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
+-  ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
+-  ".headers on|off        Turn display of headers on or off\n"
+-  ".help                  Show this message\n"
+-  ".import FILE TABLE     Import data from FILE into TABLE\n"
++/*".explain ?on|off|auto?   Turn EXPLAIN output mode on or off or to automatic",*/
++  ".fullschema ?--indent?   Show schema and the content of sqlite_stat tables",
++  ".headers on|off          Turn display of headers on or off",
++  ".help ?-all? ?PATTERN?   Show help text for PATTERN",
++  ".import FILE TABLE       Import data from FILE into TABLE",
+ #ifndef SQLITE_OMIT_TEST_CONTROL
+-  ".imposter INDEX TABLE  Create imposter table TABLE on index INDEX\n"
++  ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
+ #endif
+-  ".indexes ?TABLE?       Show names of all indexes\n"
+-  "                         If TABLE specified, only show indexes for tables\n"
+-  "                         matching LIKE pattern TABLE.\n"
++  ".indexes ?TABLE?         Show names of indexes",
++  "                           If TABLE is specified, only show indexes for",
++  "                           tables matching TABLE using the LIKE operator.",
+ #ifdef SQLITE_ENABLE_IOTRACE
+-  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
++  ".iotrace FILE            Enable I/O diagnostic logging to FILE",
+ #endif
+-  ".limit ?LIMIT? ?VAL?   Display or change the value of an SQLITE_LIMIT\n"
+-  ".lint OPTIONS          Report potential schema issues. Options:\n"
+-  "                         fkey-indexes     Find missing foreign key indexes\n"
++  ".limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT",
++  ".lint OPTIONS            Report potential schema issues.",
++  "     Options:",
++  "        fkey-indexes     Find missing foreign key indexes",
+ #ifndef SQLITE_OMIT_LOAD_EXTENSION
+-  ".load FILE ?ENTRY?     Load an extension library\n"
++  ".load FILE ?ENTRY?       Load an extension library",
+ #endif
+-  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
+-  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
+-  "                         ascii    Columns/rows delimited by 0x1F and 0x1E\n"
+-  "                         csv      Comma-separated values\n"
+-  "                         column   Left-aligned columns.  (See .width)\n"
+-  "                         html     HTML <table> code\n"
+-  "                         insert   SQL insert statements for TABLE\n"
+-  "                         line     One value per line\n"
+-  "                         list     Values delimited by \"|\"\n"
+-  "                         quote    Escape answers as for SQL\n"
+-  "                         tabs     Tab-separated values\n"
+-  "                         tcl      TCL list elements\n"
+-  ".nullvalue STRING      Use STRING in place of NULL values\n"
+-  ".once (-e|-x|FILE)     Output for the next SQL command only to FILE\n"
+-  "                         or invoke system text editor (-e) or spreadsheet (-x)\n"
+-  "                         on the output.\n"
+-  ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
+-  "                         The --new option starts with an empty file\n"
+-  "                         Other options: --readonly --append --zip\n"
+-  ".output ?FILE?         Send output to FILE or stdout\n"
+-  ".print STRING...       Print literal STRING\n"
+-  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
+-  ".quit                  Exit this program\n"
+-  ".read FILENAME         Execute SQL in FILENAME\n"
+-  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
+-  ".save FILE             Write in-memory database into FILE\n"
+-  ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
+-  ".schema ?PATTERN?      Show the CREATE statements matching PATTERN\n"
+-  "                          Add --indent for pretty-printing\n"
+-  ".selftest ?--init?     Run tests defined in the SELFTEST table\n"
+-  ".separator COL ?ROW?   Change the column separator and optionally the row\n"
+-  "                         separator for both the output mode and .import\n"
++  ".log FILE|off            Turn logging on or off.  FILE can be stderr/stdout",
++  ".mode MODE ?TABLE?       Set output mode",
++  "   MODE is one of:",
++  "     ascii    Columns/rows delimited by 0x1F and 0x1E",
++  "     csv      Comma-separated values",
++  "     column   Left-aligned columns.  (See .width)",
++  "     html     HTML <table> code",
++  "     insert   SQL insert statements for TABLE",
++  "     line     One value per line",
++  "     list     Values delimited by \"|\"",
++  "     quote    Escape answers as for SQL",
++  "     tabs     Tab-separated values",
++  "     tcl      TCL list elements",
++  ".nullvalue STRING        Use STRING in place of NULL values",
++  ".once (-e|-x|FILE)       Output for the next SQL command only to FILE",
++  "     If FILE begins with '|' then open as a pipe",
++  "     Other options:",
++  "       -e    Invoke system text editor",
++  "       -x    Open in a spreadsheet",
++  ".open ?OPTIONS? ?FILE?   Close existing database and reopen FILE",
++  "     Options:",
++  "        --append        Use appendvfs to append database to the end of FILE",
++#ifdef SQLITE_ENABLE_DESERIALIZE
++  "        --deserialize   Load into memory useing sqlite3_deserialize()",
++#endif
++  "        --new           Initialize FILE to an empty database",
++  "        --readonly      Open FILE readonly",
++  "        --zip           FILE is a ZIP archive",
++  ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
++  "     If FILE begins with '|' then open it as a pipe.",
++  ".print STRING...         Print literal STRING",
++  ".prompt MAIN CONTINUE    Replace the standard prompts",
++  ".quit                    Exit this program",
++  ".read FILE               Read input from FILE",
++  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
++  ".save FILE               Write in-memory database into FILE",
++  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
++  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
++  "     Options:",
++  "         --indent            Try to pretty-print the schema",
++  ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
++  "    Options:",
++  "       --init               Create a new SELFTEST table",
++  "       -v                   Verbose output",
++  ".separator COL ?ROW?     Change the column and row separators",
+ #if defined(SQLITE_ENABLE_SESSION)
+-  ".session CMD ...       Create or control sessions\n"
++  ".session ?NAME? CMD ...  Create or control sessions",
++  "   Subcommands:",
++  "     attach TABLE             Attach TABLE",
++  "     changeset FILE           Write a changeset into FILE",
++  "     close                    Close one session",
++  "     enable ?BOOLEAN?         Set or query the enable bit",
++  "     filter GLOB...           Reject tables matching GLOBs",
++  "     indirect ?BOOLEAN?       Mark or query the indirect status",
++  "     isempty                  Query whether the session is empty",
++  "     list                     List currently open session names",
++  "     open DB NAME             Open a new session on DB",
++  "     patchset FILE            Write a patchset into FILE",
++  "   If ?NAME? is omitted, the first defined session is used.",
+ #endif
+-  ".sha3sum ?OPTIONS...?  Compute a SHA3 hash of database content\n"
++  ".sha3sum ...             Compute a SHA3 hash of database content",
++  "    Options:",
++  "      --schema              Also hash the sqlite_master table",
++  "      --sha3-224            Use the sha3-224 algorithm",
++  "      --sha3-256            Use the sha3-256 algorithm.  This is the default.",
++  "      --sha3-384            Use the sha3-384 algorithm",
++  "      --sha3-512            Use the sha3-512 algorithm",
++  "    Any other argument is a LIKE pattern for tables to hash",
+ #ifndef SQLITE_NOHAVE_SYSTEM
+-  ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
++  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
+ #endif
+-  ".show                  Show the current values for various settings\n"
+-  ".stats ?on|off?        Show stats or turn stats on or off\n"
++  ".show                    Show the current values for various settings",
++  ".stats ?on|off?          Show stats or turn stats on or off",
+ #ifndef SQLITE_NOHAVE_SYSTEM
+-  ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
++  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
+ #endif
+-  ".tables ?TABLE?        List names of tables\n"
+-  "                         If TABLE specified, only list tables matching\n"
+-  "                         LIKE pattern TABLE.\n"
+-  ".testcase NAME         Begin redirecting output to 'testcase-out.txt'\n"
+-  ".timeout MS            Try opening locked tables for MS milliseconds\n"
+-  ".timer on|off          Turn SQL timer on or off\n"
+-  ".trace FILE|off        Output each SQL statement as it is run\n"
+-  ".vfsinfo ?AUX?         Information about the top-level VFS\n"
+-  ".vfslist               List all available VFSes\n"
+-  ".vfsname ?AUX?         Print the name of the VFS stack\n"
+-  ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
+-  "                         Negative values right-justify\n"
+-;
++  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
++  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
++  ".timeout MS              Try opening locked tables for MS milliseconds",
++  ".timer on|off            Turn SQL timer on or off",
++  ".trace FILE|off          Output each SQL statement as it is run",
++  ".vfsinfo ?AUX?           Information about the top-level VFS",
++  ".vfslist                 List all available VFSes",
++  ".vfsname ?AUX?           Print the name of the VFS stack",
++  ".width NUM1 NUM2 ...     Set column widths for \"column\" mode",
++  "     Negative values right-justify",
++};
+ 
+-#if defined(SQLITE_ENABLE_SESSION)
+ /*
+-** Print help information for the ".sessions" command
++** Output help text.
++**
++** zPattern describes the set of commands for which help text is provided.
++** If zPattern is NULL, then show all commands, but only give a one-line
++** description of each.
++**
++** Return the number of matches.
+ */
+-void session_help(ShellState *p){
+-  raw_printf(p->out,
+-    ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
+-    "If ?NAME? is omitted, the first defined session is used.\n"
+-    "Subcommands:\n"
+-    "   attach TABLE             Attach TABLE\n"
+-    "   changeset FILE           Write a changeset into FILE\n"
+-    "   close                    Close one session\n"
+-    "   enable ?BOOLEAN?         Set or query the enable bit\n"
+-    "   filter GLOB...           Reject tables matching GLOBs\n"
+-    "   indirect ?BOOLEAN?       Mark or query the indirect status\n"
+-    "   isempty                  Query whether the session is empty\n"
+-    "   list                     List currently open session names\n"
+-    "   open DB NAME             Open a new session on DB\n"
+-    "   patchset FILE            Write a patchset into FILE\n"
+-  );
++static int showHelp(FILE *out, const char *zPattern){
++  int i = 0;
++  int j = 0;
++  int n = 0;
++  char *zPat;
++  if( zPattern==0
++   || zPattern[0]=='0'
++   || strcmp(zPattern,"-a")==0
++   || strcmp(zPattern,"-all")==0
++  ){
++    /* Show all commands, but only one line per command */
++    if( zPattern==0 ) zPattern = "";
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( azHelp[i][0]=='.' || zPattern[0] ){
++        utf8_printf(out, "%s\n", azHelp[i]);
++        n++;
++      }
++    }
++  }else{
++    /* Look for commands that for which zPattern is an exact prefix */
++    zPat = sqlite3_mprintf(".%s*", zPattern);
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( sqlite3_strglob(zPat, azHelp[i])==0 ){
++        utf8_printf(out, "%s\n", azHelp[i]);
++        j = i+1;
++        n++;
++      }
++    }
++    sqlite3_free(zPat);
++    if( n ){
++      if( n==1 ){
++        /* when zPattern is a prefix of exactly one command, then include the
++        ** details of that command, which should begin at offset j */
++        while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
++          utf8_printf(out, "%s\n", azHelp[j]);
++          j++;
++        }
++      }
++      return n;
++    }
++    /* Look for commands that contain zPattern anywhere.  Show the complete
++    ** text of all commands that match. */
++    zPat = sqlite3_mprintf("%%%s%%", zPattern);
++    for(i=0; i<ArraySize(azHelp); i++){
++      if( azHelp[i][0]=='.' ) j = i;
++      if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
++        utf8_printf(out, "%s\n", azHelp[j]);
++        while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
++          j++;
++          utf8_printf(out, "%s\n", azHelp[j]);
++        }
++        i = j;
++        n++;
++      }
++    }
++    sqlite3_free(zPat);
++  }
++  return n;
+ }
+-#endif
+ 
+-
+ /* Forward reference */
+ static int process_input(ShellState *p, FILE *in);
+ 
+@@ -10907,7 +11145,7 @@
+   nIn = ftell(in);
+   rewind(in);
+   pBuf = sqlite3_malloc64( nIn+1 );
+-  if( pBuf==0 ) return 0;
++  if( pBuf==0 ){ fclose(in); return 0; }
+   nRead = fread(pBuf, nIn, 1, in);
+   fclose(in);
+   if( nRead!=1 ){
+@@ -10975,13 +11213,21 @@
+ ** Otherwise, assume an ordinary database regardless of the filename if
+ ** the type cannot be determined from content.
+ */
+-static int deduceDatabaseType(const char *zName, int dfltZip){
++int deduceDatabaseType(const char *zName, int dfltZip){
+   FILE *f = fopen(zName, "rb");
+   size_t n;
+   int rc = SHELL_OPEN_UNSPEC;
+   char zBuf[100];
+   if( f==0 ){
+-    if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ) return SHELL_OPEN_ZIPFILE;
++    if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
++       return SHELL_OPEN_ZIPFILE;
++    }else{
++       return SHELL_OPEN_NORMAL;
++    }
++  }
++  n = fread(zBuf, 16, 1, f);
++  if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
++    fclose(f);
+     return SHELL_OPEN_NORMAL;
+   }
+   fseek(f, -25, SEEK_END);
+@@ -10995,7 +11241,7 @@
+        && zBuf[3]==0x06 ){
+       rc = SHELL_OPEN_ZIPFILE;
+     }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
+-      return SHELL_OPEN_ZIPFILE;
++      rc = SHELL_OPEN_ZIPFILE;
+     }
+   }
+   fclose(f);
+@@ -11002,15 +11248,32 @@
+   return rc;  
+ }
+ 
++/* Flags for open_db().
++**
++** The default behavior of open_db() is to exit(1) if the database fails to
++** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
++** but still returns without calling exit.
++**
++** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
++** ZIP archive if the file does not exist or is empty and its name matches
++** the *.zip pattern.
++*/
++#define OPEN_DB_KEEPALIVE   0x001   /* Return after error if true */
++#define OPEN_DB_ZIPFILE     0x002   /* Open as ZIP if name matches *.zip */
++
+ /*
+ ** Make sure the database is open.  If it is not, then open it.  If
+ ** the database fails to open, print an error message and exit.
+ */
+-static void open_db(ShellState *p, int keepAlive){
++static void open_db(ShellState *p, int openFlags){
+   if( p->db==0 ){
+-    sqlite3_initialize();
+-    if( p->openMode==SHELL_OPEN_UNSPEC && access(p->zDbFilename,0)==0 ){
+-      p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 0);
++    if( p->openMode==SHELL_OPEN_UNSPEC ){
++      if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
++        p->openMode = SHELL_OPEN_NORMAL;
++      }else{
++        p->openMode = (u8)deduceDatabaseType(p->zDbFilename, 
++                             (openFlags & OPEN_DB_ZIPFILE)!=0);
++      }
+     }
+     switch( p->openMode ){
+       case SHELL_OPEN_APPENDVFS: {
+@@ -11018,6 +11281,10 @@
+            SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
+         break;
+       }
++      case SHELL_OPEN_DESERIALIZE: {
++        sqlite3_open(0, &p->db);
++        break;
++      }
+       case SHELL_OPEN_ZIPFILE: {
+         sqlite3_open(":memory:", &p->db);
+         break;
+@@ -11036,7 +11303,7 @@
+     if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
+       utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
+           p->zDbFilename, sqlite3_errmsg(p->db));
+-      if( keepAlive ) return;
++      if( openFlags & OPEN_DB_KEEPALIVE ) return;
+       exit(1);
+     }
+ #ifndef SQLITE_OMIT_LOAD_EXTENSION
+@@ -11067,9 +11334,32 @@
+       sqlite3_exec(p->db, zSql, 0, 0, 0);
+       sqlite3_free(zSql);
+     }
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
++      int nData = 0;
++      unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
++      int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
++                   SQLITE_DESERIALIZE_RESIZEABLE |
++                   SQLITE_DESERIALIZE_FREEONCLOSE);
++      if( rc ){
++        utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
++      }
++    }
++#endif
+   }
+ }
+ 
++/*
++** Attempt to close the databaes connection.  Report errors.
++*/
++void close_db(sqlite3 *db){
++  int rc = sqlite3_close(db);
++  if( rc ){
++    utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
++        rc, sqlite3_errmsg(db));
++  } 
++}
++
+ #if HAVE_READLINE || HAVE_EDITLINE
+ /*
+ ** Readline completion callbacks
+@@ -11111,7 +11401,7 @@
+   char zBuf[1000];
+ 
+   if( nLine>sizeof(zBuf)-30 ) return;
+-  if( zLine[0]=='.' ) return;
++  if( zLine[0]=='.' || zLine[0]=='#') return;
+   for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
+   if( i==nLine-1 ) return;
+   iStart = i+1;
+@@ -11311,10 +11601,7 @@
+   if( p->n+1>=p->nAlloc ){
+     p->nAlloc += p->nAlloc + 100;
+     p->z = sqlite3_realloc64(p->z, p->nAlloc);
+-    if( p->z==0 ){
+-      raw_printf(stderr, "out of memory\n");
+-      exit(1);
+-    }
++    if( p->z==0 ) shell_out_of_memory();
+   }
+   p->z[p->n++] = (char)c;
+ }
+@@ -11475,10 +11762,7 @@
+   }
+   n = sqlite3_column_count(pQuery);
+   zInsert = sqlite3_malloc64(200 + nTable + n*3);
+-  if( zInsert==0 ){
+-    raw_printf(stderr, "out of memory\n");
+-    goto end_data_xfer;
+-  }
++  if( zInsert==0 ) shell_out_of_memory();
+   sqlite3_snprintf(200+nTable,zInsert,
+                    "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
+   i = strlen30(zInsert);
+@@ -11656,7 +11940,7 @@
+     sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
+     sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
+   }
+-  sqlite3_close(newDb);
++  close_db(newDb);
+ }
+ 
+ /*
+@@ -11755,6 +12039,7 @@
+        "SELECT total(length(sql)) FROM %s" },
+   };
+   int i;
++  unsigned iDataVersion;
+   char *zSchemaTab;
+   char *zDb = nArg>=2 ? azArg[1] : "main";
+   sqlite3_stmt *pStmt = 0;
+@@ -11807,6 +12092,8 @@
+     utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
+   }
+   sqlite3_free(zSchemaTab);
++  sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
++  utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
+   return 0;
+ }
+ 
+@@ -11820,14 +12107,6 @@
+ }
+ 
+ /*
+-** Print an out-of-memory message to stderr and return 1.
+-*/
+-static int shellNomemError(void){
+-  raw_printf(stderr, "Error: out of memory\n");
+-  return 1;
+-}
+-
+-/*
+ ** Compare the pattern in zGlob[] against the text in z[].  Return TRUE
+ ** if they match and FALSE (0) if they do not match.
+ **
+@@ -12271,6 +12550,7 @@
+     char *z;
+     va_start(ap, zFmt);
+     z = sqlite3_vmprintf(zFmt, ap);
++    va_end(ap);
+     if( z==0 ){
+       *pRc = SQLITE_NOMEM;
+     }else{
+@@ -12319,6 +12599,7 @@
+   u8 bZip;                        /* True if the archive is a ZIP */
+   u8 bDryRun;                     /* True if --dry-run */
+   u8 bAppend;                     /* True if --append */
++  u8 fromCmdLine;                 /* Run from -A instead of .archive */
+   int nArg;                       /* Number of command arguments */
+   char *zSrcTable;                /* "sqlar", "zipfile($file)" or "zip" */
+   const char *zFile;              /* --file argument, or NULL */
+@@ -12332,32 +12613,7 @@
+ ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
+ */
+ static int arUsage(FILE *f){
+-  raw_printf(f,
+-"\n"
+-"Usage: .ar [OPTION...] [FILE...]\n"
+-"The .ar command manages sqlar archives.\n"
+-"\n"
+-"Examples:\n"
+-"  .ar -cf archive.sar foo bar    # Create archive.sar from files foo and bar\n"
+-"  .ar -tf archive.sar            # List members of archive.sar\n"
+-"  .ar -xvf archive.sar           # Verbosely extract files from archive.sar\n"
+-"\n"
+-"Each command line must feature exactly one command option:\n"
+-"  -c, --create               Create a new archive\n"
+-"  -u, --update               Update or add files to an existing archive\n"
+-"  -t, --list                 List contents of archive\n"
+-"  -x, --extract              Extract files from archive\n"
+-"\n"
+-"And zero or more optional options:\n"
+-"  -v, --verbose              Print each filename as it is processed\n"
+-"  -f FILE, --file FILE       Operate on archive FILE (default is current db)\n"
+-"  -a FILE, --append FILE     Operate on FILE opened using the apndvfs VFS\n"
+-"  -C DIR, --directory DIR    Change to directory DIR to read/extract files\n"
+-"  -n, --dryrun               Show the SQL that would have occurred\n"
+-"\n"
+-"See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
+-"\n"
+-);
++  showHelp(f,"archive");
+   return SQLITE_ERROR;
+ }
+ 
+@@ -12365,13 +12621,18 @@
+ ** Print an error message for the .ar command to stderr and return 
+ ** SQLITE_ERROR.
+ */
+-static int arErrorMsg(const char *zFmt, ...){
++static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
+   va_list ap;
+   char *z;
+   va_start(ap, zFmt);
+   z = sqlite3_vmprintf(zFmt, ap);
+   va_end(ap);
+-  raw_printf(stderr, "Error: %s (try \".ar --help\")\n", z);
++  utf8_printf(stderr, "Error: %s\n", z);
++  if( pAr->fromCmdLine ){
++    utf8_printf(stderr, "Use \"-A\" for more help\n");
++  }else{
++    utf8_printf(stderr, "Use \".archive --help\" for more help\n");
++  }
+   sqlite3_free(z);
+   return SQLITE_ERROR;
+ }
+@@ -12402,7 +12663,7 @@
+     case AR_CMD_UPDATE:
+     case AR_CMD_HELP:
+       if( pAr->eCmd ){
+-        return arErrorMsg("multiple command options");
++        return arErrorMsg(pAr, "multiple command options");
+       }
+       pAr->eCmd = eSwitch;
+       break;
+@@ -12459,11 +12720,10 @@
+   struct ArSwitch *pEnd = &aSwitch[nSwitch];
+ 
+   if( nArg<=1 ){
++    utf8_printf(stderr, "Wrong number of arguments.  Usage:\n");
+     return arUsage(stderr);
+   }else{
+     char *z = azArg[1];
+-    memset(pAr, 0, sizeof(ArCommand));
+-
+     if( z[0]!='-' ){
+       /* Traditional style [tar] invocation */
+       int i;
+@@ -12475,11 +12735,11 @@
+           if( z[i]==pOpt->cShort ) break;
+         }
+         if( pOpt==pEnd ){
+-          return arErrorMsg("unrecognized option: %c", z[i]);
++          return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
+         }
+         if( pOpt->bArg ){
+           if( iArg>=nArg ){
+-            return arErrorMsg("option requires an argument: %c",z[i]);
++            return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
+           }
+           zArg = azArg[iArg++];
+         }
+@@ -12513,7 +12773,7 @@
+               if( z[i]==pOpt->cShort ) break;
+             }
+             if( pOpt==pEnd ){
+-              return arErrorMsg("unrecognized option: %c\n", z[i]);
++              return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
+             }
+             if( pOpt->bArg ){
+               if( i<(n-1) ){
+@@ -12521,7 +12781,7 @@
+                 i = n;
+               }else{
+                 if( iArg>=(nArg-1) ){
+-                  return arErrorMsg("option requires an argument: %c\n",z[i]);
++                  return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
+                 }
+                 zArg = azArg[++iArg];
+               }
+@@ -12543,7 +12803,7 @@
+             const char *zLong = pOpt->zLong;
+             if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
+               if( pMatch ){
+-                return arErrorMsg("ambiguous option: %s",z);
++                return arErrorMsg(pAr, "ambiguous option: %s",z);
+               }else{
+                 pMatch = pOpt;
+               }
+@@ -12551,11 +12811,11 @@
+           }
+ 
+           if( pMatch==0 ){
+-            return arErrorMsg("unrecognized option: %s", z);
++            return arErrorMsg(pAr, "unrecognized option: %s", z);
+           }
+           if( pMatch->bArg ){
+             if( iArg>=(nArg-1) ){
+-              return arErrorMsg("option requires an argument: %s", z);
++              return arErrorMsg(pAr, "option requires an argument: %s", z);
+             }
+             zArg = azArg[++iArg];
+           }
+@@ -12684,6 +12944,7 @@
+     }
+   }
+   shellFinalize(&rc, pSql);
++  sqlite3_free(zWhere);
+   return rc;
+ }
+ 
+@@ -12696,7 +12957,8 @@
+     "SELECT "
+     " ($dir || name),"
+     " writefile(($dir || name), %s, mode, mtime) "
+-    "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)";
++    "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
++    " AND name NOT GLOB '*..[/\\]*'";
+ 
+   const char *azExtraArg[] = { 
+     "sqlar_uncompress(data, sz)",
+@@ -12886,6 +13148,7 @@
+ */
+ static int arDotCommand(
+   ShellState *pState,             /* Current shell tool state */
++  int fromCmdLine,                /* True if -A command-line option, not .ar cmd */
+   char **azArg,                   /* Array of arguments passed to dot command */
+   int nArg                        /* Number of entries in azArg[] */
+ ){
+@@ -12892,6 +13155,7 @@
+   ArCommand cmd;
+   int rc;
+   memset(&cmd, 0, sizeof(cmd));
++  cmd.fromCmdLine = fromCmdLine;
+   rc = arParseCommand(azArg, nArg, &cmd);
+   if( rc==SQLITE_OK ){
+     int eDbType = SHELL_OPEN_UNSPEC;
+@@ -12938,7 +13202,7 @@
+                               shellPutsFunc, 0, 0);
+ 
+     }
+-    if( cmd.zSrcTable==0 && cmd.bZip==0 ){
++    if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
+       if( cmd.eCmd!=AR_CMD_CREATE
+        && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
+       ){
+@@ -12974,7 +13238,7 @@
+   }
+ end_ar_command:
+   if( cmd.db!=pState->db ){
+-    sqlite3_close(cmd.db);
++    close_db(cmd.db);
+   }
+   sqlite3_free(cmd.zSrcTable);
+ 
+@@ -13054,7 +13318,7 @@
+ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+   if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
+     open_db(p, 0);
+-    rc = arDotCommand(p, azArg, nArg);
++    rc = arDotCommand(p, 0, azArg, nArg);
+   }else
+ #endif
+ 
+@@ -13066,11 +13330,14 @@
+     sqlite3 *pDest;
+     sqlite3_backup *pBackup;
+     int j;
++    const char *zVfs = 0;
+     for(j=1; j<nArg; j++){
+       const char *z = azArg[j];
+       if( z[0]=='-' ){
+-        while( z[0]=='-' ) z++;
+-        /* No options to process at this time */
++        if( z[1]=='-' ) z++;
++        if( strcmp(z, "-append")==0 ){
++          zVfs = "apndvfs";
++        }else
+         {
+           utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
+           return 1;
+@@ -13081,7 +13348,7 @@
+         zDb = zDestFile;
+         zDestFile = azArg[j];
+       }else{
+-        raw_printf(stderr, "too many arguments to .backup\n");
++        raw_printf(stderr, "Usage: .backup ?DB? ?--append? FILENAME\n");
+         return 1;
+       }
+     }
+@@ -13090,10 +13357,11 @@
+       return 1;
+     }
+     if( zDb==0 ) zDb = "main";
+-    rc = sqlite3_open(zDestFile, &pDest);
++    rc = sqlite3_open_v2(zDestFile, &pDest, 
++                  SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
+     if( rc!=SQLITE_OK ){
+       utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
+-      sqlite3_close(pDest);
++      close_db(pDest);
+       return 1;
+     }
+     open_db(p, 0);
+@@ -13100,7 +13368,7 @@
+     pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
+     if( pBackup==0 ){
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+-      sqlite3_close(pDest);
++      close_db(pDest);
+       return 1;
+     }
+     while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
+@@ -13111,7 +13379,7 @@
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
+       rc = 1;
+     }
+-    sqlite3_close(pDest);
++    close_db(pDest);
+   }else
+ 
+   if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
+@@ -13223,7 +13491,39 @@
+     }
+   }else
+ 
+-  if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
++  if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
++    static const struct DbConfigChoices {
++      const char *zName;
++      int op;
++    } aDbConfig[] = {
++        { "enable_fkey",      SQLITE_DBCONFIG_ENABLE_FKEY            },
++        { "enable_trigger",   SQLITE_DBCONFIG_ENABLE_TRIGGER         },
++        { "fts3_tokenizer",   SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER  },
++        { "load_extension",   SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION  },
++        { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE       },
++        { "enable_qpsg",      SQLITE_DBCONFIG_ENABLE_QPSG            },
++        { "trigger_eqp",      SQLITE_DBCONFIG_TRIGGER_EQP            },
++        { "reset_database",   SQLITE_DBCONFIG_RESET_DATABASE         },
++        { "defensive",        SQLITE_DBCONFIG_DEFENSIVE              },
++    };
++    int ii, v;
++    open_db(p, 0);
++    for(ii=0; ii<ArraySize(aDbConfig); ii++){
++      if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
++      if( nArg>=3 ){
++        sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
++      }
++      sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
++      utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
++      if( nArg>1 ) break;
++    }
++    if( nArg>1 && ii==ArraySize(aDbConfig) ){
++      utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
++      utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
++    }   
++  }else
++
++  if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
+     rc = shell_dbinfo_command(p, nArg, azArg);
+   }else
+ 
+@@ -13231,7 +13531,8 @@
+     const char *zLike = 0;
+     int i;
+     int savedShowHeader = p->showHeader;
+-    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines);
++    int savedShellFlags = p->shellFlgs;
++    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
+     for(i=1; i<nArg; i++){
+       if( azArg[i][0]=='-' ){
+         const char *z = azArg[i]+1;
+@@ -13313,6 +13614,7 @@
+     sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
+     raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
+     p->showHeader = savedShowHeader;
++    p->shellFlgs = savedShellFlags;
+   }else
+ 
+   if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
+@@ -13326,10 +13628,14 @@
+ 
+   if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
+     if( nArg==2 ){
++      p->autoEQPtest = 0;
+       if( strcmp(azArg[1],"full")==0 ){
+         p->autoEQP = AUTOEQP_full;
+       }else if( strcmp(azArg[1],"trigger")==0 ){
+         p->autoEQP = AUTOEQP_trigger;
++      }else if( strcmp(azArg[1],"test")==0 ){
++        p->autoEQP = AUTOEQP_on;
++        p->autoEQPtest = 1;
+       }else{
+         p->autoEQP = (u8)booleanValue(azArg[1]);
+       }
+@@ -13418,11 +13724,11 @@
+                    callback, &data, &zErrMsg);
+       data.cMode = data.mode = MODE_Insert;
+       data.zDestTable = "sqlite_stat1";
+-      shell_exec(p, "SELECT * FROM sqlite_stat1", &zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
+       data.zDestTable = "sqlite_stat3";
+-      shell_exec(p, "SELECT * FROM sqlite_stat3", &zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
+       data.zDestTable = "sqlite_stat4";
+-      shell_exec(p, "SELECT * FROM sqlite_stat4", &zErrMsg);
++      shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
+       raw_printf(p->out, "ANALYZE sqlite_master;\n");
+     }
+   }else
+@@ -13437,7 +13743,14 @@
+   }else
+ 
+   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
+-    utf8_printf(p->out, "%s", zHelp);
++    if( nArg>=2 ){
++      n = showHelp(p->out, azArg[1]);
++      if( n==0 ){
++        utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
++      }
++    }else{
++      showHelp(p->out, 0);
++    }
+   }else
+ 
+   if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
+@@ -13520,9 +13833,8 @@
+     sCtx.cRowSep = p->rowSeparator[0];
+     zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
+     if( zSql==0 ){
+-      raw_printf(stderr, "Error: out of memory\n");
+       xCloser(sCtx.in);
+-      return 1;
++      shell_out_of_memory();
+     }
+     nByte = strlen30(zSql);
+     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+@@ -13567,9 +13879,8 @@
+     if( nCol==0 ) return 0; /* no columns, no error */
+     zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
+     if( zSql==0 ){
+-      raw_printf(stderr, "Error: out of memory\n");
+       xCloser(sCtx.in);
+-      return 1;
++      shell_out_of_memory();
+     }
+     sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
+     j = strlen30(zSql);
+@@ -13645,12 +13956,17 @@
+     sqlite3_stmt *pStmt;
+     int tnum = 0;
+     int i;
+-    if( nArg!=3 ){
+-      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
++    if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
++      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
++                          "       .imposter off\n");
+       rc = 1;
+       goto meta_command_exit;
+     }
+     open_db(p, 0);
++    if( nArg==2 ){
++      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
++      goto meta_command_exit;
++    }
+     zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
+                            " WHERE name='%q' AND type='index'", azArg[1]);
+     sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+@@ -13892,7 +14208,7 @@
+     int newFlag = 0;     /* True to delete file before opening */
+     /* Close the existing database */
+     session_close_all(p);
+-    sqlite3_close(p->db);
++    close_db(p->db);
+     p->db = 0;
+     p->zDbFilename = 0;
+     sqlite3_free(p->zFreeOnClose);
+@@ -13911,6 +14227,10 @@
+         p->openMode = SHELL_OPEN_APPENDVFS;
+       }else if( optionMatch(z, "readonly") ){
+         p->openMode = SHELL_OPEN_READONLY;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++      }else if( optionMatch(z, "deserialize") ){
++        p->openMode = SHELL_OPEN_DESERIALIZE;
++#endif
+       }else if( z[0]=='-' ){
+         utf8_printf(stderr, "unknown option: %s\n", z);
+         rc = 1;
+@@ -13922,7 +14242,7 @@
+     if( zNewFilename ){
+       if( newFlag ) shellDeleteFile(zNewFilename);
+       p->zDbFilename = zNewFilename;
+-      open_db(p, 1);
++      open_db(p, OPEN_DB_KEEPALIVE);
+       if( p->db==0 ){
+         utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
+         sqlite3_free(zNewFilename);
+@@ -14072,7 +14392,7 @@
+     rc = sqlite3_open(zSrcFile, &pSrc);
+     if( rc!=SQLITE_OK ){
+       utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
+-      sqlite3_close(pSrc);
++      close_db(pSrc);
+       return 1;
+     }
+     open_db(p, 0);
+@@ -14079,7 +14399,7 @@
+     pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
+     if( pBackup==0 ){
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+-      sqlite3_close(pSrc);
++      close_db(pSrc);
+       return 1;
+     }
+     while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
+@@ -14099,7 +14419,7 @@
+       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
+       rc = 1;
+     }
+-    sqlite3_close(pSrc);
++    close_db(pSrc);
+   }else
+ 
+   if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
+@@ -14438,7 +14758,7 @@
+     }else
+     /* If no command name matches, show a syntax error */
+     session_syntax_error:
+-    session_help(p);
++    showHelp(p->out, "session");
+   }else
+ #endif
+ 
+@@ -14619,7 +14939,7 @@
+           utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
+                       azArg[i], azArg[0]);
+           raw_printf(stderr, "Should be one of: --schema"
+-                             " --sha3-224 --sha3-255 --sha3-384 --sha3-512\n");
++                             " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
+           rc = 1;
+           goto meta_command_exit;
+         }
+@@ -14783,7 +15103,10 @@
+     initText(&s);
+     open_db(p, 0);
+     rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
+-    if( rc ) return shellDatabaseError(p->db);
++    if( rc ){
++      sqlite3_finalize(pStmt);
++      return shellDatabaseError(p->db);
++    }
+ 
+     if( nArg>2 && c=='i' ){
+       /* It is an historical accident that the .indexes command shows an error
+@@ -14791,6 +15114,7 @@
+       ** command does not. */
+       raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
+       rc = 1;
++      sqlite3_finalize(pStmt);
+       goto meta_command_exit;
+     }
+     for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
+@@ -14835,18 +15159,12 @@
+         char **azNew;
+         int n2 = nAlloc*2 + 10;
+         azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
+-        if( azNew==0 ){
+-          rc = shellNomemError();
+-          break;
+-        }
++        if( azNew==0 ) shell_out_of_memory();
+         nAlloc = n2;
+         azResult = azNew;
+       }
+       azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
+-      if( 0==azResult[nRow] ){
+-        rc = shellNomemError();
+-        break;
+-      }
++      if( 0==azResult[nRow] ) shell_out_of_memory();
+       nRow++;
+     }
+     if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
+@@ -14907,9 +15225,7 @@
+       { "byteorder",          SQLITE_TESTCTRL_BYTEORDER,     ""                   },
+     /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, ""                }, */
+       { "imposter",           SQLITE_TESTCTRL_IMPOSTER,   "SCHEMA ON/OFF ROOTPAGE"},
+-#ifdef SQLITE_N_KEYWORD
+-      { "iskeyword",          SQLITE_TESTCTRL_ISKEYWORD,     "IDENTIFIER"         },
+-#endif
++      { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN"       },
+       { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN"           },
+       { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN"            },
+       { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK"       },
+@@ -15004,6 +15320,7 @@
+         /* sqlite3_test_control(int, int) */
+         case SQLITE_TESTCTRL_ASSERT:
+         case SQLITE_TESTCTRL_ALWAYS:
++        case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
+           if( nArg==3 ){
+             int opt = booleanValue(azArg[2]);
+             rc2 = sqlite3_test_control(testctrl, opt);
+@@ -15021,17 +15338,6 @@
+           }
+           break;
+ 
+-        /* sqlite3_test_control(int, char *) */
+-#ifdef SQLITE_N_KEYWORD
+-        case SQLITE_TESTCTRL_ISKEYWORD:
+-          if( nArg==3 ){
+-            const char *opt = azArg[2];
+-            rc2 = sqlite3_test_control(testctrl, opt);
+-            isOk = 1;
+-          }
+-          break;
+-#endif
+-
+         case SQLITE_TESTCTRL_IMPOSTER:
+           if( nArg==5 ){
+             rc2 = sqlite3_test_control(testctrl, p->db,
+@@ -15309,7 +15615,7 @@
+ ** user-friendly, but it does seem to work.
+ */
+ #ifdef SQLITE_OMIT_COMPLETE
+-int sqlite3_complete(const char *zSql){ return 1; }
++#define sqlite3_complete(x) 1
+ #endif
+ 
+ /*
+@@ -15327,7 +15633,7 @@
+ }
+ 
+ /*
+-** Run a single line of SQL
++** Run a single line of SQL.  Return the number of errors.
+ */
+ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
+   int rc;
+@@ -15400,13 +15706,15 @@
+       if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+       continue;
+     }
+-    if( zLine && zLine[0]=='.' && nSql==0 ){
++    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
+       if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+-      rc = do_meta_command(zLine, p);
+-      if( rc==2 ){ /* exit requested */
+-        break;
+-      }else if( rc ){
+-        errCnt++;
++      if( zLine[0]=='.' ){
++        rc = do_meta_command(zLine, p);
++        if( rc==2 ){ /* exit requested */
++          break;
++        }else if( rc ){
++          errCnt++;
++        }
+       }
+       continue;
+     }
+@@ -15417,10 +15725,7 @@
+     if( nSql+nLine+2>=nAlloc ){
+       nAlloc = nSql+nLine+100;
+       zSql = realloc(zSql, nAlloc);
+-      if( zSql==0 ){
+-        raw_printf(stderr, "Error: out of memory\n");
+-        exit(1);
+-      }
++      if( zSql==0 ) shell_out_of_memory();
+     }
+     nSqlPrior = nSql;
+     if( nSql==0 ){
+@@ -15451,7 +15756,7 @@
+     }
+   }
+   if( nSql && !_all_whitespace(zSql) ){
+-    runOneSqlLine(p, zSql, in, startline);
++    errCnt += runOneSqlLine(p, zSql, in, startline);
+   }
+   free(zSql);
+   free(zLine);
+@@ -15549,7 +15854,6 @@
+                       " cannot read ~/.sqliterc\n");
+       return;
+     }
+-    sqlite3_initialize();
+     zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
+     sqliterc = zBuf;
+   }
+@@ -15600,6 +15904,9 @@
+   "   -quote               set output mode to 'quote'\n"
+   "   -readonly            open the database read-only\n"
+   "   -separator SEP       set output column separator. Default: '|'\n"
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  "   -sorterref SIZE      sorter references threshold size\n"
++#endif
+   "   -stats               print memory stats before each finalize\n"
+   "   -version             show SQLite version\n"
+   "   -vfs NAME            use NAME as the default VFS\n"
+@@ -15624,6 +15931,17 @@
+ }
+ 
+ /*
++** Internal check:  Verify that the SQLite is uninitialized.  Print a
++** error message if it is initialized.
++*/
++static void verify_uninitialized(void){
++  if( sqlite3_config(-1)==SQLITE_MISUSE ){
++    utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
++                        " initialization.\n");
++  }
++}
++
++/*
+ ** Initialize the state information in data
+ */
+ static void main_init(ShellState *data) {
+@@ -15634,6 +15952,7 @@
+   memcpy(data->rowSeparator,SEP_Row, 2);
+   data->showHeader = 0;
+   data->shellFlgs = SHFLG_Lookaside;
++  verify_uninitialized();
+   sqlite3_config(SQLITE_CONFIG_URI, 1);
+   sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
+   sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
+@@ -15697,6 +16016,11 @@
+   int readStdin = 1;
+   int nCmd = 0;
+   char **azCmd = 0;
++  const char *zVfs = 0;           /* Value of -vfs command-line option */
++#if !SQLITE_SHELL_IS_UTF8
++  char **argvToFree = 0;
++  int argcToFree = 0;
++#endif
+ 
+   setBinaryMode(stdin, 0);
+   setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+@@ -15703,6 +16027,23 @@
+   stdin_is_interactive = isatty(0);
+   stdout_is_console = isatty(1);
+ 
++#if !defined(_WIN32_WCE)
++  if( getenv("SQLITE_DEBUG_BREAK") ){
++    if( isatty(0) && isatty(2) ){
++      fprintf(stderr,
++          "attach debugger to process %d and press any key to continue.\n",
++          GETPID());
++      fgetc(stdin);
++    }else{
++#if defined(_WIN32) || defined(WIN32)
++      DebugBreak();
++#elif defined(SIGTRAP)
++      raise(SIGTRAP);
++#endif
++    }
++  }
++#endif
++
+ #if USE_SYSTEM_SQLITE+0!=1
+   if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
+     utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
+@@ -15720,25 +16061,19 @@
+   */
+ #if !SQLITE_SHELL_IS_UTF8
+   sqlite3_initialize();
+-  argv = malloc(sizeof(argv[0])*argc);
+-  if( argv==0 ){
+-    raw_printf(stderr, "out of memory\n");
+-    exit(1);
+-  }
++  argvToFree = malloc(sizeof(argv[0])*argc*2);
++  argcToFree = argc;
++  argv = argvToFree + argc;
++  if( argv==0 ) shell_out_of_memory();
+   for(i=0; i<argc; i++){
+     char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
+     int n;
+-    if( z==0 ){
+-      raw_printf(stderr, "out of memory\n");
+-      exit(1);
+-    }
++    if( z==0 ) shell_out_of_memory();
+     n = (int)strlen(z);
+     argv[i] = malloc( n+1 );
+-    if( argv[i]==0 ){
+-      raw_printf(stderr, "out of memory\n");
+-      exit(1);
+-    }
++    if( argv[i]==0 ) shell_out_of_memory();
+     memcpy(argv[i], z, n+1);
++    argvToFree[i] = argv[i];
+     sqlite3_free(z);
+   }
+   sqlite3_shutdown();
+@@ -15773,6 +16108,7 @@
+   ** the size of the alternative malloc heap,
+   ** and the first command to execute.
+   */
++  verify_uninitialized();
+   for(i=1; i<argc; i++){
+     char *z;
+     z = argv[i];
+@@ -15785,10 +16121,7 @@
+         readStdin = 0;
+         nCmd++;
+         azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
+-        if( azCmd==0 ){
+-          raw_printf(stderr, "out of memory\n");
+-          exit(1);
+-        }
++        if( azCmd==0 ) shell_out_of_memory();
+         azCmd[nCmd-1] = z;
+       }
+     }
+@@ -15855,14 +16188,13 @@
+     }else if( strcmp(z,"-mmap")==0 ){
+       sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+       sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    }else if( strcmp(z,"-sorterref")==0 ){
++      sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
++      sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
++#endif
+     }else if( strcmp(z,"-vfs")==0 ){
+-      sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
+-      if( pVfs ){
+-        sqlite3_vfs_register(pVfs, 1);
+-      }else{
+-        utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
+-        exit(1);
+-      }
++      zVfs = cmdline_option_value(argc, argv, ++i);
+ #ifdef SQLITE_HAVE_ZLIB
+     }else if( strcmp(z,"-zip")==0 ){
+       data.openMode = SHELL_OPEN_ZIPFILE;
+@@ -15869,6 +16201,10 @@
+ #endif
+     }else if( strcmp(z,"-append")==0 ){
+       data.openMode = SHELL_OPEN_APPENDVFS;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    }else if( strcmp(z,"-deserialize")==0 ){
++      data.openMode = SHELL_OPEN_DESERIALIZE;
++#endif
+     }else if( strcmp(z,"-readonly")==0 ){
+       data.openMode = SHELL_OPEN_READONLY;
+ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+@@ -15879,6 +16215,34 @@
+ #endif
+     }
+   }
++  verify_uninitialized();
++
++
++#ifdef SQLITE_SHELL_INIT_PROC
++  {
++    /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
++    ** of a C-function that will perform initialization actions on SQLite that
++    ** occur just before or after sqlite3_initialize(). Use this compile-time
++    ** option to embed this shell program in larger applications. */
++    extern void SQLITE_SHELL_INIT_PROC(void);
++    SQLITE_SHELL_INIT_PROC();
++  }
++#else
++  /* All the sqlite3_config() calls have now been made. So it is safe
++  ** to call sqlite3_initialize() and process any command line -vfs option. */
++  sqlite3_initialize();
++#endif
++
++  if( zVfs ){
++    sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
++    if( pVfs ){
++      sqlite3_vfs_register(pVfs, 1);
++    }else{
++      utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
++      exit(1);
++    }
++  }
++
+   if( data.zDbFilename==0 ){
+ #ifndef SQLITE_OMIT_MEMORYDB
+     data.zDbFilename = ":memory:";
+@@ -15936,6 +16300,10 @@
+ #endif
+     }else if( strcmp(z,"-append")==0 ){
+       data.openMode = SHELL_OPEN_APPENDVFS;
++#ifdef SQLITE_ENABLE_DESERIALIZE
++    }else if( strcmp(z,"-deserialize")==0 ){
++      data.openMode = SHELL_OPEN_DESERIALIZE;
++#endif
+     }else if( strcmp(z,"-readonly")==0 ){
+       data.openMode = SHELL_OPEN_READONLY;
+     }else if( strcmp(z,"-ascii")==0 ){
+@@ -15991,6 +16359,10 @@
+       i+=2;
+     }else if( strcmp(z,"-mmap")==0 ){
+       i++;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    }else if( strcmp(z,"-sorterref")==0 ){
++      i++;
++#endif
+     }else if( strcmp(z,"-vfs")==0 ){
+       i++;
+ #ifdef SQLITE_ENABLE_VFSTRACE
+@@ -16031,12 +16403,12 @@
+                             " with \"%s\"\n", z);
+         return 1;
+       }
+-      open_db(&data, 0);
++      open_db(&data, OPEN_DB_ZIPFILE);
+       if( z[2] ){
+         argv[i] = &z[2];
+-        arDotCommand(&data, argv+(i-1), argc-(i-1));
++        arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
+       }else{
+-        arDotCommand(&data, argv+i, argc-i);
++        arDotCommand(&data, 1, argv+i, argc-i);
+       }
+       readStdin = 0;
+       break;
+@@ -16076,7 +16448,7 @@
+     */
+     if( stdin_is_interactive ){
+       char *zHome;
+-      char *zHistory = 0;
++      char *zHistory;
+       int nHistory;
+       printf(
+         "SQLite version %s %.19s\n" /*extra-version-info*/
+@@ -16089,8 +16461,10 @@
+         printf(".\nUse \".open FILENAME\" to reopen on a "
+                "persistent database.\n");
+       }
+-      zHome = find_home_dir(0);
+-      if( zHome ){
++      zHistory = getenv("SQLITE_HISTORY");
++      if( zHistory ){
++        zHistory = strdup(zHistory);
++      }else if( (zHome = find_home_dir(0))!=0 ){
+         nHistory = strlen30(zHome) + 20;
+         if( (zHistory = malloc(nHistory))!=0 ){
+           sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
+@@ -16115,7 +16489,7 @@
+   set_table_name(&data, 0);
+   if( data.db ){
+     session_close_all(&data);
+-    sqlite3_close(data.db);
++    close_db(data.db);
+   }
+   sqlite3_free(data.zFreeOnClose);
+   find_home_dir(1);
+@@ -16123,8 +16497,11 @@
+   data.doXdgOpen = 0;
+   clearTempFile(&data);
+ #if !SQLITE_SHELL_IS_UTF8
+-  for(i=0; i<argc; i++) free(argv[i]);
+-  free(argv);
++  for(i=0; i<argcToFree; i++) free(argvToFree[i]);
++  free(argvToFree);
+ #endif
++  /* Clear the global data structure so that valgrind will detect memory
++  ** leaks */
++  memset(&data, 0, sizeof(data));
+   return rc;
+ }
+--- contrib/sqlite3/sqlite3.c.orig
++++ contrib/sqlite3/sqlite3.c
+@@ -1,6 +1,6 @@
+ /******************************************************************************
+ ** This file is an amalgamation of many separate C source files from SQLite
+-** version 3.23.1.  By combining all the individual C code files into this
++** version 3.26.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
+@@ -55,6 +55,12 @@
+ #define CTIMEOPT_VAL_(opt) #opt
+ #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+ 
++/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This
++** option requires a separate macro because legal values contain a single
++** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */
++#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2
++#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt)
++
+ /*
+ ** An array of names of all compile-time options.  This array should 
+ ** be sorted A-Z.
+@@ -138,7 +144,7 @@
+   "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
+ #endif
+ #ifdef SQLITE_DEFAULT_LOOKASIDE
+-  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE),
++  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
+ #endif
+ #if SQLITE_DEFAULT_MEMSTATUS
+   "DEFAULT_MEMSTATUS",
+@@ -254,6 +260,9 @@
+ #if SQLITE_ENABLE_FTS5
+   "ENABLE_FTS5",
+ #endif
++#if SQLITE_ENABLE_GEOPOLY
++  "ENABLE_GEOPOLY",
++#endif
+ #if SQLITE_ENABLE_HIDDEN_COLUMNS
+   "ENABLE_HIDDEN_COLUMNS",
+ #endif
+@@ -284,6 +293,9 @@
+ #if SQLITE_ENABLE_MULTIPLEX
+   "ENABLE_MULTIPLEX",
+ #endif
++#if SQLITE_ENABLE_NORMALIZE
++  "ENABLE_NORMALIZE",
++#endif
+ #if SQLITE_ENABLE_NULL_TRIM
+   "ENABLE_NULL_TRIM",
+ #endif
+@@ -311,6 +323,9 @@
+ #if SQLITE_ENABLE_SNAPSHOT
+   "ENABLE_SNAPSHOT",
+ #endif
++#if SQLITE_ENABLE_SORTER_REFERENCES
++  "ENABLE_SORTER_REFERENCES",
++#endif
+ #if SQLITE_ENABLE_SQLLOG
+   "ENABLE_SQLLOG",
+ #endif
+@@ -1147,9 +1162,9 @@
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.23.1"
+-#define SQLITE_VERSION_NUMBER 3023001
+-#define SQLITE_SOURCE_ID      "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b"
++#define SQLITE_VERSION        "3.26.0"
++#define SQLITE_VERSION_NUMBER 3026000
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+@@ -1496,6 +1511,7 @@
+ */
+ #define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
+ #define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
++#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+ #define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+ #define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+ #define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+@@ -1528,6 +1544,7 @@
+ #define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
+ #define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
++#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+ #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+@@ -1534,7 +1551,9 @@
+ #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
+ #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+ #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
++#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+ #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
++#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
+ #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
+ #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+ #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+@@ -1908,7 +1927,8 @@
+ ** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
+ ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+ ** persistent [WAL | Write Ahead Log] setting.  By default, the auxiliary
+-** write ahead log and shared memory files used for transaction control
++** write ahead log ([WAL file]) and shared memory
++** files used for transaction control
+ ** are automatically deleted when the latest connection to the database
+ ** closes.  Setting persistent WAL mode causes those files to persist after
+ ** close.  Persisting the files is useful when other processes that do not
+@@ -2094,6 +2114,26 @@
+ ** a file lock using the xLock or xShmLock methods of the VFS to wait
+ ** for up to M milliseconds before failing, where M is the single 
+ ** unsigned integer parameter.
++**
++** <li>[[SQLITE_FCNTL_DATA_VERSION]]
++** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
++** a database file.  The argument is a pointer to a 32-bit unsigned integer.
++** The "data version" for the pager is written into the pointer.  The
++** "data version" changes whenever any change occurs to the corresponding
++** database file, either through SQL statements on the same database
++** connection or through transactions committed by separate database
++** connections possibly in other processes. The [sqlite3_total_changes()]
++** interface can be used to find if any database on the connection has changed,
++** but that interface responds to changes on TEMP as well as MAIN and does
++** not provide a mechanism to detect changes to MAIN only.  Also, the
++** [sqlite3_total_changes()] interface responds to internal changes only and
++** omits changes made by other database connections.  The
++** [PRAGMA data_version] command provide a mechanism to detect changes to
++** a single attached database that occur due to other database connections,
++** but omits changes implemented by the database connection on which it is
++** called.  This file control is the only mechanism to detect changes that
++** happen either internally or externally and that are associated with
++** a particular attached database.
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -2129,6 +2169,7 @@
+ #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
+ #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
+ #define SQLITE_FCNTL_LOCK_TIMEOUT           34
++#define SQLITE_FCNTL_DATA_VERSION           35
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -2954,6 +2995,22 @@
+ ** I/O required to support statement rollback.
+ ** The default value for this setting is controlled by the
+ ** [SQLITE_STMTJRNL_SPILL] compile-time option.
++**
++** [[SQLITE_CONFIG_SORTERREF_SIZE]]
++** <dt>SQLITE_CONFIG_SORTERREF_SIZE
++** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
++** of type (int) - the new value of the sorter-reference size threshold.
++** Usually, when SQLite uses an external sort to order records according
++** to an ORDER BY clause, all fields required by the caller are present in the
++** sorted records. However, if SQLite determines based on the declared type
++** of a table column that its values are likely to be very large - larger
++** than the configured sorter-reference size threshold - then a reference
++** is stored in each sorted record and the required column values loaded
++** from the database as records are returned in sorted order. The default
++** value for this option is to never use this optimization. Specifying a 
++** negative value for this option restores the default behaviour.
++** This option is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -2983,6 +3040,7 @@
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+ #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
+ #define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
++#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -2998,6 +3056,7 @@
+ ** is invoked.
+ **
+ ** <dl>
++** [[SQLITE_DBCONFIG_LOOKASIDE]]
+ ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+ ** <dd> ^This option takes three additional arguments that determine the 
+ ** [lookaside memory allocator] configuration for the [database connection].
+@@ -3020,6 +3079,7 @@
+ ** memory is in use leaves the configuration unchanged and returns 
+ ** [SQLITE_BUSY].)^</dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
+ ** <dd> ^This option is used to enable or disable the enforcement of
+ ** [foreign key constraints].  There should be two additional arguments.
+@@ -3030,6 +3090,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the FK enforcement setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
+ ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
+ ** There should be two additional arguments.
+@@ -3040,6 +3101,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+ ** <dd> ^This option is used to enable or disable the two-argument
+ ** version of the [fts3_tokenizer()] function which is part of the
+@@ -3053,6 +3115,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the new setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+ ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+ ** interface independently of the [load_extension()] SQL function.
+@@ -3070,7 +3133,7 @@
+ ** be a NULL pointer, in which case the new setting is not reported back.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+ ** <dd> ^This option is used to change the name of the "main" database
+ ** schema.  ^The sole argument is a pointer to a constant UTF8 string
+ ** which will become the new schema name in place of "main".  ^SQLite
+@@ -3079,6 +3142,7 @@
+ ** until after the database connection closes.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] 
+ ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+ ** <dd> Usually, when a database in wal mode is closed or detached from a 
+ ** database handle, SQLite checks if this will mean that there are now no 
+@@ -3092,7 +3156,7 @@
+ ** have been disabled - 0 if they are not disabled, 1 if they are.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+ ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+ ** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+ ** a single SQL query statement will always use the same algorithm regardless
+@@ -3108,7 +3172,7 @@
+ ** following this call.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
++** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+ ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 
+ ** include output for any operations performed by trigger programs. This
+ ** option is used to set or clear (the default) a flag that governs this
+@@ -3119,6 +3183,39 @@
+ ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
+ ** it is not disabled, 1 if it is.  
+ ** </dd>
++**
++** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
++** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
++** [VACUUM] in order to reset a database back to an empty database
++** with no schema and no content. The following process works even for
++** a badly corrupted database file:
++** <ol>
++** <li> If the database connection is newly opened, make sure it has read the
++**      database schema by preparing then discarding some query against the
++**      database, or calling sqlite3_table_column_metadata(), ignoring any
++**      errors.  This step is only necessary if the application desires to keep
++**      the database in WAL mode after the reset if it was in WAL mode before
++**      the reset.  
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
++** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
++** </ol>
++** Because resetting a database is destructive and irreversible, the
++** process requires the use of this obscure API and multiple steps to help
++** ensure that it does not happen by accident.
++**
++** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
++** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
++** "defensive" flag for a database connection.  When the defensive
++** flag is enabled, language features that allow ordinary SQL to 
++** deliberately corrupt the database file are disabled.  The disabled
++** features include but are not limited to the following:
++** <ul>
++** <li> The [PRAGMA writable_schema=ON] statement.
++** <li> Writes to the [sqlite_dbpage] virtual table.
++** <li> Direct writes to [shadow tables].
++** </ul>
++** </dd>
+ ** </dl>
+ */
+ #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
+@@ -3130,7 +3227,9 @@
+ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+ #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
+ #define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
+-#define SQLITE_DBCONFIG_MAX                   1008 /* Largest DBCONFIG */
++#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
++#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
++#define SQLITE_DBCONFIG_MAX                   1010 /* Largest DBCONFIG */
+ 
+ /*
+ ** CAPI3REF: Enable Or Disable Extended Result Codes
+@@ -3258,12 +3357,17 @@
+ ** program, the value returned reflects the number of rows modified by the 
+ ** previous INSERT, UPDATE or DELETE statement within the same trigger.
+ **
+-** See also the [sqlite3_total_changes()] interface, the
+-** [count_changes pragma], and the [changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_total_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** </ul>
+ */
+ SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+@@ -3281,13 +3385,26 @@
+ ** count, but those made as part of REPLACE constraint resolution are
+ ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+ ** are not counted.
++**
++** This the [sqlite3_total_changes(D)] interface only reports the number
++** of rows that changed due to SQL statement run against database
++** connection D.  Any changes by other database connections are ignored.
++** To detect changes against a database file from other database
++** connections use the [PRAGMA data_version] command or the
++** [SQLITE_FCNTL_DATA_VERSION] [file control].
+ ** 
+-** See also the [sqlite3_changes()] interface, the
+-** [count_changes pragma], and the [total_changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
++** </ul>
+ */
+ SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+@@ -4343,13 +4460,24 @@
+ ** [database connection] D failed, then the sqlite3_errcode(D) interface
+ ** returns the numeric [result code] or [extended result code] for that
+ ** API call.
+-** If the most recent API call was successful,
+-** then the return value from sqlite3_errcode() is undefined.
+ ** ^The sqlite3_extended_errcode()
+ ** interface is the same except that it always returns the 
+ ** [extended result code] even when extended result codes are
+ ** disabled.
+ **
++** The values returned by sqlite3_errcode() and/or
++** sqlite3_extended_errcode() might change with each API call.
++** Except, there are some interfaces that are guaranteed to never
++** change the value of the error code.  The error-code preserving
++** interfaces are:
++**
++** <ul>
++** <li> sqlite3_errcode()
++** <li> sqlite3_extended_errcode()
++** <li> sqlite3_errmsg()
++** <li> sqlite3_errmsg16()
++** </ul>
++**
+ ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+ ** text that describes the error, as either UTF-8 or UTF-16 respectively.
+ ** ^(Memory to hold the error message string is managed internally.
+@@ -4539,9 +4667,19 @@
+ ** on this hint by avoiding the use of [lookaside memory] so as not to
+ ** deplete the limited store of lookaside memory. Future versions of
+ ** SQLite may act on this hint differently.
++**
++** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
++** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
++** representation of the SQL statement should be calculated and then
++** associated with the prepared statement, which can be obtained via
++** the [sqlite3_normalized_sql()] interface.)^  The semantics used to
++** normalize a SQL statement are unspecified and subject to change.
++** At a minimum, literal values will be replaced with suitable
++** placeholders.
+ ** </dl>
+ */
+ #define SQLITE_PREPARE_PERSISTENT              0x01
++#define SQLITE_PREPARE_NORMALIZE               0x02
+ 
+ /*
+ ** CAPI3REF: Compiling An SQL Statement
+@@ -4699,6 +4837,11 @@
+ ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+ ** string containing the SQL text of prepared statement P with
+ ** [bound parameters] expanded.
++** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
++** string containing the normalized SQL text of prepared statement P.  The
++** semantics used to normalize a SQL statement are unspecified and subject
++** to change.  At a minimum, literal values will be replaced with suitable
++** placeholders.
+ **
+ ** ^(For example, if a prepared statement is created using the SQL
+ ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+@@ -4714,8 +4857,9 @@
+ ** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+ ** option causes sqlite3_expanded_sql() to always return NULL.
+ **
+-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
+-** automatically freed when the prepared statement is finalized.
++** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
++** are managed by SQLite and are automatically freed when the prepared
++** statement is finalized.
+ ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+ ** is obtained from [sqlite3_malloc()] and must be free by the application
+ ** by passing it to [sqlite3_free()].
+@@ -4722,6 +4866,7 @@
+ */
+ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -5503,11 +5648,25 @@
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+-** ^(If a memory allocation error occurs during the evaluation of any
+-** of these routines, a default value is returned.  The default value
+-** is either the integer 0, the floating point number 0.0, or a NULL
+-** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+-** [SQLITE_NOMEM].)^
++** As long as the input parameters are correct, these routines will only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_column_blob()
++** <li> sqlite3_column_text()
++** <li> sqlite3_column_text16()
++** <li> sqlite3_column_bytes()
++** <li> sqlite3_column_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+ SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+@@ -5584,11 +5743,13 @@
+ **
+ ** ^These functions (collectively known as "function creation routines")
+ ** are used to add SQL functions or aggregates or to redefine the behavior
+-** of existing SQL functions or aggregates.  The only differences between
+-** these routines are the text encoding expected for
+-** the second parameter (the name of the function being created)
+-** and the presence or absence of a destructor callback for
+-** the application data pointer.
++** of existing SQL functions or aggregates. The only differences between
++** the three "sqlite3_create_function*" routines are the text encoding 
++** expected for the second parameter (the name of the function being 
++** created) and the presence or absence of a destructor callback for
++** the application data pointer. Function sqlite3_create_window_function()
++** is similar, but allows the user to supply the extra callback functions
++** needed by [aggregate window functions].
+ **
+ ** ^The first parameter is the [database connection] to which the SQL
+ ** function is to be added.  ^If an application uses more than one database
+@@ -5634,7 +5795,8 @@
+ ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+ ** function can gain access to this pointer using [sqlite3_user_data()].)^
+ **
+-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
++** ^The sixth, seventh and eighth parameters passed to the three
++** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+ ** pointers to C-language functions that implement the SQL function or
+ ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
+ ** callback only; NULL pointers must be passed as the xStep and xFinal
+@@ -5643,16 +5805,25 @@
+ ** SQL function or aggregate, pass NULL pointers for all three function
+ ** callbacks.
+ **
+-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
+-** then it is destructor for the application data pointer. 
+-** The destructor is invoked when the function is deleted, either by being
+-** overloaded or when the database connection closes.)^
+-** ^The destructor is also invoked if the call to
+-** sqlite3_create_function_v2() fails.
+-** ^When the destructor callback of the tenth parameter is invoked, it
+-** is passed a single argument which is a copy of the application data 
+-** pointer which was the fifth parameter to sqlite3_create_function_v2().
++** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
++** and xInverse) passed to sqlite3_create_window_function are pointers to
++** C-language callbacks that implement the new function. xStep and xFinal
++** must both be non-NULL. xValue and xInverse may either both be NULL, in
++** which case a regular aggregate function is created, or must both be 
++** non-NULL, in which case the new function may be used as either an aggregate
++** or aggregate window function. More details regarding the implementation
++** of aggregate window functions are 
++** [user-defined window functions|available here].
+ **
++** ^(If the final parameter to sqlite3_create_function_v2() or
++** sqlite3_create_window_function() is not NULL, then it is destructor for
++** the application data pointer. The destructor is invoked when the function 
++** is deleted, either by being overloaded or when the database connection 
++** closes.)^ ^The destructor is also invoked if the call to 
++** sqlite3_create_function_v2() fails.  ^When the destructor callback is
++** invoked, it is passed a single argument which is a copy of the application
++** data pointer which was the fifth parameter to sqlite3_create_function_v2().
++**
+ ** ^It is permitted to register multiple implementations of the same
+ ** functions with the same name but with either differing numbers of
+ ** arguments or differing preferred text encodings.  ^SQLite will use
+@@ -5704,6 +5875,18 @@
+   void (*xFinal)(sqlite3_context*),
+   void(*xDestroy)(void*)
+ );
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunctionName,
++  int nArg,
++  int eTextRep,
++  void *pApp,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
++);
+ 
+ /*
+ ** CAPI3REF: Text Encodings
+@@ -5846,6 +6029,28 @@
+ **
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
++**
++** As long as the input parameter is correct, these routines can only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_value_blob()
++** <li> sqlite3_value_text()
++** <li> sqlite3_value_text16()
++** <li> sqlite3_value_text16le()
++** <li> sqlite3_value_text16be()
++** <li> sqlite3_value_bytes()
++** <li> sqlite3_value_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+ SQLITE_API double sqlite3_value_double(sqlite3_value*);
+@@ -6517,6 +6722,41 @@
+ SQLITE_API char *sqlite3_data_directory;
+ 
+ /*
++** CAPI3REF: Win32 Specific Interface
++**
++** These interfaces are available only on Windows.  The
++** [sqlite3_win32_set_directory] interface is used to set the value associated
++** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
++** zValue, depending on the value of the type parameter.  The zValue parameter
++** should be NULL to cause the previous value to be freed via [sqlite3_free];
++** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
++** prior to being used.  The [sqlite3_win32_set_directory] interface returns
++** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
++** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
++** [sqlite3_data_directory] variable is intended to act as a replacement for
++** the current directory on the sub-platforms of Win32 where that concept is
++** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
++** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
++** sqlite3_win32_set_directory interface except the string parameter must be
++** UTF-8 or UTF-16, respectively.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++);
++SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
++SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
++
++/*
++** CAPI3REF: Win32 Directory Types
++**
++** These macros are only available on Windows.  They define the allowed values
++** for the type argument to the [sqlite3_win32_set_directory] interface.
++*/
++#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
++#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
++
++/*
+ ** CAPI3REF: Test For Auto-Commit Mode
+ ** KEYWORDS: {autocommit mode}
+ ** METHOD: sqlite3
+@@ -7116,6 +7356,9 @@
+   int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+   int (*xRelease)(sqlite3_vtab *pVTab, int);
+   int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
++  /* The methods above are in versions 1 and 2 of the sqlite_module object.
++  ** Those below are for version 3 and greater. */
++  int (*xShadowName)(const char*);
+ };
+ 
+ /*
+@@ -7248,6 +7491,10 @@
+ 
+ /*
+ ** CAPI3REF: Virtual Table Scan Flags
++**
++** Virtual table implementations are allowed to set the 
++** [sqlite3_index_info].idxFlags field to some combination of
++** these bits.
+ */
+ #define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
+ 
+@@ -7273,6 +7520,7 @@
+ #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+ #define SQLITE_INDEX_CONSTRAINT_ISNULL    71
+ #define SQLITE_INDEX_CONSTRAINT_IS        72
++#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -7949,6 +8197,7 @@
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+ ** METHOD: sqlite3
++** KEYWORDS: {file control}
+ **
+ ** ^The [sqlite3_file_control()] interface makes a direct call to the
+ ** xFileControl method for the [sqlite3_io_methods] object associated
+@@ -7963,11 +8212,18 @@
+ ** the xFileControl method.  ^The return value of the xFileControl
+ ** method becomes the return value of this routine.
+ **
++** A few opcodes for [sqlite3_file_control()] are handled directly
++** by the SQLite core and never invoke the 
++** sqlite3_io_methods.xFileControl method.
+ ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+ ** a pointer to the underlying [sqlite3_file] object to be written into
+-** the space pointed to by the 4th parameter.  ^The [SQLITE_FCNTL_FILE_POINTER]
+-** case is a short-circuit path which does not actually invoke the
+-** underlying sqlite3_io_methods.xFileControl method.
++** the space pointed to by the 4th parameter.  The
++** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
++** the [sqlite3_file] object associated with the journal file instead of
++** the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
++** a pointer to the underlying [sqlite3_vfs] object for the file.
++** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
++** from the pager.
+ **
+ ** ^If the second parameter (zDbName) does not match the name of any
+ ** open database file, then SQLITE_ERROR is returned.  ^This error
+@@ -8023,8 +8279,9 @@
+ #define SQLITE_TESTCTRL_ALWAYS                  13
+ #define SQLITE_TESTCTRL_RESERVE                 14
+ #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
+-#define SQLITE_TESTCTRL_ISKEYWORD               16
++#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
+ #define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
++#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
+ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+@@ -8038,6 +8295,189 @@
+ #define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+ 
+ /*
++** CAPI3REF: SQL Keyword Checking
++**
++** These routines provide access to the set of SQL language keywords 
++** recognized by SQLite.  Applications can uses these routines to determine
++** whether or not a specific identifier needs to be escaped (for example,
++** by enclosing in double-quotes) so as not to confuse the parser.
++**
++** The sqlite3_keyword_count() interface returns the number of distinct
++** keywords understood by SQLite.
++**
++** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
++** makes *Z point to that keyword expressed as UTF8 and writes the number
++** of bytes in the keyword into *L.  The string that *Z points to is not
++** zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
++** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
++** or L are NULL or invalid pointers then calls to
++** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
++**
++** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
++** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
++** if it is and zero if not.
++**
++** The parser used by SQLite is forgiving.  It is often possible to use
++** a keyword as an identifier as long as such use does not result in a
++** parsing ambiguity.  For example, the statement
++** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
++** creates a new table named "BEGIN" with three columns named
++** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
++** using keywords as identifiers.  Common techniques used to avoid keyword
++** name collisions include:
++** <ul>
++** <li> Put all identifier names inside double-quotes.  This is the official
++**      SQL way to escape identifier names.
++** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
++**      but it is what SQL Server does and so lots of programmers use this
++**      technique.
++** <li> Begin every identifier with the letter "Z" as no SQL keywords start
++**      with "Z".
++** <li> Include a digit somewhere in every identifier name.
++** </ul>
++**
++** Note that the number of keywords understood by SQLite can depend on
++** compile-time options.  For example, "VACUUM" is not a keyword if
++** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
++** new keywords may be added to future releases of SQLite.
++*/
++SQLITE_API int sqlite3_keyword_count(void);
++SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
++SQLITE_API int sqlite3_keyword_check(const char*,int);
++
++/*
++** CAPI3REF: Dynamic String Object
++** KEYWORDS: {dynamic string}
++**
++** An instance of the sqlite3_str object contains a dynamically-sized
++** string under construction.
++**
++** The lifecycle of an sqlite3_str object is as follows:
++** <ol>
++** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
++** <li> ^Text is appended to the sqlite3_str object using various
++** methods, such as [sqlite3_str_appendf()].
++** <li> ^The sqlite3_str object is destroyed and the string it created
++** is returned using the [sqlite3_str_finish()] interface.
++** </ol>
++*/
++typedef struct sqlite3_str sqlite3_str;
++
++/*
++** CAPI3REF: Create A New Dynamic String Object
++** CONSTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_new(D)] interface allocates and initializes
++** a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
++** [sqlite3_str_new()] must be freed by a subsequent call to 
++** [sqlite3_str_finish(X)].
++**
++** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
++** valid [sqlite3_str] object, though in the event of an out-of-memory
++** error the returned object might be a special singleton that will
++** silently reject new text, always return SQLITE_NOMEM from 
++** [sqlite3_str_errcode()], always return 0 for 
++** [sqlite3_str_length()], and always return NULL from
++** [sqlite3_str_finish(X)].  It is always safe to use the value
++** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
++** to any of the other [sqlite3_str] methods.
++**
++** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
++** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
++** length of the string contained in the [sqlite3_str] object will be
++** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
++** of [SQLITE_MAX_LENGTH].
++*/
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
++
++/*
++** CAPI3REF: Finalize A Dynamic String
++** DESTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
++** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
++** that contains the constructed string.  The calling application should
++** pass the returned value to [sqlite3_free()] to avoid a memory leak.
++** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
++** errors were encountered during construction of the string.  ^The
++** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
++** string in [sqlite3_str] object X is zero bytes long.
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
++
++/*
++** CAPI3REF: Add Content To A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces add content to an sqlite3_str object previously obtained
++** from [sqlite3_str_new()].
++**
++** ^The [sqlite3_str_appendf(X,F,...)] and 
++** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
++** functionality of SQLite to append formatted text onto the end of 
++** [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
++** onto the end of the [sqlite3_str] object X.  N must be non-negative.
++** S must contain at least N non-zero bytes of content.  To append a
++** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
++** method instead.
++**
++** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
++** zero-terminated string S onto the end of [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
++** single-byte character C onto the end of [sqlite3_str] object X.
++** ^This method can be used, for example, to add whitespace indentation.
++**
++** ^The [sqlite3_str_reset(X)] method resets the string under construction
++** inside [sqlite3_str] object X back to zero bytes in length.  
++**
++** These methods do not return a result code.  ^If an error occurs, that fact
++** is recorded in the [sqlite3_str] object and can be recovered by a
++** subsequent call to [sqlite3_str_errcode(X)].
++*/
++SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
++SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
++SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
++SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
++SQLITE_API void sqlite3_str_reset(sqlite3_str*);
++
++/*
++** CAPI3REF: Status Of A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces return the current status of an [sqlite3_str] object.
++**
++** ^If any prior errors have occurred while constructing the dynamic string
++** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
++** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
++** [SQLITE_NOMEM] following any out-of-memory error, or
++** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
++** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
++**
++** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
++** of the dynamic string under construction in [sqlite3_str] object X.
++** ^The length returned by [sqlite3_str_length(X)] does not include the
++** zero-termination byte.
++**
++** ^The [sqlite3_str_value(X)] method returns a pointer to the current
++** content of the dynamic string under construction in X.  The value
++** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
++** and might be freed or altered by any subsequent method on the same
++** [sqlite3_str] object.  Applications must not used the pointer returned
++** [sqlite3_str_value(X)] after any subsequent method call on the same
++** object.  ^Applications may change the content of the string returned
++** by [sqlite3_str_value(X)] as long as they do not write into any bytes
++** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
++** write any byte after any subsequent sqlite3_str method call.
++*/
++SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
++SQLITE_API int sqlite3_str_length(sqlite3_str*);
++SQLITE_API char *sqlite3_str_value(sqlite3_str*);
++
++/*
+ ** CAPI3REF: SQLite Runtime Status
+ **
+ ** ^These interfaces are used to retrieve runtime status information
+@@ -9254,6 +9694,7 @@
+ ** can use to customize and optimize their behavior.
+ **
+ ** <dl>
++** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
+ ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
+ ** <dd>Calls of the form
+ ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
+@@ -9306,11 +9747,11 @@
+ ** method of a [virtual table], then it returns true if and only if the
+ ** column is being fetched as part of an UPDATE operation during which the
+ ** column value will not change.  Applications might use this to substitute
+-** a lighter-weight value to return that the corresponding [xUpdate] method
+-** understands as a "no-change" value.
++** a return value that is less expensive to compute and that the corresponding
++** [xUpdate] method understands as a "no-change" value.
+ **
+ ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+-** the column is not changed by the UPDATE statement, they the xColumn
++** the column is not changed by the UPDATE statement, then the xColumn
+ ** method can optionally return without setting a result, without calling
+ ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+ ** In that case, [sqlite3_value_nochange(X)] will return true for the
+@@ -9603,7 +10044,6 @@
+ /*
+ ** CAPI3REF: Database Snapshot
+ ** KEYWORDS: {snapshot} {sqlite3_snapshot}
+-** EXPERIMENTAL
+ **
+ ** An instance of the snapshot object records the state of a [WAL mode]
+ ** database for some specific point in history.
+@@ -9620,11 +10060,6 @@
+ ** version of the database file so that it is possible to later open a new read
+ ** transaction that sees that historical version of the database rather than
+ ** the most recent version.
+-**
+-** The constructor for this object is [sqlite3_snapshot_get()].  The
+-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+-** to an historical snapshot (if possible).  The destructor for 
+-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+ */
+ typedef struct sqlite3_snapshot {
+   unsigned char hidden[48];
+@@ -9632,7 +10067,7 @@
+ 
+ /*
+ ** CAPI3REF: Record A Database Snapshot
+-** EXPERIMENTAL
++** CONSTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+ ** new [sqlite3_snapshot] object that records the current state of
+@@ -9648,7 +10083,7 @@
+ ** in this case. 
+ **
+ ** <ul>
+-**   <li> The database handle must be in [autocommit mode].
++**   <li> The database handle must not be in [autocommit mode].
+ **
+ **   <li> Schema S of [database connection] D must be a [WAL mode] database.
+ **
+@@ -9671,7 +10106,7 @@
+ ** to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_get()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+   sqlite3 *db,
+@@ -9681,24 +10116,35 @@
+ 
+ /*
+ ** CAPI3REF: Start a read transaction on an historical snapshot
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+-** read transaction for schema S of
+-** [database connection] D such that the read transaction
+-** refers to historical [snapshot] P, rather than the most
+-** recent change to the database.
+-** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+-** or an appropriate [error code] if it fails.
++** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read 
++** transaction or upgrades an existing one for schema S of 
++** [database connection] D such that the read transaction refers to 
++** historical [snapshot] P, rather than the most recent change to the 
++** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK 
++** on success or an appropriate [error code] if it fails.
+ **
+-** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+-** the first operation following the [BEGIN] that takes the schema S
+-** out of [autocommit mode].
+-** ^In other words, schema S must not currently be in
+-** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+-** database connection D must be out of [autocommit mode].
+-** ^A [snapshot] will fail to open if it has been overwritten by a
+-** [checkpoint].
++** ^In order to succeed, the database connection must not be in 
++** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
++** is already a read transaction open on schema S, then the database handle
++** must have no active statements (SELECT statements that have been passed
++** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). 
++** SQLITE_ERROR is returned if either of these conditions is violated, or
++** if schema S does not exist, or if the snapshot object is invalid.
++**
++** ^A call to sqlite3_snapshot_open() will fail to open if the specified
++** snapshot has been overwritten by a [checkpoint]. In this case 
++** SQLITE_ERROR_SNAPSHOT is returned.
++**
++** If there is already a read transaction open when this function is 
++** invoked, then the same read transaction remains open (on the same
++** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
++** is returned. If another error code - for example SQLITE_PROTOCOL or an
++** SQLITE_IOERR error code - is returned, then the final state of the
++** read transaction is undefined. If SQLITE_OK is returned, then the 
++** read transaction is now open on database snapshot P.
++**
+ ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+ ** database connection D does not know that the database file for
+ ** schema S is in [WAL mode].  A database connection might not know
+@@ -9709,7 +10155,7 @@
+ ** database connection in order to make it ready to use snapshots.)
+ **
+ ** The [sqlite3_snapshot_open()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+   sqlite3 *db,
+@@ -9719,7 +10165,7 @@
+ 
+ /*
+ ** CAPI3REF: Destroy a snapshot
+-** EXPERIMENTAL
++** DESTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+ ** The application must eventually free every [sqlite3_snapshot] object
+@@ -9726,13 +10172,13 @@
+ ** using this routine to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_free()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+ 
+ /*
+ ** CAPI3REF: Compare the ages of two snapshot handles.
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+ ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+ ** of two valid snapshot handles. 
+@@ -9751,6 +10197,9 @@
+ ** Otherwise, this API returns a negative value if P1 refers to an older
+ ** snapshot than P2, zero if the two handles refer to the same database
+ ** snapshot, and a positive value if P1 is a newer snapshot than P2.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+   sqlite3_snapshot *p1,
+@@ -9759,23 +10208,26 @@
+ 
+ /*
+ ** CAPI3REF: Recover snapshots from a wal file
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** If all connections disconnect from a database file but do not perform
+-** a checkpoint, the existing wal file is opened along with the database
+-** file the next time the database is opened. At this point it is only
+-** possible to successfully call sqlite3_snapshot_open() to open the most
+-** recent snapshot of the database (the one at the head of the wal file),
+-** even though the wal file may contain other valid snapshots for which
+-** clients have sqlite3_snapshot handles.
++** If a [WAL file] remains on disk after all database connections close
++** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
++** or because the last process to have the database opened exited without
++** calling [sqlite3_close()]) and a new connection is subsequently opened
++** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
++** will only be able to open the last transaction added to the WAL file
++** even though the WAL file contains other valid transactions.
+ **
+-** This function attempts to scan the wal file associated with database zDb
++** This function attempts to scan the WAL file associated with database zDb
+ ** of database handle db and make all valid snapshots available to
+ ** sqlite3_snapshot_open(). It is an error if there is already a read
+-** transaction open on the database, or if the database is not a wal mode
++** transaction open on the database, or if the database is not a WAL mode
+ ** database.
+ **
+ ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+@@ -9805,7 +10257,7 @@
+ ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+ ** values of D and S.
+ ** The size of the database is written into *P even if the 
+-** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
++** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+ ** of the database exists.
+ **
+ ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+@@ -9886,7 +10338,7 @@
+ ** in the P argument is held in memory obtained from [sqlite3_malloc64()]
+ ** and that SQLite should take ownership of this memory and automatically
+ ** free it when it has finished using it.  Without this flag, the caller
+-** is resposible for freeing any dynamically allocated memory.
++** is responsible for freeing any dynamically allocated memory.
+ **
+ ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
+ ** grow the size of the database using calls to [sqlite3_realloc64()].  This
+@@ -10012,7 +10464,7 @@
+   sqlite3_int64 iRowid;             /* Rowid for current entry */
+   sqlite3_rtree_dbl rParentScore;   /* Score of parent node */
+   int eParentWithin;                /* Visibility of parent node */
+-  int eWithin;                      /* OUT: Visiblity */
++  int eWithin;                      /* OUT: Visibility */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
+   /* The following fields are only available in 3.8.11 and later */
+   sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+@@ -10508,6 +10960,13 @@
+ ** consecutively. There is no chance that the iterator will visit a change 
+ ** the applies to table X, then one for table Y, and then later on visit 
+ ** another change for table X.
++**
++** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
++**
++** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_start(
+   sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+@@ -10514,8 +10973,27 @@
+   int nChangeset,                 /* Size of changeset blob in bytes */
+   void *pChangeset                /* Pointer to blob containing changeset */
+ );
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset,               /* Pointer to blob containing changeset */
++  int flags                       /* SESSION_CHANGESETSTART_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_start_v2
++**
++** The following flags may passed via the 4th parameter to
++** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset while iterating through it. This is equivalent to
++**   inverting a changeset using sqlite3changeset_invert() before applying it.
++**   It is an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETSTART_INVERT        0x0002
+ 
++
+ /*
+ ** CAPI3REF: Advance A Changeset Iterator
+ ** METHOD: sqlite3_changeset_iter
+@@ -11168,7 +11646,7 @@
+   ),
+   void *pCtx,                     /* First argument passed to xConflict */
+   void **ppRebase, int *pnRebase, /* OUT: Rebase data */
+-  int flags                       /* Combination of SESSION_APPLY_* flags */
++  int flags                       /* SESSION_CHANGESETAPPLY_* flags */
+ );
+ 
+ /*
+@@ -11186,8 +11664,14 @@
+ **   causes the sessions module to omit this savepoint. In this case, if the
+ **   caller has an open transaction or savepoint when apply_v2() is called, 
+ **   it may revert the partially applied changeset by rolling it back.
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset before applying it. This is equivalent to inverting
++**   a changeset using sqlite3changeset_invert() before applying it. It is
++**   an error to specify this flag with a patchset.
+ */
+ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
++#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
+ 
+ /* 
+ ** CAPI3REF: Constants Passed To The Conflict Handler
+@@ -11581,6 +12065,12 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ );
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++);
+ SQLITE_API int sqlite3session_changeset_strm(
+   sqlite3_session *pSession,
+   int (*xOutput)(void *pOut, const void *pData, int nData),
+@@ -11607,8 +12097,47 @@
+   void *pOut
+ );
+ 
++/*
++** CAPI3REF: Configure global parameters
++**
++** The sqlite3session_config() interface is used to make global configuration
++** changes to the sessions module in order to tune it to the specific needs 
++** of the application.
++**
++** The sqlite3session_config() interface is not threadsafe. If it is invoked
++** while any other thread is inside any other sessions method then the
++** results are undefined. Furthermore, if it is invoked after any sessions
++** related objects have been created, the results are also undefined. 
++**
++** The first argument to the sqlite3session_config() function must be one
++** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The 
++** interpretation of the (void*) value passed as the second parameter and
++** the effect of calling this function depends on the value of the first
++** parameter.
++**
++** <dl>
++** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
++**    By default, the sessions module streaming interfaces attempt to input
++**    and output data in approximately 1 KiB chunks. This operand may be used
++**    to set and query the value of this configuration setting. The pointer
++**    passed as the second argument must point to a value of type (int).
++**    If this value is greater than 0, it is used as the new streaming data
++**    chunk size for both input and output. Before returning, the (int) value
++**    pointed to by pArg is set to the final value of the streaming interface
++**    chunk size.
++** </dl>
++**
++** This function returns SQLITE_OK if successful, or an SQLite error code
++** otherwise.
++*/
++SQLITE_API int sqlite3session_config(int op, void *pArg);
+ 
+ /*
++** CAPI3REF: Values for sqlite3session_config().
++*/
++#define SQLITE_SESSION_CONFIG_STRMSIZE 1
++
++/*
+ ** Make sure we can call this stuff from C++.
+ */
+ #if 0
+@@ -12064,7 +12593,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -12092,7 +12621,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+@@ -12941,107 +13470,119 @@
+ #define TK_ESCAPE                          58
+ #define TK_ID                              59
+ #define TK_COLUMNKW                        60
+-#define TK_FOR                             61
+-#define TK_IGNORE                          62
+-#define TK_INITIALLY                       63
+-#define TK_INSTEAD                         64
+-#define TK_NO                              65
+-#define TK_KEY                             66
+-#define TK_OF                              67
+-#define TK_OFFSET                          68
+-#define TK_PRAGMA                          69
+-#define TK_RAISE                           70
+-#define TK_RECURSIVE                       71
+-#define TK_REPLACE                         72
+-#define TK_RESTRICT                        73
+-#define TK_ROW                             74
+-#define TK_TRIGGER                         75
+-#define TK_VACUUM                          76
+-#define TK_VIEW                            77
+-#define TK_VIRTUAL                         78
+-#define TK_WITH                            79
+-#define TK_REINDEX                         80
+-#define TK_RENAME                          81
+-#define TK_CTIME_KW                        82
+-#define TK_ANY                             83
+-#define TK_BITAND                          84
+-#define TK_BITOR                           85
+-#define TK_LSHIFT                          86
+-#define TK_RSHIFT                          87
+-#define TK_PLUS                            88
+-#define TK_MINUS                           89
+-#define TK_STAR                            90
+-#define TK_SLASH                           91
+-#define TK_REM                             92
+-#define TK_CONCAT                          93
+-#define TK_COLLATE                         94
+-#define TK_BITNOT                          95
+-#define TK_INDEXED                         96
+-#define TK_STRING                          97
+-#define TK_JOIN_KW                         98
+-#define TK_CONSTRAINT                      99
+-#define TK_DEFAULT                        100
+-#define TK_NULL                           101
+-#define TK_PRIMARY                        102
+-#define TK_UNIQUE                         103
+-#define TK_CHECK                          104
+-#define TK_REFERENCES                     105
+-#define TK_AUTOINCR                       106
+-#define TK_ON                             107
+-#define TK_INSERT                         108
+-#define TK_DELETE                         109
+-#define TK_UPDATE                         110
+-#define TK_SET                            111
+-#define TK_DEFERRABLE                     112
+-#define TK_FOREIGN                        113
+-#define TK_DROP                           114
+-#define TK_UNION                          115
+-#define TK_ALL                            116
+-#define TK_EXCEPT                         117
+-#define TK_INTERSECT                      118
+-#define TK_SELECT                         119
+-#define TK_VALUES                         120
+-#define TK_DISTINCT                       121
+-#define TK_DOT                            122
+-#define TK_FROM                           123
+-#define TK_JOIN                           124
+-#define TK_USING                          125
+-#define TK_ORDER                          126
+-#define TK_GROUP                          127
+-#define TK_HAVING                         128
+-#define TK_LIMIT                          129
+-#define TK_WHERE                          130
+-#define TK_INTO                           131
+-#define TK_FLOAT                          132
+-#define TK_BLOB                           133
+-#define TK_INTEGER                        134
+-#define TK_VARIABLE                       135
+-#define TK_CASE                           136
+-#define TK_WHEN                           137
+-#define TK_THEN                           138
+-#define TK_ELSE                           139
+-#define TK_INDEX                          140
+-#define TK_ALTER                          141
+-#define TK_ADD                            142
+-#define TK_TRUEFALSE                      143
+-#define TK_ISNOT                          144
+-#define TK_FUNCTION                       145
+-#define TK_COLUMN                         146
+-#define TK_AGG_FUNCTION                   147
+-#define TK_AGG_COLUMN                     148
+-#define TK_UMINUS                         149
+-#define TK_UPLUS                          150
+-#define TK_TRUTH                          151
+-#define TK_REGISTER                       152
+-#define TK_VECTOR                         153
+-#define TK_SELECT_COLUMN                  154
+-#define TK_IF_NULL_ROW                    155
+-#define TK_ASTERISK                       156
+-#define TK_SPAN                           157
+-#define TK_END_OF_FILE                    158
+-#define TK_UNCLOSED_STRING                159
+-#define TK_SPACE                          160
+-#define TK_ILLEGAL                        161
++#define TK_DO                              61
++#define TK_FOR                             62
++#define TK_IGNORE                          63
++#define TK_INITIALLY                       64
++#define TK_INSTEAD                         65
++#define TK_NO                              66
++#define TK_KEY                             67
++#define TK_OF                              68
++#define TK_OFFSET                          69
++#define TK_PRAGMA                          70
++#define TK_RAISE                           71
++#define TK_RECURSIVE                       72
++#define TK_REPLACE                         73
++#define TK_RESTRICT                        74
++#define TK_ROW                             75
++#define TK_ROWS                            76
++#define TK_TRIGGER                         77
++#define TK_VACUUM                          78
++#define TK_VIEW                            79
++#define TK_VIRTUAL                         80
++#define TK_WITH                            81
++#define TK_CURRENT                         82
++#define TK_FOLLOWING                       83
++#define TK_PARTITION                       84
++#define TK_PRECEDING                       85
++#define TK_RANGE                           86
++#define TK_UNBOUNDED                       87
++#define TK_REINDEX                         88
++#define TK_RENAME                          89
++#define TK_CTIME_KW                        90
++#define TK_ANY                             91
++#define TK_BITAND                          92
++#define TK_BITOR                           93
++#define TK_LSHIFT                          94
++#define TK_RSHIFT                          95
++#define TK_PLUS                            96
++#define TK_MINUS                           97
++#define TK_STAR                            98
++#define TK_SLASH                           99
++#define TK_REM                            100
++#define TK_CONCAT                         101
++#define TK_COLLATE                        102
++#define TK_BITNOT                         103
++#define TK_ON                             104
++#define TK_INDEXED                        105
++#define TK_STRING                         106
++#define TK_JOIN_KW                        107
++#define TK_CONSTRAINT                     108
++#define TK_DEFAULT                        109
++#define TK_NULL                           110
++#define TK_PRIMARY                        111
++#define TK_UNIQUE                         112
++#define TK_CHECK                          113
++#define TK_REFERENCES                     114
++#define TK_AUTOINCR                       115
++#define TK_INSERT                         116
++#define TK_DELETE                         117
++#define TK_UPDATE                         118
++#define TK_SET                            119
++#define TK_DEFERRABLE                     120
++#define TK_FOREIGN                        121
++#define TK_DROP                           122
++#define TK_UNION                          123
++#define TK_ALL                            124
++#define TK_EXCEPT                         125
++#define TK_INTERSECT                      126
++#define TK_SELECT                         127
++#define TK_VALUES                         128
++#define TK_DISTINCT                       129
++#define TK_DOT                            130
++#define TK_FROM                           131
++#define TK_JOIN                           132
++#define TK_USING                          133
++#define TK_ORDER                          134
++#define TK_GROUP                          135
++#define TK_HAVING                         136
++#define TK_LIMIT                          137
++#define TK_WHERE                          138
++#define TK_INTO                           139
++#define TK_NOTHING                        140
++#define TK_FLOAT                          141
++#define TK_BLOB                           142
++#define TK_INTEGER                        143
++#define TK_VARIABLE                       144
++#define TK_CASE                           145
++#define TK_WHEN                           146
++#define TK_THEN                           147
++#define TK_ELSE                           148
++#define TK_INDEX                          149
++#define TK_ALTER                          150
++#define TK_ADD                            151
++#define TK_WINDOW                         152
++#define TK_OVER                           153
++#define TK_FILTER                         154
++#define TK_TRUEFALSE                      155
++#define TK_ISNOT                          156
++#define TK_FUNCTION                       157
++#define TK_COLUMN                         158
++#define TK_AGG_FUNCTION                   159
++#define TK_AGG_COLUMN                     160
++#define TK_UMINUS                         161
++#define TK_UPLUS                          162
++#define TK_TRUTH                          163
++#define TK_REGISTER                       164
++#define TK_VECTOR                         165
++#define TK_SELECT_COLUMN                  166
++#define TK_IF_NULL_ROW                    167
++#define TK_ASTERISK                       168
++#define TK_SPAN                           169
++#define TK_END_OF_FILE                    170
++#define TK_UNCLOSED_STRING                171
++#define TK_SPACE                          172
++#define TK_ILLEGAL                        173
+ 
+ /* The token codes above must all fit in 8 bits */
+ #define TKFLG_MASK           0xff  
+@@ -13162,6 +13703,13 @@
+ #endif
+ 
+ /*
++** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option.
++*/
++#ifndef SQLITE_DEFAULT_SORTERREF_SIZE
++# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff
++#endif
++
++/*
+ ** The compile-time options SQLITE_MMAP_READWRITE and 
+ ** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
+ ** You must choose one or the other (or neither) but not both.
+@@ -13308,7 +13856,8 @@
+ # if defined(__SIZEOF_POINTER__)
+ #   define SQLITE_PTRSIZE __SIZEOF_POINTER__
+ # elif defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+-       defined(_M_ARM)   || defined(__arm__)    || defined(__x86)
++       defined(_M_ARM)   || defined(__arm__)    || defined(__x86)   ||    \
++      (defined(__TOS_AIX__) && !defined(__64BIT__))
+ #   define SQLITE_PTRSIZE 4
+ # else
+ #   define SQLITE_PTRSIZE 8
+@@ -13349,7 +13898,7 @@
+ # if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+      defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
+      defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
+-     defined(__arm__)
++     defined(__arm__)  || defined(_M_ARM64)
+ #   define SQLITE_BYTEORDER    1234
+ # elif defined(sparc)    || defined(__ppc__)
+ #   define SQLITE_BYTEORDER    4321
+@@ -13604,6 +14153,7 @@
+ typedef struct Parse Parse;
+ typedef struct PreUpdate PreUpdate;
+ typedef struct PrintfArguments PrintfArguments;
++typedef struct RenameToken RenameToken;
+ typedef struct RowSet RowSet;
+ typedef struct Savepoint Savepoint;
+ typedef struct Select Select;
+@@ -13610,7 +14160,7 @@
+ typedef struct SQLiteThread SQLiteThread;
+ typedef struct SelectDest SelectDest;
+ typedef struct SrcList SrcList;
+-typedef struct StrAccum StrAccum;
++typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
+ typedef struct Table Table;
+ typedef struct TableLock TableLock;
+ typedef struct Token Token;
+@@ -13619,12 +14169,40 @@
+ typedef struct TriggerPrg TriggerPrg;
+ typedef struct TriggerStep TriggerStep;
+ typedef struct UnpackedRecord UnpackedRecord;
++typedef struct Upsert Upsert;
+ typedef struct VTable VTable;
+ typedef struct VtabCtx VtabCtx;
+ typedef struct Walker Walker;
+ typedef struct WhereInfo WhereInfo;
++typedef struct Window Window;
+ typedef struct With With;
+ 
++
++/*
++** The bitmask datatype defined below is used for various optimizations.
++**
++** Changing this from a 64-bit to a 32-bit type limits the number of
++** tables in a join to 32 instead of 64.  But it also reduces the size
++** of the library by 738 bytes on ix86.
++*/
++#ifdef SQLITE_BITMASK_TYPE
++  typedef SQLITE_BITMASK_TYPE Bitmask;
++#else
++  typedef u64 Bitmask;
++#endif
++
++/*
++** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
++*/
++#define BMS  ((int)(sizeof(Bitmask)*8))
++
++/*
++** A bit in a Bitmask
++*/
++#define MASKBIT(n)   (((Bitmask)1)<<(n))
++#define MASKBIT32(n) (((unsigned int)1)<<(n))
++#define ALLBITS      ((Bitmask)-1)
++
+ /* A VList object records a mapping between parameters/variables/wildcards
+ ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
+ ** variable number associated with that parameter.  See the format description
+@@ -13720,7 +14298,7 @@
+ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
+ SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
+ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
+-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
++SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*);
+ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
+ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
+ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
+@@ -13901,14 +14479,29 @@
+ ** entry in either an index or table btree.
+ **
+ ** Index btrees (used for indexes and also WITHOUT ROWID tables) contain
+-** an arbitrary key and no data.  These btrees have pKey,nKey set to their
+-** key and pData,nData,nZero set to zero.
++** an arbitrary key and no data.  These btrees have pKey,nKey set to the
++** key and the pData,nData,nZero fields are uninitialized.  The aMem,nMem
++** fields give an array of Mem objects that are a decomposition of the key.
++** The nMem field might be zero, indicating that no decomposition is available.
+ **
+ ** Table btrees (used for rowid tables) contain an integer rowid used as
+ ** the key and passed in the nKey field.  The pKey field is zero.  
+ ** pData,nData hold the content of the new entry.  nZero extra zero bytes
+ ** are appended to the end of the content when constructing the entry.
++** The aMem,nMem fields are uninitialized for table btrees.
+ **
++** Field usage summary:
++**
++**               Table BTrees                   Index Btrees
++**
++**   pKey        always NULL                    encoded key
++**   nKey        the ROWID                      length of pKey
++**   pData       data                           not used
++**   aMem        not used                       decomposed key value
++**   nMem        not used                       entries in aMem
++**   nData       length of pData                not used
++**   nZero       extra zeros after pData        not used
++**
+ ** This object is used to pass information into sqlite3BtreeInsert().  The
+ ** same information used to be passed as five separate parameters.  But placing
+ ** the information into this object helps to keep the interface more 
+@@ -13918,7 +14511,7 @@
+ struct BtreePayload {
+   const void *pKey;       /* Key content for indexes.  NULL for tables */
+   sqlite3_int64 nKey;     /* Size of pKey for indexes.  PRIMARY KEY for tabs */
+-  const void *pData;      /* Data for tables.  NULL for indexes */
++  const void *pData;      /* Data for tables. */
+   sqlite3_value *aMem;    /* First of nMem value in the unpacked pKey */
+   u16 nMem;               /* Number of aMem[] value.  Might be zero */
+   int nData;              /* Size of pData.  0 if none. */
+@@ -13928,6 +14521,9 @@
+ SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
+                        int flags, int seekResult);
+ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*);
++#endif
+ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
+ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
+ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
+@@ -14095,7 +14691,8 @@
+   u64 cycles;              /* Total time spent executing this instruction */
+ #endif
+ #ifdef SQLITE_VDBE_COVERAGE
+-  int iSrcLine;            /* Source-code line that generated this opcode */
++  u32 iSrcLine;            /* Source-code line that generated this opcode
++                           ** with flags in the upper 8 bits */
+ #endif
+ };
+ typedef struct VdbeOp VdbeOp;
+@@ -14196,52 +14793,52 @@
+ #define OP_AutoCommit      1
+ #define OP_Transaction     2
+ #define OP_SorterNext      3 /* jump                                       */
+-#define OP_PrevIfOpen      4 /* jump                                       */
+-#define OP_NextIfOpen      5 /* jump                                       */
+-#define OP_Prev            6 /* jump                                       */
+-#define OP_Next            7 /* jump                                       */
+-#define OP_Checkpoint      8
+-#define OP_JournalMode     9
+-#define OP_Vacuum         10
+-#define OP_VFilter        11 /* jump, synopsis: iplan=r[P3] zplan='P4'     */
+-#define OP_VUpdate        12 /* synopsis: data=r[P3@P2]                    */
+-#define OP_Goto           13 /* jump                                       */
+-#define OP_Gosub          14 /* jump                                       */
+-#define OP_InitCoroutine  15 /* jump                                       */
+-#define OP_Yield          16 /* jump                                       */
+-#define OP_MustBeInt      17 /* jump                                       */
+-#define OP_Jump           18 /* jump                                       */
++#define OP_Prev            4 /* jump                                       */
++#define OP_Next            5 /* jump                                       */
++#define OP_Checkpoint      6
++#define OP_JournalMode     7
++#define OP_Vacuum          8
++#define OP_VFilter         9 /* jump, synopsis: iplan=r[P3] zplan='P4'     */
++#define OP_VUpdate        10 /* synopsis: data=r[P3@P2]                    */
++#define OP_Goto           11 /* jump                                       */
++#define OP_Gosub          12 /* jump                                       */
++#define OP_InitCoroutine  13 /* jump                                       */
++#define OP_Yield          14 /* jump                                       */
++#define OP_MustBeInt      15 /* jump                                       */
++#define OP_Jump           16 /* jump                                       */
++#define OP_Once           17 /* jump                                       */
++#define OP_If             18 /* jump                                       */
+ #define OP_Not            19 /* same as TK_NOT, synopsis: r[P2]= !r[P1]    */
+-#define OP_Once           20 /* jump                                       */
+-#define OP_If             21 /* jump                                       */
+-#define OP_IfNot          22 /* jump                                       */
+-#define OP_IfNullRow      23 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
+-#define OP_SeekLT         24 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_SeekLE         25 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_SeekGE         26 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_SeekGT         27 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_NoConflict     28 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_NotFound       29 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_Found          30 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_SeekRowid      31 /* jump, synopsis: intkey=r[P3]               */
+-#define OP_NotExists      32 /* jump, synopsis: intkey=r[P3]               */
+-#define OP_Last           33 /* jump                                       */
+-#define OP_IfSmaller      34 /* jump                                       */
+-#define OP_SorterSort     35 /* jump                                       */
+-#define OP_Sort           36 /* jump                                       */
+-#define OP_Rewind         37 /* jump                                       */
+-#define OP_IdxLE          38 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_IdxGT          39 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_IdxLT          40 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_IdxGE          41 /* jump, synopsis: key=r[P3@P4]               */
+-#define OP_RowSetRead     42 /* jump, synopsis: r[P3]=rowset(P1)           */
++#define OP_IfNot          20 /* jump                                       */
++#define OP_IfNullRow      21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
++#define OP_SeekLT         22 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekLE         23 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekGE         24 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekGT         25 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IfNoHope       26 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_NoConflict     27 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_NotFound       28 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_Found          29 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_SeekRowid      30 /* jump, synopsis: intkey=r[P3]               */
++#define OP_NotExists      31 /* jump, synopsis: intkey=r[P3]               */
++#define OP_Last           32 /* jump                                       */
++#define OP_IfSmaller      33 /* jump                                       */
++#define OP_SorterSort     34 /* jump                                       */
++#define OP_Sort           35 /* jump                                       */
++#define OP_Rewind         36 /* jump                                       */
++#define OP_IdxLE          37 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxGT          38 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxLT          39 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_IdxGE          40 /* jump, synopsis: key=r[P3@P4]               */
++#define OP_RowSetRead     41 /* jump, synopsis: r[P3]=rowset(P1)           */
++#define OP_RowSetTest     42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
+ #define OP_Or             43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+ #define OP_And            44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+-#define OP_RowSetTest     45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
+-#define OP_Program        46 /* jump                                       */
+-#define OP_FkIfZero       47 /* jump, synopsis: if fkctr[P1]==0 goto P2    */
+-#define OP_IfPos          48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+-#define OP_IfNotZero      49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
++#define OP_Program        45 /* jump                                       */
++#define OP_FkIfZero       46 /* jump, synopsis: if fkctr[P1]==0 goto P2    */
++#define OP_IfPos          47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
++#define OP_IfNotZero      48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
++#define OP_DecrJumpZero   49 /* jump, synopsis: if (--r[P1])==0 goto P2    */
+ #define OP_IsNull         50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+ #define OP_NotNull        51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+ #define OP_Ne             52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+@@ -14251,118 +14848,121 @@
+ #define OP_Lt             56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
+ #define OP_Ge             57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
+ #define OP_ElseNotEq      58 /* jump, same as TK_ESCAPE                    */
+-#define OP_DecrJumpZero   59 /* jump, synopsis: if (--r[P1])==0 goto P2    */
+-#define OP_IncrVacuum     60 /* jump                                       */
+-#define OP_VNext          61 /* jump                                       */
+-#define OP_Init           62 /* jump, synopsis: Start at P2                */
+-#define OP_Return         63
+-#define OP_EndCoroutine   64
+-#define OP_HaltIfNull     65 /* synopsis: if r[P3]=null halt               */
+-#define OP_Halt           66
+-#define OP_Integer        67 /* synopsis: r[P2]=P1                         */
+-#define OP_Int64          68 /* synopsis: r[P2]=P4                         */
+-#define OP_String         69 /* synopsis: r[P2]='P4' (len=P1)              */
+-#define OP_Null           70 /* synopsis: r[P2..P3]=NULL                   */
+-#define OP_SoftNull       71 /* synopsis: r[P1]=NULL                       */
+-#define OP_Blob           72 /* synopsis: r[P2]=P4 (len=P1)                */
+-#define OP_Variable       73 /* synopsis: r[P2]=parameter(P1,P4)           */
+-#define OP_Move           74 /* synopsis: r[P2@P3]=r[P1@P3]                */
+-#define OP_Copy           75 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+-#define OP_SCopy          76 /* synopsis: r[P2]=r[P1]                      */
+-#define OP_IntCopy        77 /* synopsis: r[P2]=r[P1]                      */
+-#define OP_ResultRow      78 /* synopsis: output=r[P1@P2]                  */
+-#define OP_CollSeq        79
+-#define OP_AddImm         80 /* synopsis: r[P1]=r[P1]+P2                   */
+-#define OP_RealAffinity   81
+-#define OP_Cast           82 /* synopsis: affinity(r[P1])                  */
+-#define OP_Permutation    83
+-#define OP_BitAnd         84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+-#define OP_BitOr          85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+-#define OP_ShiftLeft      86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+-#define OP_ShiftRight     87 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+-#define OP_Add            88 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+-#define OP_Subtract       89 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+-#define OP_Multiply       90 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+-#define OP_Divide         91 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+-#define OP_Remainder      92 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+-#define OP_Concat         93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+-#define OP_Compare        94 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
+-#define OP_BitNot         95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+-#define OP_IsTrue         96 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
+-#define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
+-#define OP_Offset         98 /* synopsis: r[P3] = sqlite_offset(P1)        */
+-#define OP_Column         99 /* synopsis: r[P3]=PX                         */
+-#define OP_Affinity      100 /* synopsis: affinity(r[P1@P2])               */
+-#define OP_MakeRecord    101 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+-#define OP_Count         102 /* synopsis: r[P2]=count()                    */
+-#define OP_ReadCookie    103
+-#define OP_SetCookie     104
+-#define OP_ReopenIdx     105 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenRead      106 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenWrite     107 /* synopsis: root=P2 iDb=P3                   */
+-#define OP_OpenDup       108
+-#define OP_OpenAutoindex 109 /* synopsis: nColumn=P2                       */
+-#define OP_OpenEphemeral 110 /* synopsis: nColumn=P2                       */
+-#define OP_SorterOpen    111
+-#define OP_SequenceTest  112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+-#define OP_OpenPseudo    113 /* synopsis: P3 columns in r[P2]              */
+-#define OP_Close         114
+-#define OP_ColumnsUsed   115
+-#define OP_Sequence      116 /* synopsis: r[P2]=cursor[P1].ctr++           */
+-#define OP_NewRowid      117 /* synopsis: r[P2]=rowid                      */
+-#define OP_Insert        118 /* synopsis: intkey=r[P3] data=r[P2]          */
+-#define OP_InsertInt     119 /* synopsis: intkey=P3 data=r[P2]             */
+-#define OP_Delete        120
+-#define OP_ResetCount    121
+-#define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+-#define OP_SorterData    123 /* synopsis: r[P2]=data                       */
+-#define OP_RowData       124 /* synopsis: r[P2]=data                       */
+-#define OP_Rowid         125 /* synopsis: r[P2]=rowid                      */
+-#define OP_NullRow       126
+-#define OP_SeekEnd       127
+-#define OP_SorterInsert  128 /* synopsis: key=r[P2]                        */
+-#define OP_IdxInsert     129 /* synopsis: key=r[P2]                        */
+-#define OP_IdxDelete     130 /* synopsis: key=r[P2@P3]                     */
+-#define OP_DeferredSeek  131 /* synopsis: Move P3 to P1.rowid if needed    */
+-#define OP_Real          132 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
+-#define OP_IdxRowid      133 /* synopsis: r[P2]=rowid                      */
+-#define OP_Destroy       134
+-#define OP_Clear         135
+-#define OP_ResetSorter   136
+-#define OP_CreateBtree   137 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
+-#define OP_SqlExec       138
+-#define OP_ParseSchema   139
+-#define OP_LoadAnalysis  140
+-#define OP_DropTable     141
+-#define OP_DropIndex     142
+-#define OP_DropTrigger   143
+-#define OP_IntegrityCk   144
+-#define OP_RowSetAdd     145 /* synopsis: rowset(P1)=r[P2]                 */
+-#define OP_Param         146
+-#define OP_FkCounter     147 /* synopsis: fkctr[P1]+=P2                    */
+-#define OP_MemMax        148 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+-#define OP_OffsetLimit   149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+-#define OP_AggStep0      150 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+-#define OP_AggStep       151 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+-#define OP_AggFinal      152 /* synopsis: accum=r[P1] N=P2                 */
+-#define OP_Expire        153
+-#define OP_TableLock     154 /* synopsis: iDb=P1 root=P2 write=P3          */
+-#define OP_VBegin        155
+-#define OP_VCreate       156
+-#define OP_VDestroy      157
+-#define OP_VOpen         158
+-#define OP_VColumn       159 /* synopsis: r[P3]=vcolumn(P2)                */
+-#define OP_VRename       160
+-#define OP_Pagecount     161
+-#define OP_MaxPgcnt      162
+-#define OP_PureFunc0     163
+-#define OP_Function0     164 /* synopsis: r[P3]=func(r[P2@P5])             */
+-#define OP_PureFunc      165
+-#define OP_Function      166 /* synopsis: r[P3]=func(r[P2@P5])             */
+-#define OP_Trace         167
+-#define OP_CursorHint    168
+-#define OP_Noop          169
+-#define OP_Explain       170
++#define OP_IncrVacuum     59 /* jump                                       */
++#define OP_VNext          60 /* jump                                       */
++#define OP_Init           61 /* jump, synopsis: Start at P2                */
++#define OP_PureFunc0      62
++#define OP_Function0      63 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_PureFunc       64
++#define OP_Function       65 /* synopsis: r[P3]=func(r[P2@P5])             */
++#define OP_Return         66
++#define OP_EndCoroutine   67
++#define OP_HaltIfNull     68 /* synopsis: if r[P3]=null halt               */
++#define OP_Halt           69
++#define OP_Integer        70 /* synopsis: r[P2]=P1                         */
++#define OP_Int64          71 /* synopsis: r[P2]=P4                         */
++#define OP_String         72 /* synopsis: r[P2]='P4' (len=P1)              */
++#define OP_Null           73 /* synopsis: r[P2..P3]=NULL                   */
++#define OP_SoftNull       74 /* synopsis: r[P1]=NULL                       */
++#define OP_Blob           75 /* synopsis: r[P2]=P4 (len=P1)                */
++#define OP_Variable       76 /* synopsis: r[P2]=parameter(P1,P4)           */
++#define OP_Move           77 /* synopsis: r[P2@P3]=r[P1@P3]                */
++#define OP_Copy           78 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
++#define OP_SCopy          79 /* synopsis: r[P2]=r[P1]                      */
++#define OP_IntCopy        80 /* synopsis: r[P2]=r[P1]                      */
++#define OP_ResultRow      81 /* synopsis: output=r[P1@P2]                  */
++#define OP_CollSeq        82
++#define OP_AddImm         83 /* synopsis: r[P1]=r[P1]+P2                   */
++#define OP_RealAffinity   84
++#define OP_Cast           85 /* synopsis: affinity(r[P1])                  */
++#define OP_Permutation    86
++#define OP_Compare        87 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
++#define OP_IsTrue         88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
++#define OP_Offset         89 /* synopsis: r[P3] = sqlite_offset(P1)        */
++#define OP_Column         90 /* synopsis: r[P3]=PX                         */
++#define OP_Affinity       91 /* synopsis: affinity(r[P1@P2])               */
++#define OP_BitAnd         92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
++#define OP_BitOr          93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
++#define OP_ShiftLeft      94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
++#define OP_ShiftRight     95 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
++#define OP_Add            96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
++#define OP_Subtract       97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
++#define OP_Multiply       98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
++#define OP_Divide         99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
++#define OP_Remainder     100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
++#define OP_Concat        101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
++#define OP_MakeRecord    102 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
++#define OP_BitNot        103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
++#define OP_Count         104 /* synopsis: r[P2]=count()                    */
++#define OP_ReadCookie    105
++#define OP_String8       106 /* same as TK_STRING, synopsis: r[P2]='P4'    */
++#define OP_SetCookie     107
++#define OP_ReopenIdx     108 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenRead      109 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenWrite     110 /* synopsis: root=P2 iDb=P3                   */
++#define OP_OpenDup       111
++#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2                       */
++#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2                       */
++#define OP_SorterOpen    114
++#define OP_SequenceTest  115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
++#define OP_OpenPseudo    116 /* synopsis: P3 columns in r[P2]              */
++#define OP_Close         117
++#define OP_ColumnsUsed   118
++#define OP_SeekHit       119 /* synopsis: seekHit=P2                       */
++#define OP_Sequence      120 /* synopsis: r[P2]=cursor[P1].ctr++           */
++#define OP_NewRowid      121 /* synopsis: r[P2]=rowid                      */
++#define OP_Insert        122 /* synopsis: intkey=r[P3] data=r[P2]          */
++#define OP_InsertInt     123 /* synopsis: intkey=P3 data=r[P2]             */
++#define OP_Delete        124
++#define OP_ResetCount    125
++#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
++#define OP_SorterData    127 /* synopsis: r[P2]=data                       */
++#define OP_RowData       128 /* synopsis: r[P2]=data                       */
++#define OP_Rowid         129 /* synopsis: r[P2]=rowid                      */
++#define OP_NullRow       130
++#define OP_SeekEnd       131
++#define OP_SorterInsert  132 /* synopsis: key=r[P2]                        */
++#define OP_IdxInsert     133 /* synopsis: key=r[P2]                        */
++#define OP_IdxDelete     134 /* synopsis: key=r[P2@P3]                     */
++#define OP_DeferredSeek  135 /* synopsis: Move P3 to P1.rowid if needed    */
++#define OP_IdxRowid      136 /* synopsis: r[P2]=rowid                      */
++#define OP_Destroy       137
++#define OP_Clear         138
++#define OP_ResetSorter   139
++#define OP_CreateBtree   140 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
++#define OP_Real          141 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
++#define OP_SqlExec       142
++#define OP_ParseSchema   143
++#define OP_LoadAnalysis  144
++#define OP_DropTable     145
++#define OP_DropIndex     146
++#define OP_DropTrigger   147
++#define OP_IntegrityCk   148
++#define OP_RowSetAdd     149 /* synopsis: rowset(P1)=r[P2]                 */
++#define OP_Param         150
++#define OP_FkCounter     151 /* synopsis: fkctr[P1]+=P2                    */
++#define OP_MemMax        152 /* synopsis: r[P1]=max(r[P1],r[P2])           */
++#define OP_OffsetLimit   153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
++#define OP_AggInverse    154 /* synopsis: accum=r[P3] inverse(r[P2@P5])    */
++#define OP_AggStep       155 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggStep1      156 /* synopsis: accum=r[P3] step(r[P2@P5])       */
++#define OP_AggValue      157 /* synopsis: r[P3]=value N=P2                 */
++#define OP_AggFinal      158 /* synopsis: accum=r[P1] N=P2                 */
++#define OP_Expire        159
++#define OP_TableLock     160 /* synopsis: iDb=P1 root=P2 write=P3          */
++#define OP_VBegin        161
++#define OP_VCreate       162
++#define OP_VDestroy      163
++#define OP_VOpen         164
++#define OP_VColumn       165 /* synopsis: r[P3]=vcolumn(P2)                */
++#define OP_VRename       166
++#define OP_Pagecount     167
++#define OP_MaxPgcnt      168
++#define OP_Trace         169
++#define OP_CursorHint    170
++#define OP_Noop          171
++#define OP_Explain       172
++#define OP_Abortable     173
+ 
+ /* Properties such as "out2" or "jump" that are specified in
+ ** comments following the "case" for each opcode in the vdbe.c
+@@ -14375,28 +14975,28 @@
+ #define OPFLG_OUT2        0x10  /* out2:  P2 is an output */
+ #define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
+ #define OPFLG_INITIALIZER {\
+-/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\
+-/*   8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\
+-/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
++/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
++/*   8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
++/*  16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\
+ /*  24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
+-/*  32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+-/*  40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\
++/*  32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
++/*  40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\
+ /*  48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
+-/*  56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x02,\
+-/*  64 */ 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00,\
+-/*  72 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+-/*  80 */ 0x02, 0x02, 0x02, 0x00, 0x26, 0x26, 0x26, 0x26,\
+-/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
+-/*  96 */ 0x12, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10,\
+-/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\
+-/* 128 */ 0x04, 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,\
+-/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\
+-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
+-/* 168 */ 0x00, 0x00, 0x00,}
++/*  56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\
++/*  64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
++/*  72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
++/*  80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
++/*  88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\
++/*  96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
++/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\
++/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
++/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
++/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
++/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
++/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,}
+ 
+ /* The sqlite3P2Values() routine is able to run faster if it knows
+ ** the value of the largest JUMP opcode.  The smaller the maximum
+@@ -14404,7 +15004,7 @@
+ ** generated this include file strives to group all JUMP opcodes
+ ** together near the beginning of the list.
+ */
+-#define SQLITE_MX_JUMP_OPCODE  62  /* Maximum JUMP opcode */
++#define SQLITE_MX_JUMP_OPCODE  61  /* Maximum JUMP opcode */
+ 
+ /************** End of opcodes.h *********************************************/
+ /************** Continuing where we left off in vdbe.h ***********************/
+@@ -14438,7 +15038,24 @@
+ # define sqlite3VdbeVerifyNoMallocRequired(A,B)
+ # define sqlite3VdbeVerifyNoResultRow(A)
+ #endif
+-SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
++#if defined(SQLITE_DEBUG)
++SQLITE_PRIVATE   void sqlite3VdbeVerifyAbortable(Vdbe *p, int);
++#else
++# define sqlite3VdbeVerifyAbortable(A,B)
++#endif
++SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
++#ifndef SQLITE_OMIT_EXPLAIN
++SQLITE_PRIVATE   void sqlite3VdbeExplain(Parse*,u8,const char*,...);
++SQLITE_PRIVATE   void sqlite3VdbeExplainPop(Parse*);
++SQLITE_PRIVATE   int sqlite3VdbeExplainParent(Parse*);
++# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
++# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
++# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
++#else
++# define ExplainQueryPlan(P)
++# define ExplainQueryPlanPop(P)
++# define ExplainQueryPlanParent(P) 0
++#endif
+ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
+ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
+ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
+@@ -14482,6 +15099,7 @@
+ SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
+ #endif
+ SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
++SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*);
+ 
+ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
+ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+@@ -14537,17 +15155,43 @@
+ **
+ **    VdbeCoverageNeverTaken(v)        // Previous branch is never taken
+ **
++**    VdbeCoverageNeverNull(v)         // Previous three-way branch is only
++**                                     // taken on the first two ways.  The
++**                                     // NULL option is not possible
++**
++**    VdbeCoverageEqNe(v)              // Previous OP_Jump is only interested
++**                                     // in distingishing equal and not-equal.
++**
+ ** Every VDBE branch operation must be tagged with one of the macros above.
+ ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
+ ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
+ ** routine in vdbe.c, alerting the developer to the missed tag.
++**
++** During testing, the test application will invoke
++** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback
++** routine that is invoked as each bytecode branch is taken.  The callback
++** contains the sqlite3.c source line number ov the VdbeCoverage macro and
++** flags to indicate whether or not the branch was taken.  The test application
++** is responsible for keeping track of this and reporting byte-code branches
++** that are never taken.
++**
++** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the
++** vdbe.c source file for additional information.
+ */
+ #ifdef SQLITE_VDBE_COVERAGE
+ SQLITE_PRIVATE   void sqlite3VdbeSetLineNumber(Vdbe*,int);
+ # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
+ # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
+-# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
+-# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
++# define VdbeCoverageAlwaysTaken(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000);
++# define VdbeCoverageNeverTaken(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000);
++# define VdbeCoverageNeverNull(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
++# define VdbeCoverageNeverNullIf(v,x) \
++         if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000);
++# define VdbeCoverageEqNe(v) \
++         sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000);
+ # define VDBE_OFFSET_LINENO(x) (__LINE__+x)
+ #else
+ # define VdbeCoverage(v)
+@@ -14554,6 +15198,9 @@
+ # define VdbeCoverageIf(v,x)
+ # define VdbeCoverageAlwaysTaken(v)
+ # define VdbeCoverageNeverTaken(v)
++# define VdbeCoverageNeverNull(v)
++# define VdbeCoverageNeverNullIf(v,x)
++# define VdbeCoverageEqNe(v)
+ # define VDBE_OFFSET_LINENO(x) 0
+ #endif
+ 
+@@ -14563,6 +15210,10 @@
+ # define sqlite3VdbeScanStatus(a,b,c,d,e)
+ #endif
+ 
++#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
++SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*);
++#endif
++
+ #endif /* SQLITE_VDBE_H */
+ 
+ /************** End of vdbe.h ************************************************/
+@@ -14750,18 +15401,19 @@
+ SQLITE_PRIVATE   int sqlite3PagerWalCallback(Pager *pPager);
+ SQLITE_PRIVATE   int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
+ SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
+-# ifdef SQLITE_DIRECT_OVERFLOW_READ
+-SQLITE_PRIVATE   int sqlite3PagerUseWal(Pager *pPager, Pgno);
+-# endif
+ # ifdef SQLITE_ENABLE_SNAPSHOT
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
+ SQLITE_PRIVATE   int sqlite3PagerSnapshotRecover(Pager *pPager);
++SQLITE_PRIVATE   int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE   void sqlite3PagerSnapshotUnlock(Pager *pPager);
+ # endif
+-#else
+-# define sqlite3PagerUseWal(x,y) 0
+ #endif
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++SQLITE_PRIVATE   int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
++#endif
++
+ #ifdef SQLITE_ENABLE_ZIPVFS
+ SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
+ #endif
+@@ -15004,6 +15656,10 @@
+ /* Number of dirty pages as a percentage of the configured cache size */
+ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
++#endif
++
+ #endif /* _PCACHE_H_ */
+ 
+ /************** End of pcache.h **********************************************/
+@@ -15509,12 +16165,14 @@
+ ** functions use a regular table table from hash.h.)
+ **
+ ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
+-** Collisions are on the FuncDef.u.pHash chain.
++** Collisions are on the FuncDef.u.pHash chain.  Use the SQLITE_FUNC_HASH()
++** macro to compute a hash on the function name.
+ */
+ #define SQLITE_FUNC_HASH_SZ 23
+ struct FuncDefHash {
+   FuncDef *a[SQLITE_FUNC_HASH_SZ];       /* Hash table for functions */
+ };
++#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
+ 
+ #ifdef SQLITE_USER_AUTHENTICATION
+ /*
+@@ -15575,7 +16233,7 @@
+   Db *aDb;                      /* All backends */
+   int nDb;                      /* Number of backends currently in use */
+   u32 mDbFlags;                 /* flags recording internal state */
+-  u32 flags;                    /* flags settable by pragmas. See below */
++  u64 flags;                    /* flags settable by pragmas. See below */
+   i64 lastRowid;                /* ROWID of most recent insert (see above) */
+   i64 szMmap;                   /* Default mmap_size setting */
+   u32 nSchemaLock;              /* Do not reset the schema when non-zero */
+@@ -15595,7 +16253,7 @@
+   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 noSharedCache;             /* 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 */
+@@ -15739,14 +16397,19 @@
+ #define SQLITE_Fts3Tokenizer  0x00400000  /* Enable fts3_tokenizer(2) */
+ #define SQLITE_EnableQPSG     0x00800000  /* Query Planner Stability Guarantee*/
+ #define SQLITE_TriggerEQP     0x01000000  /* Show trigger EXPLAIN QUERY PLAN */
++#define SQLITE_ResetDatabase  0x02000000  /* Reset the database */
++#define SQLITE_LegacyAlter    0x04000000  /* Legacy ALTER TABLE behaviour */
++#define SQLITE_NoSchemaError  0x08000000  /* Do not report schema parse errors*/
++#define SQLITE_Defensive      0x10000000  /* Input SQL is likely hostile */
+ 
+ /* Flags used only if debugging */
++#define HI(X)  ((u64)(X)<<32)
+ #ifdef SQLITE_DEBUG
+-#define SQLITE_SqlTrace       0x08000000  /* Debug print SQL as it executes */
+-#define SQLITE_VdbeListing    0x10000000  /* Debug listings of VDBE programs */
+-#define SQLITE_VdbeTrace      0x20000000  /* True to trace VDBE execution */
+-#define SQLITE_VdbeAddopTrace 0x40000000  /* Trace sqlite3VdbeAddOp() calls */
+-#define SQLITE_VdbeEQP        0x80000000  /* Debug EXPLAIN QUERY PLAN */
++#define SQLITE_SqlTrace       HI(0x0001)  /* Debug print SQL as it executes */
++#define SQLITE_VdbeListing    HI(0x0002)  /* Debug listings of VDBE progs */
++#define SQLITE_VdbeTrace      HI(0x0004)  /* True to trace VDBE execution */
++#define SQLITE_VdbeAddopTrace HI(0x0008)  /* Trace sqlite3VdbeAddOp() calls */
++#define SQLITE_VdbeEQP        HI(0x0010)  /* Debug EXPLAIN QUERY PLAN */
+ #endif
+ 
+ /*
+@@ -15755,6 +16418,7 @@
+ #define DBFLAG_SchemaChange   0x0001  /* Uncommitted Hash table changes */
+ #define DBFLAG_PreferBuiltin  0x0002  /* Preference to built-in funcs */
+ #define DBFLAG_Vacuum         0x0004  /* Currently in a VACUUM */
++#define DBFLAG_SchemaKnownOk  0x0008  /* Schema is known to be valid */
+ 
+ /*
+ ** Bits of the sqlite3.dbOptFlags field that are used by the
+@@ -15762,7 +16426,7 @@
+ ** selectively disable various optimizations.
+ */
+ #define SQLITE_QueryFlattener 0x0001   /* Query flattening */
+-#define SQLITE_ColumnCache    0x0002   /* Column cache */
++                          /*  0x0002   available for reuse */
+ #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
+ #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
+ #define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
+@@ -15776,6 +16440,8 @@
+    /* TH3 expects the Stat34  ^^^^^^ value to be 0x0800.  Don't change it */
+ #define SQLITE_PushDown       0x1000   /* The push-down optimization */
+ #define SQLITE_SimplifyJoin   0x2000   /* Convert LEFT JOIN to JOIN */
++#define SQLITE_SkipScan       0x4000   /* Skip-scans */
++#define SQLITE_PropagateConst 0x8000   /* The constant propagation opt */
+ #define SQLITE_AllOpts        0xffff   /* All optimizations */
+ 
+ /*
+@@ -15814,11 +16480,13 @@
+ */
+ struct FuncDef {
+   i8 nArg;             /* Number of arguments.  -1 means unlimited */
+-  u16 funcFlags;       /* Some combination of SQLITE_FUNC_* */
++  u32 funcFlags;       /* Some combination of SQLITE_FUNC_* */
+   void *pUserData;     /* User data parameter */
+   FuncDef *pNext;      /* Next function with same name */
+   void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
+   void (*xFinalize)(sqlite3_context*);                  /* Agg finalizer */
++  void (*xValue)(sqlite3_context*);                     /* Current agg value */
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
+   const char *zName;   /* SQL name of the function. */
+   union {
+     FuncDef *pHash;      /* Next with a different name but the same hash */
+@@ -15875,6 +16543,9 @@
+                                     ** single query - might change over time */
+ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
+ #define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
++#define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
++#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
++#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
+ 
+ /*
+ ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
+@@ -15909,6 +16580,12 @@
+ **     are interpreted in the same way as the first 4 parameters to
+ **     FUNCTION().
+ **
++**   WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse)
++**     Used to create an aggregate function definition implemented by
++**     the C functions xStep and xFinal. The first four parameters
++**     are interpreted in the same way as the first 4 parameters to
++**     FUNCTION().
++**
+ **   LIKEFUNC(zName, nArg, pArg, flags)
+ **     Used to create a scalar function definition of a function zName
+ **     that accepts nArg arguments and is implemented by a call to C
+@@ -15919,32 +16596,39 @@
+ */
+ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
+-   0, 0, xFunc, 0, #zName, {0} }
++   0, 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
+-   (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} }
++   (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
+   {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
+-   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
++   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+ #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
+   {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+-   pArg, 0, xFunc, 0, #zName, }
++   pArg, 0, xFunc, 0, 0, 0, #zName, }
+ #define LIKEFUNC(zName, nArg, arg, flags) \
+   {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
+-   (void *)arg, 0, likeFunc, 0, #zName, {0} }
+-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
++   (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
++#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
+-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
+ #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
+   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
+-   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
++#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
++  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
++   SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
++#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
++  {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
++   0, 0, xFunc, 0, 0, 0, #zName, {0} }
+ 
++
+ /*
+ ** All current savepoints are stored in a linked list starting at
+ ** sqlite3.pSavepoint. The first element in the list is the most recently
+@@ -16000,6 +16684,7 @@
+ #define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
+ #define COLFLAG_HASTYPE  0x0004    /* Type name follows column name */
+ #define COLFLAG_UNIQUE   0x0008    /* Column def contains "UNIQUE" or "PK" */
++#define COLFLAG_SORTERREF 0x0010   /* Use sorter-refs with this column */
+ 
+ /*
+ ** A "Collating Sequence" is defined by an instance of the following
+@@ -16127,6 +16812,9 @@
+ struct Table {
+   char *zName;         /* Name of the table or view */
+   Column *aCol;        /* Information about each column */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  Hash *pColHash;      /* All columns indexed by name */
++#endif
+   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 */
+@@ -16177,6 +16865,7 @@
+ #define TF_StatsUsed       0x0100    /* Query planner decisions affected by
+                                      ** Index.aiRowLogEst[] values */
+ #define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */
++#define TF_Shadow          0x0400    /* True for a shadow table */
+ 
+ /*
+ ** Test to see whether or not a table is a virtual table.  This is
+@@ -16287,15 +16976,14 @@
+ #define OE_Fail     3   /* Stop the operation but leave all prior changes */
+ #define OE_Ignore   4   /* Ignore the error. Do not do the INSERT or UPDATE */
+ #define OE_Replace  5   /* Delete existing record, then do INSERT or UPDATE */
++#define OE_Update   6   /* Process as a DO UPDATE in an upsert */
++#define OE_Restrict 7   /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
++#define OE_SetNull  8   /* Set the foreign key value to NULL */
++#define OE_SetDflt  9   /* Set the foreign key value to its default */
++#define OE_Cascade  10  /* Cascade the changes */
++#define OE_Default  11  /* Do whatever the default action is */
+ 
+-#define OE_Restrict 6   /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+-#define OE_SetNull  7   /* Set the foreign key value to NULL */
+-#define OE_SetDflt  8   /* Set the foreign key value to its default */
+-#define OE_Cascade  9   /* Cascade the changes */
+ 
+-#define OE_Default  10  /* Do whatever the default action is */
+-
+-
+ /*
+ ** An instance of the following structure is passed as the first
+ ** argument to sqlite3VdbeKeyCompare and is used to control the
+@@ -16429,6 +17117,7 @@
+   tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
+   tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
+ #endif
++  Bitmask colNotIdxed;     /* 0 for unindexed columns in pTab */
+ };
+ 
+ /*
+@@ -16464,12 +17153,20 @@
+ };
+ 
+ /*
++** Possible values to use within the flags argument to sqlite3GetToken().
++*/
++#define SQLITE_TOKEN_QUOTED    0x1 /* Token is a quoted identifier. */
++#define SQLITE_TOKEN_KEYWORD   0x2 /* Token is a keyword. */
++
++/*
+ ** Each token coming out of the lexer is an instance of
+ ** this structure.  Tokens are also used as part of an expression.
+ **
+-** Note if Token.z==0 then Token.dyn and Token.n are undefined and
+-** may contain random values.  Do not make any assumptions about Token.dyn
+-** and Token.n when Token.z==0.
++** The memory that "z" points to is owned by other objects.  Take care
++** that the owner of the "z" string does not deallocate the string before
++** the Token goes out of scope!  Very often, the "z" points to some place
++** in the middle of the Parse.zSql text.  But it might also point to a
++** static string.
+ */
+ struct Token {
+   const char *z;     /* Text of the token.  Not NULL-terminated! */
+@@ -16642,8 +17339,11 @@
+                          ** TK_COLUMN: the value of p5 for OP_Column
+                          ** TK_AGG_FUNCTION: nesting depth */
+   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
+-  Table *pTab;           /* Table for TK_COLUMN expressions.  Can be NULL
+-                         ** for a column of an index on an expression */
++  union {
++    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
++                           ** for a column of an index on an expression */
++    Window *pWin;          /* TK_FUNCTION: Window definition for the func */
++  } y;
+ };
+ 
+ /*
+@@ -16652,7 +17352,7 @@
+ #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
+ #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
+ #define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
+-                  /* 0x000008 // available for use */
++#define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */
+ #define EP_Distinct  0x000010 /* Aggregate function with DISTINCT keyword */
+ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+@@ -16673,6 +17373,7 @@
+ #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
+ #define EP_Alias     0x400000 /* Is an alias for a result set column */
+ #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
++#define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
+ 
+ /*
+ ** The EP_Propagate mask is a set of properties that automatically propagate
+@@ -16740,6 +17441,7 @@
+     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 */
++    unsigned bSorterRef :1; /* Defer evaluation until after sorting */
+     union {
+       struct {
+         u16 iOrderByCol;      /* For ORDER BY, column number in result set */
+@@ -16774,31 +17476,6 @@
+ };
+ 
+ /*
+-** The bitmask datatype defined below is used for various optimizations.
+-**
+-** Changing this from a 64-bit to a 32-bit type limits the number of
+-** tables in a join to 32 instead of 64.  But it also reduces the size
+-** of the library by 738 bytes on ix86.
+-*/
+-#ifdef SQLITE_BITMASK_TYPE
+-  typedef SQLITE_BITMASK_TYPE Bitmask;
+-#else
+-  typedef u64 Bitmask;
+-#endif
+-
+-/*
+-** The number of bits in a Bitmask.  "BMS" means "BitMask Size".
+-*/
+-#define BMS  ((int)(sizeof(Bitmask)*8))
+-
+-/*
+-** A bit in a Bitmask
+-*/
+-#define MASKBIT(n)   (((Bitmask)1)<<(n))
+-#define MASKBIT32(n) (((unsigned int)1)<<(n))
+-#define ALLBITS      ((Bitmask)-1)
+-
+-/*
+ ** The following structure describes the FROM clause of a SELECT statement.
+ ** Each table or subquery in the FROM clause is a separate element of
+ ** the SrcList.a[] array.
+@@ -16839,9 +17516,6 @@
+       unsigned viaCoroutine :1;  /* Implemented as a co-routine */
+       unsigned isRecursive :1;   /* True for recursive reference in WITH */
+     } fg;
+-#ifndef SQLITE_OMIT_EXPLAIN
+-    u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
+-#endif
+     int iCursor;      /* The VDBE cursor number used to access this table */
+     Expr *pOn;        /* The ON clause of a join */
+     IdList *pUsing;   /* The USING clause of a join */
+@@ -16923,12 +17597,16 @@
+ struct NameContext {
+   Parse *pParse;       /* The parser */
+   SrcList *pSrcList;   /* One or more tables used to resolve names */
+-  ExprList *pEList;    /* Optional list of result-set columns */
+-  AggInfo *pAggInfo;   /* Information about aggregates at this level */
++  union {
++    ExprList *pEList;    /* Optional list of result-set columns */
++    AggInfo *pAggInfo;   /* Information about aggregates at this level */
++    Upsert *pUpsert;     /* ON CONFLICT clause information from an upsert */
++  } uNC;
+   NameContext *pNext;  /* Next outer name context.  NULL for outermost */
+   int nRef;            /* Number of names resolved by this context */
+   int nErr;            /* Number of errors encountered while resolving names */
+   u16 ncFlags;         /* Zero or more NC_* flags defined below */
++  Select *pWinSelect;  /* SELECT statement for any window functions */
+ };
+ 
+ /*
+@@ -16946,18 +17624,49 @@
+ #define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
+ #define NC_IdxExpr   0x0020  /* True if resolving columns of CREATE INDEX */
+ #define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
++#define NC_UEList    0x0080  /* True if uNC.pEList is used */
++#define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
++#define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
+ #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
+ #define NC_Complex   0x2000  /* True if a function or subquery seen */
++#define NC_AllowWin  0x4000  /* Window functions are allowed here */
+ 
+ /*
++** An instance of the following object describes a single ON CONFLICT
++** clause in an upsert.
++**
++** The pUpsertTarget field is only set if the ON CONFLICT clause includes
++** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
++** conflict-target clause.)  The pUpsertTargetWhere is the optional
++** WHERE clause used to identify partial unique indexes.
++**
++** pUpsertSet is the list of column=expr terms of the UPDATE statement. 
++** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING.  The
++** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the
++** WHERE clause is omitted.
++*/
++struct Upsert {
++  ExprList *pUpsertTarget;  /* Optional description of conflicting index */
++  Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */
++  ExprList *pUpsertSet;     /* The SET clause from an ON CONFLICT UPDATE */
++  Expr *pUpsertWhere;       /* WHERE clause for the ON CONFLICT UPDATE */
++  /* The fields above comprise the parse tree for the upsert clause.
++  ** The fields below are used to transfer information from the INSERT
++  ** processing down into the UPDATE processing while generating code.
++  ** Upsert owns the memory allocated above, but not the memory below. */
++  Index *pUpsertIdx;        /* Constraint that pUpsertTarget identifies */
++  SrcList *pUpsertSrc;      /* Table to be updated */
++  int regData;              /* First register holding array of VALUES */
++  int iDataCur;             /* Index of the data cursor */
++  int iIdxCur;              /* Index of the first index cursor */
++};
++
++/*
+ ** An instance of the following structure contains all information
+ ** needed to generate code for a single SELECT statement.
+ **
+-** nLimit is set to -1 if there is no LIMIT clause.  nOffset is set to 0.
+-** If there is a LIMIT clause, the parser sets nLimit to the value of the
+-** limit and nOffset to the value of the offset (or 0 if there is not
+-** offset).  But later on, nLimit and nOffset become the memory locations
+-** in the VDBE that record the limit and offset counters.
++** See the header comment on the computeLimitRegisters() routine for a
++** detailed description of the meaning of the iLimit and iOffset fields.
+ **
+ ** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
+ ** These addresses must be stored so that we can go back and fill in
+@@ -16975,9 +17684,7 @@
+   LogEst nSelectRow;     /* Estimated number of result rows */
+   u32 selFlags;          /* Various SF_* values */
+   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+-#if SELECTTRACE_ENABLED
+-  char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
+-#endif
++  u32 selId;             /* Unique identifier number for this SELECT */
+   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
+   SrcList *pSrc;         /* The FROM clause */
+   Expr *pWhere;          /* The WHERE clause */
+@@ -16988,6 +17695,10 @@
+   Select *pNext;         /* Next select to the left in a compound */
+   Expr *pLimit;          /* LIMIT expression. NULL means not used. */
+   With *pWith;           /* WITH clause attached to this select. Or NULL. */
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  Window *pWin;          /* List of window functions */
++  Window *pWinDefn;      /* List of named window definitions */
++#endif
+ };
+ 
+ /*
+@@ -17017,9 +17728,8 @@
+ #define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
+ #define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
+ #define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
+-#define SF_ComplexResult  0x40000  /* Result set contains subquery or function */
++#define SF_ComplexResult  0x40000  /* Result contains subquery or function */
+ 
+-
+ /*
+ ** The results of a SELECT can be distributed in several ways, as defined
+ ** by one of the following macros.  The "SRT" prefix means "SELECT Result
+@@ -17133,13 +17843,6 @@
+ };
+ 
+ /*
+-** Size of the column cache
+-*/
+-#ifndef SQLITE_N_COLCACHE
+-# define SQLITE_N_COLCACHE 10
+-#endif
+-
+-/*
+ ** At least one instance of the following structure is created for each
+ ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
+ ** statement. All such objects are stored in the linked list headed at
+@@ -17214,7 +17917,6 @@
+   u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
+   u8 okConstFactor;    /* OK to factor out constants */
+   u8 disableLookaside; /* Number of times lookaside has been disabled */
+-  u8 nColCache;        /* Number of entries in aColCache[] */
+   int nRangeReg;       /* Size of the temporary register block */
+   int iRangeReg;       /* First register in temporary register block */
+   int nErr;            /* Number of errors seen */
+@@ -17224,8 +17926,6 @@
+   int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
+   int iSelfTab;        /* Table associated with an index on expr, or negative
+                        ** of the base register during check-constraint eval */
+-  int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
+-  int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
+   int nLabel;          /* Number of labels used */
+   int *aLabel;         /* Space to hold the labels */
+   ExprList *pConstExpr;/* Constant expressions */
+@@ -17235,9 +17935,7 @@
+   int regRowid;        /* Register holding rowid of CREATE TABLE entry */
+   int regRoot;         /* Register holding root page number for new objects */
+   int nMaxArg;         /* Max args passed to user function by sub-program */
+-#if SELECTTRACE_ENABLED
+-  int nSelect;         /* Number of SELECT statements seen */
+-#endif
++  int nSelect;         /* Number of SELECT stmts. Counter for Select.selId */
+ #ifndef SQLITE_OMIT_SHARED_CACHE
+   int nTableLock;        /* Number of locks in aTableLock */
+   TableLock *aTableLock; /* Required table locks for shared-cache mode */
+@@ -17257,17 +17955,9 @@
+   ** Fields above must be initialized to zero.  The fields that follow,
+   ** down to the beginning of the recursive section, do not need to be
+   ** initialized as they will be set before being used.  The boundary is
+-  ** determined by offsetof(Parse,aColCache).
++  ** determined by offsetof(Parse,aTempReg).
+   **************************************************************************/
+ 
+-  struct yColCache {
+-    int iTable;           /* Table cursor number */
+-    i16 iColumn;          /* Table column number */
+-    u8 tempReg;           /* iReg is a temp register that needs to be freed */
+-    int iLevel;           /* Nesting level */
+-    int iReg;             /* Reg with value of this column. 0 means none. */
+-    int lru;              /* Least recently used entry has the smallest value */
+-  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
+   int aTempReg[8];        /* Holding area for temporary registers */
+   Token sNameToken;       /* Token with unqualified schema object name */
+ 
+@@ -17282,19 +17972,21 @@
+   ynVar nVar;               /* Number of '?' variables seen in the SQL so far */
+   u8 iPkSortOrder;          /* ASC or DESC for INTEGER PRIMARY KEY */
+   u8 explain;               /* True if the EXPLAIN flag is found on the query */
++#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE))
++  u8 eParseMode;            /* PARSE_MODE_XXX constant */
++#endif
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-  u8 declareVtab;           /* True if inside sqlite3_declare_vtab() */
+   int nVtabLock;            /* Number of virtual tables to lock */
+ #endif
+   int nHeight;              /* Expression tree height of current sub-select */
+ #ifndef SQLITE_OMIT_EXPLAIN
+-  int iSelectId;            /* ID of current select for EXPLAIN output */
+-  int iNextSelectId;        /* Next available select ID for EXPLAIN output */
++  int addrExplain;          /* Address of current OP_Explain opcode */
+ #endif
+   VList *pVList;            /* Mapping between variable names and numbers */
+   Vdbe *pReprepare;         /* VM being reprepared (sqlite3Reprepare()) */
+   const char *zTail;        /* All SQL text past the last semicolon parsed */
+   Table *pNewTable;         /* A table being constructed by CREATE TABLE */
++  Index *pNewIndex;         /* An index being constructed by CREATE INDEX */
+   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
+   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+@@ -17305,12 +17997,20 @@
+   TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
+   With *pWith;              /* Current WITH clause, or NULL */
+   With *pWithToFree;        /* Free this WITH object at the end of the parse */
++#ifndef SQLITE_OMIT_ALTERTABLE
++  RenameToken *pRename;     /* Tokens subject to renaming by ALTER TABLE */
++#endif
+ };
+ 
++#define PARSE_MODE_NORMAL        0
++#define PARSE_MODE_DECLARE_VTAB  1
++#define PARSE_MODE_RENAME_COLUMN 2
++#define PARSE_MODE_RENAME_TABLE  3
++
+ /*
+ ** Sizes and pointers of various parts of the Parse object.
+ */
+-#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
++#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/
+ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken)    /* Recursive part */
+ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
+ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */
+@@ -17321,9 +18021,21 @@
+ #ifdef SQLITE_OMIT_VIRTUALTABLE
+   #define IN_DECLARE_VTAB 0
+ #else
+-  #define IN_DECLARE_VTAB (pParse->declareVtab)
++  #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB)
+ #endif
+ 
++#if defined(SQLITE_OMIT_ALTERTABLE)
++  #define IN_RENAME_OBJECT 0
++#else
++  #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN)
++#endif
++
++#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)
++  #define IN_SPECIAL_PARSE 0
++#else
++  #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL)
++#endif
++
+ /*
+ ** An instance of the following structure can be declared on a stack and used
+ ** to save the Parse.zAuthContext value so that it can be restored later.
+@@ -17347,6 +18059,7 @@
+ */
+ #define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
+                                      /* Also used in P2 (not P5) of OP_Delete */
++#define OPFLAG_NOCHNG        0x01    /* OP_VColumn nochange for UPDATE */
+ #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
+ #define OPFLAG_LASTROWID     0x20    /* Set to update db->lastRowid */
+ #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
+@@ -17448,8 +18161,9 @@
+   Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
+   char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
+   Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
+-  ExprList *pExprList; /* SET clause for UPDATE. */
++  ExprList *pExprList; /* SET clause for UPDATE */
+   IdList *pIdList;     /* Column names for INSERT */
++  Upsert *pUpsert;     /* Upsert clauses on an INSERT */
+   char *zSpan;         /* Original SQL text of this command */
+   TriggerStep *pNext;  /* Next in the link-list */
+   TriggerStep *pLast;  /* Last element in link-list. Valid for 1st elem only */
+@@ -17474,17 +18188,15 @@
+ ** An objected used to accumulate the text of a string where we
+ ** do not necessarily know how big the string will be in the end.
+ */
+-struct StrAccum {
++struct sqlite3_str {
+   sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
+   char *zText;         /* The string collected so far */
+   u32  nAlloc;         /* Amount of space allocated in zText */
+   u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
+   u32  nChar;          /* Length of the string so far */
+-  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
++  u8   accError;       /* SQLITE_NOMEM or SQLITE_TOOBIG */
+   u8   printfFlags;    /* SQLITE_PRINTF flags below */
+ };
+-#define STRACCUM_NOMEM   1
+-#define STRACCUM_TOOBIG  2
+ #define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
+ #define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
+ #define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
+@@ -17501,9 +18213,15 @@
+   char **pzErrMsg;    /* Error message stored here */
+   int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
+   int rc;             /* Result code stored here */
++  u32 mInitFlags;     /* Flags controlling error messages */
+ } InitData;
+ 
+ /*
++** Allowed values for mInitFlags
++*/
++#define INITFLAG_AlterTable   0x0001  /* This is a reparse after ALTER TABLE */
++
++/*
+ ** Structure containing global configuration data for the SQLite library.
+ **
+ ** This structure also contains some state information.
+@@ -17553,7 +18271,7 @@
+   /* The following callback (if not NULL) is invoked on every VDBE branch
+   ** operation.  Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
+   */
+-  void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx);  /* Callback */
++  void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx);  /* Callback */
+   void *pVdbeBranchArg;                                     /* 1st argument */
+ #endif
+ #ifndef SQLITE_UNTESTABLE
+@@ -17560,7 +18278,9 @@
+   int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
+ #endif
+   int bLocaltimeFault;              /* True to fail localtime() calls */
++  int bInternalFunctions;           /* Internal SQL functions are visible */
+   int iOnceResetThreshold;          /* When to reset OP_Once counters */
++  u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
+ };
+ 
+ /*
+@@ -17603,6 +18323,9 @@
+     struct IdxExprTrans *pIdxTrans;           /* Convert idxed expr to column */
+     ExprList *pGroupBy;                       /* GROUP BY clause */
+     Select *pSelect;                          /* HAVING to WHERE clause ctx */
++    struct WindowRewrite *pRewrite;           /* Window rewrite context */
++    struct WhereConst *pConst;                /* WHERE clause constants */
++    struct RenameCtx *pRename;                /* RENAME COLUMN context */
+   } u;
+ };
+ 
+@@ -17654,6 +18377,68 @@
+ #endif /* SQLITE_DEBUG */
+ 
+ /*
++** This object is used in varioius ways, all related to window functions
++**
++**   (1) A single instance of this structure is attached to the
++**       the Expr.pWin field for each window function in an expression tree.
++**       This object holds the information contained in the OVER clause,
++**       plus additional fields used during code generation.
++**
++**   (2) All window functions in a single SELECT form a linked-list
++**       attached to Select.pWin.  The Window.pFunc and Window.pExpr
++**       fields point back to the expression that is the window function.
++**
++**   (3) The terms of the WINDOW clause of a SELECT are instances of this
++**       object on a linked list attached to Select.pWinDefn.
++**
++** The uses (1) and (2) are really the same Window object that just happens
++** to be accessible in two different ways.  Use (3) is are separate objects.
++*/
++struct Window {
++  char *zName;            /* Name of window (may be NULL) */
++  ExprList *pPartition;   /* PARTITION BY clause */
++  ExprList *pOrderBy;     /* ORDER BY clause */
++  u8 eType;               /* TK_RANGE or TK_ROWS */
++  u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
++  u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
++  Expr *pStart;           /* Expression for "<expr> PRECEDING" */
++  Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
++  Window *pNextWin;       /* Next window function belonging to this SELECT */
++  Expr *pFilter;          /* The FILTER expression */
++  FuncDef *pFunc;         /* The function */
++  int iEphCsr;            /* Partition buffer or Peer buffer */
++  int regAccum;
++  int regResult;
++  int csrApp;             /* Function cursor (used by min/max) */
++  int regApp;             /* Function register (also used by min/max) */
++  int regPart;            /* First in a set of registers holding PARTITION BY
++                          ** and ORDER BY values for the window */
++  Expr *pOwner;           /* Expression object this window is attached to */
++  int nBufferCol;         /* Number of columns in buffer table */
++  int iArgCol;            /* Offset of first argument for this function */
++};
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
++SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p);
++SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
++SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
++SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*);
++SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
++SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
++SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*);
++SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
++SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
++SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
++SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
++SQLITE_PRIVATE void sqlite3WindowFunctions(void);
++#else
++# define sqlite3WindowDelete(a,b)
++# define sqlite3WindowFunctions()
++# define sqlite3WindowAttach(a,b,c)
++#endif
++
++/*
+ ** Assuming zIn points to the first byte of a UTF-8 character,
+ ** advance zIn to point to the first byte of the next UTF-8 character.
+ */
+@@ -17740,9 +18525,7 @@
+ # define sqlite3Tolower(x)   tolower((unsigned char)(x))
+ # define sqlite3Isquote(x)   ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
+ #endif
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
+-#endif
+ 
+ /*
+ ** Internal function prototypes
+@@ -17749,6 +18532,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
+ SQLITE_PRIVATE int sqlite3Strlen30(const char*);
++#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
+ SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
+ #define sqlite3StrNICmp sqlite3_strnicmp
+ 
+@@ -17852,8 +18636,6 @@
+   sqlite3_value **apArg;   /* The argument values */
+ };
+ 
+-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list);
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
+ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
+ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
+ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+@@ -17867,9 +18649,14 @@
+ SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
+ SQLITE_PRIVATE   void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
+ SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
++SQLITE_PRIVATE   void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
+ SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
+ SQLITE_PRIVATE   void sqlite3TreeViewWith(TreeView*, const With*, u8);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE   void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
++SQLITE_PRIVATE   void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
+ #endif
++#endif
+ 
+ 
+ SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
+@@ -17893,7 +18680,7 @@
+ SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
+ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
+ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
+-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
++SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
+ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
+ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+@@ -17905,6 +18692,7 @@
+ SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
+ SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
+ SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
++SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
+ SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+ SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
+@@ -17954,8 +18742,9 @@
+ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
+ #endif
+ 
+-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
+-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
++SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*);
++SQLITE_PRIVATE void sqlite3RowSetDelete(void*);
++SQLITE_PRIVATE void sqlite3RowSetClear(void*);
+ SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
+ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64);
+ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
+@@ -17974,6 +18763,7 @@
+ SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
+ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
+ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
++SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*);
+ #ifndef SQLITE_OMIT_AUTOINCREMENT
+ SQLITE_PRIVATE   void sqlite3AutoincrementBegin(Parse *pParse);
+ SQLITE_PRIVATE   void sqlite3AutoincrementEnd(Parse *pParse);
+@@ -17981,9 +18771,9 @@
+ # define sqlite3AutoincrementBegin(X)
+ # define sqlite3AutoincrementEnd(X)
+ #endif
+-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
++SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
+ SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
+-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
++SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
+ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
+ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
+ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
+@@ -18011,13 +18801,14 @@
+ SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
+ #endif
+ SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
+-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*);
++SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
++                   Upsert*);
+ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
+ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
+ SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
+-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*);
++SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+@@ -18027,15 +18818,8 @@
+ #define ONEPASS_MULTI    2        /* ONEPASS is valid for multiple rows */
+ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
+ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
+-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
+-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
+-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
+ SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
+@@ -18098,13 +18882,17 @@
+ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
+ SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
+ SQLITE_PRIVATE int sqlite3IsRowid(const char*);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
++#endif
+ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
+     Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
+ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
+ SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
+ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
++SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
+ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+-                                     u8,u8,int,int*,int*);
++                                     u8,u8,int,int*,int*,Upsert*);
+ #ifdef SQLITE_ENABLE_NULL_TRIM
+ SQLITE_PRIVATE   void sqlite3SetMakeRecordP5(Vdbe*,Table*);
+ #else
+@@ -18123,10 +18911,8 @@
+ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
+ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
+ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+-#if SELECTTRACE_ENABLED
+-SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
+-#else
+-# define sqlite3SelectSetName(A,B)
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
+ #endif
+ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+@@ -18156,12 +18942,13 @@
+ SQLITE_PRIVATE   void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
+ SQLITE_PRIVATE   TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
+                                         const char*,const char*);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
+-                                        Select*,u8,const char*,const char*);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8,
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*,
++                                        Select*,u8,Upsert*,
+                                         const char*,const char*);
+-SQLITE_PRIVATE   TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*,
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8,
+                                         const char*,const char*);
++SQLITE_PRIVATE   TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*,
++                                        const char*,const char*);
+ SQLITE_PRIVATE   void sqlite3DeleteTrigger(sqlite3*, Trigger*);
+ SQLITE_PRIVATE   void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
+ SQLITE_PRIVATE   u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
+@@ -18275,6 +19062,7 @@
+ SQLITE_PRIVATE const char *sqlite3ErrStr(int);
+ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
+ SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
++SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*);
+ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
+ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
+ SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
+@@ -18283,6 +19071,7 @@
+ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
+ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
+ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
++SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
+ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
+ SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
+ SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
+@@ -18327,9 +19116,13 @@
+ SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
+ SQLITE_PRIVATE void sqlite3AlterFunctions(void);
+ SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
++SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
+ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
++#endif
+ SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
+-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
++SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
+ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
+ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
+@@ -18342,8 +19135,12 @@
+ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
+ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
+ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
++SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*);
++SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
++SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*);
++SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
+ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
+-SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*);
++SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
+ SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
+ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
+ SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
+@@ -18360,14 +19157,20 @@
+ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
+ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
+ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
++SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int);
++
+ #ifdef SQLITE_DEBUG
+ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+ #endif
+ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+   void (*)(sqlite3_context*,int,sqlite3_value **),
+-  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*,int,sqlite3_value **), 
++  void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*),
++  void (*)(sqlite3_context*,int,sqlite3_value **), 
+   FuncDestructor *pDestructor
+ );
++SQLITE_PRIVATE void sqlite3NoopDestructor(void*);
+ SQLITE_PRIVATE void sqlite3OomFault(sqlite3*);
+ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*);
+ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
+@@ -18374,11 +19177,7 @@
+ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
+ 
+ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
+-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
+-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
+-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
+ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
+-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
+ SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
+ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
+ 
+@@ -18405,10 +19204,11 @@
+ ** The interface to the LEMON-generated parser
+ */
+ #ifndef SQLITE_AMALGAMATION
+-SQLITE_PRIVATE   void *sqlite3ParserAlloc(void*(*)(u64));
++SQLITE_PRIVATE   void *sqlite3ParserAlloc(void*(*)(u64), Parse*);
+ SQLITE_PRIVATE   void sqlite3ParserFree(void*, void(*)(void*));
+ #endif
+-SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
++SQLITE_PRIVATE void sqlite3Parser(void*, int, Token);
++SQLITE_PRIVATE int sqlite3ParserFallback(int);
+ #ifdef YYTRACKMAXSTACKDEPTH
+ SQLITE_PRIVATE   int sqlite3ParserStackPeak(void*);
+ #endif
+@@ -18474,11 +19274,13 @@
+ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
+ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
+ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
+-SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
+ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
+ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
+ SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
++#endif
+ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
+ SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
+ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
+@@ -18496,7 +19298,19 @@
+ #define sqlite3WithPush(x,y,z)
+ #define sqlite3WithDelete(x,y)
+ #endif
++#ifndef SQLITE_OMIT_UPSERT
++SQLITE_PRIVATE   Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*);
++SQLITE_PRIVATE   void sqlite3UpsertDelete(sqlite3*,Upsert*);
++SQLITE_PRIVATE   Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
++SQLITE_PRIVATE   int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
++SQLITE_PRIVATE   void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
++#else
++#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0)
++#define sqlite3UpsertDelete(x,y)
++#define sqlite3UpsertDup(x,y)       ((Upsert*)0)
++#endif
+ 
++
+ /* Declarations for functions in fkey.c. All of these are replaced by
+ ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
+ ** key functionality is available. If OMIT_TRIGGER is defined but
+@@ -18928,7 +19742,9 @@
+    0,                         /* xTestCallback */
+ #endif
+    0,                         /* bLocaltimeFault */
+-   0x7ffffffe                 /* iOnceResetThreshold */
++   0,                         /* bInternalFunctions */
++   0x7ffffffe,                /* iOnceResetThreshold */
++   SQLITE_DEFAULT_SORTERREF_SIZE   /* szSorterRef */
+ };
+ 
+ /*
+@@ -19097,6 +19913,7 @@
+   Bool isEphemeral:1;     /* True for an ephemeral table */
+   Bool useRandomRowid:1;  /* Generate new record numbers semi-randomly */
+   Bool isOrdered:1;       /* True if the table is not BTREE_UNORDERED */
++  Bool seekHit:1;         /* See the OP_SeekHit and OP_IfNoHope opcodes */
+   Btree *pBtx;            /* Separate file holding temporary table */
+   i64 seqCount;           /* Sequence counter */
+   int *aAltMap;           /* Mapping from table to index column numbers */
+@@ -19180,6 +19997,9 @@
+   void *token;            /* Copy of SubProgram.token */
+   i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
+   AuxData *pAuxData;      /* Linked list of auxdata allocations */
++#if SQLITE_DEBUG
++  u32 iFrameMagic;        /* magic number for sanity checking */
++#endif
+   int nCursor;            /* Number of entries in apCsr */
+   int pc;                 /* Program Counter in parent (calling) frame */
+   int nOp;                /* Size of aOp array */
+@@ -19190,6 +20010,13 @@
+   int nDbChange;          /* Value of db->nChange */
+ };
+ 
++/* Magic number for sanity checking on VdbeFrame objects */
++#define SQLITE_FRAME_MAGIC 0x879fb71e
++
++/*
++** Return a pointer to the array of registers allocated for use
++** by a VdbeFrame.
++*/
+ #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
+ 
+ /*
+@@ -19204,8 +20031,6 @@
+     int nZero;          /* Extra zero bytes when MEM_Zero and MEM_Blob set */
+     const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
+     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+-    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
+-    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
+   } u;
+   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
+@@ -19220,7 +20045,7 @@
+   void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
+ #ifdef SQLITE_DEBUG
+   Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
+-  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
++  u16 mScopyFlags;    /* flags value immediately after the shallow copy */
+ #endif
+ };
+ 
+@@ -19249,8 +20074,8 @@
+ #define MEM_Real      0x0008   /* Value is a real number */
+ #define MEM_Blob      0x0010   /* Value is a BLOB */
+ #define MEM_AffMask   0x001f   /* Mask of affinity bits */
+-#define MEM_RowSet    0x0020   /* Value is a RowSet object */
+-#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
++/* Available          0x0020   */
++/* Available          0x0040   */
+ #define MEM_Undefined 0x0080   /* Value is undefined */
+ #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
+ #define MEM_TypeMask  0xc1ff   /* Mask of type bits */
+@@ -19277,7 +20102,7 @@
+ ** that needs to be deallocated to avoid a leak.
+ */
+ #define VdbeMemDynamic(X)  \
+-  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
++  (((X)->flags&(MEM_Agg|MEM_Dyn))!=0)
+ 
+ /*
+ ** Clear any existing type flags from a Mem and replace them with f
+@@ -19391,14 +20216,15 @@
+   int nOp;                /* Number of instructions in the program */
+ #ifdef SQLITE_DEBUG
+   int rcApp;              /* errcode set by sqlite3_result_error_code() */
++  u32 nWrite;             /* Number of write operations that have occurred */
+ #endif
+   u16 nResColumn;         /* Number of columns in one row of the result set */
+   u8 errorAction;         /* Recovery action to do in case of an error */
+   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
+   u8 prepFlags;           /* SQLITE_PREPARE_* flags */
+-  bft expired:1;          /* True if the VM needs to be recompiled */
++  bft expired:2;          /* 1: recompile VM immediately  2: when convenient */
++  bft explain:2;          /* True if EXPLAIN present on SQL command */
+   bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
+-  bft explain:2;          /* True if EXPLAIN present on SQL command */
+   bft changeCntOn:1;      /* True to update the change-counter */
+   bft runOnlyOnce:1;      /* Automatically expire on reset */
+   bft usesStmtJournal:1;  /* True if uses a statement journal */
+@@ -19408,6 +20234,9 @@
+   yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
+   u32 aCounter[7];        /* Counters used by sqlite3_stmt_status() */
+   char *zSql;             /* Text of the SQL statement that generated this */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  char *zNormSql;         /* Normalization of the associated SQL statement */
++#endif
+   void *pFree;            /* Free this when deleting the vdbe */
+   VdbeFrame *pFrame;      /* Parent frame */
+   VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
+@@ -19459,9 +20288,6 @@
+ void sqliteVdbePopStack(Vdbe*,int);
+ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
+ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
+-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
+-#endif
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
+ SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
+ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*);
+@@ -19473,7 +20299,9 @@
+ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
+ SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
++#ifndef SQLITE_OMIT_EXPLAIN
+ SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
++#endif
+ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
+ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
+ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
+@@ -19492,7 +20320,10 @@
+ SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
+-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
++#endif
++SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
+ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
+ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
+@@ -19506,11 +20337,20 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
+ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
+ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
++#endif
++#ifndef SQLITE_OMIT_EXPLAIN
+ SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
++#endif
+ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
+ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
+-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
++#endif
++SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*);      /* Destructor on Mem */
++SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */
+ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int);
+@@ -19526,6 +20366,14 @@
+ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
+ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
+ 
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE   void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*);
++SQLITE_PRIVATE   void sqlite3VdbeAssertAbortable(Vdbe*);
++#else
++# define sqlite3VdbeIncrWriteCounter(V,C)
++# define sqlite3VdbeAssertAbortable(V)
++#endif
++
+ #if !defined(SQLITE_OMIT_SHARED_CACHE) 
+ SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
+ #else
+@@ -21600,9 +22448,12 @@
+ ** Unregister a VFS so that it is no longer accessible.
+ */
+ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+-#if SQLITE_THREADSAFE
+-  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
++  MUTEX_LOGIC(sqlite3_mutex *mutex;)
++#ifndef SQLITE_OMIT_AUTOINIT
++  int rc = sqlite3_initialize();
++  if( rc ) return rc;
+ #endif
++  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+   sqlite3_mutex_enter(mutex);
+   vfsUnlink(pVfs);
+   sqlite3_mutex_leave(mutex);
+@@ -24218,7 +25069,6 @@
+ 
+ #endif /* !defined(SQLITE_MUTEX_OMIT) */
+ 
+-
+ /************** End of mutex.c ***********************************************/
+ /************** Begin file mutex_noop.c **************************************/
+ /*
+@@ -26382,7 +27232,7 @@
+ ** Set the StrAccum object to an error mode.
+ */
+ static void setStrAccumError(StrAccum *p, u8 eError){
+-  assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
++  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
+   p->accError = eError;
+   p->nAlloc = 0;
+ }
+@@ -26416,8 +27266,8 @@
+ /*
+ ** Render a string given by "fmt" into the StrAccum object.
+ */
+-SQLITE_PRIVATE void sqlite3VXPrintf(
+-  StrAccum *pAccum,          /* Accumulate results here */
++SQLITE_API void sqlite3_str_vappendf(
++  sqlite3_str *pAccum,       /* Accumulate results here */
+   const char *fmt,           /* Format string */
+   va_list ap                 /* arguments */
+ ){
+@@ -26474,11 +27324,11 @@
+ #else
+       do{ fmt++; }while( *fmt && *fmt != '%' );
+ #endif
+-      sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
++      sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
+       if( *fmt==0 ) break;
+     }
+     if( (c=(*++fmt))==0 ){
+-      sqlite3StrAccumAppend(pAccum, "%", 1);
++      sqlite3_str_append(pAccum, "%", 1);
+       break;
+     }
+     /* Find out what flags are present */
+@@ -26656,7 +27506,7 @@
+           u64 n = (u64)precision + 10 + precision/3;
+           zOut = zExtra = sqlite3Malloc( n );
+           if( zOut==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+           nOut = (int)n;
+@@ -26781,7 +27631,7 @@
+           bufpt = zExtra 
+               = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
+           if( bufpt==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+         }
+@@ -26913,11 +27763,11 @@
+         if( precision>1 ){
+           width -= precision-1;
+           if( width>1 && !flag_leftjustify ){
+-            sqlite3AppendChar(pAccum, width-1, ' ');
++            sqlite3_str_appendchar(pAccum, width-1, ' ');
+             width = 0;
+           }
+           while( precision-- > 1 ){
+-            sqlite3StrAccumAppend(pAccum, buf, length);
++            sqlite3_str_append(pAccum, buf, length);
+           }
+         }
+         bufpt = buf;
+@@ -26934,7 +27784,12 @@
+         if( bufpt==0 ){
+           bufpt = "";
+         }else if( xtype==etDYNSTRING ){
+-          if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){
++          if( pAccum->nChar==0
++           && pAccum->mxAlloc
++           && width==0
++           && precision<0
++           && pAccum->accError==0
++          ){
+             /* Special optimization for sqlite3_mprintf("%z..."):
+             ** Extend an existing memory allocation rather than creating
+             ** a new one. */
+@@ -27003,7 +27858,7 @@
+         if( n>etBUFSIZE ){
+           bufpt = zExtra = sqlite3Malloc( n );
+           if( bufpt==0 ){
+-            setStrAccumError(pAccum, STRACCUM_NOMEM);
++            setStrAccumError(pAccum, SQLITE_NOMEM);
+             return;
+           }
+         }else{
+@@ -27027,7 +27882,7 @@
+         pToken = va_arg(ap, Token*);
+         assert( bArgList==0 );
+         if( pToken && pToken->n ){
+-          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
++          sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
+         }
+         length = width = 0;
+         break;
+@@ -27043,10 +27898,10 @@
+         assert( bArgList==0 );
+         assert( k>=0 && k<pSrc->nSrc );
+         if( pItem->zDatabase ){
+-          sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
+-          sqlite3StrAccumAppend(pAccum, ".", 1);
++          sqlite3_str_appendall(pAccum, pItem->zDatabase);
++          sqlite3_str_append(pAccum, ".", 1);
+         }
+-        sqlite3StrAccumAppendAll(pAccum, pItem->zName);
++        sqlite3_str_appendall(pAccum, pItem->zName);
+         length = width = 0;
+         break;
+       }
+@@ -27065,11 +27920,11 @@
+     */
+     width -= length;
+     if( width>0 ){
+-      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+-      sqlite3StrAccumAppend(pAccum, bufpt, length);
+-      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
++      if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
++      sqlite3_str_append(pAccum, bufpt, length);
++      if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
+     }else{
+-      sqlite3StrAccumAppend(pAccum, bufpt, length);
++      sqlite3_str_append(pAccum, bufpt, length);
+     }
+ 
+     if( zExtra ){
+@@ -27090,13 +27945,13 @@
+   char *zNew;
+   assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+   if( p->accError ){
+-    testcase(p->accError==STRACCUM_TOOBIG);
+-    testcase(p->accError==STRACCUM_NOMEM);
++    testcase(p->accError==SQLITE_TOOBIG);
++    testcase(p->accError==SQLITE_NOMEM);
+     return 0;
+   }
+   if( p->mxAlloc==0 ){
+     N = p->nAlloc - p->nChar - 1;
+-    setStrAccumError(p, STRACCUM_TOOBIG);
++    setStrAccumError(p, SQLITE_TOOBIG);
+     return N;
+   }else{
+     char *zOld = isMalloced(p) ? p->zText : 0;
+@@ -27108,8 +27963,8 @@
+       szNew += p->nChar;
+     }
+     if( szNew > p->mxAlloc ){
+-      sqlite3StrAccumReset(p);
+-      setStrAccumError(p, STRACCUM_TOOBIG);
++      sqlite3_str_reset(p);
++      setStrAccumError(p, SQLITE_TOOBIG);
+       return 0;
+     }else{
+       p->nAlloc = (int)szNew;
+@@ -27126,8 +27981,8 @@
+       p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
+       p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+     }else{
+-      sqlite3StrAccumReset(p);
+-      setStrAccumError(p, STRACCUM_NOMEM);
++      sqlite3_str_reset(p);
++      setStrAccumError(p, SQLITE_NOMEM);
+       return 0;
+     }
+   }
+@@ -27137,7 +27992,7 @@
+ /*
+ ** Append N copies of character c to the given string buffer.
+ */
+-SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
+   testcase( p->nChar + (i64)N > 0x7fffffff );
+   if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+     return;
+@@ -27149,9 +28004,9 @@
+ ** The StrAccum "p" is not large enough to accept N new bytes of z[].
+ ** So enlarge if first, then do the append.
+ **
+-** This is a helper routine to sqlite3StrAccumAppend() that does special-case
++** This is a helper routine to sqlite3_str_append() that does special-case
+ ** work (enlarging the buffer) using tail recursion, so that the
+-** sqlite3StrAccumAppend() routine can use fast calling semantics.
++** sqlite3_str_append() routine can use fast calling semantics.
+ */
+ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
+   N = sqlite3StrAccumEnlarge(p, N);
+@@ -27165,7 +28020,7 @@
+ ** Append N bytes of text from z to the StrAccum object.  Increase the
+ ** size of the memory allocation for StrAccum if necessary.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
++SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
+   assert( z!=0 || N==0 );
+   assert( p->zText!=0 || p->nChar==0 || p->accError );
+   assert( N>=0 );
+@@ -27182,8 +28037,8 @@
+ /*
+ ** Append the complete text of zero-terminated string z[] to the p string.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
+-  sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
++SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){
++  sqlite3_str_append(p, z, sqlite3Strlen30(z));
+ }
+ 
+ 
+@@ -27200,7 +28055,7 @@
+     memcpy(zText, p->zText, p->nChar+1);
+     p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+   }else{
+-    setStrAccumError(p, STRACCUM_NOMEM);
++    setStrAccumError(p, SQLITE_NOMEM);
+   }
+   p->zText = zText;
+   return zText;
+@@ -27216,13 +28071,55 @@
+ }
+ 
+ /*
++** This singleton is an sqlite3_str object that is returned if
++** sqlite3_malloc() fails to provide space for a real one.  This
++** sqlite3_str object accepts no new text and always returns
++** an SQLITE_NOMEM error.
++*/
++static sqlite3_str sqlite3OomStr = {
++   0, 0, 0, 0, 0, SQLITE_NOMEM, 0
++};
++
++/* Finalize a string created using sqlite3_str_new().
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){
++  char *z;
++  if( p!=0 && p!=&sqlite3OomStr ){
++    z = sqlite3StrAccumFinish(p);
++    sqlite3_free(p);
++  }else{
++    z = 0;
++  }
++  return z;
++}
++
++/* Return any error code associated with p */
++SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){
++  return p ? p->accError : SQLITE_NOMEM;
++}
++
++/* Return the current length of p in bytes */
++SQLITE_API int sqlite3_str_length(sqlite3_str *p){
++  return p ? p->nChar : 0;
++}
++
++/* Return the current value for p */
++SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
++  if( p==0 || p->nChar==0 ) return 0;
++  p->zText[p->nChar] = 0;
++  return p->zText;
++}
++
++/*
+ ** Reset an StrAccum string.  Reclaim all malloced memory.
+ */
+-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
++SQLITE_API void sqlite3_str_reset(StrAccum *p){
+   if( isMalloced(p) ){
+     sqlite3DbFree(p->db, p->zText);
+     p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
+   }
++  p->nAlloc = 0;
++  p->nChar = 0;
+   p->zText = 0;
+ }
+ 
+@@ -27250,6 +28147,18 @@
+   p->printfFlags = 0;
+ }
+ 
++/* Allocate and initialize a new dynamic string object */
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){
++  sqlite3_str *p = sqlite3_malloc64(sizeof(*p));
++  if( p ){
++    sqlite3StrAccumInit(p, 0, 0, 0,
++            db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
++  }else{
++    p = &sqlite3OomStr;
++  }
++  return p;
++}
++
+ /*
+ ** Print into memory obtained from sqliteMalloc().  Use the internal
+ ** %-conversion extensions.
+@@ -27262,9 +28171,9 @@
+   sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
+                       db->aLimit[SQLITE_LIMIT_LENGTH]);
+   acc.printfFlags = SQLITE_PRINTF_INTERNAL;
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+-  if( acc.accError==STRACCUM_NOMEM ){
++  if( acc.accError==SQLITE_NOMEM ){
+     sqlite3OomFault(db);
+   }
+   return z;
+@@ -27302,7 +28211,7 @@
+   if( sqlite3_initialize() ) return 0;
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   z = sqlite3StrAccumFinish(&acc);
+   return z;
+ }
+@@ -27347,7 +28256,7 @@
+   }
+ #endif
+   sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   zBuf[acc.nChar] = 0;
+   return zBuf;
+ }
+@@ -27369,7 +28278,7 @@
+ ** allocate memory because it might be called while the memory allocator
+ ** mutex is held.
+ **
+-** sqlite3VXPrintf() might ask for *temporary* memory allocations for
++** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
+ ** certain format characters (%q) or for very large precisions or widths.
+ ** Care must be taken that any sqlite3_log() calls that occur while the
+ ** memory mutex is held do not use these mechanisms.
+@@ -27379,7 +28288,7 @@
+   char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
+ 
+   sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
+                            sqlite3StrAccumFinish(&acc));
+ }
+@@ -27408,7 +28317,7 @@
+   char zBuf[500];
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+   va_start(ap,zFormat);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
++  sqlite3_str_vappendf(&acc, zFormat, ap);
+   va_end(ap);
+   sqlite3StrAccumFinish(&acc);
+ #ifdef SQLITE_OS_TRACE_PROC
+@@ -27425,13 +28334,13 @@
+ 
+ 
+ /*
+-** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
++** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
+ ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
+ */
+-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
++SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
+   va_list ap;
+   va_start(ap,zFormat);
+-  sqlite3VXPrintf(p, zFormat, ap);
++  sqlite3_str_vappendf(p, zFormat, ap);
+   va_end(ap);
+ }
+ 
+@@ -27497,15 +28406,17 @@
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+   if( p ){
+     for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+-      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
++      sqlite3_str_append(&acc, p->bLine[i] ? "|   " : "    ", 4);
+     }
+-    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
++    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+   }
+-  va_start(ap, zFormat);
+-  sqlite3VXPrintf(&acc, zFormat, ap);
+-  va_end(ap);
+-  assert( acc.nChar>0 );
+-  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
++  if( zFormat!=0 ){
++    va_start(ap, zFormat);
++    sqlite3_str_vappendf(&acc, zFormat, ap);
++    va_end(ap);
++    assert( acc.nChar>0 );
++    sqlite3_str_append(&acc, "\n", 1);
++  }
+   sqlite3StrAccumFinish(&acc);
+   fprintf(stdout,"%s", zBuf);
+   fflush(stdout);
+@@ -27538,17 +28449,17 @@
+       char zLine[1000];
+       const struct Cte *pCte = &pWith->a[i];
+       sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+-      sqlite3XPrintf(&x, "%s", pCte->zName);
++      sqlite3_str_appendf(&x, "%s", pCte->zName);
+       if( pCte->pCols && pCte->pCols->nExpr>0 ){
+         char cSep = '(';
+         int j;
+         for(j=0; j<pCte->pCols->nExpr; j++){
+-          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
++          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
+           cSep = ',';
+         }
+-        sqlite3XPrintf(&x, ")");
++        sqlite3_str_appendf(&x, ")");
+       }
+-      sqlite3XPrintf(&x, " AS");
++      sqlite3_str_appendf(&x, " AS");
+       sqlite3StrAccumFinish(&x);
+       sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
+       sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
+@@ -27558,6 +28469,42 @@
+   }
+ }
+ 
++/*
++** Generate a human-readable description of a SrcList object.
++*/
++SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
++  int i;
++  for(i=0; i<pSrc->nSrc; i++){
++    const struct SrcList_item *pItem = &pSrc->a[i];
++    StrAccum x;
++    char zLine[100];
++    sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
++    sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
++    if( pItem->zDatabase ){
++      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
++    }else if( pItem->zName ){
++      sqlite3_str_appendf(&x, " %s", pItem->zName);
++    }
++    if( pItem->pTab ){
++      sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
++    }
++    if( pItem->zAlias ){
++      sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
++    }
++    if( pItem->fg.jointype & JT_LEFT ){
++      sqlite3_str_appendf(&x, " LEFT-JOIN");
++    }
++    sqlite3StrAccumFinish(&x);
++    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); 
++    if( pItem->pSelect ){
++      sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
++    }
++    if( pItem->fg.isTabFunc ){
++      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
++    }
++    sqlite3TreeViewPop(pView);
++  }
++}
+ 
+ /*
+ ** Generate a human-readable description of a Select object.
+@@ -27576,21 +28523,13 @@
+     sqlite3TreeViewPush(pView, 1);
+   }
+   do{
+-#if SELECTTRACE_ENABLED
+     sqlite3TreeViewLine(pView,
+-      "SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d",
++      "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d",
+       ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+       ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
+-      p->zSelName, p, p->selFlags,
++      p->selId, p, p->selFlags,
+       (int)p->nSelectRow
+     );
+-#else
+-    sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
+-      ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+-      ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
+-      (int)p->nSelectRow
+-    );
+-#endif
+     if( cnt++ ) sqlite3TreeViewPop(pView);
+     if( p->pPrior ){
+       n = 1000;
+@@ -27602,42 +28541,27 @@
+       if( p->pHaving ) n++;
+       if( p->pOrderBy ) n++;
+       if( p->pLimit ) n++;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( p->pWin ) n++;
++      if( p->pWinDefn ) n++;
++#endif
+     }
+     sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( p->pWin ){
++      Window *pX;
++      pView = sqlite3TreeViewPush(pView, (n--)>0);
++      sqlite3TreeViewLine(pView, "window-functions");
++      for(pX=p->pWin; pX; pX=pX->pNextWin){
++        sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
++      }
++      sqlite3TreeViewPop(pView);
++    }
++#endif
+     if( p->pSrc && p->pSrc->nSrc ){
+-      int i;
+       pView = sqlite3TreeViewPush(pView, (n--)>0);
+       sqlite3TreeViewLine(pView, "FROM");
+-      for(i=0; i<p->pSrc->nSrc; i++){
+-        struct SrcList_item *pItem = &p->pSrc->a[i];
+-        StrAccum x;
+-        char zLine[100];
+-        sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+-        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
+-        if( pItem->zDatabase ){
+-          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
+-        }else if( pItem->zName ){
+-          sqlite3XPrintf(&x, " %s", pItem->zName);
+-        }
+-        if( pItem->pTab ){
+-          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
+-        }
+-        if( pItem->zAlias ){
+-          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
+-        }
+-        if( pItem->fg.jointype & JT_LEFT ){
+-          sqlite3XPrintf(&x, " LEFT-JOIN");
+-        }
+-        sqlite3StrAccumFinish(&x);
+-        sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
+-        if( pItem->pSelect ){
+-          sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+-        }
+-        if( pItem->fg.isTabFunc ){
+-          sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+-        }
+-        sqlite3TreeViewPop(pView);
+-      }
++      sqlite3TreeViewSrcList(pView, p->pSrc);
+       sqlite3TreeViewPop(pView);
+     }
+     if( p->pWhere ){
+@@ -27653,6 +28577,16 @@
+       sqlite3TreeViewExpr(pView, p->pHaving, 0);
+       sqlite3TreeViewPop(pView);
+     }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( p->pWinDefn ){
++      Window *pX;
++      sqlite3TreeViewItem(pView, "WINDOW", (n--)>0);
++      for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
++        sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
++      }
++      sqlite3TreeViewPop(pView);
++    }
++#endif
+     if( p->pOrderBy ){
+       sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
+     }
+@@ -27680,7 +28614,84 @@
+   sqlite3TreeViewPop(pView);
+ }
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
+ /*
++** Generate a description of starting or stopping bounds
++*/
++SQLITE_PRIVATE void sqlite3TreeViewBound(
++  TreeView *pView,        /* View context */
++  u8 eBound,              /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */
++  Expr *pExpr,            /* Value for PRECEDING or FOLLOWING */
++  u8 moreToFollow         /* True if more to follow */
++){
++  switch( eBound ){
++    case TK_UNBOUNDED: {
++      sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_CURRENT: {
++      sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_PRECEDING: {
++      sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
++      sqlite3TreeViewExpr(pView, pExpr, 0);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++    case TK_FOLLOWING: {
++      sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
++      sqlite3TreeViewExpr(pView, pExpr, 0);
++      sqlite3TreeViewPop(pView);
++      break;
++    }
++  }
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Generate a human-readable explanation for a Window object
++*/
++SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
++  pView = sqlite3TreeViewPush(pView, more);
++  if( pWin->zName ){
++    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
++  }else{
++    sqlite3TreeViewLine(pView, "OVER");
++  }
++  if( pWin->pPartition ){
++    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
++  }
++  if( pWin->pOrderBy ){
++    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
++  }
++  if( pWin->eType ){
++    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
++    sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
++    sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
++    sqlite3TreeViewPop(pView);
++  }
++  sqlite3TreeViewPop(pView);
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Generate a human-readable explanation for a Window Function object
++*/
++SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
++  pView = sqlite3TreeViewPush(pView, more);
++  sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
++                       pWin->pFunc->zName, pWin->pFunc->nArg);
++  sqlite3TreeViewWindow(pView, pWin, 0);
++  sqlite3TreeViewPop(pView);
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** Generate a human-readable explanation of an expression tree.
+ */
+ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
+@@ -27717,6 +28728,9 @@
+         sqlite3TreeViewLine(pView, "{%d:%d}%s",
+                              pExpr->iTable, pExpr->iColumn, zFlgs);
+       }
++      if( ExprHasProperty(pExpr, EP_FixedCol) ){
++        sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
++      }
+       break;
+     }
+     case TK_INTEGER: {
+@@ -27830,10 +28844,17 @@
+     case TK_AGG_FUNCTION:
+     case TK_FUNCTION: {
+       ExprList *pFarg;       /* List of function arguments */
++      Window *pWin;
+       if( ExprHasProperty(pExpr, EP_TokenOnly) ){
+         pFarg = 0;
++        pWin = 0;
+       }else{
+         pFarg = pExpr->x.pList;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        pWin = pExpr->y.pWin;
++#else
++        pWin = 0;
++#endif 
+       }
+       if( pExpr->op==TK_AGG_FUNCTION ){
+         sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
+@@ -27842,8 +28863,13 @@
+         sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
+       }
+       if( pFarg ){
+-        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
++        sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0);
+       }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( pWin ){
++        sqlite3TreeViewWindow(pView, pWin, 0);
++      }
++#endif
+       break;
+     }
+ #ifndef SQLITE_OMIT_SUBQUERY
+@@ -27975,16 +29001,21 @@
+     for(i=0; i<pList->nExpr; i++){
+       int j = pList->a[i].u.x.iOrderByCol;
+       char *zName = pList->a[i].zName;
++      int moreToFollow = i<pList->nExpr - 1;
+       if( j || zName ){
+-        sqlite3TreeViewPush(pView, 0);
++        sqlite3TreeViewPush(pView, moreToFollow);
++        moreToFollow = 0;
++        sqlite3TreeViewLine(pView, 0);
++        if( zName ){
++          fprintf(stdout, "AS %s ", zName);
++        }
++        if( j ){
++          fprintf(stdout, "iOrderByCol=%d", j);
++        }
++        fprintf(stdout, "\n");
++        fflush(stdout);
+       }
+-      if( zName ){
+-        sqlite3TreeViewLine(pView, "AS %s", zName);
+-      }
+-      if( j ){
+-        sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
+-      }
+-      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
++      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
+       if( j || zName ){
+         sqlite3TreeViewPop(pView);
+       }
+@@ -30648,6 +31679,20 @@
+   }
+   return h;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++static unsigned int strHashN(const char *z, int n){
++  unsigned int h = 0;
++  int i;
++  for(i=0; i<n; i++){
++    /* Knuth multiplicative hashing.  (Sorting & Searching, p. 510).
++    ** 0x9e3779b1 is 2654435761 which is the closest prime number to
++    ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
++    h += sqlite3UpperToLower[z[i]];
++    h *= 0x9e3779b1;
++  }
++  return h;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ 
+ /* Link pNew element into the hash table pH.  If pEntry!=0 then also
+@@ -30759,7 +31804,41 @@
+   }
+   return &nullElement;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++static HashElem *findElementWithHashN(
++  const Hash *pH,     /* The pH to be searched */
++  const char *pKey,   /* The key we are searching for */
++  int nKey,           /* Number of key bytes to use */
++  unsigned int *pHash /* Write the hash value here */
++){
++  HashElem *elem;                /* Used to loop thru the element list */
++  int count;                     /* Number of elements left to test */
++  unsigned int h;                /* The computed hash */
++  static HashElem nullElement = { 0, 0, 0, 0 };
+ 
++  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
++    struct _ht *pEntry;
++    h = strHashN(pKey, nKey) % pH->htsize;
++    pEntry = &pH->ht[h];
++    elem = pEntry->chain;
++    count = pEntry->count;
++  }else{
++    h = 0;
++    elem = pH->first;
++    count = pH->count;
++  }
++  if( pHash ) *pHash = h;
++  while( count-- ){
++    assert( elem!=0 );
++    if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
++      return elem;
++    }
++    elem = elem->next;
++  }
++  return &nullElement;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
+ /* Remove a single entry from the hash table given a pointer to that
+ ** element and a hash on the element's key.
+ */
+@@ -30803,6 +31882,14 @@
+   assert( pKey!=0 );
+   return findElementWithHash(pH, pKey, 0)->data;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
++  assert( pH!=0 );
++  assert( pKey!=0 );
++  assert( nKey>=0 );
++  return findElementWithHashN(pH, pKey, nKey, 0)->data;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ /* Insert an element into the hash table pH.  The key is pKey
+ ** and the data is "data".
+@@ -30870,52 +31957,52 @@
+     /*   1 */ "AutoCommit"       OpHelp(""),
+     /*   2 */ "Transaction"      OpHelp(""),
+     /*   3 */ "SorterNext"       OpHelp(""),
+-    /*   4 */ "PrevIfOpen"       OpHelp(""),
+-    /*   5 */ "NextIfOpen"       OpHelp(""),
+-    /*   6 */ "Prev"             OpHelp(""),
+-    /*   7 */ "Next"             OpHelp(""),
+-    /*   8 */ "Checkpoint"       OpHelp(""),
+-    /*   9 */ "JournalMode"      OpHelp(""),
+-    /*  10 */ "Vacuum"           OpHelp(""),
+-    /*  11 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
+-    /*  12 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
+-    /*  13 */ "Goto"             OpHelp(""),
+-    /*  14 */ "Gosub"            OpHelp(""),
+-    /*  15 */ "InitCoroutine"    OpHelp(""),
+-    /*  16 */ "Yield"            OpHelp(""),
+-    /*  17 */ "MustBeInt"        OpHelp(""),
+-    /*  18 */ "Jump"             OpHelp(""),
++    /*   4 */ "Prev"             OpHelp(""),
++    /*   5 */ "Next"             OpHelp(""),
++    /*   6 */ "Checkpoint"       OpHelp(""),
++    /*   7 */ "JournalMode"      OpHelp(""),
++    /*   8 */ "Vacuum"           OpHelp(""),
++    /*   9 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
++    /*  10 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
++    /*  11 */ "Goto"             OpHelp(""),
++    /*  12 */ "Gosub"            OpHelp(""),
++    /*  13 */ "InitCoroutine"    OpHelp(""),
++    /*  14 */ "Yield"            OpHelp(""),
++    /*  15 */ "MustBeInt"        OpHelp(""),
++    /*  16 */ "Jump"             OpHelp(""),
++    /*  17 */ "Once"             OpHelp(""),
++    /*  18 */ "If"               OpHelp(""),
+     /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
+-    /*  20 */ "Once"             OpHelp(""),
+-    /*  21 */ "If"               OpHelp(""),
+-    /*  22 */ "IfNot"            OpHelp(""),
+-    /*  23 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
+-    /*  24 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
+-    /*  25 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
+-    /*  26 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
+-    /*  27 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
+-    /*  28 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
+-    /*  29 */ "NotFound"         OpHelp("key=r[P3@P4]"),
+-    /*  30 */ "Found"            OpHelp("key=r[P3@P4]"),
+-    /*  31 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
+-    /*  32 */ "NotExists"        OpHelp("intkey=r[P3]"),
+-    /*  33 */ "Last"             OpHelp(""),
+-    /*  34 */ "IfSmaller"        OpHelp(""),
+-    /*  35 */ "SorterSort"       OpHelp(""),
+-    /*  36 */ "Sort"             OpHelp(""),
+-    /*  37 */ "Rewind"           OpHelp(""),
+-    /*  38 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
+-    /*  39 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
+-    /*  40 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
+-    /*  41 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
+-    /*  42 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
++    /*  20 */ "IfNot"            OpHelp(""),
++    /*  21 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
++    /*  22 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
++    /*  23 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
++    /*  24 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
++    /*  25 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
++    /*  26 */ "IfNoHope"         OpHelp("key=r[P3@P4]"),
++    /*  27 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
++    /*  28 */ "NotFound"         OpHelp("key=r[P3@P4]"),
++    /*  29 */ "Found"            OpHelp("key=r[P3@P4]"),
++    /*  30 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
++    /*  31 */ "NotExists"        OpHelp("intkey=r[P3]"),
++    /*  32 */ "Last"             OpHelp(""),
++    /*  33 */ "IfSmaller"        OpHelp(""),
++    /*  34 */ "SorterSort"       OpHelp(""),
++    /*  35 */ "Sort"             OpHelp(""),
++    /*  36 */ "Rewind"           OpHelp(""),
++    /*  37 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
++    /*  38 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
++    /*  39 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
++    /*  40 */ "IdxGE"            OpHelp("key=r[P3@P4]"),
++    /*  41 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
++    /*  42 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+     /*  43 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
+     /*  44 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
+-    /*  45 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+-    /*  46 */ "Program"          OpHelp(""),
+-    /*  47 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+-    /*  48 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+-    /*  49 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
++    /*  45 */ "Program"          OpHelp(""),
++    /*  46 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
++    /*  47 */ "IfPos"            OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
++    /*  48 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
++    /*  49 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+     /*  50 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
+     /*  51 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
+     /*  52 */ "Ne"               OpHelp("IF r[P3]!=r[P1]"),
+@@ -30925,118 +32012,121 @@
+     /*  56 */ "Lt"               OpHelp("IF r[P3]<r[P1]"),
+     /*  57 */ "Ge"               OpHelp("IF r[P3]>=r[P1]"),
+     /*  58 */ "ElseNotEq"        OpHelp(""),
+-    /*  59 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+-    /*  60 */ "IncrVacuum"       OpHelp(""),
+-    /*  61 */ "VNext"            OpHelp(""),
+-    /*  62 */ "Init"             OpHelp("Start at P2"),
+-    /*  63 */ "Return"           OpHelp(""),
+-    /*  64 */ "EndCoroutine"     OpHelp(""),
+-    /*  65 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
+-    /*  66 */ "Halt"             OpHelp(""),
+-    /*  67 */ "Integer"          OpHelp("r[P2]=P1"),
+-    /*  68 */ "Int64"            OpHelp("r[P2]=P4"),
+-    /*  69 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
+-    /*  70 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+-    /*  71 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+-    /*  72 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+-    /*  73 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+-    /*  74 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+-    /*  75 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+-    /*  76 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+-    /*  77 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
+-    /*  78 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+-    /*  79 */ "CollSeq"          OpHelp(""),
+-    /*  80 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+-    /*  81 */ "RealAffinity"     OpHelp(""),
+-    /*  82 */ "Cast"             OpHelp("affinity(r[P1])"),
+-    /*  83 */ "Permutation"      OpHelp(""),
+-    /*  84 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
+-    /*  85 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
+-    /*  86 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
+-    /*  87 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
+-    /*  88 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
+-    /*  89 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
+-    /*  90 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
+-    /*  91 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
+-    /*  92 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
+-    /*  93 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
+-    /*  94 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
+-    /*  95 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
+-    /*  96 */ "IsTrue"           OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
+-    /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
+-    /*  98 */ "Offset"           OpHelp("r[P3] = sqlite_offset(P1)"),
+-    /*  99 */ "Column"           OpHelp("r[P3]=PX"),
+-    /* 100 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+-    /* 101 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+-    /* 102 */ "Count"            OpHelp("r[P2]=count()"),
+-    /* 103 */ "ReadCookie"       OpHelp(""),
+-    /* 104 */ "SetCookie"        OpHelp(""),
+-    /* 105 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+-    /* 106 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+-    /* 107 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+-    /* 108 */ "OpenDup"          OpHelp(""),
+-    /* 109 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
+-    /* 110 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+-    /* 111 */ "SorterOpen"       OpHelp(""),
+-    /* 112 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+-    /* 113 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+-    /* 114 */ "Close"            OpHelp(""),
+-    /* 115 */ "ColumnsUsed"      OpHelp(""),
+-    /* 116 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+-    /* 117 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+-    /* 118 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
+-    /* 119 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
+-    /* 120 */ "Delete"           OpHelp(""),
+-    /* 121 */ "ResetCount"       OpHelp(""),
+-    /* 122 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+-    /* 123 */ "SorterData"       OpHelp("r[P2]=data"),
+-    /* 124 */ "RowData"          OpHelp("r[P2]=data"),
+-    /* 125 */ "Rowid"            OpHelp("r[P2]=rowid"),
+-    /* 126 */ "NullRow"          OpHelp(""),
+-    /* 127 */ "SeekEnd"          OpHelp(""),
+-    /* 128 */ "SorterInsert"     OpHelp("key=r[P2]"),
+-    /* 129 */ "IdxInsert"        OpHelp("key=r[P2]"),
+-    /* 130 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+-    /* 131 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
+-    /* 132 */ "Real"             OpHelp("r[P2]=P4"),
+-    /* 133 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+-    /* 134 */ "Destroy"          OpHelp(""),
+-    /* 135 */ "Clear"            OpHelp(""),
+-    /* 136 */ "ResetSorter"      OpHelp(""),
+-    /* 137 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
+-    /* 138 */ "SqlExec"          OpHelp(""),
+-    /* 139 */ "ParseSchema"      OpHelp(""),
+-    /* 140 */ "LoadAnalysis"     OpHelp(""),
+-    /* 141 */ "DropTable"        OpHelp(""),
+-    /* 142 */ "DropIndex"        OpHelp(""),
+-    /* 143 */ "DropTrigger"      OpHelp(""),
+-    /* 144 */ "IntegrityCk"      OpHelp(""),
+-    /* 145 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+-    /* 146 */ "Param"            OpHelp(""),
+-    /* 147 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+-    /* 148 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+-    /* 149 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+-    /* 150 */ "AggStep0"         OpHelp("accum=r[P3] step(r[P2@P5])"),
+-    /* 151 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+-    /* 152 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+-    /* 153 */ "Expire"           OpHelp(""),
+-    /* 154 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+-    /* 155 */ "VBegin"           OpHelp(""),
+-    /* 156 */ "VCreate"          OpHelp(""),
+-    /* 157 */ "VDestroy"         OpHelp(""),
+-    /* 158 */ "VOpen"            OpHelp(""),
+-    /* 159 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+-    /* 160 */ "VRename"          OpHelp(""),
+-    /* 161 */ "Pagecount"        OpHelp(""),
+-    /* 162 */ "MaxPgcnt"         OpHelp(""),
+-    /* 163 */ "PureFunc0"        OpHelp(""),
+-    /* 164 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
+-    /* 165 */ "PureFunc"         OpHelp(""),
+-    /* 166 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
+-    /* 167 */ "Trace"            OpHelp(""),
+-    /* 168 */ "CursorHint"       OpHelp(""),
+-    /* 169 */ "Noop"             OpHelp(""),
+-    /* 170 */ "Explain"          OpHelp(""),
++    /*  59 */ "IncrVacuum"       OpHelp(""),
++    /*  60 */ "VNext"            OpHelp(""),
++    /*  61 */ "Init"             OpHelp("Start at P2"),
++    /*  62 */ "PureFunc0"        OpHelp(""),
++    /*  63 */ "Function0"        OpHelp("r[P3]=func(r[P2@P5])"),
++    /*  64 */ "PureFunc"         OpHelp(""),
++    /*  65 */ "Function"         OpHelp("r[P3]=func(r[P2@P5])"),
++    /*  66 */ "Return"           OpHelp(""),
++    /*  67 */ "EndCoroutine"     OpHelp(""),
++    /*  68 */ "HaltIfNull"       OpHelp("if r[P3]=null halt"),
++    /*  69 */ "Halt"             OpHelp(""),
++    /*  70 */ "Integer"          OpHelp("r[P2]=P1"),
++    /*  71 */ "Int64"            OpHelp("r[P2]=P4"),
++    /*  72 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
++    /*  73 */ "Null"             OpHelp("r[P2..P3]=NULL"),
++    /*  74 */ "SoftNull"         OpHelp("r[P1]=NULL"),
++    /*  75 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
++    /*  76 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
++    /*  77 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
++    /*  78 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
++    /*  79 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
++    /*  80 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
++    /*  81 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
++    /*  82 */ "CollSeq"          OpHelp(""),
++    /*  83 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
++    /*  84 */ "RealAffinity"     OpHelp(""),
++    /*  85 */ "Cast"             OpHelp("affinity(r[P1])"),
++    /*  86 */ "Permutation"      OpHelp(""),
++    /*  87 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
++    /*  88 */ "IsTrue"           OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
++    /*  89 */ "Offset"           OpHelp("r[P3] = sqlite_offset(P1)"),
++    /*  90 */ "Column"           OpHelp("r[P3]=PX"),
++    /*  91 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
++    /*  92 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
++    /*  93 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
++    /*  94 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
++    /*  95 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
++    /*  96 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
++    /*  97 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
++    /*  98 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
++    /*  99 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
++    /* 100 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
++    /* 101 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
++    /* 102 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
++    /* 103 */ "BitNot"           OpHelp("r[P2]= ~r[P1]"),
++    /* 104 */ "Count"            OpHelp("r[P2]=count()"),
++    /* 105 */ "ReadCookie"       OpHelp(""),
++    /* 106 */ "String8"          OpHelp("r[P2]='P4'"),
++    /* 107 */ "SetCookie"        OpHelp(""),
++    /* 108 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
++    /* 109 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
++    /* 110 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
++    /* 111 */ "OpenDup"          OpHelp(""),
++    /* 112 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
++    /* 113 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
++    /* 114 */ "SorterOpen"       OpHelp(""),
++    /* 115 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
++    /* 116 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
++    /* 117 */ "Close"            OpHelp(""),
++    /* 118 */ "ColumnsUsed"      OpHelp(""),
++    /* 119 */ "SeekHit"          OpHelp("seekHit=P2"),
++    /* 120 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
++    /* 121 */ "NewRowid"         OpHelp("r[P2]=rowid"),
++    /* 122 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
++    /* 123 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
++    /* 124 */ "Delete"           OpHelp(""),
++    /* 125 */ "ResetCount"       OpHelp(""),
++    /* 126 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
++    /* 127 */ "SorterData"       OpHelp("r[P2]=data"),
++    /* 128 */ "RowData"          OpHelp("r[P2]=data"),
++    /* 129 */ "Rowid"            OpHelp("r[P2]=rowid"),
++    /* 130 */ "NullRow"          OpHelp(""),
++    /* 131 */ "SeekEnd"          OpHelp(""),
++    /* 132 */ "SorterInsert"     OpHelp("key=r[P2]"),
++    /* 133 */ "IdxInsert"        OpHelp("key=r[P2]"),
++    /* 134 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
++    /* 135 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
++    /* 136 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
++    /* 137 */ "Destroy"          OpHelp(""),
++    /* 138 */ "Clear"            OpHelp(""),
++    /* 139 */ "ResetSorter"      OpHelp(""),
++    /* 140 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
++    /* 141 */ "Real"             OpHelp("r[P2]=P4"),
++    /* 142 */ "SqlExec"          OpHelp(""),
++    /* 143 */ "ParseSchema"      OpHelp(""),
++    /* 144 */ "LoadAnalysis"     OpHelp(""),
++    /* 145 */ "DropTable"        OpHelp(""),
++    /* 146 */ "DropIndex"        OpHelp(""),
++    /* 147 */ "DropTrigger"      OpHelp(""),
++    /* 148 */ "IntegrityCk"      OpHelp(""),
++    /* 149 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
++    /* 150 */ "Param"            OpHelp(""),
++    /* 151 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
++    /* 152 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
++    /* 153 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
++    /* 154 */ "AggInverse"       OpHelp("accum=r[P3] inverse(r[P2@P5])"),
++    /* 155 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 156 */ "AggStep1"         OpHelp("accum=r[P3] step(r[P2@P5])"),
++    /* 157 */ "AggValue"         OpHelp("r[P3]=value N=P2"),
++    /* 158 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
++    /* 159 */ "Expire"           OpHelp(""),
++    /* 160 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
++    /* 161 */ "VBegin"           OpHelp(""),
++    /* 162 */ "VCreate"          OpHelp(""),
++    /* 163 */ "VDestroy"         OpHelp(""),
++    /* 164 */ "VOpen"            OpHelp(""),
++    /* 165 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
++    /* 166 */ "VRename"          OpHelp(""),
++    /* 167 */ "Pagecount"        OpHelp(""),
++    /* 168 */ "MaxPgcnt"         OpHelp(""),
++    /* 169 */ "Trace"            OpHelp(""),
++    /* 170 */ "CursorHint"       OpHelp(""),
++    /* 171 */ "Noop"             OpHelp(""),
++    /* 172 */ "Explain"          OpHelp(""),
++    /* 173 */ "Abortable"        OpHelp(""),
+   };
+   return azName[i];
+ }
+@@ -31182,12 +32272,10 @@
+ #define SQLITE_FSFLAGS_IS_MSDOS     0x1
+ 
+ /*
+-** If we are to be thread-safe, include the pthreads header and define
+-** the SQLITE_UNIX_THREADS macro.
++** If we are to be thread-safe, include the pthreads header.
+ */
+ #if SQLITE_THREADSAFE
+ /* # include <pthread.h> */
+-# define SQLITE_UNIX_THREADS 1
+ #endif
+ 
+ /*
+@@ -31765,7 +32853,11 @@
+ #define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+ 
+ #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
++# ifdef __ANDROID__
++  { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 },
++# else
+   { "ioctl",         (sqlite3_syscall_ptr)ioctl,          0 },
++# endif
+ #else
+   { "ioctl",         (sqlite3_syscall_ptr)0,              0 },
+ #endif
+@@ -31946,12 +33038,25 @@
+ **   unixEnterMutex()
+ **     assert( unixMutexHeld() );
+ **   unixEnterLeave()
++**
++** To prevent deadlock, the global unixBigLock must must be acquired
++** before the unixInodeInfo.pLockMutex mutex, if both are held.  It is
++** OK to get the pLockMutex without holding unixBigLock first, but if
++** that happens, the unixBigLock mutex must not be acquired until after
++** pLockMutex is released.
++**
++**      OK:     enter(unixBigLock),  enter(pLockInfo)
++**      OK:     enter(unixBigLock)
++**      OK:     enter(pLockInfo)
++**   ERROR:     enter(pLockInfo), enter(unixBigLock)
+ */
+ static sqlite3_mutex *unixBigLock = 0;
+ static void unixEnterMutex(void){
++  assert( sqlite3_mutex_notheld(unixBigLock) );  /* Not a recursive mutex */
+   sqlite3_mutex_enter(unixBigLock);
+ }
+ static void unixLeaveMutex(void){
++  assert( sqlite3_mutex_held(unixBigLock) );
+   sqlite3_mutex_leave(unixBigLock);
+ }
+ #ifdef SQLITE_DEBUG
+@@ -32346,22 +33451,39 @@
+ 
+ /*
+ ** An instance of the following structure is allocated for each open
+-** inode.  Or, on LinuxThreads, there is one of these structures for
+-** each inode opened by each thread.
++** inode.
+ **
+ ** A single inode can have multiple file descriptors, so each unixFile
+ ** structure contains a pointer to an instance of this object and this
+ ** object keeps a count of the number of unixFile pointing to it.
++**
++** Mutex rules:
++**
++**  (1) Only the pLockMutex mutex must be held in order to read or write
++**      any of the locking fields:
++**          nShared, nLock, eFileLock, bProcessLock, pUnused
++**
++**  (2) When nRef>0, then the following fields are unchanging and can
++**      be read (but not written) without holding any mutex:
++**          fileId, pLockMutex
++**
++**  (3) With the exceptions above, all the fields may only be read
++**      or written while holding the global unixBigLock mutex.
++**
++** Deadlock prevention:  The global unixBigLock mutex may not
++** be acquired while holding the pLockMutex mutex.  If both unixBigLock
++** and pLockMutex are needed, then unixBigLock must be acquired first.
+ */
+ struct unixInodeInfo {
+   struct unixFileId fileId;       /* The lookup key */
+-  int nShared;                    /* Number of SHARED locks held */
+-  unsigned char eFileLock;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
+-  unsigned char bProcessLock;     /* An exclusive process lock is held */
++  sqlite3_mutex *pLockMutex;      /* Hold this mutex for... */
++  int nShared;                      /* Number of SHARED locks held */
++  int nLock;                        /* Number of outstanding file locks */
++  unsigned char eFileLock;          /* One of SHARED_LOCK, RESERVED_LOCK etc. */
++  unsigned char bProcessLock;       /* An exclusive process lock is held */
++  UnixUnusedFd *pUnused;            /* Unused file descriptors to close */
+   int nRef;                       /* Number of pointers to this structure */
+   unixShmNode *pShmNode;          /* Shared memory associated with this inode */
+-  int nLock;                      /* Number of outstanding file locks */
+-  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
+   unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
+   unixInodeInfo *pPrev;           /*    .... doubly linked */
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -32375,11 +33497,28 @@
+ 
+ /*
+ ** A lists of all unixInodeInfo objects.
++**
++** Must hold unixBigLock in order to read or write this variable.
+ */
+ static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
+-static unsigned int nUnusedFd = 0;    /* Total unused file descriptors */
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
++** This routine is used only within assert() to help verify correct mutex
++** usage.
++*/
++int unixFileMutexHeld(unixFile *pFile){
++  assert( pFile->pInode );
++  return sqlite3_mutex_held(pFile->pInode->pLockMutex);
++}
++int unixFileMutexNotheld(unixFile *pFile){
++  assert( pFile->pInode );
++  return sqlite3_mutex_notheld(pFile->pInode->pLockMutex);
++}
++#endif
++
++/*
+ **
+ ** This function - unixLogErrorAtLine(), is only ever called via the macro
+ ** unixLogError().
+@@ -32483,11 +33622,11 @@
+   unixInodeInfo *pInode = pFile->pInode;
+   UnixUnusedFd *p;
+   UnixUnusedFd *pNext;
++  assert( unixFileMutexHeld(pFile) );
+   for(p=pInode->pUnused; p; p=pNext){
+     pNext = p->pNext;
+     robust_close(pFile, p->fd, __LINE__);
+     sqlite3_free(p);
+-    nUnusedFd--;
+   }
+   pInode->pUnused = 0;
+ }
+@@ -32495,17 +33634,20 @@
+ /*
+ ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
+ **
+-** The mutex entered using the unixEnterMutex() function must be held
+-** when this function is called.
++** The global mutex must be held when this routine is called, but the mutex
++** on the inode being deleted must NOT be held.
+ */
+ static void releaseInodeInfo(unixFile *pFile){
+   unixInodeInfo *pInode = pFile->pInode;
+   assert( unixMutexHeld() );
++  assert( unixFileMutexNotheld(pFile) );
+   if( ALWAYS(pInode) ){
+     pInode->nRef--;
+     if( pInode->nRef==0 ){
+       assert( pInode->pShmNode==0 );
++      sqlite3_mutex_enter(pInode->pLockMutex);
+       closePendingFds(pFile);
++      sqlite3_mutex_leave(pInode->pLockMutex);
+       if( pInode->pPrev ){
+         assert( pInode->pPrev->pNext==pInode );
+         pInode->pPrev->pNext = pInode->pNext;
+@@ -32517,10 +33659,10 @@
+         assert( pInode->pNext->pPrev==pInode );
+         pInode->pNext->pPrev = pInode->pPrev;
+       }
++      sqlite3_mutex_free(pInode->pLockMutex);
+       sqlite3_free(pInode);
+     }
+   }
+-  assert( inodeList!=0 || nUnusedFd==0 );
+ }
+ 
+ /*
+@@ -32528,8 +33670,7 @@
+ ** describes that file descriptor.  Create a new one if necessary.  The
+ ** return value might be uninitialized if an error occurs.
+ **
+-** The mutex entered using the unixEnterMutex() function must be held
+-** when this function is called.
++** The global mutex must held when calling this routine.
+ **
+ ** Return an appropriate error code.
+ */
+@@ -32590,7 +33731,7 @@
+ #else
+   fileId.ino = (u64)statbuf.st_ino;
+ #endif
+-  assert( inodeList!=0 || nUnusedFd==0 );
++  assert( unixMutexHeld() );
+   pInode = inodeList;
+   while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
+     pInode = pInode->pNext;
+@@ -32602,7 +33743,15 @@
+     }
+     memset(pInode, 0, sizeof(*pInode));
+     memcpy(&pInode->fileId, &fileId, sizeof(fileId));
++    if( sqlite3GlobalConfig.bCoreMutex ){
++      pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pInode->pLockMutex==0 ){
++        sqlite3_free(pInode);
++        return SQLITE_NOMEM_BKPT;
++      }
++    }
+     pInode->nRef = 1;
++    assert( unixMutexHeld() );
+     pInode->pNext = inodeList;
+     pInode->pPrev = 0;
+     if( inodeList ) inodeList->pPrev = pInode;
+@@ -32680,7 +33829,7 @@
+ 
+   assert( pFile );
+   assert( pFile->eFileLock<=SHARED_LOCK );
+-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
++  sqlite3_mutex_enter(pFile->pInode->pLockMutex);
+ 
+   /* Check if a thread in this process holds such a lock */
+   if( pFile->pInode->eFileLock>SHARED_LOCK ){
+@@ -32705,7 +33854,7 @@
+   }
+ #endif
+   
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pFile->pInode->pLockMutex);
+   OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
+ 
+   *pResOut = reserved;
+@@ -32771,8 +33920,8 @@
+ static int unixFileLock(unixFile *pFile, struct flock *pLock){
+   int rc;
+   unixInodeInfo *pInode = pFile->pInode;
+-  assert( unixMutexHeld() );
+   assert( pInode!=0 );
++  assert( sqlite3_mutex_held(pInode->pLockMutex) );
+   if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
+     if( pInode->bProcessLock==0 ){
+       struct flock lock;
+@@ -32891,8 +34040,8 @@
+ 
+   /* This mutex is needed because pFile->pInode is shared across threads
+   */
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+ 
+   /* If some thread using this PID has a lock via a different unixFile*
+   ** handle that precludes the requested lock, return BUSY.
+@@ -33035,7 +34184,7 @@
+   }
+ 
+ end_lock:
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   OSTRACE(("LOCK    %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), 
+       rc==SQLITE_OK ? "ok" : "failed"));
+   return rc;
+@@ -33048,11 +34197,11 @@
+ static void setPendingFd(unixFile *pFile){
+   unixInodeInfo *pInode = pFile->pInode;
+   UnixUnusedFd *p = pFile->pPreallocatedUnused;
++  assert( unixFileMutexHeld(pFile) );
+   p->pNext = pInode->pUnused;
+   pInode->pUnused = p;
+   pFile->h = -1;
+   pFile->pPreallocatedUnused = 0;
+-  nUnusedFd++;
+ }
+ 
+ /*
+@@ -33083,8 +34232,8 @@
+   if( pFile->eFileLock<=eFileLock ){
+     return SQLITE_OK;
+   }
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+   assert( pInode->nShared!=0 );
+   if( pFile->eFileLock>SHARED_LOCK ){
+     assert( pInode->eFileLock==pFile->eFileLock );
+@@ -33210,14 +34359,14 @@
+     */
+     pInode->nLock--;
+     assert( pInode->nLock>=0 );
+-    if( pInode->nLock==0 ){
+-      closePendingFds(pFile);
+-    }
++    if( pInode->nLock==0 ) closePendingFds(pFile);
+   }
+ 
+ end_unlock:
+-  unixLeaveMutex();
+-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
++  sqlite3_mutex_leave(pInode->pLockMutex);
++  if( rc==SQLITE_OK ){
++    pFile->eFileLock = eFileLock;
++  }
+   return rc;
+ }
+ 
+@@ -33288,8 +34437,12 @@
+ static int unixClose(sqlite3_file *id){
+   int rc = SQLITE_OK;
+   unixFile *pFile = (unixFile *)id;
++  unixInodeInfo *pInode = pFile->pInode;
++
++  assert( pInode!=0 );
+   verifyDbFile(pFile);
+   unixUnlock(id, NO_LOCK);
++  assert( unixFileMutexNotheld(pFile) );
+   unixEnterMutex();
+ 
+   /* unixFile.pInode is always valid here. Otherwise, a different close
+@@ -33296,7 +34449,8 @@
+   ** routine (e.g. nolockClose()) would be called instead.
+   */
+   assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
+-  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
++  sqlite3_mutex_enter(pInode->pLockMutex);
++  if( pInode->nLock ){
+     /* If there are outstanding locks, do not actually close the file just
+     ** yet because that would clear those locks.  Instead, add the file
+     ** descriptor to pInode->pUnused list.  It will be automatically closed 
+@@ -33304,6 +34458,7 @@
+     */
+     setPendingFd(pFile);
+   }
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   releaseInodeInfo(pFile);
+   rc = closeUnixFile(id);
+   unixLeaveMutex();
+@@ -33901,6 +35056,7 @@
+     unixFile *pFile = (unixFile*)id;
+     semXUnlock(id, NO_LOCK);
+     assert( pFile );
++    assert( unixFileMutexNotheld(pFile) );
+     unixEnterMutex();
+     releaseInodeInfo(pFile);
+     unixLeaveMutex();
+@@ -34015,8 +35171,7 @@
+     *pResOut = 1;
+     return SQLITE_OK;
+   }
+-  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
+-  
++  sqlite3_mutex_enter(pFile->pInode->pLockMutex);
+   /* Check if a thread in this process holds such a lock */
+   if( pFile->pInode->eFileLock>SHARED_LOCK ){
+     reserved = 1;
+@@ -34040,7 +35195,7 @@
+     }
+   }
+   
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pFile->pInode->pLockMutex);
+   OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
+   
+   *pResOut = reserved;
+@@ -34103,8 +35258,8 @@
+   
+   /* This mutex is needed because pFile->pInode is shared across threads
+   */
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+ 
+   /* If some thread using this PID has a lock via a different unixFile*
+   ** handle that precludes the requested lock, return BUSY.
+@@ -34240,7 +35395,7 @@
+   }
+   
+ afp_end_lock:
+-  unixLeaveMutex();
++  sqlite3_mutex_leave(pInode->pLockMutex);
+   OSTRACE(("LOCK    %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), 
+          rc==SQLITE_OK ? "ok" : "failed"));
+   return rc;
+@@ -34272,8 +35427,8 @@
+   if( pFile->eFileLock<=eFileLock ){
+     return SQLITE_OK;
+   }
+-  unixEnterMutex();
+   pInode = pFile->pInode;
++  sqlite3_mutex_enter(pInode->pLockMutex);
+   assert( pInode->nShared!=0 );
+   if( pFile->eFileLock>SHARED_LOCK ){
+     assert( pInode->eFileLock==pFile->eFileLock );
+@@ -34342,14 +35497,14 @@
+     if( rc==SQLITE_OK ){
+       pInode->nLock--;
+       assert( pInode->nLock>=0 );
+-      if( pInode->nLock==0 ){
+-        closePendingFds(pFile);
+-      }
++      if( pInode->nLock==0 ) closePendingFds(pFile);
+     }
+   }
+   
+-  unixLeaveMutex();
+-  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
++  sqlite3_mutex_leave(pInode->pLockMutex);
++  if( rc==SQLITE_OK ){
++    pFile->eFileLock = eFileLock;
++  }
+   return rc;
+ }
+ 
+@@ -34361,14 +35516,20 @@
+   unixFile *pFile = (unixFile*)id;
+   assert( id!=0 );
+   afpUnlock(id, NO_LOCK);
++  assert( unixFileMutexNotheld(pFile) );
+   unixEnterMutex();
+-  if( pFile->pInode && pFile->pInode->nLock ){
+-    /* If there are outstanding locks, do not actually close the file just
+-    ** yet because that would clear those locks.  Instead, add the file
+-    ** descriptor to pInode->aPending.  It will be automatically closed when
+-    ** the last lock is cleared.
+-    */
+-    setPendingFd(pFile);
++  if( pFile->pInode ){
++    unixInodeInfo *pInode = pFile->pInode;
++    sqlite3_mutex_enter(pInode->pLockMutex);
++    if( pInode->nLock ){
++      /* If there are outstanding locks, do not actually close the file just
++      ** yet because that would clear those locks.  Instead, add the file
++      ** descriptor to pInode->aPending.  It will be automatically closed when
++      ** the last lock is cleared.
++      */
++      setPendingFd(pFile);
++    }
++    sqlite3_mutex_leave(pInode->pLockMutex);
+   }
+   releaseInodeInfo(pFile);
+   sqlite3_free(pFile->lockingContext);
+@@ -35023,7 +36184,7 @@
+       do{
+         err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
+       }while( err==EINTR );
+-      if( err ) return SQLITE_IOERR_WRITE;
++      if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE;
+ #else
+       /* If the OS does not have posix_fallocate(), fake it. Write a 
+       ** single byte to the last byte in each block that falls entirely
+@@ -35388,18 +36549,18 @@
+ **
+ ** The following fields are read-only after the object is created:
+ ** 
+-**      fid
++**      hShm
+ **      zFilename
+ **
+-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
++** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
+ ** unixMutexHeld() is true when reading or writing any other field
+ ** in this structure.
+ */
+ struct unixShmNode {
+   unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
+-  sqlite3_mutex *mutex;      /* Mutex to access this object */
++  sqlite3_mutex *pShmMutex;  /* Mutex to access this object */
+   char *zFilename;           /* Name of the mmapped file */
+-  int h;                     /* Open file descriptor */
++  int hShm;                  /* Open file descriptor */
+   int szRegion;              /* Size of shared-memory regions */
+   u16 nRegion;               /* Size of array apRegion */
+   u8 isReadonly;             /* True if read-only */
+@@ -35421,16 +36582,16 @@
+ ** The following fields are initialized when this object is created and
+ ** are read-only thereafter:
+ **
+-**    unixShm.pFile
++**    unixShm.pShmNode
+ **    unixShm.id
+ **
+-** All other fields are read/write.  The unixShm.pFile->mutex must be held
+-** while accessing any read/write fields.
++** All other fields are read/write.  The unixShm.pShmNode->pShmMutex must
++** be held while accessing any read/write fields.
+ */
+ struct unixShm {
+   unixShmNode *pShmNode;     /* The underlying unixShmNode object */
+   unixShm *pNext;            /* Next unixShm with the same unixShmNode */
+-  u8 hasMutex;               /* True if holding the unixShmNode mutex */
++  u8 hasMutex;               /* True if holding the unixShmNode->pShmMutex */
+   u8 id;                     /* Id of this connection within its unixShmNode */
+   u16 sharedMask;            /* Mask of shared locks held */
+   u16 exclMask;              /* Mask of exclusive locks held */
+@@ -35460,7 +36621,8 @@
+ 
+   /* Access to the unixShmNode object is serialized by the caller */
+   pShmNode = pFile->pInode->pShmNode;
+-  assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
++  assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
++  assert( pShmNode->nRef>0 || unixMutexHeld() );
+ 
+   /* Shared locks never span more than one byte */
+   assert( n==1 || lockType!=F_RDLCK );
+@@ -35468,13 +36630,13 @@
+   /* Locks are within range */
+   assert( n>=1 && n<=SQLITE_SHM_NLOCK );
+ 
+-  if( pShmNode->h>=0 ){
++  if( pShmNode->hShm>=0 ){
+     /* Initialize the locking parameters */
+     f.l_type = lockType;
+     f.l_whence = SEEK_SET;
+     f.l_start = ofst;
+     f.l_len = n;
+-    rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
++    rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
+     rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
+   }
+ 
+@@ -35546,9 +36708,9 @@
+     int nShmPerMap = unixShmRegionPerMap();
+     int i;
+     assert( p->pInode==pFd->pInode );
+-    sqlite3_mutex_free(p->mutex);
++    sqlite3_mutex_free(p->pShmMutex);
+     for(i=0; i<p->nRegion; i+=nShmPerMap){
+-      if( p->h>=0 ){
++      if( p->hShm>=0 ){
+         osMunmap(p->apRegion[i], p->szRegion);
+       }else{
+         sqlite3_free(p->apRegion[i]);
+@@ -35555,9 +36717,9 @@
+       }
+     }
+     sqlite3_free(p->apRegion);
+-    if( p->h>=0 ){
+-      robust_close(pFd, p->h, __LINE__);
+-      p->h = -1;
++    if( p->hShm>=0 ){
++      robust_close(pFd, p->hShm, __LINE__);
++      p->hShm = -1;
+     }
+     p->pInode->pShmNode = 0;
+     sqlite3_free(p);
+@@ -35599,7 +36761,7 @@
+   lock.l_start = UNIX_SHM_DMS;
+   lock.l_len = 1;
+   lock.l_type = F_WRLCK;
+-  if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
++  if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
+     rc = SQLITE_IOERR_LOCK;
+   }else if( lock.l_type==F_UNLCK ){
+     if( pShmNode->isReadonly ){
+@@ -35607,7 +36769,12 @@
+       rc = SQLITE_READONLY_CANTINIT;
+     }else{
+       rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
+-      if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
++      /* The first connection to attach must truncate the -shm file.  We
++      ** truncate to 3 bytes (an arbitrary small number, less than the
++      ** -shm header size) rather than 0 as a system debugging aid, to
++      ** help detect if a -shm file truncation is legitimate or is the work
++      ** or a rogue process. */
++      if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
+         rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
+       }
+     }
+@@ -35674,6 +36841,7 @@
+   /* Check to see if a unixShmNode object already exists. Reuse an existing
+   ** one if present. Create a new one if necessary.
+   */
++  assert( unixFileMutexNotheld(pDbFd) );
+   unixEnterMutex();
+   pInode = pDbFd->pInode;
+   pShmNode = pInode->pShmNode;
+@@ -35712,12 +36880,12 @@
+     sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
+     sqlite3FileSuffix3(pDbFd->zPath, zShm);
+ #endif
+-    pShmNode->h = -1;
++    pShmNode->hShm = -1;
+     pDbFd->pInode->pShmNode = pShmNode;
+     pShmNode->pInode = pDbFd->pInode;
+     if( sqlite3GlobalConfig.bCoreMutex ){
+-      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+-      if( pShmNode->mutex==0 ){
++      pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++      if( pShmNode->pShmMutex==0 ){
+         rc = SQLITE_NOMEM_BKPT;
+         goto shm_open_err;
+       }
+@@ -35725,11 +36893,11 @@
+ 
+     if( pInode->bProcessLock==0 ){
+       if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+-        pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
++        pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
+       }
+-      if( pShmNode->h<0 ){
+-        pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+-        if( pShmNode->h<0 ){
++      if( pShmNode->hShm<0 ){
++        pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
++        if( pShmNode->hShm<0 ){
+           rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
+           goto shm_open_err;
+         }
+@@ -35740,7 +36908,7 @@
+       ** is owned by the same user that owns the original database.  Otherwise,
+       ** the original owner will not be able to connect.
+       */
+-      robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
++      robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
+ 
+       rc = unixLockSharedMemory(pDbFd, pShmNode);
+       if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
+@@ -35760,13 +36928,13 @@
+   ** the cover of the unixEnterMutex() mutex and the pointer from the
+   ** new (struct unixShm) object to the pShmNode has been set. All that is
+   ** left to do is to link the new object into the linked list starting
+-  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
+-  ** mutex.
++  ** at pShmNode->pFirst. This must be done while holding the
++  ** pShmNode->pShmMutex.
+   */
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   p->pNext = pShmNode->pFirst;
+   pShmNode->pFirst = p;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+   return rc;
+ 
+   /* Jump here on any error */
+@@ -35818,7 +36986,7 @@
+ 
+   p = pDbFd->pShm;
+   pShmNode = p->pShmNode;
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   if( pShmNode->isUnlocked ){
+     rc = unixLockSharedMemory(pDbFd, pShmNode);
+     if( rc!=SQLITE_OK ) goto shmpage_out;
+@@ -35826,8 +36994,8 @@
+   }
+   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
+   assert( pShmNode->pInode==pDbFd->pInode );
+-  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
+-  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
++  assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
++  assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
+ 
+   /* Minimum number of regions required to be mapped. */
+   nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
+@@ -35839,12 +37007,12 @@
+ 
+     pShmNode->szRegion = szRegion;
+ 
+-    if( pShmNode->h>=0 ){
++    if( pShmNode->hShm>=0 ){
+       /* The requested region is not mapped into this processes address space.
+       ** Check to see if it has been allocated (i.e. if the wal-index file is
+       ** large enough to contain the requested region).
+       */
+-      if( osFstat(pShmNode->h, &sStat) ){
++      if( osFstat(pShmNode->hShm, &sStat) ){
+         rc = SQLITE_IOERR_SHMSIZE;
+         goto shmpage_out;
+       }
+@@ -35872,7 +37040,7 @@
+           assert( (nByte % pgsz)==0 );
+           for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
+             int x = 0;
+-            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
++            if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
+               const char *zFile = pShmNode->zFilename;
+               rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
+               goto shmpage_out;
+@@ -35895,10 +37063,10 @@
+       int nMap = szRegion*nShmPerMap;
+       int i;
+       void *pMem;
+-      if( pShmNode->h>=0 ){
++      if( pShmNode->hShm>=0 ){
+         pMem = osMmap(0, nMap,
+             pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
+-            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
++            MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
+         );
+         if( pMem==MAP_FAILED ){
+           rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
+@@ -35905,12 +37073,12 @@
+           goto shmpage_out;
+         }
+       }else{
+-        pMem = sqlite3_malloc64(szRegion);
++        pMem = sqlite3_malloc64(nMap);
+         if( pMem==0 ){
+           rc = SQLITE_NOMEM_BKPT;
+           goto shmpage_out;
+         }
+-        memset(pMem, 0, szRegion);
++        memset(pMem, 0, nMap);
+       }
+ 
+       for(i=0; i<nShmPerMap; i++){
+@@ -35927,7 +37095,7 @@
+     *pp = 0;
+   }
+   if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+   return rc;
+ }
+ 
+@@ -35961,12 +37129,12 @@
+        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
+        || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
+   assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
+-  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
+-  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
++  assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
++  assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
+ 
+   mask = (1<<(ofst+n)) - (1<<ofst);
+   assert( n>1 || mask==(1<<ofst) );
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   if( flags & SQLITE_SHM_UNLOCK ){
+     u16 allMask = 0; /* Mask of locks held by siblings */
+ 
+@@ -36039,7 +37207,7 @@
+       }
+     }
+   }
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+   OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
+            p->id, osGetpid(0), p->sharedMask, p->exclMask));
+   return rc;
+@@ -36056,6 +37224,9 @@
+ ){
+   UNUSED_PARAMETER(fd);
+   sqlite3MemoryBarrier();         /* compiler-defined memory barrier */
++  assert( fd->pMethods->xLock==nolockLock 
++       || unixFileMutexNotheld((unixFile*)fd) 
++  );
+   unixEnterMutex();               /* Also mutex, for redundancy */
+   unixLeaveMutex();
+ }
+@@ -36086,7 +37257,7 @@
+ 
+   /* Remove connection p from the set of connections associated
+   ** with pShmNode */
+-  sqlite3_mutex_enter(pShmNode->mutex);
++  sqlite3_mutex_enter(pShmNode->pShmMutex);
+   for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
+   *pp = p->pNext;
+ 
+@@ -36093,15 +37264,16 @@
+   /* Free the connection p */
+   sqlite3_free(p);
+   pDbFd->pShm = 0;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  sqlite3_mutex_leave(pShmNode->pShmMutex);
+ 
+   /* If pShmNode->nRef has reached 0, then close the underlying
+   ** shared-memory file, too */
++  assert( unixFileMutexNotheld(pDbFd) );
+   unixEnterMutex();
+   assert( pShmNode->nRef>0 );
+   pShmNode->nRef--;
+   if( pShmNode->nRef==0 ){
+-    if( deleteFlag && pShmNode->h>=0 ){
++    if( deleteFlag && pShmNode->hShm>=0 ){
+       osUnlink(pShmNode->zFilename);
+     }
+     unixShmPurge(pDbFd);
+@@ -36423,7 +37595,7 @@
+ IOMETHODS(
+   nolockIoFinder,           /* Finder function name */
+   nolockIoMethods,          /* sqlite3_io_methods object name */
+-  3,                        /* shared memory is disabled */
++  3,                        /* shared memory and mmap are enabled */
+   nolockClose,              /* xClose method */
+   nolockLock,               /* xLock method */
+   nolockUnlock,             /* xUnlock method */
+@@ -36919,7 +38091,7 @@
+   **
+   ** Even if a subsequent open() call does succeed, the consequences of
+   ** not searching for a reusable file descriptor are not dire.  */
+-  if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){
++  if( inodeList!=0 && 0==osStat(zPath, &sStat) ){
+     unixInodeInfo *pInode;
+ 
+     pInode = inodeList;
+@@ -36929,12 +38101,14 @@
+     }
+     if( pInode ){
+       UnixUnusedFd **pp;
++      assert( sqlite3_mutex_notheld(pInode->pLockMutex) );
++      sqlite3_mutex_enter(pInode->pLockMutex);
+       for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
+       pUnused = *pp;
+       if( pUnused ){
+-        nUnusedFd--;
+         *pp = pUnused->pNext;
+       }
++      sqlite3_mutex_leave(pInode->pLockMutex);
+     }
+   }
+   unixLeaveMutex();
+@@ -39517,8 +40691,7 @@
+   int nFetchOut;                /* Number of outstanding xFetch references */
+   HANDLE hMap;                  /* Handle for accessing memory mapping */
+   void *pMapRegion;             /* Area memory mapped */
+-  sqlite3_int64 mmapSize;       /* Usable size of mapped region */
+-  sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
++  sqlite3_int64 mmapSize;       /* Size of mapped region */
+   sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
+ #endif
+ };
+@@ -39549,22 +40722,6 @@
+ #endif
+ 
+ /*
+- * The value used with sqlite3_win32_set_directory() to specify that
+- * the data directory should be changed.
+- */
+-#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
+-#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
+-#endif
+-
+-/*
+- * The value used with sqlite3_win32_set_directory() to specify that
+- * the temporary directory should be changed.
+- */
+-#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
+-#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
+-#endif
+-
+-/*
+  * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
+  * various Win32 API heap functions instead of our own.
+  */
+@@ -41160,13 +42317,13 @@
+ }
+ 
+ /*
+-** This function sets the data directory or the temporary directory based on
+-** the provided arguments.  The type argument must be 1 in order to set the
+-** data directory or 2 in order to set the temporary directory.  The zValue
+-** argument is the name of the directory to use.  The return value will be
+-** SQLITE_OK if successful.
++** This function is the same as sqlite3_win32_set_directory (below); however,
++** it accepts a UTF-8 string.
+ */
+-SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
++SQLITE_API int sqlite3_win32_set_directory8(
++  unsigned long type, /* Identifier for directory being set or reset */
++  const char *zValue  /* New value for directory being set or reset */
++){
+   char **ppDirectory = 0;
+ #ifndef SQLITE_OMIT_AUTOINIT
+   int rc = sqlite3_initialize();
+@@ -41182,15 +42339,15 @@
+   );
+   assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
+   if( ppDirectory ){
+-    char *zValueUtf8 = 0;
++    char *zCopy = 0;
+     if( zValue && zValue[0] ){
+-      zValueUtf8 = winUnicodeToUtf8(zValue);
+-      if ( zValueUtf8==0 ){
++      zCopy = sqlite3_mprintf("%s", zValue);
++      if ( zCopy==0 ){
+         return SQLITE_NOMEM_BKPT;
+       }
+     }
+     sqlite3_free(*ppDirectory);
+-    *ppDirectory = zValueUtf8;
++    *ppDirectory = zCopy;
+     return SQLITE_OK;
+   }
+   return SQLITE_ERROR;
+@@ -41197,6 +42354,39 @@
+ }
+ 
+ /*
++** This function is the same as sqlite3_win32_set_directory (below); however,
++** it accepts a UTF-16 string.
++*/
++SQLITE_API int sqlite3_win32_set_directory16(
++  unsigned long type, /* Identifier for directory being set or reset */
++  const void *zValue  /* New value for directory being set or reset */
++){
++  int rc;
++  char *zUtf8 = 0;
++  if( zValue ){
++    zUtf8 = sqlite3_win32_unicode_to_utf8(zValue);
++    if( zUtf8==0 ) return SQLITE_NOMEM_BKPT;
++  }
++  rc = sqlite3_win32_set_directory8(type, zUtf8);
++  if( zUtf8 ) sqlite3_free(zUtf8);
++  return rc;
++}
++
++/*
++** This function sets the data directory or the temporary directory based on
++** the provided arguments.  The type argument must be 1 in order to set the
++** data directory or 2 in order to set the temporary directory.  The zValue
++** argument is the name of the directory to use.  The return value will be
++** SQLITE_OK if successful.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++){
++  return sqlite3_win32_set_directory16(type, zValue);
++}
++
++/*
+ ** The return value of winGetLastErrorMsg
+ ** is zero if the error message fits in the buffer, or non-zero
+ ** otherwise (if the message was truncated).
+@@ -42120,6 +43310,29 @@
+   winFile *pFile = (winFile*)id;  /* File handle object */
+   int rc = SQLITE_OK;             /* Return code for this function */
+   DWORD lastErrno;
++#if SQLITE_MAX_MMAP_SIZE>0
++  sqlite3_int64 oldMmapSize;
++  if( pFile->nFetchOut>0 ){
++    /* File truncation is a no-op if there are outstanding memory mapped
++    ** pages.  This is because truncating the file means temporarily unmapping
++    ** the file, and that might delete memory out from under existing cursors.
++    **
++    ** This can result in incremental vacuum not truncating the file,
++    ** if there is an active read cursor when the incremental vacuum occurs.
++    ** No real harm comes of this - the database file is not corrupted,
++    ** though some folks might complain that the file is bigger than it
++    ** needs to be.
++    **
++    ** The only feasible work-around is to defer the truncation until after
++    ** all references to memory-mapped content are closed.  That is doable,
++    ** but involves adding a few branches in the common write code path which
++    ** could slow down normal operations slightly.  Hence, we have decided for
++    ** now to simply make trancations a no-op if there are pending reads.  We
++    ** can maybe revisit this decision in the future.
++    */
++    return SQLITE_OK;
++  }
++#endif
+ 
+   assert( pFile );
+   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
+@@ -42135,6 +43348,15 @@
+     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
+   }
+ 
++#if SQLITE_MAX_MMAP_SIZE>0
++  if( pFile->pMapRegion ){
++    oldMmapSize = pFile->mmapSize;
++  }else{
++    oldMmapSize = 0;
++  }
++  winUnmapfile(pFile);
++#endif
++
+   /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
+   if( winSeekFile(pFile, nByte) ){
+     rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
+@@ -42147,12 +43369,12 @@
+   }
+ 
+ #if SQLITE_MAX_MMAP_SIZE>0
+-  /* If the file was truncated to a size smaller than the currently
+-  ** mapped region, reduce the effective mapping size as well. SQLite will
+-  ** use read() and write() to access data beyond this point from now on.
+-  */
+-  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
+-    pFile->mmapSize = nByte;
++  if( rc==SQLITE_OK && oldMmapSize>0 ){
++    if( oldMmapSize>nByte ){
++      winMapfile(pFile, -1);
++    }else{
++      winMapfile(pFile, oldMmapSize);
++    }
+   }
+ #endif
+ 
+@@ -43538,9 +44760,9 @@
+ static int winUnmapfile(winFile *pFile){
+   assert( pFile!=0 );
+   OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
+-           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
++           "mmapSize=%lld, mmapSizeMax=%lld\n",
+            osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
+-           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
++           pFile->mmapSize, pFile->mmapSizeMax));
+   if( pFile->pMapRegion ){
+     if( !osUnmapViewOfFile(pFile->pMapRegion) ){
+       pFile->lastErrno = osGetLastError();
+@@ -43552,7 +44774,6 @@
+     }
+     pFile->pMapRegion = 0;
+     pFile->mmapSize = 0;
+-    pFile->mmapSizeActual = 0;
+   }
+   if( pFile->hMap!=NULL ){
+     if( !osCloseHandle(pFile->hMap) ){
+@@ -43663,7 +44884,6 @@
+     }
+     pFd->pMapRegion = pNew;
+     pFd->mmapSize = nMap;
+-    pFd->mmapSizeActual = nMap;
+   }
+ 
+   OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+@@ -44465,7 +45685,6 @@
+   pFile->hMap = NULL;
+   pFile->pMapRegion = 0;
+   pFile->mmapSize = 0;
+-  pFile->mmapSizeActual = 0;
+   pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+ #endif
+ 
+@@ -45340,8 +46559,8 @@
+ ** This file also implements interface sqlite3_serialize() and
+ ** sqlite3_deserialize().
+ */
++/* #include "sqliteInt.h" */
+ #ifdef SQLITE_ENABLE_DESERIALIZE
+-/* #include "sqliteInt.h" */
+ 
+ /*
+ ** Forward declaration of objects used by this utility
+@@ -46362,7 +47581,7 @@
+ **   The PCache.pSynced variable is used to optimize searching for a dirty
+ **   page to eject from the cache mid-transaction. It is better to eject
+ **   a page that does not require a journal sync than one that does. 
+-**   Therefore, pSynced is maintained to that it *almost* always points
++**   Therefore, pSynced is maintained so that it *almost* always points
+ **   to either the oldest page in the pDirty/pDirtyTail list that has a
+ **   clear PGHDR_NEED_SYNC flag or to a page that is older than this one
+ **   (so that the right page to eject can be found by following pDirtyPrev
+@@ -47186,6 +48405,15 @@
+   return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
+ }
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
++/* 
++** Return true if there are one or more dirty pages in the cache. Else false.
++*/
++SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
++  return (pCache->pDirty!=0);
++}
++#endif
++
+ #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
+ /*
+ ** For all dirty pages currently in the cache, invoke the specified
+@@ -47309,7 +48537,8 @@
+ };
+ 
+ /*
+-** A page is pinned if it is no on the LRU list
++** A page is pinned if it is not on the LRU list.  To be "pinned" means
++** that the page is in active use and must not be deallocated.
+ */
+ #define PAGE_IS_PINNED(p)    ((p)->pLruNext==0)
+ #define PAGE_IS_UNPINNED(p)  ((p)->pLruNext!=0)
+@@ -48589,30 +49818,23 @@
+ #define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
+ 
+ /*
+-** Turn bulk memory into a RowSet object.  N bytes of memory
+-** are available at pSpace.  The db pointer is used as a memory context
+-** for any subsequent allocations that need to occur.
+-** Return a pointer to the new RowSet object.
+-**
+-** It must be the case that N is sufficient to make a Rowset.  If not
+-** an assertion fault occurs.
+-** 
+-** If N is larger than the minimum, use the surplus as an initial
+-** allocation of entries available to be filled.
++** Allocate a RowSet object.  Return NULL if a memory allocation
++** error occurs.
+ */
+-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
+-  RowSet *p;
+-  assert( N >= ROUND8(sizeof(*p)) );
+-  p = pSpace;
+-  p->pChunk = 0;
+-  p->db = db;
+-  p->pEntry = 0;
+-  p->pLast = 0;
+-  p->pForest = 0;
+-  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+-  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
+-  p->rsFlags = ROWSET_SORTED;
+-  p->iBatch = 0;
++SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){
++  RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p));
++  if( p ){
++    int N = sqlite3DbMallocSize(db, p);
++    p->pChunk = 0;
++    p->db = db;
++    p->pEntry = 0;
++    p->pLast = 0;
++    p->pForest = 0;
++    p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
++    p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
++    p->rsFlags = ROWSET_SORTED;
++    p->iBatch = 0;
++  }
+   return p;
+ }
+ 
+@@ -48621,7 +49843,8 @@
+ ** the RowSet has allocated over its lifetime.  This routine is
+ ** the destructor for the RowSet.
+ */
+-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
++SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){
++  RowSet *p = (RowSet*)pArg;
+   struct RowSetChunk *pChunk, *pNextChunk;
+   for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
+     pNextChunk = pChunk->pNextChunk;
+@@ -48636,6 +49859,16 @@
+ }
+ 
+ /*
++** Deallocate all chunks from a RowSet.  This frees all memory that
++** the RowSet has allocated over its lifetime.  This routine is
++** the destructor for the RowSet.
++*/
++SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){
++  sqlite3RowSetClear(pArg);
++  sqlite3DbFree(((RowSet*)pArg)->db, pArg);
++}
++
++/*
+ ** Allocate a new RowSetEntry object that is associated with the
+ ** given RowSet.  Return a pointer to the new and completely uninitialized
+ ** objected.
+@@ -49122,6 +50355,8 @@
+ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
+ SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
+ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
++SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot);
++SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal);
+ #endif
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -49943,19 +51178,30 @@
+ */
+ #define isOpen(pFd) ((pFd)->pMethods!=0)
+ 
++#ifdef SQLITE_DIRECT_OVERFLOW_READ
+ /*
+-** Return true if this pager uses a write-ahead log to read page pgno.
+-** Return false if the pager reads pgno directly from the database.
++** Return true if page pgno can be read directly from the database file
++** by the b-tree layer. This is the case if:
++**
++**   * the database file is open,
++**   * there are no dirty pages in the cache, and
++**   * the desired page is not currently in the wal file.
+ */
+-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
+-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
+-  u32 iRead = 0;
+-  int rc;
+-  if( pPager->pWal==0 ) return 0;
+-  rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+-  return rc || iRead;
++SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
++  if( pPager->fd->pMethods==0 ) return 0;
++  if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
++#ifndef SQLITE_OMIT_WAL
++  if( pPager->pWal ){
++    u32 iRead = 0;
++    int rc;
++    rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
++    return (rc==SQLITE_OK && iRead==0);
++  }
++#endif
++  return 1;
+ }
+ #endif
++
+ #ifndef SQLITE_OMIT_WAL
+ # define pagerUseWal(x) ((x)->pWal!=0)
+ #else
+@@ -50115,8 +51361,12 @@
+ ** to "print *pPager" in gdb:
+ **
+ ** (gdb) printf "%s", print_pager_state(pPager)
++**
++** This routine has external linkage in order to suppress compiler warnings
++** about an unused function.  It is enclosed within SQLITE_DEBUG and so does
++** not appear in normal builds.
+ */
+-static char *print_pager_state(Pager *p){
++char *print_pager_state(Pager *p){
+   static char zRet[1024];
+ 
+   sqlite3_snprintf(1024, zRet,
+@@ -50882,7 +52132,6 @@
+ ** Return the pPager->iDataVersion value
+ */
+ SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
+-  assert( pPager->eState>PAGER_OPEN );
+   return pPager->iDataVersion;
+ }
+ 
+@@ -55500,9 +56749,10 @@
+     ** backup in progress needs to be restarted.  */
+     sqlite3BackupRestart(pPager->pBackup);
+   }else{
++    PgHdr *pList;
+     if( pagerUseWal(pPager) ){
+-      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
+       PgHdr *pPageOne = 0;
++      pList = sqlite3PcacheDirtyList(pPager->pPCache);
+       if( pList==0 ){
+         /* Must have at least one page for the WAL commit flag.
+         ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
+@@ -55523,14 +56773,14 @@
+       ** should be used.  No rollback journal is created if batch-atomic-write
+       ** is enabled.
+       */
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+       sqlite3_file *fd = pPager->fd;
+-#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+-      const int bBatch = zMaster==0    /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
++      int bBatch = zMaster==0    /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
+         && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
+         && !pPager->noSync
+         && sqlite3JournalIsInMemory(pPager->jfd);
+ #else
+-# define bBatch 0
++#     define bBatch 0
+ #endif
+ 
+ #ifdef SQLITE_ENABLE_ATOMIC_WRITE
+@@ -55582,15 +56832,16 @@
+           }
+         }
+       }
+-#else 
++#else  /* SQLITE_ENABLE_ATOMIC_WRITE */
+ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+       if( zMaster ){
+         rc = sqlite3JournalCreate(pPager->jfd);
+         if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++        assert( bBatch==0 );
+       }
+ #endif
+       rc = pager_incr_changecounter(pPager, 0);
+-#endif
++#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */
+       if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+   
+       /* Write the master journal name into the journal file. If a master 
+@@ -55614,24 +56865,36 @@
+       rc = syncJournal(pPager, 0);
+       if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ 
++      pList = sqlite3PcacheDirtyList(pPager->pPCache);
++#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+       if( bBatch ){
+-        /* The pager is now in DBMOD state. But regardless of what happens
+-        ** next, attempting to play the journal back into the database would
+-        ** be unsafe. Close it now to make sure that does not happen.  */
+-        sqlite3OsClose(pPager->jfd);
+         rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
+-        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-      }
+-      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
+-      if( bBatch ){
+         if( rc==SQLITE_OK ){
+-          rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
++          rc = pager_write_pagelist(pPager, pList);
++          if( rc==SQLITE_OK ){
++            rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
++          }
++          if( rc!=SQLITE_OK ){
++            sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
++          }
+         }
+-        if( rc!=SQLITE_OK ){
+-          sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
++
++        if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){
++          rc = sqlite3JournalCreate(pPager->jfd);
++          if( rc!=SQLITE_OK ){
++            sqlite3OsClose(pPager->jfd);
++            goto commit_phase_one_exit;
++          }
++          bBatch = 0;
++        }else{
++          sqlite3OsClose(pPager->jfd);
+         }
+       }
++#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+ 
++      if( bBatch==0 ){
++        rc = pager_write_pagelist(pPager, pList);
++      }
+       if( rc!=SQLITE_OK ){
+         assert( rc!=SQLITE_IOERR_BLOCKED );
+         goto commit_phase_one_exit;
+@@ -56122,7 +57385,11 @@
+   void (*xCodecFree)(void*),
+   void *pCodec
+ ){
+-  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
++  if( pPager->xCodecFree ){
++    pPager->xCodecFree(pPager->pCodec);
++  }else{
++    pager_reset(pPager);
++  }
+   pPager->xCodec = pPager->memDb ? 0 : xCodec;
+   pPager->xCodecSizeChng = xCodecSizeChng;
+   pPager->xCodecFree = xCodecFree;
+@@ -56383,13 +57650,6 @@
+ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
+   u8 eOld = pPager->journalMode;    /* Prior journalmode */
+ 
+-#ifdef SQLITE_DEBUG
+-  /* The print_pager_state() routine is intended to be used by the debugger
+-  ** only.  We invoke it once here to suppress a compiler warning. */
+-  print_pager_state(pPager);
+-#endif
+-
+-
+   /* The eMode parameter is always valid */
+   assert(      eMode==PAGER_JOURNALMODE_DELETE
+             || eMode==PAGER_JOURNALMODE_TRUNCATE
+@@ -56758,6 +58018,38 @@
+   }
+   return rc;
+ }
++
++/*
++** The caller currently has a read transaction open on the database.
++** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise,
++** this function takes a SHARED lock on the CHECKPOINTER slot and then
++** checks if the snapshot passed as the second argument is still 
++** available. If so, SQLITE_OK is returned.
++**
++** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
++** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
++** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
++** lock is released before returning.
++*/
++SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){
++  int rc;
++  if( pPager->pWal ){
++    rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot);
++  }else{
++    rc = SQLITE_ERROR;
++  }
++  return rc;
++}
++
++/*
++** Release a lock obtained by an earlier successful call to
++** sqlite3PagerSnapshotCheck().
++*/
++SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
++  assert( pPager->pWal );
++  return sqlite3WalSnapshotUnlock(pPager->pWal);
++}
++
+ #endif /* SQLITE_ENABLE_SNAPSHOT */
+ #endif /* !SQLITE_OMIT_WAL */
+ 
+@@ -57040,6 +58332,18 @@
+ #endif
+ 
+ /*
++** WAL mode depends on atomic aligned 32-bit loads and stores in a few
++** places.  The following macros try to make this explicit.
++*/
++#if GCC_VESRION>=5004000
++# define AtomicLoad(PTR)       __atomic_load_n((PTR),__ATOMIC_RELAXED)
++# define AtomicStore(PTR,VAL)  __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
++#else
++# define AtomicLoad(PTR)       (*(PTR))
++# define AtomicStore(PTR,VAL)  (*(PTR) = (VAL))
++#endif
++
++/*
+ ** The maximum (and only) versions of the wal and wal-index formats
+ ** that may be interpreted by this version of SQLite.
+ **
+@@ -57661,48 +58965,51 @@
+   return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
+ }
+ 
++/*
++** An instance of the WalHashLoc object is used to describe the location
++** of a page hash table in the wal-index.  This becomes the return value
++** from walHashGet().
++*/
++typedef struct WalHashLoc WalHashLoc;
++struct WalHashLoc {
++  volatile ht_slot *aHash;  /* Start of the wal-index hash table */
++  volatile u32 *aPgno;      /* aPgno[1] is the page of first frame indexed */
++  u32 iZero;                /* One less than the frame number of first indexed*/
++};
++
+ /* 
+ ** Return pointers to the hash table and page number array stored on
+ ** page iHash of the wal-index. The wal-index is broken into 32KB pages
+ ** numbered starting from 0.
+ **
+-** Set output variable *paHash to point to the start of the hash table
+-** in the wal-index file. Set *piZero to one less than the frame 
++** Set output variable pLoc->aHash to point to the start of the hash table
++** in the wal-index file. Set pLoc->iZero to one less than the frame 
+ ** number of the first frame indexed by this hash table. If a
+ ** slot in the hash table is set to N, it refers to frame number 
+-** (*piZero+N) in the log.
++** (pLoc->iZero+N) in the log.
+ **
+-** Finally, set *paPgno so that *paPgno[1] is the page number of the
+-** first frame indexed by the hash table, frame (*piZero+1).
++** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
++** first frame indexed by the hash table, frame (pLoc->iZero+1).
+ */
+ static int walHashGet(
+   Wal *pWal,                      /* WAL handle */
+   int iHash,                      /* Find the iHash'th table */
+-  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
+-  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
+-  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
++  WalHashLoc *pLoc                /* OUT: Hash table location */
+ ){
+   int rc;                         /* Return code */
+-  volatile u32 *aPgno;
+ 
+-  rc = walIndexPage(pWal, iHash, &aPgno);
++  rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
+   assert( rc==SQLITE_OK || iHash>0 );
+ 
+   if( rc==SQLITE_OK ){
+-    u32 iZero;
+-    volatile ht_slot *aHash;
+-
+-    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
++    pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
+     if( iHash==0 ){
+-      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
+-      iZero = 0;
++      pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
++      pLoc->iZero = 0;
+     }else{
+-      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
++      pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
+     }
+-  
+-    *paPgno = &aPgno[-1];
+-    *paHash = aHash;
+-    *piZero = iZero;
++    pLoc->aPgno = &pLoc->aPgno[-1];
+   }
+   return rc;
+ }
+@@ -57748,9 +59055,7 @@
+ ** actually needed.
+ */
+ static void walCleanupHash(Wal *pWal){
+-  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
+-  volatile u32 *aPgno = 0;        /* Page number array for hash table */
+-  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
++  WalHashLoc sLoc;                /* Hash table location */
+   int iLimit = 0;                 /* Zero values greater than this */
+   int nByte;                      /* Number of bytes to zero in aPgno[] */
+   int i;                          /* Used to iterate through aHash[] */
+@@ -57768,16 +59073,16 @@
+   */
+   assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
+   assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
+-  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
++  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+ 
+   /* Zero all hash-table entries that correspond to frame numbers greater
+   ** than pWal->hdr.mxFrame.
+   */
+-  iLimit = pWal->hdr.mxFrame - iZero;
++  iLimit = pWal->hdr.mxFrame - sLoc.iZero;
+   assert( iLimit>0 );
+   for(i=0; i<HASHTABLE_NSLOT; i++){
+-    if( aHash[i]>iLimit ){
+-      aHash[i] = 0;
++    if( sLoc.aHash[i]>iLimit ){
++      sLoc.aHash[i] = 0;
+     }
+   }
+   
+@@ -57784,8 +59089,8 @@
+   /* Zero the entries in the aPgno array that correspond to frames with
+   ** frame numbers greater than pWal->hdr.mxFrame. 
+   */
+-  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
+-  memset((void *)&aPgno[iLimit+1], 0, nByte);
++  nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
++  memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
+ 
+ #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+   /* Verify that the every entry in the mapping region is still reachable
+@@ -57795,10 +59100,10 @@
+     int j;           /* Loop counter */
+     int iKey;        /* Hash key */
+     for(j=1; j<=iLimit; j++){
+-      for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){
+-        if( aHash[iKey]==j ) break;
++      for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
++        if( sLoc.aHash[iKey]==j ) break;
+       }
+-      assert( aHash[iKey]==j );
++      assert( sLoc.aHash[iKey]==j );
+     }
+   }
+ #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
+@@ -57811,11 +59116,9 @@
+ */
+ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
+   int rc;                         /* Return code */
+-  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
+-  volatile u32 *aPgno = 0;        /* Page number array */
+-  volatile ht_slot *aHash = 0;    /* Hash table */
++  WalHashLoc sLoc;                /* Wal-index hash table location */
+ 
+-  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
++  rc = walHashGet(pWal, walFramePage(iFrame), &sLoc);
+ 
+   /* Assuming the wal-index file was successfully mapped, populate the
+   ** page number array and hash table entry.
+@@ -57825,7 +59128,7 @@
+     int idx;                      /* Value to write to hash-table slot */
+     int nCollide;                 /* Number of hash collisions */
+ 
+-    idx = iFrame - iZero;
++    idx = iFrame - sLoc.iZero;
+     assert( idx <= HASHTABLE_NSLOT/2 + 1 );
+     
+     /* If this is the first entry to be added to this hash-table, zero the
+@@ -57832,8 +59135,9 @@
+     ** entire hash table and aPgno[] array before proceeding. 
+     */
+     if( idx==1 ){
+-      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
+-      memset((void*)&aPgno[1], 0, nByte);
++      int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
++                               - (u8 *)&sLoc.aPgno[1]);
++      memset((void*)&sLoc.aPgno[1], 0, nByte);
+     }
+ 
+     /* If the entry in aPgno[] is already set, then the previous writer
+@@ -57842,18 +59146,18 @@
+     ** Remove the remnants of that writers uncommitted transaction from 
+     ** the hash-table before writing any new entries.
+     */
+-    if( aPgno[idx] ){
++    if( sLoc.aPgno[idx] ){
+       walCleanupHash(pWal);
+-      assert( !aPgno[idx] );
++      assert( !sLoc.aPgno[idx] );
+     }
+ 
+     /* Write the aPgno[] array entry and the hash-table slot. */
+     nCollide = idx;
+-    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
++    for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
+       if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
+     }
+-    aPgno[idx] = iPage;
+-    aHash[iKey] = (ht_slot)idx;
++    sLoc.aPgno[idx] = iPage;
++    sLoc.aHash[iKey] = (ht_slot)idx;
+ 
+ #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+     /* Verify that the number of entries in the hash table exactly equals
+@@ -57862,7 +59166,7 @@
+     {
+       int i;           /* Loop counter */
+       int nEntry = 0;  /* Number of entries in the hash table */
+-      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
++      for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; }
+       assert( nEntry==idx );
+     }
+ 
+@@ -57874,10 +59178,12 @@
+     if( (idx&0x3ff)==0 ){
+       int i;           /* Loop counter */
+       for(i=1; i<=idx; i++){
+-        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
+-          if( aHash[iKey]==i ) break;
++        for(iKey=walHash(sLoc.aPgno[i]);
++            sLoc.aHash[iKey];
++            iKey=walNextHash(iKey)){
++          if( sLoc.aHash[iKey]==i ) break;
+         }
+-        assert( aHash[iKey]==i );
++        assert( sLoc.aHash[iKey]==i );
+       }
+     }
+ #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
+@@ -58415,33 +59721,31 @@
+   }
+ 
+   for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
+-    volatile ht_slot *aHash;
+-    u32 iZero;
+-    volatile u32 *aPgno;
++    WalHashLoc sLoc;
+ 
+-    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
++    rc = walHashGet(pWal, i, &sLoc);
+     if( rc==SQLITE_OK ){
+       int j;                      /* Counter variable */
+       int nEntry;                 /* Number of entries in this segment */
+       ht_slot *aIndex;            /* Sorted index for this segment */
+ 
+-      aPgno++;
++      sLoc.aPgno++;
+       if( (i+1)==nSegment ){
+-        nEntry = (int)(iLast - iZero);
++        nEntry = (int)(iLast - sLoc.iZero);
+       }else{
+-        nEntry = (int)((u32*)aHash - (u32*)aPgno);
++        nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
+       }
+-      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
+-      iZero++;
++      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero];
++      sLoc.iZero++;
+   
+       for(j=0; j<nEntry; j++){
+         aIndex[j] = (ht_slot)j;
+       }
+-      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
+-      p->aSegment[i].iZero = iZero;
++      walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry);
++      p->aSegment[i].iZero = sLoc.iZero;
+       p->aSegment[i].nEntry = nEntry;
+       p->aSegment[i].aIndex = aIndex;
+-      p->aSegment[i].aPgno = (u32 *)aPgno;
++      p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
+     }
+   }
+   sqlite3_free(aTmp);
+@@ -58616,7 +59920,6 @@
+     if( pIter
+      && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+     ){
+-      i64 nSize;                    /* Current size of database file */
+       u32 nBackfill = pInfo->nBackfill;
+ 
+       pInfo->nBackfillAttempted = mxSafeFrame;
+@@ -58629,6 +59932,7 @@
+       */
+       if( rc==SQLITE_OK ){
+         i64 nReq = ((i64)mxPage * szPage);
++        i64 nSize;                    /* Current size of database file */
+         rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
+         if( rc==SQLITE_OK && nSize<nReq ){
+           sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+@@ -59336,7 +60640,7 @@
+   }
+ #endif
+   for(i=1; i<WAL_NREADER; i++){
+-    u32 thisMark = pInfo->aReadMark[i];
++    u32 thisMark = AtomicLoad(pInfo->aReadMark+i);
+     if( mxReadMark<=thisMark && thisMark<=mxFrame ){
+       assert( thisMark!=READMARK_NOT_USED );
+       mxReadMark = thisMark;
+@@ -59349,7 +60653,7 @@
+     for(i=1; i<WAL_NREADER; i++){
+       rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
+       if( rc==SQLITE_OK ){
+-        mxReadMark = pInfo->aReadMark[i] = mxFrame;
++        mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
+         mxI = i;
+         walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+         break;
+@@ -59401,9 +60705,9 @@
+   ** we can guarantee that the checkpointer that set nBackfill could not
+   ** see any pages past pWal->hdr.mxFrame, this problem does not come up.
+   */
+-  pWal->minFrame = pInfo->nBackfill+1;
++  pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1;
+   walShmBarrier(pWal);
+-  if( pInfo->aReadMark[mxI]!=mxReadMark
++  if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
+    || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
+   ){
+     walUnlockShared(pWal, WAL_READ_LOCK(mxI));
+@@ -59454,16 +60758,14 @@
+       }else{
+         u32 i = pInfo->nBackfillAttempted;
+         for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
+-          volatile ht_slot *dummy;
+-          volatile u32 *aPgno;      /* Array of page numbers */
+-          u32 iZero;                /* Frame corresponding to aPgno[0] */
++          WalHashLoc sLoc;          /* Hash table location */
+           u32 pgno;                 /* Page number in db file */
+           i64 iDbOff;               /* Offset of db file entry */
+           i64 iWalOff;              /* Offset of wal file entry */
+ 
+-          rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
++          rc = walHashGet(pWal, walFramePage(i), &sLoc);
+           if( rc!=SQLITE_OK ) break;
+-          pgno = aPgno[i-iZero];
++          pgno = sLoc.aPgno[i-sLoc.iZero];
+           iDbOff = (i64)(pgno-1) * szPage;
+ 
+           if( iDbOff+szPage<=szDb ){
+@@ -59504,7 +60806,7 @@
+ **
+ ** If the database contents have changes since the previous read
+ ** transaction, then *pChanged is set to 1 before returning.  The
+-** Pager layer will use this to know that is cache is stale and
++** Pager layer will use this to know that its cache is stale and
+ ** needs to be flushed.
+ */
+ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
+@@ -59566,7 +60868,7 @@
+         /* Check that the wal file has not been wrapped. Assuming that it has
+         ** not, also check that no checkpointer has attempted to checkpoint any
+         ** frames beyond pSnapshot->mxFrame. If either of these conditions are
+-        ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr
++        ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
+         ** with *pSnapshot and set *pChanged as appropriate for opening the
+         ** snapshot.  */
+         if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+@@ -59576,11 +60878,12 @@
+           memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
+           *pChanged = bChanged;
+         }else{
+-          rc = SQLITE_BUSY_SNAPSHOT;
++          rc = SQLITE_ERROR_SNAPSHOT;
+         }
+ 
+         /* Release the shared CKPT lock obtained above. */
+         walUnlockShared(pWal, WAL_CKPT_LOCK);
++        pWal->minFrame = 1;
+       }
+ 
+ 
+@@ -59664,21 +60967,20 @@
+   */
+   iMinHash = walFramePage(pWal->minFrame);
+   for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
+-    volatile ht_slot *aHash;      /* Pointer to hash table */
+-    volatile u32 *aPgno;          /* Pointer to array of page numbers */
+-    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
++    WalHashLoc sLoc;              /* Hash table location */
+     int iKey;                     /* Hash slot index */
+     int nCollide;                 /* Number of hash collisions remaining */
+     int rc;                       /* Error code */
+ 
+-    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
++    rc = walHashGet(pWal, iHash, &sLoc);
+     if( rc!=SQLITE_OK ){
+       return rc;
+     }
+     nCollide = HASHTABLE_NSLOT;
+-    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
+-      u32 iFrame = aHash[iKey] + iZero;
+-      if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){
++    for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
++      u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
++      if( iFrame<=iLast && iFrame>=pWal->minFrame
++       && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
+         assert( iFrame>iRead || CORRUPT_DB );
+         iRead = iFrame;
+       }
+@@ -60553,6 +61855,43 @@
+   if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1;
+   return 0;
+ }
++
++/*
++** The caller currently has a read transaction open on the database.
++** This function takes a SHARED lock on the CHECKPOINTER slot and then
++** checks if the snapshot passed as the second argument is still 
++** available. If so, SQLITE_OK is returned.
++**
++** If the snapshot is not available, SQLITE_ERROR is returned. Or, if
++** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error
++** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER
++** lock is released before returning.
++*/
++SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){
++  int rc;
++  rc = walLockShared(pWal, WAL_CKPT_LOCK);
++  if( rc==SQLITE_OK ){
++    WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot;
++    if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
++     || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted
++    ){
++      rc = SQLITE_ERROR_SNAPSHOT;
++      walUnlockShared(pWal, WAL_CKPT_LOCK);
++    }
++  }
++  return rc;
++}
++
++/*
++** Release a lock obtained by an earlier successful call to
++** sqlite3WalSnapshotCheck().
++*/
++SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){
++  assert( pWal );
++  walUnlockShared(pWal, WAL_CKPT_LOCK);
++}
++
++
+ #endif /* SQLITE_ENABLE_SNAPSHOT */
+ 
+ #ifdef SQLITE_ENABLE_ZIPVFS
+@@ -61482,10 +62821,10 @@
+       skipOk = 0;
+     }
+   }
+-  db->skipBtreeMutex = skipOk;
++  db->noSharedCache = skipOk;
+ }
+ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
+-  if( db->skipBtreeMutex==0 ) btreeEnterAll(db);
++  if( db->noSharedCache==0 ) btreeEnterAll(db);
+ }
+ static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
+   int i;
+@@ -61497,7 +62836,7 @@
+   }
+ }
+ SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
+-  if( db->skipBtreeMutex==0 ) btreeLeaveAll(db);
++  if( db->noSharedCache==0 ) btreeLeaveAll(db);
+ }
+ 
+ #ifndef NDEBUG
+@@ -62462,7 +63801,11 @@
+ ** back to where it ought to be if this routine returns true.
+ */
+ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
+-  return pCur->eState!=CURSOR_VALID;
++  assert( EIGHT_BYTE_ALIGNMENT(pCur)
++       || pCur==sqlite3BtreeFakeValidCursor() );
++  assert( offsetof(BtCursor, eState)==0 );
++  assert( sizeof(pCur->eState)==1 );
++  return CURSOR_VALID != *(u8*)pCur;
+ }
+ 
+ /*
+@@ -64570,6 +65913,10 @@
+ # define setDefaultSyncFlag(pBt,safety_level)
+ #endif
+ 
++/* Forward declaration */
++static int newDatabase(BtShared*);
++
++
+ /*
+ ** Get a reference to pPage1 of the database file.  This will
+ ** also acquire a readlock on that file.
+@@ -64601,6 +65948,9 @@
+   if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
+     nPage = nPageFile;
+   }
++  if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
++    nPage = 0;
++  }
+   if( nPage>0 ){
+     u32 pageSize;
+     u32 usableSize;
+@@ -64699,7 +66049,7 @@
+                                    pageSize-usableSize);
+       return rc;
+     }
+-    if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
++    if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
+       rc = SQLITE_CORRUPT_BKPT;
+       goto page1_init_failed;
+     }
+@@ -64887,7 +66237,7 @@
+ ** when A already has a read lock, we encourage A to give up and let B
+ ** proceed.
+ */
+-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
++SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
+   BtShared *pBt = p->pBt;
+   int rc = SQLITE_OK;
+ 
+@@ -64903,6 +66253,12 @@
+   }
+   assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
+ 
++  if( (p->db->flags & SQLITE_ResetDatabase) 
++   && sqlite3PagerIsreadonly(pBt->pPager)==0 
++  ){
++    pBt->btsFlags &= ~BTS_READ_ONLY;
++  }
++
+   /* Write transactions are not possible on a read-only database */
+   if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
+     rc = SQLITE_READONLY;
+@@ -64962,6 +66318,11 @@
+         rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
+         if( rc==SQLITE_OK ){
+           rc = newDatabase(pBt);
++        }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
++          /* if there was no transaction opened when this function was
++          ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error
++          ** code to SQLITE_BUSY. */
++          rc = SQLITE_BUSY;
+         }
+       }
+     }
+@@ -65013,14 +66374,18 @@
+     }
+   }
+ 
+-
+ trans_begun:
+-  if( rc==SQLITE_OK && wrflag ){
+-    /* This call makes sure that the pager has the correct number of
+-    ** open savepoints. If the second parameter is greater than 0 and
+-    ** the sub-journal is not already open, then it will be opened here.
+-    */
+-    rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
++  if( rc==SQLITE_OK ){
++    if( pSchemaVersion ){
++      *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]);
++    }
++    if( wrflag ){
++      /* This call makes sure that the pager has the correct number of
++      ** open savepoints. If the second parameter is greater than 0 and
++      ** the sub-journal is not already open, then it will be opened here.
++      */
++      rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
++    }
+   }
+ 
+   btreeIntegrity(p);
+@@ -65158,6 +66523,7 @@
+       eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
+   assert( sqlite3_mutex_held(pBt->mutex) );
+   assert( pDbPage->pBt==pBt );
++  if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
+ 
+   /* Move page iDbPage from its current location to page number iFreePage */
+   TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", 
+@@ -66329,9 +67695,6 @@
+         /* Need to read this page properly. It contains some of the
+         ** range of data that is being read (eOp==0) or written (eOp!=0).
+         */
+-#ifdef SQLITE_DIRECT_OVERFLOW_READ
+-        sqlite3_file *fd;      /* File from which to do direct overflow read */
+-#endif
+         int a = amt;
+         if( a + offset > ovflSize ){
+           a = ovflSize - offset;
+@@ -66342,7 +67705,7 @@
+         **
+         **   1) this is a read operation, and 
+         **   2) data is required from the start of this overflow page, and
+-        **   3) there is no open write-transaction, and
++        **   3) there are no dirty pages in the page-cache
+         **   4) the database is file-backed, and
+         **   5) the page is not in the WAL file
+         **   6) at least 4 bytes have already been read into the output buffer 
+@@ -66353,11 +67716,10 @@
+         */
+         if( eOp==0                                             /* (1) */
+          && offset==0                                          /* (2) */
+-         && pBt->inTransaction==TRANS_READ                     /* (3) */
+-         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (4) */
+-         && 0==sqlite3PagerUseWal(pBt->pPager, nextPage)       /* (5) */
++         && sqlite3PagerDirectReadOk(pBt->pPager, nextPage)    /* (3,4,5) */
+          && &pBuf[-4]>=pBufStart                               /* (6) */
+         ){
++          sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
+           u8 aSave[4];
+           u8 *aWrite = &pBuf[-4];
+           assert( aWrite>=pBufStart );                         /* due to (6) */
+@@ -66767,6 +68129,23 @@
+   return rc;
+ }
+ 
++/*
++** This function is a no-op if cursor pCur does not point to a valid row.
++** Otherwise, if pCur is valid, configure it so that the next call to
++** sqlite3BtreeNext() is a no-op.
++*/
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){
++  /* We believe that the cursor must always be in the valid state when
++  ** this routine is called, but the proof is difficult, so we add an
++  ** ALWaYS() test just in case we are wrong. */
++  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
++    pCur->eState = CURSOR_SKIPNEXT;
++    pCur->skipNext = 1;
++  }
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
+ /* Move the cursor to the last entry in the table.  Return SQLITE_OK
+ ** on success.  Set *pRes to 0 if the cursor actually points to something
+ ** or set *pRes to 1 if the table is empty.
+@@ -67171,7 +68550,16 @@
+ 
+   pPage = pCur->pPage;
+   idx = ++pCur->ix;
+-  assert( pPage->isInit );
++  if( !pPage->isInit ){
++    /* The only known way for this to happen is for there to be a
++    ** recursive SQL function that does a DELETE operation as part of a
++    ** SELECT which deletes content out from under an active cursor
++    ** in a corrupt database file where the table being DELETE-ed from
++    ** has pages in common with the table being queried.  See TH3
++    ** module cov1/btree78.test testcase 220 (2018-06-08) for an
++    ** example. */
++    return SQLITE_CORRUPT_BKPT;
++  }
+ 
+   /* If the database file is corrupt, it is possible for the value of idx 
+   ** to be invalid here. This can only occur if a second cursor modifies
+@@ -67817,7 +69205,9 @@
+   if( pInfo->nLocal==pInfo->nPayload ){
+     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
+   }
+-  if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
++  testcase( pCell + pInfo->nSize == pPage->aDataEnd );
++  testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd );
++  if( pCell + pInfo->nSize > pPage->aDataEnd ){
+     /* Cell extends past end of page */
+     return SQLITE_CORRUPT_PAGE(pPage);
+   }
+@@ -69743,8 +71133,96 @@
+   return rc;
+ }
+ 
++/* Overwrite content from pX into pDest.  Only do the write if the
++** content is different from what is already there.
++*/
++static int btreeOverwriteContent(
++  MemPage *pPage,           /* MemPage on which writing will occur */
++  u8 *pDest,                /* Pointer to the place to start writing */
++  const BtreePayload *pX,   /* Source of data to write */
++  int iOffset,              /* Offset of first byte to write */
++  int iAmt                  /* Number of bytes to be written */
++){
++  int nData = pX->nData - iOffset;
++  if( nData<=0 ){
++    /* Overwritting with zeros */
++    int i;
++    for(i=0; i<iAmt && pDest[i]==0; i++){}
++    if( i<iAmt ){
++      int rc = sqlite3PagerWrite(pPage->pDbPage);
++      if( rc ) return rc;
++      memset(pDest + i, 0, iAmt - i);
++    }
++  }else{
++    if( nData<iAmt ){
++      /* Mixed read data and zeros at the end.  Make a recursive call
++      ** to write the zeros then fall through to write the real data */
++      int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData,
++                                 iAmt-nData);
++      if( rc ) return rc;
++      iAmt = nData;
++    }
++    if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
++      int rc = sqlite3PagerWrite(pPage->pDbPage);
++      if( rc ) return rc;
++      memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
++    }
++  }
++  return SQLITE_OK;
++}
+ 
+ /*
++** Overwrite the cell that cursor pCur is pointing to with fresh content
++** contained in pX.
++*/
++static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
++  int iOffset;                        /* Next byte of pX->pData to write */
++  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
++  int rc;                             /* Return code */
++  MemPage *pPage = pCur->pPage;       /* Page being written */
++  BtShared *pBt;                      /* Btree */
++  Pgno ovflPgno;                      /* Next overflow page to write */
++  u32 ovflPageSize;                   /* Size to write on overflow page */
++
++  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){
++    return SQLITE_CORRUPT_BKPT;
++  }
++  /* Overwrite the local portion first */
++  rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
++                             0, pCur->info.nLocal);
++  if( rc ) return rc;
++  if( pCur->info.nLocal==nTotal ) return SQLITE_OK;
++
++  /* Now overwrite the overflow pages */
++  iOffset = pCur->info.nLocal;
++  assert( nTotal>=0 );
++  assert( iOffset>=0 );
++  ovflPgno = get4byte(pCur->info.pPayload + iOffset);
++  pBt = pPage->pBt;
++  ovflPageSize = pBt->usableSize - 4;
++  do{
++    rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
++    if( rc ) return rc;
++    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){
++      rc = SQLITE_CORRUPT_BKPT;
++    }else{
++      if( iOffset+ovflPageSize<(u32)nTotal ){
++        ovflPgno = get4byte(pPage->aData);
++      }else{
++        ovflPageSize = nTotal - iOffset;
++      }
++      rc = btreeOverwriteContent(pPage, pPage->aData+4, pX,
++                                 iOffset, ovflPageSize);
++    }
++    sqlite3PagerUnref(pPage->pDbPage);
++    if( rc ) return rc;
++    iOffset += ovflPageSize;
++  }while( iOffset<nTotal );
++  return SQLITE_OK;    
++}
++
++
++/*
+ ** Insert a new record into the BTree.  The content of the new record
+ ** is described by the pX object.  The pCur cursor is used only to
+ ** define what table the record should be inserted into, and is left
+@@ -69833,35 +71311,86 @@
+     invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0);
+ 
+     /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
+-    ** to a row with the same key as the new entry being inserted.  */
+-    assert( (flags & BTREE_SAVEPOSITION)==0 || 
+-            ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
++    ** to a row with the same key as the new entry being inserted.
++    */
++#ifdef SQLITE_DEBUG
++    if( flags & BTREE_SAVEPOSITION ){
++      assert( pCur->curFlags & BTCF_ValidNKey );
++      assert( pX->nKey==pCur->info.nKey );
++      assert( pCur->info.nSize!=0 );
++      assert( loc==0 );
++    }
++#endif
+ 
+-    /* If the cursor is currently on the last row and we are appending a
+-    ** new row onto the end, set the "loc" to avoid an unnecessary
+-    ** btreeMoveto() call */
++    /* On the other hand, BTREE_SAVEPOSITION==0 does not imply
++    ** that the cursor is not pointing to a row to be overwritten.
++    ** So do a complete check.
++    */
+     if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
+-      loc = 0;
++      /* The cursor is pointing to the entry that is to be
++      ** overwritten */
++      assert( pX->nData>=0 && pX->nZero>=0 );
++      if( pCur->info.nSize!=0
++       && pCur->info.nPayload==(u32)pX->nData+pX->nZero
++      ){
++        /* New entry is the same size as the old.  Do an overwrite */
++        return btreeOverwriteCell(pCur, pX);
++      }
++      assert( loc==0 );
+     }else if( loc==0 ){
++      /* The cursor is *not* pointing to the cell to be overwritten, nor
++      ** to an adjacent cell.  Move the cursor so that it is pointing either
++      ** to the cell to be overwritten or an adjacent cell.
++      */
+       rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
+       if( rc ) return rc;
+     }
+-  }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
+-    if( pX->nMem ){
+-      UnpackedRecord r;
+-      r.pKeyInfo = pCur->pKeyInfo;
+-      r.aMem = pX->aMem;
+-      r.nField = pX->nMem;
+-      r.default_rc = 0;
+-      r.errCode = 0;
+-      r.r1 = 0;
+-      r.r2 = 0;
+-      r.eqSeen = 0;
+-      rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
+-    }else{
+-      rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
++  }else{
++    /* This is an index or a WITHOUT ROWID table */
++
++    /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing 
++    ** to a row with the same key as the new entry being inserted.
++    */
++    assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 );
++
++    /* If the cursor is not already pointing either to the cell to be
++    ** overwritten, or if a new cell is being inserted, if the cursor is
++    ** not pointing to an immediately adjacent cell, then move the cursor
++    ** so that it does.
++    */
++    if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
++      if( pX->nMem ){
++        UnpackedRecord r;
++        r.pKeyInfo = pCur->pKeyInfo;
++        r.aMem = pX->aMem;
++        r.nField = pX->nMem;
++        r.default_rc = 0;
++        r.errCode = 0;
++        r.r1 = 0;
++        r.r2 = 0;
++        r.eqSeen = 0;
++        rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
++      }else{
++        rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
++      }
++      if( rc ) return rc;
+     }
+-    if( rc ) return rc;
++
++    /* If the cursor is currently pointing to an entry to be overwritten
++    ** and the new content is the same as as the old, then use the
++    ** overwrite optimization.
++    */
++    if( loc==0 ){
++      getCellInfo(pCur);
++      if( pCur->info.nKey==pX->nKey ){
++        BtreePayload x2;
++        x2.pData = pX->pKey;
++        x2.nData = pX->nKey;
++        x2.nZero = 0;
++        return btreeOverwriteCell(pCur, &x2);
++      }
++    }
++
+   }
+   assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
+ 
+@@ -70700,14 +72229,14 @@
+   pCheck->nErr++;
+   va_start(ap, zFormat);
+   if( pCheck->errMsg.nChar ){
+-    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
++    sqlite3_str_append(&pCheck->errMsg, "\n", 1);
+   }
+   if( pCheck->zPfx ){
+-    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
++    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
+   }
+-  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
++  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
+   va_end(ap);
+-  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
++  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
+     pCheck->mallocFailed = 1;
+   }
+ }
+@@ -70742,8 +72271,7 @@
+ ** Also check that the page number is in bounds.
+ */
+ static int checkRef(IntegrityCk *pCheck, Pgno iPage){
+-  if( iPage==0 ) return 1;
+-  if( iPage>pCheck->nPage ){
++  if( iPage>pCheck->nPage || iPage==0 ){
+     checkAppendMsg(pCheck, "invalid page number %d", iPage);
+     return 1;
+   }
+@@ -70798,17 +72326,12 @@
+ ){
+   int i;
+   int expected = N;
+-  int iFirst = iPage;
+-  while( N-- > 0 && pCheck->mxErr ){
++  int nErrAtStart = pCheck->nErr;
++  while( iPage!=0 && pCheck->mxErr ){
+     DbPage *pOvflPage;
+     unsigned char *pOvflData;
+-    if( iPage<1 ){
+-      checkAppendMsg(pCheck,
+-         "%d of %d pages missing from overflow list starting at %d",
+-          N+1, expected, iFirst);
+-      break;
+-    }
+     if( checkRef(pCheck, iPage) ) break;
++    N--;
+     if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
+       checkAppendMsg(pCheck, "failed to get page %d", iPage);
+       break;
+@@ -70852,11 +72375,13 @@
+ #endif
+     iPage = get4byte(pOvflData);
+     sqlite3PagerUnref(pOvflPage);
+-
+-    if( isFreeList && N<(iPage!=0) ){
+-      checkAppendMsg(pCheck, "free-page count in header is too small");
+-    }
+   }
++  if( N && nErrAtStart==pCheck->nErr ){
++    checkAppendMsg(pCheck,
++      "%s is %d but should be %d",
++      isFreeList ? "size" : "overflow list length",
++      expected-N, expected);
++  }
+ }
+ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
+ 
+@@ -71249,6 +72774,24 @@
+ 
+   /* Check all the tables.
+   */
++#ifndef SQLITE_OMIT_AUTOVACUUM
++  if( pBt->autoVacuum ){
++    int mx = 0;
++    int mxInHdr;
++    for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i];
++    mxInHdr = get4byte(&pBt->pPage1->aData[52]);
++    if( mx!=mxInHdr ){
++      checkAppendMsg(&sCheck,
++        "max rootpage (%d) disagrees with header (%d)",
++        mx, mxInHdr
++      );
++    }
++  }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){
++    checkAppendMsg(&sCheck,
++      "incremental_vacuum enabled with a max rootpage of zero"
++    );
++  }
++#endif
+   testcase( pBt->db->flags & SQLITE_CellSizeCk );
+   pBt->db->flags &= ~SQLITE_CellSizeCk;
+   for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
+@@ -71291,11 +72834,11 @@
+   sqlite3PageFree(sCheck.heap);
+   sqlite3_free(sCheck.aPgRef);
+   if( sCheck.mallocFailed ){
+-    sqlite3StrAccumReset(&sCheck.errMsg);
++    sqlite3_str_reset(&sCheck.errMsg);
+     sCheck.nErr++;
+   }
+   *pnErr = sCheck.nErr;
+-  if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
++  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
+   /* Make sure this analysis did not leave any unref() pages. */
+   assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
+   sqlite3BtreeLeave(p);
+@@ -71530,11 +73073,11 @@
+   pBt->btsFlags &= ~BTS_NO_WAL;
+   if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;
+ 
+-  rc = sqlite3BtreeBeginTrans(pBtree, 0);
++  rc = sqlite3BtreeBeginTrans(pBtree, 0, 0);
+   if( rc==SQLITE_OK ){
+     u8 *aData = pBt->pPage1->aData;
+     if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
+-      rc = sqlite3BtreeBeginTrans(pBtree, 2);
++      rc = sqlite3BtreeBeginTrans(pBtree, 2, 0);
+       if( rc==SQLITE_OK ){
+         rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
+         if( rc==SQLITE_OK ){
+@@ -71974,7 +73517,7 @@
+     ** before this function exits.
+     */
+     if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
+-      rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
++      rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
+       bCloseTrans = 1;
+     }
+ 
+@@ -71990,10 +73533,10 @@
+ 
+     /* Lock the destination database, if it is not locked already. */
+     if( SQLITE_OK==rc && p->bDestLocked==0
+-     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) 
++     && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
++                                                (int*)&p->iDestSchema)) 
+     ){
+       p->bDestLocked = 1;
+-      sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
+     }
+ 
+     /* Do not allow backup if the destination database is in WAL mode
+@@ -72437,8 +73980,7 @@
+ 
+   if( p->flags & MEM_Null ){
+     /* Cannot be both MEM_Null and some other type */
+-    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
+-                         |MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
++    assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 );
+ 
+     /* If MEM_Null is set, then either the value is a pure NULL (the usual
+     ** case) or it is a pointer set using sqlite3_bind_pointer() or
+@@ -72551,7 +74093,7 @@
+ #ifndef SQLITE_OMIT_UTF16
+   int rc;
+ #endif
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
+            || desiredEnc==SQLITE_UTF16BE );
+   if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
+@@ -72584,7 +74126,7 @@
+ */
+ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+   assert( sqlite3VdbeCheckMemInvariants(pMem) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   testcase( pMem->db==0 );
+ 
+   /* If the bPreserve flag is set to true, then the memory cell must already
+@@ -72672,7 +74214,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
+     if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
+     if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
+@@ -72697,7 +74239,7 @@
+   int nByte;
+   assert( pMem->flags & MEM_Zero );
+   assert( pMem->flags&MEM_Blob );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ 
+   /* Set nByte to the number of bytes required to store the expanded blob. */
+@@ -72752,7 +74294,7 @@
+   assert( !(fg&MEM_Zero) );
+   assert( !(fg&(MEM_Str|MEM_Blob)) );
+   assert( fg&(MEM_Int|MEM_Real) );
+-  assert( (pMem->flags&MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+ 
+@@ -72773,7 +74315,8 @@
+     assert( fg & MEM_Real );
+     sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
+   }
+-  pMem->n = sqlite3Strlen30(pMem->z);
++  assert( pMem->z!=0 );
++  pMem->n = sqlite3Strlen30NN(pMem->z);
+   pMem->enc = SQLITE_UTF8;
+   pMem->flags |= MEM_Str|MEM_Term;
+   if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
+@@ -72811,6 +74354,35 @@
+ }
+ 
+ /*
++** Memory cell pAccum contains the context of an aggregate function.
++** This routine calls the xValue method for that function and stores
++** the results in memory cell pMem.
++**
++** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK 
++** otherwise.
++*/
++#ifndef SQLITE_OMIT_WINDOWFUNC
++SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
++  sqlite3_context ctx;
++  Mem t;
++  assert( pFunc!=0 );
++  assert( pFunc->xValue!=0 );
++  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
++  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
++  memset(&ctx, 0, sizeof(ctx));
++  memset(&t, 0, sizeof(t));
++  t.flags = MEM_Null;
++  t.db = pAccum->db;
++  sqlite3VdbeMemSetNull(pOut);
++  ctx.pOut = pOut;
++  ctx.pMem = pAccum;
++  ctx.pFunc = pFunc;
++  pFunc->xValue(&ctx);
++  return ctx.isError;
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** If the memory cell contains a value that must be freed by
+ ** invoking the external callback in Mem.xDel, then this routine
+ ** will free that value.  It also sets Mem.flags to MEM_Null.
+@@ -72828,15 +74400,8 @@
+     testcase( p->flags & MEM_Dyn );
+   }
+   if( p->flags&MEM_Dyn ){
+-    assert( (p->flags&MEM_RowSet)==0 );
+     assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
+     p->xDel((void *)p->z);
+-  }else if( p->flags&MEM_RowSet ){
+-    sqlite3RowSetClear(p->u.pRowSet);
+-  }else if( p->flags&MEM_Frame ){
+-    VdbeFrame *pFrame = p->u.pFrame;
+-    pFrame->pParent = pFrame->v->pDelFrame;
+-    pFrame->v->pDelFrame = pFrame;
+   }
+   p->flags = MEM_Null;
+ }
+@@ -72984,7 +74549,7 @@
+ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
+   i64 ix;
+   assert( pMem->flags & MEM_Real );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+@@ -73011,7 +74576,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
+ 
+   pMem->u.i = sqlite3VdbeIntValue(pMem);
+@@ -73195,7 +74760,7 @@
+ }
+ 
+ /* A no-op destructor */
+-static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
++SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
+ 
+ /*
+ ** Set the value stored in *pMem should already be a NULL.
+@@ -73229,26 +74794,36 @@
+ }
+ #endif
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Return true if the Mem holds a RowSet object.  This routine is intended
++** for use inside of assert() statements.
++*/
++SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){
++  return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn)
++         && pMem->xDel==sqlite3RowSetDelete;
++}
++#endif
++
++/*
+ ** Delete any previous value and set the value of pMem to be an
+ ** empty boolean index.
++**
++** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation
++** error occurs.
+ */
+-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
++SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){
+   sqlite3 *db = pMem->db;
++  RowSet *p;
+   assert( db!=0 );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   sqlite3VdbeMemRelease(pMem);
+-  pMem->zMalloc = sqlite3DbMallocRawNN(db, 64);
+-  if( db->mallocFailed ){
+-    pMem->flags = MEM_Null;
+-    pMem->szMalloc = 0;
+-  }else{
+-    assert( pMem->zMalloc );
+-    pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
+-    pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
+-    assert( pMem->u.pRowSet!=0 );
+-    pMem->flags = MEM_RowSet;
+-  }
++  p = sqlite3RowSetInit(db);
++  if( p==0 ) return SQLITE_NOMEM;
++  pMem->z = (char*)p;
++  pMem->flags = MEM_Blob|MEM_Dyn;
++  pMem->xDel = sqlite3RowSetDelete;
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -73281,7 +74856,21 @@
+   Mem *pX;
+   for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
+     if( pX->pScopyFrom==pMem ){
+-      pX->flags |= MEM_Undefined;
++      /* If pX is marked as a shallow copy of pMem, then verify that
++      ** no significant changes have been made to pX since the OP_SCopy.
++      ** A significant change would indicated a missed call to this
++      ** function for pX.  Minor changes, such as adding or removing a
++      ** dual type, are allowed, as long as the underlying value is the
++      ** same. */
++      u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
++      assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
++      assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
++      assert( (mFlags&MEM_Str)==0  || (pMem->n==pX->n && pMem->z==pX->z) );
++      assert( (mFlags&MEM_Blob)==0  || sqlite3BlobCompare(pMem,pX)==0 );
++      
++      /* pMem is the register that is changing.  But also mark pX as
++      ** undefined so that we can quickly detect the shallow-copy error */
++      pX->flags = MEM_Undefined;
+       pX->pScopyFrom = 0;
+     }
+   }
+@@ -73302,7 +74891,7 @@
+   sqlite3VdbeMemShallowCopy(pTo, pFrom, eType);
+ }
+ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
+-  assert( (pFrom->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pFrom) );
+   assert( pTo->db==pFrom->db );
+   if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; }
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+@@ -73320,7 +74909,7 @@
+ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
+   int rc = SQLITE_OK;
+ 
+-  assert( (pFrom->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pFrom) );
+   if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
+   memcpy(pTo, pFrom, MEMCELLSIZE);
+   pTo->flags &= ~MEM_Dyn;
+@@ -73378,7 +74967,7 @@
+   u16 flags = 0;      /* New value for pMem->flags */
+ 
+   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+ 
+   /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
+   if( !z ){
+@@ -73500,7 +75089,7 @@
+ 
+   /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
+   ** that both the BtShared and database handle mutexes are held. */
+-  assert( (pMem->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+   zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
+   assert( zData!=0 );
+ 
+@@ -73524,7 +75113,7 @@
+   assert( pVal!=0 );
+   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
+   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+-  assert( (pVal->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pVal) );
+   assert( (pVal->flags & (MEM_Null))==0 );
+   if( pVal->flags & (MEM_Blob|MEM_Str) ){
+     if( ExpandBlob(pVal) ) return 0;
+@@ -73567,7 +75156,7 @@
+   if( !pVal ) return 0;
+   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
+   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+-  assert( (pVal->flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pVal) );
+   if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
+     assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+     return pVal->z;
+@@ -73873,12 +75462,16 @@
+                          0, SQLITE_DYNAMIC);
+   }
+ #endif
+-
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+   else if( op==TK_FUNCTION && pCtx!=0 ){
+     rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
+   }
+ #endif
++  else if( op==TK_TRUEFALSE ){
++     pVal = valueNew(db, pCtx);
++     pVal->flags = MEM_Int;
++     pVal->u.i = pExpr->u.zToken[4]==0;
++  }
+ 
+   *ppVal = pVal;
+   return rc;
+@@ -74130,11 +75723,11 @@
+   int iCol,                       /* Column to extract */
+   sqlite3_value **ppVal           /* OUT: Extracted value */
+ ){
+-  u32 t;                          /* a column type code */
++  u32 t = 0;                      /* a column type code */
+   int nHdr;                       /* Size of the header in the record */
+   int iHdr;                       /* Next unread header byte */
+   int iField;                     /* Next unread data byte */
+-  int szField;                    /* Size of the current data field */
++  int szField = 0;                /* Size of the current data field */
+   int i;                          /* Column index */
+   u8 *a = (u8*)pRec;              /* Typecast byte array */
+   Mem *pMem = *ppVal;             /* Write result into this Mem object */
+@@ -74298,6 +75891,13 @@
+   }
+   assert( p->zSql==0 );
+   p->zSql = sqlite3DbStrNDup(p->db, z, n);
++#ifdef SQLITE_ENABLE_NORMALIZE
++  assert( p->zNormSql==0 );
++  if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
++    sqlite3Normalize(p, p->zSql, n, prepFlags);
++    assert( p->zNormSql!=0 || p->db->mallocFailed );
++  }
++#endif
+ }
+ 
+ /*
+@@ -74319,6 +75919,11 @@
+   zTmp = pA->zSql;
+   pA->zSql = pB->zSql;
+   pB->zSql = zTmp;
++#ifdef SQLITE_ENABLE_NORMALIZE
++  zTmp = pA->zNormSql;
++  pA->zNormSql = pB->zNormSql;
++  pB->zNormSql = zTmp;
++#endif
+   pB->expmask = pA->expmask;
+   pB->prepFlags = pA->prepFlags;
+   memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
+@@ -74427,14 +76032,6 @@
+ #endif
+ #ifdef SQLITE_DEBUG
+   if( p->db->flags & SQLITE_VdbeAddopTrace ){
+-    int jj, kk;
+-    Parse *pParse = p->pParse;
+-    for(jj=kk=0; jj<pParse->nColCache; jj++){
+-      struct yColCache *x = pParse->aColCache + jj;
+-      printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+-      kk++;
+-    }
+-    if( kk ) printf("\n");
+     sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+     test_addop_breakpoint();
+   }
+@@ -74537,7 +76134,50 @@
+   return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
+ }
+ 
++#ifndef SQLITE_OMIT_EXPLAIN
+ /*
++** Return the address of the current EXPLAIN QUERY PLAN baseline.
++** 0 means "none".
++*/
++SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
++  VdbeOp *pOp;
++  if( pParse->addrExplain==0 ) return 0;
++  pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
++  return pOp->p2;
++}
++
++/*
++** Add a new OP_Explain opcode.
++**
++** If the bPush flag is true, then make this opcode the parent for
++** subsequent Explains until sqlite3VdbeExplainPop() is called.
++*/
++SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
++  if( pParse->explain==2 ){
++    char *zMsg;
++    Vdbe *v;
++    va_list ap;
++    int iThis;
++    va_start(ap, zFmt);
++    zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
++    va_end(ap);
++    v = pParse->pVdbe;
++    iThis = v->nOp;
++    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
++                      zMsg, P4_DYNAMIC);
++    if( bPush) pParse->addrExplain = iThis;
++  }
++}
++
++/*
++** Pop the EXPLAIN QUERY PLAN stack one level.
++*/
++SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
++  pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
++}
++#endif /* SQLITE_OMIT_EXPLAIN */
++
++/*
+ ** Add an OP_ParseSchema opcode.  This routine is broken out from
+ ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
+ ** as having been used.
+@@ -74626,6 +76266,12 @@
+   assert( j<p->nLabel );
+   assert( j>=0 );
+   if( p->aLabel ){
++#ifdef SQLITE_DEBUG
++    if( p->db->flags & SQLITE_VdbeAddopTrace ){
++      printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
++    }
++#endif
++    assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
+     p->aLabel[j] = v->nOp;
+   }
+ }
+@@ -74775,7 +76421,33 @@
+ }
+ #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Increment the nWrite counter in the VDBE if the cursor is not an
++** ephemeral cursor, or if the cursor argument is NULL.
++*/
++SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){
++  if( pC==0
++   || (pC->eCurType!=CURTYPE_SORTER
++       && pC->eCurType!=CURTYPE_PSEUDO
++       && !pC->isEphemeral)
++  ){
++    p->nWrite++;
++  }
++}
++#endif
++
++#ifdef SQLITE_DEBUG
++/*
++** Assert if an Abort at this point in time might result in a corrupt
++** database.
++*/
++SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){
++  assert( p->nWrite==0 || p->usesStmtJournal );
++}
++#endif
++
++/*
+ ** This routine is called after all opcodes have been inserted.  It loops
+ ** through all the opcodes and fixes up some details.
+ **
+@@ -74835,7 +76507,6 @@
+           break;
+         }
+         case OP_Next:
+-        case OP_NextIfOpen:
+         case OP_SorterNext: {
+           pOp->p4.xAdvance = sqlite3BtreeNext;
+           pOp->p4type = P4_ADVANCE;
+@@ -74845,8 +76516,7 @@
+           assert( pOp->p2>=0 );
+           break;
+         }
+-        case OP_Prev:
+-        case OP_PrevIfOpen: {
++        case OP_Prev: {
+           pOp->p4.xAdvance = sqlite3BtreePrevious;
+           pOp->p4type = P4_ADVANCE;
+           /* The code generator never codes any of these opcodes as a jump
+@@ -74935,6 +76605,17 @@
+ #endif
+ 
+ /*
++** Generate code (a single OP_Abortable opcode) that will
++** verify that the VDBE program can safely call Abort in the current
++** context.
++*/
++#if defined(SQLITE_DEBUG)
++SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){
++  if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable);
++}
++#endif
++
++/*
+ ** This function returns a pointer to the array of opcodes associated with
+ ** the Vdbe passed as the first argument. It is the callers responsibility
+ ** to arrange for the returned array to be eventually freed using the 
+@@ -75478,23 +77159,23 @@
+   const char *zOp = 0;
+   switch( pExpr->op ){
+     case TK_STRING:
+-      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
++      sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
+       break;
+     case TK_INTEGER:
+-      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
++      sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
+       break;
+     case TK_NULL:
+-      sqlite3XPrintf(p, "NULL");
++      sqlite3_str_appendf(p, "NULL");
+       break;
+     case TK_REGISTER: {
+-      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
++      sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
+       break;
+     }
+     case TK_COLUMN: {
+       if( pExpr->iColumn<0 ){
+-        sqlite3XPrintf(p, "rowid");
++        sqlite3_str_appendf(p, "rowid");
+       }else{
+-        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
++        sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
+       }
+       break;
+     }
+@@ -75526,18 +77207,18 @@
+     case TK_NOTNULL: zOp = "NOTNULL"; break;
+ 
+     default:
+-      sqlite3XPrintf(p, "%s", "expr");
++      sqlite3_str_appendf(p, "%s", "expr");
+       break;
+   }
+ 
+   if( zOp ){
+-    sqlite3XPrintf(p, "%s(", zOp);
++    sqlite3_str_appendf(p, "%s(", zOp);
+     displayP4Expr(p, pExpr->pLeft);
+     if( pExpr->pRight ){
+-      sqlite3StrAccumAppend(p, ",", 1);
++      sqlite3_str_append(p, ",", 1);
+       displayP4Expr(p, pExpr->pRight);
+     }
+-    sqlite3StrAccumAppend(p, ")", 1);
++    sqlite3_str_append(p, ")", 1);
+   }
+ }
+ #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
+@@ -75558,14 +77239,15 @@
+       int j;
+       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
+       assert( pKeyInfo->aSortOrder!=0 );
+-      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
++      sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
+       for(j=0; j<pKeyInfo->nKeyField; j++){
+         CollSeq *pColl = pKeyInfo->aColl[j];
+         const char *zColl = pColl ? pColl->zName : "";
+         if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
+-        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
++        sqlite3_str_appendf(&x, ",%s%s", 
++               pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
+       }
+-      sqlite3StrAccumAppend(&x, ")", 1);
++      sqlite3_str_append(&x, ")", 1);
+       break;
+     }
+ #ifdef SQLITE_ENABLE_CURSOR_HINTS
+@@ -75576,31 +77258,31 @@
+ #endif
+     case P4_COLLSEQ: {
+       CollSeq *pColl = pOp->p4.pColl;
+-      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
++      sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
+       break;
+     }
+     case P4_FUNCDEF: {
+       FuncDef *pDef = pOp->p4.pFunc;
+-      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
++      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+       break;
+     }
+ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+     case P4_FUNCCTX: {
+       FuncDef *pDef = pOp->p4.pCtx->pFunc;
+-      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
++      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
+       break;
+     }
+ #endif
+     case P4_INT64: {
+-      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
++      sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
+       break;
+     }
+     case P4_INT32: {
+-      sqlite3XPrintf(&x, "%d", pOp->p4.i);
++      sqlite3_str_appendf(&x, "%d", pOp->p4.i);
+       break;
+     }
+     case P4_REAL: {
+-      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
++      sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
+       break;
+     }
+     case P4_MEM: {
+@@ -75608,9 +77290,9 @@
+       if( pMem->flags & MEM_Str ){
+         zP4 = pMem->z;
+       }else if( pMem->flags & MEM_Int ){
+-        sqlite3XPrintf(&x, "%lld", pMem->u.i);
++        sqlite3_str_appendf(&x, "%lld", pMem->u.i);
+       }else if( pMem->flags & MEM_Real ){
+-        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
++        sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
+       }else if( pMem->flags & MEM_Null ){
+         zP4 = "NULL";
+       }else{
+@@ -75622,7 +77304,7 @@
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     case P4_VTAB: {
+       sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
+-      sqlite3XPrintf(&x, "vtab:%p", pVtab);
++      sqlite3_str_appendf(&x, "vtab:%p", pVtab);
+       break;
+     }
+ #endif
+@@ -75632,14 +77314,14 @@
+       int n = ai[0];   /* The first element of an INTARRAY is always the
+                        ** count of the number of elements to follow */
+       for(i=1; i<=n; i++){
+-        sqlite3XPrintf(&x, ",%d", ai[i]);
++        sqlite3_str_appendf(&x, ",%d", ai[i]);
+       }
+       zTemp[0] = '[';
+-      sqlite3StrAccumAppend(&x, "]", 1);
++      sqlite3_str_append(&x, "]", 1);
+       break;
+     }
+     case P4_SUBPROGRAM: {
+-      sqlite3XPrintf(&x, "program");
++      sqlite3_str_appendf(&x, "program");
+       break;
+     }
+     case P4_DYNBLOB:
+@@ -75648,7 +77330,7 @@
+       break;
+     }
+     case P4_TABLE: {
+-      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
++      sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
+       break;
+     }
+     default: {
+@@ -75749,7 +77431,7 @@
+ /*
+ ** Print a single opcode.  This routine is used for debugging only.
+ */
+-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
++SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
+   char *zP4;
+   char zPtr[50];
+   char zCom[100];
+@@ -75818,9 +77500,8 @@
+       */
+       testcase( p->flags & MEM_Agg );
+       testcase( p->flags & MEM_Dyn );
+-      testcase( p->flags & MEM_Frame );
+-      testcase( p->flags & MEM_RowSet );
+-      if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
++      testcase( p->xDel==sqlite3VdbeFrameMemDel );
++      if( p->flags&(MEM_Agg|MEM_Dyn) ){
+         sqlite3VdbeMemRelease(p);
+       }else if( p->szMalloc ){
+         sqlite3DbFreeNN(db, p->zMalloc);
+@@ -75832,7 +77513,36 @@
+   }
+ }
+ 
++#ifdef SQLITE_DEBUG
+ /*
++** Verify that pFrame is a valid VdbeFrame pointer.  Return true if it is
++** and false if something is wrong.
++**
++** This routine is intended for use inside of assert() statements only.
++*/
++SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
++  if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
++  return 1;
++}
++#endif
++
++
++/*
++** This is a destructor on a Mem object (which is really an sqlite3_value)
++** that deletes the Frame object that is attached to it as a blob.
++**
++** This routine does not delete the Frame right away.  It merely adds the
++** frame to a list of frames to be deleted when the Vdbe halts.
++*/
++SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
++  VdbeFrame *pFrame = (VdbeFrame*)pArg;
++  assert( sqlite3VdbeFrameIsValid(pFrame) );
++  pFrame->pParent = pFrame->v->pDelFrame;
++  pFrame->v->pDelFrame = pFrame;
++}
++
++
++/*
+ ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
+ ** allocated by the OP_Program opcode in sqlite3VdbeExec().
+ */
+@@ -75840,6 +77550,7 @@
+   int i;
+   Mem *aMem = VdbeFrameMem(p);
+   VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
++  assert( sqlite3VdbeFrameIsValid(p) );
+   for(i=0; i<p->nChildCsr; i++){
+     sqlite3VdbeFreeCursor(p->v, apCsr[i]);
+   }
+@@ -75860,6 +77571,9 @@
+ ** p->explain==2, only OP_Explain instructions are listed and these
+ ** are shown in a different format.  p->explain==2 is used to implement
+ ** EXPLAIN QUERY PLAN.
++** 2018-04-24:  In p->explain==2 mode, the OP_Init opcodes of triggers
++** are also shown, so that the boundaries between the main program and
++** each trigger are clear.
+ **
+ ** When p->explain==1, first the main program is listed, then each of
+ ** the trigger subprograms are listed one by one.
+@@ -75922,7 +77636,7 @@
+     }
+   }
+ 
+-  do{
++  while(1){  /* Loop exits via break */
+     i = p->pc++;
+     if( i>=nRow ){
+       p->rc = SQLITE_OK;
+@@ -75968,7 +77682,10 @@
+         nRow += pOp->p4.pProgram->nOp;
+       }
+     }
+-  }while( p->explain==2 && pOp->opcode!=OP_Explain );
++    if( p->explain<2 ) break;
++    if( pOp->opcode==OP_Explain ) break;
++    if( pOp->opcode==OP_Init && p->pc>1 ) break;
++  }
+ 
+   if( rc==SQLITE_OK ){
+     if( db->u1.isInterrupted ){
+@@ -77130,7 +78847,7 @@
+   */
+   sqlite3VdbeHalt(p);
+ 
+-  /* If the VDBE has be run even partially, then transfer the error code
++  /* If the VDBE has been run even partially, then transfer the error code
+   ** and error message from the VDBE into the main database structure.  But
+   ** if the VDBE has just been set to run but has not actually executed any
+   ** instructions yet, leave the main database error information unchanged.
+@@ -77160,6 +78877,9 @@
+   sqlite3DbFree(db, p->zErrMsg);
+   p->zErrMsg = 0;
+   p->pResultSet = 0;
++#ifdef SQLITE_DEBUG
++  p->nWrite = 0;
++#endif
+ 
+   /* Save profiling information from this VDBE run.
+   */
+@@ -77275,6 +78995,9 @@
+   vdbeFreeOpArray(db, p->aOp, p->nOp);
+   sqlite3DbFree(db, p->aColName);
+   sqlite3DbFree(db, p->zSql);
++#ifdef SQLITE_ENABLE_NORMALIZE
++  sqlite3DbFree(db, p->zNormSql);
++#endif
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+   {
+     int i;
+@@ -78039,7 +79762,7 @@
+ ** is less than, equal to, or greater than the second, respectively.
+ ** If one blob is a prefix of the other, then the shorter is the lessor.
+ */
+-static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
++SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+   int c;
+   int n1 = pB1->n;
+   int n2 = pB2->n;
+@@ -78082,13 +79805,10 @@
+     i64 y;
+     double s;
+     if( r<-9223372036854775808.0 ) return +1;
+-    if( r>9223372036854775807.0 ) return -1;
++    if( r>=9223372036854775808.0 ) return -1;
+     y = (i64)r;
+     if( i<y ) return -1;
+-    if( i>y ){
+-      if( y==SMALLEST_INT64 && r>0.0 ) return -1;
+-      return +1;
+-    }
++    if( i>y ) return +1;
+     s = (double)i;
+     if( s<r ) return -1;
+     if( s>r ) return +1;
+@@ -78112,7 +79832,7 @@
+   f1 = pMem1->flags;
+   f2 = pMem2->flags;
+   combined_flags = f1|f2;
+-  assert( (combined_flags & MEM_RowSet)==0 );
++  assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) );
+  
+   /* If one value is NULL, it is less than the other. If both values
+   ** are NULL, return 0.
+@@ -78257,7 +79977,7 @@
+   u32 idx1;                       /* Offset of first type in header */
+   int rc = 0;                     /* Return value */
+   Mem *pRhs = pPKey2->aMem;       /* Next field of pPKey2 to compare */
+-  KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
++  KeyInfo *pKeyInfo;
+   const unsigned char *aKey1 = (const unsigned char *)pKey1;
+   Mem mem1;
+ 
+@@ -78352,7 +80072,7 @@
+         if( (d1+mem1.n) > (unsigned)nKey1 ){
+           pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+           return 0;                /* Corruption */
+-        }else if( pKeyInfo->aColl[i] ){
++        }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
+           mem1.enc = pKeyInfo->enc;
+           mem1.db = pKeyInfo->db;
+           mem1.flags = MEM_Str;
+@@ -78403,7 +80123,7 @@
+     }
+ 
+     if( rc!=0 ){
+-      if( pKeyInfo->aSortOrder[i] ){
++      if( pPKey2->pKeyInfo->aSortOrder[i] ){
+         rc = -rc;
+       }
+       assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
+@@ -78412,10 +80132,11 @@
+     }
+ 
+     i++;
++    if( i==pPKey2->nField ) break;
+     pRhs++;
+     d1 += sqlite3VdbeSerialTypeLen(serial_type);
+     idx1 += sqlite3VarintLen(serial_type);
+-  }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
++  }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 );
+ 
+   /* No memory allocation is ever used on mem1.  Prove this using
+   ** the following assert().  If the assert() fails, it indicates a
+@@ -78427,7 +80148,7 @@
+   ** value.  */
+   assert( CORRUPT_DB 
+        || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) 
+-       || pKeyInfo->db->mallocFailed
++       || pPKey2->pKeyInfo->db->mallocFailed
+   );
+   pPKey2->eqSeen = 1;
+   return pPKey2->default_rc;
+@@ -78678,7 +80399,9 @@
+   (void)getVarint32((u8*)m.z, szHdr);
+   testcase( szHdr==3 );
+   testcase( szHdr==m.n );
+-  if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
++  testcase( szHdr>0x7fffffff );
++  assert( m.n>=0 );
++  if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
+     goto idx_rowid_corruption;
+   }
+ 
+@@ -78753,7 +80476,7 @@
+   if( rc ){
+     return rc;
+   }
+-  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
++  *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
+   sqlite3VdbeMemRelease(&m);
+   return SQLITE_OK;
+ }
+@@ -78785,11 +80508,19 @@
+ ** programs obsolete.  Removing user-defined functions or collating
+ ** sequences, or changing an authorization function are the types of
+ ** things that make prepared statements obsolete.
++**
++** If iCode is 1, then expiration is advisory.  The statement should
++** be reprepared before being restarted, but if it is already running
++** it is allowed to run to completion.
++**
++** Internally, this function just sets the Vdbe.expired flag on all
++** prepared statements.  The flag is set to 1 for an immediate expiration
++** and set to 2 for an advisory expiration.
+ */
+-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){
++SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){
+   Vdbe *p;
+   for(p = db->pVdbe; p; p=p->pNext){
+-    p->expired = 1;
++    p->expired = iCode+1;
+   }
+ }
+ 
+@@ -79767,28 +81498,6 @@
+ }
+ 
+ /*
+-** The following is the implementation of an SQL function that always
+-** fails with an error message stating that the function is used in the
+-** wrong context.  The sqlite3_overload_function() API might construct
+-** SQL function that use this routine so that the functions will exist
+-** for name resolution but are actually overloaded by the xFindFunction
+-** method of virtual tables.
+-*/
+-SQLITE_PRIVATE void sqlite3InvalidFunction(
+-  sqlite3_context *context,  /* The function calling context */
+-  int NotUsed,               /* Number of arguments to the function */
+-  sqlite3_value **NotUsed2   /* Value of each argument */
+-){
+-  const char *zName = context->pFunc->zName;
+-  char *zErr;
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  zErr = sqlite3_mprintf(
+-      "unable to use function %s in the requested context", zName);
+-  sqlite3_result_error(context, zErr, -1);
+-  sqlite3_free(zErr);
+-}
+-
+-/*
+ ** Create a new aggregate context for p and return a pointer to
+ ** its pMem->z element.
+ */
+@@ -79971,7 +81680,7 @@
+         /* .xDel       = */ (void(*)(void*))0,
+ #ifdef SQLITE_DEBUG
+         /* .pScopyFrom = */ (Mem*)0,
+-        /* .pFiller    = */ (void*)0,
++        /* .mScopyFlags= */ 0,
+ #endif
+       };
+   return &nullMem;
+@@ -80703,6 +82412,16 @@
+ #endif
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
++/*
++** Return the normalized SQL associated with a prepared statement.
++*/
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
++  Vdbe *p = (Vdbe *)pStmt;
++  return p ? p->zNormSql : 0;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ /*
+ ** Allocate and populate an UnpackedRecord structure based on the serialized
+@@ -81055,17 +82774,17 @@
+     while( *zRawSql ){
+       const char *zStart = zRawSql;
+       while( *(zRawSql++)!='\n' && *zRawSql );
+-      sqlite3StrAccumAppend(&out, "-- ", 3);
++      sqlite3_str_append(&out, "-- ", 3);
+       assert( (zRawSql - zStart) > 0 );
+-      sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
++      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
+     }
+   }else if( p->nVar==0 ){
+-    sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
++    sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
+   }else{
+     while( zRawSql[0] ){
+       n = findNextHostParameter(zRawSql, &nToken);
+       assert( n>0 );
+-      sqlite3StrAccumAppend(&out, zRawSql, n);
++      sqlite3_str_append(&out, zRawSql, n);
+       zRawSql += n;
+       assert( zRawSql[0] || nToken==0 );
+       if( nToken==0 ) break;
+@@ -81091,11 +82810,11 @@
+       assert( idx>0 && idx<=p->nVar );
+       pVar = &p->aVar[idx-1];
+       if( pVar->flags & MEM_Null ){
+-        sqlite3StrAccumAppend(&out, "NULL", 4);
++        sqlite3_str_append(&out, "NULL", 4);
+       }else if( pVar->flags & MEM_Int ){
+-        sqlite3XPrintf(&out, "%lld", pVar->u.i);
++        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
+       }else if( pVar->flags & MEM_Real ){
+-        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
++        sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
+       }else if( pVar->flags & MEM_Str ){
+         int nOut;  /* Number of bytes of the string text to include in output */
+ #ifndef SQLITE_OMIT_UTF16
+@@ -81105,7 +82824,7 @@
+           utf8.db = db;
+           sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
+           if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
+-            out.accError = STRACCUM_NOMEM;
++            out.accError = SQLITE_NOMEM;
+             out.nAlloc = 0;
+           }
+           pVar = &utf8;
+@@ -81118,10 +82837,10 @@
+           while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
+         }
+ #endif    
+-        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
++        sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+ #ifndef SQLITE_OMIT_UTF16
+@@ -81128,28 +82847,28 @@
+         if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
+ #endif
+       }else if( pVar->flags & MEM_Zero ){
+-        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
++        sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
+       }else{
+         int nOut;  /* Number of bytes of the blob to include in output */
+         assert( pVar->flags & MEM_Blob );
+-        sqlite3StrAccumAppend(&out, "x'", 2);
++        sqlite3_str_append(&out, "x'", 2);
+         nOut = pVar->n;
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
+ #endif
+         for(i=0; i<nOut; i++){
+-          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
++          sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
+         }
+-        sqlite3StrAccumAppend(&out, "'", 1);
++        sqlite3_str_append(&out, "'", 1);
+ #ifdef SQLITE_TRACE_SIZE_LIMIT
+         if( nOut<pVar->n ){
+-          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
++          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
+         }
+ #endif
+       }
+     }
+   }
+-  if( out.accError ) sqlite3StrAccumReset(&out);
++  if( out.accError ) sqlite3_str_reset(&out);
+   return sqlite3StrAccumFinish(&out);
+ }
+ 
+@@ -81281,32 +83000,56 @@
+ ** feature is used for test suite validation only and does not appear an
+ ** production builds.
+ **
+-** M is an integer, 2 or 3, that indices how many different ways the
+-** branch can go.  It is usually 2.  "I" is the direction the branch
+-** goes.  0 means falls through.  1 means branch is taken.  2 means the
+-** second alternative branch is taken.
++** M is an integer between 2 and 4.  2 indicates a ordinary two-way
++** branch (I=0 means fall through and I=1 means taken).  3 indicates
++** a 3-way branch where the third way is when one of the operands is
++** NULL.  4 indicates the OP_Jump instruction which has three destinations
++** depending on whether the first operand is less than, equal to, or greater
++** than the second. 
+ **
+ ** iSrcLine is the source code line (from the __LINE__ macro) that
+-** generated the VDBE instruction.  This instrumentation assumes that all
+-** source code is in a single file (the amalgamation).  Special values 1
+-** and 2 for the iSrcLine parameter mean that this particular branch is
+-** always taken or never taken, respectively.
++** generated the VDBE instruction combined with flag bits.  The source
++** code line number is in the lower 24 bits of iSrcLine and the upper
++** 8 bytes are flags.  The lower three bits of the flags indicate
++** values for I that should never occur.  For example, if the branch is
++** always taken, the flags should be 0x05 since the fall-through and
++** alternate branch are never taken.  If a branch is never taken then
++** flags should be 0x06 since only the fall-through approach is allowed.
++**
++** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
++** interested in equal or not-equal.  In other words, I==0 and I==2
++** should be treated the same.
++**
++** Since only a line number is retained, not the filename, this macro
++** only works for amalgamation builds.  But that is ok, since these macros
++** should be no-ops except for special builds used to measure test coverage.
+ */
+ #if !defined(SQLITE_VDBE_COVERAGE)
+ # define VdbeBranchTaken(I,M)
+ #else
+ # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
+-  static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
+-    if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
+-      M = iSrcLine;
+-      /* Assert the truth of VdbeCoverageAlwaysTaken() and 
+-      ** VdbeCoverageNeverTaken() */
+-      assert( (M & I)==I );
+-    }else{
+-      if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
+-      sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
+-                                      iSrcLine,I,M);
++  static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){
++    u8 mNever;
++    assert( I<=2 );  /* 0: fall through,  1: taken,  2: alternate taken */
++    assert( M<=4 );  /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */
++    assert( I<M );   /* I can only be 2 if M is 3 or 4 */
++    /* Transform I from a integer [0,1,2] into a bitmask of [1,2,4] */
++    I = 1<<I;
++    /* The upper 8 bits of iSrcLine are flags.  The lower three bits of
++    ** the flags indicate directions that the branch can never go.  If
++    ** a branch really does go in one of those directions, assert right
++    ** away. */
++    mNever = iSrcLine >> 24;
++    assert( (I & mNever)==0 );
++    if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
++    I |= mNever;
++    if( M==2 ) I |= 0x04;
++    if( M==4 ){
++      I |= 0x08;
++      if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
+     }
++    sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
++                                    iSrcLine&0xffffff, I, M);
+   }
+ #endif
+ 
+@@ -81637,7 +83380,7 @@
+   }else if( p->flags & MEM_Real ){
+     printf(" r:%g", p->u.r);
+ #endif
+-  }else if( p->flags & MEM_RowSet ){
++  }else if( sqlite3VdbeMemIsRowSet(p) ){
+     printf(" (rowset)");
+   }else{
+     char zBuf[200];
+@@ -82163,6 +83906,9 @@
+ */
+ case OP_HaltIfNull: {      /* in3 */
+   pIn3 = &aMem[pOp->p3];
++#ifdef SQLITE_DEBUG
++  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
++#endif
+   if( (pIn3->flags & MEM_Null)==0 ) break;
+   /* Fall through into OP_Halt */
+ }
+@@ -82202,6 +83948,9 @@
+   int pcx;
+ 
+   pcx = (int)(pOp - aOp);
++#ifdef SQLITE_DEBUG
++  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
++#endif
+   if( pOp->p1==SQLITE_OK && p->pFrame ){
+     /* Halt the sub-program. Return control to the parent frame. */
+     pFrame = p->pFrame;
+@@ -82385,6 +84134,9 @@
+   assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
+   pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+   pOut->n = 0;
++#ifdef SQLITE_DEBUG
++  pOut->uTemp = 0;
++#endif
+   while( cnt>0 ){
+     pOut++;
+     memAboutToChange(p, pOut);
+@@ -82506,6 +84258,7 @@
+   pOut = &aMem[pOp->p2];
+   assert( pOut!=pIn1 );
+   while( 1 ){
++    memAboutToChange(p, pOut);
+     sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
+     Deephemeralize(pOut);
+ #ifdef SQLITE_DEBUG
+@@ -82538,7 +84291,8 @@
+   assert( pOut!=pIn1 );
+   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
+ #ifdef SQLITE_DEBUG
+-  if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
++  pOut->pScopyFrom = pIn1;
++  pOut->mScopyFlags = pIn1->flags;
+ #endif
+   break;
+ }
+@@ -83172,7 +84926,12 @@
+       if( (flags1 | flags3)&MEM_Str ){
+         if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+           applyNumericAffinity(pIn1,0);
+-          testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
++          assert( flags3==pIn3->flags );
++          /* testcase( flags3!=pIn3->flags );
++          ** this used to be possible with pIn1==pIn3, but not since
++          ** the column cache was removed.  The following assignment
++          ** is essentially a no-op.  But, it provides defense-in-depth
++          ** in case our analysis is incorrect, so it is left in. */
+           flags3 = pIn3->flags;
+         }
+         if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+@@ -83386,11 +85145,11 @@
+ */
+ case OP_Jump: {             /* jump */
+   if( iCompare<0 ){
+-    VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
++    VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
+   }else if( iCompare==0 ){
+-    VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
++    VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1];
+   }else{
+-    VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
++    VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1];
+   }
+   break;
+ }
+@@ -83487,7 +85246,7 @@
+ }
+ 
+ /* Opcode: BitNot P1 P2 * * *
+-** Synopsis: r[P1]= ~r[P1]
++** Synopsis: r[P2]= ~r[P1]
+ **
+ ** Interpret the content of register P1 as an integer.  Store the
+ ** ones-complement of the P1 value into register P2.  If P1 holds
+@@ -84102,9 +85861,6 @@
+     if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
+   }
+   nByte = nHdr+nData;
+-  if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-    goto too_big;
+-  }
+ 
+   /* Make sure the output register has a buffer large enough to store 
+   ** the new record. The output register (pOp->p3) is not allowed to
+@@ -84111,8 +85867,19 @@
+   ** be one of the input registers (because the following call to
+   ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
+   */
+-  if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
+-    goto no_mem;
++  if( nByte+nZero<=pOut->szMalloc ){
++    /* The output register is already large enough to hold the record.
++    ** No error checks or buffer enlargement is required */
++    pOut->z = pOut->zMalloc;
++  }else{
++    /* Need to make sure that the output is not too big and then enlarge
++    ** the output register to hold the full result */
++    if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
++      goto too_big;
++    }
++    if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
++      goto no_mem;
++    }
+   }
+   zNewRecord = (u8 *)pOut->z;
+ 
+@@ -84302,7 +86069,7 @@
+           }
+         }
+         if( isSchemaChange ){
+-          sqlite3ExpirePreparedStatements(db);
++          sqlite3ExpirePreparedStatements(db, 0);
+           sqlite3ResetAllSchemasOfConnection(db);
+           db->mDbFlags |= DBFLAG_SchemaChange;
+         }
+@@ -84444,8 +86211,7 @@
+ */
+ case OP_Transaction: {
+   Btree *pBt;
+-  int iMeta;
+-  int iGen;
++  int iMeta = 0;
+ 
+   assert( p->bIsReader );
+   assert( p->readOnly==0 || pOp->p2==0 );
+@@ -84458,7 +86224,7 @@
+   pBt = db->aDb[pOp->p1].pBt;
+ 
+   if( pBt ){
+-    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
++    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
+     testcase( rc==SQLITE_BUSY_SNAPSHOT );
+     testcase( rc==SQLITE_BUSY_RECOVERY );
+     if( rc!=SQLITE_OK ){
+@@ -84491,19 +86257,17 @@
+       p->nStmtDefCons = db->nDeferredCons;
+       p->nStmtDefImmCons = db->nDeferredImmCons;
+     }
+-
+-    /* Gather the schema version number for checking:
++  }
++  assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
++  if( pOp->p5
++   && (iMeta!=pOp->p3
++      || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
++  ){
++    /*
+     ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
+     ** version is checked to ensure that the schema has not changed since the
+     ** SQL statement was prepared.
+     */
+-    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+-    iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+-  }else{
+-    iGen = iMeta = 0;
+-  }
+-  assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
+-  if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){
+     sqlite3DbFree(db, p->zErrMsg);
+     p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
+     /* If the schema-cookie from the database file matches the cookie 
+@@ -84572,6 +86336,8 @@
+ */
+ case OP_SetCookie: {
+   Db *pDb;
++
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   assert( pOp->p2<SQLITE_N_BTREE_META );
+   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+   assert( DbMaskTest(p->btreeMask, pOp->p1) );
+@@ -84592,7 +86358,7 @@
+   if( pOp->p1==1 ){
+     /* Invalidate all prepared statements whenever the TEMP database
+     ** schema is changed.  Ticket #1644 */
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+     p->expired = 0;
+   }
+   if( rc ) goto abort_due_to_error;
+@@ -84610,23 +86376,20 @@
+ ** values need not be contiguous but all P1 values should be small integers.
+ ** It is an error for P1 to be negative.
+ **
+-** If P5!=0 then use the content of register P2 as the root page, not
+-** the value of P2 itself.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** </ul>
+ **
+-** There will be a read lock on the database whenever there is an
+-** open cursor.  If the database was unlocked prior to this instruction
+-** then a read lock is acquired as part of this instruction.  A read
+-** lock allows other processes to read the database but prohibits
+-** any other process from modifying the database.  The read lock is
+-** released when all cursors are closed.  If this instruction attempts
+-** to get a read lock but fails, the script terminates with an
+-** SQLITE_BUSY error code.
+-**
+ ** The P4 value may be either an integer (P4_INT32) or a pointer to
+ ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
+-** structure, then said structure defines the content and collating 
+-** sequence of the index being opened. Otherwise, if P4 is an integer 
+-** value, it is set to the number of columns in the table.
++** object, then table being opened must be an [index b-tree] where the
++** KeyInfo object defines the content and collating 
++** sequence of that index b-tree. Otherwise, if P4 is an integer 
++** value, then the table being opened must be a [table b-tree] with a
++** number of columns no less than the value of P4.
+ **
+ ** See also: OpenWrite, ReopenIdx
+ */
+@@ -84633,36 +86396,58 @@
+ /* Opcode: ReopenIdx P1 P2 P3 P4 P5
+ ** Synopsis: root=P2 iDb=P3
+ **
+-** The ReopenIdx opcode works exactly like ReadOpen except that it first
+-** checks to see if the cursor on P1 is already open with a root page
+-** number of P2 and if it is this opcode becomes a no-op.  In other words,
++** The ReopenIdx opcode works like OP_OpenRead except that it first
++** checks to see if the cursor on P1 is already open on the same
++** b-tree and if it is this opcode becomes a no-op.  In other words,
+ ** if the cursor is already open, do not reopen it.
+ **
+-** The ReopenIdx opcode may only be used with P5==0 and with P4 being
+-** a P4_KEYINFO object.  Furthermore, the P3 value must be the same as
+-** every other ReopenIdx or OpenRead for the same cursor number.
++** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ
++** and with P4 being a P4_KEYINFO object.  Furthermore, the P3 value must
++** be the same as every other ReopenIdx or OpenRead for the same cursor
++** number.
+ **
+-** See the OpenRead opcode documentation for additional information.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** </ul>
++**
++** See also: OP_OpenRead, OP_OpenWrite
+ */
+ /* Opcode: OpenWrite P1 P2 P3 P4 P5
+ ** Synopsis: root=P2 iDb=P3
+ **
+ ** Open a read/write cursor named P1 on the table or index whose root
+-** page is P2.  Or if P5!=0 use the content of register P2 to find the
+-** root page.
++** page is P2 (or whose root page is held in register P2 if the
++** OPFLAG_P2ISREG bit is set in P5 - see below).
+ **
+ ** The P4 value may be either an integer (P4_INT32) or a pointer to
+ ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
+-** structure, then said structure defines the content and collating 
+-** sequence of the index being opened. Otherwise, if P4 is an integer 
+-** value, it is set to the number of columns in the table, or to the
+-** largest index of any column of the table that is actually used.
++** object, then table being opened must be an [index b-tree] where the
++** KeyInfo object defines the content and collating 
++** sequence of that index b-tree. Otherwise, if P4 is an integer 
++** value, then the table being opened must be a [table b-tree] with a
++** number of columns no less than the value of P4.
+ **
+-** This instruction works just like OpenRead except that it opens the cursor
+-** in read/write mode.  For a given table, there can be one or more read-only
+-** cursors or a single read/write cursor but not both.
++** Allowed P5 bits:
++** <ul>
++** <li>  <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
++**       equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
++**       of OP_SeekLE/OP_IdxGT)
++** <li>  <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
++**       and subsequently delete entries in an index btree.  This is a
++**       hint to the storage engine that the storage engine is allowed to
++**       ignore.  The hint is not used by the official SQLite b*tree storage
++**       engine, but is used by COMDB2.
++** <li>  <b>0x10 OPFLAG_P2ISREG</b>: Use the content of register P2
++**       as the root page, not the value of P2 itself.
++** </ul>
+ **
+-** See also OpenRead.
++** This instruction works like OpenRead except that it opens the cursor
++** in read/write mode.
++**
++** See also: OP_OpenRead, OP_ReopenIdx
+ */
+ case OP_ReopenIdx: {
+   int nField;
+@@ -84691,7 +86476,7 @@
+   assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
+           || p->readOnly==0 );
+ 
+-  if( p->expired ){
++  if( p->expired==1 ){
+     rc = SQLITE_ABORT_ROLLBACK;
+     goto abort_due_to_error;
+   }
+@@ -84718,6 +86503,7 @@
+   if( pOp->p5 & OPFLAG_P2ISREG ){
+     assert( p2>0 );
+     assert( p2<=(p->nMem+1 - p->nCursor) );
++    assert( pOp->opcode==OP_OpenWrite );
+     pIn2 = &aMem[p2];
+     assert( memIsValid(pIn2) );
+     assert( (pIn2->flags & MEM_Int)!=0 );
+@@ -84846,7 +86632,7 @@
+   rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
+                         BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1);
++    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
+   }
+   if( rc==SQLITE_OK ){
+     /* If a transient index is required, create it by calling
+@@ -85073,10 +86859,10 @@
+ **
+ ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
+ */
+-case OP_SeekLT:         /* jump, in3 */
+-case OP_SeekLE:         /* jump, in3 */
+-case OP_SeekGE:         /* jump, in3 */
+-case OP_SeekGT: {       /* jump, in3 */
++case OP_SeekLT:         /* jump, in3, group */
++case OP_SeekLE:         /* jump, in3, group */
++case OP_SeekGE:         /* jump, in3, group */
++case OP_SeekGT: {       /* jump, in3, group */
+   int res;           /* Comparison result */
+   int oc;            /* Opcode */
+   VdbeCursor *pC;    /* The cursor to seek */
+@@ -85254,6 +87040,25 @@
+   break;
+ }
+ 
++/* Opcode: SeekHit P1 P2 * * *
++** Synopsis: seekHit=P2
++**
++** Set the seekHit flag on cursor P1 to the value in P2.
++** The seekHit flag is used by the IfNoHope opcode.
++**
++** P1 must be a valid b-tree cursor.  P2 must be a boolean value,
++** either 0 or 1.
++*/
++case OP_SeekHit: {
++  VdbeCursor *pC;
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  assert( pC!=0 );
++  assert( pOp->p2==0 || pOp->p2==1 );
++  pC->seekHit = pOp->p2 & 1;
++  break;
++}
++
+ /* Opcode: Found P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -85288,8 +87093,35 @@
+ ** advanced in either direction.  In other words, the Next and Prev
+ ** opcodes do not work after this operation.
+ **
+-** See also: Found, NotExists, NoConflict
++** See also: Found, NotExists, NoConflict, IfNoHope
+ */
++/* Opcode: IfNoHope P1 P2 P3 P4 *
++** Synopsis: key=r[P3@P4]
++**
++** Register P3 is the first of P4 registers that form an unpacked
++** record.
++**
++** Cursor P1 is on an index btree.  If the seekHit flag is set on P1, then
++** this opcode is a no-op.  But if the seekHit flag of P1 is clear, then
++** check to see if there is any entry in P1 that matches the
++** prefix identified by P3 and P4.  If no entry matches the prefix,
++** jump to P2.  Otherwise fall through.
++**
++** This opcode behaves like OP_NotFound if the seekHit
++** flag is clear and it behaves like OP_Noop if the seekHit flag is set.
++**
++** This opcode is used in IN clause processing for a multi-column key.
++** If an IN clause is attached to an element of the key other than the
++** left-most element, and if there are no matches on the most recent
++** seek over the whole key, then it might be that one of the key element
++** to the left is prohibiting a match, and hence there is "no hope" of
++** any match regardless of how many IN clause elements are checked.
++** In such a case, we abandon the IN clause search early, using this
++** opcode.  The opcode name comes from the fact that the
++** jump is taken if there is "no hope" of achieving a match.
++**
++** See also: NotFound, SeekHit
++*/
+ /* Opcode: NoConflict P1 P2 P3 P4 *
+ ** Synopsis: key=r[P3@P4]
+ **
+@@ -85313,6 +87145,14 @@
+ **
+ ** See also: NotFound, Found, NotExists
+ */
++case OP_IfNoHope: {     /* jump, in3 */
++  VdbeCursor *pC;
++  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
++  pC = p->apCsr[pOp->p1];
++  assert( pC!=0 );
++  if( pC->seekHit ) break;
++  /* Fall through into OP_NotFound */
++}
+ case OP_NoConflict:     /* jump, in3 */
+ case OP_NotFound:       /* jump, in3 */
+ case OP_Found: {        /* jump, in3 */
+@@ -85450,18 +87290,26 @@
+ 
+   pIn3 = &aMem[pOp->p3];
+   if( (pIn3->flags & MEM_Int)==0 ){
++    /* Make sure pIn3->u.i contains a valid integer representation of
++    ** the key value, but do not change the datatype of the register, as
++    ** other parts of the perpared statement might be depending on the
++    ** current datatype. */
++    u16 origFlags = pIn3->flags;
++    int isNotInt;
+     applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
+-    if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2;
++    isNotInt = (pIn3->flags & MEM_Int)==0;
++    pIn3->flags = origFlags;
++    if( isNotInt ) goto jump_to_p2;
+   }
+   /* Fall through into OP_NotExists */
+ case OP_NotExists:          /* jump, in3 */
+   pIn3 = &aMem[pOp->p3];
+-  assert( pIn3->flags & MEM_Int );
++  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+ #ifdef SQLITE_DEBUG
+-  pC->seekOp = 0;
++  pC->seekOp = OP_SeekRowid;
+ #endif
+   assert( pC->isTable );
+   assert( pC->eCurType==CURTYPE_BTREE );
+@@ -85535,11 +87383,8 @@
+   pOut = out2Prerelease(p, pOp);
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
+-  if( !pC->isTable ){
+-    rc = SQLITE_CORRUPT_BKPT;
+-    goto abort_due_to_error;
+-  }
+   assert( pC!=0 );
++  assert( pC->isTable );
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pC->uc.pCursor!=0 );
+   {
+@@ -85708,6 +87553,7 @@
+   assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
+   assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
+   REGISTER_TRACE(pOp->p2, pData);
++  sqlite3VdbeIncrWriteCounter(p, pC);
+ 
+   if( pOp->opcode==OP_Insert ){
+     pKey = &aMem[pOp->p3];
+@@ -85822,6 +87668,7 @@
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pC->uc.pCursor!=0 );
+   assert( pC->deferredMoveto==0 );
++  sqlite3VdbeIncrWriteCounter(p, pC);
+ 
+ #ifdef SQLITE_DEBUG
+   if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
+@@ -85990,10 +87837,10 @@
+ ** If the P1 cursor must be pointing to a valid row (not a NULL row)
+ ** of a real table, not a pseudo-table.
+ **
+-** If P3!=0 then this opcode is allowed to make an ephermeral pointer
++** If P3!=0 then this opcode is allowed to make an ephemeral pointer
+ ** into the database page.  That means that the content of the output
+ ** register will be invalidated as soon as the cursor moves - including
+-** moves caused by other cursors that "save" the the current cursors
++** moves caused by other cursors that "save" the current cursors
+ ** position in order that they can write to the same table.  If P3==0
+ ** then a copy of the data is made into memory.  P3!=0 is faster, but
+ ** P3==0 is safer.
+@@ -86116,6 +87963,9 @@
+     assert( pC->uc.pCursor!=0 );
+     sqlite3BtreeClearCursor(pC->uc.pCursor);
+   }
++#ifdef SQLITE_DEBUG
++  if( pC->seekOp==0 ) pC->seekOp = OP_NullRow;
++#endif
+   break;
+ }
+ 
+@@ -86234,7 +88084,7 @@
+   p->aCounter[SQLITE_STMTSTATUS_SORT]++;
+   /* Fall through into OP_Rewind */
+ }
+-/* Opcode: Rewind P1 P2 * * *
++/* Opcode: Rewind P1 P2 * * P5
+ **
+ ** The next use of the Rowid or Column or Next instruction for P1 
+ ** will refer to the first entry in the database table or index.
+@@ -86242,6 +88092,10 @@
+ ** If the table or index is not empty, fall through to the following 
+ ** instruction.
+ **
++** If P5 is non-zero and the table is not empty, then the "skip-next"
++** flag is set on the cursor so that the next OP_Next instruction 
++** executed on it is a no-op.
++**
+ ** This opcode leaves the cursor configured to move in forward order,
+ ** from the beginning toward the end.  In other words, the cursor is
+ ** configured to use Next, not Prev.
+@@ -86266,6 +88120,9 @@
+     pCrsr = pC->uc.pCursor;
+     assert( pCrsr );
+     rc = sqlite3BtreeFirst(pCrsr, &res);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
++#endif
+     pC->deferredMoveto = 0;
+     pC->cacheStatus = CACHE_STALE;
+   }
+@@ -86302,13 +88159,8 @@
+ ** If P5 is positive and the jump is taken, then event counter
+ ** number P5-1 in the prepared statement is incremented.
+ **
+-** See also: Prev, NextIfOpen
++** See also: Prev
+ */
+-/* Opcode: NextIfOpen P1 P2 P3 P4 P5
+-**
+-** This opcode works just like Next except that if cursor P1 is not
+-** open it behaves a no-op.
+-*/
+ /* Opcode: Prev P1 P2 P3 P4 P5
+ **
+ ** Back up cursor P1 so that it points to the previous key/data pair in its
+@@ -86335,11 +88187,6 @@
+ ** If P5 is positive and the jump is taken, then event counter
+ ** number P5-1 in the prepared statement is incremented.
+ */
+-/* Opcode: PrevIfOpen P1 P2 P3 P4 P5
+-**
+-** This opcode works just like Prev except that if cursor P1 is not
+-** open it behaves a no-op.
+-*/
+ /* Opcode: SorterNext P1 P2 * * P5
+ **
+ ** This opcode works just like OP_Next except that P1 must be a
+@@ -86354,10 +88201,6 @@
+   assert( isSorter(pC) );
+   rc = sqlite3VdbeSorterNext(db, pC);
+   goto next_tail;
+-case OP_PrevIfOpen:    /* jump */
+-case OP_NextIfOpen:    /* jump */
+-  if( p->apCsr[pOp->p1]==0 ) break;
+-  /* Fall through */
+ case OP_Prev:          /* jump */
+ case OP_Next:          /* jump */
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+@@ -86368,17 +88211,17 @@
+   assert( pC->eCurType==CURTYPE_BTREE );
+   assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
+   assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+-  assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
+-  assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
+ 
+-  /* The Next opcode is only used after SeekGT, SeekGE, and Rewind.
++  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
+   ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
+-  assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen
++  assert( pOp->opcode!=OP_Next
+        || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
+-       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found);
+-  assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen
++       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
++       || pC->seekOp==OP_NullRow);
++  assert( pOp->opcode!=OP_Prev
+        || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
+-       || pC->seekOp==OP_Last );
++       || pC->seekOp==OP_Last 
++       || pC->seekOp==OP_NullRow);
+ 
+   rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
+ next_tail:
+@@ -86440,6 +88283,7 @@
+ 
+   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+   pC = p->apCsr[pOp->p1];
++  sqlite3VdbeIncrWriteCounter(p, pC);
+   assert( pC!=0 );
+   assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
+   pIn2 = &aMem[pOp->p2];
+@@ -86486,6 +88330,7 @@
+   pC = p->apCsr[pOp->p1];
+   assert( pC!=0 );
+   assert( pC->eCurType==CURTYPE_BTREE );
++  sqlite3VdbeIncrWriteCounter(p, pC);
+   pCrsr = pC->uc.pCursor;
+   assert( pCrsr!=0 );
+   assert( pOp->p5==0 );
+@@ -86659,7 +88504,13 @@
+   }
+   r.aMem = &aMem[pOp->p3];
+ #ifdef SQLITE_DEBUG
+-  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
++  {
++    int i;
++    for(i=0; i<r.nField; i++){
++      assert( memIsValid(&r.aMem[i]) );
++      REGISTER_TRACE(pOp->p3+i, &aMem[pOp->p3+i]);
++    }
++  }
+ #endif
+   res = 0;  /* Not needed.  Only used to silence a warning. */
+   rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
+@@ -86708,6 +88559,7 @@
+   int iMoved;
+   int iDb;
+ 
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   assert( p->readOnly==0 );
+   assert( pOp->p1>1 );
+   pOut = out2Prerelease(p, pOp);
+@@ -86757,6 +88609,7 @@
+ case OP_Clear: {
+   int nChange;
+  
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   nChange = 0;
+   assert( p->readOnly==0 );
+   assert( DbMaskTest(p->btreeMask, pOp->p2) );
+@@ -86806,7 +88659,7 @@
+ ** Allocate a new b-tree in the main database file if P1==0 or in the
+ ** TEMP database file if P1==1 or in an attached database if
+ ** P1>1.  The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
+-** it must be 2 (BTREE_BLOBKEY) for a index or WITHOUT ROWID table.
++** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table.
+ ** The root page number of the new b-tree is stored in register P2.
+ */
+ case OP_CreateBtree: {          /* out2 */
+@@ -86813,6 +88666,7 @@
+   int pgno;
+   Db *pDb;
+ 
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   pOut = out2Prerelease(p, pOp);
+   pgno = 0;
+   assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
+@@ -86832,6 +88686,7 @@
+ ** Run the SQL statement or statements specified in the P4 string.
+ */
+ case OP_SqlExec: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   db->nSqlExec++;
+   rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
+   db->nSqlExec--;
+@@ -86842,7 +88697,8 @@
+ /* Opcode: ParseSchema P1 * * P4 *
+ **
+ ** Read and parse all entries from the SQLITE_MASTER table of database P1
+-** that match the WHERE clause P4. 
++** that match the WHERE clause P4.  If P4 is a NULL pointer, then the
++** entire schema for P1 is reparsed.
+ **
+ ** This opcode invokes the parser to create a new virtual machine,
+ ** then runs the new virtual machine.  It is thus a re-entrant opcode.
+@@ -86866,11 +88722,22 @@
+   iDb = pOp->p1;
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
+-  /* Used to be a conditional */ {
++
++#ifndef SQLITE_OMIT_ALTERTABLE
++  if( pOp->p4.z==0 ){
++    sqlite3SchemaClear(db->aDb[iDb].pSchema);
++    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
++    rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable);
++    db->mDbFlags |= DBFLAG_SchemaChange;
++    p->expired = 0;
++  }else
++#endif
++  {
+     zMaster = MASTER_NAME;
+     initData.db = db;
+-    initData.iDb = pOp->p1;
++    initData.iDb = iDb;
+     initData.pzErrMsg = &p->zErrMsg;
++    initData.mInitFlags = 0;
+     zSql = sqlite3MPrintf(db,
+        "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
+        db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
+@@ -86921,6 +88788,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropTable: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -86934,6 +88802,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropIndex: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -86947,6 +88816,7 @@
+ ** schema consistent with what is on disk.
+ */
+ case OP_DropTrigger: {
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
+   break;
+ }
+@@ -87020,11 +88890,11 @@
+   pIn1 = &aMem[pOp->p1];
+   pIn2 = &aMem[pOp->p2];
+   assert( (pIn2->flags & MEM_Int)!=0 );
+-  if( (pIn1->flags & MEM_RowSet)==0 ){
+-    sqlite3VdbeMemSetRowSet(pIn1);
+-    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
++  if( (pIn1->flags & MEM_Blob)==0 ){
++    if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
+   }
+-  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
++  assert( sqlite3VdbeMemIsRowSet(pIn1) );
++  sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i);
+   break;
+ }
+ 
+@@ -87040,8 +88910,9 @@
+   i64 val;
+ 
+   pIn1 = &aMem[pOp->p1];
+-  if( (pIn1->flags & MEM_RowSet)==0 
+-   || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
++  assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) );
++  if( (pIn1->flags & MEM_Blob)==0 
++   || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0
+   ){
+     /* The boolean index is empty */
+     sqlite3VdbeMemSetNull(pIn1);
+@@ -87090,20 +88961,19 @@
+   /* If there is anything other than a rowset object in memory cell P1,
+   ** delete it now and initialize P1 with an empty rowset
+   */
+-  if( (pIn1->flags & MEM_RowSet)==0 ){
+-    sqlite3VdbeMemSetRowSet(pIn1);
+-    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
++  if( (pIn1->flags & MEM_Blob)==0 ){
++    if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem;
+   }
+-
++  assert( sqlite3VdbeMemIsRowSet(pIn1) );
+   assert( pOp->p4type==P4_INT32 );
+   assert( iSet==-1 || iSet>=0 );
+   if( iSet ){
+-    exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
++    exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i);
+     VdbeBranchTaken(exists!=0,2);
+     if( exists ) goto jump_to_p2;
+   }
+   if( iSet>=0 ){
+-    sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
++    sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i);
+   }
+   break;
+ }
+@@ -87167,7 +89037,7 @@
+   ** of the current program, and the memory required at runtime to execute
+   ** the trigger program. If this trigger has been fired before, then pRt 
+   ** is already allocated. Otherwise, it must be initialized.  */
+-  if( (pRt->flags&MEM_Frame)==0 ){
++  if( (pRt->flags&MEM_Blob)==0 ){
+     /* SubProgram.nMem is set to the number of memory cells used by the 
+     ** program stored in SubProgram.aOp. As well as these, one memory
+     ** cell is required for each cursor used by the program. Set local
+@@ -87185,8 +89055,10 @@
+       goto no_mem;
+     }
+     sqlite3VdbeMemRelease(pRt);
+-    pRt->flags = MEM_Frame;
+-    pRt->u.pFrame = pFrame;
++    pRt->flags = MEM_Blob|MEM_Dyn;
++    pRt->z = (char*)pFrame;
++    pRt->n = nByte;
++    pRt->xDel = sqlite3VdbeFrameMemDel;
+ 
+     pFrame->v = p;
+     pFrame->nChildMem = nMem;
+@@ -87202,6 +89074,9 @@
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+     pFrame->anExec = p->anExec;
+ #endif
++#ifdef SQLITE_DEBUG
++    pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
++#endif
+ 
+     pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
+     for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
+@@ -87209,7 +89084,8 @@
+       pMem->db = db;
+     }
+   }else{
+-    pFrame = pRt->u.pFrame;
++    pFrame = (VdbeFrame*)pRt->z;
++    assert( pRt->xDel==sqlite3VdbeFrameMemDel );
+     assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem 
+         || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) );
+     assert( pProgram->nCsr==pFrame->nChildCsr );
+@@ -87438,24 +89314,35 @@
+ }
+ 
+ 
+-/* Opcode: AggStep0 * P2 P3 P4 P5
++/* Opcode: AggStep * P2 P3 P4 P5
+ ** Synopsis: accum=r[P3] step(r[P2@P5])
+ **
+-** Execute the step function for an aggregate.  The
+-** function has P5 arguments.   P4 is a pointer to the FuncDef
+-** structure that specifies the function.  Register P3 is the
++** Execute the xStep function for an aggregate.
++** The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
+ ** accumulator.
+ **
+ ** The P5 arguments are taken from register P2 and its
+ ** successors.
+ */
+-/* Opcode: AggStep * P2 P3 P4 P5
++/* Opcode: AggInverse * P2 P3 P4 P5
++** Synopsis: accum=r[P3] inverse(r[P2@P5])
++**
++** Execute the xInverse function for an aggregate.
++** The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
++** accumulator.
++**
++** The P5 arguments are taken from register P2 and its
++** successors.
++*/
++/* Opcode: AggStep1 P1 P2 P3 P4 P5
+ ** Synopsis: accum=r[P3] step(r[P2@P5])
+ **
+-** Execute the step function for an aggregate.  The
+-** function has P5 arguments.   P4 is a pointer to an sqlite3_context
+-** object that is used to run the function.  Register P3 is
+-** as the accumulator.
++** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
++** aggregate.  The function has P5 arguments.  P4 is a pointer to the 
++** FuncDef structure that specifies the function.  Register P3 is the
++** accumulator.
+ **
+ ** The P5 arguments are taken from register P2 and its
+ ** successors.
+@@ -87466,7 +89353,8 @@
+ ** sqlite3_context only happens once, instead of on each call to the
+ ** step function.
+ */
+-case OP_AggStep0: {
++case OP_AggInverse:
++case OP_AggStep: {
+   int n;
+   sqlite3_context *pCtx;
+ 
+@@ -87489,10 +89377,14 @@
+   pCtx->argc = n;
+   pOp->p4type = P4_FUNCCTX;
+   pOp->p4.pCtx = pCtx;
+-  pOp->opcode = OP_AggStep;
++
++  /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */
++  assert( pOp->p1==(pOp->opcode==OP_AggInverse) );
++
++  pOp->opcode = OP_AggStep1;
+   /* Fall through into OP_AggStep */
+ }
+-case OP_AggStep: {
++case OP_AggStep1: {
+   int i;
+   sqlite3_context *pCtx;
+   Mem *pMem;
+@@ -87501,6 +89393,17 @@
+   pCtx = pOp->p4.pCtx;
+   pMem = &aMem[pOp->p3];
+ 
++#ifdef SQLITE_DEBUG
++  if( pOp->p1 ){
++    /* This is an OP_AggInverse call.  Verify that xStep has always
++    ** been called at least once prior to any xInverse call. */
++    assert( pMem->uTemp==0x1122e0e3 );
++  }else{
++    /* This is an OP_AggStep call.  Mark it as such. */
++    pMem->uTemp = 0x1122e0e3;
++  }
++#endif
++
+   /* If this function is inside of a trigger, the register array in aMem[]
+   ** might change from one evaluation to the next.  The next block of code
+   ** checks to see if the register array has changed, and if so it
+@@ -87521,7 +89424,13 @@
+   assert( pCtx->pOut->flags==MEM_Null );
+   assert( pCtx->isError==0 );
+   assert( pCtx->skipFlag==0 );
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pOp->p1 ){
++    (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv);
++  }else
++#endif
+   (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
++
+   if( pCtx->isError ){
+     if( pCtx->isError>0 ){
+       sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+@@ -87546,22 +89455,46 @@
+ /* Opcode: AggFinal P1 P2 * P4 *
+ ** Synopsis: accum=r[P1] N=P2
+ **
+-** Execute the finalizer function for an aggregate.  P1 is
+-** the memory location that is the accumulator for the aggregate.
++** P1 is the memory location that is the accumulator for an aggregate
++** or window function.  Execute the finalizer function 
++** for an aggregate and store the result in P1.
+ **
+ ** P2 is the number of arguments that the step function takes and
+ ** P4 is a pointer to the FuncDef for this function.  The P2
+ ** argument is not used by this opcode.  It is only there to disambiguate
+ ** functions that can take varying numbers of arguments.  The
+-** P4 argument is only needed for the degenerate case where
++** P4 argument is only needed for the case where
+ ** the step function was not previously called.
+ */
++/* Opcode: AggValue * P2 P3 P4 *
++** Synopsis: r[P3]=value N=P2
++**
++** Invoke the xValue() function and store the result in register P3.
++**
++** P2 is the number of arguments that the step function takes and
++** P4 is a pointer to the FuncDef for this function.  The P2
++** argument is not used by this opcode.  It is only there to disambiguate
++** functions that can take varying numbers of arguments.  The
++** P4 argument is only needed for the case where
++** the step function was not previously called.
++*/
++case OP_AggValue:
+ case OP_AggFinal: {
+   Mem *pMem;
+   assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
++  assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
+   pMem = &aMem[pOp->p1];
+   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+-  rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pOp->p3 ){
++    rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
++    pMem = &aMem[pOp->p3];
++  }else
++#endif
++  {
++    rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
++  }
++  
+   if( rc ){
+     sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
+     goto abort_due_to_error;
+@@ -87756,7 +89689,7 @@
+ }
+ #endif
+ 
+-/* Opcode: Expire P1 * * * *
++/* Opcode: Expire P1 P2 * * *
+ **
+ ** Cause precompiled statements to expire.  When an expired statement
+ ** is executed using sqlite3_step() it will either automatically
+@@ -87765,12 +89698,19 @@
+ ** 
+ ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
+ ** then only the currently executing statement is expired.
++**
++** If P2 is 0, then SQL statements are expired immediately.  If P2 is 1,
++** then running SQL statements are allowed to continue to run to completion.
++** The P2==1 case occurs when a CREATE INDEX or similar schema change happens
++** that might help the statement run faster but which does not affect the
++** correctness of operation.
+ */
+ case OP_Expire: {
++  assert( pOp->p2==0 || pOp->p2==1 );
+   if( !pOp->p1 ){
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, pOp->p2);
+   }else{
+-    p->expired = 1;
++    p->expired = pOp->p2+1;
+   }
+   break;
+ }
+@@ -87992,10 +89932,11 @@
+ **
+ ** If the VColumn opcode is being used to fetch the value of
+ ** an unchanging column during an UPDATE operation, then the P5
+-** value is 1.  Otherwise, P5 is 0.  The P5 value is returned
+-** by sqlite3_vtab_nochange() routine can can be used
+-** by virtual table implementations to return special "no-change"
+-** marks which can be more efficient, depending on the virtual table.
++** value is OPFLAG_NOCHNG.  This will cause the sqlite3_vtab_nochange()
++** function to return true inside the xColumn method of the virtual
++** table implementation.  The P5 column might also contain other
++** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
++** unused by OP_VColumn.
+ */
+ case OP_VColumn: {
+   sqlite3_vtab *pVtab;
+@@ -88017,7 +89958,8 @@
+   assert( pModule->xColumn );
+   memset(&sContext, 0, sizeof(sContext));
+   sContext.pOut = pDest;
+-  if( pOp->p5 ){
++  testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
++  if( pOp->p5 & OPFLAG_NOCHNG ){
+     sqlite3VdbeMemSetNull(pDest);
+     pDest->flags = MEM_Null|MEM_Zero;
+     pDest->u.nZero = 0;
+@@ -88094,7 +90036,10 @@
+ case OP_VRename: {
+   sqlite3_vtab *pVtab;
+   Mem *pName;
+-
++  int isLegacy;
++  
++  isLegacy = (db->flags & SQLITE_LegacyAlter);
++  db->flags |= SQLITE_LegacyAlter;
+   pVtab = pOp->p4.pVtab->pVtab;
+   pName = &aMem[pOp->p1];
+   assert( pVtab->pModule->xRename );
+@@ -88108,6 +90053,7 @@
+   rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
+   if( rc ) goto abort_due_to_error;
+   rc = pVtab->pModule->xRename(pVtab, pName->z);
++  if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter;
+   sqlite3VtabImportErrmsg(p, pVtab);
+   p->expired = 0;
+   if( rc ) goto abort_due_to_error;
+@@ -88156,6 +90102,8 @@
+        || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
+   );
+   assert( p->readOnly==0 );
++  if( db->mallocFailed ) goto no_mem;
++  sqlite3VdbeIncrWriteCounter(p, 0);
+   pVtab = pOp->p4.pVtab->pVtab;
+   if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+     rc = SQLITE_LOCKED;
+@@ -88276,8 +90224,8 @@
+ **
+ ** See also: Function0, AggStep, AggFinal
+ */
+-case OP_PureFunc0:
+-case OP_Function0: {
++case OP_PureFunc0:              /* group */
++case OP_Function0: {            /* group */
+   int n;
+   sqlite3_context *pCtx;
+ 
+@@ -88301,8 +90249,8 @@
+   pOp->opcode += 2;
+   /* Fall through into OP_Function */
+ }
+-case OP_PureFunc:
+-case OP_Function: {
++case OP_PureFunc:              /* group */
++case OP_Function: {            /* group */
+   int i;
+   sqlite3_context *pCtx;
+ 
+@@ -88473,6 +90421,22 @@
+ }
+ #endif /* SQLITE_ENABLE_CURSOR_HINTS */
+ 
++#ifdef SQLITE_DEBUG
++/* Opcode:  Abortable   * * * * *
++**
++** Verify that an Abort can happen.  Assert if an Abort at this point
++** might cause database corruption.  This opcode only appears in debugging
++** builds.
++**
++** An Abort is safe if either there have been no writes, or if there is
++** an active statement journal.
++*/
++case OP_Abortable: {
++  sqlite3VdbeAssertAbortable(p);
++  break;
++}
++#endif
++
+ /* Opcode: Noop * * * * *
+ **
+ ** Do nothing.  This instruction is often useful as a jump
+@@ -88484,8 +90448,9 @@
+ ** This opcode records information from the optimizer.  It is the
+ ** the same as a no-op.  This opcodesnever appears in a real VM program.
+ */
+-default: {          /* This is really OP_Noop and OP_Explain */
++default: {          /* This is really OP_Noop, OP_Explain */
+   assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
++
+   break;
+ }
+ 
+@@ -91210,8 +93175,12 @@
+ ){
+   int rc = SQLITE_OK;             /* Return code */
+   int i;                          /* For looping over PmaReader objects */
+-  int nTree = pMerger->nTree;
++  int nTree;                      /* Number of subtrees to merge */
+ 
++  /* Failure to allocate the merge would have been detected prior to
++  ** invoking this routine */
++  assert( pMerger!=0 );
++
+   /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+   assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+ 
+@@ -91219,6 +93188,7 @@
+   assert( pMerger->pTask==0 );
+   pMerger->pTask = pTask;
+ 
++  nTree = pMerger->nTree;
+   for(i=0; i<nTree; i++){
+     if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
+       /* PmaReaders should be normally initialized in order, as if they are
+@@ -92347,6 +94317,14 @@
+       }else if( pExpr->x.pList ){
+         if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
+       }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(pExpr, EP_WinFunc) ){
++        Window *pWin = pExpr->y.pWin;
++        if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
++        if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
++        if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
++      }
++#endif
+     }
+     break;
+   }
+@@ -92530,29 +94508,31 @@
+   assert( pOrig!=0 );
+   db = pParse->db;
+   pDup = sqlite3ExprDup(db, pOrig, 0);
+-  if( pDup==0 ) return;
+-  if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
+-  if( pExpr->op==TK_COLLATE ){
+-    pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
+-  }
+-  ExprSetProperty(pDup, EP_Alias);
++  if( pDup!=0 ){
++    if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
++    if( pExpr->op==TK_COLLATE ){
++      pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
++    }
++    ExprSetProperty(pDup, EP_Alias);
+ 
+-  /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
+-  ** prevents ExprDelete() from deleting the Expr structure itself,
+-  ** allowing it to be repopulated by the memcpy() on the following line.
+-  ** The pExpr->u.zToken might point into memory that will be freed by the
+-  ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
+-  ** make a copy of the token before doing the sqlite3DbFree().
+-  */
+-  ExprSetProperty(pExpr, EP_Static);
+-  sqlite3ExprDelete(db, pExpr);
+-  memcpy(pExpr, pDup, sizeof(*pExpr));
+-  if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
+-    assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
+-    pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
+-    pExpr->flags |= EP_MemToken;
++    /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
++    ** prevents ExprDelete() from deleting the Expr structure itself,
++    ** allowing it to be repopulated by the memcpy() on the following line.
++    ** The pExpr->u.zToken might point into memory that will be freed by the
++    ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
++    ** make a copy of the token before doing the sqlite3DbFree().
++    */
++    ExprSetProperty(pExpr, EP_Static);
++    sqlite3ExprDelete(db, pExpr);
++    memcpy(pExpr, pDup, sizeof(*pExpr));
++    if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
++      assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
++      pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
++      pExpr->flags |= EP_MemToken;
++    }
++    sqlite3DbFree(db, pDup);
+   }
+-  sqlite3DbFree(db, pDup);
++  ExprSetProperty(pExpr, EP_Alias);
+ }
+ 
+ 
+@@ -92612,7 +94592,7 @@
+ **                         (even if X is implied).
+ **    pExpr->iTable        Set to the cursor number for the table obtained
+ **                         from pSrcList.
+-**    pExpr->pTab          Points to the Table structure of X.Y (even if
++**    pExpr->y.pTab        Points to the Table structure of X.Y (even if
+ **                         X and/or Y are implied.)
+ **    pExpr->iColumn       Set to the column number within the table.
+ **    pExpr->op            Set to TK_COLUMN.
+@@ -92646,7 +94626,7 @@
+   struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
+   NameContext *pTopNC = pNC;        /* First namecontext in the list */
+   Schema *pSchema = 0;              /* Schema of the expression */
+-  int isTrigger = 0;                /* True if resolved to a trigger column */
++  int eNewExprOp = TK_COLUMN;       /* New value for pExpr->op on success */
+   Table *pTab = 0;                  /* Table hold the row */
+   Column *pCol;                     /* A column of pTab */
+ 
+@@ -92656,7 +94636,6 @@
+ 
+   /* Initialize the node to no-match */
+   pExpr->iTable = -1;
+-  pExpr->pTab = 0;
+   ExprSetVVAProperty(pExpr, EP_NoReduce);
+ 
+   /* Translate the schema name in zDb into a pointer to the corresponding
+@@ -92717,6 +94696,9 @@
+           if( sqlite3StrICmp(zTabName, zTab)!=0 ){
+             continue;
+           }
++          if( IN_RENAME_OBJECT && pItem->zAlias ){
++            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
++          }
+         }
+         if( 0==(cntTab++) ){
+           pMatch = pItem;
+@@ -92741,32 +94723,45 @@
+       }
+       if( pMatch ){
+         pExpr->iTable = pMatch->iCursor;
+-        pExpr->pTab = pMatch->pTab;
++        pExpr->y.pTab = pMatch->pTab;
+         /* RIGHT JOIN not (yet) supported */
+         assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
+         if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+           ExprSetProperty(pExpr, EP_CanBeNull);
+         }
+-        pSchema = pExpr->pTab->pSchema;
++        pSchema = pExpr->y.pTab->pSchema;
+       }
+     } /* if( pSrcList ) */
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
++#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
+     /* If we have not already resolved the name, then maybe 
+-    ** it is a new.* or old.* trigger argument reference
++    ** it is a new.* or old.* trigger argument reference.  Or
++    ** maybe it is an excluded.* from an upsert.
+     */
+-    if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
+-      int op = pParse->eTriggerOp;
+-      assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
+-      if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
+-        pExpr->iTable = 1;
+-        pTab = pParse->pTriggerTab;
+-      }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
+-        pExpr->iTable = 0;
+-        pTab = pParse->pTriggerTab;
+-      }else{
+-        pTab = 0;
++    if( zDb==0 && zTab!=0 && cntTab==0 ){
++      pTab = 0;
++#ifndef SQLITE_OMIT_TRIGGER
++      if( pParse->pTriggerTab!=0 ){
++        int op = pParse->eTriggerOp;
++        assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
++        if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
++          pExpr->iTable = 1;
++          pTab = pParse->pTriggerTab;
++        }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
++          pExpr->iTable = 0;
++          pTab = pParse->pTriggerTab;
++        }
+       }
++#endif /* SQLITE_OMIT_TRIGGER */
++#ifndef SQLITE_OMIT_UPSERT
++      if( (pNC->ncFlags & NC_UUpsert)!=0 ){
++        Upsert *pUpsert = pNC->uNC.pUpsert;
++        if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
++          pTab = pUpsert->pUpsertSrc->a[0].pTab;
++          pExpr->iTable = 2;
++        }
++      }
++#endif /* SQLITE_OMIT_UPSERT */
+ 
+       if( pTab ){ 
+         int iCol;
+@@ -92786,24 +94781,42 @@
+         }
+         if( iCol<pTab->nCol ){
+           cnt++;
+-          if( iCol<0 ){
+-            pExpr->affinity = SQLITE_AFF_INTEGER;
+-          }else if( pExpr->iTable==0 ){
+-            testcase( iCol==31 );
+-            testcase( iCol==32 );
+-            pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
+-          }else{
+-            testcase( iCol==31 );
+-            testcase( iCol==32 );
+-            pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++#ifndef SQLITE_OMIT_UPSERT
++          if( pExpr->iTable==2 ){
++            testcase( iCol==(-1) );
++            if( IN_RENAME_OBJECT ){
++              pExpr->iColumn = iCol;
++              pExpr->y.pTab = pTab;
++              eNewExprOp = TK_COLUMN;
++            }else{
++              pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
++              eNewExprOp = TK_REGISTER;
++              ExprSetProperty(pExpr, EP_Alias);
++            }
++          }else
++#endif /* SQLITE_OMIT_UPSERT */
++          {
++#ifndef SQLITE_OMIT_TRIGGER
++            if( iCol<0 ){
++              pExpr->affinity = SQLITE_AFF_INTEGER;
++            }else if( pExpr->iTable==0 ){
++              testcase( iCol==31 );
++              testcase( iCol==32 );
++              pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++            }else{
++              testcase( iCol==31 );
++              testcase( iCol==32 );
++              pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
++            }
++            pExpr->y.pTab = pTab;
++            pExpr->iColumn = (i16)iCol;
++            eNewExprOp = TK_TRIGGER;
++#endif /* SQLITE_OMIT_TRIGGER */
+           }
+-          pExpr->iColumn = (i16)iCol;
+-          pExpr->pTab = pTab;
+-          isTrigger = 1;
+         }
+       }
+     }
+-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
++#endif /* !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) */
+ 
+     /*
+     ** Perhaps the name is a reference to the ROWID
+@@ -92838,10 +94851,12 @@
+     ** is supported for backwards compatibility only. Hence, we issue a warning
+     ** on sqlite3_log() whenever the capability is used.
+     */
+-    if( (pEList = pNC->pEList)!=0
++    if( (pNC->ncFlags & NC_UEList)!=0
++     && cnt==0
+      && zTab==0
+-     && cnt==0
+     ){
++      pEList = pNC->uNC.pEList;
++      assert( pEList!=0 );
+       for(j=0; j<pEList->nExpr; j++){
+         char *zAs = pEList->a[j].zName;
+         if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
+@@ -92862,6 +94877,9 @@
+           cnt = 1;
+           pMatch = 0;
+           assert( zTab==0 && zDb==0 );
++          if( IN_RENAME_OBJECT ){
++            sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
++          }
+           goto lookupname_end;
+         }
+       } 
+@@ -92890,7 +94908,7 @@
+     assert( pExpr->op==TK_ID );
+     if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+       pExpr->op = TK_STRING;
+-      pExpr->pTab = 0;
++      pExpr->y.pTab = 0;
+       return WRC_Prune;
+     }
+     if( sqlite3ExprIdToTrueFalse(pExpr) ){
+@@ -92938,7 +94956,7 @@
+   pExpr->pLeft = 0;
+   sqlite3ExprDelete(db, pExpr->pRight);
+   pExpr->pRight = 0;
+-  pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
++  pExpr->op = eNewExprOp;
+   ExprSetProperty(pExpr, EP_Leaf);
+ lookupname_end:
+   if( cnt==1 ){
+@@ -92968,9 +94986,9 @@
+   Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
+   if( p ){
+     struct SrcList_item *pItem = &pSrc->a[iSrc];
+-    p->pTab = pItem->pTab;
++    p->y.pTab = pItem->pTab;
+     p->iTable = pItem->iCursor;
+-    if( p->pTab->iPKey==iCol ){
++    if( p->y.pTab->iPKey==iCol ){
+       p->iColumn = -1;
+     }else{
+       p->iColumn = (ynVar)iCol;
+@@ -93060,7 +95078,7 @@
+       pItem = pSrcList->a;
+       assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
+       pExpr->op = TK_COLUMN;
+-      pExpr->pTab = pItem->pTab;
++      pExpr->y.pTab = pItem->pTab;
+       pExpr->iTable = pItem->iCursor;
+       pExpr->iColumn = -1;
+       pExpr->affinity = SQLITE_AFF_INTEGER;
+@@ -93089,18 +95107,23 @@
+         zTable = 0;
+         zColumn = pExpr->u.zToken;
+       }else{
++        Expr *pLeft = pExpr->pLeft;
+         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;
++          zDb = pLeft->u.zToken;
++          pLeft = pRight->pLeft;
++          pRight = pRight->pRight;
+         }
++        zTable = pLeft->u.zToken;
++        zColumn = pRight->u.zToken;
++        if( IN_RENAME_OBJECT ){
++          sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
++          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
++        }
+       }
+       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
+     }
+@@ -93181,41 +95204,105 @@
+           notValid(pParse, pNC, "non-deterministic functions",
+                    NC_IdxExpr|NC_PartIdx);
+         }
++        if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
++         && pParse->nested==0
++         && sqlite3Config.bInternalFunctions==0
++        ){
++          /* Internal-use-only functions are disallowed unless the
++          ** SQL is being compiled using sqlite3NestedParse() */
++          no_such_func = 1;
++          pDef = 0;
++        }
+       }
+-      if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
+-        sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
+-        pNC->nErr++;
+-        is_agg = 0;
+-      }else if( no_such_func && pParse->db->init.busy==0
++
++      if( 0==IN_RENAME_OBJECT ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
++          || (pDef->xValue==0 && pDef->xInverse==0)
++          || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
++        );
++        if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
++          sqlite3ErrorMsg(pParse, 
++              "%.*s() may not be used as a window function", nId, zId
++          );
++          pNC->nErr++;
++        }else if( 
++              (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
++           || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
++           || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
++        ){
++          const char *zType;
++          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
++            zType = "window";
++          }else{
++            zType = "aggregate";
++          }
++          sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
++          pNC->nErr++;
++          is_agg = 0;
++        }
++#else
++        if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){
++          sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId);
++          pNC->nErr++;
++          is_agg = 0;
++        }
++#endif
++        else if( no_such_func && pParse->db->init.busy==0
+ #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+-                && pParse->explain==0
++                  && pParse->explain==0
+ #endif
+-      ){
+-        sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
+-        pNC->nErr++;
+-      }else if( wrong_num_args ){
+-        sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
+-             nId, zId);
+-        pNC->nErr++;
++        ){
++          sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
++          pNC->nErr++;
++        }else if( wrong_num_args ){
++          sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
++               nId, zId);
++          pNC->nErr++;
++        }
++        if( is_agg ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++          pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
++#else
++          pNC->ncFlags &= ~NC_AllowAgg;
++#endif
++        }
+       }
+-      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
+       sqlite3WalkExprList(pWalker, pList);
+       if( is_agg ){
+-        NameContext *pNC2 = pNC;
+-        pExpr->op = TK_AGG_FUNCTION;
+-        pExpr->op2 = 0;
+-        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
+-          pExpr->op2++;
+-          pNC2 = pNC2->pNext;
+-        }
+-        assert( pDef!=0 );
+-        if( pNC2 ){
+-          assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
+-          testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
+-          pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        if( pExpr->y.pWin ){
++          Select *pSel = pNC->pWinSelect;
++          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
++          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
++          sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
++          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
++          if( 0==pSel->pWin 
++           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
++          ){
++            pExpr->y.pWin->pNextWin = pSel->pWin;
++            pSel->pWin = pExpr->y.pWin;
++          }
++          pNC->ncFlags |= NC_AllowWin;
++        }else
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++        {
++          NameContext *pNC2 = pNC;
++          pExpr->op = TK_AGG_FUNCTION;
++          pExpr->op2 = 0;
++          while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
++            pExpr->op2++;
++            pNC2 = pNC2->pNext;
++          }
++          assert( pDef!=0 );
++          if( pNC2 ){
++            assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
++            testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
++            pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+ 
++          }
++          pNC->ncFlags |= NC_AllowAgg;
+         }
+-        pNC->ncFlags |= NC_AllowAgg;
+       }
+       /* FIX ME:  Compute pExpr->affinity based on the expected return
+       ** type of the function 
+@@ -93370,8 +95457,8 @@
+   memset(&nc, 0, sizeof(nc));
+   nc.pParse = pParse;
+   nc.pSrcList = pSelect->pSrc;
+-  nc.pEList = pEList;
+-  nc.ncFlags = NC_AllowAgg;
++  nc.uNC.pEList = pEList;
++  nc.ncFlags = NC_AllowAgg|NC_UEList;
+   nc.nErr = 0;
+   db = pParse->db;
+   savedSuppErr = db->suppressErr;
+@@ -93616,6 +95703,19 @@
+     }
+     for(j=0; j<pSelect->pEList->nExpr; j++){
+       if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
++#ifndef SQLITE_OMIT_WINDOWFUNC
++        if( ExprHasProperty(pE, EP_WinFunc) ){
++          /* Since this window function is being changed into a reference
++          ** to the same window function the result set, remove the instance
++          ** of this window function from the Select.pWin list. */
++          Window **pp;
++          for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
++            if( *pp==pE->y.pWin ){
++              *pp = (*pp)->pNextWin;
++            }    
++          }
++        }
++#endif
+         pItem->u.x.iOrderByCol = j+1;
+       }
+     }
+@@ -93672,6 +95772,7 @@
+     */
+     memset(&sNC, 0, sizeof(sNC));
+     sNC.pParse = pParse;
++    sNC.pWinSelect = p;
+     if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
+       return WRC_Abort;
+     }
+@@ -93720,12 +95821,13 @@
+     /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
+     ** resolve the result-set expression list.
+     */
+-    sNC.ncFlags = NC_AllowAgg;
++    sNC.ncFlags = NC_AllowAgg|NC_AllowWin;
+     sNC.pSrcList = p->pSrc;
+     sNC.pNext = pOuterNC;
+   
+     /* Resolve names in the result set. */
+     if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort;
++    sNC.ncFlags &= ~NC_AllowWin;
+   
+     /* If there are no aggregate functions in the result-set, and no GROUP BY 
+     ** expression, do not allow aggregates in any of the other expressions.
+@@ -93754,7 +95856,9 @@
+     ** Minor point: If this is the case, then the expression will be
+     ** re-evaluated for each reference to it.
+     */
+-    sNC.pEList = p->pEList;
++    assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 );
++    sNC.uNC.pEList = p->pEList;
++    sNC.ncFlags |= NC_UEList;
+     if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
+     if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+ 
+@@ -93772,7 +95876,7 @@
+     ** outer queries 
+     */
+     sNC.pNext = 0;
+-    sNC.ncFlags |= NC_AllowAgg;
++    sNC.ncFlags |= NC_AllowAgg|NC_AllowWin;
+ 
+     /* If this is a converted compound query, move the ORDER BY clause from 
+     ** the sub-query back to the parent query. At this point each term
+@@ -93803,6 +95907,7 @@
+     if( db->mallocFailed ){
+       return WRC_Abort;
+     }
++    sNC.ncFlags &= ~NC_AllowWin;
+   
+     /* Resolve the GROUP BY clause.  At the same time, make sure 
+     ** the GROUP BY clause does not contain aggregate functions.
+@@ -93987,7 +96092,7 @@
+   Table *pTab,        /* The table being referenced */
+   int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+   Expr *pExpr,        /* Expression to resolve.  May be NULL. */
+-  ExprList *pList     /* Expression list to resolve.  May be NUL. */
++  ExprList *pList     /* Expression list to resolve.  May be NULL. */
+ ){
+   SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
+   NameContext sNC;                /* Name context for pParse->pNewTable */
+@@ -94068,8 +96173,8 @@
+     return sqlite3AffinityType(pExpr->u.zToken, 0);
+   }
+ #endif
+-  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
+-    return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
++  if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
++    return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+   }
+   if( op==TK_SELECT_COLUMN ){
+     assert( pExpr->pLeft->flags&EP_xIsSelect );
+@@ -94151,27 +96256,27 @@
+   while( p ){
+     int op = p->op;
+     if( p->flags & EP_Generic ) break;
+-    if( op==TK_CAST || op==TK_UPLUS ){
+-      p = p->pLeft;
+-      continue;
+-    }
+-    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+-      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
+-      break;
+-    }
+     if( (op==TK_AGG_COLUMN || op==TK_COLUMN
+           || op==TK_REGISTER || op==TK_TRIGGER)
+-     && p->pTab!=0
++     && p->y.pTab!=0
+     ){
+-      /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
++      /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
+       ** a TK_COLUMN but was previously evaluated and cached in a register */
+       int j = p->iColumn;
+       if( j>=0 ){
+-        const char *zColl = p->pTab->aCol[j].zColl;
++        const char *zColl = p->y.pTab->aCol[j].zColl;
+         pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
+       }
+       break;
+     }
++    if( op==TK_CAST || op==TK_UPLUS ){
++      p = p->pLeft;
++      continue;
++    }
++    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
++      pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
++      break;
++    }
+     if( p->flags & EP_Collate ){
+       if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
+         p = p->pLeft;
+@@ -94591,7 +96696,6 @@
+     Expr *pL, *pR; 
+     int r1, r2;
+     assert( i>=0 && i<nLeft );
+-    if( i>0 ) sqlite3ExprCachePush(pParse);
+     r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
+     r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
+     codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
+@@ -94603,7 +96707,6 @@
+     testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+     sqlite3ReleaseTempReg(pParse, regFree1);
+     sqlite3ReleaseTempReg(pParse, regFree2);
+-    if( i>0 ) sqlite3ExprCachePop(pParse);
+     if( i==nLeft-1 ){
+       break;
+     }
+@@ -94951,7 +97054,12 @@
+ ** Construct a new expression node for a function with multiple
+ ** arguments.
+ */
+-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
++SQLITE_PRIVATE Expr *sqlite3ExprFunction(
++  Parse *pParse,        /* Parsing context */
++  ExprList *pList,      /* Argument list */
++  Token *pToken,        /* Name of the function */
++  int eDistinct         /* SF_Distinct or SF_ALL or 0 */
++){
+   Expr *pNew;
+   sqlite3 *db = pParse->db;
+   assert( pToken );
+@@ -94960,10 +97068,14 @@
+     sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
+     return 0;
+   }
++  if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
++    sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
++  }
+   pNew->x.pList = pList;
+   ExprSetProperty(pNew, EP_HasFunc);
+   assert( !ExprHasProperty(pNew, EP_xIsSelect) );
+   sqlite3ExprSetHeightAndFlags(pParse, pNew);
++  if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
+   return pNew;
+ }
+ 
+@@ -95055,6 +97167,10 @@
+   assert( p!=0 );
+   /* Sanity check: Assert that the IntValue is non-negative if it exists */
+   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
++
++  assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
++  assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
++          || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
+ #ifdef SQLITE_DEBUG
+   if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
+     assert( p->pLeft==0 );
+@@ -95073,6 +97189,10 @@
+     }else{
+       sqlite3ExprListDelete(db, p->x.pList);
+     }
++    if( ExprHasProperty(p, EP_WinFunc) ){
++      assert( p->op==TK_FUNCTION );
++      sqlite3WindowDelete(db, p->y.pWin);
++    }
+   }
+   if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
+   if( !ExprHasProperty(p, EP_Static) ){
+@@ -95121,7 +97241,7 @@
+ ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
+ ** (unreduced) Expr objects as they or originally constructed by the parser.
+ ** During expression analysis, extra information is computed and moved into
+-** later parts of teh Expr object and that extra information might get chopped
++** later parts of the Expr object and that extra information might get chopped
+ ** off if the expression is reduced.  Note also that it does not work to
+ ** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
+ ** to reduce a pristine expression tree from the parser.  The implementation
+@@ -95133,7 +97253,11 @@
+   assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
+   assert( EXPR_FULLSIZE<=0xfff );
+   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
+-  if( 0==flags || p->op==TK_SELECT_COLUMN ){
++  if( 0==flags || p->op==TK_SELECT_COLUMN 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++   || ExprHasProperty(p, EP_WinFunc)
++#endif
++  ){
+     nSize = EXPR_FULLSIZE;
+   }else{
+     assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+@@ -95158,7 +97282,7 @@
+ static int dupedExprNodeSize(Expr *p, int flags){
+   int nByte = dupedExprStructSize(p, flags) & 0xfff;
+   if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+-    nByte += sqlite3Strlen30(p->u.zToken)+1;
++    nByte += sqlite3Strlen30NN(p->u.zToken)+1;
+   }
+   return ROUND8(nByte);
+ }
+@@ -95261,7 +97385,7 @@
+     }
+ 
+     /* Fill in pNew->pLeft and pNew->pRight. */
+-    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
++    if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
+       zAlloc += dupedExprNodeSize(p, dupFlags);
+       if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
+         pNew->pLeft = p->pLeft ?
+@@ -95269,6 +97393,12 @@
+         pNew->pRight = p->pRight ?
+                        exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
+       }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(p, EP_WinFunc) ){
++        pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
++        assert( ExprHasProperty(pNew, EP_WinFunc) );
++      }
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+       if( pzBuffer ){
+         *pzBuffer = zAlloc;
+       }
+@@ -95373,6 +97503,7 @@
+     pItem->sortOrder = pOldItem->sortOrder;
+     pItem->done = 0;
+     pItem->bSpanIsTab = pOldItem->bSpanIsTab;
++    pItem->bSorterRef = pOldItem->bSorterRef;
+     pItem->u = pOldItem->u;
+   }
+   return pNew;
+@@ -95478,7 +97609,11 @@
+     pNew->addrOpenEphm[1] = -1;
+     pNew->nSelectRow = p->nSelectRow;
+     pNew->pWith = withDup(db, p->pWith);
+-    sqlite3SelectSetName(pNew, p->zSelName);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    pNew->pWin = 0;
++    pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
++#endif
++    pNew->selId = p->selId;
+     *pp = pNew;
+     pp = &pNew->pPrior;
+     pNext = pNew;
+@@ -95650,6 +97785,9 @@
+     assert( pItem->zName==0 );
+     pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+     if( dequote ) sqlite3Dequote(pItem->zName);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
++    }
+   }
+ }
+ 
+@@ -95830,11 +97968,16 @@
+       testcase( pExpr->op==TK_COLUMN );
+       testcase( pExpr->op==TK_AGG_FUNCTION );
+       testcase( pExpr->op==TK_AGG_COLUMN );
++      if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){
++        return WRC_Continue;
++      }
+       if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
+         return WRC_Continue;
+       }
+       /* Fall through */
+     case TK_IF_NULL_ROW:
++    case TK_REGISTER:
++      testcase( pExpr->op==TK_REGISTER );
+       testcase( pExpr->op==TK_IF_NULL_ROW );
+       pWalker->eCode = 0;
+       return WRC_Abort;
+@@ -95852,8 +97995,8 @@
+       }
+       /* Fall through */
+     default:
+-      testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail will disallow */
+-      testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail will disallow */
++      testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
++      testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
+       return WRC_Continue;
+   }
+ }
+@@ -95883,10 +98026,17 @@
+ }
+ 
+ /*
+-** Walk an expression tree.  Return non-zero if the expression is constant
+-** that does no originate from the ON or USING clauses of a join.
+-** Return 0 if it involves variables or function calls or terms from
+-** an ON or USING clause.
++** Walk an expression tree.  Return non-zero if
++**
++**   (1) the expression is constant, and
++**   (2) the expression does originate in the ON or USING clause
++**       of a LEFT JOIN, and
++**   (3) the expression does not contain any EP_FixedCol TK_COLUMN
++**       operands created by the constant propagation optimization.
++**
++** When this routine returns true, it indicates that the expression
++** can be added to the pParse->pConstExpr list and evaluated once when
++** the prepared statement starts up.  See sqlite3ExprCodeAtInit().
+ */
+ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
+   return exprIsConst(p, 2, 0);
+@@ -95916,7 +98066,7 @@
+     Expr *p = pGroupBy->a[i].pExpr;
+     if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
+       CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
+-      if( sqlite3_stricmp("BINARY", pColl->zName)==0 ){
++      if( sqlite3IsBinary(pColl) ){
+         return WRC_Prune;
+       }
+     }
+@@ -96058,8 +98208,8 @@
+       return 0;
+     case TK_COLUMN:
+       return ExprHasProperty(p, EP_CanBeNull) ||
+-             p->pTab==0 ||  /* Reference to column of index on expression */
+-             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
++             p->y.pTab==0 ||  /* Reference to column of index on expression */
++             (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
+     default:
+       return 1;
+   }
+@@ -96114,6 +98264,14 @@
+   if( sqlite3StrICmp(z, "OID")==0 ) return 1;
+   return 0;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
++  if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
++  if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
++  if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
++  return 0;
++}
++#endif
+ 
+ /*
+ ** pX is the RHS of an IN operator.  If pX is a SELECT statement 
+@@ -96338,7 +98496,8 @@
+ 
+       sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+       eType = IN_INDEX_ROWID;
+-
++      ExplainQueryPlan((pParse, 0,
++            "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName));
+       sqlite3VdbeJumpHere(v, iAddr);
+     }else{
+       Index *pIdx;                         /* Iterator variable */
+@@ -96417,11 +98576,8 @@
+           if( colUsed==(MASKBIT(nExpr)-1) ){
+             /* If we reach this point, that means the index pIdx is usable */
+             int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+-#ifndef SQLITE_OMIT_EXPLAIN
+-            sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
+-              sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
+-              P4_DYNAMIC);
+-#endif
++            ExplainQueryPlan((pParse, 0,
++                              "USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
+             sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+             sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+             VdbeComment((v, "%s", pIdx->zName));
+@@ -96600,7 +98756,6 @@
+   int rReg = 0;                           /* Register storing resulting */
+   Vdbe *v = sqlite3GetVdbe(pParse);
+   if( NEVER(v==0) ) return 0;
+-  sqlite3ExprCachePush(pParse);
+ 
+   /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+   ** is encountered if any of the following is true:
+@@ -96616,17 +98771,6 @@
+     jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+   }
+ 
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  if( pParse->explain==2 ){
+-    char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d",
+-        jmpIfDynamic>=0?"":"CORRELATED ",
+-        pExpr->op==TK_IN?"LIST":"SCALAR",
+-        pParse->iNextSelectId
+-    );
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
+-#endif
+-
+   switch( pExpr->op ){
+     case TK_IN: {
+       int addr;                   /* Address of OP_OpenEphemeral instruction */
+@@ -96664,6 +98808,9 @@
+         Select *pSelect = pExpr->x.pSelect;
+         ExprList *pEList = pSelect->pEList;
+ 
++        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
++            jmpIfDynamic>=0?"":"CORRELATED "
++        ));
+         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. */
+@@ -96705,7 +98852,6 @@
+         ExprList *pList = pExpr->x.pList;
+         struct ExprList_item *pItem;
+         int r1, r2, r3;
+-
+         affinity = sqlite3ExprAffinity(pLeft);
+         if( !affinity ){
+           affinity = SQLITE_AFF_BLOB;
+@@ -96745,7 +98891,6 @@
+               sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
+             }else{
+               sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+-              sqlite3ExprCacheAffinityChange(pParse, r3, 1);
+               sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
+             }
+           }
+@@ -96786,6 +98931,8 @@
+       assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ 
+       pSel = pExpr->x.pSelect;
++      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
++            jmpIfDynamic>=0?"":"CORRELATED "));
+       nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+       sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+       pParse->nMem += nReg;
+@@ -96824,7 +98971,6 @@
+   if( jmpIfDynamic>=0 ){
+     sqlite3VdbeJumpHere(v, jmpIfDynamic);
+   }
+-  sqlite3ExprCachePop(pParse);
+ 
+   return rReg;
+ }
+@@ -96943,7 +99089,6 @@
+   ** aiMap[] array contains a mapping from the original LHS field order to
+   ** the field order that matches the RHS index.
+   */
+-  sqlite3ExprCachePush(pParse);
+   rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
+   for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
+   if( i==nVector ){
+@@ -97102,7 +99247,6 @@
+ 
+ sqlite3ExprCodeIN_finished:
+   if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
+-  sqlite3ExprCachePop(pParse);
+   VdbeComment((v, "end IN expr"));
+ sqlite3ExprCodeIN_oom_error:
+   sqlite3DbFree(pParse->db, aiMap);
+@@ -97170,146 +99314,7 @@
+   }
+ }
+ 
+-/*
+-** Erase column-cache entry number i
+-*/
+-static void cacheEntryClear(Parse *pParse, int i){
+-  if( pParse->aColCache[i].tempReg ){
+-    if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+-      pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+-    }
+-  }
+-  pParse->nColCache--;
+-  if( i<pParse->nColCache ){
+-    pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
+-  }
+-}
+ 
+-
+-/*
+-** Record in the column cache that a particular column from a
+-** particular table is stored in a particular register.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
+-  int i;
+-  int minLru;
+-  int idxLru;
+-  struct yColCache *p;
+-
+-  /* Unless an error has occurred, register numbers are always positive. */
+-  assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
+-  assert( iCol>=-1 && iCol<32768 );  /* Finite column numbers */
+-
+-  /* The SQLITE_ColumnCache flag disables the column cache.  This is used
+-  ** for testing only - to verify that SQLite always gets the same answer
+-  ** with and without the column cache.
+-  */
+-  if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
+-
+-  /* First replace any existing entry.
+-  **
+-  ** Actually, the way the column cache is currently used, we are guaranteed
+-  ** that the object will never already be in cache.  Verify this guarantee.
+-  */
+-#ifndef NDEBUG
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    assert( p->iTable!=iTab || p->iColumn!=iCol );
+-  }
+-#endif
+-
+-  /* If the cache is already full, delete the least recently used entry */
+-  if( pParse->nColCache>=SQLITE_N_COLCACHE ){
+-    minLru = 0x7fffffff;
+-    idxLru = -1;
+-    for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+-      if( p->lru<minLru ){
+-        idxLru = i;
+-        minLru = p->lru;
+-      }
+-    }
+-    p = &pParse->aColCache[idxLru];
+-  }else{
+-    p = &pParse->aColCache[pParse->nColCache++];
+-  }
+-
+-  /* Add the new entry to the end of the cache */
+-  p->iLevel = pParse->iCacheLevel;
+-  p->iTable = iTab;
+-  p->iColumn = iCol;
+-  p->iReg = iReg;
+-  p->tempReg = 0;
+-  p->lru = pParse->iCacheCnt++;
+-}
+-
+-/*
+-** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
+-** Purge the range of registers from the column cache.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
+-  int i = 0;
+-  while( i<pParse->nColCache ){
+-    struct yColCache *p = &pParse->aColCache[i];
+-    if( p->iReg >= iReg && p->iReg < iReg+nReg ){
+-      cacheEntryClear(pParse, i);
+-    }else{
+-      i++;
+-    }
+-  }
+-}
+-
+-/*
+-** Remember the current column cache context.  Any new entries added
+-** added to the column cache after this call are removed when the
+-** corresponding pop occurs.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
+-  pParse->iCacheLevel++;
+-#ifdef SQLITE_DEBUG
+-  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+-    printf("PUSH to %d\n", pParse->iCacheLevel);
+-  }
+-#endif
+-}
+-
+-/*
+-** Remove from the column cache any entries that were added since the
+-** the previous sqlite3ExprCachePush operation.  In other words, restore
+-** the cache to the state it was in prior the most recent Push.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
+-  int i = 0;
+-  assert( pParse->iCacheLevel>=1 );
+-  pParse->iCacheLevel--;
+-#ifdef SQLITE_DEBUG
+-  if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+-    printf("POP  to %d\n", pParse->iCacheLevel);
+-  }
+-#endif
+-  while( i<pParse->nColCache ){
+-    if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
+-      cacheEntryClear(pParse, i);
+-    }else{
+-      i++;
+-    }
+-  }
+-}
+-
+-/*
+-** When a cached column is reused, make sure that its register is
+-** no longer available as a temp register.  ticket #3879:  that same
+-** register might be in the cache in multiple places, so be sure to
+-** get them all.
+-*/
+-static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
+-  int i;
+-  struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    if( p->iReg==iReg ){
+-      p->tempReg = 0;
+-    }
+-  }
+-}
+-
+ /* Generate code that will load into register regOut a value that is
+ ** appropriate for the iIdxCol-th column of index pIdx.
+ */
+@@ -97364,13 +99369,8 @@
+ 
+ /*
+ ** Generate code that will extract the iColumn-th column from
+-** table pTab and store the column value in a register. 
++** table pTab and store the column value in register iReg. 
+ **
+-** An effort is made to store the column value in register iReg.  This
+-** is not garanteeed for GetColumn() - the result can be stored in
+-** any register.  But the result is guaranteed to land in register iReg
+-** for GetColumnToReg().
+-**
+ ** There must be an open cursor to pTab in iTable when this routine
+ ** is called.  If iColumn<0 then code is generated that extracts the rowid.
+ */
+@@ -97383,97 +99383,24 @@
+   u8 p5            /* P5 value for OP_Column + FLAGS */
+ ){
+   Vdbe *v = pParse->pVdbe;
+-  int i;
+-  struct yColCache *p;
+-
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    if( p->iTable==iTable && p->iColumn==iColumn ){
+-      p->lru = pParse->iCacheCnt++;
+-      sqlite3ExprCachePinRegister(pParse, p->iReg);
+-      return p->iReg;
+-    }
+-  }  
+   assert( v!=0 );
+   sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
+   if( p5 ){
+     sqlite3VdbeChangeP5(v, p5);
+-  }else{   
+-    sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
+   }
+   return iReg;
+ }
+-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
+-  Parse *pParse,   /* Parsing and code generating context */
+-  Table *pTab,     /* Description of the table we are reading from */
+-  int iColumn,     /* Index of the table column */
+-  int iTable,      /* The cursor pointing to the table */
+-  int iReg         /* Store results here */
+-){
+-  int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0);
+-  if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg);
+-}
+ 
+-
+ /*
+-** Clear all column cache entries.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
+-  int i;
+-
+-#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)
+-    ){
+-       pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
+-    }
+-  }
+-  pParse->nColCache = 0;
+-}
+-
+-/*
+-** Record the fact that an affinity change has occurred on iCount
+-** registers starting with iStart.
+-*/
+-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
+-  sqlite3ExprCacheRemove(pParse, iStart, iCount);
+-}
+-
+-/*
+ ** Generate code to move content from registers iFrom...iFrom+nReg-1
+-** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
++** over to iTo..iTo+nReg-1.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
+   assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
+   sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
+-  sqlite3ExprCacheRemove(pParse, iFrom, nReg);
+ }
+ 
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
+ /*
+-** Return true if any register in the range iFrom..iTo (inclusive)
+-** is used as part of the column cache.
+-**
+-** This routine is used within assert() and testcase() macros only
+-** and does not appear in a normal build.
+-*/
+-static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
+-  int i;
+-  struct yColCache *p;
+-  for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-    int r = p->iReg;
+-    if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
+-  }
+-  return 0;
+-}
+-#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
+-
+-
+-/*
+ ** Convert a scalar expression node to a TK_REGISTER referencing
+ ** register iReg.  The caller must ensure that iReg already contains
+ ** the correct value for the expression.
+@@ -97548,6 +99475,7 @@
+     return 0;
+   }
+ 
++expr_code_doover:
+   if( pExpr==0 ){
+     op = TK_NULL;
+   }else{
+@@ -97569,6 +99497,28 @@
+     }
+     case TK_COLUMN: {
+       int iTab = pExpr->iTable;
++      if( ExprHasProperty(pExpr, EP_FixedCol) ){
++        /* This COLUMN expression is really a constant due to WHERE clause
++        ** constraints, and that constant is coded by the pExpr->pLeft
++        ** expresssion.  However, make sure the constant has the correct
++        ** datatype by applying the Affinity of the table column to the
++        ** constant.
++        */
++        int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
++        int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
++        if( aff!=SQLITE_AFF_BLOB ){
++          static const char zAff[] = "B\000C\000D\000E";
++          assert( SQLITE_AFF_BLOB=='A' );
++          assert( SQLITE_AFF_TEXT=='B' );
++          if( iReg!=target ){
++            sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
++            iReg = target;
++          }
++          sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
++                            &zAff[(aff-'B')*2], P4_STATIC);
++        }
++        return iReg;
++      }
+       if( iTab<0 ){
+         if( pParse->iSelfTab<0 ){
+           /* Generating CHECK constraints or inserting into partial index */
+@@ -97579,7 +99529,7 @@
+           iTab = pParse->iSelfTab - 1;
+         }
+       }
+-      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
++      return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
+                                pExpr->iColumn, iTab, target,
+                                pExpr->op2);
+     }
+@@ -97649,8 +99599,6 @@
+       }
+       sqlite3VdbeAddOp2(v, OP_Cast, target,
+                         sqlite3AffinityType(pExpr->u.zToken, 0));
+-      testcase( usedAsColumnCache(pParse, inReg, inReg) );
+-      sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
+       return inReg;
+     }
+ #endif /* SQLITE_OMIT_CAST */
+@@ -97794,6 +99742,12 @@
+       u8 enc = ENC(db);      /* The text encoding used by this database */
+       CollSeq *pColl = 0;    /* A collating sequence */
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      if( ExprHasProperty(pExpr, EP_WinFunc) ){
++        return pExpr->y.pWin->regResult;
++      }
++#endif
++
+       if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
+         /* SQL functions can be expensive. So try to move constant functions
+         ** out of the inner loop, even if that means an extra OP_Copy. */
+@@ -97830,10 +99784,7 @@
+         for(i=1; i<nFarg; i++){
+           sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
+           VdbeCoverage(v);
+-          sqlite3ExprCacheRemove(pParse, target, 1);
+-          sqlite3ExprCachePush(pParse);
+           sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
+-          sqlite3ExprCachePop(pParse);
+         }
+         sqlite3VdbeResolveLabel(v, endCoalesce);
+         break;
+@@ -97899,10 +99850,8 @@
+           }
+         }
+ 
+-        sqlite3ExprCachePush(pParse);     /* Ticket 2ea2425d34be */
+         sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
+                                 SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
+-        sqlite3ExprCachePop(pParse);      /* Ticket 2ea2425d34be */
+       }else{
+         r1 = 0;
+       }
+@@ -97919,7 +99868,7 @@
+       ** "glob(B,A).  We want to use the A in "A glob B" to test
+       ** for function overloading.  But we use the B term in "glob(B,A)".
+       */
+-      if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
++      if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){
+         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
+       }else if( nFarg>0 ){
+         pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
+@@ -98008,7 +99957,8 @@
+     case TK_SPAN:
+     case TK_COLLATE: 
+     case TK_UPLUS: {
+-      return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
++      pExpr = pExpr->pLeft;
++      goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
+     }
+ 
+     case TK_TRIGGER: {
+@@ -98037,7 +99987,7 @@
+       **   p1==1   ->    old.a         p1==4   ->    new.a
+       **   p1==2   ->    old.b         p1==5   ->    new.b       
+       */
+-      Table *pTab = pExpr->pTab;
++      Table *pTab = pExpr->y.pTab;
+       int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
+ 
+       assert( pExpr->iTable==0 || pExpr->iTable==1 );
+@@ -98046,10 +99996,9 @@
+       assert( p1>=0 && p1<(pTab->nCol*2+2) );
+ 
+       sqlite3VdbeAddOp2(v, OP_Param, p1, target);
+-      VdbeComment((v, "%s.%s -> $%d",
++      VdbeComment((v, "r[%d]=%s.%s", target,
+         (pExpr->iTable ? "new" : "old"),
+-        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
+-        target
++        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
+       ));
+ 
+ #ifndef SQLITE_OMIT_FLOATING_POINT
+@@ -98075,9 +100024,7 @@
+     case TK_IF_NULL_ROW: {
+       int addrINR;
+       addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
+-      sqlite3ExprCachePush(pParse);
+       inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+-      sqlite3ExprCachePop(pParse);
+       sqlite3VdbeJumpHere(v, addrINR);
+       sqlite3VdbeChangeP3(v, addrINR, inReg);
+       break;
+@@ -98114,7 +100061,6 @@
+       Expr opCompare;                   /* The X==Ei expression */
+       Expr *pX;                         /* The X expression */
+       Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */
+-      VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
+ 
+       assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
+       assert(pExpr->x.pList->nExpr > 0);
+@@ -98138,7 +100084,6 @@
+         regFree1 = 0;
+       }
+       for(i=0; i<nExpr-1; i=i+2){
+-        sqlite3ExprCachePush(pParse);
+         if( pX ){
+           assert( pTest!=0 );
+           opCompare.pRight = aListelem[i].pExpr;
+@@ -98151,18 +100096,13 @@
+         testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
+         sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
+         sqlite3VdbeGoto(v, endLabel);
+-        sqlite3ExprCachePop(pParse);
+         sqlite3VdbeResolveLabel(v, nextCase);
+       }
+       if( (nExpr&1)!=0 ){
+-        sqlite3ExprCachePush(pParse);
+         sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
+-        sqlite3ExprCachePop(pParse);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+       }
+-      assert( pParse->db->mallocFailed || pParse->nErr>0 
+-           || pParse->iCacheLevel==iCacheLevel );
+       sqlite3VdbeResolveLabel(v, endLabel);
+       break;
+     }
+@@ -98312,7 +100252,7 @@
+ ** might choose to code the expression at initialization time.
+ */
+ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
+-  if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
++  if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
+     sqlite3ExprCodeAtInit(pParse, pExpr, target);
+   }else{
+     sqlite3ExprCode(pParse, pExpr, target);
+@@ -98381,6 +100321,12 @@
+   if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
+   for(pItem=pList->a, i=0; i<n; i++, pItem++){
+     Expr *pExpr = pItem->pExpr;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( pItem->bSorterRef ){
++      i--;
++      n--;
++    }else
++#endif
+     if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
+       if( flags & SQLITE_ECEL_OMITREF ){
+         i--;
+@@ -98388,7 +100334,9 @@
+       }else{
+         sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+       }
+-    }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
++    }else if( (flags & SQLITE_ECEL_FACTOR)!=0
++           && sqlite3ExprIsConstantNotJoin(pExpr)
++    ){
+       sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+     }else{
+       int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
+@@ -98514,18 +100462,14 @@
+       int d2 = sqlite3VdbeMakeLabel(v);
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+       sqlite3VdbeResolveLabel(v, d2);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_OR: {
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_NOT: {
+@@ -98684,9 +100628,7 @@
+     case TK_AND: {
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_OR: {
+@@ -98693,10 +100635,8 @@
+       int d2 = sqlite3VdbeMakeLabel(v);
+       testcase( jumpIfNull==0 );
+       sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+       sqlite3VdbeResolveLabel(v, d2);
+-      sqlite3ExprCachePop(pParse);
+       break;
+     }
+     case TK_NOT: {
+@@ -98909,17 +100849,35 @@
+   if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
+     if( pA->op==TK_FUNCTION ){
+       if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      /* Justification for the assert():
++      ** window functions have p->op==TK_FUNCTION but aggregate functions
++      ** have p->op==TK_AGG_FUNCTION.  So any comparison between an aggregate
++      ** function and a window function should have failed before reaching
++      ** this point.  And, it is not possible to have a window function and
++      ** a scalar function with the same name and number of arguments.  So
++      ** if we reach this point, either A and B both window functions or
++      ** neither are a window functions. */
++      assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
++      if( ExprHasProperty(pA,EP_WinFunc) ){
++        if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
++      }
++#endif
++    }else if( pA->op==TK_COLLATE ){
++      if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+     }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+-      return pA->op==TK_COLLATE ? 1 : 2;
++      return 2;
+     }
+   }
+   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
+   if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+     if( combinedFlags & EP_xIsSelect ) return 2;
+-    if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
++    if( (combinedFlags & EP_FixedCol)==0
++     && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
+     if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
+     if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+-    if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
++    assert( (combinedFlags & EP_Reduced)==0 );
++    if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
+       if( pA->iColumn!=pB->iColumn ) return 2;
+       if( pA->iTable!=pB->iTable 
+        && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+@@ -99014,18 +100972,15 @@
+ /*
+ ** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
+ ** If the expression node requires that the table at pWalker->iCur
+-** have a non-NULL column, then set pWalker->eCode to 1 and abort.
++** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
++**
++** This routine controls an optimization.  False positives (setting
++** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives
++** (never setting pWalker->eCode) is a harmless missed optimization.
+ */
+ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
+-  /* This routine is only called for WHERE clause expressions and so it
+-  ** cannot have any TK_AGG_COLUMN entries because those are only found
+-  ** in HAVING clauses.  We can get a TK_AGG_FUNCTION in a WHERE clause,
+-  ** but that is an illegal construct and the query will be rejected at
+-  ** a later stage of processing, so the TK_AGG_FUNCTION case does not
+-  ** need to be considered here. */
+-  assert( pExpr->op!=TK_AGG_COLUMN );
++  testcase( pExpr->op==TK_AGG_COLUMN );
+   testcase( pExpr->op==TK_AGG_FUNCTION );
+-
+   if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
+   switch( pExpr->op ){
+     case TK_ISNOT:
+@@ -99067,8 +101022,8 @@
+       testcase( pExpr->op==TK_LE );
+       testcase( pExpr->op==TK_GT );
+       testcase( pExpr->op==TK_GE );
+-      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
+-       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
++      if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
++       || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
+       ){
+        return WRC_Prune;
+       }
+@@ -99265,8 +101220,9 @@
+   NameContext *pNC = pWalker->u.pNC;
+   Parse *pParse = pNC->pParse;
+   SrcList *pSrcList = pNC->pSrcList;
+-  AggInfo *pAggInfo = pNC->pAggInfo;
++  AggInfo *pAggInfo = pNC->uNC.pAggInfo;
+ 
++  assert( pNC->ncFlags & NC_UAggInfo );
+   switch( pExpr->op ){
+     case TK_AGG_COLUMN:
+     case TK_COLUMN: {
+@@ -99298,7 +101254,7 @@
+              && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 
+             ){
+               pCol = &pAggInfo->aCol[k];
+-              pCol->pTab = pExpr->pTab;
++              pCol->pTab = pExpr->y.pTab;
+               pCol->iTable = pExpr->iTable;
+               pCol->iColumn = pExpr->iColumn;
+               pCol->iMem = ++pParse->nMem;
+@@ -99444,21 +101400,9 @@
+ /*
+ ** Deallocate a register, making available for reuse for some other
+ ** purpose.
+-**
+-** If a register is currently being used by the column cache, then
+-** the deallocation is deferred until the column cache line that uses
+-** the register becomes stale.
+ */
+ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
+   if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+-    int i;
+-    struct yColCache *p;
+-    for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+-      if( p->iReg==iReg ){
+-        p->tempReg = 1;
+-        return;
+-      }
+-    }
+     pParse->aTempReg[pParse->nTempReg++] = iReg;
+   }
+ }
+@@ -99472,7 +101416,6 @@
+   i = pParse->iRangeReg;
+   n = pParse->nRangeReg;
+   if( nReg<=n ){
+-    assert( !usedAsColumnCache(pParse, i, i+n-1) );
+     pParse->iRangeReg += nReg;
+     pParse->nRangeReg -= nReg;
+   }else{
+@@ -99486,7 +101429,6 @@
+     sqlite3ReleaseTempReg(pParse, iReg);
+     return;
+   }
+-  sqlite3ExprCacheRemove(pParse, iReg, nReg);
+   if( nReg>pParse->nRangeReg ){
+     pParse->nRangeReg = nReg;
+     pParse->iRangeReg = iReg;
+@@ -99548,369 +101490,66 @@
+ */
+ #ifndef SQLITE_OMIT_ALTERTABLE
+ 
+-
+ /*
+-** This function is used by SQL generated to implement the 
+-** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
+-** CREATE INDEX command. The second is a table name. The table name in 
+-** the CREATE TABLE or CREATE INDEX statement is replaced with the third
+-** argument and the result returned. Examples:
++** Parameter zName is the name of a table that is about to be altered
++** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
++** If the table is a system table, this function leaves an error message
++** in pParse->zErr (system tables may not be altered) and returns non-zero.
+ **
+-** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
+-**     -> 'CREATE TABLE def(a, b, c)'
+-**
+-** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
+-**     -> 'CREATE INDEX i ON def(a, b, c)'
++** Or, if zName is not a system table, zero is returned.
+ */
+-static void renameTableFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  unsigned char const *zSql = sqlite3_value_text(argv[0]);
+-  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+-
+-  int token;
+-  Token tname;
+-  unsigned char const *zCsr = zSql;
+-  int len = 0;
+-  char *zRet;
+-
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-
+-  UNUSED_PARAMETER(NotUsed);
+-
+-  /* The principle used to locate the table name in the CREATE TABLE 
+-  ** statement is that the table name is the first non-space token that
+-  ** is immediately followed by a TK_LP or TK_USING token.
+-  */
+-  if( zSql ){
+-    do {
+-      if( !*zCsr ){
+-        /* Ran out of input before finding an opening bracket. Return NULL. */
+-        return;
+-      }
+-
+-      /* Store the token that zCsr points to in tname. */
+-      tname.z = (char*)zCsr;
+-      tname.n = len;
+-
+-      /* Advance zCsr to the next token. Store that token type in 'token',
+-      ** and its length in 'len' (to be used next iteration of this loop).
+-      */
+-      do {
+-        zCsr += len;
+-        len = sqlite3GetToken(zCsr, &token);
+-      } while( token==TK_SPACE );
+-      assert( len>0 );
+-    } while( token!=TK_LP && token!=TK_USING );
+-
+-    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+-       zSql, zTableName, tname.z+tname.n);
+-    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
++static int isSystemTable(Parse *pParse, const char *zName){
++  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
++    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
++    return 1;
+   }
++  return 0;
+ }
+ 
+ /*
+-** This C function implements an SQL user function that is used by SQL code
+-** generated by the ALTER TABLE ... RENAME command to modify the definition
+-** of any foreign key constraints that use the table being renamed as the 
+-** parent table. It is passed three arguments:
+-**
+-**   1) The complete text of the CREATE TABLE statement being modified,
+-**   2) The old name of the table being renamed, and
+-**   3) The new name of the table being renamed.
+-**
+-** It returns the new CREATE TABLE statement. For example:
+-**
+-**   sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
+-**       -> 'CREATE TABLE t1(a REFERENCES t3)'
++** Generate code to verify that the schemas of database zDb and, if
++** bTemp is not true, database "temp", can still be parsed. This is
++** called at the end of the generation of an ALTER TABLE ... RENAME ...
++** statement to ensure that the operation has not rendered any schema
++** objects unusable.
+ */
+-#ifndef SQLITE_OMIT_FOREIGN_KEY
+-static void renameParentFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-  char *zOutput = 0;
+-  char *zResult;
+-  unsigned char const *zInput = sqlite3_value_text(argv[0]);
+-  unsigned char const *zOld = sqlite3_value_text(argv[1]);
+-  unsigned char const *zNew = sqlite3_value_text(argv[2]);
++static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
++  sqlite3NestedParse(pParse, 
++      "SELECT 1 "
++      "FROM \"%w\".%s "
++      "WHERE name NOT LIKE 'sqlite_%%'"
++      " AND sql NOT LIKE 'create virtual%%'"
++      " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
++      zDb, MASTER_NAME, 
++      zDb, bTemp
++  );
+ 
+-  unsigned const char *z;         /* Pointer to token */
+-  int n;                          /* Length of token z */
+-  int token;                      /* Type of token */
+-
+-  UNUSED_PARAMETER(NotUsed);
+-  if( zInput==0 || zOld==0 ) return;
+-  for(z=zInput; *z; z=z+n){
+-    n = sqlite3GetToken(z, &token);
+-    if( token==TK_REFERENCES ){
+-      char *zParent;
+-      do {
+-        z += n;
+-        n = sqlite3GetToken(z, &token);
+-      }while( token==TK_SPACE );
+-
+-      if( token==TK_ILLEGAL ) break;
+-      zParent = sqlite3DbStrNDup(db, (const char *)z, n);
+-      if( zParent==0 ) break;
+-      sqlite3Dequote(zParent);
+-      if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
+-        char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", 
+-            (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
+-        );
+-        sqlite3DbFree(db, zOutput);
+-        zOutput = zOut;
+-        zInput = &z[n];
+-      }
+-      sqlite3DbFree(db, zParent);
+-    }
++  if( bTemp==0 ){
++    sqlite3NestedParse(pParse, 
++        "SELECT 1 "
++        "FROM temp.%s "
++        "WHERE name NOT LIKE 'sqlite_%%'"
++        " AND sql NOT LIKE 'create virtual%%'"
++        " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
++        MASTER_NAME, zDb 
++    );
+   }
+-
+-  zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), 
+-  sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
+-  sqlite3DbFree(db, zOutput);
+ }
+-#endif
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
+-/* This function is used by SQL generated to implement the
+-** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
+-** statement. The second is a table name. The table name in the CREATE 
+-** TRIGGER statement is replaced with the third argument and the result 
+-** returned. This is analagous to renameTableFunc() above, except for CREATE
+-** TRIGGER, not CREATE INDEX and CREATE TABLE.
+-*/
+-static void renameTriggerFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **argv
+-){
+-  unsigned char const *zSql = sqlite3_value_text(argv[0]);
+-  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
+-
+-  int token;
+-  Token tname;
+-  int dist = 3;
+-  unsigned char const *zCsr = zSql;
+-  int len = 0;
+-  char *zRet;
+-  sqlite3 *db = sqlite3_context_db_handle(context);
+-
+-  UNUSED_PARAMETER(NotUsed);
+-
+-  /* The principle used to locate the table name in the CREATE TRIGGER 
+-  ** statement is that the table name is the first token that is immediately
+-  ** preceded by either TK_ON or TK_DOT and immediately followed by one
+-  ** of TK_WHEN, TK_BEGIN or TK_FOR.
+-  */
+-  if( zSql ){
+-    do {
+-
+-      if( !*zCsr ){
+-        /* Ran out of input before finding the table name. Return NULL. */
+-        return;
+-      }
+-
+-      /* Store the token that zCsr points to in tname. */
+-      tname.z = (char*)zCsr;
+-      tname.n = len;
+-
+-      /* Advance zCsr to the next token. Store that token type in 'token',
+-      ** and its length in 'len' (to be used next iteration of this loop).
+-      */
+-      do {
+-        zCsr += len;
+-        len = sqlite3GetToken(zCsr, &token);
+-      }while( token==TK_SPACE );
+-      assert( len>0 );
+-
+-      /* Variable 'dist' stores the number of tokens read since the most
+-      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
+-      ** token is read and 'dist' equals 2, the condition stated above
+-      ** to be met.
+-      **
+-      ** Note that ON cannot be a database, table or column name, so
+-      ** there is no need to worry about syntax like 
+-      ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
+-      */
+-      dist++;
+-      if( token==TK_DOT || token==TK_ON ){
+-        dist = 0;
+-      }
+-    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
+-
+-    /* Variable tname now contains the token that is the old table-name
+-    ** in the CREATE TRIGGER statement.
+-    */
+-    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+-       zSql, zTableName, tname.z+tname.n);
+-    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
+-  }
+-}
+-#endif   /* !SQLITE_OMIT_TRIGGER */
+-
+ /*
+-** Register built-in functions used to help implement ALTER TABLE
++** Generate code to reload the schema for database iDb. And, if iDb!=1, for
++** the temp database as well.
+ */
+-SQLITE_PRIVATE void sqlite3AlterFunctions(void){
+-  static FuncDef aAlterTableFuncs[] = {
+-    FUNCTION(sqlite_rename_table,   2, 0, 0, renameTableFunc),
+-#ifndef SQLITE_OMIT_TRIGGER
+-    FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
+-#endif
+-#ifndef SQLITE_OMIT_FOREIGN_KEY
+-    FUNCTION(sqlite_rename_parent,  3, 0, 0, renameParentFunc),
+-#endif
+-  };
+-  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
+-}
+-
+-/*
+-** This function is used to create the text of expressions of the form:
+-**
+-**   name=<constant1> OR name=<constant2> OR ...
+-**
+-** If argument zWhere is NULL, then a pointer string containing the text 
+-** "name=<constant>" is returned, where <constant> is the quoted version
+-** of the string passed as argument zConstant. The returned buffer is
+-** allocated using sqlite3DbMalloc(). It is the responsibility of the
+-** caller to ensure that it is eventually freed.
+-**
+-** If argument zWhere is not NULL, then the string returned is 
+-** "<where> OR name=<constant>", where <where> is the contents of zWhere.
+-** In this case zWhere is passed to sqlite3DbFree() before returning.
+-** 
+-*/
+-static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
+-  char *zNew;
+-  if( !zWhere ){
+-    zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
+-  }else{
+-    zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
+-    sqlite3DbFree(db, zWhere);
++static void renameReloadSchema(Parse *pParse, int iDb){
++  Vdbe *v = pParse->pVdbe;
++  if( v ){
++    sqlite3ChangeCookie(pParse, iDb);
++    sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0);
++    if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0);
+   }
+-  return zNew;
+ }
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ /*
+-** Generate the text of a WHERE expression which can be used to select all
+-** tables that have foreign key constraints that refer to table pTab (i.e.
+-** constraints for which pTab is the parent table) from the sqlite_master
+-** table.
+-*/
+-static char *whereForeignKeys(Parse *pParse, Table *pTab){
+-  FKey *p;
+-  char *zWhere = 0;
+-  for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+-    zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
+-  }
+-  return zWhere;
+-}
+-#endif
+-
+-/*
+-** Generate the text of a WHERE expression which can be used to select all
+-** temporary triggers on table pTab from the sqlite_temp_master table. If
+-** table pTab has no temporary triggers, or is itself stored in the 
+-** temporary database, NULL is returned.
+-*/
+-static char *whereTempTriggers(Parse *pParse, Table *pTab){
+-  Trigger *pTrig;
+-  char *zWhere = 0;
+-  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
+-
+-  /* If the table is not located in the temp-db (in which case NULL is 
+-  ** returned, loop through the tables list of triggers. For each trigger
+-  ** that is not part of the temp-db schema, add a clause to the WHERE 
+-  ** expression being built up in zWhere.
+-  */
+-  if( pTab->pSchema!=pTempSchema ){
+-    sqlite3 *db = pParse->db;
+-    for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
+-      if( pTrig->pSchema==pTempSchema ){
+-        zWhere = whereOrName(db, zWhere, pTrig->zName);
+-      }
+-    }
+-  }
+-  if( zWhere ){
+-    char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
+-    sqlite3DbFree(pParse->db, zWhere);
+-    zWhere = zNew;
+-  }
+-  return zWhere;
+-}
+-
+-/*
+-** Generate code to drop and reload the internal representation of table
+-** pTab from the database, including triggers and temporary triggers.
+-** Argument zName is the name of the table in the database schema at
+-** the time the generated code is executed. This can be different from
+-** pTab->zName if this function is being called to code part of an 
+-** "ALTER TABLE RENAME TO" statement.
+-*/
+-static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
+-  Vdbe *v;
+-  char *zWhere;
+-  int iDb;                   /* Index of database containing pTab */
+-#ifndef SQLITE_OMIT_TRIGGER
+-  Trigger *pTrig;
+-#endif
+-
+-  v = sqlite3GetVdbe(pParse);
+-  if( NEVER(v==0) ) return;
+-  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
+-  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+-  assert( iDb>=0 );
+-
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* Drop any table triggers from the internal schema. */
+-  for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
+-    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
+-    assert( iTrigDb==iDb || iTrigDb==1 );
+-    sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
+-  }
+-#endif
+-
+-  /* Drop the table and index from the internal schema.  */
+-  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
+-
+-  /* Reload the table, index and permanent trigger schemas. */
+-  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
+-  if( !zWhere ) return;
+-  sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
+-
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* Now, if the table is not stored in the temp database, reload any temp 
+-  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
+-  */
+-  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
+-    sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
+-  }
+-#endif
+-}
+-
+-/*
+-** Parameter zName is the name of a table that is about to be altered
+-** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
+-** If the table is a system table, this function leaves an error message
+-** in pParse->zErr (system tables may not be altered) and returns non-zero.
+-**
+-** Or, if zName is not a system table, zero is returned.
+-*/
+-static int isSystemTable(Parse *pParse, const char *zName){
+-  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+-    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+-    return 1;
+-  }
+-  return 0;
+-}
+-
+-/*
+ ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
+ ** command. 
+ */
+@@ -99927,9 +101566,6 @@
+   int nTabName;             /* Number of UTF-8 characters in zTabName */
+   const char *zTabName;     /* Original name of the table */
+   Vdbe *v;
+-#ifndef SQLITE_OMIT_TRIGGER
+-  char *zWhere = 0;         /* Where clause to locate temp triggers */
+-#endif
+   VTable *pVTab = 0;        /* Non-zero if this is a v-tab with an xRename() */
+   u32 savedDbFlags;         /* Saved value of db->mDbFlags */
+ 
+@@ -100002,52 +101638,25 @@
+   if( v==0 ){
+     goto exit_rename_table;
+   }
+-  sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
+-  sqlite3ChangeCookie(pParse, iDb);
+ 
+-  /* If this is a virtual table, invoke the xRename() function if
+-  ** one is defined. The xRename() callback will modify the names
+-  ** of any resources used by the v-table implementation (including other
+-  ** SQLite tables) that are identified by the name of the virtual table.
+-  */
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  if( pVTab ){
+-    int i = ++pParse->nMem;
+-    sqlite3VdbeLoadString(v, i, zName);
+-    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
+-    sqlite3MayAbort(pParse);
+-  }
+-#endif
+-
+   /* figure out how many UTF-8 characters are in zName */
+   zTabName = pTab->zName;
+   nTabName = sqlite3Utf8CharLen(zTabName, -1);
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  if( db->flags&SQLITE_ForeignKeys ){
+-    /* If foreign-key support is enabled, rewrite the CREATE TABLE 
+-    ** statements corresponding to all child tables of foreign key constraints
+-    ** for which the renamed table is the parent table.  */
+-    if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
+-      sqlite3NestedParse(pParse, 
+-          "UPDATE \"%w\".%s SET "
+-              "sql = sqlite_rename_parent(sql, %Q, %Q) "
+-              "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere);
+-      sqlite3DbFree(db, zWhere);
+-    }
+-  }
+-#endif
++  /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
++  ** the schema to use the new table name.  */
++  sqlite3NestedParse(pParse, 
++      "UPDATE \"%w\".%s SET "
++      "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
++      "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
++      "AND   name NOT LIKE 'sqlite_%%'"
++      , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
++  );
+ 
+-  /* Modify the sqlite_master table to use the new table name. */
++  /* Update the tbl_name and name columns of the sqlite_master table
++  ** as required.  */
+   sqlite3NestedParse(pParse,
+       "UPDATE %Q.%s SET "
+-#ifdef SQLITE_OMIT_TRIGGER
+-          "sql = sqlite_rename_table(sql, %Q), "
+-#else
+-          "sql = CASE "
+-            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
+-            "ELSE sqlite_rename_table(sql, %Q) END, "
+-#endif
+           "tbl_name = %Q, "
+           "name = CASE "
+             "WHEN type='table' THEN %Q "
+@@ -100056,11 +101665,9 @@
+             "ELSE name END "
+       "WHERE tbl_name=%Q COLLATE nocase AND "
+           "(type='table' OR type='index' OR type='trigger');", 
+-      zDb, MASTER_NAME, zName, zName, zName, 
+-#ifndef SQLITE_OMIT_TRIGGER
+-      zName,
+-#endif
+-      zName, nTabName, zTabName
++      zDb, MASTER_NAME, 
++      zName, zName, zName, 
++      nTabName, zTabName
+   );
+ 
+ #ifndef SQLITE_OMIT_AUTOINCREMENT
+@@ -100074,35 +101681,37 @@
+   }
+ #endif
+ 
+-#ifndef SQLITE_OMIT_TRIGGER
+-  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
+-  ** table. Don't do this if the table being ALTERed is itself located in
+-  ** the temp database.
+-  */
+-  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
++  /* If the table being renamed is not itself part of the temp database,
++  ** edit view and trigger definitions within the temp database 
++  ** as required.  */
++  if( iDb!=1 ){
+     sqlite3NestedParse(pParse, 
+         "UPDATE sqlite_temp_master SET "
+-            "sql = sqlite_rename_trigger(sql, %Q), "
+-            "tbl_name = %Q "
+-            "WHERE %s;", zName, zName, zWhere);
+-    sqlite3DbFree(db, zWhere);
++            "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
++            "tbl_name = "
++              "CASE WHEN tbl_name=%Q COLLATE nocase AND "
++              "          sqlite_rename_test(%Q, sql, type, name, 1) "
++              "THEN %Q ELSE tbl_name END "
++            "WHERE type IN ('view', 'trigger')"
++        , zDb, zTabName, zName, zTabName, zDb, zName);
+   }
+-#endif
+ 
+-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+-  if( db->flags&SQLITE_ForeignKeys ){
+-    FKey *p;
+-    for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
+-      Table *pFrom = p->pFrom;
+-      if( pFrom!=pTab ){
+-        reloadTableSchema(pParse, p->pFrom, pFrom->zName);
+-      }
+-    }
++  /* If this is a virtual table, invoke the xRename() function if
++  ** one is defined. The xRename() callback will modify the names
++  ** of any resources used by the v-table implementation (including other
++  ** SQLite tables) that are identified by the name of the virtual table.
++  */
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( pVTab ){
++    int i = ++pParse->nMem;
++    sqlite3VdbeLoadString(v, i, zName);
++    sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
++    sqlite3MayAbort(pParse);
+   }
+ #endif
+ 
+-  /* Drop and reload the internal table schema. */
+-  reloadTableSchema(pParse, pTab, zName);
++  renameReloadSchema(pParse, iDb);
++  renameTestSchema(pParse, zDb, iDb==1);
+ 
+ exit_rename_table:
+   sqlite3SrcListDelete(db, pSrc);
+@@ -100128,12 +101737,11 @@
+   Column *pCol;             /* The new column */
+   Expr *pDflt;              /* Default value for the new column */
+   sqlite3 *db;              /* The database connection; */
+-  Vdbe *v = pParse->pVdbe;  /* The prepared statement under construction */
++  Vdbe *v;                  /* The prepared statement under construction */
+   int r1;                   /* Temporary registers */
+ 
+   db = pParse->db;
+   if( pParse->nErr || db->mallocFailed ) return;
+-  assert( v!=0 );
+   pNew = pParse->pNewTable;
+   assert( pNew );
+ 
+@@ -100228,17 +101836,20 @@
+   ** from less than 3 to 4, as that will corrupt any preexisting DESC
+   ** index.
+   */
+-  r1 = sqlite3GetTempReg(pParse);
+-  sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+-  sqlite3VdbeUsesBtree(v, iDb);
+-  sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
+-  sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
+-  VdbeCoverage(v);
+-  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
+-  sqlite3ReleaseTempReg(pParse, r1);
++  v = sqlite3GetVdbe(pParse);
++  if( v ){
++    r1 = sqlite3GetTempReg(pParse);
++    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
++    sqlite3VdbeUsesBtree(v, iDb);
++    sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
++    sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
++    sqlite3ReleaseTempReg(pParse, r1);
++  }
+ 
+-  /* Reload the schema of the modified table. */
+-  reloadTableSchema(pParse, pTab, pTab->zName);
++  /* Reload the table definition */
++  renameReloadSchema(pParse, iDb);
+ }
+ 
+ /*
+@@ -100259,7 +101870,6 @@
+ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
+   Table *pNew;
+   Table *pTab;
+-  Vdbe *v;
+   int iDb;
+   int i;
+   int nAlloc;
+@@ -100323,16 +101933,1146 @@
+   pNew->addColOffset = pTab->addColOffset;
+   pNew->nTabRef = 1;
+ 
+-  /* Begin a transaction and increment the schema cookie.  */
+-  sqlite3BeginWriteOperation(pParse, 0, iDb);
+-  v = sqlite3GetVdbe(pParse);
+-  if( !v ) goto exit_begin_add_column;
+-  sqlite3ChangeCookie(pParse, iDb);
+-
+ exit_begin_add_column:
+   sqlite3SrcListDelete(db, pSrc);
+   return;
+ }
++
++/*
++** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN
++** command. This function checks if the table is a view or virtual
++** table (columns of views or virtual tables may not be renamed). If so,
++** it loads an error message into pParse and returns non-zero.
++**
++** Or, if pTab is not a view or virtual table, zero is returned.
++*/
++#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
++static int isRealTable(Parse *pParse, Table *pTab){
++  const char *zType = 0;
++#ifndef SQLITE_OMIT_VIEW
++  if( pTab->pSelect ){
++    zType = "view";
++  }
++#endif
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  if( IsVirtual(pTab) ){
++    zType = "virtual table";
++  }
++#endif
++  if( zType ){
++    sqlite3ErrorMsg(
++        pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName
++    );
++    return 1;
++  }
++  return 0;
++}
++#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
++# define isRealTable(x,y) (0)
++#endif
++
++/*
++** Handles the following parser reduction:
++**
++**  cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew
++*/
++SQLITE_PRIVATE void sqlite3AlterRenameColumn(
++  Parse *pParse,                  /* Parsing context */
++  SrcList *pSrc,                  /* Table being altered.  pSrc->nSrc==1 */
++  Token *pOld,                    /* Name of column being changed */
++  Token *pNew                     /* New column name */
++){
++  sqlite3 *db = pParse->db;       /* Database connection */
++  Table *pTab;                    /* Table being updated */
++  int iCol;                       /* Index of column being renamed */
++  char *zOld = 0;                 /* Old column name */
++  char *zNew = 0;                 /* New column name */
++  const char *zDb;                /* Name of schema containing the table */
++  int iSchema;                    /* Index of the schema */
++  int bQuote;                     /* True to quote the new name */
++
++  /* Locate the table to be altered */
++  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
++  if( !pTab ) goto exit_rename_column;
++
++  /* Cannot alter a system table */
++  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
++  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
++
++  /* Which schema holds the table to be altered */  
++  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
++  assert( iSchema>=0 );
++  zDb = db->aDb[iSchema].zDbSName;
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  /* Invoke the authorization callback. */
++  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
++    goto exit_rename_column;
++  }
++#endif
++
++  /* Make sure the old name really is a column name in the table to be
++  ** altered.  Set iCol to be the index of the column being renamed */
++  zOld = sqlite3NameFromToken(db, pOld);
++  if( !zOld ) goto exit_rename_column;
++  for(iCol=0; iCol<pTab->nCol; iCol++){
++    if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break;
++  }
++  if( iCol==pTab->nCol ){
++    sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld);
++    goto exit_rename_column;
++  }
++
++  /* Do the rename operation using a recursive UPDATE statement that
++  ** uses the sqlite_rename_column() SQL function to compute the new
++  ** CREATE statement text for the sqlite_master table.
++  */
++  zNew = sqlite3NameFromToken(db, pNew);
++  if( !zNew ) goto exit_rename_column;
++  assert( pNew->n>0 );
++  bQuote = sqlite3Isquote(pNew->z[0]);
++  sqlite3NestedParse(pParse, 
++      "UPDATE \"%w\".%s SET "
++      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
++      "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
++      " AND sql NOT LIKE 'create virtual%%'",
++      zDb, MASTER_NAME, 
++      zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
++      pTab->zName
++  );
++
++  sqlite3NestedParse(pParse, 
++      "UPDATE temp.%s SET "
++      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
++      "WHERE type IN ('trigger', 'view')",
++      MASTER_NAME, 
++      zDb, pTab->zName, iCol, zNew, bQuote
++  );
++
++  /* Drop and reload the database schema. */
++  renameReloadSchema(pParse, iSchema);
++  renameTestSchema(pParse, zDb, iSchema==1);
++
++ exit_rename_column:
++  sqlite3SrcListDelete(db, pSrc);
++  sqlite3DbFree(db, zOld);
++  sqlite3DbFree(db, zNew);
++  return;
++}
++
++/*
++** Each RenameToken object maps an element of the parse tree into
++** the token that generated that element.  The parse tree element
++** might be one of:
++**
++**     *  A pointer to an Expr that represents an ID
++**     *  The name of a table column in Column.zName
++**
++** A list of RenameToken objects can be constructed during parsing.
++** Each new object is created by sqlite3RenameTokenMap().
++** As the parse tree is transformed, the sqlite3RenameTokenRemap()
++** routine is used to keep the mapping current.
++**
++** After the parse finishes, renameTokenFind() routine can be used
++** to look up the actual token value that created some element in
++** the parse tree.
++*/
++struct RenameToken {
++  void *p;               /* Parse tree element created by token t */
++  Token t;               /* The token that created parse tree element p */
++  RenameToken *pNext;    /* Next is a list of all RenameToken objects */
++};
++
++/*
++** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
++** down into the Walker.
++*/
++typedef struct RenameCtx RenameCtx;
++struct RenameCtx {
++  RenameToken *pList;             /* List of tokens to overwrite */
++  int nList;                      /* Number of tokens in pList */
++  int iCol;                       /* Index of column being renamed */
++  Table *pTab;                    /* Table being ALTERed */ 
++  const char *zOld;               /* Old column name */
++};
++
++#ifdef SQLITE_DEBUG
++/*
++** This function is only for debugging. It performs two tasks:
++**
++**   1. Checks that pointer pPtr does not already appear in the 
++**      rename-token list.
++**
++**   2. Dereferences each pointer in the rename-token list.
++**
++** The second is most effective when debugging under valgrind or
++** address-sanitizer or similar. If any of these pointers no longer 
++** point to valid objects, an exception is raised by the memory-checking 
++** tool.
++**
++** The point of this is to prevent comparisons of invalid pointer values.
++** Even though this always seems to work, it is undefined according to the
++** C standard. Example of undefined comparison:
++**
++**     sqlite3_free(x);
++**     if( x==y ) ...
++**
++** Technically, as x no longer points into a valid object or to the byte
++** following a valid object, it may not be used in comparison operations.
++*/
++static void renameTokenCheckAll(Parse *pParse, void *pPtr){
++  if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
++    RenameToken *p;
++    u8 i = 0;
++    for(p=pParse->pRename; p; p=p->pNext){
++      if( p->p ){
++        assert( p->p!=pPtr );
++        i += *(u8*)(p->p);
++      }
++    }
++  }
++}
++#else
++# define renameTokenCheckAll(x,y)
++#endif
++
++/*
++** Remember that the parser tree element pPtr was created using
++** the token pToken.
++**
++** In other words, construct a new RenameToken object and add it
++** to the list of RenameToken objects currently being built up
++** in pParse->pRename.
++**
++** The pPtr argument is returned so that this routine can be used
++** with tail recursion in tokenExpr() routine, for a small performance
++** improvement.
++*/
++SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
++  RenameToken *pNew;
++  assert( pPtr || pParse->db->mallocFailed );
++  renameTokenCheckAll(pParse, pPtr);
++  pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
++  if( pNew ){
++    pNew->p = pPtr;
++    pNew->t = *pToken;
++    pNew->pNext = pParse->pRename;
++    pParse->pRename = pNew;
++  }
++
++  return pPtr;
++}
++
++/*
++** It is assumed that there is already a RenameToken object associated
++** with parse tree element pFrom. This function remaps the associated token
++** to parse tree element pTo.
++*/
++SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){
++  RenameToken *p;
++  renameTokenCheckAll(pParse, pTo);
++  for(p=pParse->pRename; p; p=p->pNext){
++    if( p->p==pFrom ){
++      p->p = pTo;
++      break;
++    }
++  }
++}
++
++/*
++** Walker callback used by sqlite3RenameExprUnmap().
++*/
++static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
++  Parse *pParse = pWalker->pParse;
++  sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);
++  return WRC_Continue;
++}
++
++/*
++** Remove all nodes that are part of expression pExpr from the rename list.
++*/
++SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
++  Walker sWalker;
++  memset(&sWalker, 0, sizeof(Walker));
++  sWalker.pParse = pParse;
++  sWalker.xExprCallback = renameUnmapExprCb;
++  sqlite3WalkExpr(&sWalker, pExpr);
++}
++
++/*
++** Remove all nodes that are part of expression-list pEList from the 
++** rename list.
++*/
++SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
++  if( pEList ){
++    int i;
++    Walker sWalker;
++    memset(&sWalker, 0, sizeof(Walker));
++    sWalker.pParse = pParse;
++    sWalker.xExprCallback = renameUnmapExprCb;
++    sqlite3WalkExprList(&sWalker, pEList);
++    for(i=0; i<pEList->nExpr; i++){
++      sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
++    }
++  }
++}
++
++/*
++** Free the list of RenameToken objects given in the second argument
++*/
++static void renameTokenFree(sqlite3 *db, RenameToken *pToken){
++  RenameToken *pNext;
++  RenameToken *p;
++  for(p=pToken; p; p=pNext){
++    pNext = p->pNext;
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Search the Parse object passed as the first argument for a RenameToken
++** object associated with parse tree element pPtr. If found, remove it
++** from the Parse object and add it to the list maintained by the
++** RenameCtx object passed as the second argument.
++*/
++static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
++  RenameToken **pp;
++  assert( pPtr!=0 );
++  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
++    if( (*pp)->p==pPtr ){
++      RenameToken *pToken = *pp;
++      *pp = pToken->pNext;
++      pToken->pNext = pCtx->pList;
++      pCtx->pList = pToken;
++      pCtx->nList++;
++      break;
++    }
++  }
++}
++
++/*
++** This is a Walker select callback. It does nothing. It is only required
++** because without a dummy callback, sqlite3WalkExpr() and similar do not
++** descend into sub-select statements.
++*/
++static int renameColumnSelectCb(Walker *pWalker, Select *p){
++  UNUSED_PARAMETER(pWalker);
++  UNUSED_PARAMETER(p);
++  return WRC_Continue;
++}
++
++/*
++** This is a Walker expression callback.
++**
++** For every TK_COLUMN node in the expression tree, search to see
++** if the column being references is the column being renamed by an
++** ALTER TABLE statement.  If it is, then attach its associated
++** RenameToken object to the list of RenameToken objects being
++** constructed in RenameCtx object at pWalker->u.pRename.
++*/
++static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
++  RenameCtx *p = pWalker->u.pRename;
++  if( pExpr->op==TK_TRIGGER 
++   && pExpr->iColumn==p->iCol 
++   && pWalker->pParse->pTriggerTab==p->pTab
++  ){
++    renameTokenFind(pWalker->pParse, p, (void*)pExpr);
++  }else if( pExpr->op==TK_COLUMN 
++   && pExpr->iColumn==p->iCol 
++   && p->pTab==pExpr->y.pTab
++  ){
++    renameTokenFind(pWalker->pParse, p, (void*)pExpr);
++  }
++  return WRC_Continue;
++}
++
++/*
++** The RenameCtx contains a list of tokens that reference a column that
++** is being renamed by an ALTER TABLE statement.  Return the "last"
++** RenameToken in the RenameCtx and remove that RenameToken from the
++** RenameContext.  "Last" means the last RenameToken encountered when
++** the input SQL is parsed from left to right.  Repeated calls to this routine
++** return all column name tokens in the order that they are encountered
++** in the SQL statement.
++*/
++static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){
++  RenameToken *pBest = pCtx->pList;
++  RenameToken *pToken;
++  RenameToken **pp;
++
++  for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){
++    if( pToken->t.z>pBest->t.z ) pBest = pToken;
++  }
++  for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
++  *pp = pBest->pNext;
++
++  return pBest;
++}
++
++/*
++** An error occured while parsing or otherwise processing a database
++** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
++** ALTER TABLE RENAME COLUMN program. The error message emitted by the
++** sub-routine is currently stored in pParse->zErrMsg. This function
++** adds context to the error message and then stores it in pCtx.
++*/
++static void renameColumnParseError(
++  sqlite3_context *pCtx, 
++  int bPost,
++  sqlite3_value *pType,
++  sqlite3_value *pObject,
++  Parse *pParse
++){
++  const char *zT = (const char*)sqlite3_value_text(pType);
++  const char *zN = (const char*)sqlite3_value_text(pObject);
++  char *zErr;
++
++  zErr = sqlite3_mprintf("error in %s %s%s: %s", 
++      zT, zN, (bPost ? " after rename" : ""),
++      pParse->zErrMsg
++  );
++  sqlite3_result_error(pCtx, zErr, -1);
++  sqlite3_free(zErr);
++}
++
++/*
++** For each name in the the expression-list pEList (i.e. each
++** pEList->a[i].zName) that matches the string in zOld, extract the 
++** corresponding rename-token from Parse object pParse and add it
++** to the RenameCtx pCtx.
++*/
++static void renameColumnElistNames(
++  Parse *pParse, 
++  RenameCtx *pCtx, 
++  ExprList *pEList, 
++  const char *zOld
++){
++  if( pEList ){
++    int i;
++    for(i=0; i<pEList->nExpr; i++){
++      char *zName = pEList->a[i].zName;
++      if( 0==sqlite3_stricmp(zName, zOld) ){
++        renameTokenFind(pParse, pCtx, (void*)zName);
++      }
++    }
++  }
++}
++
++/*
++** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) 
++** that matches the string in zOld, extract the corresponding rename-token 
++** from Parse object pParse and add it to the RenameCtx pCtx.
++*/
++static void renameColumnIdlistNames(
++  Parse *pParse, 
++  RenameCtx *pCtx, 
++  IdList *pIdList, 
++  const char *zOld
++){
++  if( pIdList ){
++    int i;
++    for(i=0; i<pIdList->nId; i++){
++      char *zName = pIdList->a[i].zName;
++      if( 0==sqlite3_stricmp(zName, zOld) ){
++        renameTokenFind(pParse, pCtx, (void*)zName);
++      }
++    }
++  }
++}
++
++/*
++** Parse the SQL statement zSql using Parse object (*p). The Parse object
++** is initialized by this function before it is used.
++*/
++static int renameParseSql(
++  Parse *p,                       /* Memory to use for Parse object */
++  const char *zDb,                /* Name of schema SQL belongs to */
++  int bTable,                     /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
++  sqlite3 *db,                    /* Database handle */
++  const char *zSql,               /* SQL to parse */
++  int bTemp                       /* True if SQL is from temp schema */
++){
++  int rc;
++  char *zErr = 0;
++
++  db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb);
++
++  /* Parse the SQL statement passed as the first argument. If no error
++  ** occurs and the parse does not result in a new table, index or
++  ** trigger object, the database must be corrupt. */
++  memset(p, 0, sizeof(Parse));
++  p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
++  p->db = db;
++  p->nQueryLoop = 1;
++  rc = sqlite3RunParser(p, zSql, &zErr);
++  assert( p->zErrMsg==0 );
++  assert( rc!=SQLITE_OK || zErr==0 );
++  assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 );
++  p->zErrMsg = zErr;
++  if( db->mallocFailed ) rc = SQLITE_NOMEM;
++  if( rc==SQLITE_OK 
++   && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 
++  ){
++    rc = SQLITE_CORRUPT_BKPT;
++  }
++
++#ifdef SQLITE_DEBUG
++  /* Ensure that all mappings in the Parse.pRename list really do map to
++  ** a part of the input string.  */
++  if( rc==SQLITE_OK ){
++    int nSql = sqlite3Strlen30(zSql);
++    RenameToken *pToken;
++    for(pToken=p->pRename; pToken; pToken=pToken->pNext){
++      assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] );
++    }
++  }
++#endif
++
++  db->init.iDb = 0;
++  return rc;
++}
++
++/*
++** This function edits SQL statement zSql, replacing each token identified
++** by the linked list pRename with the text of zNew. If argument bQuote is
++** true, then zNew is always quoted first. If no error occurs, the result
++** is loaded into context object pCtx as the result.
++**
++** Or, if an error occurs (i.e. an OOM condition), an error is left in
++** pCtx and an SQLite error code returned.
++*/
++static int renameEditSql(
++  sqlite3_context *pCtx,          /* Return result here */
++  RenameCtx *pRename,             /* Rename context */
++  const char *zSql,               /* SQL statement to edit */
++  const char *zNew,               /* New token text */
++  int bQuote                      /* True to always quote token */
++){
++  int nNew = sqlite3Strlen30(zNew);
++  int nSql = sqlite3Strlen30(zSql);
++  sqlite3 *db = sqlite3_context_db_handle(pCtx);
++  int rc = SQLITE_OK;
++  char *zQuot;
++  char *zOut;
++  int nQuot;
++
++  /* Set zQuot to point to a buffer containing a quoted copy of the 
++  ** identifier zNew. If the corresponding identifier in the original 
++  ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to
++  ** point to zQuot so that all substitutions are made using the
++  ** quoted version of the new column name.  */
++  zQuot = sqlite3MPrintf(db, "\"%w\"", zNew);
++  if( zQuot==0 ){
++    return SQLITE_NOMEM;
++  }else{
++    nQuot = sqlite3Strlen30(zQuot);
++  }
++  if( bQuote ){
++    zNew = zQuot;
++    nNew = nQuot;
++  }
++
++  /* At this point pRename->pList contains a list of RenameToken objects
++  ** corresponding to all tokens in the input SQL that must be replaced
++  ** with the new column name. All that remains is to construct and
++  ** return the edited SQL string. */
++  assert( nQuot>=nNew );
++  zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1);
++  if( zOut ){
++    int nOut = nSql;
++    memcpy(zOut, zSql, nSql);
++    while( pRename->pList ){
++      int iOff;                   /* Offset of token to replace in zOut */
++      RenameToken *pBest = renameColumnTokenNext(pRename);
++
++      u32 nReplace;
++      const char *zReplace;
++      if( sqlite3IsIdChar(*pBest->t.z) ){
++        nReplace = nNew;
++        zReplace = zNew;
++      }else{
++        nReplace = nQuot;
++        zReplace = zQuot;
++      }
++
++      iOff = pBest->t.z - zSql;
++      if( pBest->t.n!=nReplace ){
++        memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], 
++            nOut - (iOff + pBest->t.n)
++        );
++        nOut += nReplace - pBest->t.n;
++        zOut[nOut] = '\0';
++      }
++      memcpy(&zOut[iOff], zReplace, nReplace);
++      sqlite3DbFree(db, pBest);
++    }
++
++    sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT);
++    sqlite3DbFree(db, zOut);
++  }else{
++    rc = SQLITE_NOMEM;
++  }
++
++  sqlite3_free(zQuot);
++  return rc;
++}
++
++/*
++** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming
++** it was read from the schema of database zDb. Return SQLITE_OK if 
++** successful. Otherwise, return an SQLite error code and leave an error
++** message in the Parse object.
++*/
++static int renameResolveTrigger(Parse *pParse, const char *zDb){
++  sqlite3 *db = pParse->db;
++  Trigger *pNew = pParse->pNewTrigger;
++  TriggerStep *pStep;
++  NameContext sNC;
++  int rc = SQLITE_OK;
++
++  memset(&sNC, 0, sizeof(sNC));
++  sNC.pParse = pParse;
++  assert( pNew->pTabSchema );
++  pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, 
++      db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
++  );
++  pParse->eTriggerOp = pNew->op;
++  /* ALWAYS() because if the table of the trigger does not exist, the
++  ** error would have been hit before this point */
++  if( ALWAYS(pParse->pTriggerTab) ){
++    rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
++  }
++
++  /* Resolve symbols in WHEN clause */
++  if( rc==SQLITE_OK && pNew->pWhen ){
++    rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
++  }
++
++  for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
++    if( pStep->pSelect ){
++      sqlite3SelectPrep(pParse, pStep->pSelect, &sNC);
++      if( pParse->nErr ) rc = pParse->rc;
++    }
++    if( rc==SQLITE_OK && pStep->zTarget ){
++      Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb);
++      if( pTarget==0 ){
++        rc = SQLITE_ERROR;
++      }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){
++        SrcList sSrc;
++        memset(&sSrc, 0, sizeof(sSrc));
++        sSrc.nSrc = 1;
++        sSrc.a[0].zName = pStep->zTarget;
++        sSrc.a[0].pTab = pTarget;
++        sNC.pSrcList = &sSrc;
++        if( pStep->pWhere ){
++          rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
++        }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
++        }
++        assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) );
++        if( pStep->pUpsert ){
++          Upsert *pUpsert = pStep->pUpsert;
++          assert( rc==SQLITE_OK );
++          pUpsert->pUpsertSrc = &sSrc;
++          sNC.uNC.pUpsert = pUpsert;
++          sNC.ncFlags = NC_UUpsert;
++          rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
++          if( rc==SQLITE_OK ){
++            ExprList *pUpsertSet = pUpsert->pUpsertSet;
++            rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere);
++          }
++          if( rc==SQLITE_OK ){
++            rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
++          }
++          sNC.ncFlags = 0;
++        }
++      }
++    }
++  }
++  return rc;
++}
++
++/*
++** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr
++** objects that are part of the trigger passed as the second argument.
++*/
++static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
++  TriggerStep *pStep;
++
++  /* Find tokens to edit in WHEN clause */
++  sqlite3WalkExpr(pWalker, pTrigger->pWhen);
++
++  /* Find tokens to edit in trigger steps */
++  for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
++    sqlite3WalkSelect(pWalker, pStep->pSelect);
++    sqlite3WalkExpr(pWalker, pStep->pWhere);
++    sqlite3WalkExprList(pWalker, pStep->pExprList);
++    if( pStep->pUpsert ){
++      Upsert *pUpsert = pStep->pUpsert;
++      sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget);
++      sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet);
++      sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere);
++      sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere);
++    }
++  }
++}
++
++/*
++** Free the contents of Parse object (*pParse). Do not free the memory
++** occupied by the Parse object itself.
++*/
++static void renameParseCleanup(Parse *pParse){
++  sqlite3 *db = pParse->db;
++  if( pParse->pVdbe ){
++    sqlite3VdbeFinalize(pParse->pVdbe);
++  }
++  sqlite3DeleteTable(db, pParse->pNewTable);
++  if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
++  sqlite3DeleteTrigger(db, pParse->pNewTrigger);
++  sqlite3DbFree(db, pParse->zErrMsg);
++  renameTokenFree(db, pParse->pRename);
++  sqlite3ParserReset(pParse);
++}
++
++/*
++** SQL function:
++**
++**     sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
++**
++**   0. zSql:     SQL statement to rewrite
++**   1. type:     Type of object ("table", "view" etc.)
++**   2. object:   Name of object
++**   3. Database: Database name (e.g. "main")
++**   4. Table:    Table name
++**   5. iCol:     Index of column to rename
++**   6. zNew:     New column name
++**   7. bQuote:   Non-zero if the new column name should be quoted.
++**   8. bTemp:    True if zSql comes from temp schema
++**
++** Do a column rename operation on the CREATE statement given in zSql.
++** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
++** into zNew.  The name should be quoted if bQuote is true.
++**
++** This function is used internally by the ALTER TABLE RENAME COLUMN command.
++** It is only accessible to SQL created using sqlite3NestedParse().  It is
++** not reachable from ordinary SQL passed into sqlite3_prepare().
++*/
++static void renameColumnFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  RenameCtx sCtx;
++  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
++  const char *zDb = (const char*)sqlite3_value_text(argv[3]);
++  const char *zTable = (const char*)sqlite3_value_text(argv[4]);
++  int iCol = sqlite3_value_int(argv[5]);
++  const char *zNew = (const char*)sqlite3_value_text(argv[6]);
++  int bQuote = sqlite3_value_int(argv[7]);
++  int bTemp = sqlite3_value_int(argv[8]);
++  const char *zOld;
++  int rc;
++  Parse sParse;
++  Walker sWalker;
++  Index *pIdx;
++  int i;
++  Table *pTab;
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  sqlite3_xauth xAuth = db->xAuth;
++#endif
++
++  UNUSED_PARAMETER(NotUsed);
++  if( zSql==0 ) return;
++  if( zTable==0 ) return;
++  if( zNew==0 ) return;
++  if( iCol<0 ) return;
++  sqlite3BtreeEnterAll(db);
++  pTab = sqlite3FindTable(db, zTable, zDb);
++  if( pTab==0 || iCol>=pTab->nCol ){
++    sqlite3BtreeLeaveAll(db);
++    return;
++  }
++  zOld = pTab->aCol[iCol].zName;
++  memset(&sCtx, 0, sizeof(sCtx));
++  sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = 0;
++#endif
++  rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);
++
++  /* Find tokens that need to be replaced. */
++  memset(&sWalker, 0, sizeof(Walker));
++  sWalker.pParse = &sParse;
++  sWalker.xExprCallback = renameColumnExprCb;
++  sWalker.xSelectCallback = renameColumnSelectCb;
++  sWalker.u.pRename = &sCtx;
++
++  sCtx.pTab = pTab;
++  if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++  if( sParse.pNewTable ){
++    Select *pSelect = sParse.pNewTable->pSelect;
++    if( pSelect ){
++      sParse.rc = SQLITE_OK;
++      sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
++      rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
++      if( rc==SQLITE_OK ){
++        sqlite3WalkSelect(&sWalker, pSelect);
++      }
++      if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++    }else{
++      /* A regular table */
++      int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
++      FKey *pFKey;
++      assert( sParse.pNewTable->pSelect==0 );
++      sCtx.pTab = sParse.pNewTable;
++      if( bFKOnly==0 ){
++        renameTokenFind(
++            &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName
++        );
++        if( sCtx.iCol<0 ){
++          renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey);
++        }
++        sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck);
++        for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
++          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
++        }
++      }
++
++      for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
++        for(i=0; i<pFKey->nCol; i++){
++          if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
++            renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
++          }
++          if( 0==sqlite3_stricmp(pFKey->zTo, zTable)
++           && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld)
++          ){
++            renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol);
++          }
++        }
++      }
++    }
++  }else if( sParse.pNewIndex ){
++    sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
++    sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
++  }else{
++    /* A trigger */
++    TriggerStep *pStep;
++    rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb));
++    if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
++
++    for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){
++      if( pStep->zTarget ){ 
++        Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb);
++        if( pTarget==pTab ){
++          if( pStep->pUpsert ){
++            ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet;
++            renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld);
++          }
++          renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld);
++          renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld);
++        }
++      }
++    }
++
++
++    /* Find tokens to edit in UPDATE OF clause */
++    if( sParse.pTriggerTab==pTab ){
++      renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld);
++    }
++
++    /* Find tokens to edit in various expressions and selects */
++    renameWalkTrigger(&sWalker, sParse.pNewTrigger);
++  }
++
++  assert( rc==SQLITE_OK );
++  rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote);
++
++renameColumnFunc_done:
++  if( rc!=SQLITE_OK ){
++    if( sParse.zErrMsg ){
++      renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
++    }else{
++      sqlite3_result_error_code(context, rc);
++    }
++  }
++
++  renameParseCleanup(&sParse);
++  renameTokenFree(db, sCtx.pList);
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = xAuth;
++#endif
++  sqlite3BtreeLeaveAll(db);
++}
++
++/*
++** Walker expression callback used by "RENAME TABLE". 
++*/
++static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
++  RenameCtx *p = pWalker->u.pRename;
++  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
++    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
++  }
++  return WRC_Continue;
++}
++
++/*
++** Walker select callback used by "RENAME TABLE". 
++*/
++static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
++  int i;
++  RenameCtx *p = pWalker->u.pRename;
++  SrcList *pSrc = pSelect->pSrc;
++  for(i=0; i<pSrc->nSrc; i++){
++    struct SrcList_item *pItem = &pSrc->a[i];
++    if( pItem->pTab==p->pTab ){
++      renameTokenFind(pWalker->pParse, p, pItem->zName);
++    }
++  }
++
++  return WRC_Continue;
++}
++
++
++/*
++** This C function implements an SQL user function that is used by SQL code
++** generated by the ALTER TABLE ... RENAME command to modify the definition
++** of any foreign key constraints that use the table being renamed as the 
++** parent table. It is passed three arguments:
++**
++**   0: The database containing the table being renamed.
++**   1. type:     Type of object ("table", "view" etc.)
++**   2. object:   Name of object
++**   3: The complete text of the schema statement being modified,
++**   4: The old name of the table being renamed, and
++**   5: The new name of the table being renamed.
++**   6: True if the schema statement comes from the temp db.
++**
++** It returns the new schema statement. For example:
++**
++** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0)
++**       -> 'CREATE TABLE t1(a REFERENCES t3)'
++*/
++static void renameTableFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  const char *zDb = (const char*)sqlite3_value_text(argv[0]);
++  const char *zInput = (const char*)sqlite3_value_text(argv[3]);
++  const char *zOld = (const char*)sqlite3_value_text(argv[4]);
++  const char *zNew = (const char*)sqlite3_value_text(argv[5]);
++  int bTemp = sqlite3_value_int(argv[6]);
++  UNUSED_PARAMETER(NotUsed);
++
++  if( zInput && zOld && zNew ){
++    Parse sParse;
++    int rc;
++    int bQuote = 1;
++    RenameCtx sCtx;
++    Walker sWalker;
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++    sqlite3_xauth xAuth = db->xAuth;
++    db->xAuth = 0;
++#endif
++
++    sqlite3BtreeEnterAll(db);
++
++    memset(&sCtx, 0, sizeof(RenameCtx));
++    sCtx.pTab = sqlite3FindTable(db, zOld, zDb);
++    memset(&sWalker, 0, sizeof(Walker));
++    sWalker.pParse = &sParse;
++    sWalker.xExprCallback = renameTableExprCb;
++    sWalker.xSelectCallback = renameTableSelectCb;
++    sWalker.u.pRename = &sCtx;
++
++    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
++
++    if( rc==SQLITE_OK ){
++      int isLegacy = (db->flags & SQLITE_LegacyAlter);
++      if( sParse.pNewTable ){
++        Table *pTab = sParse.pNewTable;
++
++        if( pTab->pSelect ){
++          if( isLegacy==0 ){
++            NameContext sNC;
++            memset(&sNC, 0, sizeof(sNC));
++            sNC.pParse = &sParse;
++
++            sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
++            if( sParse.nErr ) rc = sParse.rc;
++            sqlite3WalkSelect(&sWalker, pTab->pSelect);
++          }
++        }else{
++          /* Modify any FK definitions to point to the new table. */
++#ifndef SQLITE_OMIT_FOREIGN_KEY
++          if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
++            FKey *pFKey;
++            for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
++              if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
++                renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
++              }
++            }
++          }
++#endif
++
++          /* If this is the table being altered, fix any table refs in CHECK
++          ** expressions. Also update the name that appears right after the
++          ** "CREATE [VIRTUAL] TABLE" bit. */
++          if( sqlite3_stricmp(zOld, pTab->zName)==0 ){
++            sCtx.pTab = pTab;
++            if( isLegacy==0 ){
++              sqlite3WalkExprList(&sWalker, pTab->pCheck);
++            }
++            renameTokenFind(&sParse, &sCtx, pTab->zName);
++          }
++        }
++      }
++
++      else if( sParse.pNewIndex ){
++        renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName);
++        if( isLegacy==0 ){
++          sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
++        }
++      }
++
++#ifndef SQLITE_OMIT_TRIGGER
++      else{
++        Trigger *pTrigger = sParse.pNewTrigger;
++        TriggerStep *pStep;
++        if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) 
++            && sCtx.pTab->pSchema==pTrigger->pTabSchema
++          ){
++          renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table);
++        }
++
++        if( isLegacy==0 ){
++          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
++          if( rc==SQLITE_OK ){
++            renameWalkTrigger(&sWalker, pTrigger);
++            for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){
++              if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
++                renameTokenFind(&sParse, &sCtx, pStep->zTarget);
++              }
++            }
++          }
++        }
++      }
++#endif
++    }
++
++    if( rc==SQLITE_OK ){
++      rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
++    }
++    if( rc!=SQLITE_OK ){
++      if( sParse.zErrMsg ){
++        renameColumnParseError(context, 0, argv[1], argv[2], &sParse);
++      }else{
++        sqlite3_result_error_code(context, rc);
++      }
++    }
++
++    renameParseCleanup(&sParse);
++    renameTokenFree(db, sCtx.pList);
++    sqlite3BtreeLeaveAll(db);
++#ifndef SQLITE_OMIT_AUTHORIZATION
++    db->xAuth = xAuth;
++#endif
++  }
++
++  return;
++}
++
++/*
++** An SQL user function that checks that there are no parse or symbol
++** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
++** After an ALTER TABLE .. RENAME operation is performed and the schema
++** reloaded, this function is called on each SQL statement in the schema
++** to ensure that it is still usable.
++**
++**   0: Database name ("main", "temp" etc.).
++**   1: SQL statement.
++**   2: Object type ("view", "table", "trigger" or "index").
++**   3: Object name.
++**   4: True if object is from temp schema.
++**
++** Unless it finds an error, this function normally returns NULL. However, it
++** returns integer value 1 if:
++**
++**   * the SQL argument creates a trigger, and
++**   * the table that the trigger is attached to is in database zDb.
++*/
++static void renameTableTest(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **argv
++){
++  sqlite3 *db = sqlite3_context_db_handle(context);
++  char const *zDb = (const char*)sqlite3_value_text(argv[0]);
++  char const *zInput = (const char*)sqlite3_value_text(argv[1]);
++  int bTemp = sqlite3_value_int(argv[4]);
++  int isLegacy = (db->flags & SQLITE_LegacyAlter);
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  sqlite3_xauth xAuth = db->xAuth;
++  db->xAuth = 0;
++#endif
++
++  UNUSED_PARAMETER(NotUsed);
++  if( zDb && zInput ){
++    int rc;
++    Parse sParse;
++    rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
++    if( rc==SQLITE_OK ){
++      if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
++        NameContext sNC;
++        memset(&sNC, 0, sizeof(sNC));
++        sNC.pParse = &sParse;
++        sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC);
++        if( sParse.nErr ) rc = sParse.rc;
++      }
++
++      else if( sParse.pNewTrigger ){
++        if( isLegacy==0 ){
++          rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb);
++        }
++        if( rc==SQLITE_OK ){
++          int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
++          int i2 = sqlite3FindDbName(db, zDb);
++          if( i1==i2 ) sqlite3_result_int(context, 1);
++        }
++      }
++    }
++
++    if( rc!=SQLITE_OK ){
++      renameColumnParseError(context, 1, argv[2], argv[3], &sParse);
++    }
++    renameParseCleanup(&sParse);
++  }
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++  db->xAuth = xAuth;
++#endif
++}
++
++/*
++** Register built-in functions used to help implement ALTER TABLE
++*/
++SQLITE_PRIVATE void sqlite3AlterFunctions(void){
++  static FuncDef aAlterTableFuncs[] = {
++    INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
++    INTERNAL_FUNCTION(sqlite_rename_table,  7, renameTableFunc),
++    INTERNAL_FUNCTION(sqlite_rename_test,   5, renameTableTest),
++  };
++  sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
++}
+ #endif  /* SQLITE_ALTER_TABLE */
+ 
+ /************** End of alter.c ***********************************************/
+@@ -100824,6 +103564,7 @@
+   0,               /* pNext */
+   statInit,        /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_init",     /* zName */
+   {0}
+ };
+@@ -101140,6 +103881,7 @@
+   0,               /* pNext */
+   statPush,        /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_push",     /* zName */
+   {0}
+ };
+@@ -101291,6 +104033,7 @@
+   0,               /* pNext */
+   statGet,         /* xSFunc */
+   0,               /* xFinalize */
++  0, 0,            /* xValue, xInverse */
+   "stat_get",      /* zName */
+   {0}
+ };
+@@ -101610,10 +104353,7 @@
+       callStatGet(v, regStat4, STAT_GET_NLT, regLt);
+       callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
+       sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
+-      /* We know that the regSampleRowid row exists because it was read by
+-      ** the previous loop.  Thus the not-found jump of seekOp will never
+-      ** be taken */
+-      VdbeCoverageNeverTaken(v);
++      VdbeCoverage(v);
+ #ifdef SQLITE_ENABLE_STAT3
+       sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
+ #else
+@@ -102253,7 +104993,7 @@
+ 
+   /* Load the statistics from the sqlite_stat4 table. */
+ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+-  if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
++  if( rc==SQLITE_OK ){
+     db->lookaside.bDisable++;
+     rc = loadStat4(db, sInfo.zDatabase);
+     db->lookaside.bDisable--;
+@@ -102378,7 +105118,7 @@
+     if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
+     pNew->pBt = 0;
+     pNew->pSchema = 0;
+-    rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
++    rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+   }else{
+     /* This is a real ATTACH
+     **
+@@ -102436,7 +105176,7 @@
+     sqlite3_free( zPath );
+     db->nDb++;
+   }
+-  db->skipBtreeMutex = 0;
++  db->noSharedCache = 0;
+   if( rc==SQLITE_CONSTRAINT ){
+     rc = SQLITE_ERROR;
+     zErrDyn = sqlite3MPrintf(db, "database is already attached");
+@@ -102508,6 +105248,7 @@
+   if( rc==SQLITE_OK ){
+     sqlite3BtreeEnterAll(db);
+     db->init.iDb = 0;
++    db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
+     rc = sqlite3Init(db, &zErrDyn);
+     sqlite3BtreeLeaveAll(db);
+     assert( zErrDyn==0 || rc!=SQLITE_OK );
+@@ -102691,6 +105432,7 @@
+     0,                /* pNext */
+     detachFunc,       /* xSFunc */
+     0,                /* xFinalize */
++    0, 0,             /* xValue, xInverse */
+     "sqlite_detach",  /* zName */
+     {0}
+   };
+@@ -102710,6 +105452,7 @@
+     0,                /* pNext */
+     attachFunc,       /* xSFunc */
+     0,                /* xFinalize */
++    0, 0,             /* xValue, xInverse */
+     "sqlite_attach",  /* zName */
+     {0}
+   };
+@@ -102780,6 +105523,9 @@
+     if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
+     if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
+ #endif
++    if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){
++      return 1;
++    }
+   }
+   return 0;
+ }
+@@ -102879,6 +105625,18 @@
+     if( sqlite3FixExprList(pFix, pStep->pExprList) ){
+       return 1;
+     }
++#ifndef SQLITE_OMIT_UPSERT
++    if( pStep->pUpsert ){
++      Upsert *pUp = pStep->pUpsert;
++      if( sqlite3FixExprList(pFix, pUp->pUpsertTarget)
++       || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere)
++       || sqlite3FixExprList(pFix, pUp->pUpsertSet)
++       || sqlite3FixExpr(pFix, pUp->pUpsertWhere)
++      ){
++        return 1;
++      }
++    }
++#endif
+     pStep = pStep->pNext;
+   }
+   return 0;
+@@ -102967,7 +105725,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   db->xAuth = (sqlite3_xauth)xAuth;
+   db->pAuthArg = pArg;
+-  sqlite3ExpirePreparedStatements(db);
++  sqlite3ExpirePreparedStatements(db, 0);
+   sqlite3_mutex_leave(db->mutex);
+   return SQLITE_OK;
+ }
+@@ -103039,6 +105797,8 @@
+   int iDb;              /* The index of the database the expression refers to */
+   int iCol;             /* Index of column in table */
+ 
++  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
++  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
+   if( db->xAuth==0 ) return;
+   iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
+   if( iDb<0 ){
+@@ -103047,7 +105807,6 @@
+     return;
+   }
+ 
+-  assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
+   if( pExpr->op==TK_TRIGGER ){
+     pTab = pParse->pTriggerTab;
+   }else{
+@@ -103096,7 +105855,8 @@
+   /* Don't do any authorization checks if the database is initialising
+   ** or if the parser is being invoked from within sqlite3_declare_vtab.
+   */
+-  if( db->init.busy || IN_DECLARE_VTAB ){
++  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
++  if( db->init.busy || IN_SPECIAL_PARSE ){
+     return SQLITE_OK;
+   }
+ 
+@@ -103388,7 +106148,6 @@
+   /* Get the VDBE program ready for execution
+   */
+   if( v && pParse->nErr==0 && !db->mallocFailed ){
+-    assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
+     /* A minimum of one cursor is required if autoincrement is used
+     *  See ticket [a696379c1f08866] */
+     if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+@@ -103506,29 +106265,30 @@
+   const char *zDbase     /* Name of the database.  Might be NULL */
+ ){
+   Table *p;
++  sqlite3 *db = pParse->db;
+ 
+   /* Read the database schema. If an error occurs, leave an error message
+   ** and code in pParse and return NULL. */
+-  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
++  if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 
++   && SQLITE_OK!=sqlite3ReadSchema(pParse)
++  ){
+     return 0;
+   }
+ 
+-  p = sqlite3FindTable(pParse->db, zName, zDbase);
++  p = sqlite3FindTable(db, zName, zDbase);
+   if( p==0 ){
+     const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+-    if( sqlite3FindDbName(pParse->db, zDbase)<1 ){
+-      /* If zName is the not the name of a table in the schema created using
+-      ** CREATE, then check to see if it is the name of an virtual table that
+-      ** can be an eponymous virtual table. */
+-      Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+-      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+-        pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
+-      }
+-      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+-        return pMod->pEpoTab;
+-      }
++    /* If zName is the not the name of a table in the schema created using
++    ** CREATE, then check to see if it is the name of an virtual table that
++    ** can be an eponymous virtual table. */
++    Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
++    if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
++      pMod = sqlite3PragmaVtabRegister(db, zName);
+     }
++    if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
++      return pMod->pEpoTab;
++    }
+ #endif
+     if( (flags & LOCATE_NOERR)==0 ){
+       if( zDbase ){
+@@ -103600,7 +106360,7 @@
+ /*
+ ** Reclaim the memory used by an index
+ */
+-static void freeIndex(sqlite3 *db, Index *p){
++SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){
+ #ifndef SQLITE_OMIT_ANALYZE
+   sqlite3DeleteIndexSamples(db, p);
+ #endif
+@@ -103640,7 +106400,7 @@
+         p->pNext = pIndex->pNext;
+       }
+     }
+-    freeIndex(db, pIndex);
++    sqlite3FreeIndex(db, pIndex);
+   }
+   db->mDbFlags |= DBFLAG_SchemaChange;
+ }
+@@ -103688,6 +106448,7 @@
+     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+     DbSetProperty(db, iDb, DB_ResetWanted);
+     DbSetProperty(db, 1, DB_ResetWanted);
++    db->mDbFlags &= ~DBFLAG_SchemaKnownOk;
+   }
+ 
+   if( db->nSchemaLock==0 ){
+@@ -103706,17 +106467,22 @@
+ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
+   int i;
+   sqlite3BtreeEnterAll(db);
+-  assert( db->nSchemaLock==0 );
+   for(i=0; i<db->nDb; i++){
+     Db *pDb = &db->aDb[i];
+     if( pDb->pSchema ){
+-      sqlite3SchemaClear(pDb->pSchema);
++      if( db->nSchemaLock==0 ){
++        sqlite3SchemaClear(pDb->pSchema);
++      }else{
++        DbSetProperty(db, i, DB_ResetWanted);
++      }
+     }
+   }
+-  db->mDbFlags &= ~DBFLAG_SchemaChange;
++  db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
+   sqlite3VtabUnlockList(db);
+   sqlite3BtreeLeaveAll(db);
+-  sqlite3CollapseDatabaseArray(db);
++  if( db->nSchemaLock==0 ){
++    sqlite3CollapseDatabaseArray(db);
++  }
+ }
+ 
+ /*
+@@ -103785,7 +106551,7 @@
+       assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+       assert( pOld==pIndex || pOld==0 );
+     }
+-    freeIndex(db, pIndex);
++    sqlite3FreeIndex(db, pIndex);
+   }
+ 
+   /* Delete any foreign keys attached to this table. */
+@@ -103793,6 +106559,12 @@
+ 
+   /* Delete the Table structure itself.
+   */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  if( pTable->pColHash ){
++    sqlite3HashClear(pTable->pColHash);
++    sqlite3_free(pTable->pColHash);
++  }
++#endif
+   sqlite3DeleteColumnNames(db, pTable);
+   sqlite3DbFree(db, pTable->zName);
+   sqlite3DbFree(db, pTable->zColAff);
+@@ -103943,7 +106715,7 @@
+       return -1;
+     }
+   }else{
+-    assert( db->init.iDb==0 || db->init.busy
++    assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT
+              || (db->mDbFlags & DBFLAG_Vacuum)!=0);
+     iDb = db->init.iDb;
+     *pUnqual = pName1;
+@@ -103952,6 +106724,20 @@
+ }
+ 
+ /*
++** True if PRAGMA writable_schema is ON
++*/
++SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               SQLITE_WriteSchema );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               SQLITE_Defensive );
++  testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
++               (SQLITE_WriteSchema|SQLITE_Defensive) );
++  return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
++}
++
++/*
+ ** This routine is used to check if the UTF-8 string zName is a legal
+ ** unqualified name for a new schema object (table, index, view or
+ ** trigger). All names are legal except those that begin with the string
+@@ -103960,7 +106746,7 @@
+ */
+ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
+   if( !pParse->db->init.busy && pParse->nested==0 
+-          && (pParse->db->flags & SQLITE_WriteSchema)==0
++          && sqlite3WritableSchema(pParse->db)==0
+           && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
+     sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
+     return SQLITE_ERROR;
+@@ -104038,6 +106824,9 @@
+     }
+     if( !OMIT_TEMPDB && isTemp ) iDb = 1;
+     zName = sqlite3NameFromToken(db, pName);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, (void*)zName, pName);
++    }
+   }
+   pParse->sNameToken = *pName;
+   if( zName==0 ) return;
+@@ -104073,7 +106862,7 @@
+   ** and types will be used, so there is no need to test for namespace
+   ** collisions.
+   */
+-  if( !IN_DECLARE_VTAB ){
++  if( !IN_SPECIAL_PARSE ){
+     char *zDb = db->aDb[iDb].zDbSName;
+     if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
+       goto begin_table_error;
+@@ -104232,6 +107021,7 @@
+   }
+   z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
+   if( z==0 ) return;
++  if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName);
+   memcpy(z, pName->z, pName->n);
+   z[pName->n] = 0;
+   sqlite3Dequote(z);
+@@ -104258,15 +107048,20 @@
+  
+   if( pType->n==0 ){
+     /* If there is no type specified, columns have the default affinity
+-    ** 'BLOB'. */
++    ** 'BLOB' with a default size of 4 bytes. */
+     pCol->affinity = SQLITE_AFF_BLOB;
+     pCol->szEst = 1;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( 4>=sqlite3GlobalConfig.szSorterRef ){
++      pCol->colFlags |= COLFLAG_SORTERREF;
++    }
++#endif
+   }else{
+     zType = z + sqlite3Strlen30(z) + 1;
+     memcpy(zType, pType->z, pType->n);
+     zType[pType->n] = 0;
+     sqlite3Dequote(zType);
+-    pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
++    pCol->affinity = sqlite3AffinityType(zType, pCol);
+     pCol->colFlags |= COLFLAG_HASTYPE;
+   }
+   p->nCol++;
+@@ -104326,7 +107121,7 @@
+ ** If none of the substrings in the above table are found,
+ ** SQLITE_AFF_NUMERIC is returned.
+ */
+-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
++SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){
+   u32 h = 0;
+   char aff = SQLITE_AFF_NUMERIC;
+   const char *zChar = 0;
+@@ -104363,27 +107158,32 @@
+     }
+   }
+ 
+-  /* If pszEst is not NULL, store an estimate of the field size.  The
++  /* If pCol is not NULL, store an estimate of the field size.  The
+   ** estimate is scaled so that the size of an integer is 1.  */
+-  if( pszEst ){
+-    *pszEst = 1;   /* default size is approx 4 bytes */
++  if( pCol ){
++    int v = 0;   /* default size is approx 4 bytes */
+     if( aff<SQLITE_AFF_NUMERIC ){
+       if( zChar ){
+         while( zChar[0] ){
+           if( sqlite3Isdigit(zChar[0]) ){
+-            int v = 0;
++            /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+             sqlite3GetInt32(zChar, &v);
+-            v = v/4 + 1;
+-            if( v>255 ) v = 255;
+-            *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+             break;
+           }
+           zChar++;
+         }
+       }else{
+-        *pszEst = 5;   /* BLOB, TEXT, CLOB -> r=5  (approx 20 bytes)*/
++        v = 16;   /* BLOB, TEXT, CLOB -> r=5  (approx 20 bytes)*/
+       }
+     }
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( v>=sqlite3GlobalConfig.szSorterRef ){
++      pCol->colFlags |= COLFLAG_SORTERREF;
++    }
++#endif
++    v = v/4 + 1;
++    if( v>255 ) v = 255;
++    pCol->szEst = v;
+   }
+   return aff;
+ }
+@@ -104428,6 +107228,9 @@
+       sqlite3DbFree(db, x.u.zToken);
+     }
+   }
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameExprUnmap(pParse, pExpr);
++  }
+   sqlite3ExprDelete(db, pExpr);
+ }
+ 
+@@ -104519,6 +107322,9 @@
+    && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0
+    && sortOrder!=SQLITE_SO_DESC
+   ){
++    if( IN_RENAME_OBJECT && pList ){
++      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
++    }
+     pTab->iPKey = iCol;
+     pTab->keyConf = (u8)onError;
+     assert( autoInc==0 || autoInc==1 );
+@@ -104844,6 +107650,31 @@
+   return 0;
+ }
+ 
++/* Recompute the colNotIdxed field of the Index.
++**
++** colNotIdxed is a bitmask that has a 0 bit representing each indexed
++** columns that are within the first 63 columns of the table.  The
++** high-order bit of colNotIdxed is always 1.  All unindexed columns
++** of the table have a 1.
++**
++** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
++** to determine if the index is covering index.
++*/
++static void recomputeColumnsNotIndexed(Index *pIdx){
++  Bitmask m = 0;
++  int j;
++  for(j=pIdx->nColumn-1; j>=0; j--){
++    int x = pIdx->aiColumn[j];
++    if( x>=0 ){
++      testcase( x==BMS-1 );
++      testcase( x==BMS-2 );
++      if( x<BMS-1 ) m |= MASKBIT(x);
++    }
++  }
++  pIdx->colNotIdxed = ~m;
++  assert( (pIdx->colNotIdxed>>63)==1 );
++}
++
+ /*
+ ** This routine runs at the end of parsing a CREATE TABLE statement that
+ ** has a WITHOUT ROWID clause.  The job of this routine is to convert both
+@@ -104886,10 +107717,6 @@
+     }
+   }
+ 
+-  /* The remaining transformations only apply to b-tree tables, not to
+-  ** virtual tables */
+-  if( IN_DECLARE_VTAB ) return;
+-
+   /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
+   ** into BTREE_BLOBKEY.
+   */
+@@ -104912,7 +107739,7 @@
+     assert( pParse->pNewTable==pTab );
+     sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
+                        SQLITE_IDXTYPE_PRIMARYKEY);
+-    if( db->mallocFailed ) return;
++    if( db->mallocFailed || pParse->nErr ) return;
+     pPk = sqlite3PrimaryKeyIndex(pTab);
+     pTab->iPKey = -1;
+   }else{
+@@ -104992,9 +107819,40 @@
+   }else{
+     pPk->nColumn = pTab->nCol;
+   }
++  recomputeColumnsNotIndexed(pPk);
+ }
+ 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /*
++** Return true if zName is a shadow table name in the current database
++** connection.
++**
++** zName is temporarily modified while this routine is running, but is
++** restored to its original value prior to this routine returning.
++*/
++static int isShadowTableName(sqlite3 *db, char *zName){
++  char *zTail;                  /* Pointer to the last "_" in zName */
++  Table *pTab;                  /* Table that zName is a shadow of */
++  Module *pMod;                 /* Module for the virtual table */
++
++  zTail = strrchr(zName, '_');
++  if( zTail==0 ) return 0;
++  *zTail = 0;
++  pTab = sqlite3FindTable(db, zName, 0);
++  *zTail = '_';
++  if( pTab==0 ) return 0;
++  if( !IsVirtual(pTab) ) return 0;
++  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
++  if( pMod==0 ) return 0;
++  if( pMod->pModule->iVersion<3 ) return 0;
++  if( pMod->pModule->xShadowName==0 ) return 0;
++  return pMod->pModule->xShadowName(zTail+1);
++}
++#else
++# define isShadowTableName(x,y) 0
++#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
++
++/*
+ ** This routine is called to report the final ")" that terminates
+ ** a CREATE TABLE statement.
+ **
+@@ -105033,6 +107891,10 @@
+   p = pParse->pNewTable;
+   if( p==0 ) return;
+ 
++  if( pSelect==0 && isShadowTableName(db, p->zName) ){
++    p->tabFlags |= TF_Shadow;
++  }
++
+   /* If the db->init.busy is 1 it means we are reading the SQL off the
+   ** "sqlite_master" or "sqlite_temp_master" table on the disk.
+   ** So do not write to the disk again.  Extract the root page number
+@@ -105295,7 +108157,12 @@
+   ** allocated rather than point to the input string - which means that
+   ** they will persist after the current sqlite3_exec() call returns.
+   */
+-  p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++  if( IN_RENAME_OBJECT ){
++    p->pSelect = pSelect;
++    pSelect = 0;
++  }else{
++    p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++  }
+   p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
+   if( db->mallocFailed ) goto create_view_fail;
+ 
+@@ -105320,6 +108187,9 @@
+ 
+ create_view_fail:
+   sqlite3SelectDelete(db, pSelect);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameExprlistUnmap(pParse, pCNames);
++  }
+   sqlite3ExprListDelete(db, pCNames);
+   return;
+ }
+@@ -105393,6 +108263,10 @@
+   assert( pTable->pSelect );
+   pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
+   if( pSel ){
++#ifndef SQLITE_OMIT_ALTERTABLE
++    u8 eParseMode = pParse->eParseMode;
++    pParse->eParseMode = PARSE_MODE_NORMAL;
++#endif
+     n = pParse->nTab;
+     sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
+     pTable->nCol = -1;
+@@ -105438,10 +108312,18 @@
+     sqlite3DeleteTable(db, pSelTab);
+     sqlite3SelectDelete(db, pSel);
+     db->lookaside.bDisable--;
++#ifndef SQLITE_OMIT_ALTERTABLE
++    pParse->eParseMode = eParseMode;
++#endif
+   } else {
+     nErr++;
+   }
+   pTable->pSchema->schemaFlags |= DB_UnresetViews;
++  if( db->mallocFailed ){
++    sqlite3DeleteColumnNames(db, pTable);
++    pTable->aCol = 0;
++    pTable->nCol = 0;
++  }
+ #endif /* SQLITE_OMIT_VIEW */
+   return nErr;  
+ }
+@@ -105520,7 +108402,7 @@
+ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
+   Vdbe *v = sqlite3GetVdbe(pParse);
+   int r1 = sqlite3GetTempReg(pParse);
+-  assert( iTable>1 );
++  if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
+   sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
+   sqlite3MayAbort(pParse);
+ #ifndef SQLITE_OMIT_AUTOVACUUM
+@@ -105780,8 +108662,10 @@
+   v = sqlite3GetVdbe(pParse);
+   if( v ){
+     sqlite3BeginWriteOperation(pParse, 1, iDb);
+-    sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
+-    sqlite3FkDropTable(pParse, pName, pTab);
++    if( !isView ){
++      sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
++      sqlite3FkDropTable(pParse, pName, pTab);
++    }
+     sqlite3CodeDropTable(pParse, pTab, iDb, isView);
+   }
+ 
+@@ -105856,6 +108740,9 @@
+   pFKey->pNextFrom = p->pFKey;
+   z = (char*)&pFKey->aCol[nCol];
+   pFKey->zTo = z;
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)z, pTo);
++  }
+   memcpy(z, pTo->z, pTo->n);
+   z[pTo->n] = 0;
+   sqlite3Dequote(z);
+@@ -105878,6 +108765,9 @@
+           pFromCol->a[i].zName);
+         goto fk_end;
+       }
++      if( IN_RENAME_OBJECT ){
++        sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName);
++      }
+     }
+   }
+   if( pToCol ){
+@@ -105884,6 +108774,9 @@
+     for(i=0; i<nCol; i++){
+       int n = sqlite3Strlen30(pToCol->a[i].zName);
+       pFKey->aCol[i].zCol = z;
++      if( IN_RENAME_OBJECT ){
++        sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName);
++      }
+       memcpy(z, pToCol->a[i].zName, n);
+       z[n] = 0;
+       z += n+1;
+@@ -105992,6 +108885,7 @@
+   sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
+   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
+   regRecord = sqlite3GetTempReg(pParse);
++  sqlite3MultiWrite(pParse);
+ 
+   sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
+   sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
+@@ -106005,12 +108899,13 @@
+ 
+   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
+   if( IsUniqueIndex(pIndex) ){
+-    int j2 = sqlite3VdbeCurrentAddr(v) + 3;
+-    sqlite3VdbeGoto(v, j2);
++    int j2 = sqlite3VdbeGoto(v, 1);
+     addr2 = sqlite3VdbeCurrentAddr(v);
++    sqlite3VdbeVerifyAbortable(v, OE_Abort);
+     sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+                          pIndex->nKeyCol); VdbeCoverage(v);
+     sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
++    sqlite3VdbeJumpHere(v, j2);
+   }else{
+     addr2 = sqlite3VdbeCurrentAddr(v);
+   }
+@@ -106173,7 +109068,11 @@
+ #if SQLITE_USER_AUTHENTICATION
+        && sqlite3UserAuthTable(pTab->zName)==0
+ #endif
+-       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
++#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
++       && sqlite3StrICmp(&pTab->zName[7],"master")!=0
++#endif
++       && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0
++ ){
+     sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
+     goto exit_create_index;
+   }
+@@ -106210,21 +109109,23 @@
+     if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
+       goto exit_create_index;
+     }
+-    if( !db->init.busy ){
+-      if( sqlite3FindTable(db, zName, 0)!=0 ){
+-        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
++    if( !IN_RENAME_OBJECT ){
++      if( !db->init.busy ){
++        if( sqlite3FindTable(db, zName, 0)!=0 ){
++          sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
++          goto exit_create_index;
++        }
++      }
++      if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
++        if( !ifNotExist ){
++          sqlite3ErrorMsg(pParse, "index %s already exists", zName);
++        }else{
++          assert( !db->init.busy );
++          sqlite3CodeVerifySchema(pParse, iDb);
++        }
+         goto exit_create_index;
+       }
+     }
+-    if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
+-      if( !ifNotExist ){
+-        sqlite3ErrorMsg(pParse, "index %s already exists", zName);
+-      }else{
+-        assert( !db->init.busy );
+-        sqlite3CodeVerifySchema(pParse, iDb);
+-      }
+-      goto exit_create_index;
+-    }
+   }else{
+     int n;
+     Index *pLoop;
+@@ -106239,13 +109140,13 @@
+     ** The following statement converts "sqlite3_autoindex..." into
+     ** "sqlite3_butoindex..." in order to make the names distinct.
+     ** The "vtab_err.test" test demonstrates the need of this statement. */
+-    if( IN_DECLARE_VTAB ) zName[7]++;
++    if( IN_SPECIAL_PARSE ) zName[7]++;
+   }
+ 
+   /* Check for authorization to create an index.
+   */
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  {
++  if( !IN_RENAME_OBJECT ){
+     const char *zDb = pDb->zDbSName;
+     if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
+       goto exit_create_index;
+@@ -106332,7 +109233,12 @@
+   ** TODO: Issue a warning if the table primary key is used as part of the
+   ** index key.
+   */
+-  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
++  pListItem = pList->a;
++  if( IN_RENAME_OBJECT ){
++    pIndex->aColExpr = pList;
++    pList = 0;
++  }
++  for(i=0; i<pIndex->nKeyCol; i++, pListItem++){
+     Expr *pCExpr;                  /* The i-th index expression */
+     int requestedSortOrder;        /* ASC or DESC on the i-th expression */
+     const char *zColl;             /* Collation sequence name */
+@@ -106348,12 +109254,8 @@
+         goto exit_create_index;
+       }
+       if( pIndex->aColExpr==0 ){
+-        ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
+-        pIndex->aColExpr = pCopy;
+-        if( !db->mallocFailed ){
+-          assert( pCopy!=0 );
+-          pListItem = &pCopy->a[i];
+-        }
++        pIndex->aColExpr = pList;
++        pList = 0;
+       }
+       j = XN_EXPR;
+       pIndex->aiColumn[i] = XN_EXPR;
+@@ -106419,6 +109321,7 @@
+   ** it as a covering index */
+   assert( HasRowid(pTab) 
+       || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
++  recomputeColumnsNotIndexed(pIndex);
+   if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+     pIndex->isCovering = 1;
+     for(j=0; j<pTab->nCol; j++){
+@@ -106491,98 +109394,101 @@
+     }
+   }
+ 
+-  /* Link the new Index structure to its table and to the other
+-  ** in-memory database structures. 
+-  */
+-  assert( pParse->nErr==0 );
+-  if( db->init.busy ){
+-    Index *p;
+-    assert( !IN_DECLARE_VTAB );
+-    assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+-    p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
+-                          pIndex->zName, pIndex);
+-    if( p ){
+-      assert( p==pIndex );  /* Malloc must have failed */
+-      sqlite3OomFault(db);
+-      goto exit_create_index;
++  if( !IN_RENAME_OBJECT ){
++
++    /* Link the new Index structure to its table and to the other
++    ** in-memory database structures. 
++    */
++    assert( pParse->nErr==0 );
++    if( db->init.busy ){
++      Index *p;
++      assert( !IN_SPECIAL_PARSE );
++      assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
++      p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
++          pIndex->zName, pIndex);
++      if( p ){
++        assert( p==pIndex );  /* Malloc must have failed */
++        sqlite3OomFault(db);
++        goto exit_create_index;
++      }
++      db->mDbFlags |= DBFLAG_SchemaChange;
++      if( pTblName!=0 ){
++        pIndex->tnum = db->init.newTnum;
++      }
+     }
+-    db->mDbFlags |= DBFLAG_SchemaChange;
+-    if( pTblName!=0 ){
+-      pIndex->tnum = db->init.newTnum;
+-    }
+-  }
+ 
+-  /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+-  ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+-  ** emit code to allocate the index rootpage on disk and make an entry for
+-  ** the index in the sqlite_master table and populate the index with
+-  ** content.  But, do not do this if we are simply reading the sqlite_master
+-  ** table to parse the schema, or if this index is the PRIMARY KEY index
+-  ** of a WITHOUT ROWID table.
+-  **
+-  ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+-  ** or UNIQUE index in a CREATE TABLE statement.  Since the table
+-  ** has just been created, it contains no data and the index initialization
+-  ** step can be skipped.
+-  */
+-  else if( HasRowid(pTab) || pTblName!=0 ){
+-    Vdbe *v;
+-    char *zStmt;
+-    int iMem = ++pParse->nMem;
++    /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
++    ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
++    ** emit code to allocate the index rootpage on disk and make an entry for
++    ** the index in the sqlite_master table and populate the index with
++    ** content.  But, do not do this if we are simply reading the sqlite_master
++    ** table to parse the schema, or if this index is the PRIMARY KEY index
++    ** of a WITHOUT ROWID table.
++    **
++    ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
++    ** or UNIQUE index in a CREATE TABLE statement.  Since the table
++    ** has just been created, it contains no data and the index initialization
++    ** step can be skipped.
++    */
++    else if( HasRowid(pTab) || pTblName!=0 ){
++      Vdbe *v;
++      char *zStmt;
++      int iMem = ++pParse->nMem;
+ 
+-    v = sqlite3GetVdbe(pParse);
+-    if( v==0 ) goto exit_create_index;
++      v = sqlite3GetVdbe(pParse);
++      if( v==0 ) goto exit_create_index;
+ 
+-    sqlite3BeginWriteOperation(pParse, 1, iDb);
++      sqlite3BeginWriteOperation(pParse, 1, iDb);
+ 
+-    /* Create the rootpage for the index using CreateIndex. But before
+-    ** doing so, code a Noop instruction and store its address in 
+-    ** Index.tnum. This is required in case this index is actually a 
+-    ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
+-    ** that case the convertToWithoutRowidTable() routine will replace
+-    ** the Noop with a Goto to jump over the VDBE code generated below. */
+-    pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
+-    sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
++      /* Create the rootpage for the index using CreateIndex. But before
++      ** doing so, code a Noop instruction and store its address in 
++      ** Index.tnum. This is required in case this index is actually a 
++      ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In 
++      ** that case the convertToWithoutRowidTable() routine will replace
++      ** the Noop with a Goto to jump over the VDBE code generated below. */
++      pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
++      sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
+ 
+-    /* Gather the complete text of the CREATE INDEX statement into
+-    ** the zStmt variable
+-    */
+-    if( pStart ){
+-      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+-      if( pName->z[n-1]==';' ) n--;
+-      /* A named index with an explicit CREATE INDEX statement */
+-      zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
+-        onError==OE_None ? "" : " UNIQUE", n, pName->z);
+-    }else{
+-      /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
+-      /* zStmt = sqlite3MPrintf(""); */
+-      zStmt = 0;
+-    }
++      /* Gather the complete text of the CREATE INDEX statement into
++      ** the zStmt variable
++      */
++      if( pStart ){
++        int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
++        if( pName->z[n-1]==';' ) n--;
++        /* A named index with an explicit CREATE INDEX statement */
++        zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
++            onError==OE_None ? "" : " UNIQUE", n, pName->z);
++      }else{
++        /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
++        /* zStmt = sqlite3MPrintf(""); */
++        zStmt = 0;
++      }
+ 
+-    /* Add an entry in sqlite_master for this index
+-    */
+-    sqlite3NestedParse(pParse, 
+-        "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
+-        db->aDb[iDb].zDbSName, MASTER_NAME,
+-        pIndex->zName,
+-        pTab->zName,
+-        iMem,
+-        zStmt
+-    );
+-    sqlite3DbFree(db, zStmt);
++      /* Add an entry in sqlite_master for this index
++      */
++      sqlite3NestedParse(pParse, 
++          "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
++          db->aDb[iDb].zDbSName, MASTER_NAME,
++          pIndex->zName,
++          pTab->zName,
++          iMem,
++          zStmt
++          );
++      sqlite3DbFree(db, zStmt);
+ 
+-    /* Fill the index with data and reparse the schema. Code an OP_Expire
+-    ** to invalidate all pre-compiled statements.
+-    */
+-    if( pTblName ){
+-      sqlite3RefillIndex(pParse, pIndex, iMem);
+-      sqlite3ChangeCookie(pParse, iDb);
+-      sqlite3VdbeAddParseSchemaOp(v, iDb,
+-         sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
+-      sqlite3VdbeAddOp0(v, OP_Expire);
++      /* Fill the index with data and reparse the schema. Code an OP_Expire
++      ** to invalidate all pre-compiled statements.
++      */
++      if( pTblName ){
++        sqlite3RefillIndex(pParse, pIndex, iMem);
++        sqlite3ChangeCookie(pParse, iDb);
++        sqlite3VdbeAddParseSchemaOp(v, iDb,
++            sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
++        sqlite3VdbeAddOp2(v, OP_Expire, 0, 1);
++      }
++
++      sqlite3VdbeJumpHere(v, pIndex->tnum);
+     }
+-
+-    sqlite3VdbeJumpHere(v, pIndex->tnum);
+   }
+ 
+   /* When adding an index to the list of indices for a table, make
+@@ -106606,10 +109512,15 @@
+     }
+     pIndex = 0;
+   }
++  else if( IN_RENAME_OBJECT ){
++    assert( pParse->pNewIndex==0 );
++    pParse->pNewIndex = pIndex;
++    pIndex = 0;
++  }
+ 
+   /* Clean up before exiting */
+ exit_create_index:
+-  if( pIndex ) freeIndex(db, pIndex);
++  if( pIndex ) sqlite3FreeIndex(db, pIndex);
+   sqlite3ExprDelete(db, pPIWhere);
+   sqlite3ExprListDelete(db, pList);
+   sqlite3SrcListDelete(db, pTblName);
+@@ -106778,7 +109689,8 @@
+ **
+ ** A new IdList is returned, or NULL if malloc() fails.
+ */
+-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
++SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){
++  sqlite3 *db = pParse->db;
+   int i;
+   if( pList==0 ){
+     pList = sqlite3DbMallocZero(db, sizeof(IdList) );
+@@ -106796,6 +109708,9 @@
+     return 0;
+   }
+   pList->a[i].zName = sqlite3NameFromToken(db, pToken);
++  if( IN_RENAME_OBJECT && pList->a[i].zName ){
++    sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
++  }
+   return pList;
+ }
+ 
+@@ -107042,6 +109957,12 @@
+   }
+   assert( p->nSrc>0 );
+   pItem = &p->a[p->nSrc-1];
++  assert( (pTable==0)==(pDatabase==0) );
++  assert( pItem->zName==0 || pDatabase!=0 );
++  if( IN_RENAME_OBJECT && pItem->zName ){
++    Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable;
++    sqlite3RenameTokenMap(pParse, pItem->zName, pToken);
++  }
+   assert( pAlias!=0 );
+   if( pAlias->n ){
+     pItem->zAlias = sqlite3NameFromToken(db, pAlias);
+@@ -107352,16 +110273,16 @@
+ 
+   sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+   if( pIdx->aColExpr ){
+-    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
++    sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
+   }else{
+     for(j=0; j<pIdx->nKeyCol; j++){
+       char *zCol;
+       assert( pIdx->aiColumn[j]>=0 );
+       zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+-      if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+-      sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
+-      sqlite3StrAccumAppend(&errMsg, ".", 1);
+-      sqlite3StrAccumAppendAll(&errMsg, zCol);
++      if( j ) sqlite3_str_append(&errMsg, ", ", 2);
++      sqlite3_str_appendall(&errMsg, pTab->zName);
++      sqlite3_str_append(&errMsg, ".", 1);
++      sqlite3_str_appendall(&errMsg, zCol);
+     }
+   }
+   zErr = sqlite3StrAccumFinish(&errMsg);
+@@ -107936,6 +110857,21 @@
+   }
+   return 0;
+ }
++#ifdef SQLITE_ENABLE_NORMALIZE
++SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
++  int h,               /* Hash of the name */
++  const char *zFunc,   /* Name of function */
++  int nFunc            /* Length of the name */
++){
++  FuncDef *p;
++  for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
++    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
++      return p;
++    }
++  }
++  return 0;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
+ 
+ /*
+ ** Insert a new FuncDef into a FuncDefHash hash table.
+@@ -107949,7 +110885,7 @@
+     FuncDef *pOther;
+     const char *zName = aDef[i].zName;
+     int nName = sqlite3Strlen30(zName);
+-    int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
++    int h = SQLITE_FUNC_HASH(zName[0], nName);
+     assert( zName[0]>='a' && zName[0]<='z' );
+     pOther = functionSearch(h, zName);
+     if( pOther ){
+@@ -108028,7 +110964,7 @@
+   */ 
+   if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
+     bestScore = 0;
+-    h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
++    h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
+     p = functionSearch(h, zName);
+     while( p ){
+       int score = matchQuality(p, nArg, enc);
+@@ -108047,10 +110983,12 @@
+   if( createFlag && bestScore<FUNC_PERFECT_MATCH && 
+       (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
+     FuncDef *pOther;
++    u8 *z;
+     pBest->zName = (const char*)&pBest[1];
+     pBest->nArg = (u16)nArg;
+     pBest->funcFlags = enc;
+     memcpy((char*)&pBest[1], zName, nName+1);
++    for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z];
+     pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+     if( pOther==pBest ){
+       sqlite3DbFree(db, pBest);
+@@ -108174,6 +111112,39 @@
+   return pTab;
+ }
+ 
++/* Return true if table pTab is read-only.
++**
++** A table is read-only if any of the following are true:
++**
++**   1) It is a virtual table and no implementation of the xUpdate method
++**      has been provided
++**
++**   2) It is a system table (i.e. sqlite_master), this call is not
++**      part of a nested parse and writable_schema pragma has not 
++**      been specified
++**
++**   3) The table is a shadow table, the database connection is in
++**      defensive mode, and the current sqlite3_prepare()
++**      is for a top-level SQL statement.
++*/
++static int tabIsReadOnly(Parse *pParse, Table *pTab){
++  sqlite3 *db;
++  if( IsVirtual(pTab) ){
++    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
++  }
++  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
++  db = pParse->db;
++  if( (pTab->tabFlags & TF_Readonly)!=0 ){
++    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
++  }
++  assert( pTab->tabFlags & TF_Shadow );
++  return (db->flags & SQLITE_Defensive)!=0 
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++          && db->pVtabCtx==0
++#endif
++          && db->nVdbeExec==0;
++}
++
+ /*
+ ** Check to make sure the given table is writable.  If it is not
+ ** writable, generate an error message and return 1.  If it is
+@@ -108180,26 +111151,10 @@
+ ** writable return 0;
+ */
+ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+-  /* A table is not writable under the following circumstances:
+-  **
+-  **   1) It is a virtual table and no implementation of the xUpdate method
+-  **      has been provided, or
+-  **   2) It is a system table (i.e. sqlite_master), this call is not
+-  **      part of a nested parse and writable_schema pragma has not 
+-  **      been specified.
+-  **
+-  ** In either case leave an error message in pParse and return non-zero.
+-  */
+-  if( ( IsVirtual(pTab) 
+-     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
+-   || ( (pTab->tabFlags & TF_Readonly)!=0
+-     && (pParse->db->flags & SQLITE_WriteSchema)==0
+-     && pParse->nested==0 )
+-  ){
++  if( tabIsReadOnly(pParse, pTab) ){
+     sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
+     return 1;
+   }
+-
+ #ifndef SQLITE_OMIT_VIEW
+   if( !viewOk && pTab->pSelect ){
+     sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
+@@ -108368,7 +111323,7 @@
+   AuthContext sContext;  /* Authorization context */
+   NameContext sNC;       /* Name context to resolve expressions in */
+   int iDb;               /* Database number */
+-  int memCnt = -1;       /* Memory cell used for change counting */
++  int memCnt = 0;        /* Memory cell used for change counting */
+   int rcauth;            /* Value returned by authorization callback */
+   int eOnePass;          /* ONEPASS_OFF or _SINGLE or _MULTI */
+   int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
+@@ -108473,7 +111428,7 @@
+     goto delete_from_cleanup;
+   }
+   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+-  sqlite3BeginWriteOperation(pParse, 1, iDb);
++  sqlite3BeginWriteOperation(pParse, bComplex, iDb);
+ 
+   /* If we are trying to delete from a view, realize that view into
+   ** an ephemeral table.
+@@ -108501,7 +111456,10 @@
+   /* Initialize the counter of the number of rows deleted, if
+   ** we are counting rows.
+   */
+-  if( db->flags & SQLITE_CountRows ){
++  if( (db->flags & SQLITE_CountRows)!=0
++   && !pParse->nested
++   && !pParse->pTriggerTab
++  ){
+     memCnt = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
+   }
+@@ -108529,7 +111487,7 @@
+     assert( !isView );
+     sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+     if( HasRowid(pTab) ){
+-      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
++      sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1,
+                         pTab->zName, P4_STATIC);
+     }
+     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+@@ -108574,9 +111532,10 @@
+     eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+     assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
+     assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
++    if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse);
+   
+     /* Keep track of the number of rows to be deleted */
+-    if( db->flags & SQLITE_CountRows ){
++    if( memCnt ){
+       sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
+     }
+   
+@@ -108589,9 +111548,8 @@
+       }
+       iKey = iPk;
+     }else{
+-      iKey = pParse->nMem + 1;
+-      iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
+-      if( iKey>pParse->nMem ) pParse->nMem = iKey;
++      iKey = ++pParse->nMem;
++      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey);
+     }
+   
+     if( eOnePass!=ONEPASS_OFF ){
+@@ -108679,13 +111637,16 @@
+     if( IsVirtual(pTab) ){
+       const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
+       sqlite3VtabMakeWritable(pParse, pTab);
+-      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
+-      sqlite3VdbeChangeP5(v, OE_Abort);
+       assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
+       sqlite3MayAbort(pParse);
+-      if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
+-        pParse->isMultiWrite = 0;
++      if( eOnePass==ONEPASS_SINGLE ){
++        sqlite3VdbeAddOp1(v, OP_Close, iTabCur);
++        if( sqlite3IsToplevel(pParse) ){
++          pParse->isMultiWrite = 0;
++        }
+       }
++      sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
++      sqlite3VdbeChangeP5(v, OE_Abort);
+     }else
+ #endif
+     {
+@@ -108719,7 +111680,7 @@
+   ** generating code because of a call to sqlite3NestedParse(), do not
+   ** invoke the callback function.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
++  if( memCnt ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
+@@ -109021,7 +111982,6 @@
+     if( pIdx->pPartIdxWhere ){
+       *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+       pParse->iSelfTab = iDataCur + 1;
+-      sqlite3ExprCachePush(pParse);
+       sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
+                             SQLITE_JUMPIFNULL);
+       pParse->iSelfTab = 0;
+@@ -109068,7 +112028,6 @@
+ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
+   if( iLabel ){
+     sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel);
+-    sqlite3ExprCachePop(pParse);
+   }
+ }
+ 
+@@ -109327,7 +112286,7 @@
+     x.apArg = argv+1;
+     sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
+     str.printfFlags = SQLITE_PRINTF_SQLFUNC;
+-    sqlite3XPrintf(&str, zFormat, &x);
++    sqlite3_str_appendf(&str, zFormat, &x);
+     n = str.nChar;
+     sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+                         SQLITE_DYNAMIC);
+@@ -110581,7 +113540,7 @@
+       i64 v = sqlite3_value_int64(argv[0]);
+       p->rSum += v;
+       if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
+-        p->overflow = 1;
++        p->approx = p->overflow = 1;
+       }
+     }else{
+       p->rSum += sqlite3_value_double(argv[0]);
+@@ -110589,6 +113548,32 @@
+     }
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){
++  SumCtx *p;
++  int type;
++  assert( argc==1 );
++  UNUSED_PARAMETER(argc);
++  p = sqlite3_aggregate_context(context, sizeof(*p));
++  type = sqlite3_value_numeric_type(argv[0]);
++  /* p is always non-NULL because sumStep() will have been called first
++  ** to initialize it */
++  if( ALWAYS(p) && type!=SQLITE_NULL ){
++    assert( p->cnt>0 );
++    p->cnt--;
++    assert( type==SQLITE_INTEGER || p->approx );
++    if( type==SQLITE_INTEGER && p->approx==0 ){
++      i64 v = sqlite3_value_int64(argv[0]);
++      p->rSum -= v;
++      p->iSum -= v;
++    }else{
++      p->rSum -= sqlite3_value_double(argv[0]);
++    }
++  }
++}
++#else
++# define sumInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ static void sumFinalize(sqlite3_context *context){
+   SumCtx *p;
+   p = sqlite3_aggregate_context(context, 0);
+@@ -110623,6 +113608,9 @@
+ typedef struct CountCtx CountCtx;
+ struct CountCtx {
+   i64 n;
++#ifdef SQLITE_DEBUG
++  int bInverse;                   /* True if xInverse() ever called */
++#endif
+ };
+ 
+ /*
+@@ -110640,7 +113628,7 @@
+   ** sure it still operates correctly, verify that its count agrees with our 
+   ** internal count when using count(*) and when the total count can be
+   ** expressed as a 32-bit integer. */
+-  assert( argc==1 || p==0 || p->n>0x7fffffff
++  assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse
+           || p->n==sqlite3_aggregate_count(context) );
+ #endif
+ }   
+@@ -110649,6 +113637,21 @@
+   p = sqlite3_aggregate_context(context, 0);
+   sqlite3_result_int64(context, p ? p->n : 0);
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){
++  CountCtx *p;
++  p = sqlite3_aggregate_context(ctx, sizeof(*p));
++  /* p is always non-NULL since countStep() will have been called first */
++  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){
++    p->n--;
++#ifdef SQLITE_DEBUG
++    p->bInverse = 1;
++#endif
++  }
++}   
++#else
++# define countInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ 
+ /*
+ ** Routines to implement min() and max() aggregate functions.
+@@ -110665,7 +113668,7 @@
+   pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
+   if( !pBest ) return;
+ 
+-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
++  if( sqlite3_value_type(pArg)==SQLITE_NULL ){
+     if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
+   }else if( pBest->flags ){
+     int max;
+@@ -110691,7 +113694,7 @@
+     sqlite3VdbeMemCopy(pBest, pArg);
+   }
+ }
+-static void minMaxFinalize(sqlite3_context *context){
++static void minMaxValueFinalize(sqlite3_context *context, int bValue){
+   sqlite3_value *pRes;
+   pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
+   if( pRes ){
+@@ -110698,9 +113701,19 @@
+     if( pRes->flags ){
+       sqlite3_result_value(context, pRes);
+     }
+-    sqlite3VdbeMemRelease(pRes);
++    if( bValue==0 ) sqlite3VdbeMemRelease(pRes);
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void minMaxValue(sqlite3_context *context){
++  minMaxValueFinalize(context, 1);
++}
++#else
++# define minMaxValue 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++static void minMaxFinalize(sqlite3_context *context){
++  minMaxValueFinalize(context, 0);
++}
+ 
+ /*
+ ** group_concat(EXPR, ?SEPARATOR?)
+@@ -110730,20 +113743,52 @@
+         zSep = ",";
+         nSep = 1;
+       }
+-      if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
++      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
+     }
+     zVal = (char*)sqlite3_value_text(argv[0]);
+     nVal = sqlite3_value_bytes(argv[0]);
+-    if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
++    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void groupConcatInverse(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  int n;
++  StrAccum *pAccum;
++  assert( argc==1 || argc==2 );
++  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
++  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
++  /* pAccum is always non-NULL since groupConcatStep() will have always
++  ** run frist to initialize it */
++  if( ALWAYS(pAccum) ){
++    n = sqlite3_value_bytes(argv[0]);
++    if( argc==2 ){
++      n += sqlite3_value_bytes(argv[1]);
++    }else{
++      n++;
++    }
++    if( n>=(int)pAccum->nChar ){
++      pAccum->nChar = 0;
++    }else{
++      pAccum->nChar -= n;
++      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
++    }
++    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;
++  }
++}
++#else
++# define groupConcatInverse 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ static void groupConcatFinalize(sqlite3_context *context){
+   StrAccum *pAccum;
+   pAccum = sqlite3_aggregate_context(context, 0);
+   if( pAccum ){
+-    if( pAccum->accError==STRACCUM_TOOBIG ){
++    if( pAccum->accError==SQLITE_TOOBIG ){
+       sqlite3_result_error_toobig(context);
+-    }else if( pAccum->accError==STRACCUM_NOMEM ){
++    }else if( pAccum->accError==SQLITE_NOMEM ){
+       sqlite3_result_error_nomem(context);
+     }else{    
+       sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
+@@ -110751,6 +113796,24 @@
+     }
+   }
+ }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++static void groupConcatValue(sqlite3_context *context){
++  sqlite3_str *pAccum;
++  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
++  if( pAccum ){
++    if( pAccum->accError==SQLITE_TOOBIG ){
++      sqlite3_result_error_toobig(context);
++    }else if( pAccum->accError==SQLITE_NOMEM ){
++      sqlite3_result_error_nomem(context);
++    }else{    
++      const char *zText = sqlite3_str_value(pAccum);
++      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
++    }
++  }
++}
++#else
++# define groupConcatValue 0
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+ 
+ /*
+ ** This routine does per-connection function registration.  Most
+@@ -110788,10 +113851,10 @@
+   }else{
+     pInfo = (struct compareInfo*)&likeInfoNorm;
+   }
+-  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
+-  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
++  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
++  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
+   sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
+-      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
++      (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
+   setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
+   setLikeOptFlag(db, "like", 
+       caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+@@ -110900,11 +113963,11 @@
+     FUNCTION(trim,               2, 3, 0, trimFunc         ),
+     FUNCTION(min,               -1, 0, 1, minmaxFunc       ),
+     FUNCTION(min,                0, 0, 1, 0                ),
+-    AGGREGATE2(min,              1, 0, 1, minmaxStep,      minMaxFinalize,
++    WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
+                                           SQLITE_FUNC_MINMAX ),
+     FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
+     FUNCTION(max,                0, 1, 1, 0                ),
+-    AGGREGATE2(max,              1, 1, 1, minmaxStep,      minMaxFinalize,
++    WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
+                                           SQLITE_FUNC_MINMAX ),
+     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
+     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
+@@ -110935,14 +113998,17 @@
+     FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),
+     FUNCTION(substr,             2, 0, 0, substrFunc       ),
+     FUNCTION(substr,             3, 0, 0, substrFunc       ),
+-    AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
+-    AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
+-    AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
+-    AGGREGATE2(count,            0, 0, 0, countStep,       countFinalize,
+-               SQLITE_FUNC_COUNT  ),
+-    AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
+-    AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
+-    AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
++    WAGGREGATE(sum,   1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0),
++    WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0),
++    WAGGREGATE(avg,   1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0),
++    WAGGREGATE(count, 0,0,0, countStep, 
++        countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT  ),
++    WAGGREGATE(count, 1,0,0, countStep, 
++        countFinalize, countFinalize, countInverse, 0  ),
++    WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, 
++        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
++    WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, 
++        groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
+   
+     LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
+ #ifdef SQLITE_CASE_SENSITIVE_LIKE
+@@ -110962,6 +114028,7 @@
+ #ifndef SQLITE_OMIT_ALTERTABLE
+   sqlite3AlterFunctions();
+ #endif
++  sqlite3WindowFunctions();
+ #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+   sqlite3AnalyzeFunctions();
+ #endif
+@@ -111320,6 +114387,12 @@
+   int iCur = pParse->nTab - 1;              /* Cursor number to use */
+   int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */
+ 
++  sqlite3VdbeVerifyAbortable(v,
++    (!pFKey->isDeferred
++      && !(pParse->db->flags & SQLITE_DeferFKs)
++      && !pParse->pToplevel 
++      && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore);
++
+   /* If nIncr is less than zero, then check at runtime if there are any
+   ** outstanding constraints to resolve. If there are not, there is no need
+   ** to check if deleting this row resolves any outstanding violations.
+@@ -111485,7 +114558,7 @@
+ ){
+   Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+   if( pExpr ){
+-    pExpr->pTab = pTab;
++    pExpr->y.pTab = pTab;
+     pExpr->iTable = iCursor;
+     pExpr->iColumn = iCol;
+   }
+@@ -111693,11 +114766,12 @@
+ */
+ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
+   sqlite3 *db = pParse->db;
+-  if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
++  if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){
+     int iSkip = 0;
+     Vdbe *v = sqlite3GetVdbe(pParse);
+ 
+     assert( v );                  /* VDBE has already been allocated */
++    assert( pTab->pSelect==0 );   /* Not a view */
+     if( sqlite3FkReferences(pTab)==0 ){
+       /* Search for a deferred foreign key constraint for which this table
+       ** is the child table. If one cannot be found, return without 
+@@ -111727,6 +114801,7 @@
+     ** constraints are violated.
+     */
+     if( (db->flags & SQLITE_DeferFKs)==0 ){
++      sqlite3VdbeVerifyAbortable(v, OE_Abort);
+       sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+       VdbeCoverage(v);
+       sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+@@ -112559,7 +115634,8 @@
+     }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
+     pTab->zColAff = zColAff;
+   }
+-  i = sqlite3Strlen30(zColAff);
++  assert( zColAff!=0 );
++  i = sqlite3Strlen30NN(zColAff);
+   if( i ){
+     if( iReg ){
+       sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
+@@ -112639,12 +115715,27 @@
+   Table *pTab         /* The table we are writing to */
+ ){
+   int memId = 0;      /* Register holding maximum rowid */
++  assert( pParse->db->aDb[iDb].pSchema!=0 );
+   if( (pTab->tabFlags & TF_Autoincrement)!=0
+    && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
+   ){
+     Parse *pToplevel = sqlite3ParseToplevel(pParse);
+     AutoincInfo *pInfo;
++    Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
+ 
++    /* Verify that the sqlite_sequence table exists and is an ordinary
++    ** rowid table with exactly two columns.
++    ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */
++    if( pSeqTab==0
++     || !HasRowid(pSeqTab)
++     || IsVirtual(pSeqTab)
++     || pSeqTab->nCol!=2
++    ){
++      pParse->nErr++;
++      pParse->rc = SQLITE_CORRUPT_SEQUENCE;
++      return 0;
++    }
++
+     pInfo = pToplevel->pAinc;
+     while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
+     if( pInfo==0 ){
+@@ -112901,7 +115992,8 @@
+   SrcList *pTabList,    /* Name of table into which we are inserting */
+   Select *pSelect,      /* A SELECT statement to use as the data source */
+   IdList *pColumn,      /* Column names corresponding to IDLIST. */
+-  int onError           /* How to handle constraint errors */
++  int onError,          /* How to handle constraint errors */
++  Upsert *pUpsert       /* ON CONFLICT clauses for upsert, or NULL */
+ ){
+   sqlite3 *db;          /* The main database structure */
+   Table *pTab;          /* The table to insert into.  aka TABLE */
+@@ -113196,7 +116288,10 @@
+     
+   /* Initialize the count of rows to be inserted
+   */
+-  if( db->flags & SQLITE_CountRows ){
++  if( (db->flags & SQLITE_CountRows)!=0
++   && !pParse->nested
++   && !pParse->pTriggerTab
++  ){
+     regRowCount = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+   }
+@@ -113216,7 +116311,20 @@
+       pParse->nMem += pIdx->nColumn;
+     }
+   }
++#ifndef SQLITE_OMIT_UPSERT
++  if( pUpsert ){
++    pTabList->a[0].iCursor = iDataCur;
++    pUpsert->pUpsertSrc = pTabList;
++    pUpsert->regData = regData;
++    pUpsert->iDataCur = iDataCur;
++    pUpsert->iIdxCur = iIdxCur;
++    if( pUpsert->pUpsertTarget ){
++      sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert);
++    }
++  }
++#endif
+ 
++
+   /* This is the top of the main insertion loop */
+   if( useTempTable ){
+     /* This block codes the top of loop only.  The complete loop is the
+@@ -113418,7 +116526,7 @@
+       int isReplace;    /* Set to true if constraints may cause a replace */
+       int bUseSeek;     /* True to use OPFLAG_SEEKRESULT */
+       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+-          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
++          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert
+       );
+       sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+ 
+@@ -113441,7 +116549,7 @@
+ 
+   /* Update the count of rows that are inserted
+   */
+-  if( (db->flags & SQLITE_CountRows)!=0 ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+   }
+ 
+@@ -113478,7 +116586,7 @@
+   ** generating code because of a call to sqlite3NestedParse(), do not
+   ** invoke the callback function.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
+@@ -113487,6 +116595,7 @@
+ insert_cleanup:
+   sqlite3SrcListDelete(db, pTabList);
+   sqlite3ExprListDelete(db, pList);
++  sqlite3UpsertDelete(db, pUpsert);
+   sqlite3SelectDelete(db, pSelect);
+   sqlite3IdListDelete(db, pColumn);
+   sqlite3DbFree(db, aRegIdx);
+@@ -113506,14 +116615,15 @@
+ #endif
+ 
+ /*
+-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
++** Meanings of bits in of pWalker->eCode for 
++** sqlite3ExprReferencesUpdatedColumn()
+ */
+ #define CKCNSTRNT_COLUMN   0x01    /* CHECK constraint uses a changing column */
+ #define CKCNSTRNT_ROWID    0x02    /* CHECK constraint references the ROWID */
+ 
+-/* This is the Walker callback from checkConstraintUnchanged().  Set
+-** bit 0x01 of pWalker->eCode if
+-** pWalker->eCode to 0 if this expression node references any of the
++/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
++*  Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
++** expression node references any of the
+ ** columns that are being modifed by an UPDATE statement.
+ */
+ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
+@@ -113535,12 +116645,21 @@
+ ** only columns that are modified by the UPDATE are those for which
+ ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
+ **
+-** Return true if CHECK constraint pExpr does not use any of the
++** Return true if CHECK constraint pExpr uses any of the
+ ** changing columns (or the rowid if it is changing).  In other words,
+-** return true if this CHECK constraint can be skipped when validating
++** return true if this CHECK constraint must be validated for
+ ** the new row in the UPDATE statement.
++**
++** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
++** The operation of this routine is the same - return true if an only if
++** the expression uses one or more of columns identified by the second and
++** third arguments.
+ */
+-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
++SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
++  Expr *pExpr,    /* The expression to be checked */
++  int *aiChng,    /* aiChng[x]>=0 if column x changed by the UPDATE */
++  int chngRowid   /* True if UPDATE changes the rowid */
++){
+   Walker w;
+   memset(&w, 0, sizeof(w));
+   w.eCode = 0;
+@@ -113555,7 +116674,7 @@
+   testcase( w.eCode==CKCNSTRNT_COLUMN );
+   testcase( w.eCode==CKCNSTRNT_ROWID );
+   testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
+-  return !w.eCode;
++  return w.eCode!=0;
+ }
+ 
+ /*
+@@ -113653,7 +116772,8 @@
+   u8 overrideError,    /* Override onError to this if not OE_Default */
+   int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
+   int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
+-  int *aiChng          /* column i is unchanged if aiChng[i]<0 */
++  int *aiChng,         /* column i is unchanged if aiChng[i]<0 */
++  Upsert *pUpsert      /* ON CONFLICT clauses, if any.  NULL otherwise */
+ ){
+   Vdbe *v;             /* VDBE under constrution */
+   Index *pIdx;         /* Pointer to one of the indices */
+@@ -113666,10 +116786,13 @@
+   int addr1;           /* Address of jump instruction */
+   int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
+   int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+-  int ipkTop = 0;      /* Top of the rowid change constraint check */
+-  int ipkBottom = 0;   /* Bottom of the rowid change constraint check */
++  Index *pUpIdx = 0;   /* Index to which to apply the upsert */
+   u8 isUpdate;         /* True if this is an UPDATE operation */
+   u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
++  int upsertBypass = 0;  /* Address of Goto to bypass upsert subroutine */
++  int upsertJump = 0;    /* Address of Goto that jumps into upsert subroutine */
++  int ipkTop = 0;        /* Top of the IPK uniqueness check */
++  int ipkBottom = 0;     /* OP_Goto at the end of the IPK uniqueness check */
+ 
+   isUpdate = regOldData!=0;
+   db = pParse->db;
+@@ -113757,8 +116880,15 @@
+     for(i=0; i<pCheck->nExpr; i++){
+       int allOk;
+       Expr *pExpr = pCheck->a[i].pExpr;
+-      if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
++      if( aiChng
++       && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
++      ){
++        /* The check constraints do not reference any of the columns being
++        ** updated so there is no point it verifying the check constraint */
++        continue;
++      }
+       allOk = sqlite3VdbeMakeLabel(v);
++      sqlite3VdbeVerifyAbortable(v, onError);
+       sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
+       if( onError==OE_Ignore ){
+         sqlite3VdbeGoto(v, ignoreDest);
+@@ -113776,6 +116906,50 @@
+   }
+ #endif /* !defined(SQLITE_OMIT_CHECK) */
+ 
++  /* UNIQUE and PRIMARY KEY constraints should be handled in the following
++  ** order:
++  **
++  **   (1)  OE_Update
++  **   (2)  OE_Abort, OE_Fail, OE_Rollback, OE_Ignore
++  **   (3)  OE_Replace
++  **
++  ** OE_Fail and OE_Ignore must happen before any changes are made.
++  ** OE_Update guarantees that only a single row will change, so it
++  ** must happen before OE_Replace.  Technically, OE_Abort and OE_Rollback
++  ** could happen in any order, but they are grouped up front for
++  ** convenience.
++  **
++  ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43
++  ** The order of constraints used to have OE_Update as (2) and OE_Abort
++  ** and so forth as (1). But apparently PostgreSQL checks the OE_Update
++  ** constraint before any others, so it had to be moved.
++  **
++  ** Constraint checking code is generated in this order:
++  **   (A)  The rowid constraint
++  **   (B)  Unique index constraints that do not have OE_Replace as their
++  **        default conflict resolution strategy
++  **   (C)  Unique index that do use OE_Replace by default.
++  **
++  ** The ordering of (2) and (3) is accomplished by making sure the linked
++  ** list of indexes attached to a table puts all OE_Replace indexes last
++  ** in the list.  See sqlite3CreateIndex() for where that happens.
++  */
++
++  if( pUpsert ){
++    if( pUpsert->pUpsertTarget==0 ){
++      /* An ON CONFLICT DO NOTHING clause, without a constraint-target.
++      ** Make all unique constraint resolution be OE_Ignore */
++      assert( pUpsert->pUpsertSet==0 );
++      overrideError = OE_Ignore;
++      pUpsert = 0;
++    }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){
++      /* If the constraint-target uniqueness check must be run first.
++      ** Jump to that uniqueness check now */
++      upsertJump = sqlite3VdbeAddOp0(v, OP_Goto);
++      VdbeComment((v, "UPSERT constraint goes first"));
++    }
++  }
++
+   /* If rowid is changing, make sure the new rowid does not previously
+   ** exist in the table.
+   */
+@@ -113790,6 +116964,28 @@
+       onError = OE_Abort;
+     }
+ 
++    /* figure out whether or not upsert applies in this case */
++    if( pUpsert && pUpsert->pUpsertIdx==0 ){
++      if( pUpsert->pUpsertSet==0 ){
++        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
++      }else{
++        onError = OE_Update;  /* DO UPDATE */
++      }
++    }
++
++    /* If the response to a rowid conflict is REPLACE but the response
++    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
++    ** to defer the running of the rowid conflict checking until after
++    ** the UNIQUE constraints have run.
++    */
++    if( onError==OE_Replace      /* IPK rule is REPLACE */
++     && onError!=overrideError   /* Rules for other contraints are different */
++     && pTab->pIndex             /* There exist other constraints */
++    ){
++      ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1;
++      VdbeComment((v, "defer IPK REPLACE until last"));
++    }
++
+     if( isUpdate ){
+       /* pkChng!=0 does not mean that the rowid has changed, only that
+       ** it might have changed.  Skip the conflict logic below if the rowid
+@@ -113799,26 +116995,13 @@
+       VdbeCoverage(v);
+     }
+ 
+-    /* If the response to a rowid conflict is REPLACE but the response
+-    ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+-    ** to defer the running of the rowid conflict checking until after
+-    ** the UNIQUE constraints have run.
+-    */
+-    if( onError==OE_Replace && overrideError!=OE_Replace ){
+-      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+-        if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+-          ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+-          break;
+-        }
+-      }
+-    }
+-
+     /* Check to see if the new rowid already exists in the table.  Skip
+     ** the following conflict logic if it does not. */
++    VdbeNoopComment((v, "uniqueness check for ROWID"));
++    sqlite3VdbeVerifyAbortable(v, onError);
+     sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+     VdbeCoverage(v);
+ 
+-    /* Generate code that deals with a rowid collision */
+     switch( onError ){
+       default: {
+         onError = OE_Abort;
+@@ -113827,6 +117010,9 @@
+       case OE_Rollback:
+       case OE_Abort:
+       case OE_Fail: {
++        testcase( onError==OE_Rollback );
++        testcase( onError==OE_Abort );
++        testcase( onError==OE_Fail );
+         sqlite3RowidConstraint(pParse, onError, pTab);
+         break;
+       }
+@@ -113863,14 +117049,13 @@
+                                    regNewData, 1, 0, OE_Replace, 1, -1);
+         }else{
+ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+-          if( HasRowid(pTab) ){
+-            /* This OP_Delete opcode fires the pre-update-hook only. It does
+-            ** not modify the b-tree. It is more efficient to let the coming
+-            ** OP_Insert replace the existing entry than it is to delete the
+-            ** existing entry and then insert a new one. */
+-            sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
+-            sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+-          }
++          assert( HasRowid(pTab) );
++          /* This OP_Delete opcode fires the pre-update-hook only. It does
++          ** not modify the b-tree. It is more efficient to let the coming
++          ** OP_Insert replace the existing entry than it is to delete the
++          ** existing entry and then insert a new one. */
++          sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
++          sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
+ #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
+           if( pTab->pIndex ){
+             sqlite3MultiWrite(pParse);
+@@ -113880,8 +117065,14 @@
+         seenReplace = 1;
+         break;
+       }
++#ifndef SQLITE_OMIT_UPSERT
++      case OE_Update: {
++        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur);
++        /* Fall through */
++      }
++#endif
+       case OE_Ignore: {
+-        /*assert( seenReplace==0 );*/
++        testcase( onError==OE_Ignore );
+         sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+@@ -113889,7 +117080,7 @@
+     sqlite3VdbeResolveLabel(v, addrRowidOk);
+     if( ipkTop ){
+       ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+-      sqlite3VdbeJumpHere(v, ipkTop);
++      sqlite3VdbeJumpHere(v, ipkTop-1);
+     }
+   }
+ 
+@@ -113907,13 +117098,22 @@
+     int addrUniqueOk;    /* Jump here if the UNIQUE constraint is satisfied */
+ 
+     if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
+-    if( bAffinityDone==0 ){
++    if( pUpIdx==pIdx ){
++      addrUniqueOk = upsertJump+1;
++      upsertBypass = sqlite3VdbeGoto(v, 0);
++      VdbeComment((v, "Skip upsert subroutine"));
++      sqlite3VdbeJumpHere(v, upsertJump);
++    }else{
++      addrUniqueOk = sqlite3VdbeMakeLabel(v);
++    }
++    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
+       sqlite3TableAffinity(v, pTab, regNewData+1);
+       bAffinityDone = 1;
+     }
++    VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
+     iThisCur = iIdxCur+ix;
+-    addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ 
++
+     /* Skip partial indices for which the WHERE clause is not true */
+     if( pIdx->pPartIdxWhere ){
+       sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+@@ -113972,6 +117172,15 @@
+       onError = OE_Abort;
+     }
+ 
++    /* Figure out if the upsert clause applies to this index */
++    if( pUpIdx==pIdx ){
++      if( pUpsert->pUpsertSet==0 ){
++        onError = OE_Ignore;  /* DO NOTHING is the same as INSERT OR IGNORE */
++      }else{
++        onError = OE_Update;  /* DO UPDATE */
++      }
++    }
++
+     /* Collision detection may be omitted if all of the following are true:
+     **   (1) The conflict resolution algorithm is REPLACE
+     **   (2) The table is a WITHOUT ROWID table
+@@ -113992,7 +117201,7 @@
+     }
+ 
+     /* Check to see if the new index entry will be unique */
+-    sqlite3ExprCachePush(pParse);
++    sqlite3VdbeVerifyAbortable(v, onError);
+     sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+                          regIdx, pIdx->nKeyCol); VdbeCoverage(v);
+ 
+@@ -114054,15 +117263,25 @@
+ 
+     /* Generate code that executes if the new index entry is not unique */
+     assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
+-        || onError==OE_Ignore || onError==OE_Replace );
++        || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update );
+     switch( onError ){
+       case OE_Rollback:
+       case OE_Abort:
+       case OE_Fail: {
++        testcase( onError==OE_Rollback );
++        testcase( onError==OE_Abort );
++        testcase( onError==OE_Fail );
+         sqlite3UniqueConstraint(pParse, onError, pIdx);
+         break;
+       }
++#ifndef SQLITE_OMIT_UPSERT
++      case OE_Update: {
++        sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix);
++        /* Fall through */
++      }
++#endif
+       case OE_Ignore: {
++        testcase( onError==OE_Ignore );
+         sqlite3VdbeGoto(v, ignoreDest);
+         break;
+       }
+@@ -114069,10 +117288,12 @@
+       default: {
+         Trigger *pTrigger = 0;
+         assert( onError==OE_Replace );
+-        sqlite3MultiWrite(pParse);
+         if( db->flags&SQLITE_RecTriggers ){
+           pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
+         }
++        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
++          sqlite3MultiWrite(pParse);
++        }
+         sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+             regR, nPkField, 0, OE_Replace,
+             (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
+@@ -114080,15 +117301,22 @@
+         break;
+       }
+     }
+-    sqlite3VdbeResolveLabel(v, addrUniqueOk);
+-    sqlite3ExprCachePop(pParse);
++    if( pUpIdx==pIdx ){
++      sqlite3VdbeGoto(v, upsertJump+1);
++      sqlite3VdbeJumpHere(v, upsertBypass);
++    }else{
++      sqlite3VdbeResolveLabel(v, addrUniqueOk);
++    }
+     if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
+   }
++
++  /* If the IPK constraint is a REPLACE, run it last */
+   if( ipkTop ){
+     sqlite3VdbeGoto(v, ipkTop+1);
++    VdbeComment((v, "Do IPK REPLACE"));
+     sqlite3VdbeJumpHere(v, ipkBottom);
+   }
+-  
++
+   *pbMayReplace = seenReplace;
+   VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
+ }
+@@ -114184,7 +117412,6 @@
+   sqlite3SetMakeRecordP5(v, pTab);
+   if( !bAffinityDone ){
+     sqlite3TableAffinity(v, pTab, 0);
+-    sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
+   }
+   if( pParse->nested ){
+     pik_flags = 0;
+@@ -114587,6 +117814,7 @@
+     emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
+     if( pDest->iPKey>=0 ){
+       addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
++      sqlite3VdbeVerifyAbortable(v, onError);
+       addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+       VdbeCoverage(v);
+       sqlite3RowidConstraint(pParse, onError, pDest);
+@@ -115144,6 +118372,30 @@
+   int (*vtab_nochange)(sqlite3_context*);
+   int (*value_nochange)(sqlite3_value*);
+   const char *(*vtab_collation)(sqlite3_index_info*,int);
++  /* Version 3.24.0 and later */
++  int (*keyword_count)(void);
++  int (*keyword_name)(int,const char**,int*);
++  int (*keyword_check)(const char*,int);
++  sqlite3_str *(*str_new)(sqlite3*);
++  char *(*str_finish)(sqlite3_str*);
++  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
++  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
++  void (*str_append)(sqlite3_str*, const char *zIn, int N);
++  void (*str_appendall)(sqlite3_str*, const char *zIn);
++  void (*str_appendchar)(sqlite3_str*, int N, char C);
++  void (*str_reset)(sqlite3_str*);
++  int (*str_errcode)(sqlite3_str*);
++  int (*str_length)(sqlite3_str*);
++  char *(*str_value)(sqlite3_str*);
++  /* Version 3.25.0 and later */
++  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
++                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++                            void (*xFinal)(sqlite3_context*),
++                            void (*xValue)(sqlite3_context*),
++                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
++                            void(*xDestroy)(void*));
++  /* Version 3.26.0 and later */
++  const char *(*normalized_sql)(sqlite3_stmt*);
+ };
+ 
+ /*
+@@ -115414,6 +118666,25 @@
+ #define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
+ #define sqlite3_value_nochange         sqlite3_api->value_nochange
+ #define sqlite3_vtab_collation         sqlite3_api->vtab_collation
++/* Version 3.24.0 and later */
++#define sqlite3_keyword_count          sqlite3_api->keyword_count
++#define sqlite3_keyword_name           sqlite3_api->keyword_name
++#define sqlite3_keyword_check          sqlite3_api->keyword_check
++#define sqlite3_str_new                sqlite3_api->str_new
++#define sqlite3_str_finish             sqlite3_api->str_finish
++#define sqlite3_str_appendf            sqlite3_api->str_appendf
++#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
++#define sqlite3_str_append             sqlite3_api->str_append
++#define sqlite3_str_appendall          sqlite3_api->str_appendall
++#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
++#define sqlite3_str_reset              sqlite3_api->str_reset
++#define sqlite3_str_errcode            sqlite3_api->str_errcode
++#define sqlite3_str_length             sqlite3_api->str_length
++#define sqlite3_str_value              sqlite3_api->str_value
++/* Version 3.25.0 and later */
++#define sqlite3_create_window_function sqlite3_api->create_window_function
++/* Version 3.26.0 and later */
++#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
+ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+ 
+ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+@@ -115502,6 +118773,7 @@
+ # define sqlite3_declare_vtab 0
+ # define sqlite3_vtab_config 0
+ # define sqlite3_vtab_on_conflict 0
++# define sqlite3_vtab_collation 0
+ #endif
+ 
+ #ifdef SQLITE_OMIT_SHARED_CACHE
+@@ -115852,7 +119124,30 @@
+   /* Version 3.22.0 and later */
+   sqlite3_vtab_nochange,
+   sqlite3_value_nochange,
+-  sqlite3_vtab_collation
++  sqlite3_vtab_collation,
++  /* Version 3.24.0 and later */
++  sqlite3_keyword_count,
++  sqlite3_keyword_name,
++  sqlite3_keyword_check,
++  sqlite3_str_new,
++  sqlite3_str_finish,
++  sqlite3_str_appendf,
++  sqlite3_str_vappendf,
++  sqlite3_str_append,
++  sqlite3_str_appendall,
++  sqlite3_str_appendchar,
++  sqlite3_str_reset,
++  sqlite3_str_errcode,
++  sqlite3_str_length,
++  sqlite3_str_value,
++  /* Version 3.25.0 and later */
++  sqlite3_create_window_function,
++  /* Version 3.26.0 and later */
++#ifdef SQLITE_ENABLE_NORMALIZE
++  sqlite3_normalized_sql
++#else
++  0
++#endif
+ };
+ 
+ /*
+@@ -115918,10 +119213,8 @@
+ #if SQLITE_OS_UNIX || SQLITE_OS_WIN
+   for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
+     char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+-    int bExists = 0;
+     if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
+-    sqlite3OsAccess(pVfs, zAltFile, SQLITE_ACCESS_EXISTS, &bExists);
+-    if( bExists )  handle = sqlite3OsDlOpen(pVfs, zAltFile);
++    handle = sqlite3OsDlOpen(pVfs, zAltFile);
+     sqlite3_free(zAltFile);
+   }
+ #endif
+@@ -116304,10 +119597,9 @@
+ #define PragTyp_ACTIVATE_EXTENSIONS           40
+ #define PragTyp_HEXKEY                        41
+ #define PragTyp_KEY                           42
+-#define PragTyp_REKEY                         43
+-#define PragTyp_LOCK_STATUS                   44
+-#define PragTyp_PARSER_TRACE                  45
+-#define PragTyp_STATS                         46
++#define PragTyp_LOCK_STATUS                   43
++#define PragTyp_PARSER_TRACE                  44
++#define PragTyp_STATS                         45
+ 
+ /* Property flags associated with various pragma. */
+ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
+@@ -116324,21 +119616,22 @@
+ ** result column is different from the name of the pragma
+ */
+ static const char *const pragCName[] = {
+-  /*   0 */ "cache_size",  /* Used by: default_cache_size */
+-  /*   1 */ "cid",         /* Used by: table_info */
+-  /*   2 */ "name",       
+-  /*   3 */ "type",       
+-  /*   4 */ "notnull",    
+-  /*   5 */ "dflt_value", 
+-  /*   6 */ "pk",         
+-  /*   7 */ "tbl",         /* Used by: stats */
+-  /*   8 */ "idx",        
+-  /*   9 */ "wdth",       
+-  /*  10 */ "hght",       
+-  /*  11 */ "flgs",       
+-  /*  12 */ "seqno",       /* Used by: index_info */
+-  /*  13 */ "cid",        
+-  /*  14 */ "name",       
++  /*   0 */ "id",          /* Used by: foreign_key_list */
++  /*   1 */ "seq",        
++  /*   2 */ "table",      
++  /*   3 */ "from",       
++  /*   4 */ "to",         
++  /*   5 */ "on_update",  
++  /*   6 */ "on_delete",  
++  /*   7 */ "match",      
++  /*   8 */ "cid",         /* Used by: table_xinfo */
++  /*   9 */ "name",       
++  /*  10 */ "type",       
++  /*  11 */ "notnull",    
++  /*  12 */ "dflt_value", 
++  /*  13 */ "pk",         
++  /*  14 */ "hidden",     
++                           /* table_info reuses 8 */
+   /*  15 */ "seqno",       /* Used by: index_xinfo */
+   /*  16 */ "cid",        
+   /*  17 */ "name",       
+@@ -116345,37 +119638,35 @@
+   /*  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 */
++  /*  21 */ "tbl",         /* Used by: stats */
++  /*  22 */ "idx",        
++  /*  23 */ "wdth",       
++  /*  24 */ "hght",       
++  /*  25 */ "flgs",       
++  /*  26 */ "seq",         /* Used by: index_list */
+   /*  27 */ "name",       
+-  /*  28 */ "file",       
+-  /*  29 */ "name",        /* Used by: function_list */
+-  /*  30 */ "builtin",    
+-  /*  31 */ "name",        /* Used by: module_list pragma_list */
+-  /*  32 */ "seq",         /* Used by: collation_list */
+-  /*  33 */ "name",       
+-  /*  34 */ "id",          /* Used by: foreign_key_list */
+-  /*  35 */ "seq",        
+-  /*  36 */ "table",      
+-  /*  37 */ "from",       
+-  /*  38 */ "to",         
+-  /*  39 */ "on_update",  
+-  /*  40 */ "on_delete",  
+-  /*  41 */ "match",      
+-  /*  42 */ "table",       /* Used by: foreign_key_check */
+-  /*  43 */ "rowid",      
+-  /*  44 */ "parent",     
+-  /*  45 */ "fkid",       
+-  /*  46 */ "busy",        /* Used by: wal_checkpoint */
+-  /*  47 */ "log",        
+-  /*  48 */ "checkpointed",
+-  /*  49 */ "timeout",     /* Used by: busy_timeout */
+-  /*  50 */ "database",    /* Used by: lock_status */
+-  /*  51 */ "status",     
++  /*  28 */ "unique",     
++  /*  29 */ "origin",     
++  /*  30 */ "partial",    
++  /*  31 */ "table",       /* Used by: foreign_key_check */
++  /*  32 */ "rowid",      
++  /*  33 */ "parent",     
++  /*  34 */ "fkid",       
++                           /* index_info reuses 15 */
++  /*  35 */ "seq",         /* Used by: database_list */
++  /*  36 */ "name",       
++  /*  37 */ "file",       
++  /*  38 */ "busy",        /* Used by: wal_checkpoint */
++  /*  39 */ "log",        
++  /*  40 */ "checkpointed",
++  /*  41 */ "name",        /* Used by: function_list */
++  /*  42 */ "builtin",    
++                           /* collation_list reuses 26 */
++  /*  43 */ "database",    /* Used by: lock_status */
++  /*  44 */ "status",     
++  /*  45 */ "cache_size",  /* Used by: default_cache_size */
++                           /* module_list pragma_list reuses 9 */
++  /*  46 */ "timeout",     /* Used by: busy_timeout */
+ };
+ 
+ /* Definitions of all built-in pragmas */
+@@ -116385,7 +119676,7 @@
+   u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
+   u8 iPragCName;           /* Start of column names in pragCName[] */
+   u8 nPragCName;           /* Num of col names. 0 means use pragma name */
+-  u32 iArg;                /* Extra argument */
++  u64 iArg;                /* Extra argument */
+ } PragmaName;
+ static const PragmaName aPragmaName[] = {
+ #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+@@ -116421,7 +119712,7 @@
+  {/* zName:     */ "busy_timeout",
+   /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 49, 1,
++  /* ColNames:  */ 46, 1,
+   /* iArg:      */ 0 },
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+  {/* zName:     */ "cache_size",
+@@ -116458,7 +119749,7 @@
+  {/* zName:     */ "collation_list",
+   /* ePragTyp:  */ PragTyp_COLLATION_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 32, 2,
++  /* ColNames:  */ 26, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+@@ -116493,7 +119784,7 @@
+  {/* zName:     */ "database_list",
+   /* ePragTyp:  */ PragTyp_DATABASE_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+-  /* ColNames:  */ 26, 3,
++  /* ColNames:  */ 35, 3,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+@@ -116500,7 +119791,7 @@
+  {/* zName:     */ "default_cache_size",
+   /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+-  /* ColNames:  */ 0, 1,
++  /* ColNames:  */ 45, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -116530,7 +119821,7 @@
+  {/* zName:     */ "foreign_key_check",
+   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+-  /* ColNames:  */ 42, 4,
++  /* ColNames:  */ 31, 4,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FOREIGN_KEY)
+@@ -116537,7 +119828,7 @@
+  {/* zName:     */ "foreign_key_list",
+   /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 34, 8,
++  /* ColNames:  */ 0, 8,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -116573,7 +119864,7 @@
+  {/* zName:     */ "function_list",
+   /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 29, 2,
++  /* ColNames:  */ 41, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #endif
+@@ -116582,12 +119873,12 @@
+   /* ePragTyp:  */ PragTyp_HEXKEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 2 },
+  {/* zName:     */ "hexrekey",
+   /* ePragTyp:  */ PragTyp_HEXKEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 3 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ #if !defined(SQLITE_OMIT_CHECK)
+@@ -116609,12 +119900,12 @@
+  {/* zName:     */ "index_info",
+   /* ePragTyp:  */ PragTyp_INDEX_INFO,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 12, 3,
++  /* ColNames:  */ 15, 3,
+   /* iArg:      */ 0 },
+  {/* zName:     */ "index_list",
+   /* ePragTyp:  */ PragTyp_INDEX_LIST,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 21, 5,
++  /* ColNames:  */ 26, 5,
+   /* iArg:      */ 0 },
+  {/* zName:     */ "index_xinfo",
+   /* ePragTyp:  */ PragTyp_INDEX_INFO,
+@@ -116649,6 +119940,11 @@
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
++ {/* zName:     */ "legacy_alter_table",
++  /* ePragTyp:  */ PragTyp_FLAG,
++  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ SQLITE_LegacyAlter },
+  {/* zName:     */ "legacy_file_format",
+   /* ePragTyp:  */ PragTyp_FLAG,
+   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
+@@ -116666,7 +119962,7 @@
+  {/* zName:     */ "lock_status",
+   /* ePragTyp:  */ PragTyp_LOCK_STATUS,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 50, 2,
++  /* ColNames:  */ 43, 2,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+@@ -116692,7 +119988,7 @@
+  {/* zName:     */ "module_list",
+   /* ePragTyp:  */ PragTyp_MODULE_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 31, 1,
++  /* ColNames:  */ 9, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #endif
+@@ -116725,7 +120021,7 @@
+  {/* zName:     */ "pragma_list",
+   /* ePragTyp:  */ PragTyp_PRAGMA_LIST,
+   /* ePragFlg:  */ PragFlg_Result0,
+-  /* ColNames:  */ 31, 1,
++  /* ColNames:  */ 9, 1,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -116756,10 +120052,10 @@
+ #endif
+ #if defined(SQLITE_HAS_CODEC)
+  {/* zName:     */ "rekey",
+-  /* ePragTyp:  */ PragTyp_REKEY,
++  /* ePragTyp:  */ PragTyp_KEY,
+   /* ePragFlg:  */ 0,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ 0 },
++  /* iArg:      */ 1 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+  {/* zName:     */ "reverse_unordered_selects",
+@@ -116812,7 +120108,7 @@
+  {/* zName:     */ "stats",
+   /* ePragTyp:  */ PragTyp_STATS,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+-  /* ColNames:  */ 7, 5,
++  /* ColNames:  */ 21, 5,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+@@ -116826,8 +120122,13 @@
+  {/* zName:     */ "table_info",
+   /* ePragTyp:  */ PragTyp_TABLE_INFO,
+   /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+-  /* ColNames:  */ 1, 6,
++  /* ColNames:  */ 8, 6,
+   /* iArg:      */ 0 },
++ {/* zName:     */ "table_xinfo",
++  /* ePragTyp:  */ PragTyp_TABLE_INFO,
++  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
++  /* ColNames:  */ 8, 7,
++  /* iArg:      */ 1 },
+ #endif
+ #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+  {/* zName:     */ "temp_store",
+@@ -116841,6 +120142,18 @@
+   /* ColNames:  */ 0, 0,
+   /* iArg:      */ 0 },
+ #endif
++#if defined(SQLITE_HAS_CODEC)
++ {/* zName:     */ "textkey",
++  /* ePragTyp:  */ PragTyp_KEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 4 },
++ {/* zName:     */ "textrekey",
++  /* ePragTyp:  */ PragTyp_KEY,
++  /* ePragFlg:  */ 0,
++  /* ColNames:  */ 0, 0,
++  /* iArg:      */ 5 },
++#endif
+  {/* zName:     */ "threads",
+   /* ePragTyp:  */ PragTyp_THREADS,
+   /* ePragFlg:  */ PragFlg_Result0,
+@@ -116891,7 +120204,7 @@
+  {/* zName:     */ "wal_checkpoint",
+   /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
+   /* ePragFlg:  */ PragFlg_NeedSchema,
+-  /* ColNames:  */ 46, 3,
++  /* ColNames:  */ 38, 3,
+   /* iArg:      */ 0 },
+ #endif
+ #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+@@ -116899,10 +120212,10 @@
+   /* ePragTyp:  */ PragTyp_FLAG,
+   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
+   /* ColNames:  */ 0, 0,
+-  /* iArg:      */ SQLITE_WriteSchema },
++  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
+ #endif
+ };
+-/* Number of pragmas: 60 on by default, 77 total. */
++/* Number of pragmas: 62 on by default, 81 total. */
+ 
+ /************** End of pragma.h **********************************************/
+ /************** Continuing where we left off in pragma.c *********************/
+@@ -117914,7 +121227,7 @@
+       setPragmaResultColumnNames(v, pPragma);
+       returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
+     }else{
+-      int mask = pPragma->iArg;    /* Mask of bits to set or clear. */
++      u64 mask = pPragma->iArg;    /* Mask of bits to set or clear. */
+       if( db->autoCommit==0 ){
+         /* Foreign key support may not be enabled or disabled while not
+         ** in auto-commit mode.  */
+@@ -117963,15 +121276,17 @@
+     Table *pTab;
+     pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
+     if( pTab ){
++      int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+       int i, k;
+       int nHidden = 0;
+       Column *pCol;
+       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+-      pParse->nMem = 6;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      pParse->nMem = 7;
++      sqlite3CodeVerifySchema(pParse, iTabDb);
+       sqlite3ViewGetColumnNames(pParse, pTab);
+       for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
+-        if( IsHiddenColumn(pCol) ){
++        int isHidden = IsHiddenColumn(pCol);
++        if( isHidden && pPragma->iArg==0 ){
+           nHidden++;
+           continue;
+         }
+@@ -117983,13 +121298,14 @@
+           for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
+         }
+         assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
+-        sqlite3VdbeMultiLoad(v, 1, "issisi",
++        sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
+                i-nHidden,
+                pCol->zName,
+                sqlite3ColumnType(pCol,""),
+                pCol->notNull ? 1 : 0,
+                pCol->pDflt ? pCol->pDflt->u.zToken : 0,
+-               k);
++               k,
++               isHidden);
+       }
+     }
+   }
+@@ -118027,6 +121343,7 @@
+     Table *pTab;
+     pIdx = sqlite3FindIndex(db, zRight, zDb);
+     if( pIdx ){
++      int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
+       int i;
+       int mx;
+       if( pPragma->iArg ){
+@@ -118039,7 +121356,7 @@
+         pParse->nMem = 3;
+       }
+       pTab = pIdx->pTable;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      sqlite3CodeVerifySchema(pParse, iIdxDb);
+       assert( pParse->nMem<=pPragma->nPragCName );
+       for(i=0; i<mx; i++){
+         i16 cnum = pIdx->aiColumn[i];
+@@ -118063,8 +121380,9 @@
+     int i;
+     pTab = sqlite3FindTable(db, zRight, zDb);
+     if( pTab ){
++      int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+       pParse->nMem = 5;
+-      sqlite3CodeVerifySchema(pParse, iDb);
++      sqlite3CodeVerifySchema(pParse, iTabDb);
+       for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+         const char *azOrigin[] = { "c", "u", "pk" };
+         sqlite3VdbeMultiLoad(v, 1, "isisi",
+@@ -118111,6 +121429,7 @@
+     pParse->nMem = 2;
+     for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
+       for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
++        if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
+         sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
+       }
+     }
+@@ -118152,9 +121471,10 @@
+     if( pTab ){
+       pFK = pTab->pFKey;
+       if( pFK ){
++        int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+         int i = 0; 
+         pParse->nMem = 8;
+-        sqlite3CodeVerifySchema(pParse, iDb);
++        sqlite3CodeVerifySchema(pParse, iTabDb);
+         while(pFK){
+           int j;
+           for(j=0; j<pFK->nCol; j++){
+@@ -118199,9 +121519,9 @@
+     pParse->nMem += 4;
+     regKey = ++pParse->nMem;
+     regRow = ++pParse->nMem;
+-    sqlite3CodeVerifySchema(pParse, iDb);
+     k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
+     while( k ){
++      int iTabDb;
+       if( zRight ){
+         pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
+         k = 0;
+@@ -118210,21 +121530,23 @@
+         k = sqliteHashNext(k);
+       }
+       if( pTab==0 || pTab->pFKey==0 ) continue;
+-      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
++      iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
++      sqlite3CodeVerifySchema(pParse, iTabDb);
++      sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
+       if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+-      sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
++      sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
+       sqlite3VdbeLoadString(v, regResult, pTab->zName);
+       for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
+         pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+         if( pParent==0 ) continue;
+         pIdx = 0;
+-        sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
++        sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
+         x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
+         if( x==0 ){
+           if( pIdx==0 ){
+-            sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
++            sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
+           }else{
+-            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
++            sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
+             sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+           }
+         }else{
+@@ -118427,7 +121749,6 @@
+ 
+         if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
+         pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+-        sqlite3ExprCacheClear(pParse);
+         sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
+                                    1, 0, &iDataCur, &iIdxCur);
+         /* reg[7] counts the number of entries in the table.
+@@ -118441,6 +121762,11 @@
+         assert( sqlite3NoTempsInRange(pParse,1,7+j) );
+         sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
+         loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
++        if( !isQuick ){
++          /* Sanity check on record header decoding */
++          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
++          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
++        }
+         /* Verify that all NOT NULL columns really are NOT NULL */
+         for(j=0; j<pTab->nCol; j++){
+           char *zErr;
+@@ -118465,7 +121791,6 @@
+             char *zErr;
+             int k;
+             pParse->iSelfTab = iDataCur + 1;
+-            sqlite3ExprCachePush(pParse);
+             for(k=pCheck->nExpr-1; k>0; k--){
+               sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+             }
+@@ -118478,14 +121803,10 @@
+             sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+             integrityCheckResultRow(v);
+             sqlite3VdbeResolveLabel(v, addrCkOk);
+-            sqlite3ExprCachePop(pParse);
+           }
+           sqlite3ExprListDelete(db, pCheck);
+         }
+         if( !isQuick ){ /* Omit the remaining tests for quick_check */
+-          /* Sanity check on record header decoding */
+-          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
+-          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+           /* Validate index entries for the current row */
+           for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+             int jmp2, jmp3, jmp4, jmp5;
+@@ -118994,14 +122315,26 @@
+ #endif
+ 
+ #ifdef SQLITE_HAS_CODEC
++  /* Pragma        iArg
++  ** ----------   ------
++  **  key           0
++  **  rekey         1
++  **  hexkey        2
++  **  hexrekey      3
++  **  textkey       4
++  **  textrekey     5
++  */
+   case PragTyp_KEY: {
+-    if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
++    if( zRight ){
++      int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
++      if( (pPragma->iArg & 1)==0 ){
++        sqlite3_key_v2(db, zDb, zRight, n);
++      }else{
++        sqlite3_rekey_v2(db, zDb, zRight, n);
++      }
++    }
+     break;
+   }
+-  case PragTyp_REKEY: {
+-    if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+-    break;
+-  }
+   case PragTyp_HEXKEY: {
+     if( zRight ){
+       u8 iByte;
+@@ -119011,7 +122344,7 @@
+         iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+         if( (i&1)!=0 ) zKey[i/2] = iByte;
+       }
+-      if( (zLeft[3] & 0xf)==0xb ){
++      if( (pPragma->iArg & 1)==0 ){
+         sqlite3_key_v2(db, zDb, zKey, i/2);
+       }else{
+         sqlite3_rekey_v2(db, zDb, zKey, i/2);
+@@ -119093,26 +122426,25 @@
+   UNUSED_PARAMETER(argc);
+   UNUSED_PARAMETER(argv);
+   sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+-  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
++  sqlite3_str_appendall(&acc, "CREATE TABLE x");
+   for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
+-    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
++    sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
+     cSep = ',';
+   }
+   if( i==0 ){
+-    sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
+-    cSep = ',';
++    sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
+     i++;
+   }
+   j = 0;
+   if( pPragma->mPragFlg & PragFlg_Result1 ){
+-    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
++    sqlite3_str_appendall(&acc, ",arg HIDDEN");
+     j++;
+   }
+   if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
+-    sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
++    sqlite3_str_appendall(&acc, ",schema HIDDEN");
+     j++;
+   }
+-  sqlite3StrAccumAppend(&acc, ")", 1);
++  sqlite3_str_append(&acc, ")", 1);
+   sqlite3StrAccumFinish(&acc);
+   assert( strlen(zBuf) < sizeof(zBuf)-1 );
+   rc = sqlite3_declare_vtab(db, zBuf);
+@@ -119264,13 +122596,13 @@
+     }
+   }
+   sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
+-  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
++  sqlite3_str_appendall(&acc, "PRAGMA ");
+   if( pCsr->azArg[1] ){
+-    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
++    sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
+   }
+-  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
++  sqlite3_str_appendall(&acc, pTab->pName->zName);
+   if( pCsr->azArg[0] ){
+-    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
++    sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
+   }
+   zSql = sqlite3StrAccumFinish(&acc);
+   if( zSql==0 ) return SQLITE_NOMEM;
+@@ -119342,7 +122674,8 @@
+   0,                           /* xRename - rename the table */
+   0,                           /* xSavepoint */
+   0,                           /* xRelease */
+-  0                            /* xRollbackTo */
++  0,                           /* xRollbackTo */
++  0                            /* xShadowName */
+ };
+ 
+ /*
+@@ -119393,15 +122726,23 @@
+   const char *zExtra   /* Error information */
+ ){
+   sqlite3 *db = pData->db;
+-  if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){
++  if( db->mallocFailed ){
++    pData->rc = SQLITE_NOMEM_BKPT;
++  }else if( pData->pzErrMsg[0]!=0 ){
++    /* A error message has already been generated.  Do not overwrite it */
++  }else if( pData->mInitFlags & INITFLAG_AlterTable ){
++    *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra);
++    pData->rc = SQLITE_ERROR;
++  }else if( db->flags & SQLITE_WriteSchema ){
++    pData->rc = SQLITE_CORRUPT_BKPT;
++  }else{
+     char *z;
+     if( zObj==0 ) zObj = "?";
+     z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
+     if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
+-    sqlite3DbFree(db, *pData->pzErrMsg);
+     *pData->pzErrMsg = z;
++    pData->rc = SQLITE_CORRUPT_BKPT;
+   }
+-  pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
+ }
+ 
+ /*
+@@ -119453,7 +122794,7 @@
+     rc = db->errCode;
+     assert( (rc&0xFF)==(rcp&0xFF) );
+     db->init.iDb = saved_iDb;
+-    assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 );
++    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
+     if( SQLITE_OK!=rc ){
+       if( db->init.orphanTrigger ){
+         assert( iDb==1 );
+@@ -119500,7 +122841,7 @@
+ ** auxiliary databases.  Return one of the SQLITE_ error codes to
+ ** indicate success or failure.
+ */
+-static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
++SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
+   int rc;
+   int i;
+ #ifndef SQLITE_OMIT_DEPRECATED
+@@ -119513,6 +122854,7 @@
+   const char *zMasterName;
+   int openedTransaction = 0;
+ 
++  assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 );
+   assert( iDb>=0 && iDb<db->nDb );
+   assert( db->aDb[iDb].pSchema );
+   assert( sqlite3_mutex_held(db->mutex) );
+@@ -119534,6 +122876,7 @@
+   initData.iDb = iDb;
+   initData.rc = SQLITE_OK;
+   initData.pzErrMsg = pzErrMsg;
++  initData.mInitFlags = mFlags;
+   sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
+   if( initData.rc ){
+     rc = initData.rc;
+@@ -119555,7 +122898,7 @@
+   ** will be closed before this function returns.  */
+   sqlite3BtreeEnter(pDb->pBt);
+   if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
+-    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
++    rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0);
+     if( rc!=SQLITE_OK ){
+       sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
+       goto initone_error_out;
+@@ -119583,6 +122926,9 @@
+   for(i=0; i<ArraySize(meta); i++){
+     sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
+   }
++  if( (db->flags & SQLITE_ResetDatabase)!=0 ){
++    memset(meta, 0, sizeof(meta));
++  }
+   pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
+ 
+   /* If opening a non-empty database, check the text encoding. For the
+@@ -119682,8 +123028,8 @@
+     rc = SQLITE_NOMEM_BKPT;
+     sqlite3ResetAllSchemasOfConnection(db);
+   }
+-  if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
+-    /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
++  if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
++    /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
+     ** the schema loaded, even if errors occurred. In this situation the 
+     ** current sqlite3_prepare() operation will fail, but the following one
+     ** will attempt to compile the supplied statement against whatever subset
+@@ -119737,13 +123083,14 @@
+   assert( db->nDb>0 );
+   /* Do the main schema first */
+   if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
+-    rc = sqlite3InitOne(db, 0, pzErrMsg);
++    rc = sqlite3InitOne(db, 0, pzErrMsg, 0);
+     if( rc ) return rc;
+   }
+   /* All other schemas after the main schema. The "temp" schema must be last */
+   for(i=db->nDb-1; i>0; i--){
++    assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) );
+     if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
+-      rc = sqlite3InitOne(db, i, pzErrMsg);
++      rc = sqlite3InitOne(db, i, pzErrMsg, 0);
+       if( rc ) return rc;
+     }
+   }
+@@ -119763,11 +123110,13 @@
+   assert( sqlite3_mutex_held(db->mutex) );
+   if( !db->init.busy ){
+     rc = sqlite3Init(db, &pParse->zErrMsg);
++    if( rc!=SQLITE_OK ){
++      pParse->rc = rc;
++      pParse->nErr++;
++    }else if( db->noSharedCache ){
++      db->mDbFlags |= DBFLAG_SchemaKnownOk;
++    }
+   }
+-  if( rc!=SQLITE_OK ){
+-    pParse->rc = rc;
+-    pParse->nErr++;
+-  }
+   return rc;
+ }
+ 
+@@ -119794,7 +123143,7 @@
+     ** on the b-tree database, open one now. If a transaction is opened, it 
+     ** will be closed immediately after reading the meta-value. */
+     if( !sqlite3BtreeIsInReadTrans(pBt) ){
+-      rc = sqlite3BtreeBeginTrans(pBt, 0);
++      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+       if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+         sqlite3OomFault(db);
+       }
+@@ -119977,7 +123326,7 @@
+   if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
+     static const char * const azColName[] = {
+        "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+-       "selectid", "order", "from", "detail"
++       "id", "parent", "notused", "detail"
+     };
+     int iFirst, mx;
+     if( sParse.explain==2 ){
+@@ -120061,7 +123410,295 @@
+   return rc;
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
+ /*
++** Checks if the specified token is a table, column, or function name,
++** based on the databases associated with the statement being prepared.
++** If the function fails, zero is returned and pRc is filled with the
++** error code.
++*/
++static int shouldTreatAsIdentifier(
++  sqlite3 *db,        /* Database handle. */
++  const char *zToken, /* Pointer to start of token to be checked */
++  int nToken,         /* Length of token to be checked */
++  int *pRc            /* Pointer to error code upon failure */
++){
++  int bFound = 0;     /* Non-zero if token is an identifier name. */
++  int i, j;           /* Database and column loop indexes. */
++  Schema *pSchema;    /* Schema for current database. */
++  Hash *pHash;        /* Hash table of tables for current database. */
++  HashElem *e;        /* Hash element for hash table iteration. */
++  Table *pTab;        /* Database table for columns being checked. */
++
++  if( sqlite3IsRowidN(zToken, nToken) ){
++    return 1;
++  }
++  if( nToken>0 ){
++    int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
++    if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
++  }
++  assert( db!=0 );
++  sqlite3_mutex_enter(db->mutex);
++  sqlite3BtreeEnterAll(db);
++  for(i=0; i<db->nDb; i++){
++    pHash = &db->aFunc;
++    if( sqlite3HashFindN(pHash, zToken, nToken) ){
++      bFound = 1;
++      break;
++    }
++    pSchema = db->aDb[i].pSchema;
++    if( pSchema==0 ) continue;
++    pHash = &pSchema->tblHash;
++    if( sqlite3HashFindN(pHash, zToken, nToken) ){
++      bFound = 1;
++      break;
++    }
++    for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
++      pTab = sqliteHashData(e);
++      if( pTab==0 ) continue;
++      pHash = pTab->pColHash;
++      if( pHash==0 ){
++        pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
++        if( pHash ){
++          sqlite3HashInit(pHash);
++          for(j=0; j<pTab->nCol; j++){
++            Column *pCol = &pTab->aCol[j];
++            sqlite3HashInsert(pHash, pCol->zName, pCol);
++          }
++        }else{
++          *pRc = SQLITE_NOMEM_BKPT;
++          bFound = 0;
++          goto done;
++        }
++      }
++      if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
++        bFound = 1;
++        goto done;
++      }
++    }
++  }
++done:
++  sqlite3BtreeLeaveAll(db);
++  sqlite3_mutex_leave(db->mutex);
++  return bFound;
++}
++
++/*
++** Attempt to estimate the final output buffer size needed for the fully
++** normalized version of the specified SQL string.  This should take into
++** account any potential expansion that could occur (e.g. via IN clauses
++** being expanded, etc).  This size returned is the total number of bytes
++** including the NUL terminator.
++*/
++static int estimateNormalizedSize(
++  const char *zSql, /* The original SQL string */
++  int nSql,         /* Length of original SQL string */
++  u8 prepFlags      /* The flags passed to sqlite3_prepare_v3() */
++){
++  int nOut = nSql + 4;
++  const char *z = zSql;
++  while( nOut<nSql*5 ){
++    while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; }
++    if( z[0]==0 ) break;
++    z++;
++    if( z[0]!='N' && z[0]!='n' ) break;
++    z++;
++    while( sqlite3Isspace(z[0]) ){ z++; }
++    if( z[0]!='(' ) break;
++    z++;
++    nOut += 5; /* ?,?,? */
++  }
++  return nOut;
++}
++
++/*
++** Copy the current token into the output buffer while dealing with quoted
++** identifiers.  By default, all letters will be converted into lowercase.
++** If the bUpper flag is set, uppercase will be used.  The piOut argument
++** will be used to update the target index into the output string.
++*/
++static void copyNormalizedToken(
++  const char *zSql, /* The original SQL string */
++  int iIn,          /* Current index into the original SQL string */
++  int nToken,       /* Number of bytes in the current token */
++  int tokenFlags,   /* Flags returned by the tokenizer */
++  char *zOut,       /* The output string */
++  int *piOut        /* Pointer to target index into the output string */
++){
++  int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED;
++  int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD;
++  int j = *piOut, k = 0;
++  for(; k<nToken; k++){
++    if( bQuoted ){
++      if( k==0 && iIn>0 ){
++        zOut[j++] = '"';
++        continue;
++      }else if( k==nToken-1 ){
++        zOut[j++] = '"';
++        continue;
++      }
++    }
++    if( bKeyword ){
++      zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
++    }else{
++      zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
++    }
++  }
++  *piOut = j;
++}
++
++/*
++** Perform normalization of the SQL contained in the prepared statement and
++** store the result in the zNormSql field.  The schema for the associated
++** databases are consulted while performing the normalization in order to
++** determine if a token appears to be an identifier.  All identifiers are
++** left intact in the normalized SQL and all literals are replaced with a
++** single '?'.
++*/
++SQLITE_PRIVATE void sqlite3Normalize(
++  Vdbe *pVdbe,      /* VM being reprepared */
++  const char *zSql, /* The original SQL string */
++  int nSql,         /* Size of the input string in bytes */
++  u8 prepFlags      /* The flags passed to sqlite3_prepare_v3() */
++){
++  sqlite3 *db;           /* Database handle. */
++  char *z;               /* The output string */
++  int nZ;                /* Size of the output string in bytes */
++  int i;                 /* Next character to read from zSql[] */
++  int j;                 /* Next character to fill in on z[] */
++  int tokenType = 0;     /* Type of the next token */
++  int prevTokenType = 0; /* Type of the previous token, except spaces */
++  int n;                 /* Size of the next token */
++  int nParen = 0;        /* Nesting level of parenthesis */
++  Hash inHash;           /* Table of parenthesis levels to output index. */
++
++  db = sqlite3VdbeDb(pVdbe);
++  assert( db!=0 );
++  assert( pVdbe->zNormSql==0 );
++  if( zSql==0 ) return;
++  nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
++  z = sqlite3DbMallocRawNN(db, nZ);
++  if( z==0 ) return;
++  sqlite3HashInit(&inHash);
++  for(i=j=0; i<nSql && zSql[i]; i+=n){
++    int flags = 0;
++    if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
++    n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
++    switch( tokenType ){
++      case TK_SPACE: {
++        break;
++      }
++      case TK_ILLEGAL: {
++        sqlite3DbFree(db, z);
++        sqlite3HashClear(&inHash);
++        return;
++      }
++      case TK_STRING:
++      case TK_INTEGER:
++      case TK_FLOAT:
++      case TK_VARIABLE:
++      case TK_BLOB: {
++        z[j++] = '?';
++        break;
++      }
++      case TK_LP:
++      case TK_RP: {
++        if( tokenType==TK_LP ){
++          nParen++;
++          if( prevTokenType==TK_IN ){
++            assert( nParen<nSql );
++            sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
++          }
++        }else{
++          int jj;
++          assert( nParen<nSql );
++          jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
++          if( jj>0 ){
++            sqlite3HashInsert(&inHash, zSql+nParen, 0);
++            assert( jj+6<nZ );
++            memcpy(z+jj+1, "?,?,?", 5);
++            j = jj+6;
++            assert( nZ-1-j>=0 );
++            assert( nZ-1-j<nZ );
++            memset(z+j, 0, nZ-1-j);
++          }
++          nParen--;
++        }
++        assert( nParen>=0 );
++        /* Fall through */
++      }
++      case TK_MINUS:
++      case TK_SEMI:
++      case TK_PLUS:
++      case TK_STAR:
++      case TK_SLASH:
++      case TK_REM:
++      case TK_EQ:
++      case TK_LE:
++      case TK_NE:
++      case TK_LSHIFT:
++      case TK_LT:
++      case TK_RSHIFT:
++      case TK_GT:
++      case TK_GE:
++      case TK_BITOR:
++      case TK_CONCAT:
++      case TK_COMMA:
++      case TK_BITAND:
++      case TK_BITNOT:
++      case TK_DOT:
++      case TK_IN:
++      case TK_IS:
++      case TK_NOT:
++      case TK_NULL:
++      case TK_ID: {
++        if( tokenType==TK_NULL ){
++          if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
++            /* NULL is a keyword in this case, not a literal value */
++          }else{
++            /* Here the NULL is a literal value */
++            z[j++] = '?';
++            break;
++          }
++        }
++        if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
++          z[j++] = ' ';
++        }
++        if( tokenType==TK_ID ){
++          int i2 = i, n2 = n, rc = SQLITE_OK;
++          if( nParen>0 ){
++            assert( nParen<nSql );
++            sqlite3HashInsert(&inHash, zSql+nParen, 0);
++          }
++          if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
++          if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
++            if( rc!=SQLITE_OK ){
++              sqlite3DbFree(db, z);
++              sqlite3HashClear(&inHash);
++              return;
++            }
++            if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
++              z[j++] = '?';
++              break;
++            }
++          }
++        }
++        copyNormalizedToken(zSql, i, n, flags, z, &j);
++        break;
++      }
++    }
++  }
++  assert( j<nZ && "one" );
++  while( j>0 && z[j-1]==' ' ){ j--; }
++  if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
++  z[j] = 0;
++  assert( j<nZ && "two" );
++  pVdbe->zNormSql = z;
++  sqlite3HashClear(&inHash);
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
++/*
+ ** Rerun the compilation of a statement after a schema change.
+ **
+ ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
+@@ -120291,7 +123928,7 @@
+ /***/ int sqlite3SelectTrace = 0;
+ # define SELECTTRACE(K,P,S,X)  \
+   if(sqlite3SelectTrace&(K))   \
+-    sqlite3DebugPrintf("%s/%p: ",(S)->zSelName,(S)),\
++    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
+     sqlite3DebugPrintf X
+ #else
+ # define SELECTTRACE(K,P,S,X)
+@@ -120314,6 +123951,20 @@
+ /*
+ ** An instance of the following object is used to record information about
+ ** the ORDER BY (or GROUP BY) clause of query is being coded.
++**
++** The aDefer[] array is used by the sorter-references optimization. For
++** example, assuming there is no index that can be used for the ORDER BY,
++** for the query:
++**
++**     SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10;
++**
++** it may be more efficient to add just the "a" values to the sorter, and
++** retrieve the associated "bigblob" values directly from table t1 as the
++** 10 smallest "a" values are extracted from the sorter.
++**
++** When the sorter-reference optimization is used, there is one entry in the
++** aDefer[] array for each database table that may be read as values are
++** extracted from the sorter.
+ */
+ typedef struct SortCtx SortCtx;
+ struct SortCtx {
+@@ -120324,8 +123975,17 @@
+   int labelBkOut;       /* Start label for the block-output subroutine */
+   int addrSortIndex;    /* Address of the OP_SorterOpen or OP_OpenEphemeral */
+   int labelDone;        /* Jump here when done, ex: LIMIT reached */
++  int labelOBLopt;      /* Jump here when sorter is full */
+   u8 sortFlags;         /* Zero or more SORTFLAG_* bits */
+-  u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  u8 nDefer;            /* Number of valid entries in aDefer[] */
++  struct DeferredCsr {
++    Table *pTab;        /* Table definition */
++    int iCsr;           /* Cursor number for table */
++    int nKey;           /* Number of PK columns for table pTab (>=1) */
++  } aDefer[4];
++#endif
++  struct RowLoadInfo *pDeferredRowLoad;  /* Deferred row loading info or NULL */
+ };
+ #define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */
+ 
+@@ -120343,6 +124003,11 @@
+     sqlite3ExprDelete(db, p->pHaving);
+     sqlite3ExprListDelete(db, p->pOrderBy);
+     sqlite3ExprDelete(db, p->pLimit);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
++      sqlite3WindowListDelete(db, p->pWinDefn);
++    }
++#endif
+     if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
+     if( bFree ) sqlite3DbFreeNN(db, p);
+     p = pPrior;
+@@ -120393,9 +124058,7 @@
+   pNew->selFlags = selFlags;
+   pNew->iLimit = 0;
+   pNew->iOffset = 0;
+-#if SELECTTRACE_ENABLED
+-  pNew->zSelName[0] = 0;
+-#endif
++  pNew->selId = ++pParse->nSelect;
+   pNew->addrOpenEphm[0] = -1;
+   pNew->addrOpenEphm[1] = -1;
+   pNew->nSelectRow = 0;
+@@ -120409,6 +124072,10 @@
+   pNew->pNext = 0;
+   pNew->pLimit = pLimit;
+   pNew->pWith = 0;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  pNew->pWin = 0;
++  pNew->pWinDefn = 0;
++#endif
+   if( pParse->db->mallocFailed ) {
+     clearSelect(pParse->db, pNew, pNew!=&standin);
+     pNew = 0;
+@@ -120419,18 +124086,7 @@
+   return pNew;
+ }
+ 
+-#if SELECTTRACE_ENABLED
+-/*
+-** Set the name of a Select object
+-*/
+-SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
+-  if( p && zName ){
+-    sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
+-  }
+-}
+-#endif
+ 
+-
+ /*
+ ** Delete the given Select structure and all of its substructures.
+ */
+@@ -120776,15 +124432,63 @@
+   return 0;
+ }
+ 
+-/* Forward reference */
+-static KeyInfo *keyInfoFromExprList(
+-  Parse *pParse,       /* Parsing context */
+-  ExprList *pList,     /* Form the KeyInfo object from this ExprList */
+-  int iStart,          /* Begin with this column of pList */
+-  int nExtra           /* Add this many extra columns to the end */
+-);
++/*
++** An instance of this object holds information (beyond pParse and pSelect)
++** needed to load the next result row that is to be added to the sorter.
++*/
++typedef struct RowLoadInfo RowLoadInfo;
++struct RowLoadInfo {
++  int regResult;               /* Store results in array of registers here */
++  u8 ecelFlags;                /* Flag argument to ExprCodeExprList() */
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  ExprList *pExtra;            /* Extra columns needed by sorter refs */
++  int regExtraResult;          /* Where to load the extra columns */
++#endif
++};
+ 
+ /*
++** This routine does the work of loading query data into an array of
++** registers so that it can be added to the sorter.
++*/
++static void innerLoopLoadRow(
++  Parse *pParse,             /* Statement under construction */
++  Select *pSelect,           /* The query being coded */
++  RowLoadInfo *pInfo         /* Info needed to complete the row load */
++){
++  sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult,
++                          0, pInfo->ecelFlags);
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  if( pInfo->pExtra ){
++    sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0);
++    sqlite3ExprListDelete(pParse->db, pInfo->pExtra);
++  }
++#endif
++}
++
++/*
++** Code the OP_MakeRecord instruction that generates the entry to be
++** added into the sorter.
++**
++** Return the register in which the result is stored.
++*/
++static int makeSorterRecord(
++  Parse *pParse,
++  SortCtx *pSort,
++  Select *pSelect,
++  int regBase,
++  int nBase
++){
++  int nOBSat = pSort->nOBSat;
++  Vdbe *v = pParse->pVdbe;
++  int regOut = ++pParse->nMem;
++  if( pSort->pDeferredRowLoad ){
++    innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad);
++  }
++  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut);
++  return regOut;
++}
++
++/*
+ ** Generate code that will push the record in registers regData
+ ** through regData+nData-1 onto the sorter.
+ */
+@@ -120794,7 +124498,7 @@
+   Select *pSelect,       /* The whole SELECT statement */
+   int regData,           /* First register holding data to be sorted */
+   int regOrigData,       /* First register holding data before packing */
+-  int nData,             /* Number of elements in the data array */
++  int nData,             /* Number of elements in the regData data array */
+   int nPrefixReg         /* No. of reg prior to regData available for use */
+ ){
+   Vdbe *v = pParse->pVdbe;                         /* Stmt under construction */
+@@ -120802,16 +124506,32 @@
+   int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
+   int nBase = nExpr + bSeq + nData;                /* Fields in sorter record */
+   int regBase;                                     /* Regs for sorter record */
+-  int regRecord = ++pParse->nMem;                  /* Assembled sorter record */
++  int regRecord = 0;                               /* Assembled sorter record */
+   int nOBSat = pSort->nOBSat;                      /* ORDER BY terms to skip */
+   int op;                            /* Opcode to add sorter record to sorter */
+   int iLimit;                        /* LIMIT counter */
++  int iSkip = 0;                     /* End of the sorter insert loop */
+ 
+   assert( bSeq==0 || bSeq==1 );
++
++  /* Three cases:
++  **   (1) The data to be sorted has already been packed into a Record
++  **       by a prior OP_MakeRecord.  In this case nData==1 and regData
++  **       will be completely unrelated to regOrigData.
++  **   (2) All output columns are included in the sort record.  In that
++  **       case regData==regOrigData.
++  **   (3) Some output columns are omitted from the sort record due to
++  **       the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the
++  **       SQLITE_ECEL_OMITREF optimization, or due to the 
++  **       SortCtx.pDeferredRowLoad optimiation.  In any of these cases
++  **       regOrigData is 0 to prevent this routine from trying to copy
++  **       values that might not yet exist.
++  */
+   assert( nData==1 || regData==regOrigData || regOrigData==0 );
++
+   if( nPrefixReg ){
+     assert( nPrefixReg==nExpr+bSeq );
+-    regBase = regData - nExpr - bSeq;
++    regBase = regData - nPrefixReg;
+   }else{
+     regBase = pParse->nMem + 1;
+     pParse->nMem += nBase;
+@@ -120827,7 +124547,6 @@
+   if( nPrefixReg==0 && nData>0 ){
+     sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+   }
+-  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
+   if( nOBSat>0 ){
+     int regPrevKey;   /* The first nOBSat columns of the previous row */
+     int addrFirst;    /* Address of the OP_IfNot opcode */
+@@ -120836,6 +124555,7 @@
+     int nKey;         /* Number of sorting key columns, including OP_Sequence */
+     KeyInfo *pKI;     /* Original KeyInfo on the sorter table */
+ 
++    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
+     regPrevKey = pParse->nMem+1;
+     pParse->nMem += pSort->nOBSat;
+     nKey = nExpr - pSort->nOBSat + bSeq;
+@@ -120853,7 +124573,7 @@
+     memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
+     sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
+     testcase( pKI->nAllField > pKI->nKeyField+2 );
+-    pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
++    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
+                                            pKI->nAllField-pKI->nKeyField-1);
+     addrJmp = sqlite3VdbeCurrentAddr(v);
+     sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
+@@ -120869,6 +124589,34 @@
+     sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
+     sqlite3VdbeJumpHere(v, addrJmp);
+   }
++  if( iLimit ){
++    /* At this point the values for the new sorter entry are stored
++    ** in an array of registers. They need to be composed into a record
++    ** and inserted into the sorter if either (a) there are currently
++    ** less than LIMIT+OFFSET items or (b) the new record is smaller than 
++    ** the largest record currently in the sorter. If (b) is true and there
++    ** are already LIMIT+OFFSET items in the sorter, delete the largest
++    ** entry before inserting the new one. This way there are never more 
++    ** than LIMIT+OFFSET items in the sorter.
++    **
++    ** If the new record does not need to be inserted into the sorter,
++    ** jump to the next iteration of the loop. If the pSort->labelOBLopt
++    ** value is not zero, then it is a label of where to jump.  Otherwise,
++    ** just bypass the row insert logic.  See the header comment on the
++    ** sqlite3WhereOrderByLimitOptLabel() function for additional info.
++    */
++    int iCsr = pSort->iECursor;
++    sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0);
++    iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE,
++                                 iCsr, 0, regBase+nOBSat, nExpr-nOBSat);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp1(v, OP_Delete, iCsr);
++  }
++  if( regRecord==0 ){
++    regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase);
++  }
+   if( pSort->sortFlags & SORTFLAG_UseSorter ){
+     op = OP_SorterInsert;
+   }else{
+@@ -120876,33 +124624,9 @@
+   }
+   sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
+                        regBase+nOBSat, nBase-nOBSat);
+-  if( iLimit ){
+-    int addr;
+-    int r1 = 0;
+-    /* Fill the sorter until it contains LIMIT+OFFSET entries.  (The iLimit
+-    ** register is initialized with value of LIMIT+OFFSET.)  After the sorter
+-    ** fills up, delete the least entry in the sorter after each insert.
+-    ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
+-    addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
+-    sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
+-    if( pSort->bOrderedInnerLoop ){
+-      r1 = ++pParse->nMem;
+-      sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1);
+-      VdbeComment((v, "seq"));
+-    }
+-    sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
+-    if( pSort->bOrderedInnerLoop ){
+-      /* If the inner loop is driven by an index such that values from
+-      ** the same iteration of the inner loop are in sorted order, then
+-      ** immediately jump to the next iteration of an inner loop if the
+-      ** entry from the current iteration does not fit into the top
+-      ** LIMIT+OFFSET entries of the sorter. */
+-      int iBrk = sqlite3VdbeCurrentAddr(v) + 2;
+-      sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1);
+-      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+-      VdbeCoverage(v);
+-    }
+-    sqlite3VdbeJumpHere(v, addr);
++  if( iSkip ){
++    sqlite3VdbeChangeP2(v, iSkip,
++         pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
+   }
+ }
+ 
+@@ -120948,7 +124672,88 @@
+   sqlite3ReleaseTempReg(pParse, r1);
+ }
+ 
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+ /*
++** This function is called as part of inner-loop generation for a SELECT
++** statement with an ORDER BY that is not optimized by an index. It 
++** determines the expressions, if any, that the sorter-reference 
++** optimization should be used for. The sorter-reference optimization
++** is used for SELECT queries like:
++**
++**   SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10
++**
++** If the optimization is used for expression "bigblob", then instead of
++** storing values read from that column in the sorter records, the PK of
++** the row from table t1 is stored instead. Then, as records are extracted from
++** the sorter to return to the user, the required value of bigblob is
++** retrieved directly from table t1. If the values are very large, this 
++** can be more efficient than storing them directly in the sorter records.
++**
++** The ExprList_item.bSorterRef flag is set for each expression in pEList 
++** for which the sorter-reference optimization should be enabled. 
++** Additionally, the pSort->aDefer[] array is populated with entries
++** for all cursors required to evaluate all selected expressions. Finally.
++** output variable (*ppExtra) is set to an expression list containing
++** expressions for all extra PK values that should be stored in the
++** sorter records.
++*/
++static void selectExprDefer(
++  Parse *pParse,                  /* Leave any error here */
++  SortCtx *pSort,                 /* Sorter context */
++  ExprList *pEList,               /* Expressions destined for sorter */
++  ExprList **ppExtra              /* Expressions to append to sorter record */
++){
++  int i;
++  int nDefer = 0;
++  ExprList *pExtra = 0;
++  for(i=0; i<pEList->nExpr; i++){
++    struct ExprList_item *pItem = &pEList->a[i];
++    if( pItem->u.x.iOrderByCol==0 ){
++      Expr *pExpr = pItem->pExpr;
++      Table *pTab = pExpr->y.pTab;
++      if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
++       && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
++      ){
++        int j;
++        for(j=0; j<nDefer; j++){
++          if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
++        }
++        if( j==nDefer ){
++          if( nDefer==ArraySize(pSort->aDefer) ){
++            continue;
++          }else{
++            int nKey = 1;
++            int k;
++            Index *pPk = 0;
++            if( !HasRowid(pTab) ){
++              pPk = sqlite3PrimaryKeyIndex(pTab);
++              nKey = pPk->nKeyCol;
++            }
++            for(k=0; k<nKey; k++){
++              Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
++              if( pNew ){
++                pNew->iTable = pExpr->iTable;
++                pNew->y.pTab = pExpr->y.pTab;
++                pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
++                pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
++              }
++            }
++            pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
++            pSort->aDefer[nDefer].iCsr = pExpr->iTable;
++            pSort->aDefer[nDefer].nKey = nKey;
++            nDefer++;
++          }
++        }
++        pItem->bSorterRef = 1;
++      }
++    }
++  }
++  pSort->nDefer = (u8)nDefer;
++  *ppExtra = pExtra;
++}
++#endif
++
++/*
+ ** This routine generates the code for the inside of the inner loop
+ ** of a SELECT.
+ **
+@@ -120974,6 +124779,7 @@
+   int iParm = pDest->iSDParm; /* First argument to disposal method */
+   int nResultCol;             /* Number of result columns */
+   int nPrefixReg = 0;         /* Number of extra registers before regResult */
++  RowLoadInfo sRowLoadInfo;   /* Info for deferred row loading */
+ 
+   /* Usually, regResult is the first cell in an array of memory cells
+   ** containing the current result row. In this case regOrig is set to the
+@@ -121020,10 +124826,14 @@
+       VdbeComment((v, "%s", p->pEList->a[i].zName));
+     }
+   }else if( eDest!=SRT_Exists ){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    ExprList *pExtra = 0;
++#endif
+     /* If the destination is an EXISTS(...) expression, the actual
+     ** values returned by the SELECT are not required.
+     */
+-    u8 ecelFlags;
++    u8 ecelFlags;    /* "ecel" is an abbreviation of "ExprCodeExprList" */
++    ExprList *pEList;
+     if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
+       ecelFlags = SQLITE_ECEL_DUP;
+     }else{
+@@ -121037,6 +124847,7 @@
+       ** This allows the p->pEList field to be omitted from the sorted record,
+       ** saving space and CPU cycles.  */
+       ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
++
+       for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
+         int j;
+         if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
+@@ -121043,12 +124854,61 @@
+           p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
+         }
+       }
+-      regOrig = 0;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++      selectExprDefer(pParse, pSort, p->pEList, &pExtra);
++      if( pExtra && pParse->db->mallocFailed==0 ){
++        /* If there are any extra PK columns to add to the sorter records,
++        ** allocate extra memory cells and adjust the OpenEphemeral 
++        ** instruction to account for the larger records. This is only
++        ** required if there are one or more WITHOUT ROWID tables with
++        ** composite primary keys in the SortCtx.aDefer[] array.  */
++        VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
++        pOp->p2 += (pExtra->nExpr - pSort->nDefer);
++        pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer);
++        pParse->nMem += pExtra->nExpr;
++      }
++#endif
++
++      /* Adjust nResultCol to account for columns that are omitted
++      ** from the sorter by the optimizations in this branch */
++      pEList = p->pEList;
++      for(i=0; i<pEList->nExpr; i++){
++        if( pEList->a[i].u.x.iOrderByCol>0
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++         || pEList->a[i].bSorterRef
++#endif
++        ){
++          nResultCol--;
++          regOrig = 0;
++        }
++      }
++
++      testcase( regOrig );
++      testcase( eDest==SRT_Set );
++      testcase( eDest==SRT_Mem );
++      testcase( eDest==SRT_Coroutine );
++      testcase( eDest==SRT_Output );
+       assert( eDest==SRT_Set || eDest==SRT_Mem 
+            || eDest==SRT_Coroutine || eDest==SRT_Output );
+     }
+-    nResultCol = sqlite3ExprCodeExprList(pParse,p->pEList,regResult,
+-                                         0,ecelFlags);
++    sRowLoadInfo.regResult = regResult;
++    sRowLoadInfo.ecelFlags = ecelFlags;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    sRowLoadInfo.pExtra = pExtra;
++    sRowLoadInfo.regExtraResult = regResult + nResultCol;
++    if( pExtra ) nResultCol += pExtra->nExpr;
++#endif
++    if( p->iLimit
++     && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 
++     && nPrefixReg>0
++    ){
++      assert( pSort!=0 );
++      assert( hasDistinct==0 );
++      pSort->pDeferredRowLoad = &sRowLoadInfo;
++      regOrig = 0;
++    }else{
++      innerLoopLoadRow(pParse, p, &sRowLoadInfo);
++    }
+   }
+ 
+   /* If the DISTINCT keyword was present on the SELECT statement
+@@ -121164,7 +125024,8 @@
+       }
+ #endif
+       if( pSort ){
+-        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg);
++        assert( regResult==regOrig );
++        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg);
+       }else{
+         int r2 = sqlite3GetTempReg(pParse);
+         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
+@@ -121194,7 +125055,6 @@
+         assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
+         sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, 
+             r1, pDest->zAffSdst, nResultCol);
+-        sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+         sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+         sqlite3ReleaseTempReg(pParse, r1);
+       }
+@@ -121238,7 +125098,6 @@
+         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
+-        sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+       }
+       break;
+     }
+@@ -121381,7 +125240,7 @@
+ ** function is responsible for seeing that this structure is eventually
+ ** freed.
+ */
+-static KeyInfo *keyInfoFromExprList(
++SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(
+   Parse *pParse,       /* Parsing context */
+   ExprList *pList,     /* Form the KeyInfo object from this ExprList */
+   int iStart,          /* Begin with this column of pList */
+@@ -121431,11 +125290,7 @@
+ ** is determined by the zUsage argument.
+ */
+ static void explainTempTable(Parse *pParse, const char *zUsage){
+-  if( pParse->explain==2 ){
+-    Vdbe *v = pParse->pVdbe;
+-    char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
++  ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage));
+ }
+ 
+ /*
+@@ -121453,42 +125308,6 @@
+ # define explainSetInteger(y,z)
+ #endif
+ 
+-#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
+-/*
+-** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
+-** is a no-op. Otherwise, it adds a single row of output to the EQP result,
+-** where the caption is of one of the two forms:
+-**
+-**   "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
+-**   "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
+-**
+-** where iSub1 and iSub2 are the integers passed as the corresponding
+-** function parameters, and op is the text representation of the parameter
+-** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
+-** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is 
+-** false, or the second form if it is true.
+-*/
+-static void explainComposite(
+-  Parse *pParse,                  /* Parse context */
+-  int op,                         /* One of TK_UNION, TK_EXCEPT etc. */
+-  int iSub1,                      /* Subquery id 1 */
+-  int iSub2,                      /* Subquery id 2 */
+-  int bUseTmp                     /* True if a temp table was used */
+-){
+-  assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
+-  if( pParse->explain==2 ){
+-    Vdbe *v = pParse->pVdbe;
+-    char *zMsg = sqlite3MPrintf(
+-        pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
+-        bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
+-    );
+-    sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
+-  }
+-}
+-#else
+-/* No-op versions of the explainXXX() functions and macros. */
+-# define explainComposite(v,w,x,y,z)
+-#endif
+ 
+ /*
+ ** If the inner loop was generated using a non-null pOrderBy argument,
+@@ -121506,7 +125325,7 @@
+   Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
+   int addrBreak = pSort->labelDone;            /* Jump here to exit loop */
+   int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
+-  int addr;
++  int addr;                       /* Top of output loop. Jump for Next. */
+   int addrOnce = 0;
+   int iTab;
+   ExprList *pOrderBy = pSort->pOrderBy;
+@@ -121515,11 +125334,11 @@
+   int regRow;
+   int regRowid;
+   int iCol;
+-  int nKey;
++  int nKey;                       /* Number of key columns in sorter record */
+   int iSortTab;                   /* Sorter cursor to read from */
+-  int nSortData;                  /* Trailing values to read from sorter */
+   int i;
+   int bSeq;                       /* True if sorter record includes seq. no. */
++  int nRefKey = 0;
+   struct ExprList_item *aOutEx = p->pEList->a;
+ 
+   assert( addrBreak<0 );
+@@ -121528,15 +125347,24 @@
+     sqlite3VdbeGoto(v, addrBreak);
+     sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
+   }
++
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  /* Open any cursors needed for sorter-reference expressions */
++  for(i=0; i<pSort->nDefer; i++){
++    Table *pTab = pSort->aDefer[i].pTab;
++    int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
++    sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead);
++    nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey);
++  }
++#endif
++
+   iTab = pSort->iECursor;
+   if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
+     regRowid = 0;
+     regRow = pDest->iSdst;
+-    nSortData = nColumn;
+   }else{
+     regRowid = sqlite3GetTempReg(pParse);
+     regRow = sqlite3GetTempRange(pParse, nColumn);
+-    nSortData = nColumn;
+   }
+   nKey = pOrderBy->nExpr - pSort->nOBSat;
+   if( pSort->sortFlags & SORTFLAG_UseSorter ){
+@@ -121545,7 +125373,8 @@
+     if( pSort->labelBkOut ){
+       addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+     }
+-    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
++    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, 
++        nKey+1+nColumn+nRefKey);
+     if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+     addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
+     VdbeCoverage(v);
+@@ -121558,19 +125387,60 @@
+     iSortTab = iTab;
+     bSeq = 1;
+   }
+-  for(i=0, iCol=nKey+bSeq-1; i<nSortData; i++){
++  for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( aOutEx[i].bSorterRef ) continue;
++#endif
+     if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
+   }
+-  for(i=nSortData-1; i>=0; i--){
+-    int iRead;
+-    if( aOutEx[i].u.x.iOrderByCol ){
+-      iRead = aOutEx[i].u.x.iOrderByCol-1;
+-    }else{
+-      iRead = iCol--;
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++  if( pSort->nDefer ){
++    int iKey = iCol+1;
++    int regKey = sqlite3GetTempRange(pParse, nRefKey);
++
++    for(i=0; i<pSort->nDefer; i++){
++      int iCsr = pSort->aDefer[i].iCsr;
++      Table *pTab = pSort->aDefer[i].pTab;
++      int nKey = pSort->aDefer[i].nKey;
++
++      sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
++      if( HasRowid(pTab) ){
++        sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey);
++        sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, 
++            sqlite3VdbeCurrentAddr(v)+1, regKey);
++      }else{
++        int k;
++        int iJmp;
++        assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey );
++        for(k=0; k<nKey; k++){
++          sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey+k);
++        }
++        iJmp = sqlite3VdbeCurrentAddr(v);
++        sqlite3VdbeAddOp4Int(v, OP_SeekGE, iCsr, iJmp+2, regKey, nKey);
++        sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, iJmp+3, regKey, nKey);
++        sqlite3VdbeAddOp1(v, OP_NullRow, iCsr);
++      }
+     }
+-    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
+-    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
++    sqlite3ReleaseTempRange(pParse, regKey, nRefKey);
+   }
++#endif
++  for(i=nColumn-1; i>=0; i--){
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    if( aOutEx[i].bSorterRef ){
++      sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i);
++    }else
++#endif
++    {
++      int iRead;
++      if( aOutEx[i].u.x.iOrderByCol ){
++        iRead = aOutEx[i].u.x.iOrderByCol-1;
++      }else{
++        iRead = iCol--;
++      }
++      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
++      VdbeComment((v, "%s", aOutEx[i].zName?aOutEx[i].zName : aOutEx[i].zSpan));
++    }
++  }
+   switch( eDest ){
+     case SRT_Table:
+     case SRT_EphemTab: {
+@@ -121584,7 +125454,6 @@
+       assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
+                         pDest->zAffSdst, nColumn);
+-      sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
+       sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
+       break;
+     }
+@@ -121599,7 +125468,6 @@
+       testcase( eDest==SRT_Coroutine );
+       if( eDest==SRT_Output ){
+         sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
+-        sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
+       }else{
+         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
+       }
+@@ -121719,7 +125587,7 @@
+         break;
+       }
+ 
+-      assert( pTab && pExpr->pTab==pTab );
++      assert( pTab && pExpr->y.pTab==pTab );
+       if( pS ){
+         /* The "table" is actually a sub-select or a view in the FROM clause
+         ** of the SELECT statement. Return the declaration type and origin
+@@ -121887,7 +125755,7 @@
+   }
+ #endif
+ 
+-  if( pParse->colNamesSet || db->mallocFailed ) return;
++  if( pParse->colNamesSet ) return;
+   /* Column names are determined by the left-most term of a compound select */
+   while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+   SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
+@@ -121904,7 +125772,7 @@
+ 
+     assert( p!=0 );
+     assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
+-    assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
++    assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
+     if( pEList->a[i].zName ){
+       /* An AS clause always takes first priority */
+       char *zName = pEList->a[i].zName;
+@@ -121912,7 +125780,7 @@
+     }else if( srcName && p->op==TK_COLUMN ){
+       char *zCol;
+       int iCol = p->iColumn;
+-      pTab = p->pTab;
++      pTab = p->y.pTab;
+       assert( pTab!=0 );
+       if( iCol<0 ) iCol = pTab->iPKey;
+       assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+@@ -122003,7 +125871,7 @@
+       if( pColExpr->op==TK_COLUMN ){
+         /* For columns use the column name name */
+         int iCol = pColExpr->iColumn;
+-        Table *pTab = pColExpr->pTab;
++        Table *pTab = pColExpr->y.pTab;
+         assert( pTab!=0 );
+         if( iCol<0 ) iCol = pTab->iPKey;
+         zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
+@@ -122200,7 +126068,6 @@
+   ** The current implementation interprets "LIMIT 0" to mean
+   ** no rows.
+   */
+-  sqlite3ExprCacheClear(pParse);
+   if( pLimit ){
+     assert( pLimit->op==TK_LIMIT );
+     assert( pLimit->pLeft!=0 );
+@@ -122358,6 +126225,13 @@
+   Expr *pLimit;                 /* Saved LIMIT and OFFSET */
+   int regLimit, regOffset;      /* Registers used by LIMIT and OFFSET */
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( p->pWin ){
++    sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
++    return;
++  }
++#endif
++
+   /* Obtain authorization to do a recursive query */
+   if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
+ 
+@@ -122414,6 +126288,7 @@
+ 
+   /* Store the results of the setup-query in Queue. */
+   pSetup->pNext = 0;
++  ExplainQueryPlan((pParse, 1, "SETUP"));
+   rc = sqlite3Select(pParse, pSetup, &destQueue);
+   pSetup->pNext = p;
+   if( rc ) goto end_of_recursive_query;
+@@ -122448,6 +126323,7 @@
+     sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
+   }else{
+     p->pPrior = 0;
++    ExplainQueryPlan((pParse, 1, "RECURSIVE STEP"));
+     sqlite3Select(pParse, p, &destQueue);
+     assert( p->pPrior==0 );
+     p->pPrior = pSetup;
+@@ -122493,10 +126369,9 @@
+   Select *p,            /* The right-most of SELECTs to be coded */
+   SelectDest *pDest     /* What to do with query results */
+ ){
+-  Select *pPrior;
+-  Select *pRightmost = p;
+   int nRow = 1;
+   int rc = 0;
++  int bShowAll = p->pLimit==0;
+   assert( p->selFlags & SF_MultiValue );
+   do{
+     assert( p->selFlags & SF_Values );
+@@ -122505,14 +126380,13 @@
+     if( p->pPrior==0 ) break;
+     assert( p->pPrior->pNext==p );
+     p = p->pPrior;
+-    nRow++;
++    nRow += bShowAll;
+   }while(1);
++  ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow,
++                    nRow==1 ? "" : "S"));
+   while( p ){
+-    pPrior = p->pPrior;
+-    p->pPrior = 0;
+-    rc = sqlite3Select(pParse, p, pDest);
+-    p->pPrior = pPrior;
+-    if( rc || pRightmost->pLimit ) break;
++    selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1);
++    if( !bShowAll ) break;
+     p->nSelectRow = nRow;
+     p = p->pNext;
+   }
+@@ -122561,10 +126435,6 @@
+   SelectDest dest;      /* Alternative data destination */
+   Select *pDelete = 0;  /* Chain of simple selects to delete */
+   sqlite3 *db;          /* Database connection */
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iSub1 = 0;        /* EQP id of left-hand query */
+-  int iSub2 = 0;        /* EQP id of right-hand query */
+-#endif
+ 
+   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
+   ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
+@@ -122615,217 +126485,231 @@
+   */
+   if( p->pOrderBy ){
+     return multiSelectOrderBy(pParse, p, pDest);
+-  }else
++  }else{
+ 
+-  /* Generate code for the left and right SELECT statements.
+-  */
+-  switch( p->op ){
+-    case TK_ALL: {
+-      int addr = 0;
+-      int nLimit;
+-      assert( !pPrior->pLimit );
+-      pPrior->iLimit = p->iLimit;
+-      pPrior->iOffset = p->iOffset;
+-      pPrior->pLimit = p->pLimit;
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &dest);
+-      p->pLimit = 0;
+-      if( rc ){
+-        goto multi_select_end;
++#ifndef SQLITE_OMIT_EXPLAIN
++    if( pPrior->pPrior==0 ){
++      ExplainQueryPlan((pParse, 1, "COMPOUND QUERY"));
++      ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
++    }
++#endif
++
++    /* Generate code for the left and right SELECT statements.
++    */
++    switch( p->op ){
++      case TK_ALL: {
++        int addr = 0;
++        int nLimit;
++        assert( !pPrior->pLimit );
++        pPrior->iLimit = p->iLimit;
++        pPrior->iOffset = p->iOffset;
++        pPrior->pLimit = p->pLimit;
++        rc = sqlite3Select(pParse, pPrior, &dest);
++        p->pLimit = 0;
++        if( rc ){
++          goto multi_select_end;
++        }
++        p->pPrior = 0;
++        p->iLimit = pPrior->iLimit;
++        p->iOffset = pPrior->iOffset;
++        if( p->iLimit ){
++          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
++          VdbeComment((v, "Jump ahead if LIMIT reached"));
++          if( p->iOffset ){
++            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
++                              p->iLimit, p->iOffset+1, p->iOffset);
++          }
++        }
++        ExplainQueryPlan((pParse, 1, "UNION ALL"));
++        rc = sqlite3Select(pParse, p, &dest);
++        testcase( rc!=SQLITE_OK );
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
++        if( pPrior->pLimit
++         && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
++         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
++        ){
++          p->nSelectRow = sqlite3LogEst((u64)nLimit);
++        }
++        if( addr ){
++          sqlite3VdbeJumpHere(v, addr);
++        }
++        break;
+       }
+-      p->pPrior = 0;
+-      p->iLimit = pPrior->iLimit;
+-      p->iOffset = pPrior->iOffset;
+-      if( p->iLimit ){
+-        addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+-        VdbeComment((v, "Jump ahead if LIMIT reached"));
+-        if( p->iOffset ){
+-          sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+-                            p->iLimit, p->iOffset+1, p->iOffset);
++      case TK_EXCEPT:
++      case TK_UNION: {
++        int unionTab;    /* Cursor number of the temp table holding result */
++        u8 op = 0;       /* One of the SRT_ operations to apply to self */
++        int priorOp;     /* The SRT_ operation to apply to prior selects */
++        Expr *pLimit;    /* Saved values of p->nLimit  */
++        int addr;
++        SelectDest uniondest;
++  
++        testcase( p->op==TK_EXCEPT );
++        testcase( p->op==TK_UNION );
++        priorOp = SRT_Union;
++        if( dest.eDest==priorOp ){
++          /* We can reuse a temporary table generated by a SELECT to our
++          ** right.
++          */
++          assert( p->pLimit==0 );      /* Not allowed on leftward elements */
++          unionTab = dest.iSDParm;
++        }else{
++          /* We will need to create our own temporary table to hold the
++          ** intermediate results.
++          */
++          unionTab = pParse->nTab++;
++          assert( p->pOrderBy==0 );
++          addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
++          assert( p->addrOpenEphm[0] == -1 );
++          p->addrOpenEphm[0] = addr;
++          findRightmost(p)->selFlags |= SF_UsesEphemeral;
++          assert( p->pEList );
+         }
++  
++        /* Code the SELECT statements to our left
++        */
++        assert( !pPrior->pOrderBy );
++        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
++        rc = sqlite3Select(pParse, pPrior, &uniondest);
++        if( rc ){
++          goto multi_select_end;
++        }
++  
++        /* Code the current SELECT statement
++        */
++        if( p->op==TK_EXCEPT ){
++          op = SRT_Except;
++        }else{
++          assert( p->op==TK_UNION );
++          op = SRT_Union;
++        }
++        p->pPrior = 0;
++        pLimit = p->pLimit;
++        p->pLimit = 0;
++        uniondest.eDest = op;
++        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
++                          selectOpName(p->op)));
++        rc = sqlite3Select(pParse, p, &uniondest);
++        testcase( rc!=SQLITE_OK );
++        /* Query flattening in sqlite3Select() might refill p->pOrderBy.
++        ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
++        sqlite3ExprListDelete(db, p->pOrderBy);
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        p->pOrderBy = 0;
++        if( p->op==TK_UNION ){
++          p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
++        }
++        sqlite3ExprDelete(db, p->pLimit);
++        p->pLimit = pLimit;
++        p->iLimit = 0;
++        p->iOffset = 0;
++  
++        /* Convert the data in the temporary table into whatever form
++        ** it is that we currently need.
++        */
++        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
++        if( dest.eDest!=priorOp ){
++          int iCont, iBreak, iStart;
++          assert( p->pEList );
++          iBreak = sqlite3VdbeMakeLabel(v);
++          iCont = sqlite3VdbeMakeLabel(v);
++          computeLimitRegisters(pParse, p, iBreak);
++          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
++          iStart = sqlite3VdbeCurrentAddr(v);
++          selectInnerLoop(pParse, p, unionTab,
++                          0, 0, &dest, iCont, iBreak);
++          sqlite3VdbeResolveLabel(v, iCont);
++          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
++          sqlite3VdbeResolveLabel(v, iBreak);
++          sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
++        }
++        break;
+       }
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &dest);
+-      testcase( rc!=SQLITE_OK );
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+-      if( pPrior->pLimit
+-       && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
+-       && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) 
+-      ){
+-        p->nSelectRow = sqlite3LogEst((u64)nLimit);
+-      }
+-      if( addr ){
+-        sqlite3VdbeJumpHere(v, addr);
+-      }
+-      break;
+-    }
+-    case TK_EXCEPT:
+-    case TK_UNION: {
+-      int unionTab;    /* Cursor number of the temporary table holding result */
+-      u8 op = 0;       /* One of the SRT_ operations to apply to self */
+-      int priorOp;     /* The SRT_ operation to apply to prior selects */
+-      Expr *pLimit;    /* Saved values of p->nLimit  */
+-      int addr;
+-      SelectDest uniondest;
+-
+-      testcase( p->op==TK_EXCEPT );
+-      testcase( p->op==TK_UNION );
+-      priorOp = SRT_Union;
+-      if( dest.eDest==priorOp ){
+-        /* We can reuse a temporary table generated by a SELECT to our
+-        ** right.
++      default: assert( p->op==TK_INTERSECT ); {
++        int tab1, tab2;
++        int iCont, iBreak, iStart;
++        Expr *pLimit;
++        int addr;
++        SelectDest intersectdest;
++        int r1;
++  
++        /* INTERSECT is different from the others since it requires
++        ** two temporary tables.  Hence it has its own case.  Begin
++        ** by allocating the tables we will need.
+         */
+-        assert( p->pLimit==0 );      /* Not allowed on leftward elements */
+-        unionTab = dest.iSDParm;
+-      }else{
+-        /* We will need to create our own temporary table to hold the
+-        ** intermediate results.
+-        */
+-        unionTab = pParse->nTab++;
++        tab1 = pParse->nTab++;
++        tab2 = pParse->nTab++;
+         assert( p->pOrderBy==0 );
+-        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
++  
++        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
+         assert( p->addrOpenEphm[0] == -1 );
+         p->addrOpenEphm[0] = addr;
+         findRightmost(p)->selFlags |= SF_UsesEphemeral;
+         assert( p->pEList );
+-      }
+-
+-      /* Code the SELECT statements to our left
+-      */
+-      assert( !pPrior->pOrderBy );
+-      sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &uniondest);
+-      if( rc ){
+-        goto multi_select_end;
+-      }
+-
+-      /* Code the current SELECT statement
+-      */
+-      if( p->op==TK_EXCEPT ){
+-        op = SRT_Except;
+-      }else{
+-        assert( p->op==TK_UNION );
+-        op = SRT_Union;
+-      }
+-      p->pPrior = 0;
+-      pLimit = p->pLimit;
+-      p->pLimit = 0;
+-      uniondest.eDest = op;
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &uniondest);
+-      testcase( rc!=SQLITE_OK );
+-      /* Query flattening in sqlite3Select() might refill p->pOrderBy.
+-      ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
+-      sqlite3ExprListDelete(db, p->pOrderBy);
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      p->pOrderBy = 0;
+-      if( p->op==TK_UNION ){
+-        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+-      }
+-      sqlite3ExprDelete(db, p->pLimit);
+-      p->pLimit = pLimit;
+-      p->iLimit = 0;
+-      p->iOffset = 0;
+-
+-      /* Convert the data in the temporary table into whatever form
+-      ** it is that we currently need.
+-      */
+-      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
+-      if( dest.eDest!=priorOp ){
+-        int iCont, iBreak, iStart;
++  
++        /* Code the SELECTs to our left into temporary table "tab1".
++        */
++        sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
++        rc = sqlite3Select(pParse, pPrior, &intersectdest);
++        if( rc ){
++          goto multi_select_end;
++        }
++  
++        /* Code the current SELECT into temporary table "tab2"
++        */
++        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
++        assert( p->addrOpenEphm[1] == -1 );
++        p->addrOpenEphm[1] = addr;
++        p->pPrior = 0;
++        pLimit = p->pLimit;
++        p->pLimit = 0;
++        intersectdest.iSDParm = tab2;
++        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
++                          selectOpName(p->op)));
++        rc = sqlite3Select(pParse, p, &intersectdest);
++        testcase( rc!=SQLITE_OK );
++        pDelete = p->pPrior;
++        p->pPrior = pPrior;
++        if( p->nSelectRow>pPrior->nSelectRow ){
++          p->nSelectRow = pPrior->nSelectRow;
++        }
++        sqlite3ExprDelete(db, p->pLimit);
++        p->pLimit = pLimit;
++  
++        /* Generate code to take the intersection of the two temporary
++        ** tables.
++        */
+         assert( p->pEList );
+         iBreak = sqlite3VdbeMakeLabel(v);
+         iCont = sqlite3VdbeMakeLabel(v);
+         computeLimitRegisters(pParse, p, iBreak);
+-        sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
+-        iStart = sqlite3VdbeCurrentAddr(v);
+-        selectInnerLoop(pParse, p, unionTab,
++        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
++        r1 = sqlite3GetTempReg(pParse);
++        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
++        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
++        VdbeCoverage(v);
++        sqlite3ReleaseTempReg(pParse, r1);
++        selectInnerLoop(pParse, p, tab1,
+                         0, 0, &dest, iCont, iBreak);
+         sqlite3VdbeResolveLabel(v, iCont);
+-        sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
++        sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
+         sqlite3VdbeResolveLabel(v, iBreak);
+-        sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
++        sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
++        sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
++        break;
+       }
+-      break;
+     }
+-    default: assert( p->op==TK_INTERSECT ); {
+-      int tab1, tab2;
+-      int iCont, iBreak, iStart;
+-      Expr *pLimit;
+-      int addr;
+-      SelectDest intersectdest;
+-      int r1;
+-
+-      /* INTERSECT is different from the others since it requires
+-      ** two temporary tables.  Hence it has its own case.  Begin
+-      ** by allocating the tables we will need.
+-      */
+-      tab1 = pParse->nTab++;
+-      tab2 = pParse->nTab++;
+-      assert( p->pOrderBy==0 );
+-
+-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
+-      assert( p->addrOpenEphm[0] == -1 );
+-      p->addrOpenEphm[0] = addr;
+-      findRightmost(p)->selFlags |= SF_UsesEphemeral;
+-      assert( p->pEList );
+-
+-      /* Code the SELECTs to our left into temporary table "tab1".
+-      */
+-      sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
+-      explainSetInteger(iSub1, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, pPrior, &intersectdest);
+-      if( rc ){
+-        goto multi_select_end;
+-      }
+-
+-      /* Code the current SELECT into temporary table "tab2"
+-      */
+-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
+-      assert( p->addrOpenEphm[1] == -1 );
+-      p->addrOpenEphm[1] = addr;
+-      p->pPrior = 0;
+-      pLimit = p->pLimit;
+-      p->pLimit = 0;
+-      intersectdest.iSDParm = tab2;
+-      explainSetInteger(iSub2, pParse->iNextSelectId);
+-      rc = sqlite3Select(pParse, p, &intersectdest);
+-      testcase( rc!=SQLITE_OK );
+-      pDelete = p->pPrior;
+-      p->pPrior = pPrior;
+-      if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
+-      sqlite3ExprDelete(db, p->pLimit);
+-      p->pLimit = pLimit;
+-
+-      /* Generate code to take the intersection of the two temporary
+-      ** tables.
+-      */
+-      assert( p->pEList );
+-      iBreak = sqlite3VdbeMakeLabel(v);
+-      iCont = sqlite3VdbeMakeLabel(v);
+-      computeLimitRegisters(pParse, p, iBreak);
+-      sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
+-      r1 = sqlite3GetTempReg(pParse);
+-      iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+-      sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
+-      sqlite3ReleaseTempReg(pParse, r1);
+-      selectInnerLoop(pParse, p, tab1,
+-                      0, 0, &dest, iCont, iBreak);
+-      sqlite3VdbeResolveLabel(v, iCont);
+-      sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
+-      sqlite3VdbeResolveLabel(v, iBreak);
+-      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
+-      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
+-      break;
++  
++  #ifndef SQLITE_OMIT_EXPLAIN
++    if( p->pNext==0 ){
++      ExplainQueryPlanPop(pParse);
+     }
++  #endif
+   }
+-
+-  explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
+-
++  
+   /* Compute collating sequences used by 
+   ** temporary tables needed to implement the compound select.
+   ** Attach the KeyInfo structure to all temporary tables.
+@@ -122976,7 +126860,6 @@
+       r1 = sqlite3GetTempReg(pParse);
+       sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, 
+           r1, pDest->zAffSdst, pIn->nSdst);
+-      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+       sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
+                            pIn->iSdst, pIn->nSdst);
+       sqlite3ReleaseTempReg(pParse, r1);
+@@ -123019,7 +126902,6 @@
+     default: {
+       assert( pDest->eDest==SRT_Output );
+       sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+-      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+       break;
+     }
+   }
+@@ -123163,10 +127045,6 @@
+   ExprList *pOrderBy;   /* The ORDER BY clause */
+   int nOrderBy;         /* Number of terms in the ORDER BY clause */
+   int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iSub1;            /* EQP id of left-hand query */
+-  int iSub2;            /* EQP id of right-hand query */
+-#endif
+ 
+   assert( p->pOrderBy!=0 );
+   assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
+@@ -123286,6 +127164,8 @@
+   sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
+   sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
+ 
++  ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op)));
++
+   /* Generate a coroutine to evaluate the SELECT statement to the
+   ** left of the compound operator - the "A" select.
+   */
+@@ -123293,7 +127173,7 @@
+   addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+   VdbeComment((v, "left SELECT"));
+   pPrior->iLimit = regLimitA;
+-  explainSetInteger(iSub1, pParse->iNextSelectId);
++  ExplainQueryPlan((pParse, 1, "LEFT"));
+   sqlite3Select(pParse, pPrior, &destA);
+   sqlite3VdbeEndCoroutine(v, regAddrA);
+   sqlite3VdbeJumpHere(v, addr1);
+@@ -123308,7 +127188,7 @@
+   savedOffset = p->iOffset;
+   p->iLimit = regLimitB;
+   p->iOffset = 0;  
+-  explainSetInteger(iSub2, pParse->iNextSelectId);
++  ExplainQueryPlan((pParse, 1, "RIGHT"));
+   sqlite3Select(pParse, p, &destB);
+   p->iLimit = savedLimit;
+   p->iOffset = savedOffset;
+@@ -123420,7 +127300,7 @@
+ 
+   /*** TBD:  Insert subroutine calls to close cursors on incomplete
+   **** subqueries ****/
+-  explainComposite(pParse, p->op, iSub1, iSub2, 0);
++  ExplainQueryPlanPop(pParse);
+   return pParse->nErr!=0;
+ }
+ #endif
+@@ -123476,7 +127356,7 @@
+       Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr;
+       Expr ifNullRow;
+       assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr );
+-      assert( pExpr->pLeft==0 && pExpr->pRight==0 );
++      assert( pExpr->pRight==0 );
+       if( sqlite3ExprIsVector(pCopy) ){
+         sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
+       }else{
+@@ -123690,7 +127570,11 @@
+ **        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
+ **        return the value X for which Y was maximal.)
+ **
++**  (25)  If either the subquery or the parent query contains a window
++**        function in the select list or ORDER BY clause, flattening
++**        is not attempted.
+ **
++**
+ ** In this routine, the "p" parameter is a pointer to the outer query.
+ ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
+ ** uses aggregates.
+@@ -123733,6 +127617,10 @@
+   pSub = pSubitem->pSelect;
+   assert( pSub!=0 );
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( p->pWin || pSub->pWin ) return 0;                  /* Restriction (25) */
++#endif
++
+   pSubSrc = pSub->pSrc;
+   assert( pSubSrc );
+   /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
+@@ -123843,8 +127731,8 @@
+   assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );
+ 
+   /***** If we reach this point, flattening is permitted. *****/
+-  SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
+-                   pSub->zSelName, pSub, iFrom));
++  SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
++                   pSub->selId, pSub, iFrom));
+ 
+   /* Authorize the subquery */
+   pParse->zAuthContext = pSubitem->zName;
+@@ -123895,7 +127783,6 @@
+     p->pPrior = 0;
+     p->pLimit = 0;
+     pNew = sqlite3SelectDup(db, p, 0);
+-    sqlite3SelectSetName(pNew, pSub->zSelName);
+     p->pLimit = pLimit;
+     p->pOrderBy = pOrderBy;
+     p->pSrc = pSrc;
+@@ -123907,9 +127794,8 @@
+       if( pPrior ) pPrior->pNext = pNew;
+       pNew->pNext = p;
+       p->pPrior = pNew;
+-      SELECTTRACE(2,pParse,p,
+-         ("compound-subquery flattener creates %s.%p as peer\n",
+-         pNew->zSelName, pNew));
++      SELECTTRACE(2,pParse,p,("compound-subquery flattener"
++                              " creates %u as peer\n",pNew->selId));
+     }
+     if( db->mallocFailed ) return 1;
+   }
+@@ -124094,8 +127980,184 @@
+ }
+ #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
+ 
++/*
++** A structure to keep track of all of the column values that are fixed to
++** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
++*/
++typedef struct WhereConst WhereConst;
++struct WhereConst {
++  Parse *pParse;   /* Parsing context */
++  int nConst;      /* Number for COLUMN=CONSTANT terms */
++  int nChng;       /* Number of times a constant is propagated */
++  Expr **apExpr;   /* [i*2] is COLUMN and [i*2+1] is VALUE */
++};
+ 
++/*
++** Add a new entry to the pConst object.  Except, do not add duplicate
++** pColumn entires.
++*/
++static void constInsert(
++  WhereConst *pConst,      /* The WhereConst into which we are inserting */
++  Expr *pColumn,           /* The COLUMN part of the constraint */
++  Expr *pValue             /* The VALUE part of the constraint */
++){
++  int i;
++  assert( pColumn->op==TK_COLUMN );
+ 
++  /* 2018-10-25 ticket [cf5ed20f]
++  ** Make sure the same pColumn is not inserted more than once */
++  for(i=0; i<pConst->nConst; i++){
++    const Expr *pExpr = pConst->apExpr[i*2];
++    assert( pExpr->op==TK_COLUMN );
++    if( pExpr->iTable==pColumn->iTable
++     && pExpr->iColumn==pColumn->iColumn
++    ){
++      return;  /* Already present.  Return without doing anything. */
++    }
++  }
++
++  pConst->nConst++;
++  pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
++                         pConst->nConst*2*sizeof(Expr*));
++  if( pConst->apExpr==0 ){
++    pConst->nConst = 0;
++  }else{
++    if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft;
++    pConst->apExpr[pConst->nConst*2-2] = pColumn;
++    pConst->apExpr[pConst->nConst*2-1] = pValue;
++  }
++}
++
++/*
++** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE
++** is a constant expression and where the term must be true because it
++** is part of the AND-connected terms of the expression.  For each term
++** found, add it to the pConst structure.
++*/
++static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
++  Expr *pRight, *pLeft;
++  if( pExpr==0 ) return;
++  if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
++  if( pExpr->op==TK_AND ){
++    findConstInWhere(pConst, pExpr->pRight);
++    findConstInWhere(pConst, pExpr->pLeft);
++    return;
++  }
++  if( pExpr->op!=TK_EQ ) return;
++  pRight = pExpr->pRight;
++  pLeft = pExpr->pLeft;
++  assert( pRight!=0 );
++  assert( pLeft!=0 );
++  if( pRight->op==TK_COLUMN
++   && !ExprHasProperty(pRight, EP_FixedCol)
++   && sqlite3ExprIsConstant(pLeft)
++   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
++  ){
++    constInsert(pConst, pRight, pLeft);
++  }else
++  if( pLeft->op==TK_COLUMN
++   && !ExprHasProperty(pLeft, EP_FixedCol)
++   && sqlite3ExprIsConstant(pRight)
++   && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight))
++  ){
++    constInsert(pConst, pLeft, pRight);
++  }
++}
++
++/*
++** This is a Walker expression callback.  pExpr is a candidate expression
++** to be replaced by a value.  If pExpr is equivalent to one of the
++** columns named in pWalker->u.pConst, then overwrite it with its
++** corresponding value.
++*/
++static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){
++  int i;
++  WhereConst *pConst;
++  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
++  if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue;
++  pConst = pWalker->u.pConst;
++  for(i=0; i<pConst->nConst; i++){
++    Expr *pColumn = pConst->apExpr[i*2];
++    if( pColumn==pExpr ) continue;
++    if( pColumn->iTable!=pExpr->iTable ) continue;
++    if( pColumn->iColumn!=pExpr->iColumn ) continue;
++    /* A match is found.  Add the EP_FixedCol property */
++    pConst->nChng++;
++    ExprClearProperty(pExpr, EP_Leaf);
++    ExprSetProperty(pExpr, EP_FixedCol);
++    assert( pExpr->pLeft==0 );
++    pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0);
++    break;
++  }
++  return WRC_Prune;
++}
++
++/*
++** The WHERE-clause constant propagation optimization.
++**
++** If the WHERE clause contains terms of the form COLUMN=CONSTANT or
++** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level
++** AND-connected terms that are not part of a ON clause from a LEFT JOIN)
++** then throughout the query replace all other occurrences of COLUMN
++** with CONSTANT within the WHERE clause.
++**
++** For example, the query:
++**
++**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b
++**
++** Is transformed into
++**
++**      SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39
++**
++** Return true if any transformations where made and false if not.
++**
++** Implementation note:  Constant propagation is tricky due to affinity
++** and collating sequence interactions.  Consider this example:
++**
++**    CREATE TABLE t1(a INT,b TEXT);
++**    INSERT INTO t1 VALUES(123,'0123');
++**    SELECT * FROM t1 WHERE a=123 AND b=a;
++**    SELECT * FROM t1 WHERE a=123 AND b=123;
++**
++** The two SELECT statements above should return different answers.  b=a
++** is alway true because the comparison uses numeric affinity, but b=123
++** is false because it uses text affinity and '0123' is not the same as '123'.
++** To work around this, the expression tree is not actually changed from
++** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol
++** and the "123" value is hung off of the pLeft pointer.  Code generator
++** routines know to generate the constant "123" instead of looking up the
++** column value.  Also, to avoid collation problems, this optimization is
++** only attempted if the "a=123" term uses the default BINARY collation.
++*/
++static int propagateConstants(
++  Parse *pParse,   /* The parsing context */
++  Select *p        /* The query in which to propagate constants */
++){
++  WhereConst x;
++  Walker w;
++  int nChng = 0;
++  x.pParse = pParse;
++  do{
++    x.nConst = 0;
++    x.nChng = 0;
++    x.apExpr = 0;
++    findConstInWhere(&x, p->pWhere);
++    if( x.nConst ){
++      memset(&w, 0, sizeof(w));
++      w.pParse = pParse;
++      w.xExprCallback = propagateConstantExprRewrite;
++      w.xSelectCallback = sqlite3SelectWalkNoop;
++      w.xSelectCallback2 = 0;
++      w.walkerDepth = 0;
++      w.u.pConst = &x;
++      sqlite3WalkExpr(&w, p->pWhere);
++      sqlite3DbFree(x.pParse->db, x.apExpr);
++      nChng += x.nChng;
++    }
++  }while( x.nChng );  
++  return nChng;
++}
++
+ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ /*
+ ** Make copies of relevant WHERE clause terms of the outer query into
+@@ -124124,7 +128186,7 @@
+ **   (2) The inner query is the recursive part of a common table expression.
+ **
+ **   (3) The inner query has a LIMIT clause (since the changes to the WHERE
+-**       close would change the meaning of the LIMIT).
++**       clause would change the meaning of the LIMIT).
+ **
+ **   (4) The inner query is the right operand of a LEFT JOIN and the
+ **       expression to be pushed down does not come from the ON clause
+@@ -124143,6 +128205,10 @@
+ **       But if the (b2=2) term were to be pushed down into the bb subquery,
+ **       then the (1,1,NULL) row would be suppressed.
+ **
++**   (6) The inner query features one or more window-functions (since 
++**       changes to the WHERE clause of the inner query could change the 
++**       window over which window functions are calculated).
++**
+ ** Return 0 if no changes are made and non-zero if one or more WHERE clause
+ ** terms are duplicated into the subquery.
+ */
+@@ -124158,6 +128224,10 @@
+   if( pWhere==0 ) return 0;
+   if( pSubq->selFlags & SF_Recursive ) return 0;  /* restriction (2) */
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( pSubq->pWin ) return 0;    /* restriction (6) */
++#endif
++
+ #ifdef SQLITE_DEBUG
+   /* Only the first term of a compound can have a WITH clause.  But make
+   ** sure no other terms are marked SF_Recursive in case something changes
+@@ -124604,6 +128674,35 @@
+ #endif
+ 
+ /*
++** The SrcList_item structure passed as the second argument represents a
++** sub-query in the FROM clause of a SELECT statement. This function
++** allocates and populates the SrcList_item.pTab object. If successful,
++** SQLITE_OK is returned. Otherwise, if an OOM error is encountered,
++** SQLITE_NOMEM.
++*/
++SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){
++  Select *pSel = pFrom->pSelect;
++  Table *pTab;
++
++  assert( pSel );
++  pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
++  if( pTab==0 ) return SQLITE_NOMEM;
++  pTab->nTabRef = 1;
++  if( pFrom->zAlias ){
++    pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
++  }else{
++    pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId);
++  }
++  while( pSel->pPrior ){ pSel = pSel->pPrior; }
++  sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
++  pTab->iPKey = -1;
++  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
++  pTab->tabFlags |= TF_Ephemeral;
++
++  return SQLITE_OK;
++}
++
++/*
+ ** This routine is a Walker callback for "expanding" a SELECT statement.
+ ** "Expanding" means to do the following:
+ **
+@@ -124675,19 +128774,7 @@
+       assert( pSel!=0 );
+       assert( pFrom->pTab==0 );
+       if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
+-      pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+-      if( pTab==0 ) return WRC_Abort;
+-      pTab->nTabRef = 1;
+-      if( pFrom->zAlias ){
+-        pTab->zName = sqlite3DbStrDup(db, pFrom->zAlias);
+-      }else{
+-        pTab->zName = sqlite3MPrintf(db, "subquery_%p", (void*)pTab);
+-      }
+-      while( pSel->pPrior ){ pSel = pSel->pPrior; }
+-      sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
+-      pTab->iPKey = -1;
+-      pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
+-      pTab->tabFlags |= TF_Ephemeral;
++      if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
+ #endif
+     }else{
+       /* An ordinary table or view name in the FROM clause */
+@@ -124710,7 +128797,6 @@
+         if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
+         assert( pFrom->pSelect==0 );
+         pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+-        sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
+         nCol = pTab->nCol;
+         pTab->nCol = -1;
+         sqlite3WalkSelect(pWalker, pFrom->pSelect);
+@@ -124988,7 +129074,7 @@
+   struct SrcList_item *pFrom;
+ 
+   assert( p->selFlags & SF_Resolved );
+-  assert( (p->selFlags & SF_HasTypeInfo)==0 );
++  if( p->selFlags & SF_HasTypeInfo ) return;
+   p->selFlags |= SF_HasTypeInfo;
+   pParse = pWalker->pParse;
+   pTabList = p->pSrc;
+@@ -125091,7 +129177,7 @@
+            "argument");
+         pFunc->iDistinct = -1;
+       }else{
+-        KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0);
++        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
+         sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
+                           (char*)pKeyInfo, P4_KEYINFO);
+       }
+@@ -125115,11 +129201,17 @@
+   }
+ }
+ 
++
+ /*
+ ** Update the accumulator memory cells for an aggregate based on
+ ** the current cursor position.
++**
++** If regAcc is non-zero and there are no min() or max() aggregates
++** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator
++** registers i register regAcc contains 0. The caller will take care
++** of setting and clearing regAcc.
+ */
+-static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
++static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
+   Vdbe *v = pParse->pVdbe;
+   int i;
+   int regHit = 0;
+@@ -125162,36 +129254,24 @@
+       if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+       sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
+     }
+-    sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
++    sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
+     sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
+     sqlite3VdbeChangeP5(v, (u8)nArg);
+-    sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
+     sqlite3ReleaseTempRange(pParse, regAgg, nArg);
+     if( addrNext ){
+       sqlite3VdbeResolveLabel(v, addrNext);
+-      sqlite3ExprCacheClear(pParse);
+     }
+   }
+-
+-  /* Before populating the accumulator registers, clear the column cache.
+-  ** Otherwise, if any of the required column values are already present 
+-  ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
+-  ** to pC->iMem. But by the time the value is used, the original register
+-  ** may have been used, invalidating the underlying buffer holding the
+-  ** text or blob value. See ticket [883034dcb5].
+-  **
+-  ** Another solution would be to change the OP_SCopy used to copy cached
+-  ** values to an OP_Copy.
+-  */
++  if( regHit==0 && pAggInfo->nAccumulator ){
++    regHit = regAcc;
++  }
+   if( regHit ){
+     addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
+   }
+-  sqlite3ExprCacheClear(pParse);
+   for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
+     sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
+   }
+   pAggInfo->directMode = 0;
+-  sqlite3ExprCacheClear(pParse);
+   if( addrHitTest ){
+     sqlite3VdbeJumpHere(v, addrHitTest);
+   }
+@@ -125209,14 +129289,11 @@
+ ){
+   if( pParse->explain==2 ){
+     int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx)));
+-    char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
++    sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s",
+         pTab->zName,
+         bCover ? " USING COVERING INDEX " : "",
+         bCover ? pIdx->zName : ""
+     );
+-    sqlite3VdbeAddOp4(
+-        pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
+-    );
+   }
+ }
+ #else
+@@ -125324,6 +129401,7 @@
+ ** The transformation only works if all of the following are true:
+ **
+ **   *  The subquery is a UNION ALL of two or more terms
++**   *  The subquery does not have a LIMIT clause
+ **   *  There is no WHERE or GROUP BY or HAVING clauses on the subqueries
+ **   *  The outer query is a simple count(*)
+ **
+@@ -125347,6 +129425,7 @@
+   do{
+     if( pSub->op!=TK_ALL && pSub->pPrior ) return 0;  /* Must be UNION ALL */
+     if( pSub->pWhere ) return 0;                      /* No WHERE clause */
++    if( pSub->pLimit ) return 0;                      /* No LIMIT clause */
+     if( pSub->selFlags & SF_Aggregate ) return 0;     /* Not an aggregate */
+     pSub = pSub->pPrior;                              /* Repeat over compound */
+   }while( pSub );
+@@ -125429,12 +129508,8 @@
+   ExprList *pMinMaxOrderBy = 0;  /* Added ORDER BY for min/max queries */
+   u8 minMaxFlag;                 /* Flag for min/max queries */
+ 
+-#ifndef SQLITE_OMIT_EXPLAIN
+-  int iRestoreSelectId = pParse->iSelectId;
+-  pParse->iSelectId = pParse->iNextSelectId++;
+-#endif
+-
+   db = pParse->db;
++  v = sqlite3GetVdbe(pParse);
+   if( p==0 || db->mallocFailed || pParse->nErr ){
+     return 1;
+   }
+@@ -125441,7 +129516,7 @@
+   if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
+   memset(&sAggInfo, 0, sizeof(sAggInfo));
+ #if SELECTTRACE_ENABLED
+-  SELECTTRACE(1,pParse,p, ("begin processing:\n"));
++  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
+   if( sqlite3SelectTrace & 0x100 ){
+     sqlite3TreeViewSelect(0, p, 0);
+   }
+@@ -125463,29 +129538,37 @@
+     p->selFlags &= ~SF_Distinct;
+   }
+   sqlite3SelectPrep(pParse, p, 0);
+-  memset(&sSort, 0, sizeof(sSort));
+-  sSort.pOrderBy = p->pOrderBy;
+-  pTabList = p->pSrc;
+   if( pParse->nErr || db->mallocFailed ){
+     goto select_end;
+   }
+   assert( p->pEList!=0 );
+-  isAgg = (p->selFlags & SF_Aggregate)!=0;
+ #if SELECTTRACE_ENABLED
+-  if( sqlite3SelectTrace & 0x100 ){
+-    SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
++  if( sqlite3SelectTrace & 0x104 ){
++    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
+     sqlite3TreeViewSelect(0, p, 0);
+   }
+ #endif
+ 
+-  /* Get a pointer the VDBE under construction, allocating a new VDBE if one
+-  ** does not already exist */
+-  v = sqlite3GetVdbe(pParse);
+-  if( v==0 ) goto select_end;
+   if( pDest->eDest==SRT_Output ){
+     generateColumnNames(pParse, p);
+   }
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  if( sqlite3WindowRewrite(pParse, p) ){
++    goto select_end;
++  }
++#if SELECTTRACE_ENABLED
++  if( sqlite3SelectTrace & 0x108 ){
++    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
++    sqlite3TreeViewSelect(0, p, 0);
++  }
++#endif
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++  pTabList = p->pSrc;
++  isAgg = (p->selFlags & SF_Aggregate)!=0;
++  memset(&sSort, 0, sizeof(sSort));
++  sSort.pOrderBy = p->pOrderBy;
++
+   /* Try to various optimizations (flattening subqueries, and strength
+   ** reduction of join operators) in the FROM clause up into the main query
+   */
+@@ -125574,14 +129657,46 @@
+   */
+   if( p->pPrior ){
+     rc = multiSelect(pParse, p, pDest);
+-    explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+ #if SELECTTRACE_ENABLED
+-    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
++    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
++    if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
++      sqlite3TreeViewSelect(0, p, 0);
++    }
+ #endif
++    if( p->pNext==0 ) ExplainQueryPlanPop(pParse);
+     return rc;
+   }
+ #endif
+ 
++  /* Do the WHERE-clause constant propagation optimization if this is
++  ** a join.  No need to speed time on this operation for non-join queries
++  ** as the equivalent optimization will be handled by query planner in
++  ** sqlite3WhereBegin().
++  */
++  if( pTabList->nSrc>1
++   && OptimizationEnabled(db, SQLITE_PropagateConst)
++   && propagateConstants(pParse, p)
++  ){
++#if SELECTTRACE_ENABLED
++    if( sqlite3SelectTrace & 0x100 ){
++      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
++      sqlite3TreeViewSelect(0, p, 0);
++    }
++#endif
++  }else{
++    SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
++  }
++
++#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
++  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
++   && countOfViewOptimization(pParse, p)
++  ){
++    if( db->mallocFailed ) goto select_end;
++    pEList = p->pEList;
++    pTabList = p->pSrc;
++  }
++#endif
++
+   /* For each term in the FROM clause, do two things:
+   ** (1) Authorized unreferenced tables
+   ** (2) Generate code for all sub-queries
+@@ -125655,7 +129770,8 @@
+     ){
+ #if SELECTTRACE_ENABLED
+       if( sqlite3SelectTrace & 0x100 ){
+-        SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n"));
++        SELECTTRACE(0x100,pParse,p,
++            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
+         sqlite3TreeViewSelect(0, p, 0);
+       }
+ #endif
+@@ -125689,7 +129805,7 @@
+       VdbeComment((v, "%s", pItem->pTab->zName));
+       pItem->addrFillSub = addrTop;
+       sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+-      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
++      ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId));
+       sqlite3Select(pParse, pSub, &dest);
+       pItem->pTab->nRowLogEst = pSub->nSelectRow;
+       pItem->fg.viaCoroutine = 1;
+@@ -125724,12 +129840,11 @@
+       pPrior = isSelfJoinView(pTabList, pItem);
+       if( pPrior ){
+         sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
+-        explainSetInteger(pItem->iSelectId, pPrior->iSelectId);
+         assert( pPrior->pSelect!=0 );
+         pSub->nSelectRow = pPrior->pSelect->nSelectRow;
+       }else{
+         sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+-        explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
++        ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId));
+         sqlite3Select(pParse, pSub, &dest);
+       }
+       pItem->pTab->nRowLogEst = pSub->nSelectRow;
+@@ -125760,16 +129875,6 @@
+   }
+ #endif
+ 
+-#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
+-  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
+-   && countOfViewOptimization(pParse, p)
+-  ){
+-    if( db->mallocFailed ) goto select_end;
+-    pEList = p->pEList;
+-    pTabList = p->pSrc;
+-  }
+-#endif
+-
+   /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
+   ** if the select-list is the same as the ORDER BY list, then this query
+   ** can be rewritten as a GROUP BY. In other words, this:
+@@ -125813,7 +129918,8 @@
+   */
+   if( sSort.pOrderBy ){
+     KeyInfo *pKeyInfo;
+-    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
++    pKeyInfo = sqlite3KeyInfoFromExprList(
++        pParse, sSort.pOrderBy, 0, pEList->nExpr);
+     sSort.iECursor = pParse->nTab++;
+     sSort.addrSortIndex =
+       sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+@@ -125847,9 +129953,9 @@
+   if( p->selFlags & SF_Distinct ){
+     sDistinct.tabTnct = pParse->nTab++;
+     sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+-                             sDistinct.tabTnct, 0, 0,
+-                             (char*)keyInfoFromExprList(pParse, p->pEList,0,0),
+-                             P4_KEYINFO);
++                       sDistinct.tabTnct, 0, 0,
++                       (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0),
++                       P4_KEYINFO);
+     sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+     sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
+   }else{
+@@ -125858,10 +129964,17 @@
+ 
+   if( !isAgg && pGroupBy==0 ){
+     /* No aggregate functions and no GROUP BY clause */
+-    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
++    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
++                   | (p->selFlags & SF_FixedLimit);
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    Window *pWin = p->pWin;      /* Master window object (or NULL) */
++    if( pWin ){
++      sqlite3WindowCodeInit(pParse, pWin);
++    }
++#endif
+     assert( WHERE_USE_LIMIT==SF_FixedLimit );
+-    wctrlFlags |= p->selFlags & SF_FixedLimit;
+ 
++
+     /* Begin the database scan. */
+     SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+     pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
+@@ -125875,7 +129988,7 @@
+     }
+     if( sSort.pOrderBy ){
+       sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo);
+-      sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo);
++      sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo);
+       if( sSort.nOBSat==sSort.pOrderBy->nExpr ){
+         sSort.pOrderBy = 0;
+       }
+@@ -125889,15 +130002,37 @@
+       sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
+     }
+ 
+-    /* Use the standard inner loop. */
+     assert( p->pEList==pEList );
+-    selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
+-                    sqlite3WhereContinueLabel(pWInfo),
+-                    sqlite3WhereBreakLabel(pWInfo));
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( pWin ){
++      int addrGosub = sqlite3VdbeMakeLabel(v);
++      int iCont = sqlite3VdbeMakeLabel(v);
++      int iBreak = sqlite3VdbeMakeLabel(v);
++      int regGosub = ++pParse->nMem;
+ 
+-    /* End the database scan loop.
+-    */
+-    sqlite3WhereEnd(pWInfo);
++      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
++
++      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
++      sqlite3VdbeResolveLabel(v, addrGosub);
++      VdbeNoopComment((v, "inner-loop subroutine"));
++      sSort.labelOBLopt = 0;
++      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak);
++      sqlite3VdbeResolveLabel(v, iCont);
++      sqlite3VdbeAddOp1(v, OP_Return, regGosub);
++      VdbeComment((v, "end inner-loop subroutine"));
++      sqlite3VdbeResolveLabel(v, iBreak);
++    }else
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++    {
++      /* Use the standard inner loop. */
++      selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
++          sqlite3WhereContinueLabel(pWInfo),
++          sqlite3WhereBreakLabel(pWInfo));
++
++      /* End the database scan loop.
++      */
++      sqlite3WhereEnd(pWInfo);
++    }
+   }else{
+     /* This case when there exist aggregate functions or a GROUP BY clause
+     ** or both */
+@@ -125956,7 +130091,8 @@
+     memset(&sNC, 0, sizeof(sNC));
+     sNC.pParse = pParse;
+     sNC.pSrcList = pTabList;
+-    sNC.pAggInfo = &sAggInfo;
++    sNC.uNC.pAggInfo = &sAggInfo;
++    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
+     sAggInfo.mnReg = pParse->nMem+1;
+     sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
+     sAggInfo.pGroupBy = pGroupBy;
+@@ -126025,7 +130161,7 @@
+       ** will be converted into a Noop.  
+       */
+       sAggInfo.sortingIdx = pParse->nTab++;
+-      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
++      pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
+       addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
+           sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
+           0, (char*)pKeyInfo, P4_KEYINFO);
+@@ -126044,8 +130180,6 @@
+       pParse->nMem += pGroupBy->nExpr;
+       sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
+       VdbeComment((v, "clear abort flag"));
+-      sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
+-      VdbeComment((v, "indicate accumulator empty"));
+       sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
+ 
+       /* Begin a loop that will extract all source rows in GROUP BY order.
+@@ -126091,7 +130225,6 @@
+           }
+         }
+         regBase = sqlite3GetTempRange(pParse, nCol);
+-        sqlite3ExprCacheClear(pParse);
+         sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
+         j = nGroupBy;
+         for(i=0; i<sAggInfo.nColumn; i++){
+@@ -126098,8 +130231,8 @@
+           struct AggInfo_col *pCol = &sAggInfo.aCol[i];
+           if( pCol->iSorterColumn>=j ){
+             int r1 = j + regBase;
+-            sqlite3ExprCodeGetColumnToReg(pParse, 
+-                               pCol->pTab, pCol->iColumn, pCol->iTable, r1);
++            sqlite3ExprCodeGetColumnOfTable(v,
++                               pCol->pTab, pCol->iTable, pCol->iColumn, r1);
+             j++;
+           }
+         }
+@@ -126115,8 +130248,6 @@
+         sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
+         VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
+         sAggInfo.useSortingIdx = 1;
+-        sqlite3ExprCacheClear(pParse);
+-
+       }
+ 
+       /* If the index or temporary table used by the GROUP BY sort
+@@ -126139,7 +130270,6 @@
+       ** from the previous row currently stored in a0, a1, a2...
+       */
+       addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
+-      sqlite3ExprCacheClear(pParse);
+       if( groupBySort ){
+         sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
+                           sortOut, sortPTab);
+@@ -126178,7 +130308,7 @@
+       ** the current row
+       */
+       sqlite3VdbeJumpHere(v, addr1);
+-      updateAccumulator(pParse, &sAggInfo);
++      updateAccumulator(pParse, iUseFlag, &sAggInfo);
+       sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
+       VdbeComment((v, "indicate data in accumulator"));
+ 
+@@ -126230,6 +130360,8 @@
+       */
+       sqlite3VdbeResolveLabel(v, addrReset);
+       resetAccumulator(pParse, &sAggInfo);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
++      VdbeComment((v, "indicate accumulator empty"));
+       sqlite3VdbeAddOp1(v, OP_Return, regReset);
+      
+     } /* endif pGroupBy.  Begin aggregate queries without GROUP BY: */
+@@ -126295,6 +130427,23 @@
+       }else
+ #endif /* SQLITE_OMIT_BTREECOUNT */
+       {
++        int regAcc = 0;           /* "populate accumulators" flag */
++
++        /* If there are accumulator registers but no min() or max() functions,
++        ** allocate register regAcc. Register regAcc will contain 0 the first
++        ** time the inner loop runs, and 1 thereafter. The code generated
++        ** by updateAccumulator() only updates the accumulator registers if
++        ** regAcc contains 0.  */
++        if( sAggInfo.nAccumulator ){
++          for(i=0; i<sAggInfo.nFunc; i++){
++            if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
++          }
++          if( i==sAggInfo.nFunc ){
++            regAcc = ++pParse->nMem;
++            sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
++          }
++        }
++
+         /* This case runs if the aggregate has no GROUP BY clause.  The
+         ** processing is much simpler since there is only a single row
+         ** of output.
+@@ -126316,7 +130465,8 @@
+         if( pWInfo==0 ){
+           goto select_end;
+         }
+-        updateAccumulator(pParse, &sAggInfo);
++        updateAccumulator(pParse, regAcc, &sAggInfo);
++        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
+         if( sqlite3WhereIsOrdered(pWInfo)>0 ){
+           sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
+           VdbeComment((v, "%s() by index",
+@@ -126345,6 +130495,7 @@
+   if( sSort.pOrderBy ){
+     explainTempTable(pParse,
+                      sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
++    assert( p->pEList==pEList );
+     generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
+   }
+ 
+@@ -126360,13 +130511,16 @@
+   ** successful coding of the SELECT.
+   */
+ select_end:
+-  explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+   sqlite3ExprListDelete(db, pMinMaxOrderBy);
+   sqlite3DbFree(db, sAggInfo.aCol);
+   sqlite3DbFree(db, sAggInfo.aFunc);
+ #if SELECTTRACE_ENABLED
+-  SELECTTRACE(1,pParse,p,("end processing\n"));
++  SELECTTRACE(0x1,pParse,p,("end processing\n"));
++  if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
++    sqlite3TreeViewSelect(0, p, 0);
++  }
+ #endif
++  ExplainQueryPlanPop(pParse);
+   return rc;
+ }
+ 
+@@ -126600,6 +130754,7 @@
+     sqlite3ExprListDelete(db, pTmp->pExprList);
+     sqlite3SelectDelete(db, pTmp->pSelect);
+     sqlite3IdListDelete(db, pTmp->pIdList);
++    sqlite3UpsertDelete(db, pTmp->pUpsert);
+     sqlite3DbFree(db, pTmp->zSpan);
+ 
+     sqlite3DbFree(db, pTmp);
+@@ -126755,14 +130910,16 @@
+     goto trigger_cleanup;
+   }
+   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+-  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
+-    if( !noErr ){
+-      sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+-    }else{
+-      assert( !db->init.busy );
+-      sqlite3CodeVerifySchema(pParse, iDb);
++  if( !IN_RENAME_OBJECT ){
++    if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
++      if( !noErr ){
++        sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
++      }else{
++        assert( !db->init.busy );
++        sqlite3CodeVerifySchema(pParse, iDb);
++      }
++      goto trigger_cleanup;
+     }
+-    goto trigger_cleanup;
+   }
+ 
+   /* Do not create a trigger on a system table */
+@@ -126786,7 +130943,7 @@
+   }
+ 
+ #ifndef SQLITE_OMIT_AUTHORIZATION
+-  {
++  if( !IN_RENAME_OBJECT ){
+     int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+     int code = SQLITE_CREATE_TRIGGER;
+     const char *zDb = db->aDb[iTabDb].zDbSName;
+@@ -126820,8 +130977,15 @@
+   pTrigger->pTabSchema = pTab->pSchema;
+   pTrigger->op = (u8)op;
+   pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
+-  pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
+-  pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName);
++    pTrigger->pWhen = pWhen;
++    pWhen = 0;
++  }else{
++    pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
++  }
++  pTrigger->pColumns = pColumns;
++  pColumns = 0;
+   assert( pParse->pNewTrigger==0 );
+   pParse->pNewTrigger = pTrigger;
+ 
+@@ -126870,6 +131034,14 @@
+     goto triggerfinish_cleanup;
+   }
+ 
++#ifndef SQLITE_OMIT_ALTERTABLE
++  if( IN_RENAME_OBJECT ){
++    assert( !db->init.busy );
++    pParse->pNewTrigger = pTrig;
++    pTrig = 0;
++  }else
++#endif
++
+   /* if we are not initializing,
+   ** build the sqlite_master entry
+   */
+@@ -126911,7 +131083,7 @@
+ 
+ triggerfinish_cleanup:
+   sqlite3DeleteTrigger(db, pTrig);
+-  assert( !pParse->pNewTrigger );
++  assert( IN_RENAME_OBJECT || !pParse->pNewTrigger );
+   sqlite3DeleteTriggerStep(db, pStepList);
+ }
+ 
+@@ -126958,12 +131130,13 @@
+ ** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+ */
+ static TriggerStep *triggerStepAllocate(
+-  sqlite3 *db,                /* Database connection */
++  Parse *pParse,              /* Parser context */
+   u8 op,                      /* Trigger opcode */
+   Token *pName,               /* The target name */
+   const char *zStart,         /* Start of SQL text */
+   const char *zEnd            /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+   pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
+@@ -126974,6 +131147,9 @@
+     pTriggerStep->zTarget = z;
+     pTriggerStep->op = op;
+     pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
++    if( IN_RENAME_OBJECT ){
++      sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName);
++    }
+   }
+   return pTriggerStep;
+ }
+@@ -126986,25 +131162,36 @@
+ ** body of a trigger.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
+-  sqlite3 *db,        /* The database connection */
++  Parse *pParse,      /* Parser */
+   Token *pTableName,  /* Name of the table into which we insert */
+   IdList *pColumn,    /* List of columns in pTableName to insert into */
+   Select *pSelect,    /* A SELECT statement that supplies values */
+   u8 orconf,          /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
++  Upsert *pUpsert,    /* ON CONFLICT clauses for upsert */
+   const char *zStart, /* Start of SQL text */
+   const char *zEnd    /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+   assert(pSelect != 0 || db->mallocFailed);
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName, zStart, zEnd);
++  pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pSelect = pSelect;
++      pSelect = 0;
++    }else{
++      pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->pIdList = pColumn;
++    pTriggerStep->pUpsert = pUpsert;
+     pTriggerStep->orconf = orconf;
+   }else{
++    testcase( pColumn );
+     sqlite3IdListDelete(db, pColumn);
++    testcase( pUpsert );
++    sqlite3UpsertDelete(db, pUpsert);
+   }
+   sqlite3SelectDelete(db, pSelect);
+ 
+@@ -127017,7 +131204,7 @@
+ ** sees an UPDATE statement inside the body of a CREATE TRIGGER.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
+-  sqlite3 *db,         /* The database connection */
++  Parse *pParse,          /* Parser */
+   Token *pTableName,   /* Name of the table to be updated */
+   ExprList *pEList,    /* The SET clause: list of column and new values */
+   Expr *pWhere,        /* The WHERE clause */
+@@ -127025,12 +131212,20 @@
+   const char *zStart,  /* Start of SQL text */
+   const char *zEnd     /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName, zStart, zEnd);
++  pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+-    pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pExprList = pEList;
++      pTriggerStep->pWhere = pWhere;
++      pEList = 0;
++      pWhere = 0;
++    }else{
++      pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
++      pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->orconf = orconf;
+   }
+   sqlite3ExprListDelete(db, pEList);
+@@ -127044,17 +131239,23 @@
+ ** sees a DELETE statement inside the body of a CREATE TRIGGER.
+ */
+ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
+-  sqlite3 *db,            /* Database connection */
++  Parse *pParse,          /* Parser */
+   Token *pTableName,      /* The table from which rows are deleted */
+   Expr *pWhere,           /* The WHERE clause */
+   const char *zStart,     /* Start of SQL text */
+   const char *zEnd        /* End of SQL text */
+ ){
++  sqlite3 *db = pParse->db;
+   TriggerStep *pTriggerStep;
+ 
+-  pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName, zStart, zEnd);
++  pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd);
+   if( pTriggerStep ){
+-    pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    if( IN_RENAME_OBJECT ){
++      pTriggerStep->pWhere = pWhere;
++      pWhere = 0;
++    }else{
++      pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
++    }
+     pTriggerStep->orconf = OE_Default;
+   }
+   sqlite3ExprDelete(db, pWhere);
+@@ -127321,7 +131522,7 @@
+           targetSrcList(pParse, pStep),
+           sqlite3ExprListDup(db, pStep->pExprList, 0), 
+           sqlite3ExprDup(db, pStep->pWhere, 0), 
+-          pParse->eOrconf, 0, 0
++          pParse->eOrconf, 0, 0, 0
+         );
+         break;
+       }
+@@ -127330,7 +131531,8 @@
+           targetSrcList(pParse, pStep),
+           sqlite3SelectDup(db, pStep->pSelect, 0), 
+           sqlite3IdListDup(db, pStep->pIdList), 
+-          pParse->eOrconf
++          pParse->eOrconf,
++          sqlite3UpsertDup(db, pStep->pUpsert)
+         );
+         break;
+       }
+@@ -127795,6 +131997,57 @@
+ }
+ 
+ /*
++** Check to see if column iCol of index pIdx references any of the
++** columns defined by aXRef and chngRowid.  Return true if it does
++** and false if not.  This is an optimization.  False-positives are a
++** performance degradation, but false-negatives can result in a corrupt
++** index and incorrect answers.
++**
++** aXRef[j] will be non-negative if column j of the original table is
++** being updated.  chngRowid will be true if the rowid of the table is
++** being updated.
++*/
++static int indexColumnIsBeingUpdated(
++  Index *pIdx,      /* The index to check */
++  int iCol,         /* Which column of the index to check */
++  int *aXRef,       /* aXRef[j]>=0 if column j is being updated */
++  int chngRowid     /* true if the rowid is being updated */
++){
++  i16 iIdxCol = pIdx->aiColumn[iCol];
++  assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
++  if( iIdxCol>=0 ){
++    return aXRef[iIdxCol]>=0;
++  }
++  assert( iIdxCol==XN_EXPR );
++  assert( pIdx->aColExpr!=0 );
++  assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
++  return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
++                                            aXRef,chngRowid);
++}
++
++/*
++** Check to see if index pIdx is a partial index whose conditional
++** expression might change values due to an UPDATE.  Return true if
++** the index is subject to change and false if the index is guaranteed
++** to be unchanged.  This is an optimization.  False-positives are a
++** performance degradation, but false-negatives can result in a corrupt
++** index and incorrect answers.
++**
++** aXRef[j] will be non-negative if column j of the original table is
++** being updated.  chngRowid will be true if the rowid of the table is
++** being updated.
++*/
++static int indexWhereClauseMightChange(
++  Index *pIdx,      /* The index to check */
++  int *aXRef,       /* aXRef[j]>=0 if column j is being updated */
++  int chngRowid     /* true if the rowid is being updated */
++){
++  if( pIdx->pPartIdxWhere==0 ) return 0;
++  return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
++                                            aXRef, chngRowid);
++}
++
++/*
+ ** Process an UPDATE statement.
+ **
+ **   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+@@ -127808,7 +132061,8 @@
+   Expr *pWhere,          /* The WHERE clause.  May be null */
+   int onError,           /* How to handle constraint errors */
+   ExprList *pOrderBy,    /* ORDER BY clause. May be null */
+-  Expr *pLimit           /* LIMIT clause. May be null */
++  Expr *pLimit,          /* LIMIT clause. May be null */
++  Upsert *pUpsert        /* ON CONFLICT clause, or null */
+ ){
+   int i, j;              /* Loop counters */
+   Table *pTab;           /* The table to be updated */
+@@ -127915,16 +132169,23 @@
+   ** need to occur right after the database cursor.  So go ahead and
+   ** allocate enough space, just in case.
+   */
+-  pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
++  iBaseCur = iDataCur = pParse->nTab++;
+   iIdxCur = iDataCur+1;
+   pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
++  testcase( pPk!=0 && pPk!=pTab->pIndex );
+   for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+-    if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){
++    if( pPk==pIdx ){
+       iDataCur = pParse->nTab;
+-      pTabList->a[0].iCursor = iDataCur;
+     }
+     pParse->nTab++;
+   }
++  if( pUpsert ){
++    /* On an UPSERT, reuse the same cursors already opened by INSERT */
++    iDataCur = pUpsert->iDataCur;
++    iIdxCur = pUpsert->iIdxCur;
++    pParse->nTab = iBaseCur;
++  }
++  pTabList->a[0].iCursor = iDataCur;
+ 
+   /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].  
+   ** Initialize aXRef[] and aToOpen[] to their default values.
+@@ -127941,6 +132202,8 @@
+   memset(&sNC, 0, sizeof(sNC));
+   sNC.pParse = pParse;
+   sNC.pSrcList = pTabList;
++  sNC.uNC.pUpsert = pUpsert;
++  sNC.ncFlags = NC_UUpsert;
+ 
+   /* Resolve the column names in all the expressions of the
+   ** of the UPDATE statement.  Also find the column index
+@@ -128007,19 +132270,18 @@
+   /* There is one entry in the aRegIdx[] array for each index on the table
+   ** being updated.  Fill in aRegIdx[] with a register number that will hold
+   ** the key for accessing each index.
+-  **
+-  ** FIXME:  Be smarter about omitting indexes that use expressions.
+   */
+   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+     int reg;
+-    if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
++    if( chngKey || hasFK>1 || pIdx==pPk
++     || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
++    ){
+       reg = ++pParse->nMem;
+       pParse->nMem += pIdx->nColumn;
+     }else{
+       reg = 0;
+       for(i=0; i<pIdx->nKeyCol; i++){
+-        i16 iIdxCol = pIdx->aiColumn[i];
+-        if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
++        if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
+           reg = ++pParse->nMem;
+           pParse->nMem += pIdx->nColumn;
+           if( (onError==OE_Replace)
+@@ -128044,7 +132306,7 @@
+   v = sqlite3GetVdbe(pParse);
+   if( v==0 ) goto update_cleanup;
+   if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
+-  sqlite3BeginWriteOperation(pParse, 1, iDb);
++  sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb);
+ 
+   /* Allocate required registers. */
+   if( !IsVirtual(pTab) ){
+@@ -128095,8 +132357,16 @@
+   }
+ #endif
+ 
+-  /* Initialize the count of updated rows */
+-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
++  /* Jump to labelBreak to abandon further processing of this UPDATE */
++  labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
++
++  /* Not an UPSERT.  Normal processing.  Begin by
++  ** initialize the count of updated rows */
++  if( (db->flags&SQLITE_CountRows)!=0
++   && !pParse->pTriggerTab
++   && !pParse->nested
++   && pUpsert==0
++  ){
+     regRowCount = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+   }
+@@ -128109,46 +132379,61 @@
+     iPk = pParse->nMem+1;
+     pParse->nMem += nPk;
+     regKey = ++pParse->nMem;
+-    iEph = pParse->nTab++;
+-
+-    sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
+-    addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+-    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
++    if( pUpsert==0 ){
++      iEph = pParse->nTab++;
++        sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1);
++      addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
++      sqlite3VdbeSetP4KeyInfo(pParse, pPk);
++    }
+   }
+-
+-  /* Begin the database scan. 
+-  **
+-  ** Do not consider a single-pass strategy for a multi-row update if
+-  ** there are any triggers or foreign keys to process, or rows may
+-  ** be deleted as a result of REPLACE conflict handling. Any of these
+-  ** things might disturb a cursor being used to scan through the table
+-  ** or index, causing a single-pass approach to malfunction.  */
+-  flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
+-  if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+-    flags |= WHERE_ONEPASS_MULTIROW;
++  
++  if( pUpsert ){
++    /* If this is an UPSERT, then all cursors have already been opened by
++    ** the outer INSERT and the data cursor should be pointing at the row
++    ** that is to be updated.  So bypass the code that searches for the
++    ** row(s) to be updated.
++    */
++    pWInfo = 0;
++    eOnePass = ONEPASS_SINGLE;
++    sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
++  }else{
++    /* Begin the database scan. 
++    **
++    ** Do not consider a single-pass strategy for a multi-row update if
++    ** there are any triggers or foreign keys to process, or rows may
++    ** be deleted as a result of REPLACE conflict handling. Any of these
++    ** things might disturb a cursor being used to scan through the table
++    ** or index, causing a single-pass approach to malfunction.  */
++    flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
++    if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
++      flags |= WHERE_ONEPASS_MULTIROW;
++    }
++    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
++    if( pWInfo==0 ) goto update_cleanup;
++  
++    /* A one-pass strategy that might update more than one row may not
++    ** be used if any column of the index used for the scan is being
++    ** updated. Otherwise, if there is an index on "b", statements like
++    ** the following could create an infinite loop:
++    **
++    **   UPDATE t1 SET b=b+1 WHERE b>?
++    **
++    ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
++    ** strategy that uses an index for which one or more columns are being
++    ** updated.  */
++    eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
++    if( eOnePass!=ONEPASS_SINGLE ){
++      sqlite3MultiWrite(pParse);
++      if( eOnePass==ONEPASS_MULTI ){
++        int iCur = aiCurOnePass[1];
++        if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
++          eOnePass = ONEPASS_OFF;
++        }
++        assert( iCur!=iDataCur || !HasRowid(pTab) );
++      }
++    }
+   }
+-  pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
+-  if( pWInfo==0 ) goto update_cleanup;
+ 
+-  /* A one-pass strategy that might update more than one row may not
+-  ** be used if any column of the index used for the scan is being
+-  ** updated. Otherwise, if there is an index on "b", statements like
+-  ** the following could create an infinite loop:
+-  **
+-  **   UPDATE t1 SET b=b+1 WHERE b>?
+-  **
+-  ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
+-  ** strategy that uses an index for which one or more columns are being
+-  ** updated.  */
+-  eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+-  if( eOnePass==ONEPASS_MULTI ){
+-    int iCur = aiCurOnePass[1];
+-    if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
+-      eOnePass = ONEPASS_OFF;
+-    }
+-    assert( iCur!=iDataCur || !HasRowid(pTab) );
+-  }
+-  
+   if( HasRowid(pTab) ){
+     /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
+     ** mode, write the rowid into the FIFO. In either of the one-pass modes,
+@@ -128168,7 +132453,7 @@
+       sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
+     }
+     if( eOnePass ){
+-      sqlite3VdbeChangeToNoop(v, addrOpen);
++      if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen);
+       nKey = nPk;
+       regKey = iPk;
+     }else{
+@@ -128178,59 +132463,58 @@
+     }
+   }
+ 
+-  if( eOnePass!=ONEPASS_MULTI ){
+-    sqlite3WhereEnd(pWInfo);
+-  }
+-
+-  labelBreak = sqlite3VdbeMakeLabel(v);
+-  if( !isView ){
+-    int addrOnce = 0;
+-
+-    /* Open every index that needs updating. */
+-    if( eOnePass!=ONEPASS_OFF ){
+-      if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+-      if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
++  if( pUpsert==0 ){
++    if( eOnePass!=ONEPASS_MULTI ){
++      sqlite3WhereEnd(pWInfo);
+     }
+-
+-    if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
+-      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++  
++    if( !isView ){
++      int addrOnce = 0;
++  
++      /* Open every index that needs updating. */
++      if( eOnePass!=ONEPASS_OFF ){
++        if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
++        if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
++      }
++  
++      if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
++        addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
++      }
++      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
++                                 aToOpen, 0, 0);
++      if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+     }
+-    sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
+-                               0, 0);
+-    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+-  }
+-
+-  /* Top of the update loop */
+-  if( eOnePass!=ONEPASS_OFF ){
+-    if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
+-      assert( pPk );
+-      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+-      VdbeCoverageNeverTaken(v);
+-    }
+-    if( eOnePass==ONEPASS_SINGLE ){
+-      labelContinue = labelBreak;
++  
++    /* Top of the update loop */
++    if( eOnePass!=ONEPASS_OFF ){
++      if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
++        assert( pPk );
++        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
++        VdbeCoverage(v);
++      }
++      if( eOnePass!=ONEPASS_SINGLE ){
++        labelContinue = sqlite3VdbeMakeLabel(v);
++      }
++      sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
++      VdbeCoverageIf(v, pPk==0);
++      VdbeCoverageIf(v, pPk!=0);
++    }else if( pPk ){
++      labelContinue = sqlite3VdbeMakeLabel(v);
++      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
++      addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
++      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
++      VdbeCoverage(v);
+     }else{
+-      labelContinue = sqlite3VdbeMakeLabel(v);
++      labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
++                               regOldRowid);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
++      VdbeCoverage(v);
+     }
+-    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+-    VdbeCoverageIf(v, pPk==0);
+-    VdbeCoverageIf(v, pPk!=0);
+-  }else if( pPk ){
+-    labelContinue = sqlite3VdbeMakeLabel(v);
+-    sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
+-    addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
+-    sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+-    VdbeCoverage(v);
+-  }else{
+-    labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+-                             regOldRowid);
+-    VdbeCoverage(v);
+-    sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+-    VdbeCoverage(v);
+   }
+ 
+-  /* If the record number will change, set register regNewRowid to
+-  ** contain the new value. If the record number is not being modified,
++  /* If the rowid value will change, set register regNewRowid to
++  ** contain the new value. If the rowid is not being modified,
+   ** then regNewRowid is the same register as regOldRowid, which is
+   ** already populated.  */
+   assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
+@@ -128293,7 +132577,7 @@
+         */
+         testcase( i==31 );
+         testcase( i==32 );
+-        sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i);
++        sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
+       }else{
+         sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
+       }
+@@ -128322,10 +132606,14 @@
+       VdbeCoverage(v);
+     }
+ 
+-    /* If it did not delete it, the row-trigger may still have modified 
++    /* After-BEFORE-trigger-reload-loop:
++    ** If it did not delete it, the BEFORE trigger may still have modified 
+     ** some of the columns of the row being updated. Load the values for 
+-    ** all columns not modified by the update statement into their 
+-    ** registers in case this has happened.
++    ** all columns not modified by the update statement into their registers
++    ** in case this has happened. Only unmodified columns are reloaded.
++    ** The values computed for modified columns use the values before the
++    ** BEFORE trigger runs.  See test case trigger1-18.0 (added 2018-04-26)
++    ** for an example.
+     */
+     for(i=0; i<pTab->nCol; i++){
+       if( aXRef[i]<0 && i!=pTab->iPKey ){
+@@ -128341,7 +132629,7 @@
+     assert( regOldRowid>0 );
+     sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+         regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
+-        aXRef);
++        aXRef, 0);
+ 
+     /* Do FK constraint checks. */
+     if( hasFK ){
+@@ -128411,7 +132699,7 @@
+ 
+   /* Increment the row counter 
+   */
+-  if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
+   }
+ 
+@@ -128438,16 +132726,15 @@
+   ** maximum rowid counter values recorded while inserting into
+   ** autoincrement tables.
+   */
+-  if( pParse->nested==0 && pParse->pTriggerTab==0 ){
++  if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){
+     sqlite3AutoincrementEnd(pParse);
+   }
+ 
+   /*
+-  ** Return the number of rows that were changed. If this routine is 
+-  ** generating code because of a call to sqlite3NestedParse(), do not
+-  ** invoke the callback function.
++  ** Return the number of rows that were changed, if we are tracking
++  ** that information.
+   */
+-  if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
++  if( regRowCount ){
+     sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
+     sqlite3VdbeSetNumCols(v, 1);
+     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
+@@ -128519,7 +132806,7 @@
+   int regRowid;                   /* Register for ephem table rowid */
+   int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
+   int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
+-  int bOnePass;                   /* True to use onepass strategy */
++  int eOnePass;                   /* True to use onepass strategy */
+   int addr;                       /* Address of OP_OpenEphemeral */
+ 
+   /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
+@@ -128543,7 +132830,7 @@
+       sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
+     }else{
+       sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
+-      sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
++      sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
+     }
+   }
+   if( HasRowid(pTab) ){
+@@ -128564,19 +132851,20 @@
+     sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
+   }
+ 
+-  bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
++  eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
+ 
+-  if( bOnePass ){
++  /* There is no ONEPASS_MULTI on virtual tables */
++  assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
++
++  if( eOnePass ){
+     /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
+-    ** above. Also, if this is a top-level parse (not a trigger), clear the
+-    ** multi-write flag so that the VM does not open a statement journal */
++    ** above. */
+     sqlite3VdbeChangeToNoop(v, addr);
+-    if( sqlite3IsToplevel(pParse) ){
+-      pParse->isMultiWrite = 0;
+-    }
++    sqlite3VdbeAddOp1(v, OP_Close, iCsr);
+   }else{
+     /* Create a record from the argument register contents and insert it into
+     ** the ephemeral table. */
++    sqlite3MultiWrite(pParse);
+     sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
+ #ifdef SQLITE_DEBUG
+     /* Signal an assert() within OP_MakeRecord that it is allowed to
+@@ -128588,7 +132876,7 @@
+   }
+ 
+ 
+-  if( bOnePass==0 ){
++  if( eOnePass==ONEPASS_OFF ){
+     /* End the virtual table scan */
+     sqlite3WhereEnd(pWInfo);
+ 
+@@ -128608,7 +132896,7 @@
+ 
+   /* End of the ephemeral table scan. Or, if using the onepass strategy,
+   ** jump to here if the scan visited zero rows. */
+-  if( bOnePass==0 ){
++  if( eOnePass==ONEPASS_OFF ){
+     sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
+     sqlite3VdbeJumpHere(v, addr);
+     sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
+@@ -128619,6 +132907,261 @@
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+ /************** End of update.c **********************************************/
++/************** Begin file upsert.c ******************************************/
++/*
++** 2018-04-12
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains code to implement various aspects of UPSERT
++** processing and handling of the Upsert object.
++*/
++/* #include "sqliteInt.h" */
++
++#ifndef SQLITE_OMIT_UPSERT
++/*
++** Free a list of Upsert objects
++*/
++SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){
++  if( p ){
++    sqlite3ExprListDelete(db, p->pUpsertTarget);
++    sqlite3ExprDelete(db, p->pUpsertTargetWhere);
++    sqlite3ExprListDelete(db, p->pUpsertSet);
++    sqlite3ExprDelete(db, p->pUpsertWhere);
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Duplicate an Upsert object.
++*/
++SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){
++  if( p==0 ) return 0;
++  return sqlite3UpsertNew(db,
++           sqlite3ExprListDup(db, p->pUpsertTarget, 0),
++           sqlite3ExprDup(db, p->pUpsertTargetWhere, 0),
++           sqlite3ExprListDup(db, p->pUpsertSet, 0),
++           sqlite3ExprDup(db, p->pUpsertWhere, 0)
++         );
++}
++
++/*
++** Create a new Upsert object.
++*/
++SQLITE_PRIVATE Upsert *sqlite3UpsertNew(
++  sqlite3 *db,           /* Determines which memory allocator to use */
++  ExprList *pTarget,     /* Target argument to ON CONFLICT, or NULL */
++  Expr *pTargetWhere,    /* Optional WHERE clause on the target */
++  ExprList *pSet,        /* UPDATE columns, or NULL for a DO NOTHING */
++  Expr *pWhere           /* WHERE clause for the ON CONFLICT UPDATE */
++){
++  Upsert *pNew;
++  pNew = sqlite3DbMallocRaw(db, sizeof(Upsert));
++  if( pNew==0 ){
++    sqlite3ExprListDelete(db, pTarget);
++    sqlite3ExprDelete(db, pTargetWhere);
++    sqlite3ExprListDelete(db, pSet);
++    sqlite3ExprDelete(db, pWhere);
++    return 0;
++  }else{
++    pNew->pUpsertTarget = pTarget;
++    pNew->pUpsertTargetWhere = pTargetWhere;
++    pNew->pUpsertSet = pSet;
++    pNew->pUpsertWhere = pWhere;
++    pNew->pUpsertIdx = 0;
++  }
++  return pNew;
++}
++
++/*
++** Analyze the ON CONFLICT clause described by pUpsert.  Resolve all
++** symbols in the conflict-target.
++**
++** Return SQLITE_OK if everything works, or an error code is something
++** is wrong.
++*/
++SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
++  Parse *pParse,     /* The parsing context */
++  SrcList *pTabList, /* Table into which we are inserting */
++  Upsert *pUpsert    /* The ON CONFLICT clauses */
++){
++  Table *pTab;            /* That table into which we are inserting */
++  int rc;                 /* Result code */
++  int iCursor;            /* Cursor used by pTab */
++  Index *pIdx;            /* One of the indexes of pTab */
++  ExprList *pTarget;      /* The conflict-target clause */
++  Expr *pTerm;            /* One term of the conflict-target clause */
++  NameContext sNC;        /* Context for resolving symbolic names */
++  Expr sCol[2];           /* Index column converted into an Expr */
++
++  assert( pTabList->nSrc==1 );
++  assert( pTabList->a[0].pTab!=0 );
++  assert( pUpsert!=0 );
++  assert( pUpsert->pUpsertTarget!=0 );
++
++  /* Resolve all symbolic names in the conflict-target clause, which
++  ** includes both the list of columns and the optional partial-index
++  ** WHERE clause.
++  */
++  memset(&sNC, 0, sizeof(sNC));
++  sNC.pParse = pParse;
++  sNC.pSrcList = pTabList;
++  rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget);
++  if( rc ) return rc;
++  rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere);
++  if( rc ) return rc;
++
++  /* Check to see if the conflict target matches the rowid. */  
++  pTab = pTabList->a[0].pTab;
++  pTarget = pUpsert->pUpsertTarget;
++  iCursor = pTabList->a[0].iCursor;
++  if( HasRowid(pTab) 
++   && pTarget->nExpr==1
++   && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN
++   && pTerm->iColumn==XN_ROWID
++  ){
++    /* The conflict-target is the rowid of the primary table */
++    assert( pUpsert->pUpsertIdx==0 );
++    return SQLITE_OK;
++  }
++
++  /* Initialize sCol[0..1] to be an expression parse tree for a
++  ** single column of an index.  The sCol[0] node will be the TK_COLLATE
++  ** operator and sCol[1] will be the TK_COLUMN operator.  Code below
++  ** will populate the specific collation and column number values
++  ** prior to comparing against the conflict-target expression.
++  */
++  memset(sCol, 0, sizeof(sCol));
++  sCol[0].op = TK_COLLATE;
++  sCol[0].pLeft = &sCol[1];
++  sCol[1].op = TK_COLUMN;
++  sCol[1].iTable = pTabList->a[0].iCursor;
++
++  /* Check for matches against other indexes */
++  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
++    int ii, jj, nn;
++    if( !IsUniqueIndex(pIdx) ) continue;
++    if( pTarget->nExpr!=pIdx->nKeyCol ) continue;
++    if( pIdx->pPartIdxWhere ){
++      if( pUpsert->pUpsertTargetWhere==0 ) continue;
++      if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere,
++                             pIdx->pPartIdxWhere, iCursor)!=0 ){
++        continue;
++      }
++    }
++    nn = pIdx->nKeyCol;
++    for(ii=0; ii<nn; ii++){
++      Expr *pExpr;
++      sCol[0].u.zToken = (char*)pIdx->azColl[ii];
++      if( pIdx->aiColumn[ii]==XN_EXPR ){
++        assert( pIdx->aColExpr!=0 );
++        assert( pIdx->aColExpr->nExpr>ii );
++        pExpr = pIdx->aColExpr->a[ii].pExpr;
++        if( pExpr->op!=TK_COLLATE ){
++          sCol[0].pLeft = pExpr;
++          pExpr = &sCol[0];
++        }
++      }else{
++        sCol[0].pLeft = &sCol[1];
++        sCol[1].iColumn = pIdx->aiColumn[ii];
++        pExpr = &sCol[0];
++      }
++      for(jj=0; jj<nn; jj++){
++        if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){
++          break;  /* Column ii of the index matches column jj of target */
++        }
++      }
++      if( jj>=nn ){
++        /* The target contains no match for column jj of the index */
++        break;
++      }
++    }
++    if( ii<nn ){
++      /* Column ii of the index did not match any term of the conflict target.
++      ** Continue the search with the next index. */
++      continue;
++    }
++    pUpsert->pUpsertIdx = pIdx;
++    return SQLITE_OK;
++  }
++  sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any "
++                          "PRIMARY KEY or UNIQUE constraint");
++  return SQLITE_ERROR;
++}
++
++/*
++** Generate bytecode that does an UPDATE as part of an upsert.
++**
++** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
++** In this case parameter iCur is a cursor open on the table b-tree that
++** currently points to the conflicting table row. Otherwise, if pIdx
++** is not NULL, then pIdx is the constraint that failed and iCur is a
++** cursor points to the conflicting row.
++*/
++SQLITE_PRIVATE void sqlite3UpsertDoUpdate(
++  Parse *pParse,        /* The parsing and code-generating context */
++  Upsert *pUpsert,      /* The ON CONFLICT clause for the upsert */
++  Table *pTab,          /* The table being updated */
++  Index *pIdx,          /* The UNIQUE constraint that failed */
++  int iCur              /* Cursor for pIdx (or pTab if pIdx==NULL) */
++){
++  Vdbe *v = pParse->pVdbe;
++  sqlite3 *db = pParse->db;
++  SrcList *pSrc;            /* FROM clause for the UPDATE */
++  int iDataCur;
++
++  assert( v!=0 );
++  assert( pUpsert!=0 );
++  VdbeNoopComment((v, "Begin DO UPDATE of UPSERT"));
++  iDataCur = pUpsert->iDataCur;
++  if( pIdx && iCur!=iDataCur ){
++    if( HasRowid(pTab) ){
++      int regRowid = sqlite3GetTempReg(pParse);
++      sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid);
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid);
++      VdbeCoverage(v);
++      sqlite3ReleaseTempReg(pParse, regRowid);
++    }else{
++      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
++      int nPk = pPk->nKeyCol;
++      int iPk = pParse->nMem+1;
++      int i;
++      pParse->nMem += nPk;
++      for(i=0; i<nPk; i++){
++        int k;
++        assert( pPk->aiColumn[i]>=0 );
++        k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
++        sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i);
++        VdbeComment((v, "%s.%s", pIdx->zName,
++                    pTab->aCol[pPk->aiColumn[i]].zName));
++      }
++      sqlite3VdbeVerifyAbortable(v, OE_Abort);
++      i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, 
++            "corrupt database", P4_STATIC);
++      sqlite3VdbeJumpHere(v, i);
++    }
++  }
++  /* pUpsert does not own pUpsertSrc - the outer INSERT statement does.  So
++  ** we have to make a copy before passing it down into sqlite3Update() */
++  pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0);
++  sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet,
++      pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert);
++  pUpsert->pUpsertSet = 0;    /* Will have been deleted by sqlite3Update() */
++  pUpsert->pUpsertWhere = 0;  /* Will have been deleted by sqlite3Update() */
++  VdbeNoopComment((v, "End DO UPDATE of UPSERT"));
++}
++
++#endif /* SQLITE_OMIT_UPSERT */
++
++/************** End of upsert.c **********************************************/
+ /************** Begin file vacuum.c ******************************************/
+ /*
+ ** 2003 April 6
+@@ -128661,8 +133204,14 @@
+   while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
+     const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
+     assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
+-    assert( sqlite3_strnicmp(zSubSql,"SELECT",6)!=0 || CORRUPT_DB );
+-    if( zSubSql && zSubSql[0]!='S' ){
++    /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX,
++    ** or INSERT.  Historically there have been attacks that first
++    ** corrupt the sqlite_master.sql field with other kinds of statements
++    ** then run VACUUM to get those statements to execute at inappropriate
++    ** times. */
++    if( zSubSql
++     && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0)
++    ){
+       rc = execSql(db, pzErrMsg, zSubSql);
+       if( rc!=SQLITE_OK ) break;
+     }
+@@ -128782,7 +133331,8 @@
+   saved_mTrace = db->mTrace;
+   db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+   db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
+-  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
++  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
++                   | SQLITE_Defensive | SQLITE_CountRows);
+   db->mTrace = 0;
+ 
+   zDbMain = db->aDb[iDb].zDbSName;
+@@ -128840,7 +133390,7 @@
+   */
+   rc = execSql(db, pzErrMsg, "BEGIN");
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+-  rc = sqlite3BtreeBeginTrans(pMain, 2);
++  rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ 
+   /* Do not attempt to change the page size for a WAL database */
+@@ -128875,7 +133425,7 @@
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+   rc = execSqlF(db, pzErrMsg,
+       "SELECT sql FROM \"%w\".sqlite_master"
+-      " WHERE type='index' AND length(sql)>10",
++      " WHERE type='index'",
+       zDbMain
+   );
+   if( rc!=SQLITE_OK ) goto end_of_vacuum;
+@@ -129258,7 +133808,7 @@
+   assert( sqlite3_mutex_held(db->mutex) );
+ 
+   if( p ){
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+     do {
+       VTable *pNext = p->pNext;
+       sqlite3VtabUnlock(p);
+@@ -129324,7 +133874,6 @@
+   Token *pModuleName,   /* Name of the module for the virtual table */
+   int ifNotExists       /* No error if the table already exists */
+ ){
+-  int iDb;              /* The database the table is being created in */
+   Table *pTable;        /* The new virtual table */
+   sqlite3 *db;          /* Database connection */
+ 
+@@ -129334,8 +133883,6 @@
+   assert( 0==pTable->pIndex );
+ 
+   db = pParse->db;
+-  iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+-  assert( iDb>=0 );
+ 
+   assert( pTable->nModuleArg==0 );
+   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
+@@ -129355,6 +133902,8 @@
+   ** The second call, to obtain permission to create the table, is made now.
+   */
+   if( pTable->azModuleArg ){
++    int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
++    assert( iDb>=0 ); /* The database the table is being created in */
+     sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, 
+             pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
+   }
+@@ -129754,7 +134303,7 @@
+   assert( IsVirtual(pTab) );
+ 
+   memset(&sParse, 0, sizeof(sParse));
+-  sParse.declareVtab = 1;
++  sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
+   sParse.db = db;
+   sParse.nQueryLoop = 1;
+   if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) 
+@@ -129795,7 +134344,7 @@
+     sqlite3DbFree(db, zErr);
+     rc = SQLITE_ERROR;
+   }
+-  sParse.declareVtab = 0;
++  sParse.eParseMode = PARSE_MODE_NORMAL;
+ 
+   if( sParse.pVdbe ){
+     sqlite3VdbeFinalize(sParse.pVdbe);
+@@ -130045,14 +134594,11 @@
+   void *pArg = 0;
+   FuncDef *pNew;
+   int rc = 0;
+-  char *zLowerName;
+-  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;
++  pTab = pExpr->y.pTab;
+   if( pTab==0 ) return pDef;
+   if( !IsVirtual(pTab) ) return pDef;
+   pVtab = sqlite3GetVTable(db, pTab)->pVtab;
+@@ -130062,16 +134608,22 @@
+   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 
++  ** to see if the implementation wants to overload this function.
++  **
++  ** Though undocumented, we have historically always invoked xFindFunction
++  ** with an all lower-case function name.  Continue in this tradition to
++  ** avoid any chance of an incompatibility.
+   */
+-  zLowerName = sqlite3DbStrDup(db, pDef->zName);
+-  if( zLowerName ){
+-    for(z=(unsigned char*)zLowerName; *z; z++){
+-      *z = sqlite3UpperToLower[*z];
++#ifdef SQLITE_DEBUG
++  {
++    int i;
++    for(i=0; pDef->zName[i]; i++){
++      unsigned char x = (unsigned char)pDef->zName[i];
++      assert( x==sqlite3UpperToLower[x] );
+     }
+-    rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg);
+-    sqlite3DbFree(db, zLowerName);
+   }
++#endif
++  rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg);
+   if( rc==0 ){
+     return pDef;
+   }
+@@ -130346,6 +134898,8 @@
+       struct InLoop {
+         int iCur;              /* The VDBE cursor used by this IN operator */
+         int addrInTop;         /* Top of the IN loop */
++        int iBase;             /* Base register of multi-key index record */
++        int nPrefix;           /* Number of prior entires in the key */
+         u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
+       } *aInLoop;           /* Information about each nested IN operator */
+     } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
+@@ -130584,6 +135138,7 @@
+   WhereInfo *pWInfo;       /* WHERE clause processing context */
+   WhereClause *pOuter;     /* Outer conjunction */
+   u8 op;                   /* Split operator.  TK_AND or TK_OR */
++  u8 hasOr;                /* True if any a[].eOperator is WO_OR */
+   int nTerm;               /* Number of terms */
+   int nSlot;               /* Number of entries in a[] */
+   WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
+@@ -130663,6 +135218,7 @@
+   int nRecValid;            /* Number of valid fields currently in pRec */
+ #endif
+   unsigned int bldFlags;    /* SQLITE_BLDF_* flags */
++  unsigned int iPlanLimit;  /* Search limiter */
+ };
+ 
+ /* Allowed values for WhereLoopBuider.bldFlags */
+@@ -130669,6 +135225,26 @@
+ #define SQLITE_BLDF_INDEXED  0x0001   /* An index is used */
+ #define SQLITE_BLDF_UNIQUE   0x0002   /* All keys of a UNIQUE index used */
+ 
++/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
++** index+constraint combinations the query planner will consider for a
++** particular query.  If this parameter is unlimited, then certain
++** pathological queries can spend excess time in the sqlite3WhereBegin()
++** routine.  The limit is high enough that is should not impact real-world
++** queries.
++**
++** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit.  The limit is
++** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
++** clause is processed, so that every table in a join is guaranteed to be
++** able to propose a some index+constraint combinations even if the initial
++** baseline limit was exhausted by prior tables of the join.
++*/
++#ifndef SQLITE_QUERY_PLANNER_LIMIT
++# define SQLITE_QUERY_PLANNER_LIMIT 20000
++#endif
++#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
++# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
++#endif
++
+ /*
+ ** The WHERE clause processing routine has two halves.  The
+ ** first part does the start of the WHERE loop and the second
+@@ -130731,12 +135307,10 @@
+   Parse *pParse,                  /* Parse context */
+   SrcList *pTabList,              /* Table list this loop refers to */
+   WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
+-  int iLevel,                     /* Value for "level" column of output */
+-  int iFrom,                      /* Value for "from" column of output */
+   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
+ );
+ #else
+-# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0
++# define sqlite3WhereExplainOneScan(u,v,w,x) 0
+ #endif /* SQLITE_OMIT_EXPLAIN */
+ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
+@@ -130759,6 +135333,7 @@
+ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*);
+ SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8);
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*);
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*);
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*);
+ SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*);
+ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*);
+@@ -130821,6 +135396,7 @@
+ #define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
+ #define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
+ #define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
++#define WHERE_IN_EARLYOUT  0x00040000  /* Perhaps quit IN loops early */
+ 
+ /************** End of whereInt.h ********************************************/
+ /************** Continuing where we left off in wherecode.c ******************/
+@@ -130856,23 +135432,23 @@
+   int i;
+ 
+   assert( nTerm>=1 );
+-  if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
++  if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
+ 
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
+   for(i=0; i<nTerm; i++){
+-    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+-    sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
++    if( i ) sqlite3_str_append(pStr, ",", 1);
++    sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
+   }
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
+ 
+-  sqlite3StrAccumAppend(pStr, zOp, 1);
++  sqlite3_str_append(pStr, zOp, 1);
+ 
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
+   for(i=0; i<nTerm; i++){
+-    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+-    sqlite3StrAccumAppend(pStr, "?", 1);
++    if( i ) sqlite3_str_append(pStr, ",", 1);
++    sqlite3_str_append(pStr, "?", 1);
+   }
+-  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
++  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
+ }
+ 
+ /*
+@@ -130896,11 +135472,11 @@
+   int i, j;
+ 
+   if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
+-  sqlite3StrAccumAppend(pStr, " (", 2);
++  sqlite3_str_append(pStr, " (", 2);
+   for(i=0; i<nEq; i++){
+     const char *z = explainIndexColumnName(pIndex, i);
+-    if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+-    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
++    if( i ) sqlite3_str_append(pStr, " AND ", 5);
++    sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
+   }
+ 
+   j = i;
+@@ -130911,7 +135487,7 @@
+   if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
+     explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
+   }
+-  sqlite3StrAccumAppend(pStr, ")", 1);
++  sqlite3_str_append(pStr, ")", 1);
+ }
+ 
+ /*
+@@ -130927,8 +135503,6 @@
+   Parse *pParse,                  /* Parse context */
+   SrcList *pTabList,              /* Table list this loop refers to */
+   WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
+-  int iLevel,                     /* Value for "level" column of output */
+-  int iFrom,                      /* Value for "from" column of output */
+   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
+ ){
+   int ret = 0;
+@@ -130939,7 +135513,6 @@
+     struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
+     Vdbe *v = pParse->pVdbe;      /* VM being constructed */
+     sqlite3 *db = pParse->db;     /* Database handle */
+-    int iId = pParse->iSelectId;  /* Select id (left-most output column) */
+     int isSearch;                 /* True for a SEARCH. False for SCAN. */
+     WhereLoop *pLoop;             /* The controlling WhereLoop object */
+     u32 flags;                    /* Flags that describe this loop */
+@@ -130956,15 +135529,15 @@
+             || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+ 
+     sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+-    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
++    sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
+     if( pItem->pSelect ){
+-      sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
++      sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId);
+     }else{
+-      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
++      sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
+     }
+ 
+     if( pItem->zAlias ){
+-      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
++      sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
+     }
+     if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
+       const char *zFmt = 0;
+@@ -130987,8 +135560,8 @@
+         zFmt = "INDEX %s";
+       }
+       if( zFmt ){
+-        sqlite3StrAccumAppend(&str, " USING ", 7);
+-        sqlite3XPrintf(&str, zFmt, pIdx->zName);
++        sqlite3_str_append(&str, " USING ", 7);
++        sqlite3_str_appendf(&str, zFmt, pIdx->zName);
+         explainIndexRange(&str, pLoop);
+       }
+     }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
+@@ -131003,23 +135576,26 @@
+         assert( flags&WHERE_TOP_LIMIT);
+         zRangeOp = "<";
+       }
+-      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
++      sqlite3_str_appendf(&str, 
++          " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
+     }
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+     else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
+-      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
++      sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
+                   pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
+     }
+ #endif
+ #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
+     if( pLoop->nOut>=10 ){
+-      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
++      sqlite3_str_appendf(&str, " (~%llu rows)",
++             sqlite3LogEstToInt(pLoop->nOut));
+     }else{
+-      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
++      sqlite3_str_append(&str, " (~1 row)", 9);
+     }
+ #endif
+     zMsg = sqlite3StrAccumFinish(&str);
+-    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
++    ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
++                            pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
+   }
+   return ret;
+ }
+@@ -131152,7 +135728,6 @@
+   /* Code the OP_Affinity opcode if there is anything left to do. */
+   if( n>0 ){
+     sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n);
+-    sqlite3ExprCacheAffinityChange(pParse, base, n);
+   }
+ }
+ 
+@@ -131231,7 +135806,7 @@
+     for(i=iEq; i<pLoop->nLTerm; i++){
+       if( pLoop->aLTerm[i]->pExpr==pX ){
+         int iField = pLoop->aLTerm[i]->iField - 1;
+-        assert( pOrigRhs->a[iField].pExpr!=0 );
++        if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
+         pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
+         pOrigRhs->a[iField].pExpr = 0;
+         assert( pOrigLhs->a[iField].pExpr!=0 );
+@@ -131396,7 +135971,14 @@
+           sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
+           if( i==iEq ){
+             pIn->iCur = iTab;
+-            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
++            pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
++            if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){
++              pIn->iBase = iReg - i;
++              pIn->nPrefix = i;
++              pLoop->wsFlags |= WHERE_IN_EARLYOUT;
++            }else{
++              pIn->nPrefix = 0;
++            }
+           }else{
+             pIn->eEndLoopOp = OP_Noop;
+           }
+@@ -131683,11 +136265,8 @@
+   struct CCurHint *pHint = pWalker->u.pCCurHint;
+   if( pExpr->op==TK_COLUMN ){
+     if( pExpr->iTable!=pHint->iTabCur ){
+-      Vdbe *v = pWalker->pParse->pVdbe;
+       int reg = ++pWalker->pParse->nMem;   /* Register for column value */
+-      sqlite3ExprCodeGetColumnOfTable(
+-          v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg
+-      );
++      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
+       pExpr->op = TK_REGISTER;
+       pExpr->iTable = reg;
+     }else if( pHint->pIdx!=0 ){
+@@ -131919,7 +136498,7 @@
+     pExpr->op = TK_COLUMN;
+     pExpr->iTable = pX->iIdxCur;
+     pExpr->iColumn = pX->iIdxCol;
+-    pExpr->pTab = 0;
++    pExpr->y.pTab = 0;
+     return WRC_Prune;
+   }else{
+     return WRC_Continue;
+@@ -132020,6 +136599,9 @@
+   ** initialize a memory cell that records if this table matches any
+   ** row of the left table of the join.
+   */
++  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
++       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
++  );
+   if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
+     pLevel->iLeftJoin = ++pParse->nMem;
+     sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
+@@ -132037,7 +136619,7 @@
+     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));
++    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+     pLevel->op = OP_Goto;
+   }else
+ 
+@@ -132051,7 +136633,6 @@
+     int nConstraint = pLoop->nLTerm;
+     int iIn;    /* Counter for IN constraints */
+ 
+-    sqlite3ExprCachePush(pParse);
+     iReg = sqlite3GetTempRange(pParse, nConstraint+2);
+     addrNotFound = pLevel->addrBrk;
+     for(j=0; j<nConstraint; j++){
+@@ -132124,7 +136705,6 @@
+     **
+     **    sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
+     */
+-    sqlite3ExprCachePop(pParse);
+   }else
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+ 
+@@ -132148,9 +136728,6 @@
+     addrNxt = pLevel->addrNxt;
+     sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
+     VdbeCoverage(v);
+-    sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
+-    sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+-    VdbeComment((v, "pk"));
+     pLevel->op = OP_Noop;
+   }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+          && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+@@ -132220,7 +136797,6 @@
+       VdbeCoverageIf(v, pX->op==TK_LE);
+       VdbeCoverageIf(v, pX->op==TK_LT);
+       VdbeCoverageIf(v, pX->op==TK_GE);
+-      sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+       sqlite3ReleaseTempReg(pParse, rTemp);
+     }else{
+       sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
+@@ -132255,7 +136831,6 @@
+     if( testOp!=OP_Noop ){
+       iRowidReg = ++pParse->nMem;
+       sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
+-      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+       sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
+       VdbeCoverageIf(v, testOp==OP_Le);
+       VdbeCoverageIf(v, testOp==OP_Lt);
+@@ -132460,6 +137035,9 @@
+       ** above has already left the cursor sitting on the correct row,
+       ** so no further seeking is needed */
+     }else{
++      if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
++        sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur);
++      }
+       op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+       assert( op!=0 );
+       sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+@@ -132478,7 +137056,6 @@
+     nConstraint = nEq;
+     if( pRangeEnd ){
+       Expr *pRight = pRangeEnd->pExpr->pRight;
+-      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
+       codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
+       whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
+       if( (pRangeEnd->wtFlags & TERM_VNULL)==0
+@@ -132503,7 +137080,6 @@
+       }
+     }else if( bStopAtNull ){
+       sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+-      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
+       endEq = 0;
+       nConstraint++;
+     }
+@@ -132523,6 +137099,10 @@
+       testcase( op==OP_IdxLE );  VdbeCoverageIf(v, op==OP_IdxLE );
+     }
+ 
++    if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
++      sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
++    }
++
+     /* Seek the table cursor, if required */
+     if( omitTable ){
+       /* pIdx is a covering index.  No need to access the main table. */
+@@ -132533,7 +137113,6 @@
+       )){
+         iRowidReg = ++pParse->nMem;
+         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
+-        sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
+         sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
+         VdbeCoverage(v);
+       }else{
+@@ -132553,10 +137132,17 @@
+     /* If pIdx is an index on one or more expressions, then look through
+     ** all the expressions in pWInfo and try to transform matching expressions
+     ** into reference to index columns.
++    **
++    ** Do not do this for the RHS of a LEFT JOIN. This is because the 
++    ** expression may be evaluated after OP_NullRow has been executed on
++    ** the cursor. In this case it is important to do the full evaluation,
++    ** as the result of the expression may not be NULL, even if all table
++    ** column values are.  https://www.sqlite.org/src/info/7fa8049685b50b5a
+     */
+-    whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
++    if( pLevel->iLeftJoin==0 ){
++      whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
++    }
+ 
+-
+     /* Record the instruction used to terminate the loop. */
+     if( pLoop->wsFlags & WHERE_ONEROW ){
+       pLevel->op = OP_Noop;
+@@ -132711,7 +137297,6 @@
+       for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
+         Expr *pExpr = pWC->a[iTerm].pExpr;
+         if( &pWC->a[iTerm] == pTerm ) continue;
+-        if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
+         testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
+         testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
+         if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
+@@ -132730,6 +137315,7 @@
+     ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
+     */
+     wctrlFlags =  WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
++    ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
+     for(ii=0; ii<pOrWc->nTerm; ii++){
+       WhereTerm *pOrTerm = &pOrWc->a[ii];
+       if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
+@@ -132736,7 +137322,10 @@
+         WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
+         Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
+         int jmp1 = 0;                   /* Address of jump operation */
+-        if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
++        assert( (pTabItem[0].fg.jointype & JT_LEFT)==0 
++             || ExprHasProperty(pOrExpr, EP_FromJoin) 
++        );
++        if( pAndExpr ){
+           pAndExpr->pLeft = pOrExpr;
+           pOrExpr = pAndExpr;
+         }
+@@ -132748,7 +137337,7 @@
+         if( pSubWInfo ){
+           WhereLoop *pSubLoop;
+           int addrExplain = sqlite3WhereExplainOneScan(
+-              pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
++              pParse, pOrTab, &pSubWInfo->a[0], 0
+           );
+           sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
+ 
+@@ -132758,23 +137347,23 @@
+           ** row will be skipped in subsequent sub-WHERE clauses.
+           */
+           if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+-            int r;
+             int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
+             if( HasRowid(pTab) ){
+-              r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
++              sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid);
+               jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
+-                                           r,iSet);
++                                          regRowid, iSet);
+               VdbeCoverage(v);
+             }else{
+               Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+               int nPk = pPk->nKeyCol;
+               int iPk;
++              int r;
+ 
+               /* Read the PK into an array of temp registers. */
+               r = sqlite3GetTempRange(pParse, nPk);
+               for(iPk=0; iPk<nPk; iPk++){
+                 int iCol = pPk->aiColumn[iPk];
+-                sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk);
++                sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk);
+               }
+ 
+               /* Check if the temp table already contains this key. If so,
+@@ -132847,6 +137436,7 @@
+         }
+       }
+     }
++    ExplainQueryPlanPop(pParse);
+     pLevel->u.pCovidx = pCov;
+     if( pCov ) pLevel->iIdxCur = iCovCur;
+     if( pAndExpr ){
+@@ -132919,7 +137509,7 @@
+       }
+       pE = pTerm->pExpr;
+       assert( pE!=0 );
+-      if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
++      if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
+         continue;
+       }
+       
+@@ -133006,7 +137596,6 @@
+     pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
+     sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
+     VdbeComment((v, "record LEFT JOIN hit"));
+-    sqlite3ExprCacheClear(pParse);
+     for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
+       testcase( pTerm->wtFlags & TERM_VIRTUAL );
+       testcase( pTerm->wtFlags & TERM_CODED );
+@@ -133222,18 +137811,18 @@
+   int *pisComplete, /* True if the only wildcard is % in the last character */
+   int *pnoCase      /* True if uppercase is equivalent to lowercase */
+ ){
+-  const u8 *z = 0;         /* String on RHS of LIKE operator */
++  const u8 *z = 0;           /* String on RHS of LIKE operator */
+   Expr *pRight, *pLeft;      /* Right and left size of LIKE operator */
+   ExprList *pList;           /* List of operands to the LIKE operator */
+-  int c;                     /* One character in z[] */
++  u8 c;                      /* One character in z[] */
+   int cnt;                   /* Number of non-wildcard prefix characters */
+-  char wc[4];                /* Wildcard characters */
++  u8 wc[4];                  /* Wildcard characters */
+   sqlite3 *db = pParse->db;  /* Database connection */
+   sqlite3_value *pVal = 0;
+   int op;                    /* Opcode of pRight */
+   int rc;                    /* Result code to return */
+ 
+-  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
++  if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){
+     return 0;
+   }
+ #ifdef SQLITE_EBCDIC
+@@ -133258,23 +137847,6 @@
+   }
+   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;
+-      }
+-    }
+-
+     /* Count the number of prefix characters prior to the first wildcard */
+     cnt = 0;
+     while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
+@@ -133284,11 +137856,13 @@
+ 
+     /* The optimization is possible only if (1) the pattern does not begin
+     ** with a wildcard and if (2) the non-wildcard prefix does not end with
+-    ** an (illegal 0xff) character.  The second condition is necessary so
++    ** an (illegal 0xff) character, or (3) the pattern does not consist of
++    ** a single escape character. The second condition is necessary so
+     ** that we can increment the prefix key to find an upper bound for the
+-    ** range search. 
+-    */
+-    if( cnt!=0 && 255!=(u8)z[cnt-1] ){
++    ** range search. The third is because the caller assumes that the pattern
++    ** consists of at least one character after all escapes have been
++    ** removed.  */
++    if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){
+       Expr *pPrefix;
+ 
+       /* A "complete" match if the pattern ends with "*" or "%" */
+@@ -133305,6 +137879,32 @@
+           zNew[iTo++] = zNew[iFrom];
+         }
+         zNew[iTo] = 0;
++
++        /* 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.
++        **
++        ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
++        ** The RHS pattern must not be '/%' because the termination condition
++        ** will then become "x<'0'" and if the affinity is numeric, will then
++        ** be converted into "x<0", which is incorrect.
++        */
++        if( sqlite3Isdigit(zNew[0])
++         || zNew[0]=='-'
++         || (zNew[0]+1=='0' && iTo==1)
++        ){
++          if( pLeft->op!=TK_COLUMN 
++           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
++           || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
++          ){
++            sqlite3ExprDelete(db, pPrefix);
++            sqlite3ValueFree(pVal);
++            return 0;
++          }
++        }
+       }
+       *ppPrefix = pPrefix;
+ 
+@@ -133366,6 +137966,7 @@
+ ** If the expression matches none of the patterns above, return 0.
+ */
+ static int isAuxiliaryVtabOperator(
++  sqlite3 *db,                    /* Parsing context */
+   Expr *pExpr,                    /* Test this expression */
+   unsigned char *peOp2,           /* OUT: 0 for MATCH, or else an op2 value */
+   Expr **ppLeft,                  /* Column expression to left of MATCH/op2 */
+@@ -133389,16 +137990,54 @@
+     if( pList==0 || pList->nExpr!=2 ){
+       return 0;
+     }
++
++    /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a
++    ** virtual table on their second argument, which is the same as
++    ** the left-hand side operand in their in-fix form.
++    **
++    **       vtab_column MATCH expression
++    **       MATCH(expression,vtab_column)
++    */
+     pCol = pList->a[1].pExpr;
+-    if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
+-      return 0;
++    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
++      for(i=0; i<ArraySize(aOp); i++){
++        if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
++          *peOp2 = aOp[i].eOp2;
++          *ppRight = pList->a[0].pExpr;
++          *ppLeft = pCol;
++          return 1;
++        }
++      }
+     }
+-    for(i=0; i<ArraySize(aOp); i++){
+-      if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+-        *peOp2 = aOp[i].eOp2;
+-        *ppRight = pList->a[0].pExpr;
+-        *ppLeft = pCol;
+-        return 1;
++
++    /* We can also match against the first column of overloaded
++    ** functions where xFindFunction returns a value of at least
++    ** SQLITE_INDEX_CONSTRAINT_FUNCTION.
++    **
++    **      OVERLOADED(vtab_column,expression)
++    **
++    ** Historically, xFindFunction expected to see lower-case function
++    ** names.  But for this use case, xFindFunction is expected to deal
++    ** with function names in an arbitrary case.
++    */
++    pCol = pList->a[0].pExpr;
++    if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
++      sqlite3_vtab *pVtab;
++      sqlite3_module *pMod;
++      void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
++      void *pNotUsed;
++      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
++      assert( pVtab!=0 );
++      assert( pVtab->pModule!=0 );
++      pMod = (sqlite3_module *)pVtab->pModule;
++      if( pMod->xFindFunction!=0 ){
++        i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
++        if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
++          *peOp2 = i;
++          *ppRight = pList->a[1].pExpr;
++          *ppLeft = pCol;
++          return 1;
++        }
+       }
+     }
+   }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
+@@ -133405,10 +138044,10 @@
+     int res = 0;
+     Expr *pLeft = pExpr->pLeft;
+     Expr *pRight = pExpr->pRight;
+-    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
++    if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
+       res++;
+     }
+-    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
++    if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
+       res++;
+       SWAP(Expr*, pLeft, pRight);
+     }
+@@ -133700,7 +138339,12 @@
+   ** empty.
+   */
+   pOrInfo->indexable = indexable;
+-  pTerm->eOperator = indexable==0 ? 0 : WO_OR;
++  if( indexable ){
++    pTerm->eOperator = WO_OR;
++    pWC->hasOr = 1;
++  }else{
++    pTerm->eOperator = WO_OR;
++  }
+ 
+   /* For a two-way OR, attempt to implementation case 2.
+   */
+@@ -133841,12 +138485,11 @@
+         idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+         testcase( idxNew==0 );
+         exprAnalyze(pSrc, pWC, idxNew);
+-        pTerm = &pWC->a[idxTerm];
++        /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */
+         markTermAsChild(pWC, idxNew, idxTerm);
+       }else{
+         sqlite3ExprListDelete(db, pList);
+       }
+-      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 3 */
+     }
+   }
+ }
+@@ -133881,7 +138524,7 @@
+     return 0;
+   }
+   pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
+-  if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
++  if( sqlite3IsBinary(pColl) ) return 1;
+   return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
+ }
+ 
+@@ -134040,7 +138683,7 @@
+     pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
+   }
+   pMaskSet->bVarSelect = 0;
+-  prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr);
++  prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
+   if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
+   if( ExprHasProperty(pExpr, EP_FromJoin) ){
+     Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
+@@ -134222,7 +138865,7 @@
+       }
+       *pC = c + 1;
+     }
+-    zCollSeqName = noCase ? "NOCASE" : "BINARY";
++    zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY;
+     pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
+     pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+            sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
+@@ -134259,7 +138902,7 @@
+   */
+   if( pWC->op==TK_AND ){
+     Expr *pRight = 0, *pLeft = 0;
+-    int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight);
++    int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight);
+     while( res-- > 0 ){
+       int idxNew;
+       WhereTerm *pNewTerm;
+@@ -134356,6 +138999,7 @@
+   if( pExpr->op==TK_NOTNULL
+    && pExpr->pLeft->op==TK_COLUMN
+    && pExpr->pLeft->iColumn>=0
++   && !ExprHasProperty(pExpr, EP_FromJoin)
+    && OptimizationEnabled(db, SQLITE_Stat34)
+   ){
+     Expr *pNewExpr;
+@@ -134433,6 +139077,7 @@
+   WhereInfo *pWInfo        /* The WHERE processing context */
+ ){
+   pWC->pWInfo = pWInfo;
++  pWC->hasOr = 0;
+   pWC->pOuter = 0;
+   pWC->nTerm = 0;
+   pWC->nSlot = ArraySize(pWC->aStatic);
+@@ -134469,17 +139114,18 @@
+ ** a bitmask indicating which tables are used in that expression
+ ** tree.
+ */
+-SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
+   Bitmask mask;
+-  if( p==0 ) return 0;
+-  if( p->op==TK_COLUMN ){
++  if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
+     return sqlite3WhereGetMask(pMaskSet, p->iTable);
++  }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
++    assert( p->op!=TK_IF_NULL_ROW );
++    return 0;
+   }
+   mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
+-  assert( !ExprHasProperty(p, EP_TokenOnly) );
+-  if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
++  if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
+   if( p->pRight ){
+-    mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight);
++    mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
+     assert( p->x.pList==0 );
+   }else if( ExprHasProperty(p, EP_xIsSelect) ){
+     if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
+@@ -134489,6 +139135,9 @@
+   }
+   return mask;
+ }
++SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
++  return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
++}
+ SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
+   int i;
+   Bitmask mask = 0;
+@@ -134542,6 +139191,7 @@
+   pArgs = pItem->u1.pFuncArg;
+   if( pArgs==0 ) return;
+   for(j=k=0; j<pArgs->nExpr; j++){
++    Expr *pRhs;
+     while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
+     if( k>=pTab->nCol ){
+       sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
+@@ -134552,9 +139202,10 @@
+     if( pColRef==0 ) return;
+     pColRef->iTable = pItem->iCursor;
+     pColRef->iColumn = k++;
+-    pColRef->pTab = pTab;
+-    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
+-                         sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
++    pColRef->y.pTab = pTab;
++    pRhs = sqlite3PExpr(pParse, TK_UPLUS, 
++        sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
++    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
+     whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
+   }
+ }
+@@ -134630,15 +139281,38 @@
+ }
+ 
+ /*
+-** Return TRUE if the innermost loop of the WHERE clause implementation
+-** returns rows in ORDER BY order for complete run of the inner loop.
++** In the ORDER BY LIMIT optimization, if the inner-most loop is known
++** to emit rows in increasing order, and if the last row emitted by the
++** inner-most loop did not fit within the sorter, then we can skip all
++** subsequent rows for the current iteration of the inner loop (because they
++** will not fit in the sorter either) and continue with the second inner
++** loop - the loop immediately outside the inner-most.
+ **
+-** Across multiple iterations of outer loops, the output rows need not be
+-** sorted.  As long as rows are sorted for just the innermost loop, this
+-** routine can return TRUE.
++** When a row does not fit in the sorter (because the sorter already
++** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the
++** label returned by this function.
++**
++** If the ORDER BY LIMIT optimization applies, the jump destination should
++** be the continuation for the second-inner-most loop.  If the ORDER BY
++** LIMIT optimization does not apply, then the jump destination should
++** be the continuation for the inner-most loop.
++**
++** It is always safe for this routine to return the continuation of the
++** inner-most loop, in the sense that a correct answer will result.  
++** Returning the continuation the second inner loop is an optimization
++** that might make the code run a little faster, but should not change
++** the final answer.
+ */
+-SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){
+-  return pWInfo->bOrderedInnerLoop;
++SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
++  WhereLevel *pInner;
++  if( !pWInfo->bOrderedInnerLoop ){
++    /* The ORDER BY LIMIT optimization does not apply.  Jump to the 
++    ** continuation of the inner-most loop. */
++    return pWInfo->iContinue;
++  }
++  pInner = &pWInfo->a[pWInfo->nLevel-1];
++  assert( pInner->addrNxt!=0 );
++  return pInner->addrNxt;
+ }
+ 
+ /*
+@@ -135365,7 +140039,6 @@
+   VdbeComment((v, "for %s", pTable->zName));
+ 
+   /* Fill the automatic index with content */
+-  sqlite3ExprCachePush(pParse);
+   pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
+   if( pTabItem->fg.viaCoroutine ){
+     int regYield = pTabItem->regReturn;
+@@ -135373,7 +140046,7 @@
+     sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+     addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
+     VdbeCoverage(v);
+-    VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
++    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+   }else{
+     addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
+   }
+@@ -135395,7 +140068,6 @@
+     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);
+   }
+@@ -135402,7 +140074,6 @@
+   sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
+   sqlite3VdbeJumpHere(v, addrTop);
+   sqlite3ReleaseTempReg(pParse, regRecord);
+-  sqlite3ExprCachePop(pParse);
+   
+   /* Jump here when skipping the initialization */
+   sqlite3VdbeJumpHere(v, addrInit);
+@@ -135508,6 +140179,20 @@
+     testcase( pTerm->eOperator & WO_ALL );
+     if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+     if( pTerm->wtFlags & TERM_VNULL ) continue;
++    if( (pSrc->fg.jointype & JT_LEFT)!=0
++     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
++     && (pTerm->eOperator & (WO_IS|WO_ISNULL))
++    ){
++      /* An "IS" term in the WHERE clause where the virtual table is the rhs
++      ** of a LEFT JOIN. Do not pass this term to the virtual table
++      ** implementation, as this can lead to incorrect results from SQL such
++      ** as:
++      **
++      **   "LEFT JOIN vtab WHERE vtab.col IS NULL"  */
++      testcase( pTerm->eOperator & WO_ISNULL );
++      testcase( pTerm->eOperator & WO_IS );
++      continue;
++    }
+     assert( pTerm->u.leftColumn>=(-1) );
+     pIdxCons[j].iColumn = pTerm->u.leftColumn;
+     pIdxCons[j].iTermOffset = i;
+@@ -135560,9 +140245,11 @@
+ ** method of the virtual table with the sqlite3_index_info object that
+ ** comes in as the 3rd argument to this function.
+ **
+-** If an error occurs, pParse is populated with an error message and a
+-** non-zero value is returned. Otherwise, 0 is returned and the output
+-** part of the sqlite3_index_info structure is left populated.
++** If an error occurs, pParse is populated with an error message and an
++** appropriate error code is returned.  A return of SQLITE_CONSTRAINT from
++** xBestIndex is not considered an error.  SQLITE_CONSTRAINT indicates that
++** the current configuration of "unusable" flags in sqlite3_index_info can
++** not result in a valid plan.
+ **
+ ** Whether or not an error is returned, it is the responsibility of the
+ ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
+@@ -135576,7 +140263,7 @@
+   rc = pVtab->pModule->xBestIndex(pVtab, p);
+   TRACE_IDX_OUTPUTS(p);
+ 
+-  if( rc!=SQLITE_OK ){
++  if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
+     if( rc==SQLITE_NOMEM ){
+       sqlite3OomFault(pParse->db);
+     }else if( !pVtab->zErrMsg ){
+@@ -135587,19 +140274,7 @@
+   }
+   sqlite3_free(pVtab->zErrMsg);
+   pVtab->zErrMsg = 0;
+-
+-#if 0
+-  /* This error is now caught by the caller.
+-  ** Search for "xBestIndex malfunction" below */
+-  for(i=0; i<p->nConstraint; i++){
+-    if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
+-      sqlite3ErrorMsg(pParse, 
+-          "table %s: xBestIndex returned an invalid plan", pTab->zName);
+-    }
+-  }
+-#endif
+-
+-  return pParse->nErr;
++  return rc;
+ }
+ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
+ 
+@@ -135999,7 +140674,9 @@
+   Index *p = pLoop->u.btree.pIndex;
+   int nEq = pLoop->u.btree.nEq;
+ 
+-  if( p->nSample>0 && nEq<p->nSampleCol ){
++  if( p->nSample>0 && nEq<p->nSampleCol
++   && OptimizationEnabled(pParse->db, SQLITE_Stat34)
++  ){
+     if( nEq==pBuilder->nRecValid ){
+       UnpackedRecord *pRec = pBuilder->pRec;
+       tRowcnt a[2];
+@@ -136652,6 +141329,14 @@
+   sqlite3 *db = pWInfo->pParse->db;
+   int rc;
+ 
++  /* Stop the search once we hit the query planner search limit */
++  if( pBuilder->iPlanLimit==0 ){
++    WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
++    if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
++    return SQLITE_DONE;
++  }
++  pBuilder->iPlanLimit--;
++
+   /* If pBuilder->pOrSet is defined, then only keep track of the costs
+   ** and prereqs.
+   */
+@@ -136983,15 +141668,12 @@
+     ** to mix with a lower range bound from some other source */
+     if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
+ 
+-    /* Do not allow IS constraints from the WHERE clause to be used by the
++    /* Do not allow constraints from the WHERE clause to be used by the
+     ** right table of a LEFT JOIN.  Only constraints in the ON clause are
+     ** allowed */
+     if( (pSrc->fg.jointype & JT_LEFT)!=0
+      && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+-     && (eOp & (WO_IS|WO_ISNULL))!=0
+     ){
+-      testcase( eOp & WO_IS );
+-      testcase( eOp & WO_ISNULL );
+       continue;
+     }
+ 
+@@ -137017,7 +141699,6 @@
+ 
+     if( eOp & WO_IN ){
+       Expr *pExpr = pTerm->pExpr;
+-      pNew->wsFlags |= WHERE_COLUMN_IN;
+       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+         /* "x IN (SELECT ...)":  TUNING: the SELECT returns 25 rows */
+         int i;
+@@ -137037,6 +141718,42 @@
+         assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
+                           ** changes "x IN (?)" into "x=?". */
+       }
++      if( pProbe->hasStat1 ){
++        LogEst M, logK, safetyMargin;
++        /* Let:
++        **   N = the total number of rows in the table
++        **   K = the number of entries on the RHS of the IN operator
++        **   M = the number of rows in the table that match terms to the 
++        **       to the left in the same index.  If the IN operator is on
++        **       the left-most index column, M==N.
++        **
++        ** Given the definitions above, it is better to omit the IN operator
++        ** from the index lookup and instead do a scan of the M elements,
++        ** testing each scanned row against the IN operator separately, if:
++        **
++        **        M*log(K) < K*log(N)
++        **
++        ** Our estimates for M, K, and N might be inaccurate, so we build in
++        ** a safety margin of 2 (LogEst: 10) that favors using the IN operator
++        ** with the index, as using an index has better worst-case behavior.
++        ** If we do not have real sqlite_stat1 data, always prefer to use
++        ** the index.
++        */
++        M = pProbe->aiRowLogEst[saved_nEq];
++        logK = estLog(nIn);
++        safetyMargin = 10;  /* TUNING: extra weight for indexed IN */
++        if( M + logK + safetyMargin < nIn + rLogSize ){
++          WHERETRACE(0x40,
++            ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n",
++             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
++          continue;
++        }else{
++          WHERETRACE(0x40,
++            ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n",
++             saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize));
++        }
++      }
++      pNew->wsFlags |= WHERE_COLUMN_IN;
+     }else if( eOp & (WO_EQ|WO_IS) ){
+       int iCol = pProbe->aiColumn[saved_nEq];
+       pNew->wsFlags |= WHERE_COLUMN_EQ;
+@@ -137115,6 +141832,7 @@
+          && pProbe->nSample 
+          && pNew->u.btree.nEq<=pProbe->nSampleCol
+          && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
++         && OptimizationEnabled(db, SQLITE_Stat34)
+         ){
+           Expr *pExpr = pTerm->pExpr;
+           if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
+@@ -137203,6 +141921,7 @@
+   if( saved_nEq==saved_nSkip
+    && saved_nEq+1<pProbe->nKeyCol
+    && pProbe->noSkipScan==0
++   && OptimizationEnabled(db, SQLITE_SkipScan)
+    && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
+    && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
+   ){
+@@ -137266,24 +141985,6 @@
+   return 0;
+ }
+ 
+-/*
+-** Return a bitmask where 1s indicate that the corresponding column of
+-** the table is used by an index.  Only the first 63 columns are considered.
+-*/
+-static Bitmask columnsInIndex(Index *pIdx){
+-  Bitmask m = 0;
+-  int j;
+-  for(j=pIdx->nColumn-1; j>=0; j--){
+-    int x = pIdx->aiColumn[j];
+-    if( x>=0 ){
+-      testcase( x==BMS-1 );
+-      testcase( x==BMS-2 );
+-      if( x<BMS-1 ) m |= MASKBIT(x);
+-    }
+-  }
+-  return m;
+-}
+-
+ /* Check to see if a partial index with pPartIndexWhere can be used
+ ** in the current query.  Return true if it can be and false if not.
+ */
+@@ -137428,14 +142129,16 @@
+         /* TUNING: One-time cost for computing the automatic index is
+         ** estimated to be X*N*log2(N) where N is the number of rows in
+         ** the table being indexed and where X is 7 (LogEst=28) for normal
+-        ** tables or 1.375 (LogEst=4) for views and subqueries.  The value
++        ** tables or 0.5 (LogEst=-10) for views and subqueries.  The value
+         ** of X is smaller for views and subqueries so that the query planner
+         ** will be more aggressive about generating automatic indexes for
+         ** those objects, since there is no opportunity to add schema
+         ** indexes on subqueries and views. */
+-        pNew->rSetup = rLogSize + rSize + 4;
++        pNew->rSetup = rLogSize + rSize;
+         if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
+-          pNew->rSetup += 24;
++          pNew->rSetup += 28;
++        }else{
++          pNew->rSetup -= 10;
+         }
+         ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
+         if( pNew->rSetup<0 ) pNew->rSetup = 0;
+@@ -137497,7 +142200,7 @@
+         pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
+         m = 0;
+       }else{
+-        m = pSrc->colUsed & ~columnsInIndex(pProbe);
++        m = pSrc->colUsed & pProbe->colNotIdxed;
+         pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+       }
+ 
+@@ -137644,7 +142347,17 @@
+ 
+   /* Invoke the virtual table xBestIndex() method */
+   rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+-  if( rc ) return rc;
++  if( rc ){
++    if( rc==SQLITE_CONSTRAINT ){
++      /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
++      ** that the particular combination of parameters provided is unusable.
++      ** Make no entries in the loop table.
++      */
++      WHERETRACE(0xffff, ("  ^^^^--- non-viable plan rejected!\n"));
++      return SQLITE_OK;
++    }
++    return rc;
++  }
+ 
+   mxTerm = -1;
+   assert( pNew->nLSlot>=nConstraint );
+@@ -137748,7 +142461,7 @@
+     if( pX->pLeft ){
+       pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight);
+     }
+-    zRet = (pC ? pC->zName : "BINARY");
++    zRet = (pC ? pC->zName : sqlite3StrBINARY);
+   }
+   return zRet;
+ }
+@@ -138040,9 +142753,11 @@
+   /* Loop over the tables in the join, from left to right */
+   pNew = pBuilder->pNew;
+   whereLoopInit(pNew);
++  pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
+   for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){
+     Bitmask mUnusable = 0;
+     pNew->iTab = iTab;
++    pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
+     pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
+     if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
+       /* This condition is true when pItem is the FROM clause term on the
+@@ -138064,11 +142779,19 @@
+     {
+       rc = whereLoopAddBtree(pBuilder, mPrereq);
+     }
+-    if( rc==SQLITE_OK ){
++    if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
+       rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
+     }
+     mPrior |= pNew->maskSelf;
+-    if( rc || db->mallocFailed ) break;
++    if( rc || db->mallocFailed ){
++      if( rc==SQLITE_DONE ){
++        /* We hit the query planner search limit set by iPlanLimit */
++        sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
++        rc = SQLITE_OK;
++      }else{
++        break;
++      }
++    }
+   }
+ 
+   whereLoopClear(db, pNew);
+@@ -138571,12 +143294,15 @@
+ 
+         if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+         if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+-        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
++        if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
+           /* Do not use an automatic index if the this loop is expected
+-          ** to run less than 2 times. */
++          ** to run less than 1.25 times.  It is tempting to also exclude
++          ** automatic index usage on an outer loop, but sometimes an automatic
++          ** index is useful in the outer loop of a correlated subquery. */
+           assert( 10==sqlite3LogEst(2) );
+           continue;
+         }
++
+         /* At this point, pWLoop is a candidate to be the next loop. 
+         ** Compute its cost */
+         rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+@@ -138596,7 +143322,11 @@
+                 pWInfo, nRowEst, nOrderBy, isOrdered
+             );
+           }
+-          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
++          /* TUNING:  Add a small extra penalty (5) to sorting as an
++          ** extra encouragment to the query planner to select a plan
++          ** where the rows emerge in the correct order without any sorting
++          ** required. */
++          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
+ 
+           WHERETRACE(0x002,
+               ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
+@@ -138786,6 +143516,7 @@
+       pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+     }
+   }
++  pWInfo->bOrderedInnerLoop = 0;
+   if( pWInfo->pOrderBy ){
+     if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
+       if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
+@@ -138897,7 +143628,7 @@
+       }
+       if( j!=pIdx->nKeyCol ) continue;
+       pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
+-      if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
++      if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){
+         pLoop->wsFlags |= WHERE_IDX_ONLY;
+       }
+       pLoop->nLTerm = j;
+@@ -139158,6 +143889,7 @@
+     if( wctrlFlags & WHERE_WANT_DISTINCT ){
+       pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+     }
++    ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
+   }else{
+     /* Assign a bit from the bitmask to every term in the FROM clause.
+     **
+@@ -139553,7 +144285,7 @@
+     }
+ #endif
+     addrExplain = sqlite3WhereExplainOneScan(
+-        pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
++        pParse, pTabList, pLevel, wctrlFlags
+     );
+     pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+     notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+@@ -139577,6 +144309,26 @@
+ }
+ 
+ /*
++** Part of sqlite3WhereEnd() will rewrite opcodes to reference the
++** index rather than the main table.  In SQLITE_DEBUG mode, we want
++** to trace those changes if PRAGMA vdbe_addoptrace=on.  This routine
++** does that.
++*/
++#ifndef SQLITE_DEBUG
++# define OpcodeRewriteTrace(D,K,P) /* no-op */
++#else
++# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P)
++  static void sqlite3WhereOpcodeRewriteTrace(
++    sqlite3 *db,
++    int pc,
++    VdbeOp *pOp
++  ){
++    if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
++    sqlite3VdbePrintOp(0, pc, pOp);
++  }
++#endif
++
++/*
+ ** Generate the end of the WHERE loop.  See comments on 
+ ** sqlite3WhereBegin() for additional information.
+ */
+@@ -139592,7 +144344,6 @@
+   /* Generate loop termination code.
+   */
+   VdbeModuleComment((v, "End WHERE-core"));
+-  sqlite3ExprCacheClear(pParse);
+   for(i=pWInfo->nLevel-1; i>=0; i--){
+     int addr;
+     pLevel = &pWInfo->a[i];
+@@ -139643,10 +144394,17 @@
+       for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
+         sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
+         if( pIn->eEndLoopOp!=OP_Noop ){
++          if( pIn->nPrefix ){
++            assert( pLoop->wsFlags & WHERE_IN_EARLYOUT );
++            sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur,
++                              sqlite3VdbeCurrentAddr(v)+2,
++                              pIn->iBase, pIn->nPrefix);
++            VdbeCoverage(v);
++          }
+           sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+           VdbeCoverage(v);
+-          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+-          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev);
++          VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next);
+         }
+         sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
+       }
+@@ -139737,6 +144495,11 @@
+     ){
+       last = sqlite3VdbeCurrentAddr(v);
+       k = pLevel->addrBody;
++#ifdef SQLITE_DEBUG
++      if( db->flags & SQLITE_VdbeAddopTrace ){
++        printf("TRANSLATE opcodes in range %d..%d\n", k, last-1);
++      }
++#endif
+       pOp = sqlite3VdbeGetOp(v, k);
+       for(; k<last; k++, pOp++){
+         if( pOp->p1!=pLevel->iTabCur ) continue;
+@@ -139756,6 +144519,7 @@
+           if( x>=0 ){
+             pOp->p2 = x;
+             pOp->p1 = pLevel->iIdxCur;
++            OpcodeRewriteTrace(db, k, pOp);
+           }
+           assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 
+               || pWInfo->eOnePass );
+@@ -139762,10 +144526,15 @@
+         }else if( pOp->opcode==OP_Rowid ){
+           pOp->p1 = pLevel->iIdxCur;
+           pOp->opcode = OP_IdxRowid;
++          OpcodeRewriteTrace(db, k, pOp);
+         }else if( pOp->opcode==OP_IfNullRow ){
+           pOp->p1 = pLevel->iIdxCur;
++          OpcodeRewriteTrace(db, k, pOp);
+         }
+       }
++#ifdef SQLITE_DEBUG
++      if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n");
++#endif
+     }
+   }
+ 
+@@ -139777,6 +144546,2263 @@
+ }
+ 
+ /************** End of where.c ***********************************************/
++/************** Begin file window.c ******************************************/
++/*
++** 2018 May 08
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++*/
++/* #include "sqliteInt.h" */
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++
++/*
++** SELECT REWRITING
++**
++**   Any SELECT statement that contains one or more window functions in
++**   either the select list or ORDER BY clause (the only two places window
++**   functions may be used) is transformed by function sqlite3WindowRewrite()
++**   in order to support window function processing. For example, with the
++**   schema:
++**
++**     CREATE TABLE t1(a, b, c, d, e, f, g);
++**
++**   the statement:
++**
++**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e;
++**
++**   is transformed to:
++**
++**     SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM (
++**         SELECT a, e, c, d, b FROM t1 ORDER BY c, d
++**     ) ORDER BY e;
++**
++**   The flattening optimization is disabled when processing this transformed
++**   SELECT statement. This allows the implementation of the window function
++**   (in this case max()) to process rows sorted in order of (c, d), which
++**   makes things easier for obvious reasons. More generally:
++**
++**     * FROM, WHERE, GROUP BY and HAVING clauses are all moved to 
++**       the sub-query.
++**
++**     * ORDER BY, LIMIT and OFFSET remain part of the parent query.
++**
++**     * Terminals from each of the expression trees that make up the 
++**       select-list and ORDER BY expressions in the parent query are
++**       selected by the sub-query. For the purposes of the transformation,
++**       terminals are column references and aggregate functions.
++**
++**   If there is more than one window function in the SELECT that uses
++**   the same window declaration (the OVER bit), then a single scan may
++**   be used to process more than one window function. For example:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
++**            min(e) OVER (PARTITION BY c ORDER BY d) 
++**     FROM t1;
++**
++**   is transformed in the same way as the example above. However:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d), 
++**            min(e) OVER (PARTITION BY a ORDER BY b) 
++**     FROM t1;
++**
++**   Must be transformed to:
++**
++**     SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM (
++**         SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM
++**           SELECT a, e, c, d, b FROM t1 ORDER BY a, b
++**         ) ORDER BY c, d
++**     ) ORDER BY e;
++**
++**   so that both min() and max() may process rows in the order defined by
++**   their respective window declarations.
++**
++** INTERFACE WITH SELECT.C
++**
++**   When processing the rewritten SELECT statement, code in select.c calls
++**   sqlite3WhereBegin() to begin iterating through the results of the
++**   sub-query, which is always implemented as a co-routine. It then calls
++**   sqlite3WindowCodeStep() to process rows and finish the scan by calling
++**   sqlite3WhereEnd().
++**
++**   sqlite3WindowCodeStep() generates VM code so that, for each row returned
++**   by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked.
++**   When the sub-routine is invoked:
++**
++**     * The results of all window-functions for the row are stored
++**       in the associated Window.regResult registers.
++**
++**     * The required terminal values are stored in the current row of
++**       temp table Window.iEphCsr.
++**
++**   In some cases, depending on the window frame and the specific window
++**   functions invoked, sqlite3WindowCodeStep() caches each entire partition
++**   in a temp table before returning any rows. In other cases it does not.
++**   This detail is encapsulated within this file, the code generated by
++**   select.c is the same in either case.
++**
++** BUILT-IN WINDOW FUNCTIONS
++**
++**   This implementation features the following built-in window functions:
++**
++**     row_number()
++**     rank()
++**     dense_rank()
++**     percent_rank()
++**     cume_dist()
++**     ntile(N)
++**     lead(expr [, offset [, default]])
++**     lag(expr [, offset [, default]])
++**     first_value(expr)
++**     last_value(expr)
++**     nth_value(expr, N)
++**   
++**   These are the same built-in window functions supported by Postgres. 
++**   Although the behaviour of aggregate window functions (functions that
++**   can be used as either aggregates or window funtions) allows them to
++**   be implemented using an API, built-in window functions are much more
++**   esoteric. Additionally, some window functions (e.g. nth_value()) 
++**   may only be implemented by caching the entire partition in memory.
++**   As such, some built-in window functions use the same API as aggregate
++**   window functions and some are implemented directly using VDBE 
++**   instructions. Additionally, for those functions that use the API, the
++**   window frame is sometimes modified before the SELECT statement is
++**   rewritten. For example, regardless of the specified window frame, the
++**   row_number() function always uses:
++**
++**     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   See sqlite3WindowUpdate() for details.
++**
++**   As well as some of the built-in window functions, aggregate window
++**   functions min() and max() are implemented using VDBE instructions if
++**   the start of the window frame is declared as anything other than 
++**   UNBOUNDED PRECEDING.
++*/
++
++/*
++** Implementation of built-in window function row_number(). Assumes that the
++** window frame has been coerced to:
++**
++**   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++*/
++static void row_numberStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ) (*p)++;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void row_numberValueFunc(sqlite3_context *pCtx){
++  i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  sqlite3_result_int64(pCtx, (p ? *p : 0));
++}
++
++/*
++** Context object type used by rank(), dense_rank(), percent_rank() and
++** cume_dist().
++*/
++struct CallCount {
++  i64 nValue;
++  i64 nStep;
++  i64 nTotal;
++};
++
++/*
++** Implementation of built-in window function dense_rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void dense_rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ) p->nStep = 1;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void dense_rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nStep ){
++      p->nValue++;
++      p->nStep = 0;
++    }
++    sqlite3_result_int64(pCtx, p->nValue);
++  }
++}
++
++/*
++** Implementation of built-in window function rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    p->nStep++;
++    if( p->nValue==0 ){
++      p->nValue = p->nStep;
++    }
++  }
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++}
++static void rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    sqlite3_result_int64(pCtx, p->nValue);
++    p->nValue = 0;
++  }
++}
++
++/*
++** Implementation of built-in window function percent_rank(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void percent_rankStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  UNUSED_PARAMETER(nArg); assert( nArg==1 );
++
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nTotal = sqlite3_value_int64(apArg[0]);
++    }
++    p->nStep++;
++    if( p->nValue==0 ){
++      p->nValue = p->nStep;
++    }
++  }
++}
++static void percent_rankValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal>1 ){
++      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
++      sqlite3_result_double(pCtx, r);
++    }else{
++      sqlite3_result_double(pCtx, 0.0);
++    }
++    p->nValue = 0;
++  }
++}
++
++/*
++** Implementation of built-in window function cume_dist(). Assumes that
++** the window frame has been set to:
++**
++**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++*/
++static void cume_distStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct CallCount *p;
++  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
++
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nTotal = sqlite3_value_int64(apArg[0]);
++    }
++    p->nStep++;
++  }
++}
++static void cume_distValueFunc(sqlite3_context *pCtx){
++  struct CallCount *p;
++  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->nTotal ){
++    double r = (double)(p->nStep) / (double)(p->nTotal);
++    sqlite3_result_double(pCtx, r);
++  }
++}
++
++/*
++** Context object for ntile() window function.
++*/
++struct NtileCtx {
++  i64 nTotal;                     /* Total rows in partition */
++  i64 nParam;                     /* Parameter passed to ntile(N) */
++  i64 iRow;                       /* Current row */
++};
++
++/*
++** Implementation of ntile(). This assumes that the window frame has
++** been coerced to:
++**
++**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
++*/
++static void ntileStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct NtileCtx *p;
++  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
++  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    if( p->nTotal==0 ){
++      p->nParam = sqlite3_value_int64(apArg[0]);
++      p->nTotal = sqlite3_value_int64(apArg[1]);
++      if( p->nParam<=0 ){
++        sqlite3_result_error(
++            pCtx, "argument of ntile must be a positive integer", -1
++        );
++      }
++    }
++    p->iRow++;
++  }
++}
++static void ntileValueFunc(sqlite3_context *pCtx){
++  struct NtileCtx *p;
++  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->nParam>0 ){
++    int nSize = (p->nTotal / p->nParam);
++    if( nSize==0 ){
++      sqlite3_result_int64(pCtx, p->iRow);
++    }else{
++      i64 nLarge = p->nTotal - p->nParam*nSize;
++      i64 iSmall = nLarge*(nSize+1);
++      i64 iRow = p->iRow-1;
++
++      assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
++
++      if( iRow<iSmall ){
++        sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
++      }else{
++        sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
++      }
++    }
++  }
++}
++
++/*
++** Context object for last_value() window function.
++*/
++struct LastValueCtx {
++  sqlite3_value *pVal;
++  int nVal;
++};
++
++/*
++** Implementation of last_value().
++*/
++static void last_valueStepFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct LastValueCtx *p;
++  UNUSED_PARAMETER(nArg);
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p ){
++    sqlite3_value_free(p->pVal);
++    p->pVal = sqlite3_value_dup(apArg[0]);
++    if( p->pVal==0 ){
++      sqlite3_result_error_nomem(pCtx);
++    }else{
++      p->nVal++;
++    }
++  }
++}
++static void last_valueInvFunc(
++  sqlite3_context *pCtx, 
++  int nArg,
++  sqlite3_value **apArg
++){
++  struct LastValueCtx *p;
++  UNUSED_PARAMETER(nArg);
++  UNUSED_PARAMETER(apArg);
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( ALWAYS(p) ){
++    p->nVal--;
++    if( p->nVal==0 ){
++      sqlite3_value_free(p->pVal);
++      p->pVal = 0;
++    }
++  }
++}
++static void last_valueValueFunc(sqlite3_context *pCtx){
++  struct LastValueCtx *p;
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->pVal ){
++    sqlite3_result_value(pCtx, p->pVal);
++  }
++}
++static void last_valueFinalizeFunc(sqlite3_context *pCtx){
++  struct LastValueCtx *p;
++  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
++  if( p && p->pVal ){
++    sqlite3_result_value(pCtx, p->pVal);
++    sqlite3_value_free(p->pVal);
++    p->pVal = 0;
++  }
++}
++
++/*
++** Static names for the built-in window function names.  These static
++** names are used, rather than string literals, so that FuncDef objects
++** can be associated with a particular window function by direct
++** comparison of the zName pointer.  Example:
++**
++**       if( pFuncDef->zName==row_valueName ){ ... }
++*/
++static const char row_numberName[] =   "row_number";
++static const char dense_rankName[] =   "dense_rank";
++static const char rankName[] =         "rank";
++static const char percent_rankName[] = "percent_rank";
++static const char cume_distName[] =    "cume_dist";
++static const char ntileName[] =        "ntile";
++static const char last_valueName[] =   "last_value";
++static const char nth_valueName[] =    "nth_value";
++static const char first_valueName[] =  "first_value";
++static const char leadName[] =         "lead";
++static const char lagName[] =          "lag";
++
++/*
++** No-op implementations of xStep() and xFinalize().  Used as place-holders
++** for built-in window functions that never call those interfaces.
++**
++** The noopValueFunc() is called but is expected to do nothing.  The
++** noopStepFunc() is never called, and so it is marked with NO_TEST to
++** let the test coverage routine know not to expect this function to be
++** invoked.
++*/
++static void noopStepFunc(    /*NO_TEST*/
++  sqlite3_context *p,        /*NO_TEST*/
++  int n,                     /*NO_TEST*/
++  sqlite3_value **a          /*NO_TEST*/
++){                           /*NO_TEST*/
++  UNUSED_PARAMETER(p);       /*NO_TEST*/
++  UNUSED_PARAMETER(n);       /*NO_TEST*/
++  UNUSED_PARAMETER(a);       /*NO_TEST*/
++  assert(0);                 /*NO_TEST*/
++}                            /*NO_TEST*/
++static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
++
++/* Window functions that use all window interfaces: xStep, xFinal,
++** xValue, and xInverse */
++#define WINDOWFUNCALL(name,nArg,extra) {                                   \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc,               \
++  name ## InvFunc, name ## Name, {0}                                       \
++}
++
++/* Window functions that are implemented using bytecode and thus have
++** no-op routines for their methods */
++#define WINDOWFUNCNOOP(name,nArg,extra) {                                  \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  noopStepFunc, noopValueFunc, noopValueFunc,                              \
++  noopStepFunc, name ## Name, {0}                                          \
++}
++
++/* Window functions that use all window interfaces: xStep, the
++** same routine for xFinalize and xValue and which never call
++** xInverse. */
++#define WINDOWFUNCX(name,nArg,extra) {                                     \
++  nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0,                      \
++  name ## StepFunc, name ## ValueFunc, name ## ValueFunc,                  \
++  noopStepFunc, name ## Name, {0}                                          \
++}
++
++
++/*
++** Register those built-in window functions that are not also aggregates.
++*/
++SQLITE_PRIVATE void sqlite3WindowFunctions(void){
++  static FuncDef aWindowFuncs[] = {
++    WINDOWFUNCX(row_number, 0, 0),
++    WINDOWFUNCX(dense_rank, 0, 0),
++    WINDOWFUNCX(rank, 0, 0),
++    WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
++    WINDOWFUNCALL(last_value, 1, 0),
++    WINDOWFUNCNOOP(nth_value, 2, 0),
++    WINDOWFUNCNOOP(first_value, 1, 0),
++    WINDOWFUNCNOOP(lead, 1, 0),
++    WINDOWFUNCNOOP(lead, 2, 0),
++    WINDOWFUNCNOOP(lead, 3, 0),
++    WINDOWFUNCNOOP(lag, 1, 0),
++    WINDOWFUNCNOOP(lag, 2, 0),
++    WINDOWFUNCNOOP(lag, 3, 0),
++  };
++  sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
++}
++
++/*
++** This function is called immediately after resolving the function name
++** for a window function within a SELECT statement. Argument pList is a
++** linked list of WINDOW definitions for the current SELECT statement.
++** Argument pFunc is the function definition just resolved and pWin
++** is the Window object representing the associated OVER clause. This
++** function updates the contents of pWin as follows:
++**
++**   * If the OVER clause refered to a named window (as in "max(x) OVER win"),
++**     search list pList for a matching WINDOW definition, and update pWin
++**     accordingly. If no such WINDOW clause can be found, leave an error
++**     in pParse.
++**
++**   * If the function is a built-in window function that requires the
++**     window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top
++**     of this file), pWin is updated here.
++*/
++SQLITE_PRIVATE void sqlite3WindowUpdate(
++  Parse *pParse, 
++  Window *pList,                  /* List of named windows for this SELECT */
++  Window *pWin,                   /* Window frame to update */
++  FuncDef *pFunc                  /* Window function definition */
++){
++  if( pWin->zName && pWin->eType==0 ){
++    Window *p;
++    for(p=pList; p; p=p->pNextWin){
++      if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
++    }
++    if( p==0 ){
++      sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
++      return;
++    }
++    pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
++    pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
++    pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
++    pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
++    pWin->eStart = p->eStart;
++    pWin->eEnd = p->eEnd;
++    pWin->eType = p->eType;
++  }
++  if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
++    sqlite3 *db = pParse->db;
++    if( pWin->pFilter ){
++      sqlite3ErrorMsg(pParse, 
++          "FILTER clause may only be used with aggregate window functions"
++      );
++    }else
++    if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
++      sqlite3ExprDelete(db, pWin->pStart);
++      sqlite3ExprDelete(db, pWin->pEnd);
++      pWin->pStart = pWin->pEnd = 0;
++      pWin->eType = TK_ROWS;
++      pWin->eStart = TK_UNBOUNDED;
++      pWin->eEnd = TK_CURRENT;
++    }else
++
++    if( pFunc->zName==dense_rankName || pFunc->zName==rankName
++     || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
++    ){
++      sqlite3ExprDelete(db, pWin->pStart);
++      sqlite3ExprDelete(db, pWin->pEnd);
++      pWin->pStart = pWin->pEnd = 0;
++      pWin->eType = TK_RANGE;
++      pWin->eStart = TK_UNBOUNDED;
++      pWin->eEnd = TK_CURRENT;
++    }
++  }
++  pWin->pFunc = pFunc;
++}
++
++/*
++** Context object passed through sqlite3WalkExprList() to
++** selectWindowRewriteExprCb() by selectWindowRewriteEList().
++*/
++typedef struct WindowRewrite WindowRewrite;
++struct WindowRewrite {
++  Window *pWin;
++  SrcList *pSrc;
++  ExprList *pSub;
++  Select *pSubSelect;             /* Current sub-select, if any */
++};
++
++/*
++** Callback function used by selectWindowRewriteEList(). If necessary,
++** this function appends to the output expression-list and updates 
++** expression (*ppExpr) in place.
++*/
++static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
++  struct WindowRewrite *p = pWalker->u.pRewrite;
++  Parse *pParse = pWalker->pParse;
++
++  /* If this function is being called from within a scalar sub-select
++  ** that used by the SELECT statement being processed, only process
++  ** TK_COLUMN expressions that refer to it (the outer SELECT). Do
++  ** not process aggregates or window functions at all, as they belong
++  ** to the scalar sub-select.  */
++  if( p->pSubSelect ){
++    if( pExpr->op!=TK_COLUMN ){
++      return WRC_Continue;
++    }else{
++      int nSrc = p->pSrc->nSrc;
++      int i;
++      for(i=0; i<nSrc; i++){
++        if( pExpr->iTable==p->pSrc->a[i].iCursor ) break;
++      }
++      if( i==nSrc ) return WRC_Continue;
++    }
++  }
++
++  switch( pExpr->op ){
++
++    case TK_FUNCTION:
++      if( !ExprHasProperty(pExpr, EP_WinFunc) ){
++        break;
++      }else{
++        Window *pWin;
++        for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
++          if( pExpr->y.pWin==pWin ){
++            assert( pWin->pOwner==pExpr );
++            return WRC_Prune;
++          }
++        }
++      }
++      /* Fall through.  */
++
++    case TK_AGG_FUNCTION:
++    case TK_COLUMN: {
++      Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
++      p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
++      if( p->pSub ){
++        assert( ExprHasProperty(pExpr, EP_Static)==0 );
++        ExprSetProperty(pExpr, EP_Static);
++        sqlite3ExprDelete(pParse->db, pExpr);
++        ExprClearProperty(pExpr, EP_Static);
++        memset(pExpr, 0, sizeof(Expr));
++
++        pExpr->op = TK_COLUMN;
++        pExpr->iColumn = p->pSub->nExpr-1;
++        pExpr->iTable = p->pWin->iEphCsr;
++      }
++
++      break;
++    }
++
++    default: /* no-op */
++      break;
++  }
++
++  return WRC_Continue;
++}
++static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){
++  struct WindowRewrite *p = pWalker->u.pRewrite;
++  Select *pSave = p->pSubSelect;
++  if( pSave==pSelect ){
++    return WRC_Continue;
++  }else{
++    p->pSubSelect = pSelect;
++    sqlite3WalkSelect(pWalker, pSelect);
++    p->pSubSelect = pSave;
++  }
++  return WRC_Prune;
++}
++
++
++/*
++** Iterate through each expression in expression-list pEList. For each:
++**
++**   * TK_COLUMN,
++**   * aggregate function, or
++**   * window function with a Window object that is not a member of the 
++**     Window list passed as the second argument (pWin).
++**
++** Append the node to output expression-list (*ppSub). And replace it
++** with a TK_COLUMN that reads the (N-1)th element of table 
++** pWin->iEphCsr, where N is the number of elements in (*ppSub) after
++** appending the new one.
++*/
++static void selectWindowRewriteEList(
++  Parse *pParse, 
++  Window *pWin,
++  SrcList *pSrc,
++  ExprList *pEList,               /* Rewrite expressions in this list */
++  ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
++){
++  Walker sWalker;
++  WindowRewrite sRewrite;
++
++  memset(&sWalker, 0, sizeof(Walker));
++  memset(&sRewrite, 0, sizeof(WindowRewrite));
++
++  sRewrite.pSub = *ppSub;
++  sRewrite.pWin = pWin;
++  sRewrite.pSrc = pSrc;
++
++  sWalker.pParse = pParse;
++  sWalker.xExprCallback = selectWindowRewriteExprCb;
++  sWalker.xSelectCallback = selectWindowRewriteSelectCb;
++  sWalker.u.pRewrite = &sRewrite;
++
++  (void)sqlite3WalkExprList(&sWalker, pEList);
++
++  *ppSub = sRewrite.pSub;
++}
++
++/*
++** Append a copy of each expression in expression-list pAppend to
++** expression list pList. Return a pointer to the result list.
++*/
++static ExprList *exprListAppendList(
++  Parse *pParse,          /* Parsing context */
++  ExprList *pList,        /* List to which to append. Might be NULL */
++  ExprList *pAppend       /* List of values to append. Might be NULL */
++){
++  if( pAppend ){
++    int i;
++    int nInit = pList ? pList->nExpr : 0;
++    for(i=0; i<pAppend->nExpr; i++){
++      Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
++      pList = sqlite3ExprListAppend(pParse, pList, pDup);
++      if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
++    }
++  }
++  return pList;
++}
++
++/*
++** If the SELECT statement passed as the second argument does not invoke
++** any SQL window functions, this function is a no-op. Otherwise, it 
++** rewrites the SELECT statement so that window function xStep functions
++** are invoked in the correct order as described under "SELECT REWRITING"
++** at the top of this file.
++*/
++SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
++  int rc = SQLITE_OK;
++  if( p->pWin && p->pPrior==0 ){
++    Vdbe *v = sqlite3GetVdbe(pParse);
++    sqlite3 *db = pParse->db;
++    Select *pSub = 0;             /* The subquery */
++    SrcList *pSrc = p->pSrc;
++    Expr *pWhere = p->pWhere;
++    ExprList *pGroupBy = p->pGroupBy;
++    Expr *pHaving = p->pHaving;
++    ExprList *pSort = 0;
++
++    ExprList *pSublist = 0;       /* Expression list for sub-query */
++    Window *pMWin = p->pWin;      /* Master window object */
++    Window *pWin;                 /* Window object iterator */
++
++    p->pSrc = 0;
++    p->pWhere = 0;
++    p->pGroupBy = 0;
++    p->pHaving = 0;
++
++    /* Create the ORDER BY clause for the sub-select. This is the concatenation
++    ** of the window PARTITION and ORDER BY clauses. Then, if this makes it
++    ** redundant, remove the ORDER BY from the parent SELECT.  */
++    pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
++    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
++    if( pSort && p->pOrderBy ){
++      if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
++        sqlite3ExprListDelete(db, p->pOrderBy);
++        p->pOrderBy = 0;
++      }
++    }
++
++    /* Assign a cursor number for the ephemeral table used to buffer rows.
++    ** The OpenEphemeral instruction is coded later, after it is known how
++    ** many columns the table will have.  */
++    pMWin->iEphCsr = pParse->nTab++;
++
++    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
++    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
++    pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
++
++    /* Append the PARTITION BY and ORDER BY expressions to the to the 
++    ** sub-select expression list. They are required to figure out where 
++    ** boundaries for partitions and sets of peer rows lie.  */
++    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
++    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
++
++    /* Append the arguments passed to each window function to the
++    ** sub-select expression list. Also allocate two registers for each
++    ** window function - one for the accumulator, another for interim
++    ** results.  */
++    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++      pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
++      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
++      if( pWin->pFilter ){
++        Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
++        pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
++      }
++      pWin->regAccum = ++pParse->nMem;
++      pWin->regResult = ++pParse->nMem;
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++    }
++
++    /* If there is no ORDER BY or PARTITION BY clause, and the window
++    ** function accepts zero arguments, and there are no other columns
++    ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible
++    ** that pSublist is still NULL here. Add a constant expression here to 
++    ** keep everything legal in this case. 
++    */
++    if( pSublist==0 ){
++      pSublist = sqlite3ExprListAppend(pParse, 0, 
++          sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0)
++      );
++    }
++
++    pSub = sqlite3SelectNew(
++        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
++    );
++    p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
++    assert( p->pSrc || db->mallocFailed );
++    if( p->pSrc ){
++      p->pSrc->a[0].pSelect = pSub;
++      sqlite3SrcListAssignCursors(pParse, p->pSrc);
++      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
++        rc = SQLITE_NOMEM;
++      }else{
++        pSub->selFlags |= SF_Expanded;
++        p->selFlags &= ~SF_Aggregate;
++        sqlite3SelectPrep(pParse, pSub, 0);
++      }
++
++      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
++    }else{
++      sqlite3SelectDelete(db, pSub);
++    }
++    if( db->mallocFailed ) rc = SQLITE_NOMEM;
++  }
++
++  return rc;
++}
++
++/*
++** Free the Window object passed as the second argument.
++*/
++SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){
++  if( p ){
++    sqlite3ExprDelete(db, p->pFilter);
++    sqlite3ExprListDelete(db, p->pPartition);
++    sqlite3ExprListDelete(db, p->pOrderBy);
++    sqlite3ExprDelete(db, p->pEnd);
++    sqlite3ExprDelete(db, p->pStart);
++    sqlite3DbFree(db, p->zName);
++    sqlite3DbFree(db, p);
++  }
++}
++
++/*
++** Free the linked list of Window objects starting at the second argument.
++*/
++SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
++  while( p ){
++    Window *pNext = p->pNextWin;
++    sqlite3WindowDelete(db, p);
++    p = pNext;
++  }
++}
++
++/*
++** The argument expression is an PRECEDING or FOLLOWING offset.  The
++** value should be a non-negative integer.  If the value is not a
++** constant, change it to NULL.  The fact that it is then a non-negative
++** integer will be caught later.  But it is important not to leave
++** variable values in the expression tree.
++*/
++static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
++  if( 0==sqlite3ExprIsConstant(pExpr) ){
++    sqlite3ExprDelete(pParse->db, pExpr);
++    pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
++  }
++  return pExpr;
++}
++
++/*
++** Allocate and return a new Window object describing a Window Definition.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowAlloc(
++  Parse *pParse,    /* Parsing context */
++  int eType,        /* Frame type. TK_RANGE or TK_ROWS */
++  int eStart,       /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
++  Expr *pStart,     /* Start window size if TK_PRECEDING or FOLLOWING */
++  int eEnd,         /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
++  Expr *pEnd        /* End window size if TK_FOLLOWING or PRECEDING */
++){
++  Window *pWin = 0;
++
++  /* Parser assures the following: */
++  assert( eType==TK_RANGE || eType==TK_ROWS );
++  assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
++           || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
++  assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
++           || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
++  assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
++  assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
++
++
++  /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
++  ** either "<expr> PRECEDING" or "<expr> FOLLOWING".
++  */
++  if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
++    sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
++    goto windowAllocErr;
++  }
++
++  /* Additionally, the
++  ** starting boundary type may not occur earlier in the following list than
++  ** the ending boundary type:
++  **
++  **   UNBOUNDED PRECEDING
++  **   <expr> PRECEDING
++  **   CURRENT ROW
++  **   <expr> FOLLOWING
++  **   UNBOUNDED FOLLOWING
++  **
++  ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
++  ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
++  ** frame boundary.
++  */
++  if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
++   || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
++  ){
++    sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
++    goto windowAllocErr;
++  }
++
++  pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
++  if( pWin==0 ) goto windowAllocErr;
++  pWin->eType = eType;
++  pWin->eStart = eStart;
++  pWin->eEnd = eEnd;
++  pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
++  pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
++  return pWin;
++
++windowAllocErr:
++  sqlite3ExprDelete(pParse->db, pEnd);
++  sqlite3ExprDelete(pParse->db, pStart);
++  return 0;
++}
++
++/*
++** Attach window object pWin to expression p.
++*/
++SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
++  if( p ){
++    assert( p->op==TK_FUNCTION );
++    /* This routine is only called for the parser.  If pWin was not
++    ** allocated due to an OOM, then the parser would fail before ever
++    ** invoking this routine */
++    if( ALWAYS(pWin) ){
++      p->y.pWin = pWin;
++      ExprSetProperty(p, EP_WinFunc);
++      pWin->pOwner = p;
++      if( p->flags & EP_Distinct ){
++        sqlite3ErrorMsg(pParse,
++           "DISTINCT is not supported for window functions");
++      }
++    }
++  }else{
++    sqlite3WindowDelete(pParse->db, pWin);
++  }
++}
++
++/*
++** Return 0 if the two window objects are identical, or non-zero otherwise.
++** Identical window objects can be processed in a single scan.
++*/
++SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
++  if( p1->eType!=p2->eType ) return 1;
++  if( p1->eStart!=p2->eStart ) return 1;
++  if( p1->eEnd!=p2->eEnd ) return 1;
++  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
++  if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
++  if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
++  if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
++  return 0;
++}
++
++
++/*
++** This is called by code in select.c before it calls sqlite3WhereBegin()
++** to begin iterating through the sub-query results. It is used to allocate
++** and initialize registers and cursors used by sqlite3WindowCodeStep().
++*/
++SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
++  Window *pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
++  nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
++  if( nPart ){
++    pMWin->regPart = pParse->nMem+1;
++    pParse->nMem += nPart;
++    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
++  }
++
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *p = pWin->pFunc;
++    if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
++      /* The inline versions of min() and max() require a single ephemeral
++      ** table and 3 registers. The registers are used as follows:
++      **
++      **   regApp+0: slot to copy min()/max() argument to for MakeRecord
++      **   regApp+1: integer value used to ensure keys are unique
++      **   regApp+2: output of MakeRecord
++      */
++      ExprList *pList = pWin->pOwner->x.pList;
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
++      pWin->csrApp = pParse->nTab++;
++      pWin->regApp = pParse->nMem+1;
++      pParse->nMem += 3;
++      if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
++        assert( pKeyInfo->aSortOrder[0]==0 );
++        pKeyInfo->aSortOrder[0] = 1;
++      }
++      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
++      sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++    else if( p->zName==nth_valueName || p->zName==first_valueName ){
++      /* Allocate two registers at pWin->regApp. These will be used to
++      ** store the start and end index of the current frame.  */
++      assert( pMWin->iEphCsr );
++      pWin->regApp = pParse->nMem+1;
++      pWin->csrApp = pParse->nTab++;
++      pParse->nMem += 2;
++      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
++    }
++    else if( p->zName==leadName || p->zName==lagName ){
++      assert( pMWin->iEphCsr );
++      pWin->csrApp = pParse->nTab++;
++      sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
++    }
++  }
++}
++
++/*
++** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
++** value of the second argument to nth_value() (eCond==2) has just been
++** evaluated and the result left in register reg. This function generates VM
++** code to check that the value is a non-negative integer and throws an
++** exception if it is not.
++*/
++static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
++  static const char *azErr[] = {
++    "frame starting offset must be a non-negative integer",
++    "frame ending offset must be a non-negative integer",
++    "second argument to nth_value must be a positive integer"
++  };
++  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regZero = sqlite3GetTempReg(pParse);
++  assert( eCond==0 || eCond==1 || eCond==2 );
++  sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
++  sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverageIf(v, eCond==0);
++  VdbeCoverageIf(v, eCond==1);
++  VdbeCoverageIf(v, eCond==2);
++  sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
++  VdbeCoverageNeverNullIf(v, eCond==0);
++  VdbeCoverageNeverNullIf(v, eCond==1);
++  VdbeCoverageNeverNullIf(v, eCond==2);
++  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
++  sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
++  sqlite3ReleaseTempReg(pParse, regZero);
++}
++
++/*
++** Return the number of arguments passed to the window-function associated
++** with the object passed as the only argument to this function.
++*/
++static int windowArgCount(Window *pWin){
++  ExprList *pList = pWin->pOwner->x.pList;
++  return (pList ? pList->nExpr : 0);
++}
++
++/*
++** Generate VM code to invoke either xStep() (if bInverse is 0) or 
++** xInverse (if bInverse is non-zero) for each window function in the 
++** linked list starting at pMWin. Or, for built-in window functions
++** that do not use the standard function API, generate the required
++** inline VM code.
++**
++** If argument csr is greater than or equal to 0, then argument reg is
++** the first register in an array of registers guaranteed to be large
++** enough to hold the array of arguments for each function. In this case
++** the arguments are extracted from the current row of csr into the
++** array of registers before invoking OP_AggStep or OP_AggInverse
++**
++** Or, if csr is less than zero, then the array of registers at reg is
++** already populated with all columns from the current row of the sub-query.
++**
++** If argument regPartSize is non-zero, then it is a register containing the
++** number of rows in the current partition.
++*/
++static void windowAggStep(
++  Parse *pParse, 
++  Window *pMWin,                  /* Linked list of window functions */
++  int csr,                        /* Read arguments from this cursor */
++  int bInverse,                   /* True to invoke xInverse instead of xStep */
++  int reg,                        /* Array of registers */
++  int regPartSize                 /* Register containing size of partition */
++){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    int flags = pWin->pFunc->funcFlags;
++    int regArg;
++    int nArg = windowArgCount(pWin);
++
++    if( csr>=0 ){
++      int i;
++      for(i=0; i<nArg; i++){
++        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
++      }
++      regArg = reg;
++      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
++        if( nArg==0 ){
++          regArg = regPartSize;
++        }else{
++          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
++        }
++        nArg++;
++      }
++    }else{
++      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
++      regArg = reg + pWin->iArgCol;
++    }
++
++    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
++      && pWin->eStart!=TK_UNBOUNDED 
++    ){
++      int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
++      VdbeCoverage(v);
++      if( bInverse==0 ){
++        sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
++        sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
++        sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
++        sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2);
++      }else{
++        sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
++        VdbeCoverageNeverTaken(v);
++        sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
++        sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
++      }
++      sqlite3VdbeJumpHere(v, addrIsNull);
++    }else if( pWin->regApp ){
++      assert( pWin->pFunc->zName==nth_valueName
++           || pWin->pFunc->zName==first_valueName
++      );
++      assert( bInverse==0 || bInverse==1 );
++      sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
++    }else if( pWin->pFunc->zName==leadName
++           || pWin->pFunc->zName==lagName
++    ){
++      /* no-op */
++    }else{
++      int addrIf = 0;
++      if( pWin->pFilter ){
++        int regTmp;
++        assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
++        assert( nArg || pWin->pOwner->x.pList==0 );
++        if( csr>0 ){
++          regTmp = sqlite3GetTempReg(pParse);
++          sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
++        }else{
++          regTmp = regArg + nArg;
++        }
++        addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
++        VdbeCoverage(v);
++        if( csr>0 ){
++          sqlite3ReleaseTempReg(pParse, regTmp);
++        }
++      }
++      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
++        CollSeq *pColl;
++        assert( nArg>0 );
++        pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
++        sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
++      }
++      sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
++                        bInverse, regArg, pWin->regAccum);
++      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++      sqlite3VdbeChangeP5(v, (u8)nArg);
++      if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
++    }
++  }
++}
++
++/*
++** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
++** (bFinal==1) for each window function in the linked list starting at
++** pMWin. Or, for built-in window-functions that do not use the standard
++** API, generate the equivalent VM code.
++*/
++static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
++     && pWin->eStart!=TK_UNBOUNDED 
++    ){
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++      sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
++      sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
++      if( bFinal ){
++        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
++      }
++    }else if( pWin->regApp ){
++    }else{
++      if( bFinal ){
++        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
++        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++        sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
++        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++      }else{
++        sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
++                             pWin->regResult);
++        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
++      }
++    }
++  }
++}
++
++/*
++** This function generates VM code to invoke the sub-routine at address
++** lblFlushPart once for each partition with the entire partition cached in
++** the Window.iEphCsr temp table.
++*/
++static void windowPartitionCache(
++  Parse *pParse,
++  Select *p,                      /* The rewritten SELECT statement */
++  WhereInfo *pWInfo,              /* WhereInfo to call WhereEnd() on */
++  int regFlushPart,               /* Register to use with Gosub lblFlushPart */
++  int lblFlushPart,               /* Subroutine to Gosub to */
++  int *pRegSize                   /* OUT: Register containing partition size */
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int iSubCsr = p->pSrc->a[0].iCursor;
++  int nSub = p->pSrc->a[0].pTab->nCol;
++  int k;
++
++  int reg = pParse->nMem+1;
++  int regRecord = reg+nSub;
++  int regRowid = regRecord+1;
++
++  *pRegSize = regRowid;
++  pParse->nMem += nSub + 2;
++
++  /* Load the column values for the row returned by the sub-select
++  ** into an array of registers starting at reg. */
++  for(k=0; k<nSub; k++){
++    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
++  }
++  sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
++
++  /* Check if this is the start of a new partition. If so, call the
++  ** flush_partition sub-routine.  */
++  if( pMWin->pPartition ){
++    int addr;
++    ExprList *pPart = pMWin->pPartition;
++    int nPart = pPart->nExpr;
++    int regNewPart = reg + pMWin->nBufferCol;
++    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
++
++    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
++    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
++    VdbeCoverageEqNe(v);
++    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
++    sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
++    VdbeComment((v, "call flush_partition"));
++  }
++
++  /* Buffer the current row in the ephemeral table. */
++  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
++  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
++
++  /* End of the input loop */
++  sqlite3WhereEnd(pWInfo);
++
++  /* Invoke "flush_partition" to deal with the final (or only) partition */
++  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
++  VdbeComment((v, "call flush_partition"));
++}
++
++/*
++** Invoke the sub-routine at regGosub (generated by code in select.c) to
++** return the current row of Window.iEphCsr. If all window functions are
++** aggregate window functions that use the standard API, a single
++** OP_Gosub instruction is all that this routine generates. Extra VM code
++** for per-row processing is only generated for the following built-in window
++** functions:
++**
++**   nth_value()
++**   first_value()
++**   lag()
++**   lead()
++*/
++static void windowReturnOneRow(
++  Parse *pParse,
++  Window *pMWin,
++  int regGosub,
++  int addrGosub
++){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *pFunc = pWin->pFunc;
++    if( pFunc->zName==nth_valueName
++     || pFunc->zName==first_valueName
++    ){
++      int csr = pWin->csrApp;
++      int lbl = sqlite3VdbeMakeLabel(v);
++      int tmpReg = sqlite3GetTempReg(pParse);
++      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++
++      if( pFunc->zName==nth_valueName ){
++        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
++        windowCheckIntValue(pParse, tmpReg, 2);
++      }else{
++        sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
++      }
++      sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
++      sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
++      VdbeCoverageNeverNull(v);
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
++      VdbeCoverageNeverTaken(v);
++      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
++      sqlite3VdbeResolveLabel(v, lbl);
++      sqlite3ReleaseTempReg(pParse, tmpReg);
++    }
++    else if( pFunc->zName==leadName || pFunc->zName==lagName ){
++      int nArg = pWin->pOwner->x.pList->nExpr;
++      int iEph = pMWin->iEphCsr;
++      int csr = pWin->csrApp;
++      int lbl = sqlite3VdbeMakeLabel(v);
++      int tmpReg = sqlite3GetTempReg(pParse);
++
++      if( nArg<3 ){
++        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
++      }else{
++        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
++      }
++      sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
++      if( nArg<2 ){
++        int val = (pFunc->zName==leadName ? 1 : -1);
++        sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
++      }else{
++        int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
++        int tmpReg2 = sqlite3GetTempReg(pParse);
++        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
++        sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
++        sqlite3ReleaseTempReg(pParse, tmpReg2);
++      }
++
++      sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
++      sqlite3VdbeResolveLabel(v, lbl);
++      sqlite3ReleaseTempReg(pParse, tmpReg);
++    }
++  }
++  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++}
++
++/*
++** Invoke the code generated by windowReturnOneRow() and, optionally, the
++** xInverse() function for each window function, for one or more rows
++** from the Window.iEphCsr temp table. This routine generates VM code
++** similar to:
++**
++**   while( regCtr>0 ){
++**     regCtr--;
++**     windowReturnOneRow()
++**     if( bInverse ){
++**       AggInverse
++**     }
++**     Next (Window.iEphCsr)
++**   }
++*/
++static void windowReturnRows(
++  Parse *pParse,
++  Window *pMWin,                  /* List of window functions */
++  int regCtr,                     /* Register containing number of rows */
++  int regGosub,                   /* Register for Gosub addrGosub */
++  int addrGosub,                  /* Address of sub-routine for ReturnOneRow */
++  int regInvArg,                  /* Array of registers for xInverse args */
++  int regInvSize                  /* Register containing size of partition */
++){
++  int addr;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  windowAggFinal(pParse, pMWin, 0);
++  addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
++  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
++  if( regInvArg ){
++    windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
++  }
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
++  VdbeCoverage(v);
++  sqlite3VdbeJumpHere(v, addr+1);   /* The OP_Goto */
++}
++
++/*
++** Generate code to set the accumulator register for each window function
++** in the linked list passed as the second argument to NULL. And perform
++** any equivalent initialization required by any built-in window functions
++** in the list.
++*/
++static int windowInitAccum(Parse *pParse, Window *pMWin){
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regArg;
++  int nArg = 0;
++  Window *pWin;
++  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++    FuncDef *pFunc = pWin->pFunc;
++    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
++    nArg = MAX(nArg, windowArgCount(pWin));
++    if( pFunc->zName==nth_valueName
++     || pFunc->zName==first_valueName
++    ){
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++
++    if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
++      assert( pWin->eStart!=TK_UNBOUNDED );
++      sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
++      sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
++    }
++  }
++  regArg = pParse->nMem+1;
++  pParse->nMem += nArg;
++  return regArg;
++}
++
++
++/*
++** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
++** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
++** ROW". Pseudo-code for each follows.
++**
++** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
++**
++**     ...
++**       if( new partition ){
++**         Gosub flush_partition
++**       }
++**       Insert (record in eph-table)
++**     sqlite3WhereEnd()
++**     Gosub flush_partition
++**  
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrStart)
++**       OpenDup (iEphCsr -> csrEnd)
++**     }
++**     regStart = <expr1>                // PRECEDING expression
++**     regEnd = <expr2>                  // FOLLOWING expression
++**     if( regStart<0 || regEnd<0 ){ error! }
++**     Rewind (csr,csrStart,csrEnd)      // if EOF goto flush_partition_done
++**       Next(csrEnd)                    // if EOF skip Aggstep
++**       Aggstep (csrEnd)
++**       if( (regEnd--)<=0 ){
++**         AggFinal (xValue)
++**         Gosub addrGosub
++**         Next(csr)                // if EOF goto flush_partition_done
++**         if( (regStart--)<=0 ){
++**           AggInverse (csrStart)
++**           Next(csrStart)
++**         }
++**       }
++**   flush_partition_done:
++**     ResetSorter (csr)
++**     Return
++**
++** ROWS BETWEEN <expr> PRECEDING    AND CURRENT ROW
++** ROWS BETWEEN CURRENT ROW         AND <expr> FOLLOWING
++** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
++**
++**   These are similar to the above. For "CURRENT ROW", intialize the
++**   register to 0. For "UNBOUNDED PRECEDING" to infinity.
++**
++** ROWS BETWEEN <expr> PRECEDING    AND UNBOUNDED FOLLOWING
++** ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING
++**
++**     Rewind (csr,csrStart,csrEnd)    // if EOF goto flush_partition_done
++**     while( 1 ){
++**       Next(csrEnd)                  // Exit while(1) at EOF
++**       Aggstep (csrEnd)
++**     }
++**     while( 1 ){
++**       AggFinal (xValue)
++**       Gosub addrGosub
++**       Next(csr)                     // if EOF goto flush_partition_done
++**       if( (regStart--)<=0 ){
++**         AggInverse (csrStart)
++**         Next(csrStart)
++**       }
++**     }
++**
++**   For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() 
++**   condition is always true (as if regStart were initialized to 0).
++**
++** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++** 
++**   This is the only RANGE case handled by this routine. It modifies the
++**   second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
++**   be:
++**
++**     while( 1 ){
++**       AggFinal (xValue)
++**       while( 1 ){
++**         regPeer++
++**         Gosub addrGosub
++**         Next(csr)                     // if EOF goto flush_partition_done
++**         if( new peer ) break;
++**       }
++**       while( (regPeer--)>0 ){
++**         AggInverse (csrStart)
++**         Next(csrStart)
++**       }
++**     }
++**
++** ROWS BETWEEN <expr> FOLLOWING    AND <expr> FOLLOWING
++**
++**   regEnd = regEnd - regStart
++**   Rewind (csr,csrStart,csrEnd)   // if EOF goto flush_partition_done
++**     Aggstep (csrEnd)
++**     Next(csrEnd)                 // if EOF fall-through
++**     if( (regEnd--)<=0 ){
++**       if( (regStart--)<=0 ){
++**         AggFinal (xValue)
++**         Gosub addrGosub
++**         Next(csr)              // if EOF goto flush_partition_done
++**       }
++**       AggInverse (csrStart)
++**       Next (csrStart)
++**     }
++**
++** ROWS BETWEEN <expr> PRECEDING    AND <expr> PRECEDING
++**
++**   Replace the bit after "Rewind" in the above with:
++**
++**     if( (regEnd--)<=0 ){
++**       AggStep (csrEnd)
++**       Next (csrEnd)
++**     }
++**     AggFinal (xValue)
++**     Gosub addrGosub
++**     Next(csr)                  // if EOF goto flush_partition_done
++**     if( (regStart--)<=0 ){
++**       AggInverse (csr2)
++**       Next (csr2)
++**     }
++**
++*/
++static void windowCodeRowExprStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int regFlushPart;               /* Register for "Gosub flush_partition" */
++  int lblFlushPart;               /* Label for "Gosub flush_partition" */
++  int lblFlushDone;               /* Label for "Gosub flush_partition_done" */
++
++  int regArg;
++  int addr;
++  int csrStart = pParse->nTab++;
++  int csrEnd = pParse->nTab++;
++  int regStart;                    /* Value of <expr> PRECEDING */
++  int regEnd;                      /* Value of <expr> FOLLOWING */
++  int addrGoto;
++  int addrTop;
++  int addrIfPos1 = 0;
++  int addrIfPos2 = 0;
++  int regSize = 0;
++
++  assert( pMWin->eStart==TK_PRECEDING 
++       || pMWin->eStart==TK_CURRENT 
++       || pMWin->eStart==TK_FOLLOWING 
++       || pMWin->eStart==TK_UNBOUNDED 
++  );
++  assert( pMWin->eEnd==TK_FOLLOWING 
++       || pMWin->eEnd==TK_CURRENT 
++       || pMWin->eEnd==TK_UNBOUNDED 
++       || pMWin->eEnd==TK_PRECEDING 
++  );
++
++  /* Allocate register and label for the "flush_partition" sub-routine. */
++  regFlushPart = ++pParse->nMem;
++  lblFlushPart = sqlite3VdbeMakeLabel(v);
++  lblFlushDone = sqlite3VdbeMakeLabel(v);
++
++  regStart = ++pParse->nMem;
++  regEnd = ++pParse->nMem;
++
++  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
++
++  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++
++  /* Start of "flush_partition" */
++  sqlite3VdbeResolveLabel(v, lblFlushPart);
++  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
++  VdbeCoverage(v);
++  VdbeComment((v, "Flush_partition subroutine"));
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
++
++  /* If either regStart or regEnd are not non-negative integers, throw 
++  ** an exception.  */
++  if( pMWin->pStart ){
++    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
++    windowCheckIntValue(pParse, regStart, 0);
++  }
++  if( pMWin->pEnd ){
++    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
++    windowCheckIntValue(pParse, regEnd, 1);
++  }
++
++  /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
++  **
++  **   if( regEnd<regStart ){
++  **     // The frame always consists of 0 rows
++  **     regStart = regSize;
++  **   }
++  **   regEnd = regEnd - regStart;
++  */
++  if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
++    assert( pMWin->pStart!=0 );
++    assert( pMWin->eEnd==TK_FOLLOWING );
++    sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
++    VdbeCoverageNeverNull(v);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
++    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
++  }
++
++  if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
++    assert( pMWin->pEnd!=0 );
++    assert( pMWin->eStart==TK_PRECEDING );
++    sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
++    VdbeCoverageNeverNull(v);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
++    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
++  }
++
++  /* Initialize the accumulator register for each window function to NULL */
++  regArg = windowInitAccum(pParse, pMWin);
++
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
++  VdbeCoverageNeverTaken(v);
++  sqlite3VdbeChangeP5(v, 1);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
++  VdbeCoverageNeverTaken(v);
++  sqlite3VdbeChangeP5(v, 1);
++
++  /* Invoke AggStep function for each window function using the row that
++  ** csrEnd currently points to. Or, if csrEnd is already at EOF,
++  ** do nothing.  */
++  addrTop = sqlite3VdbeCurrentAddr(v);
++  if( pMWin->eEnd==TK_PRECEDING ){
++    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
++    VdbeCoverage(v);
++  }
++  sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  addr = sqlite3VdbeAddOp0(v, OP_Goto);
++  windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
++  if( pMWin->eEnd==TK_UNBOUNDED ){
++    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
++    sqlite3VdbeJumpHere(v, addr);
++    addrTop = sqlite3VdbeCurrentAddr(v);
++  }else{
++    sqlite3VdbeJumpHere(v, addr);
++    if( pMWin->eEnd==TK_PRECEDING ){
++      sqlite3VdbeJumpHere(v, addrIfPos1);
++    }
++  }
++
++  if( pMWin->eEnd==TK_FOLLOWING ){
++    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
++    VdbeCoverage(v);
++  }
++  if( pMWin->eStart==TK_FOLLOWING ){
++    addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
++    VdbeCoverage(v);
++  }
++  windowAggFinal(pParse, pMWin, 0);
++  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
++  if( pMWin->eStart==TK_FOLLOWING ){
++    sqlite3VdbeJumpHere(v, addrIfPos2);
++  }
++
++  if( pMWin->eStart==TK_CURRENT 
++   || pMWin->eStart==TK_PRECEDING 
++   || pMWin->eStart==TK_FOLLOWING 
++  ){
++    int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
++    if( pMWin->eStart==TK_PRECEDING ){
++      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
++      VdbeCoverage(v);
++    }
++    if( pMWin->eStart==TK_FOLLOWING ){
++      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
++    }else{
++      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
++      VdbeCoverageAlwaysTaken(v);
++    }
++    windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
++    sqlite3VdbeResolveLabel(v, lblSkipInverse);
++  }
++  if( pMWin->eEnd==TK_FOLLOWING ){
++    sqlite3VdbeJumpHere(v, addrIfPos1);
++  }
++  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
++
++  /* flush_partition_done: */
++  sqlite3VdbeResolveLabel(v, lblFlushDone);
++  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
++  VdbeComment((v, "end flush_partition subroutine"));
++
++  /* Jump to here to skip over flush_partition */
++  sqlite3VdbeJumpHere(v, addrGoto);
++}
++
++/*
++** This function does the work of sqlite3WindowCodeStep() for cases that
++** would normally be handled by windowCodeDefaultStep() when there are
++** one or more built-in window-functions that require the entire partition
++** to be cached in a temp table before any rows can be returned. Additionally.
++** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
++** this function.
++**
++** Pseudo-code corresponding to the VM code generated by this function
++** for each type of window follows.
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     Integer ctr 0
++**     foreach row (csrLead){
++**       if( new peer ){
++**         AggFinal (xValue)
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           Next iEphCsr
++**         }
++**         Integer ctr 0
++**       }
++**       AggStep (csrLead)
++**       Incr ctr
++**     }
++**
++**     AggFinal (xFinalize)
++**     for(i=0; i<ctr; i++){
++**       Gosub addrGosub
++**       Next iEphCsr
++**     }
++**
++**     ResetSorter (csr)
++**     Return
++**
++** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   As above, except that the "if( new peer )" branch is always taken.
++**
++** RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
++**
++**   As above, except that each of the for() loops becomes:
++**
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           AggInverse (iEphCsr)
++**           Next iEphCsr
++**         }
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     foreach row (csrLead) {
++**       AggStep (csrLead)
++**     }
++**     foreach row (iEphCsr) {
++**       Gosub addrGosub
++**     }
++** 
++** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++**
++**   flush_partition:
++**     Once {
++**       OpenDup (iEphCsr -> csrLead)
++**     }
++**     foreach row (csrLead){
++**       AggStep (csrLead)
++**     }
++**     Rewind (csrLead)
++**     Integer ctr 0
++**     foreach row (csrLead){
++**       if( new peer ){
++**         AggFinal (xValue)
++**         for(i=0; i<ctr; i++){
++**           Gosub addrGosub
++**           AggInverse (iEphCsr)
++**           Next iEphCsr
++**         }
++**         Integer ctr 0
++**       }
++**       Incr ctr
++**     }
++**
++**     AggFinal (xFinalize)
++**     for(i=0; i<ctr; i++){
++**       Gosub addrGosub
++**       Next iEphCsr
++**     }
++**
++**     ResetSorter (csr)
++**     Return
++*/
++static void windowCodeCacheStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int k;
++  int addr;
++  ExprList *pPart = pMWin->pPartition;
++  ExprList *pOrderBy = pMWin->pOrderBy;
++  int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
++  int regNewPeer;
++
++  int addrGoto;                   /* Address of Goto used to jump flush_par.. */
++  int addrNext;                   /* Jump here for next iteration of loop */
++  int regFlushPart;
++  int lblFlushPart;
++  int csrLead;
++  int regCtr;
++  int regArg;                     /* Register array to martial function args */
++  int regSize;
++  int lblEmpty;
++  int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT 
++          && pMWin->eEnd==TK_UNBOUNDED;
++
++  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
++       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
++  );
++
++  lblEmpty = sqlite3VdbeMakeLabel(v);
++  regNewPeer = pParse->nMem+1;
++  pParse->nMem += nPeer;
++
++  /* Allocate register and label for the "flush_partition" sub-routine. */
++  regFlushPart = ++pParse->nMem;
++  lblFlushPart = sqlite3VdbeMakeLabel(v);
++
++  csrLead = pParse->nTab++;
++  regCtr = ++pParse->nMem;
++
++  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
++  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++
++  /* Start of "flush_partition" */
++  sqlite3VdbeResolveLabel(v, lblFlushPart);
++  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
++
++  /* Initialize the accumulator register for each window function to NULL */
++  regArg = windowInitAccum(pParse, pMWin);
++
++  sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
++  sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
++  VdbeCoverageNeverTaken(v);
++
++  if( bReverse ){
++    int addr2 = sqlite3VdbeCurrentAddr(v);
++    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
++    sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
++    VdbeCoverageNeverTaken(v);
++  }
++  addrNext = sqlite3VdbeCurrentAddr(v);
++
++  if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
++    int bCurrent = (pMWin->eStart==TK_CURRENT);
++    int addrJump = 0;             /* Address of OP_Jump below */
++    if( pMWin->eType==TK_RANGE ){
++      int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
++      int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
++      for(k=0; k<nPeer; k++){
++        sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
++      }
++      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
++      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++      VdbeCoverage(v);
++      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
++    }
++
++    windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 
++        (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
++    );
++    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++  }
++
++  if( bReverse==0 ){
++    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
++  }
++  sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
++  sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
++  VdbeCoverage(v);
++
++  windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
++
++  sqlite3VdbeResolveLabel(v, lblEmpty);
++  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
++
++  /* Jump to here to skip over flush_partition */
++  sqlite3VdbeJumpHere(v, addrGoto);
++}
++
++
++/*
++** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++**
++**   ...
++**     if( new partition ){
++**       AggFinal (xFinalize)
++**       Gosub addrGosub
++**       ResetSorter eph-table
++**     }
++**     else if( new peer ){
++**       AggFinal (xValue)
++**       Gosub addrGosub
++**       ResetSorter eph-table
++**     }
++**     AggStep
++**     Insert (record into eph-table)
++**   sqlite3WhereEnd()
++**   AggFinal (xFinalize)
++**   Gosub addrGosub
++**
++** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++**
++**   As above, except take no action for a "new peer". Invoke
++**   the sub-routine once only for each partition.
++**
++** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
++**
++**   As above, except that the "new peer" condition is handled in the
++**   same way as "new partition" (so there is no "else if" block).
++**
++** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++** 
++**   As above, except assume every row is a "new peer".
++*/
++static void windowCodeDefaultStep(
++  Parse *pParse, 
++  Select *p,
++  WhereInfo *pWInfo,
++  int regGosub, 
++  int addrGosub
++){
++  Window *pMWin = p->pWin;
++  Vdbe *v = sqlite3GetVdbe(pParse);
++  int k;
++  int iSubCsr = p->pSrc->a[0].iCursor;
++  int nSub = p->pSrc->a[0].pTab->nCol;
++  int reg = pParse->nMem+1;
++  int regRecord = reg+nSub;
++  int regRowid = regRecord+1;
++  int addr;
++  ExprList *pPart = pMWin->pPartition;
++  ExprList *pOrderBy = pMWin->pOrderBy;
++
++  assert( pMWin->eType==TK_RANGE 
++      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
++  );
++
++  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
++       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
++       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
++  );
++
++  if( pMWin->eEnd==TK_UNBOUNDED ){
++    pOrderBy = 0;
++  }
++
++  pParse->nMem += nSub + 2;
++
++  /* Load the individual column values of the row returned by
++  ** the sub-select into an array of registers. */
++  for(k=0; k<nSub; k++){
++    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
++  }
++
++  /* Check if this is the start of a new partition or peer group. */
++  if( pPart || pOrderBy ){
++    int nPart = (pPart ? pPart->nExpr : 0);
++    int addrGoto = 0;
++    int addrJump = 0;
++    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
++
++    if( pPart ){
++      int regNewPart = reg + pMWin->nBufferCol;
++      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
++      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
++      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++      VdbeCoverageEqNe(v);
++      windowAggFinal(pParse, pMWin, 1);
++      if( pOrderBy ){
++        addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
++      }
++    }
++
++    if( pOrderBy ){
++      int regNewPeer = reg + pMWin->nBufferCol + nPart;
++      int regPeer = pMWin->regPart + nPart;
++
++      if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++      if( pMWin->eType==TK_RANGE ){
++        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
++        addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
++        sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
++        addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
++        VdbeCoverage(v);
++      }else{
++        addrJump = 0;
++      }
++      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
++      if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
++    }
++
++    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
++    VdbeCoverage(v);
++    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
++    VdbeCoverage(v);
++
++    sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
++    sqlite3VdbeAddOp3(
++        v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
++    );
++
++    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
++  }
++
++  /* Invoke step function for window functions */
++  windowAggStep(pParse, pMWin, -1, 0, reg, 0);
++
++  /* Buffer the current row in the ephemeral table. */
++  if( pMWin->nBufferCol>0 ){
++    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
++  }else{
++    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
++    sqlite3VdbeAppendP4(v, (void*)"", 0);
++  }
++  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
++  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
++
++  /* End the database scan loop. */
++  sqlite3WhereEnd(pWInfo);
++
++  windowAggFinal(pParse, pMWin, 1);
++  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
++  VdbeCoverage(v);
++  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
++  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
++  VdbeCoverage(v);
++}
++
++/*
++** Allocate and return a duplicate of the Window object indicated by the
++** third argument. Set the Window.pOwner field of the new object to
++** pOwner.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
++  Window *pNew = 0;
++  if( ALWAYS(p) ){
++    pNew = sqlite3DbMallocZero(db, sizeof(Window));
++    if( pNew ){
++      pNew->zName = sqlite3DbStrDup(db, p->zName);
++      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
++      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
++      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
++      pNew->eType = p->eType;
++      pNew->eEnd = p->eEnd;
++      pNew->eStart = p->eStart;
++      pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
++      pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
++      pNew->pOwner = pOwner;
++    }
++  }
++  return pNew;
++}
++
++/*
++** Return a copy of the linked list of Window objects passed as the
++** second argument.
++*/
++SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
++  Window *pWin;
++  Window *pRet = 0;
++  Window **pp = &pRet;
++
++  for(pWin=p; pWin; pWin=pWin->pNextWin){
++    *pp = sqlite3WindowDup(db, 0, pWin);
++    if( *pp==0 ) break;
++    pp = &((*pp)->pNextWin);
++  }
++
++  return pRet;
++}
++
++/*
++** sqlite3WhereBegin() has already been called for the SELECT statement 
++** passed as the second argument when this function is invoked. It generates
++** code to populate the Window.regResult register for each window function and
++** invoke the sub-routine at instruction addrGosub once for each row.
++** This function calls sqlite3WhereEnd() before returning. 
++*/
++SQLITE_PRIVATE void sqlite3WindowCodeStep(
++  Parse *pParse,                  /* Parse context */
++  Select *p,                      /* Rewritten SELECT statement */
++  WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
++  int regGosub,                   /* Register for OP_Gosub */
++  int addrGosub                   /* OP_Gosub here to return each row */
++){
++  Window *pMWin = p->pWin;
++
++  /* There are three different functions that may be used to do the work
++  ** of this one, depending on the window frame and the specific built-in
++  ** window functions used (if any).
++  **
++  ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
++  **
++  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++  **
++  ** The exception is because windowCodeRowExprStep() implements all window
++  ** frame types by caching the entire partition in a temp table, and
++  ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
++  ** implement without such a cache.
++  **
++  ** windowCodeCacheStep() is used for:
++  **
++  **   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
++  **
++  ** It is also used for anything not handled by windowCodeRowExprStep() 
++  ** that invokes a built-in window function that requires the entire 
++  ** partition to be cached in a temp table before any rows are returned
++  ** (e.g. nth_value() or percent_rank()).
++  **
++  ** Finally, assuming there is no built-in window function that requires
++  ** the partition to be cached, windowCodeDefaultStep() is used for:
++  **
++  **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
++  **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
++  **   RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
++  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
++  **
++  ** windowCodeDefaultStep() is the only one of the three functions that
++  ** does not cache each partition in a temp table before beginning to
++  ** return rows.
++  */
++  if( pMWin->eType==TK_ROWS 
++   && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
++  ){
++    VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
++    windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
++  }else{
++    Window *pWin;
++    int bCache = 0;               /* True to use CacheStep() */
++
++    if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
++      bCache = 1;
++    }else{
++      for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
++        FuncDef *pFunc = pWin->pFunc;
++        if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
++         || (pFunc->zName==nth_valueName)
++         || (pFunc->zName==first_valueName)
++         || (pFunc->zName==leadName)
++         || (pFunc->zName==lagName)
++        ){
++          bCache = 1;
++          break;
++        }
++      }
++    }
++
++    /* Otherwise, call windowCodeDefaultStep().  */
++    if( bCache ){
++      VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
++      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
++    }else{
++      VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
++      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
++    }
++  }
++}
++
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/************** End of window.c **********************************************/
+ /************** Begin file parse.c *******************************************/
+ /*
+ ** 2000-05-29
+@@ -139803,6 +146829,7 @@
+ ** input grammar file:
+ */
+ /* #include <stdio.h> */
++/* #include <assert.h> */
+ /************ Begin %include sections from the grammar ************************/
+ 
+ /* #include "sqliteInt.h" */
+@@ -139854,6 +146881,8 @@
+ */
+ struct TrigEvent { int a; IdList * b; };
+ 
++struct FrameBound     { int eType; Expr *pExpr; };
++
+ /*
+ ** Disable lookaside memory allocation for objects that might be
+ ** shared across database connections.
+@@ -139894,10 +146923,18 @@
+   static Expr *tokenExpr(Parse *pParse, int op, Token t){
+     Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
+     if( p ){
+-      memset(p, 0, sizeof(Expr));
++      /* memset(p, 0, sizeof(Expr)); */
+       p->op = (u8)op;
++      p->affinity = 0;
+       p->flags = EP_Leaf;
+       p->iAgg = -1;
++      p->pLeft = p->pRight = 0;
++      p->x.pList = 0;
++      p->pAggInfo = 0;
++      p->y.pTab = 0;
++      p->op2 = 0;
++      p->iTable = 0;
++      p->iColumn = 0;
+       p->u.zToken = (char*)&p[1];
+       memcpy(p->u.zToken, t.z, t.n);
+       p->u.zToken[t.n] = 0;
+@@ -139908,15 +146945,19 @@
+ #if SQLITE_MAX_EXPR_DEPTH>0
+       p->nHeight = 1;
+ #endif  
++      if( IN_RENAME_OBJECT ){
++        return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t);
++      }
+     }
+     return p;
+   }
+ 
++
+   /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
+   ** unary TK_ISNULL or TK_NOTNULL expression. */
+   static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
+     sqlite3 *db = pParse->db;
+-    if( pA && pY && pY->op==TK_NULL ){
++    if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){
+       pA->op = (u8)op;
+       sqlite3ExprDelete(db, pA->pRight);
+       pA->pRight = 0;
+@@ -139985,8 +147026,10 @@
+ **                       zero the stack is dynamically sized using realloc()
+ **    sqlite3ParserARG_SDECL     A static variable declaration for the %extra_argument
+ **    sqlite3ParserARG_PDECL     A parameter declaration for the %extra_argument
++**    sqlite3ParserARG_PARAM     Code to pass %extra_argument as a subroutine parameter
+ **    sqlite3ParserARG_STORE     Code to store %extra_argument into yypParser
+ **    sqlite3ParserARG_FETCH     Code to extract %extra_argument from yypParser
++**    sqlite3ParserCTX_*         As sqlite3ParserARG_ except for %extra_context
+ **    YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
+ **    YYNSTATE           the combined number of states.
+@@ -140005,46 +147048,56 @@
+ # define INTERFACE 1
+ #endif
+ /************* Begin control #defines *****************************************/
+-#define YYCODETYPE unsigned char
+-#define YYNOCODE 253
++#define YYCODETYPE unsigned short int
++#define YYNOCODE 277
+ #define YYACTIONTYPE unsigned short int
+-#define YYWILDCARD 83
++#define YYWILDCARD 91
+ #define sqlite3ParserTOKENTYPE Token
+ typedef union {
+   int yyinit;
+   sqlite3ParserTOKENTYPE yy0;
+-  int yy4;
+-  struct TrigEvent yy90;
+-  TriggerStep* yy203;
+-  struct {int value; int mask;} yy215;
+-  SrcList* yy259;
+-  Expr* yy314;
+-  ExprList* yy322;
+-  const char* yy336;
+-  IdList* yy384;
+-  Select* yy387;
+-  With* yy451;
++  Expr* yy18;
++  struct TrigEvent yy34;
++  IdList* yy48;
++  int yy70;
++  struct {int value; int mask;} yy111;
++  struct FrameBound yy119;
++  SrcList* yy135;
++  TriggerStep* yy207;
++  Window* yy327;
++  Upsert* yy340;
++  const char* yy392;
++  ExprList* yy420;
++  With* yy449;
++  Select* yy489;
+ } YYMINORTYPE;
+ #ifndef YYSTACKDEPTH
+ #define YYSTACKDEPTH 100
+ #endif
+-#define sqlite3ParserARG_SDECL Parse *pParse;
+-#define sqlite3ParserARG_PDECL ,Parse *pParse
+-#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
+-#define sqlite3ParserARG_STORE yypParser->pParse = pParse
++#define sqlite3ParserARG_SDECL
++#define sqlite3ParserARG_PDECL
++#define sqlite3ParserARG_PARAM
++#define sqlite3ParserARG_FETCH
++#define sqlite3ParserARG_STORE
++#define sqlite3ParserCTX_SDECL Parse *pParse;
++#define sqlite3ParserCTX_PDECL ,Parse *pParse
++#define sqlite3ParserCTX_PARAM ,pParse
++#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
++#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
+ #define YYFALLBACK 1
+-#define YYNSTATE             472
+-#define YYNRULE              333
+-#define YYNTOKEN             143
+-#define YY_MAX_SHIFT         471
+-#define YY_MIN_SHIFTREDUCE   681
+-#define YY_MAX_SHIFTREDUCE   1013
+-#define YY_ERROR_ACTION      1014
+-#define YY_ACCEPT_ACTION     1015
+-#define YY_NO_ACTION         1016
+-#define YY_MIN_REDUCE        1017
+-#define YY_MAX_REDUCE        1349
++#define YYNSTATE             521
++#define YYNRULE              367
++#define YYNTOKEN             155
++#define YY_MAX_SHIFT         520
++#define YY_MIN_SHIFTREDUCE   756
++#define YY_MAX_SHIFTREDUCE   1122
++#define YY_ERROR_ACTION      1123
++#define YY_ACCEPT_ACTION     1124
++#define YY_NO_ACTION         1125
++#define YY_MIN_REDUCE        1126
++#define YY_MAX_REDUCE        1492
+ /************* End control #defines *******************************************/
++#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
+ 
+ /* Define the yytestcase() macro to be a no-op if is not already defined
+ ** otherwise.
+@@ -140109,481 +147162,568 @@
+ **  yy_default[]       Default action for each state.
+ **
+ *********** Begin parsing tables **********************************************/
+-#define YY_ACTTAB_COUNT (1566)
++#define YY_ACTTAB_COUNT (2009)
+ static const YYACTIONTYPE yy_action[] = {
+- /*     0 */  1169, 1015,  167,  167,    1,  168,  466, 1313,  466, 1083,
+- /*    10 */  1062,  466,   97,   94,  183, 1057,  466,  329, 1083,  342,
+- /*    20 */    97,   94,  183,  459,  459,  459,  436,   57,   57,   57,
+- /*    30 */    57,  807,   57,   57,  367,  367,  367,   57,   57,  808,
+- /*    40 */  1270, 1088, 1088,  104,  105,   95,  991,  991,  868,  871,
+- /*    50 */   860,  860,  102,  102,  103,  103,  103,  103,  233,  233,
+- /*    60 */   326, 1011,  449,  437,  449,  446,  351,  449,  461, 1142,
+- /*    70 */   463,  342,  449,  426, 1316,  209,  180,  742,   80,  299,
+- /*    80 */   857,  857,  869,  872,  101,  101,  101,  101,  100,  100,
+- /*    90 */    99,   99,   99,   98,  368,  104,  105,   95,  991,  991,
+- /*   100 */   868,  871,  860,  860,  102,  102,  103,  103,  103,  103,
+- /*   110 */    99,   99,   99,   98,  368,  355,   97,   94,  183,  228,
+- /*   120 */   106, 1012,  407,  342,  101,  101,  101,  101,  100,  100,
+- /*   130 */    99,   99,   99,   98,  368,  861,  101,  101,  101,  101,
+- /*   140 */   100,  100,   99,   99,   99,   98,  368,  104,  105,   95,
+- /*   150 */   991,  991,  868,  871,  860,  860,  102,  102,  103,  103,
+- /*   160 */   103,  103,  201,  368,  375,  420,  417,  416,  387,  273,
+- /*   170 */    65,   97,   94,  183,  168,  342,  415,  951, 1343,  396,
+- /*   180 */    66, 1343,  320,  959,  371,  970,  334,  340,  101,  101,
+- /*   190 */   101,  101,  100,  100,   99,   99,   99,   98,  368,  104,
+- /*   200 */   105,   95,  991,  991,  868,  871,  860,  860,  102,  102,
+- /*   210 */   103,  103,  103,  103,  373,  100,  100,   99,   99,   99,
+- /*   220 */    98,  368,  970,  971,  972,  201, 1100,  342,  420,  417,
+- /*   230 */   416,  287,  366,  365,  337,  970, 1162,  463,  949,  415,
+- /*   240 */   101,  101,  101,  101,  100,  100,   99,   99,   99,   98,
+- /*   250 */   368,  104,  105,   95,  991,  991,  868,  871,  860,  860,
+- /*   260 */   102,  102,  103,  103,  103,  103,  777,  241,  233,  233,
+- /*   270 */     9,  847,  970,  971,  972,  390,  998, 1141,  998,  342,
+- /*   280 */   463,  252,  829,  719,   98,  368,  840,  298,  338,  142,
+- /*   290 */   839,  339,  101,  101,  101,  101,  100,  100,   99,   99,
+- /*   300 */    99,   98,  368,  104,  105,   95,  991,  991,  868,  871,
+- /*   310 */   860,  860,  102,  102,  103,  103,  103,  103,  272,  466,
+- /*   320 */   392,  839,  839,  841,   97,   94,  183,  390, 1317,  253,
+- /*   330 */   456,  342,  125,  166,  807,  712,  208,  407,  386,  970,
+- /*   340 */    57,   57,  808,  238,  101,  101,  101,  101,  100,  100,
+- /*   350 */    99,   99,   99,   98,  368,  104,  105,   95,  991,  991,
+- /*   360 */   868,  871,  860,  860,  102,  102,  103,  103,  103,  103,
+- /*   370 */   466,  108,  466,  267,  465,  442,  970,  971,  972,  261,
+- /*   380 */   951, 1344,  909,  342, 1344,  142,  829,  848, 1292,  959,
+- /*   390 */   371,   55,   55,   57,   57,  242,  101,  101,  101,  101,
+- /*   400 */   100,  100,   99,   99,   99,   98,  368,  104,  105,   95,
+- /*   410 */   991,  991,  868,  871,  860,  860,  102,  102,  103,  103,
+- /*   420 */   103,  103,  272,  382,  262,  253,  456,  310,  364,  253,
+- /*   430 */   456,   86,  264,   84,  266,  342,  441,  176,  175,  834,
+- /*   440 */   464,  949,  767,  767,  332,  313, 1094,  396,  101,  101,
+- /*   450 */   101,  101,  100,  100,   99,   99,   99,   98,  368,  104,
+- /*   460 */   105,   95,  991,  991,  868,  871,  860,  860,  102,  102,
+- /*   470 */   103,  103,  103,  103,  227,  227,  233,  233,  233,  233,
+- /*   480 */   387,  273,  234,  234,  326,  950,  463,  342,  463,  298,
+- /*   490 */   463,  914,  914,  404,  463, 1037,  123,  265,   27,  970,
+- /*   500 */   101,  101,  101,  101,  100,  100,   99,   99,   99,   98,
+- /*   510 */   368,  104,  105,   95,  991,  991,  868,  871,  860,  860,
+- /*   520 */   102,  102,  103,  103,  103,  103,  435,  233,  233,  466,
+- /*   530 */   285,  686,  687,  688,  127,  271,  970,  971,  972,  463,
+- /*   540 */  1345,  327,  342,  407,  157, 1012,  988,   13,   13,  181,
+- /*   550 */    41,   41,  101,  101,  101,  101,  100,  100,   99,   99,
+- /*   560 */    99,   98,  368,  715,  794,  378,  104,  105,   95,  991,
+- /*   570 */   991,  868,  871,  860,  860,  102,  102,  103,  103,  103,
+- /*   580 */   103,  970,  378,  377,  346,  239,  847, 1086, 1086,  280,
+- /*   590 */  1169,  283,  204,  203,  202,  177,  298,  342,  407,  298,
+- /*   600 */   715,  840,  169,  299,  407,  839,   82,  101,  101,  101,
+- /*   610 */   101,  100,  100,   99,   99,   99,   98,  368,  970,  971,
+- /*   620 */   972,  104,  105,   95,  991,  991,  868,  871,  860,  860,
+- /*   630 */   102,  102,  103,  103,  103,  103,  839,  839,  841,  362,
+- /*   640 */   240,  124, 1169,  172,  126,  378, 1269, 1169, 1066,  342,
+- /*   650 */   253,  456,  407,  407,  407,  396,  352,  401,  407,  429,
+- /*   660 */   398,   85,  101,  101,  101,  101,  100,  100,   99,   99,
+- /*   670 */    99,   98,  368,  104,  105,   95,  991,  991,  868,  871,
+- /*   680 */   860,  860,  102,  102,  103,  103,  103,  103, 1169,  466,
+- /*   690 */   230,  233,  233,  792, 1235, 1095, 1091, 1293,    1,   77,
+- /*   700 */   278,  342,  205,  463,  974,  911, 1040,  348,  353,  911,
+- /*   710 */    42,   42,   79,  403,  101,  101,  101,  101,  100,  100,
+- /*   720 */    99,   99,   99,   98,  368,  104,   93,   95,  991,  991,
+- /*   730 */   868,  871,  860,  860,  102,  102,  103,  103,  103,  103,
+- /*   740 */   402,    9,  974,  243,  772,  458,  348,  232,  180,  771,
+- /*   750 */   946,  312,  342,  328,  363,  349,  143,  831,  389, 1278,
+- /*   760 */   211,  211,   21,  347,  432,  182,  101,  101,  101,  101,
+- /*   770 */   100,  100,   99,   99,   99,   98,  368,  105,   95,  991,
+- /*   780 */   991,  868,  871,  860,  860,  102,  102,  103,  103,  103,
+- /*   790 */   103,  792,  724,   22,  732,  731,  233,  233, 1239,  256,
+- /*   800 */   391,  274,  342,  211,   79,  360,  257,  413,  463,  397,
+- /*   810 */   207,  288,  260,  450,   79, 1239, 1241,  101,  101,  101,
+- /*   820 */   101,  100,  100,   99,   99,   99,   98,  368,   95,  991,
+- /*   830 */   991,  868,  871,  860,  860,  102,  102,  103,  103,  103,
+- /*   840 */   103,   91,  457,  296,    3,  233,  233,    5,  438,  212,
+- /*   850 */   331,  394,  739,  740,  295,  898,  894,  463,  460,  207,
+- /*   860 */   801, 1237,  722,  211,  698,  843, 1283,  101,  101,  101,
+- /*   870 */   101,  100,  100,   99,   99,   99,   98,  368, 1239,  380,
+- /*   880 */   357,  369,  233,  233,  989,  219,  236,  297,  423,  292,
+- /*   890 */   422,  206,  454,  898,  463,  970,   91,  457,  290,    3,
+- /*   900 */   722,  142,  268,  843,  847,  466, 1258,  149,  388,  425,
+- /*   910 */    88,   89,  769,  460,  930,   87,  447,   90,  369,  468,
+- /*   920 */   467,  385,  989,  839, 1257,  439,   57,   57,  395,  931,
+- /*   930 */  1065,  158,  970,  971,  972,  772,  369,  471, 1019,  399,
+- /*   940 */   771,  253,  456,  254,  932,  119,  891,  454,  233,  233,
+- /*   950 */     4,  970, 1096,  275,  839,  839,  841,  842,   19,  847,
+- /*   960 */   463,  449,  448,  163,  453,   88,   89,  776,  970, 1127,
+- /*   970 */   279,  930,   90,  369,  468,  467,   91,  457,  839,    3,
+- /*   980 */   235, 1064,  466, 1228,  233,  233,  931,  970,  970,  971,
+- /*   990 */   972,  970,  908,  460,  908,    2,  463,   81,  457,  212,
+- /*  1000 */     3,  932,  282,   10,   10,  970,  971,  972,  189,  839,
+- /*  1010 */   839,  841,  842,   19,  460,  284,  369,  354,  907,  286,
+- /*  1020 */   907,  753,  466, 1079,  970,  971,  972,  454,  970,  971,
+- /*  1030 */   972,  754,  970, 1063,  989,  372,  792,  369, 1118,  847,
+- /*  1040 */   291,  452,  466,   10,   10,   88,   89,  142,  454,  168,
+- /*  1050 */   300,  412,   90,  369,  468,  467,  793,  356,  839,  706,
+- /*  1060 */   847,  341,  121,   10,   10,  301,   88,   89,  379,  970,
+- /*  1070 */   971,  972,  989,   90,  369,  468,  467,  244,  205,  839,
+- /*  1080 */  1306,  245, 1135,  245,  250, 1168, 1114,  253,  456,  839,
+- /*  1090 */   839,  841,  842,   19, 1125,  237,  122,  451, 1174,  733,
+- /*  1100 */   324,  324,  323,  222,  321,  466, 1046,  695,  182,  225,
+- /*  1110 */   839,  839,  841,  842,   19,  103,  103,  103,  103,   96,
+- /*  1120 */   185,  466,  259, 1039, 1028,  170,   10,   10, 1027,  421,
+- /*  1130 */   258, 1029, 1300,  708,  792,  466,  408,  734,    8,  347,
+- /*  1140 */   444,  174,   12,   12,  290,  101,  101,  101,  101,  100,
+- /*  1150 */   100,   99,   99,   99,   98,  368,   32,   32,  466,  187,
+- /*  1160 */   466, 1111,  103,  103,  103,  103,  188,  466,  325,  138,
+- /*  1170 */   186,  708,  303,  305,  307,  358,  970,  270,  393,   43,
+- /*  1180 */    43,   44,   44, 1157,  333,  178,  418,  294,   45,   45,
+- /*  1190 */  1232,  318,  101,  101,  101,  101,  100,  100,   99,   99,
+- /*  1200 */    99,   98,  368,  381,  343,  366,  365,  466,  263,  253,
+- /*  1210 */   456,  466, 1062,  970,  971,  972, 1231,  997,  309,  466,
+- /*  1220 */   455,  466,  427,  466,  995,  173,  996, 1303,   46,   46,
+- /*  1230 */   145,  376,   37,   37, 1006, 1277,  466,  214, 1275,   64,
+- /*  1240 */    47,   47,   33,   33,   34,   34, 1003,   67,  466,  998,
+- /*  1250 */   350,  998,  466,  155,  233,  233,  466,   36,   36,   24,
+- /*  1260 */   140,   77, 1154,  466,  383,  466,  463,  428,  466,   48,
+- /*  1270 */    48,  466,  147,   49,   49,  466,  150,   50,   50,  466,
+- /*  1280 */   151,  152,  466,  384,   11,   11,   51,   51,  466,  110,
+- /*  1290 */   110,  153,   52,   52,  411,  466,   38,   38,  466,  191,
+- /*  1300 */    53,   53,  466,   54,   54,  466,  400,  466,  330,   39,
+- /*  1310 */    39,  466, 1164,  466,   25,  466,   56,   56,  466,  131,
+- /*  1320 */   131,   72,  466,  132,  132,  159,  133,  133,   61,   61,
+- /*  1330 */  1226,  195,   40,   40,  111,  111,   58,   58,  406,  112,
+- /*  1340 */   112,  466,  277,  113,  113,  466,  226,  466, 1246,  466,
+- /*  1350 */   197,  466,  164,  466,  409,  466,  198,  466,  199,  466,
+- /*  1360 */   335,  281,  109,  109,  466, 1030,  130,  130,  129,  129,
+- /*  1370 */   117,  117,  116,  116,  114,  114,  115,  115,   60,   60,
+- /*  1380 */    62,   62,  466,  359,  466,   59,   59,  424, 1082, 1081,
+- /*  1390 */  1080,  724, 1073, 1054,  336,  293, 1053, 1052, 1315,  431,
+- /*  1400 */   361,   76,  248,   31,   31,   35,   35, 1072,  249,  440,
+- /*  1410 */   302,  434,  213, 1122,    6,  311, 1212,  107,   83,  251,
+- /*  1420 */    78, 1123,  445,  220,  443, 1036,  304,   23, 1121,  469,
+- /*  1430 */   965,  221,  223, 1104,  314,  224,  344,  317,  315,  316,
+- /*  1440 */   470,  306, 1025, 1120,  308, 1262, 1020,  134,  120,  246,
+- /*  1450 */   682,  370,  171,  255, 1263,  135,  184, 1261, 1260,  374,
+- /*  1460 */   118,  906,  904,  827, 1050,  146,  136,  137,  148, 1049,
+- /*  1470 */    63, 1047,  756,  190,  269,  920,  154,  156,   68,   69,
+- /*  1480 */    70,   71,  139,  923,  192,  193,  144,  919,  345,  128,
+- /*  1490 */    14,  194,  276,  211, 1000,  405,  196,  161,  912,  160,
+- /*  1500 */    26,  697,  410,  295,  200,  289,  414,  162,  419,   73,
+- /*  1510 */    15,   16,  141,   74,   28,  247,  846,  845,  735,  874,
+- /*  1520 */   954,   75,  430,  955,   29,  433,  179,  229,  231,  800,
+- /*  1530 */   165,  795,   87,  210,  889,   79,  875,   17,  873,  877,
+- /*  1540 */   929,   18,  928,  216,  215,  878,   20,   30,  462,  844,
+- /*  1550 */   707,   92,  766,  770,    7,  322,  217,  218,  319, 1308,
+- /*  1560 */   960, 1016, 1016, 1016, 1016, 1307,
++ /*     0 */   368,  105,  102,  197,  105,  102,  197,  515, 1124,    1,
++ /*    10 */     1,  520,    2, 1128,  515, 1192, 1171, 1456,  275,  370,
++ /*    20 */   127, 1389, 1197, 1197, 1192, 1166,  178, 1205,   64,   64,
++ /*    30 */   477,  887,  322,  428,  348,   37,   37,  808,  362,  888,
++ /*    40 */   509,  509,  509,  112,  113,  103, 1100, 1100,  953,  956,
++ /*    50 */   946,  946,  110,  110,  111,  111,  111,  111,  365,  252,
++ /*    60 */   252,  515,  252,  252,  497,  515,  309,  515,  459,  515,
++ /*    70 */  1079,  491,  512,  478,    6,  512,  809,  134,  498,  228,
++ /*    80 */   194,  428,   37,   37,  515,  208,   64,   64,   64,   64,
++ /*    90 */    13,   13,  109,  109,  109,  109,  108,  108,  107,  107,
++ /*   100 */   107,  106,  401,  258,  381,   13,   13,  398,  397,  428,
++ /*   110 */   252,  252,  370,  476,  405, 1104, 1079, 1080, 1081,  386,
++ /*   120 */  1106,  390,  497,  512,  497, 1423, 1419,  304, 1105,  307,
++ /*   130 */  1256,  496,  370,  499,   16,   16,  112,  113,  103, 1100,
++ /*   140 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   150 */   111,  262, 1107,  495, 1107,  401,  112,  113,  103, 1100,
++ /*   160 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   170 */   111,  129, 1425,  343, 1420,  339, 1059,  492, 1057,  263,
++ /*   180 */    73,  105,  102,  197,  994,  109,  109,  109,  109,  108,
++ /*   190 */   108,  107,  107,  107,  106,  401,  370,  111,  111,  111,
++ /*   200 */   111,  104,  492,   89, 1432,  109,  109,  109,  109,  108,
++ /*   210 */   108,  107,  107,  107,  106,  401,  111,  111,  111,  111,
++ /*   220 */   112,  113,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*   230 */   110,  111,  111,  111,  111,  109,  109,  109,  109,  108,
++ /*   240 */   108,  107,  107,  107,  106,  401,  114,  108,  108,  107,
++ /*   250 */   107,  107,  106,  401,  109,  109,  109,  109,  108,  108,
++ /*   260 */   107,  107,  107,  106,  401,  152,  399,  399,  399,  109,
++ /*   270 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*   280 */   178,  493, 1412,  434, 1037, 1486, 1079,  515, 1486,  370,
++ /*   290 */   421,  297,  357,  412,   74, 1079,  109,  109,  109,  109,
++ /*   300 */   108,  108,  107,  107,  107,  106,  401, 1413,   37,   37,
++ /*   310 */  1431,  274,  506,  112,  113,  103, 1100, 1100,  953,  956,
++ /*   320 */   946,  946,  110,  110,  111,  111,  111,  111, 1436,  520,
++ /*   330 */     2, 1128, 1079, 1080, 1081,  430,  275, 1079,  127,  366,
++ /*   340 */   933, 1079, 1080, 1081,  220, 1205,  913,  458,  455,  454,
++ /*   350 */   392,  167,  515, 1035,  152,  445,  924,  453,  152,  874,
++ /*   360 */   923,  289,  109,  109,  109,  109,  108,  108,  107,  107,
++ /*   370 */   107,  106,  401,   13,   13,  261,  853,  252,  252,  227,
++ /*   380 */   106,  401,  370, 1079, 1080, 1081,  311,  388, 1079,  296,
++ /*   390 */   512,  923,  923,  925,  231,  323, 1255, 1388, 1423,  490,
++ /*   400 */   274,  506,   12,  208,  274,  506,  112,  113,  103, 1100,
++ /*   410 */  1100,  953,  956,  946,  946,  110,  110,  111,  111,  111,
++ /*   420 */   111, 1440,  286, 1128,  288, 1079, 1097,  247,  275, 1098,
++ /*   430 */   127,  387,  405,  389, 1079, 1080, 1081, 1205,  159,  238,
++ /*   440 */   255,  321,  461,  316,  460,  225,  790,  105,  102,  197,
++ /*   450 */   513,  314,  842,  842,  445,  109,  109,  109,  109,  108,
++ /*   460 */   108,  107,  107,  107,  106,  401,  515,  514,  515,  252,
++ /*   470 */   252, 1079, 1080, 1081,  435,  370, 1098,  933, 1460,  794,
++ /*   480 */   274,  506,  512,  105,  102,  197,  336,   63,   63,   64,
++ /*   490 */    64,   27,  790,  924,  287,  208, 1354,  923,  515,  112,
++ /*   500 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*   510 */   111,  111,  111,  111,  107,  107,  107,  106,  401,   49,
++ /*   520 */    49,  515,   28, 1079,  405,  497,  421,  297,  923,  923,
++ /*   530 */   925,  186,  468, 1079,  467,  999,  999,  442,  515, 1079,
++ /*   540 */   334,  515,   45,   45, 1083,  342,  173,  168,  109,  109,
++ /*   550 */   109,  109,  108,  108,  107,  107,  107,  106,  401,   13,
++ /*   560 */    13,  205,   13,   13,  252,  252, 1195, 1195,  370, 1079,
++ /*   570 */  1080, 1081,  787,  265,    5,  359,  494,  512,  469, 1079,
++ /*   580 */  1080, 1081,  398,  397, 1079, 1079, 1080, 1081,    3,  282,
++ /*   590 */  1079, 1083,  112,  113,  103, 1100, 1100,  953,  956,  946,
++ /*   600 */   946,  110,  110,  111,  111,  111,  111,  252,  252, 1015,
++ /*   610 */   220, 1079,  873,  458,  455,  454,  943,  943,  954,  957,
++ /*   620 */   512,  252,  252,  453, 1016, 1079,  445, 1107, 1209, 1107,
++ /*   630 */  1079, 1080, 1081,  515,  512,  426, 1079, 1080, 1081, 1017,
++ /*   640 */   512,  109,  109,  109,  109,  108,  108,  107,  107,  107,
++ /*   650 */   106,  401, 1052,  515,   50,   50,  515, 1079, 1080, 1081,
++ /*   660 */   828,  370, 1051,  379,  411, 1064, 1358,  207,  408,  773,
++ /*   670 */   829, 1079, 1080, 1081,   64,   64,  322,   64,   64, 1302,
++ /*   680 */   947,  411,  410, 1358, 1360,  112,  113,  103, 1100, 1100,
++ /*   690 */   953,  956,  946,  946,  110,  110,  111,  111,  111,  111,
++ /*   700 */   294,  482,  515, 1037, 1487,  515,  434, 1487,  354, 1120,
++ /*   710 */   483,  996,  913,  485,  466,  996,  132,  178,   33,  450,
++ /*   720 */  1203,  136,  406,   64,   64,  479,   64,   64,  419,  369,
++ /*   730 */   283, 1146,  252,  252,  109,  109,  109,  109,  108,  108,
++ /*   740 */   107,  107,  107,  106,  401,  512,  224,  440,  411,  266,
++ /*   750 */  1358,  266,  252,  252,  370,  296,  416,  284,  934,  396,
++ /*   760 */   976,  470,  400,  252,  252,  512,    9,  473,  231,  500,
++ /*   770 */   354, 1036, 1035, 1488,  355,  374,  512, 1121,  112,  113,
++ /*   780 */   103, 1100, 1100,  953,  956,  946,  946,  110,  110,  111,
++ /*   790 */   111,  111,  111,  252,  252, 1015,  515, 1347,  295,  252,
++ /*   800 */   252,  252,  252, 1098,  375,  249,  512,  445,  872,  322,
++ /*   810 */  1016,  480,  512,  195,  512,  434,  273,   15,   15,  515,
++ /*   820 */   314,  515,   95,  515,   93, 1017,  367,  109,  109,  109,
++ /*   830 */   109,  108,  108,  107,  107,  107,  106,  401,  515, 1121,
++ /*   840 */    39,   39,   51,   51,   52,   52,  503,  370,  515, 1204,
++ /*   850 */  1098,  918,  439,  341,  133,  436,  223,  222,  221,   53,
++ /*   860 */    53,  322, 1400,  761,  762,  763,  515,  370,   88,   54,
++ /*   870 */    54,  112,  113,  103, 1100, 1100,  953,  956,  946,  946,
++ /*   880 */   110,  110,  111,  111,  111,  111,  407,   55,   55,  196,
++ /*   890 */   515,  112,  113,  103, 1100, 1100,  953,  956,  946,  946,
++ /*   900 */   110,  110,  111,  111,  111,  111,  135,  264, 1149,  376,
++ /*   910 */   515,   40,   40,  515,  872,  515,  993,  515,  993,  116,
++ /*   920 */   109,  109,  109,  109,  108,  108,  107,  107,  107,  106,
++ /*   930 */   401,   41,   41,  515,   43,   43,   44,   44,   56,   56,
++ /*   940 */   109,  109,  109,  109,  108,  108,  107,  107,  107,  106,
++ /*   950 */   401,  515,  379,  515,   57,   57,  515,  799,  515,  379,
++ /*   960 */   515,  445,  200,  515,  323,  515, 1397,  515, 1459,  515,
++ /*   970 */  1287,  817,   58,   58,   14,   14,  515,   59,   59,  118,
++ /*   980 */   118,   60,   60,  515,   46,   46,   61,   61,   62,   62,
++ /*   990 */    47,   47,  515,  190,  189,   91,  515,  140,  140,  515,
++ /*  1000 */   394,  515,  277, 1200,  141,  141,  515, 1115,  515,  992,
++ /*  1010 */   515,  992,  515,   69,   69,  370,  278,   48,   48,  259,
++ /*  1020 */    65,   65,  119,  119,  246,  246,  260,   66,   66,  120,
++ /*  1030 */   120,  121,  121,  117,  117,  370,  515,  512,  383,  112,
++ /*  1040 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*  1050 */   111,  111,  111,  111,  515,  872,  515,  139,  139,  112,
++ /*  1060 */   113,  103, 1100, 1100,  953,  956,  946,  946,  110,  110,
++ /*  1070 */   111,  111,  111,  111, 1287,  138,  138,  125,  125,  515,
++ /*  1080 */    12,  515,  281, 1287,  515,  445,  131, 1287,  109,  109,
++ /*  1090 */   109,  109,  108,  108,  107,  107,  107,  106,  401,  515,
++ /*  1100 */   124,  124,  122,  122,  515,  123,  123,  515,  109,  109,
++ /*  1110 */   109,  109,  108,  108,  107,  107,  107,  106,  401,  515,
++ /*  1120 */    68,   68,  463,  783,  515,   70,   70,  302,   67,   67,
++ /*  1130 */  1032,  253,  253,  356, 1287,  191,  196, 1433,  465, 1301,
++ /*  1140 */    38,   38,  384,   94,  512,   42,   42,  177,  848,  274,
++ /*  1150 */   506,  385,  420,  847, 1356,  441,  508,  376,  377,  153,
++ /*  1160 */   423,  872,  432,  370,  224,  251,  194,  887,  182,  293,
++ /*  1170 */   783,  848,   88,  254,  466,  888,  847,  915,  807,  806,
++ /*  1180 */   230, 1241,  910,  370,   17,  413,  797,  112,  113,  103,
++ /*  1190 */  1100, 1100,  953,  956,  946,  946,  110,  110,  111,  111,
++ /*  1200 */   111,  111,  395,  814,  815, 1175,  983,  112,  101,  103,
++ /*  1210 */  1100, 1100,  953,  956,  946,  946,  110,  110,  111,  111,
++ /*  1220 */   111,  111,  375,  422,  427,  429,  298,  230,  230,   88,
++ /*  1230 */  1240,  451,  312,  797,  226,   88,  109,  109,  109,  109,
++ /*  1240 */   108,  108,  107,  107,  107,  106,  401,   86,  433,  979,
++ /*  1250 */   927,  881,  226,  983,  230,  415,  109,  109,  109,  109,
++ /*  1260 */   108,  108,  107,  107,  107,  106,  401,  320,  845,  781,
++ /*  1270 */   846,  100,  130,  100, 1403,  290,  370,  319, 1377, 1376,
++ /*  1280 */   437, 1449,  299, 1237,  303,  306,  308,  310, 1188, 1174,
++ /*  1290 */  1173, 1172,  315,  324,  325, 1228,  370,  927, 1249,  271,
++ /*  1300 */  1286,  113,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*  1310 */   110,  111,  111,  111,  111, 1224, 1235,  502,  501, 1292,
++ /*  1320 */  1221, 1155,  103, 1100, 1100,  953,  956,  946,  946,  110,
++ /*  1330 */   110,  111,  111,  111,  111, 1148, 1137, 1136, 1138, 1443,
++ /*  1340 */   446,  244,  184,   98,  507,  188,    4,  353,  327,  109,
++ /*  1350 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*  1360 */   510,  329,  331,  199,  414,  456,  292,  285,  318,  109,
++ /*  1370 */   109,  109,  109,  108,  108,  107,  107,  107,  106,  401,
++ /*  1380 */    11, 1271, 1279,  402,  361,  192, 1171, 1351,  431,  505,
++ /*  1390 */   346, 1350,  333,   98,  507,  504,    4,  187, 1446, 1115,
++ /*  1400 */   233, 1396,  155, 1394, 1112,  152,   72,   75,  378,  425,
++ /*  1410 */   510,  165,  149,  157,  933, 1276,   86,   30, 1268,  417,
++ /*  1420 */    96,   96,    8,  160,  161,  162,  163,   97,  418,  402,
++ /*  1430 */   517,  516,  449,  402,  923,  210,  358,  424, 1282,  438,
++ /*  1440 */   169,  214,  360, 1345,   80,  504,   31,  444, 1365,  301,
++ /*  1450 */   245,  274,  506,  216,  174,  305,  488,  447,  217,  462,
++ /*  1460 */  1139,  487,  218,  363,  933,  923,  923,  925,  926,   24,
++ /*  1470 */    96,   96, 1191, 1190, 1189,  391, 1182,   97, 1163,  402,
++ /*  1480 */   517,  516,  799,  364,  923, 1162,  317, 1161,   98,  507,
++ /*  1490 */  1181,    4, 1458,  472,  393,  269,  270,  475,  481, 1232,
++ /*  1500 */    85, 1233,  326,  328,  232,  510,  495, 1231,  330,   98,
++ /*  1510 */   507, 1230,    4,  486,  335,  923,  923,  925,  926,   24,
++ /*  1520 */  1435, 1068,  404,  181,  336,  256,  510,  115,  402,  332,
++ /*  1530 */   352,  352,  351,  241,  349, 1214, 1414,  770,  338,   10,
++ /*  1540 */   504,  340,  272,   92, 1331, 1213,   87,  183,  484,  402,
++ /*  1550 */   201,  488,  280,  239,  344,  345,  489, 1145,   29,  933,
++ /*  1560 */   279,  504, 1074,  518,  240,   96,   96,  242,  243,  519,
++ /*  1570 */  1134, 1129,   97,  154,  402,  517,  516,  372,  373,  923,
++ /*  1580 */   933,  142,  143,  128, 1381,  267,   96,   96,  852,  757,
++ /*  1590 */   203,  144,  403,   97, 1382,  402,  517,  516,  204, 1380,
++ /*  1600 */   923,  146, 1379, 1159, 1158,   71, 1156,  276,  202,  185,
++ /*  1610 */   923,  923,  925,  926,   24,  198,  257,  126,  991,  989,
++ /*  1620 */   907,   98,  507,  156,    4,  145,  158,  206,  831,  209,
++ /*  1630 */   291,  923,  923,  925,  926,   24, 1005,  911,  510,  164,
++ /*  1640 */   147,  380,  371,  382,  166,   76,   77,  274,  506,  148,
++ /*  1650 */    78,   79, 1008,  211,  212, 1004,  137,  213,   18,  300,
++ /*  1660 */   230,  402,  997, 1109,  443,  215,   32,  170,  171,  772,
++ /*  1670 */   409,  448,  319,  504,  219,  172,  452,   81,   19,  457,
++ /*  1680 */   313,   20,   82,  268,  488,  150,  810,  179,   83,  487,
++ /*  1690 */   464,  151,  933,  180,  959,   84, 1040,   34,   96,   96,
++ /*  1700 */   471, 1041,   35,  474,  193,   97,  248,  402,  517,  516,
++ /*  1710 */  1068,  404,  923,  250,  256,  880,  229,  175,  875,  352,
++ /*  1720 */   352,  351,  241,  349,  100,   21,  770,   22, 1054, 1056,
++ /*  1730 */     7,   98,  507, 1045,    4,  337, 1058,   23,  974,  201,
++ /*  1740 */   176,  280,   88,  923,  923,  925,  926,   24,  510,  279,
++ /*  1750 */   960,  958,  962, 1014,  963, 1013,  235,  234,   25,   36,
++ /*  1760 */    99,   90,  507,  928,    4,  511,  350,  782,   26,  841,
++ /*  1770 */   236,  402,  347, 1069,  237, 1125, 1125, 1451,  510,  203,
++ /*  1780 */  1450, 1125, 1125,  504, 1125, 1125, 1125,  204, 1125, 1125,
++ /*  1790 */   146, 1125, 1125, 1125, 1125, 1125, 1125,  202, 1125, 1125,
++ /*  1800 */  1125,  402,  933, 1125, 1125, 1125, 1125, 1125,   96,   96,
++ /*  1810 */  1125, 1125, 1125,  504, 1125,   97, 1125,  402,  517,  516,
++ /*  1820 */  1125, 1125,  923, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1830 */  1125,  371,  933, 1125, 1125, 1125,  274,  506,   96,   96,
++ /*  1840 */  1125, 1125, 1125, 1125, 1125,   97, 1125,  402,  517,  516,
++ /*  1850 */  1125, 1125,  923,  923,  923,  925,  926,   24, 1125,  409,
++ /*  1860 */  1125, 1125, 1125,  256, 1125, 1125, 1125, 1125,  352,  352,
++ /*  1870 */   351,  241,  349, 1125, 1125,  770, 1125, 1125, 1125, 1125,
++ /*  1880 */  1125, 1125, 1125,  923,  923,  925,  926,   24,  201, 1125,
++ /*  1890 */   280, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  279, 1125,
++ /*  1900 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1910 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1920 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  203, 1125,
++ /*  1930 */  1125, 1125, 1125, 1125, 1125, 1125,  204, 1125, 1125,  146,
++ /*  1940 */  1125, 1125, 1125, 1125, 1125, 1125,  202, 1125, 1125, 1125,
++ /*  1950 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1960 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1970 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  1980 */   371, 1125, 1125, 1125, 1125,  274,  506, 1125, 1125, 1125,
++ /*  1990 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
++ /*  2000 */  1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,  409,
+ };
+ static const YYCODETYPE yy_lookahead[] = {
+- /*     0 */   152,  144,  145,  146,  147,  152,  152,  172,  152,  180,
+- /*    10 */   181,  152,  223,  224,  225,  180,  152,  164,  189,   19,
+- /*    20 */   223,  224,  225,  168,  169,  170,  163,  173,  174,  173,
+- /*    30 */   174,   31,  173,  174,  168,  169,  170,  173,  174,   39,
+- /*    40 */   243,  191,  192,   43,   44,   45,   46,   47,   48,   49,
+- /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,  195,  196,
+- /*    60 */    22,   23,  208,  209,  208,  209,  218,  208,  209,  176,
+- /*    70 */   207,   19,  208,  209,   23,  212,  213,   26,   26,  152,
+- /*    80 */    46,   47,   48,   49,   84,   85,   86,   87,   88,   89,
+- /*    90 */    90,   91,   92,   93,   94,   43,   44,   45,   46,   47,
+- /*   100 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
+- /*   110 */    90,   91,   92,   93,   94,  188,  223,  224,  225,  171,
+- /*   120 */    68,   83,  152,   19,   84,   85,   86,   87,   88,   89,
+- /*   130 */    90,   91,   92,   93,   94,  101,   84,   85,   86,   87,
+- /*   140 */    88,   89,   90,   91,   92,   93,   94,   43,   44,   45,
+- /*   150 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+- /*   160 */    56,   57,   99,   94,  194,  102,  103,  104,  109,  110,
+- /*   170 */    66,  223,  224,  225,  152,   19,  113,   22,   23,  152,
+- /*   180 */    24,   26,  160,    1,    2,   59,  164,  173,   84,   85,
+- /*   190 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   43,
+- /*   200 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+- /*   210 */    54,   55,   56,   57,  244,   88,   89,   90,   91,   92,
+- /*   220 */    93,   94,   96,   97,   98,   99,  196,   19,  102,  103,
+- /*   230 */   104,   23,   88,   89,  173,   59,  163,  207,   83,  113,
+- /*   240 */    84,   85,   86,   87,   88,   89,   90,   91,   92,   93,
+- /*   250 */    94,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+- /*   260 */    52,   53,   54,   55,   56,   57,   90,  240,  195,  196,
+- /*   270 */   171,   82,   96,   97,   98,  152,  132,  176,  134,   19,
+- /*   280 */   207,  200,   72,   23,   93,   94,   97,  152,  173,   79,
+- /*   290 */   101,  210,   84,   85,   86,   87,   88,   89,   90,   91,
+- /*   300 */    92,   93,   94,   43,   44,   45,   46,   47,   48,   49,
+- /*   310 */    50,   51,   52,   53,   54,   55,   56,   57,  108,  152,
+- /*   320 */   152,  132,  133,  134,  223,  224,  225,  152,  186,  119,
+- /*   330 */   120,   19,  197,  234,   31,   23,   26,  152,  239,   59,
+- /*   340 */   173,  174,   39,  220,   84,   85,   86,   87,   88,   89,
+- /*   350 */    90,   91,   92,   93,   94,   43,   44,   45,   46,   47,
+- /*   360 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
+- /*   370 */   152,   22,  152,   16,  152,  208,   96,   97,   98,  194,
+- /*   380 */    22,   23,   11,   19,   26,   79,   72,   23,    0,    1,
+- /*   390 */     2,  173,  174,  173,  174,  220,   84,   85,   86,   87,
+- /*   400 */    88,   89,   90,   91,   92,   93,   94,   43,   44,   45,
+- /*   410 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+- /*   420 */    56,   57,  108,  109,  110,  119,  120,  152,  208,  119,
+- /*   430 */   120,  137,   75,  139,   77,   19,  152,   88,   89,   23,
+- /*   440 */   115,   83,  117,  118,  163,  227,  163,  152,   84,   85,
+- /*   450 */    86,   87,   88,   89,   90,   91,   92,   93,   94,   43,
+- /*   460 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+- /*   470 */    54,   55,   56,   57,  195,  196,  195,  196,  195,  196,
+- /*   480 */   109,  110,  195,  196,   22,   23,  207,   19,  207,  152,
+- /*   490 */   207,  108,  109,  110,  207,  163,   22,  140,   24,   59,
+- /*   500 */    84,   85,   86,   87,   88,   89,   90,   91,   92,   93,
+- /*   510 */    94,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+- /*   520 */    52,   53,   54,   55,   56,   57,  152,  195,  196,  152,
+- /*   530 */    16,    7,    8,    9,  197,  240,   96,   97,   98,  207,
+- /*   540 */   249,  250,   19,  152,   22,   83,   26,  173,  174,  152,
+- /*   550 */   173,  174,   84,   85,   86,   87,   88,   89,   90,   91,
+- /*   560 */    92,   93,   94,   59,  124,  152,   43,   44,   45,   46,
+- /*   570 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
+- /*   580 */    57,   59,  169,  170,  157,  194,   82,  191,  192,   75,
+- /*   590 */   152,   77,  108,  109,  110,   26,  152,   19,  152,  152,
+- /*   600 */    96,   97,   24,  152,  152,  101,  138,   84,   85,   86,
+- /*   610 */    87,   88,   89,   90,   91,   92,   93,   94,   96,   97,
+- /*   620 */    98,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+- /*   630 */    52,   53,   54,   55,   56,   57,  132,  133,  134,  188,
+- /*   640 */   194,  197,  152,  123,  197,  232,  194,  152,  182,   19,
+- /*   650 */   119,  120,  152,  152,  152,  152,  218,  230,  152,  163,
+- /*   660 */   233,  138,   84,   85,   86,   87,   88,   89,   90,   91,
+- /*   670 */    92,   93,   94,   43,   44,   45,   46,   47,   48,   49,
+- /*   680 */    50,   51,   52,   53,   54,   55,   56,   57,  152,  152,
+- /*   690 */    23,  195,  196,   26,  194,  194,  194,  146,  147,  130,
+- /*   700 */   194,   19,   46,  207,   59,   29,  166,  167,  218,   33,
+- /*   710 */   173,  174,   26,  218,   84,   85,   86,   87,   88,   89,
+- /*   720 */    90,   91,   92,   93,   94,   43,   44,   45,   46,   47,
+- /*   730 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
+- /*   740 */    64,  171,   97,  240,  116,  166,  167,  212,  213,  121,
+- /*   750 */    23,  152,   19,   26,  218,  247,  248,   23,   23,  152,
+- /*   760 */    26,   26,   22,  107,  163,   98,   84,   85,   86,   87,
+- /*   770 */    88,   89,   90,   91,   92,   93,   94,   44,   45,   46,
+- /*   780 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
+- /*   790 */    57,  124,  106,   53,  100,  101,  195,  196,  152,  152,
+- /*   800 */    23,   23,   19,   26,   26,   19,  152,   23,  207,  239,
+- /*   810 */    26,   23,  152,  163,   26,  169,  170,   84,   85,   86,
+- /*   820 */    87,   88,   89,   90,   91,   92,   93,   94,   45,   46,
+- /*   830 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
+- /*   840 */    57,   19,   20,  101,   22,  195,  196,   22,   19,   24,
+- /*   850 */   163,   19,    7,    8,  112,   59,   23,  207,   36,   26,
+- /*   860 */    23,  152,   59,   26,   21,   59,  152,   84,   85,   86,
+- /*   870 */    87,   88,   89,   90,   91,   92,   93,   94,  232,  221,
+- /*   880 */    94,   59,  195,  196,   59,   99,  100,  101,  102,  103,
+- /*   890 */   104,  105,   70,   97,  207,   59,   19,   20,  112,   22,
+- /*   900 */    97,   79,  152,   97,   82,  152,  152,   71,  221,   90,
+- /*   910 */    88,   89,   23,   36,   12,   26,  163,   95,   96,   97,
+- /*   920 */    98,   78,   97,  101,  152,   96,  173,  174,   96,   27,
+- /*   930 */   182,   22,   96,   97,   98,  116,   59,  148,  149,  152,
+- /*   940 */   121,  119,  120,  154,   42,  156,  103,   70,  195,  196,
+- /*   950 */    22,   59,  163,  152,  132,  133,  134,  135,  136,   82,
+- /*   960 */   207,  208,  209,   71,   62,   88,   89,   90,   59,  152,
+- /*   970 */   152,   12,   95,   96,   97,   98,   19,   20,  101,   22,
+- /*   980 */    22,  182,  152,  140,  195,  196,   27,   59,   96,   97,
+- /*   990 */    98,   59,  132,   36,  134,   22,  207,   19,   20,   24,
+- /*  1000 */    22,   42,  152,  173,  174,   96,   97,   98,  219,  132,
+- /*  1010 */   133,  134,  135,  136,   36,  152,   59,  187,  132,  152,
+- /*  1020 */   134,   62,  152,  152,   96,   97,   98,   70,   96,   97,
+- /*  1030 */    98,   72,   59,  152,   59,  246,   26,   59,  214,   82,
+- /*  1040 */   152,  192,  152,  173,  174,   88,   89,   79,   70,  152,
+- /*  1050 */   152,   19,   95,   96,   97,   98,  124,  187,  101,   23,
+- /*  1060 */    82,  164,   26,  173,  174,  152,   88,   89,  100,   96,
+- /*  1070 */    97,   98,   97,   95,   96,   97,   98,  187,   46,  101,
+- /*  1080 */   122,  184,  152,  186,  211,  152,  152,  119,  120,  132,
+- /*  1090 */   133,  134,  135,  136,  152,    5,   22,  152,  152,   35,
+- /*  1100 */    10,   11,   12,   13,   14,  152,  152,   17,   98,  235,
+- /*  1110 */   132,  133,  134,  135,  136,   54,   55,   56,   57,   58,
+- /*  1120 */    30,  152,   32,  152,  152,  198,  173,  174,  152,   65,
+- /*  1130 */    40,  152,  152,   59,  124,  152,  236,   73,  199,  107,
+- /*  1140 */   187,  171,  173,  174,  112,   84,   85,   86,   87,   88,
+- /*  1150 */    89,   90,   91,   92,   93,   94,  173,  174,  152,   69,
+- /*  1160 */   152,  211,   54,   55,   56,   57,   76,  152,  150,   79,
+- /*  1170 */    80,   97,  211,  211,  211,  111,   59,  241,  241,  173,
+- /*  1180 */   174,  173,  174,  202,  202,  185,  177,  176,  173,  174,
+- /*  1190 */   176,  201,   84,   85,   86,   87,   88,   89,   90,   91,
+- /*  1200 */    92,   93,   94,  215,  114,   88,   89,  152,  215,  119,
+- /*  1210 */   120,  152,  181,   96,   97,   98,  176,  100,  215,  152,
+- /*  1220 */   229,  152,  163,  152,  107,  199,  109,  155,  173,  174,
+- /*  1230 */   245,  141,  173,  174,   60,  159,  152,  122,  159,  242,
+- /*  1240 */   173,  174,  173,  174,  173,  174,   38,  242,  152,  132,
+- /*  1250 */   159,  134,  152,   22,  195,  196,  152,  173,  174,  222,
+- /*  1260 */    43,  130,  202,  152,   18,  152,  207,  208,  152,  173,
+- /*  1270 */   174,  152,  190,  173,  174,  152,  193,  173,  174,  152,
+- /*  1280 */   193,  193,  152,  159,  173,  174,  173,  174,  152,  173,
+- /*  1290 */   174,  193,  173,  174,   18,  152,  173,  174,  152,  158,
+- /*  1300 */   173,  174,  152,  173,  174,  152,  159,  152,  202,  173,
+- /*  1310 */   174,  152,  190,  152,  222,  152,  173,  174,  152,  173,
+- /*  1320 */   174,  137,  152,  173,  174,  190,  173,  174,  173,  174,
+- /*  1330 */   202,  158,  173,  174,  173,  174,  173,  174,   61,  173,
+- /*  1340 */   174,  152,  237,  173,  174,  152,  159,  152,  238,  152,
+- /*  1350 */   158,  152,   22,  152,  178,  152,  158,  152,  158,  152,
+- /*  1360 */   178,  159,  173,  174,  152,  159,  173,  174,  173,  174,
+- /*  1370 */   173,  174,  173,  174,  173,  174,  173,  174,  173,  174,
+- /*  1380 */   173,  174,  152,   63,  152,  173,  174,  107,  175,  175,
+- /*  1390 */   175,  106,  183,  175,  178,  175,  177,  175,  175,  178,
+- /*  1400 */    94,  107,  231,  173,  174,  173,  174,  183,  231,  125,
+- /*  1410 */   216,  178,  159,  217,   22,  159,  226,  129,  137,  228,
+- /*  1420 */   128,  217,  126,   25,  127,  162,  216,   26,  217,  161,
+- /*  1430 */    13,  153,  153,  206,  205,    6,  251,  202,  204,  203,
+- /*  1440 */   151,  216,  151,  217,  216,  171,  151,  165,  179,  179,
+- /*  1450 */     4,    3,   22,  142,  171,  165,   15,  171,  171,   81,
+- /*  1460 */    16,   23,   23,  120,  171,  131,  165,  111,  123,  171,
+- /*  1470 */   171,  171,   20,  125,   16,    1,  123,  131,   53,   53,
+- /*  1480 */    53,   53,  111,   96,   34,  122,  248,    1,  251,    5,
+- /*  1490 */    22,  107,  140,   26,   74,   41,  122,  107,   67,   67,
+- /*  1500 */    24,   20,   19,  112,  105,   23,   66,   22,   66,   22,
+- /*  1510 */    22,   22,   37,   22,   22,   66,   23,   23,   28,   23,
+- /*  1520 */    23,   26,   24,   23,   22,   24,  122,   23,   23,   96,
+- /*  1530 */    22,  124,   26,   34,   23,   26,   23,   34,   23,   23,
+- /*  1540 */    23,   34,   23,   22,   26,   11,   22,   22,   26,   23,
+- /*  1550 */    23,   22,  116,   23,   22,   15,  122,  122,   23,  122,
+- /*  1560 */     1,  252,  252,  252,  252,  122,  252,  252,  252,  252,
+- /*  1570 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1580 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1590 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1600 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1610 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1620 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1630 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1640 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1650 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1660 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1670 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1680 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1690 */   252,  252,  252,  252,  252,  252,  252,  252,  252,  252,
+- /*  1700 */   252,  252,  252,  252,  252,  252,  252,  252,  252,
++ /*     0 */   184,  238,  239,  240,  238,  239,  240,  163,  155,  156,
++ /*    10 */   157,  158,  159,  160,  163,  191,  192,  183,  165,   19,
++ /*    20 */   167,  258,  202,  203,  200,  191,  163,  174,  184,  185,
++ /*    30 */   174,   31,  163,  163,  171,  184,  185,   35,  175,   39,
++ /*    40 */   179,  180,  181,   43,   44,   45,   46,   47,   48,   49,
++ /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,  184,  206,
++ /*    60 */   207,  163,  206,  207,  220,  163,   16,  163,   66,  163,
++ /*    70 */    59,  270,  219,  229,  273,  219,   74,  208,  174,  223,
++ /*    80 */   224,  163,  184,  185,  163,  232,  184,  185,  184,  185,
++ /*    90 */   184,  185,   92,   93,   94,   95,   96,   97,   98,   99,
++ /*   100 */   100,  101,  102,  233,  198,  184,  185,   96,   97,  163,
++ /*   110 */   206,  207,   19,  163,  261,  104,  105,  106,  107,  198,
++ /*   120 */   109,  119,  220,  219,  220,  274,  275,   77,  117,   79,
++ /*   130 */   187,  229,   19,  229,  184,  185,   43,   44,   45,   46,
++ /*   140 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   150 */    57,  233,  141,  134,  143,  102,   43,   44,   45,   46,
++ /*   160 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   170 */    57,  152,  274,  216,  276,  218,   83,  163,   85,  233,
++ /*   180 */    67,  238,  239,  240,   11,   92,   93,   94,   95,   96,
++ /*   190 */    97,   98,   99,  100,  101,  102,   19,   54,   55,   56,
++ /*   200 */    57,   58,  163,   26,  163,   92,   93,   94,   95,   96,
++ /*   210 */    97,   98,   99,  100,  101,  102,   54,   55,   56,   57,
++ /*   220 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*   230 */    53,   54,   55,   56,   57,   92,   93,   94,   95,   96,
++ /*   240 */    97,   98,   99,  100,  101,  102,   69,   96,   97,   98,
++ /*   250 */    99,  100,  101,  102,   92,   93,   94,   95,   96,   97,
++ /*   260 */    98,   99,  100,  101,  102,   81,  179,  180,  181,   92,
++ /*   270 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*   280 */   163,  267,  268,  163,   22,   23,   59,  163,   26,   19,
++ /*   290 */   117,  118,  175,  109,   24,   59,   92,   93,   94,   95,
++ /*   300 */    96,   97,   98,   99,  100,  101,  102,  268,  184,  185,
++ /*   310 */   269,  127,  128,   43,   44,   45,   46,   47,   48,   49,
++ /*   320 */    50,   51,   52,   53,   54,   55,   56,   57,  157,  158,
++ /*   330 */   159,  160,  105,  106,  107,  163,  165,   59,  167,  184,
++ /*   340 */    90,  105,  106,  107,  108,  174,   73,  111,  112,  113,
++ /*   350 */    19,   22,  163,   91,   81,  163,  106,  121,   81,  132,
++ /*   360 */   110,   16,   92,   93,   94,   95,   96,   97,   98,   99,
++ /*   370 */   100,  101,  102,  184,  185,  255,   98,  206,  207,   26,
++ /*   380 */   101,  102,   19,  105,  106,  107,   23,  198,   59,  116,
++ /*   390 */   219,  141,  142,  143,   24,  163,  187,  205,  274,  275,
++ /*   400 */   127,  128,  182,  232,  127,  128,   43,   44,   45,   46,
++ /*   410 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
++ /*   420 */    57,  158,   77,  160,   79,   59,   26,  182,  165,   59,
++ /*   430 */   167,  199,  261,  102,  105,  106,  107,  174,   72,  108,
++ /*   440 */   109,  110,  111,  112,  113,  114,   59,  238,  239,  240,
++ /*   450 */   123,  120,  125,  126,  163,   92,   93,   94,   95,   96,
++ /*   460 */    97,   98,   99,  100,  101,  102,  163,  163,  163,  206,
++ /*   470 */   207,  105,  106,  107,  254,   19,  106,   90,  197,   23,
++ /*   480 */   127,  128,  219,  238,  239,  240,   22,  184,  185,  184,
++ /*   490 */   185,   22,  105,  106,  149,  232,  205,  110,  163,   43,
++ /*   500 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*   510 */    54,   55,   56,   57,   98,   99,  100,  101,  102,  184,
++ /*   520 */   185,  163,   53,   59,  261,  220,  117,  118,  141,  142,
++ /*   530 */   143,  131,  174,   59,  229,  116,  117,  118,  163,   59,
++ /*   540 */   163,  163,  184,  185,   59,  242,   72,   22,   92,   93,
++ /*   550 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  184,
++ /*   560 */   185,   24,  184,  185,  206,  207,  202,  203,   19,  105,
++ /*   570 */   106,  107,   23,  198,   22,  174,  198,  219,  220,  105,
++ /*   580 */   106,  107,   96,   97,   59,  105,  106,  107,   22,  174,
++ /*   590 */    59,  106,   43,   44,   45,   46,   47,   48,   49,   50,
++ /*   600 */    51,   52,   53,   54,   55,   56,   57,  206,  207,   12,
++ /*   610 */   108,   59,  132,  111,  112,  113,   46,   47,   48,   49,
++ /*   620 */   219,  206,  207,  121,   27,   59,  163,  141,  207,  143,
++ /*   630 */   105,  106,  107,  163,  219,  234,  105,  106,  107,   42,
++ /*   640 */   219,   92,   93,   94,   95,   96,   97,   98,   99,  100,
++ /*   650 */   101,  102,   76,  163,  184,  185,  163,  105,  106,  107,
++ /*   660 */    63,   19,   86,  163,  163,   23,  163,  130,  205,   21,
++ /*   670 */    73,  105,  106,  107,  184,  185,  163,  184,  185,  237,
++ /*   680 */   110,  180,  181,  180,  181,   43,   44,   45,   46,   47,
++ /*   690 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
++ /*   700 */   174,  163,  163,   22,   23,  163,  163,   26,   22,   23,
++ /*   710 */   220,   29,   73,  220,  272,   33,   22,  163,   24,   19,
++ /*   720 */   174,  208,  259,  184,  185,   19,  184,  185,   80,  175,
++ /*   730 */   230,  174,  206,  207,   92,   93,   94,   95,   96,   97,
++ /*   740 */    98,   99,  100,  101,  102,  219,   46,   65,  247,  195,
++ /*   750 */   247,  197,  206,  207,   19,  116,  117,  118,   23,  220,
++ /*   760 */   112,  174,  220,  206,  207,  219,   22,  174,   24,  174,
++ /*   770 */    22,   23,   91,  264,  265,  168,  219,   91,   43,   44,
++ /*   780 */    45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
++ /*   790 */    55,   56,   57,  206,  207,   12,  163,  149,  255,  206,
++ /*   800 */   207,  206,  207,   59,  104,   23,  219,  163,   26,  163,
++ /*   810 */    27,  105,  219,  163,  219,  163,  211,  184,  185,  163,
++ /*   820 */   120,  163,  146,  163,  148,   42,  221,   92,   93,   94,
++ /*   830 */    95,   96,   97,   98,   99,  100,  101,  102,  163,   91,
++ /*   840 */   184,  185,  184,  185,  184,  185,   63,   19,  163,  205,
++ /*   850 */   106,   23,  245,  163,  208,  248,  116,  117,  118,  184,
++ /*   860 */   185,  163,  163,    7,    8,    9,  163,   19,   26,  184,
++ /*   870 */   185,   43,   44,   45,   46,   47,   48,   49,   50,   51,
++ /*   880 */    52,   53,   54,   55,   56,   57,  163,  184,  185,  107,
++ /*   890 */   163,   43,   44,   45,   46,   47,   48,   49,   50,   51,
++ /*   900 */    52,   53,   54,   55,   56,   57,  208,  255,  177,  178,
++ /*   910 */   163,  184,  185,  163,  132,  163,  141,  163,  143,   22,
++ /*   920 */    92,   93,   94,   95,   96,   97,   98,   99,  100,  101,
++ /*   930 */   102,  184,  185,  163,  184,  185,  184,  185,  184,  185,
++ /*   940 */    92,   93,   94,   95,   96,   97,   98,   99,  100,  101,
++ /*   950 */   102,  163,  163,  163,  184,  185,  163,  115,  163,  163,
++ /*   960 */   163,  163,   15,  163,  163,  163,  163,  163,   23,  163,
++ /*   970 */   163,   26,  184,  185,  184,  185,  163,  184,  185,  184,
++ /*   980 */   185,  184,  185,  163,  184,  185,  184,  185,  184,  185,
++ /*   990 */   184,  185,  163,   96,   97,  147,  163,  184,  185,  163,
++ /*  1000 */   199,  163,  163,  205,  184,  185,  163,   60,  163,  141,
++ /*  1010 */   163,  143,  163,  184,  185,   19,  163,  184,  185,  230,
++ /*  1020 */   184,  185,  184,  185,  206,  207,  230,  184,  185,  184,
++ /*  1030 */   185,  184,  185,  184,  185,   19,  163,  219,  231,   43,
++ /*  1040 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*  1050 */    54,   55,   56,   57,  163,   26,  163,  184,  185,   43,
++ /*  1060 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
++ /*  1070 */    54,   55,   56,   57,  163,  184,  185,  184,  185,  163,
++ /*  1080 */   182,  163,  163,  163,  163,  163,   22,  163,   92,   93,
++ /*  1090 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  163,
++ /*  1100 */   184,  185,  184,  185,  163,  184,  185,  163,   92,   93,
++ /*  1110 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  163,
++ /*  1120 */   184,  185,   98,   59,  163,  184,  185,  205,  184,  185,
++ /*  1130 */    23,  206,  207,   26,  163,   26,  107,  153,  154,  237,
++ /*  1140 */   184,  185,  231,  147,  219,  184,  185,  249,  124,  127,
++ /*  1150 */   128,  231,  254,  129,  163,  231,  177,  178,  262,  263,
++ /*  1160 */   118,  132,   19,   19,   46,  223,  224,   31,   24,   23,
++ /*  1170 */   106,  124,   26,   22,  272,   39,  129,   23,  109,  110,
++ /*  1180 */    26,  163,  140,   19,   22,  234,   59,   43,   44,   45,
++ /*  1190 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
++ /*  1200 */    56,   57,  231,    7,    8,  193,   59,   43,   44,   45,
++ /*  1210 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
++ /*  1220 */    56,   57,  104,   61,   23,   23,   23,   26,   26,   26,
++ /*  1230 */   163,   23,   23,  106,   26,   26,   92,   93,   94,   95,
++ /*  1240 */    96,   97,   98,   99,  100,  101,  102,  138,  105,   23,
++ /*  1250 */    59,   23,   26,  106,   26,  163,   92,   93,   94,   95,
++ /*  1260 */    96,   97,   98,   99,  100,  101,  102,  110,   23,   23,
++ /*  1270 */    23,   26,   26,   26,  163,  163,   19,  120,  163,  163,
++ /*  1280 */   163,  130,  163,  163,  163,  163,  163,  163,  163,  193,
++ /*  1290 */   193,  163,  163,  163,  163,  225,   19,  106,  163,  222,
++ /*  1300 */   163,   44,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*  1310 */    53,   54,   55,   56,   57,  163,  163,  203,  163,  163,
++ /*  1320 */   222,  163,   45,   46,   47,   48,   49,   50,   51,   52,
++ /*  1330 */    53,   54,   55,   56,   57,  163,  163,  163,  163,  163,
++ /*  1340 */   251,  250,  209,   19,   20,  182,   22,  161,  222,   92,
++ /*  1350 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*  1360 */    36,  222,  222,  260,  226,  188,  256,  226,  187,   92,
++ /*  1370 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
++ /*  1380 */   210,  213,  213,   59,  213,  196,  192,  187,  256,  244,
++ /*  1390 */   212,  187,  226,   19,   20,   71,   22,  210,  166,   60,
++ /*  1400 */   130,  170,  260,  170,   38,   81,  257,  257,  170,  104,
++ /*  1410 */    36,   22,   43,  201,   90,  236,  138,  235,  213,   18,
++ /*  1420 */    96,   97,   48,  204,  204,  204,  204,  103,  170,  105,
++ /*  1430 */   106,  107,   18,   59,  110,  169,  213,  213,  201,  170,
++ /*  1440 */   201,  169,  236,  213,  146,   71,  235,   62,  253,  252,
++ /*  1450 */   170,  127,  128,  169,   22,  170,   82,  189,  169,  104,
++ /*  1460 */   170,   87,  169,  189,   90,  141,  142,  143,  144,  145,
++ /*  1470 */    96,   97,  186,  186,  186,   64,  194,  103,  186,  105,
++ /*  1480 */   106,  107,  115,  189,  110,  188,  186,  186,   19,   20,
++ /*  1490 */   194,   22,  186,  189,  102,  246,  246,  189,  133,  228,
++ /*  1500 */   104,  228,  227,  227,  170,   36,  134,  228,  227,   19,
++ /*  1510 */    20,  228,   22,   84,  271,  141,  142,  143,  144,  145,
++ /*  1520 */     0,    1,    2,  216,   22,    5,   36,  137,   59,  227,
++ /*  1530 */    10,   11,   12,   13,   14,  217,  269,   17,  216,   22,
++ /*  1540 */    71,  170,  243,  146,  241,  217,  136,  215,  135,   59,
++ /*  1550 */    30,   82,   32,   25,  214,  213,   87,  173,   26,   90,
++ /*  1560 */    40,   71,   13,  172,  164,   96,   97,  164,    6,  162,
++ /*  1570 */   162,  162,  103,  263,  105,  106,  107,  266,  266,  110,
++ /*  1580 */    90,  176,  176,  190,  182,  190,   96,   97,   98,    4,
++ /*  1590 */    70,  176,    3,  103,  182,  105,  106,  107,   78,  182,
++ /*  1600 */   110,   81,  182,  182,  182,  182,  182,  151,   88,   22,
++ /*  1610 */   141,  142,  143,  144,  145,   15,   89,   16,   23,   23,
++ /*  1620 */   128,   19,   20,  139,   22,  119,  131,   24,   20,  133,
++ /*  1630 */    16,  141,  142,  143,  144,  145,    1,  140,   36,  131,
++ /*  1640 */   119,   61,  122,   37,  139,   53,   53,  127,  128,  119,
++ /*  1650 */    53,   53,  105,   34,  130,    1,    5,  104,   22,  149,
++ /*  1660 */    26,   59,   68,   75,   41,  130,   24,   68,  104,   20,
++ /*  1670 */   150,   19,  120,   71,  114,   22,   67,   22,   22,   67,
++ /*  1680 */    23,   22,   22,   67,   82,   37,   28,   23,  138,   87,
++ /*  1690 */    22,  153,   90,   23,   23,   26,   23,   22,   96,   97,
++ /*  1700 */    24,   23,   22,   24,  130,  103,   23,  105,  106,  107,
++ /*  1710 */     1,    2,  110,   23,    5,  105,   34,   22,  132,   10,
++ /*  1720 */    11,   12,   13,   14,   26,   34,   17,   34,   85,   83,
++ /*  1730 */    44,   19,   20,   23,   22,   24,   75,   34,   23,   30,
++ /*  1740 */    26,   32,   26,  141,  142,  143,  144,  145,   36,   40,
++ /*  1750 */    23,   23,   23,   23,   11,   23,   22,   26,   22,   22,
++ /*  1760 */    22,   19,   20,   23,   22,   26,   15,   23,   22,  124,
++ /*  1770 */   130,   59,   23,    1,  130,  277,  277,  130,   36,   70,
++ /*  1780 */   130,  277,  277,   71,  277,  277,  277,   78,  277,  277,
++ /*  1790 */    81,  277,  277,  277,  277,  277,  277,   88,  277,  277,
++ /*  1800 */   277,   59,   90,  277,  277,  277,  277,  277,   96,   97,
++ /*  1810 */   277,  277,  277,   71,  277,  103,  277,  105,  106,  107,
++ /*  1820 */   277,  277,  110,  277,  277,  277,  277,  277,  277,  277,
++ /*  1830 */   277,  122,   90,  277,  277,  277,  127,  128,   96,   97,
++ /*  1840 */   277,  277,  277,  277,  277,  103,  277,  105,  106,  107,
++ /*  1850 */   277,  277,  110,  141,  142,  143,  144,  145,  277,  150,
++ /*  1860 */   277,  277,  277,    5,  277,  277,  277,  277,   10,   11,
++ /*  1870 */    12,   13,   14,  277,  277,   17,  277,  277,  277,  277,
++ /*  1880 */   277,  277,  277,  141,  142,  143,  144,  145,   30,  277,
++ /*  1890 */    32,  277,  277,  277,  277,  277,  277,  277,   40,  277,
++ /*  1900 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1910 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1920 */   277,  277,  277,  277,  277,  277,  277,  277,   70,  277,
++ /*  1930 */   277,  277,  277,  277,  277,  277,   78,  277,  277,   81,
++ /*  1940 */   277,  277,  277,  277,  277,  277,   88,  277,  277,  277,
++ /*  1950 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1960 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1970 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  1980 */   122,  277,  277,  277,  277,  127,  128,  277,  277,  277,
++ /*  1990 */   277,  277,  277,  277,  277,  277,  277,  277,  277,  277,
++ /*  2000 */   277,  277,  277,  277,  277,  277,  277,  277,  150,  277,
++ /*  2010 */   277,  277,  277,  277,  277,  277,  277,  277,  277,
+ };
+-#define YY_SHIFT_COUNT    (471)
++#define YY_SHIFT_COUNT    (520)
+ #define YY_SHIFT_MIN      (0)
+-#define YY_SHIFT_MAX      (1559)
++#define YY_SHIFT_MAX      (1858)
+ static const unsigned short int yy_shift_ofst[] = {
+- /*     0 */   182, 1090,  822,  822,  306,  957,  957,  957,  957,  210,
+- /*    10 */     0,    0,  104,  630,  957,  957,  957,  957,  957,  957,
+- /*    20 */   957, 1117, 1117,  126,  968,  306,  306,  306,  306,  306,
+- /*    30 */   306,   52,  156,  208,  260,  312,  364,  416,  468,  523,
+- /*    40 */   578,  630,  630,  630,  630,  630,  630,  630,  630,  630,
+- /*    50 */   630,  630,  630,  630,  630,  630,  630,  630,  682,  630,
+- /*    60 */   733,  783,  783,  877,  957,  957,  957,  957,  957,  957,
+- /*    70 */   957,  957,  957,  957,  957,  957,  957,  957,  957,  957,
+- /*    80 */   957,  957,  957,  957,  957,  957,  957,  957,  957,  957,
+- /*    90 */   957,  957,  957,  957,  957,  978,  957,  957,  957,  957,
+- /*   100 */   957,  957,  957,  957,  957,  957,  957,  957,  957, 1061,
+- /*   110 */  1108, 1108, 1108, 1108, 1108,   40,  127,   20,  280,  843,
+- /*   120 */  1032,  144,  144,  280,  310,  310,  310,  310,   59,  191,
+- /*   130 */    69, 1566, 1566, 1566,  786,  786,  786,  522,  836,  522,
+- /*   140 */   959,  959,  892,  155,  358,  280,  280,  280,  280,  280,
+- /*   150 */   280,  280,  280,  280,  280,  280,  280,  280,  280,  280,
+- /*   160 */   280,  280,  280,  280,  280,  280,  371,  388,  645,  645,
+- /*   170 */   531, 1566, 1566, 1566,  504,  189,  189,  909,   63,  176,
+- /*   180 */   928,  440,  932,  973,  280,  280,  280,  280,  280,  314,
+- /*   190 */   280,  280,  280,  280,  280,  280,  280,  280,  280,  280,
+- /*   200 */   280,  280, 1064, 1064, 1064,  280,  280,  280,  280,  667,
+- /*   210 */   280,  280,  280,  825,  280,  280,  902,  280,  280,  280,
+- /*   220 */   280,  280,  280,  280,  280,  383,  676,  325,  975,  975,
+- /*   230 */   975,  975, 1010,  325,  325,  819,  349,  524,  569,  829,
+- /*   240 */   829,  832,  569,  832,  686,   51,  656,  303,  303,  303,
+- /*   250 */   829,  294,  520,  628,  474, 1174, 1115, 1115, 1208, 1208,
+- /*   260 */  1115, 1231, 1217, 1131, 1246, 1246, 1246, 1246, 1115, 1276,
+- /*   270 */  1131, 1231, 1217, 1217, 1131, 1115, 1276, 1184, 1277, 1115,
+- /*   280 */  1276, 1330, 1115, 1276, 1115, 1276, 1330, 1280, 1280, 1280,
+- /*   290 */  1320, 1330, 1280, 1285, 1280, 1320, 1280, 1280, 1330, 1306,
+- /*   300 */  1306, 1330, 1284, 1294, 1284, 1294, 1284, 1294, 1284, 1294,
+- /*   310 */  1115, 1392, 1115, 1281, 1288, 1296, 1292, 1297, 1131, 1398,
+- /*   320 */  1401, 1417, 1417, 1429, 1429, 1429, 1566, 1566, 1566, 1566,
+- /*   330 */  1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+- /*   340 */  1566, 1566,   34,  357,   38,  462,  514,  484, 1074,  727,
+- /*   350 */   740,  734,  735,  777,  778,  784,  788,  803,  694,  845,
+- /*   360 */   742,  796,  833,  837,  889,  860,  886, 1036,  806,  958,
+- /*   370 */  1446, 1448, 1430, 1311, 1441, 1378, 1444, 1438, 1439, 1343,
+- /*   380 */  1334, 1356, 1345, 1452, 1348, 1458, 1474, 1353, 1346, 1425,
+- /*   390 */  1426, 1427, 1428, 1371, 1387, 1450, 1363, 1486, 1484, 1468,
+- /*   400 */  1384, 1352, 1431, 1467, 1432, 1420, 1454, 1374, 1390, 1476,
+- /*   410 */  1481, 1483, 1391, 1399, 1485, 1440, 1487, 1488, 1482, 1489,
+- /*   420 */  1442, 1490, 1491, 1449, 1475, 1493, 1494, 1496, 1495, 1497,
+- /*   430 */  1492, 1498, 1500, 1502, 1501, 1404, 1504, 1505, 1433, 1499,
+- /*   440 */  1508, 1407, 1506, 1503, 1509, 1507, 1511, 1513, 1515, 1506,
+- /*   450 */  1516, 1517, 1518, 1519, 1521, 1534, 1524, 1525, 1526, 1527,
+- /*   460 */  1529, 1530, 1532, 1522, 1436, 1434, 1435, 1437, 1443, 1535,
+- /*   470 */  1540, 1559,
++ /*     0 */  1709, 1520, 1858, 1324, 1324,  277, 1374, 1469, 1602, 1712,
++ /*    10 */  1712, 1712,  273,    0,    0,  113, 1016, 1712, 1712, 1712,
++ /*    20 */  1712, 1712, 1712, 1712, 1712, 1712, 1712,   11,   11,  236,
++ /*    30 */   184,  277,  277,  277,  277,  277,  277,   93,  177,  270,
++ /*    40 */   363,  456,  549,  642,  735,  828,  848,  996, 1144, 1016,
++ /*    50 */  1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016,
++ /*    60 */  1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277,
++ /*    70 */  1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*    80 */  1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*    90 */  1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*   100 */  1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712,
++ /*   110 */  1712, 1712, 1712, 1712, 1712, 1712, 1712,  143,  162,  162,
++ /*   120 */   162,  162,  162,  204,  151,  416,  531,  648,  700,  531,
++ /*   130 */   486,  486,  531,  353,  353,  353,  353,  409,  279,   53,
++ /*   140 */  2009, 2009,  331,  331,  331,  329,  366,  329,  329,  597,
++ /*   150 */   597,  464,  474,  262,  681,  531,  531,  531,  531,  531,
++ /*   160 */   531,  531,  531,  531,  531,  531,  531,  531,  531,  531,
++ /*   170 */   531,  531,  531,  531,  531,  531,  531,  173,  485,  984,
++ /*   180 */   984,  576,  485,   19, 1022, 2009, 2009, 2009,  387,  250,
++ /*   190 */   250,  525,  502,  278,  552,  227,  480,  566,  531,  531,
++ /*   200 */   531,  531,  531,  531,  531,  531,  531,  531,  639,  531,
++ /*   210 */   531,  531,  531,  531,  531,  531,  531,  531,  531,  531,
++ /*   220 */   531,    2,    2,    2,  531,  531,  531,  531,  782,  531,
++ /*   230 */   531,  531,  744,  531,  531,  783,  531,  531,  531,  531,
++ /*   240 */   531,  531,  531,  531,  419,  682,  327,  370,  370,  370,
++ /*   250 */   370, 1029,  327,  327, 1024,  897,  856,  947, 1109,  706,
++ /*   260 */   706, 1143, 1109, 1109, 1143,  842,  945, 1118, 1136, 1136,
++ /*   270 */  1136,  706,  676,  400, 1047,  694, 1339, 1270, 1270, 1366,
++ /*   280 */  1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401,
++ /*   290 */  1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270,
++ /*   300 */  1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414,
++ /*   310 */  1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411,
++ /*   320 */  1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396,
++ /*   330 */  1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372,
++ /*   340 */  1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549,
++ /*   350 */  1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009,
++ /*   360 */  2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
++ /*   370 */   570,  345,  686,  748,   50,  740, 1064, 1107,  469,  537,
++ /*   380 */  1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127,
++ /*   390 */  1069, 1196, 1157, 1147, 1226, 1228, 1245,  775,  868, 1246,
++ /*   400 */  1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601,
++ /*   410 */  1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614,
++ /*   420 */  1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597,
++ /*   430 */  1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510,
++ /*   440 */  1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652,
++ /*   450 */  1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658,
++ /*   460 */  1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669,
++ /*   470 */  1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610,
++ /*   480 */  1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646,
++ /*   490 */  1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728,
++ /*   500 */  1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744,
++ /*   510 */  1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751,
++ /*   520 */  1772,
+ };
+-#define YY_REDUCE_COUNT (341)
+-#define YY_REDUCE_MIN   (-211)
+-#define YY_REDUCE_MAX   (1301)
++#define YY_REDUCE_COUNT (369)
++#define YY_REDUCE_MIN   (-237)
++#define YY_REDUCE_MAX   (1424)
+ static const short yy_reduce_ofst[] = {
+- /*     0 */  -143,  789,  753, 1059, -137, -146, -144, -141, -136,  687,
+- /*    10 */  -107,  101, -203,  -52,  830,  870,  890,  167,  953,  218,
+- /*    20 */   220,  413,  646,  897,   73,  281,  283,  332,  496,  601,
+- /*    30 */   650, -211, -211, -211, -211, -211, -211, -211, -211, -211,
+- /*    40 */  -211, -211, -211, -211, -211, -211, -211, -211, -211, -211,
+- /*    50 */  -211, -211, -211, -211, -211, -211, -211, -211, -211, -211,
+- /*    60 */  -211, -211, -211,  374,  377,  537,  969,  983, 1006, 1008,
+- /*    70 */  1015, 1055, 1067, 1069, 1071, 1084, 1096, 1100, 1104, 1111,
+- /*    80 */  1113, 1116, 1119, 1123, 1127, 1130, 1136, 1143, 1146, 1150,
+- /*    90 */  1153, 1155, 1159, 1161, 1163, 1166, 1170, 1189, 1193, 1195,
+- /*   100 */  1197, 1199, 1201, 1203, 1205, 1207, 1212, 1230, 1232, -211,
+- /*   110 */  -211, -211, -211, -211, -211, -211, -211, -211,  -30,  427,
+- /*   120 */  -171, -145, -134,   22,  279,  287,  279,  287,   99, -211,
+- /*   130 */  -211, -211, -211, -211, -165, -165, -165,  123,  135,  175,
+- /*   140 */  -150,  396,  337,  291,  291, -147,  185,  391,  446,  444,
+- /*   150 */   452,  500,  501,  502,   27, -152,  295,  438,  490,  503,
+- /*   160 */   495,  506,  -73,  447,  451,  536,  570,  551,  540,  579,
+- /*   170 */    30,  508,  535,   81,   14,   61,  115,  168,  142,  222,
+- /*   180 */   275,  284,  397,  599,  607,  647,  654,  660,  709,  658,
+- /*   190 */   714,  750,  754,  772,  787,  801,  817,  818,  850,  863,
+- /*   200 */   867,  871,  466,  748,  799,  881,  888,  898,  913,  824,
+- /*   210 */   930,  933,  934,  873,  942,  945,  849,  946,  222,  954,
+- /*   220 */   971,  972,  976,  979,  980,  900,  874,  927,  950,  961,
+- /*   230 */   962,  963,  824,  927,  927,  939,  970, 1018,  981,  988,
+- /*   240 */   993,  936,  982,  937, 1009, 1000, 1031, 1011, 1014, 1040,
+- /*   250 */  1003,  991,  990, 1026, 1072,  985, 1076, 1079,  997, 1005,
+- /*   260 */  1091, 1037, 1082, 1060, 1083, 1087, 1088, 1098, 1124, 1141,
+- /*   270 */  1106, 1092, 1122, 1135, 1128, 1147, 1173, 1110, 1105, 1187,
+- /*   280 */  1192, 1176, 1202, 1198, 1206, 1200, 1182, 1213, 1214, 1215,
+- /*   290 */  1209, 1216, 1218, 1219, 1220, 1224, 1222, 1223, 1221, 1171,
+- /*   300 */  1177, 1233, 1196, 1194, 1204, 1210, 1211, 1225, 1226, 1228,
+- /*   310 */  1253, 1190, 1256, 1191, 1227, 1229, 1234, 1236, 1235, 1263,
+- /*   320 */  1268, 1278, 1279, 1289, 1291, 1295, 1185, 1237, 1238, 1282,
+- /*   330 */  1274, 1283, 1286, 1287, 1290, 1269, 1270, 1293, 1298, 1299,
+- /*   340 */  1300, 1301,
++ /*     0 */  -147,  171,  263,  -96,  358, -144, -149, -102,  124, -156,
++ /*    10 */   -98,  305,  401,  -57,  209, -237,  245,  -94,  -79,  189,
++ /*    20 */   375,  490,  493,  378,  303,  539,  542,  501,  503,  554,
++ /*    30 */   415,  526,  546,  557,  587,  593,  595, -234, -234, -234,
++ /*    40 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    50 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    60 */  -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
++ /*    70 */  -234,  -50,  335,  470,  633,  656,  658,  660,  675,  685,
++ /*    80 */   703,  727,  747,  750,  752,  754,  770,  788,  790,  793,
++ /*    90 */   795,  797,  800,  802,  804,  806,  813,  820,  829,  833,
++ /*   100 */   836,  838,  843,  845,  847,  849,  873,  891,  893,  916,
++ /*   110 */   918,  921,  936,  941,  944,  956,  961, -234, -234, -234,
++ /*   120 */  -234, -234, -234, -234, -234, -234,  463,  607, -176,   14,
++ /*   130 */  -139,   87, -137,  818,  925,  818,  925,  898, -234, -234,
++ /*   140 */  -234, -234, -166, -166, -166, -130, -131,  -82,  -54, -180,
++ /*   150 */   364,   41,  513,  509,  509,  117,  500,  789,  796,  646,
++ /*   160 */   192,  291,  644,  798,  120,  807,  543,  911,  920,  652,
++ /*   170 */   924,  922,  232,  698,  801,  971,   39,  220,  731,  442,
++ /*   180 */   902, -199,  979,  -43,  421,  896,  942,  605, -184, -126,
++ /*   190 */   155,  172,  281,  304,  377,  538,  650,  690,  699,  723,
++ /*   200 */   803,  839,  853,  919,  991, 1018, 1067, 1092,  951, 1111,
++ /*   210 */  1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124,
++ /*   220 */  1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135,
++ /*   230 */  1137, 1152, 1077, 1153, 1155, 1114, 1156,  304, 1158, 1172,
++ /*   240 */  1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139,
++ /*   250 */  1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138,
++ /*   260 */  1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200,
++ /*   270 */  1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149,
++ /*   280 */  1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222,
++ /*   290 */  1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269,
++ /*   300 */  1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293,
++ /*   310 */  1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296,
++ /*   320 */  1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276,
++ /*   330 */  1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322,
++ /*   340 */  1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400,
++ /*   350 */  1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412,
++ /*   360 */  1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415,
+ };
+ static const YYACTIONTYPE yy_default[] = {
+- /*     0 */  1297, 1349, 1221, 1014, 1119, 1221, 1221, 1221, 1221, 1014,
+- /*    10 */  1145, 1145, 1272, 1045, 1014, 1014, 1014, 1014, 1014, 1220,
+- /*    20 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*    30 */  1014, 1151, 1014, 1014, 1014, 1014, 1222, 1223, 1014, 1014,
+- /*    40 */  1014, 1271, 1273, 1161, 1160, 1159, 1158, 1254, 1132, 1156,
+- /*    50 */  1149, 1153, 1216, 1217, 1215, 1219, 1222, 1223, 1014, 1152,
+- /*    60 */  1186, 1200, 1185, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*    70 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*    80 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*    90 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   100 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1194,
+- /*   110 */  1199, 1206, 1198, 1195, 1188, 1187, 1189, 1190, 1014, 1035,
+- /*   120 */  1084, 1014, 1014, 1014, 1289, 1288, 1014, 1014, 1045, 1191,
+- /*   130 */  1192, 1203, 1202, 1201, 1279, 1305, 1304, 1014, 1014, 1014,
+- /*   140 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   150 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   160 */  1014, 1014, 1014, 1014, 1014, 1014, 1045, 1297, 1041, 1041,
+- /*   170 */  1014, 1284, 1119, 1110, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   180 */  1014, 1014, 1014, 1014, 1014, 1276, 1274, 1014, 1236, 1014,
+- /*   190 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   200 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   210 */  1014, 1014, 1014, 1115, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   220 */  1014, 1014, 1014, 1014, 1299, 1014, 1249, 1098, 1115, 1115,
+- /*   230 */  1115, 1115, 1117, 1099, 1097, 1109, 1045, 1021, 1155, 1134,
+- /*   240 */  1134, 1338, 1155, 1338, 1059, 1319, 1056, 1145, 1145, 1145,
+- /*   250 */  1134, 1218, 1116, 1109, 1014, 1341, 1124, 1124, 1340, 1340,
+- /*   260 */  1124, 1166, 1087, 1155, 1093, 1093, 1093, 1093, 1124, 1032,
+- /*   270 */  1155, 1166, 1087, 1087, 1155, 1124, 1032, 1253, 1335, 1124,
+- /*   280 */  1032, 1229, 1124, 1032, 1124, 1032, 1229, 1085, 1085, 1085,
+- /*   290 */  1074, 1229, 1085, 1059, 1085, 1074, 1085, 1085, 1229, 1233,
+- /*   300 */  1233, 1229, 1138, 1133, 1138, 1133, 1138, 1133, 1138, 1133,
+- /*   310 */  1124, 1224, 1124, 1014, 1150, 1139, 1148, 1146, 1155, 1038,
+- /*   320 */  1077, 1302, 1302, 1298, 1298, 1298, 1346, 1346, 1284, 1314,
+- /*   330 */  1045, 1045, 1045, 1045, 1314, 1061, 1061, 1045, 1045, 1045,
+- /*   340 */  1045, 1314, 1014, 1014, 1014, 1014, 1014, 1014, 1309, 1014,
+- /*   350 */  1238, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   360 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1171,
+- /*   370 */  1014, 1017, 1281, 1014, 1014, 1280, 1014, 1014, 1014, 1014,
+- /*   380 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   390 */  1014, 1014, 1014, 1014, 1014, 1014, 1337, 1014, 1014, 1014,
+- /*   400 */  1014, 1014, 1014, 1252, 1251, 1014, 1014, 1126, 1014, 1014,
+- /*   410 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   420 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   430 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   440 */  1014, 1014, 1147, 1014, 1140, 1014, 1014, 1014, 1014, 1328,
+- /*   450 */  1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014,
+- /*   460 */  1014, 1014, 1014, 1323, 1101, 1173, 1014, 1172, 1176, 1014,
+- /*   470 */  1026, 1014,
++ /*     0 */  1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340,
++ /*    10 */  1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123,
++ /*    20 */  1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123,
++ /*    30 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123,
++ /*    40 */  1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390,
++ /*    50 */  1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267,
++ /*    60 */  1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320,
++ /*    70 */  1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*    80 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*    90 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   100 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   110 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325,
++ /*   120 */  1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123,
++ /*   130 */  1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312,
++ /*   140 */  1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123,
++ /*   150 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   160 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   170 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300,
++ /*   180 */  1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123,
++ /*   190 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   200 */  1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123,
++ /*   210 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   220 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   230 */  1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   240 */  1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225,
++ /*   250 */  1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248,
++ /*   260 */  1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259,
++ /*   270 */  1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483,
++ /*   280 */  1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202,
++ /*   290 */  1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234,
++ /*   300 */  1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141,
++ /*   310 */  1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183,
++ /*   320 */  1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247,
++ /*   330 */  1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253,
++ /*   340 */  1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445,
++ /*   350 */  1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154,
++ /*   360 */  1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457,
++ /*   370 */  1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238,
++ /*   380 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   390 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   400 */  1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123,
++ /*   410 */  1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123,
++ /*   420 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   430 */  1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123,
++ /*   440 */  1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123,
++ /*   450 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   460 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   470 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   480 */  1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123,
++ /*   490 */  1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123,
++ /*   500 */  1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
++ /*   510 */  1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135,
++ /*   520 */  1123,
+ };
+ /********** End of lemon-generated parsing tables *****************************/
+ 
+@@ -140664,6 +147804,7 @@
+     0,  /*     ESCAPE => nothing */
+     0,  /*         ID => nothing */
+    59,  /*   COLUMNKW => ID */
++   59,  /*         DO => ID */
+    59,  /*        FOR => ID */
+    59,  /*     IGNORE => ID */
+    59,  /*  INITIALLY => ID */
+@@ -140678,11 +147819,18 @@
+    59,  /*    REPLACE => ID */
+    59,  /*   RESTRICT => ID */
+    59,  /*        ROW => ID */
++   59,  /*       ROWS => ID */
+    59,  /*    TRIGGER => ID */
+    59,  /*     VACUUM => ID */
+    59,  /*       VIEW => ID */
+    59,  /*    VIRTUAL => ID */
+    59,  /*       WITH => ID */
++   59,  /*    CURRENT => ID */
++   59,  /*  FOLLOWING => ID */
++   59,  /*  PARTITION => ID */
++   59,  /*  PRECEDING => ID */
++   59,  /*      RANGE => ID */
++   59,  /*  UNBOUNDED => ID */
+    59,  /*    REINDEX => ID */
+    59,  /*     RENAME => ID */
+    59,  /*   CTIME_KW => ID */
+@@ -140725,6 +147873,7 @@
+   int yyerrcnt;                 /* Shifts left before out of the error */
+ #endif
+   sqlite3ParserARG_SDECL                /* A place to hold %extra_argument */
++  sqlite3ParserCTX_SDECL                /* A place to hold %extra_context */
+ #if YYSTACKDEPTH<=0
+   int yystksz;                  /* Current side of the stack */
+   yyStackEntry *yystack;        /* The parser's stack */
+@@ -140833,197 +147982,222 @@
+   /*   58 */ "ESCAPE",
+   /*   59 */ "ID",
+   /*   60 */ "COLUMNKW",
+-  /*   61 */ "FOR",
+-  /*   62 */ "IGNORE",
+-  /*   63 */ "INITIALLY",
+-  /*   64 */ "INSTEAD",
+-  /*   65 */ "NO",
+-  /*   66 */ "KEY",
+-  /*   67 */ "OF",
+-  /*   68 */ "OFFSET",
+-  /*   69 */ "PRAGMA",
+-  /*   70 */ "RAISE",
+-  /*   71 */ "RECURSIVE",
+-  /*   72 */ "REPLACE",
+-  /*   73 */ "RESTRICT",
+-  /*   74 */ "ROW",
+-  /*   75 */ "TRIGGER",
+-  /*   76 */ "VACUUM",
+-  /*   77 */ "VIEW",
+-  /*   78 */ "VIRTUAL",
+-  /*   79 */ "WITH",
+-  /*   80 */ "REINDEX",
+-  /*   81 */ "RENAME",
+-  /*   82 */ "CTIME_KW",
+-  /*   83 */ "ANY",
+-  /*   84 */ "BITAND",
+-  /*   85 */ "BITOR",
+-  /*   86 */ "LSHIFT",
+-  /*   87 */ "RSHIFT",
+-  /*   88 */ "PLUS",
+-  /*   89 */ "MINUS",
+-  /*   90 */ "STAR",
+-  /*   91 */ "SLASH",
+-  /*   92 */ "REM",
+-  /*   93 */ "CONCAT",
+-  /*   94 */ "COLLATE",
+-  /*   95 */ "BITNOT",
+-  /*   96 */ "INDEXED",
+-  /*   97 */ "STRING",
+-  /*   98 */ "JOIN_KW",
+-  /*   99 */ "CONSTRAINT",
+-  /*  100 */ "DEFAULT",
+-  /*  101 */ "NULL",
+-  /*  102 */ "PRIMARY",
+-  /*  103 */ "UNIQUE",
+-  /*  104 */ "CHECK",
+-  /*  105 */ "REFERENCES",
+-  /*  106 */ "AUTOINCR",
+-  /*  107 */ "ON",
+-  /*  108 */ "INSERT",
+-  /*  109 */ "DELETE",
+-  /*  110 */ "UPDATE",
+-  /*  111 */ "SET",
+-  /*  112 */ "DEFERRABLE",
+-  /*  113 */ "FOREIGN",
+-  /*  114 */ "DROP",
+-  /*  115 */ "UNION",
+-  /*  116 */ "ALL",
+-  /*  117 */ "EXCEPT",
+-  /*  118 */ "INTERSECT",
+-  /*  119 */ "SELECT",
+-  /*  120 */ "VALUES",
+-  /*  121 */ "DISTINCT",
+-  /*  122 */ "DOT",
+-  /*  123 */ "FROM",
+-  /*  124 */ "JOIN",
+-  /*  125 */ "USING",
+-  /*  126 */ "ORDER",
+-  /*  127 */ "GROUP",
+-  /*  128 */ "HAVING",
+-  /*  129 */ "LIMIT",
+-  /*  130 */ "WHERE",
+-  /*  131 */ "INTO",
+-  /*  132 */ "FLOAT",
+-  /*  133 */ "BLOB",
+-  /*  134 */ "INTEGER",
+-  /*  135 */ "VARIABLE",
+-  /*  136 */ "CASE",
+-  /*  137 */ "WHEN",
+-  /*  138 */ "THEN",
+-  /*  139 */ "ELSE",
+-  /*  140 */ "INDEX",
+-  /*  141 */ "ALTER",
+-  /*  142 */ "ADD",
+-  /*  143 */ "error",
+-  /*  144 */ "input",
+-  /*  145 */ "cmdlist",
+-  /*  146 */ "ecmd",
+-  /*  147 */ "explain",
+-  /*  148 */ "cmdx",
+-  /*  149 */ "cmd",
+-  /*  150 */ "transtype",
+-  /*  151 */ "trans_opt",
+-  /*  152 */ "nm",
+-  /*  153 */ "savepoint_opt",
+-  /*  154 */ "create_table",
+-  /*  155 */ "create_table_args",
+-  /*  156 */ "createkw",
+-  /*  157 */ "temp",
+-  /*  158 */ "ifnotexists",
+-  /*  159 */ "dbnm",
+-  /*  160 */ "columnlist",
+-  /*  161 */ "conslist_opt",
+-  /*  162 */ "table_options",
+-  /*  163 */ "select",
+-  /*  164 */ "columnname",
+-  /*  165 */ "carglist",
+-  /*  166 */ "typetoken",
+-  /*  167 */ "typename",
+-  /*  168 */ "signed",
+-  /*  169 */ "plus_num",
+-  /*  170 */ "minus_num",
+-  /*  171 */ "scanpt",
+-  /*  172 */ "ccons",
+-  /*  173 */ "term",
+-  /*  174 */ "expr",
+-  /*  175 */ "onconf",
+-  /*  176 */ "sortorder",
+-  /*  177 */ "autoinc",
+-  /*  178 */ "eidlist_opt",
+-  /*  179 */ "refargs",
+-  /*  180 */ "defer_subclause",
+-  /*  181 */ "refarg",
+-  /*  182 */ "refact",
+-  /*  183 */ "init_deferred_pred_opt",
+-  /*  184 */ "conslist",
+-  /*  185 */ "tconscomma",
+-  /*  186 */ "tcons",
+-  /*  187 */ "sortlist",
+-  /*  188 */ "eidlist",
+-  /*  189 */ "defer_subclause_opt",
+-  /*  190 */ "orconf",
+-  /*  191 */ "resolvetype",
+-  /*  192 */ "raisetype",
+-  /*  193 */ "ifexists",
+-  /*  194 */ "fullname",
+-  /*  195 */ "selectnowith",
+-  /*  196 */ "oneselect",
+-  /*  197 */ "wqlist",
+-  /*  198 */ "multiselect_op",
+-  /*  199 */ "distinct",
+-  /*  200 */ "selcollist",
+-  /*  201 */ "from",
+-  /*  202 */ "where_opt",
+-  /*  203 */ "groupby_opt",
+-  /*  204 */ "having_opt",
+-  /*  205 */ "orderby_opt",
+-  /*  206 */ "limit_opt",
+-  /*  207 */ "values",
+-  /*  208 */ "nexprlist",
+-  /*  209 */ "exprlist",
+-  /*  210 */ "sclp",
+-  /*  211 */ "as",
+-  /*  212 */ "seltablist",
+-  /*  213 */ "stl_prefix",
+-  /*  214 */ "joinop",
+-  /*  215 */ "indexed_opt",
+-  /*  216 */ "on_opt",
+-  /*  217 */ "using_opt",
+-  /*  218 */ "idlist",
+-  /*  219 */ "with",
+-  /*  220 */ "setlist",
+-  /*  221 */ "insert_cmd",
+-  /*  222 */ "idlist_opt",
+-  /*  223 */ "likeop",
+-  /*  224 */ "between_op",
+-  /*  225 */ "in_op",
+-  /*  226 */ "paren_exprlist",
+-  /*  227 */ "case_operand",
+-  /*  228 */ "case_exprlist",
+-  /*  229 */ "case_else",
+-  /*  230 */ "uniqueflag",
+-  /*  231 */ "collate",
+-  /*  232 */ "nmnum",
+-  /*  233 */ "trigger_decl",
+-  /*  234 */ "trigger_cmd_list",
+-  /*  235 */ "trigger_time",
+-  /*  236 */ "trigger_event",
+-  /*  237 */ "foreach_clause",
+-  /*  238 */ "when_clause",
+-  /*  239 */ "trigger_cmd",
+-  /*  240 */ "trnm",
+-  /*  241 */ "tridxby",
+-  /*  242 */ "database_kw_opt",
+-  /*  243 */ "key_opt",
+-  /*  244 */ "add_column_fullname",
+-  /*  245 */ "kwcolumn_opt",
+-  /*  246 */ "create_vtab",
+-  /*  247 */ "vtabarglist",
+-  /*  248 */ "vtabarg",
+-  /*  249 */ "vtabargtoken",
+-  /*  250 */ "lp",
+-  /*  251 */ "anylist",
++  /*   61 */ "DO",
++  /*   62 */ "FOR",
++  /*   63 */ "IGNORE",
++  /*   64 */ "INITIALLY",
++  /*   65 */ "INSTEAD",
++  /*   66 */ "NO",
++  /*   67 */ "KEY",
++  /*   68 */ "OF",
++  /*   69 */ "OFFSET",
++  /*   70 */ "PRAGMA",
++  /*   71 */ "RAISE",
++  /*   72 */ "RECURSIVE",
++  /*   73 */ "REPLACE",
++  /*   74 */ "RESTRICT",
++  /*   75 */ "ROW",
++  /*   76 */ "ROWS",
++  /*   77 */ "TRIGGER",
++  /*   78 */ "VACUUM",
++  /*   79 */ "VIEW",
++  /*   80 */ "VIRTUAL",
++  /*   81 */ "WITH",
++  /*   82 */ "CURRENT",
++  /*   83 */ "FOLLOWING",
++  /*   84 */ "PARTITION",
++  /*   85 */ "PRECEDING",
++  /*   86 */ "RANGE",
++  /*   87 */ "UNBOUNDED",
++  /*   88 */ "REINDEX",
++  /*   89 */ "RENAME",
++  /*   90 */ "CTIME_KW",
++  /*   91 */ "ANY",
++  /*   92 */ "BITAND",
++  /*   93 */ "BITOR",
++  /*   94 */ "LSHIFT",
++  /*   95 */ "RSHIFT",
++  /*   96 */ "PLUS",
++  /*   97 */ "MINUS",
++  /*   98 */ "STAR",
++  /*   99 */ "SLASH",
++  /*  100 */ "REM",
++  /*  101 */ "CONCAT",
++  /*  102 */ "COLLATE",
++  /*  103 */ "BITNOT",
++  /*  104 */ "ON",
++  /*  105 */ "INDEXED",
++  /*  106 */ "STRING",
++  /*  107 */ "JOIN_KW",
++  /*  108 */ "CONSTRAINT",
++  /*  109 */ "DEFAULT",
++  /*  110 */ "NULL",
++  /*  111 */ "PRIMARY",
++  /*  112 */ "UNIQUE",
++  /*  113 */ "CHECK",
++  /*  114 */ "REFERENCES",
++  /*  115 */ "AUTOINCR",
++  /*  116 */ "INSERT",
++  /*  117 */ "DELETE",
++  /*  118 */ "UPDATE",
++  /*  119 */ "SET",
++  /*  120 */ "DEFERRABLE",
++  /*  121 */ "FOREIGN",
++  /*  122 */ "DROP",
++  /*  123 */ "UNION",
++  /*  124 */ "ALL",
++  /*  125 */ "EXCEPT",
++  /*  126 */ "INTERSECT",
++  /*  127 */ "SELECT",
++  /*  128 */ "VALUES",
++  /*  129 */ "DISTINCT",
++  /*  130 */ "DOT",
++  /*  131 */ "FROM",
++  /*  132 */ "JOIN",
++  /*  133 */ "USING",
++  /*  134 */ "ORDER",
++  /*  135 */ "GROUP",
++  /*  136 */ "HAVING",
++  /*  137 */ "LIMIT",
++  /*  138 */ "WHERE",
++  /*  139 */ "INTO",
++  /*  140 */ "NOTHING",
++  /*  141 */ "FLOAT",
++  /*  142 */ "BLOB",
++  /*  143 */ "INTEGER",
++  /*  144 */ "VARIABLE",
++  /*  145 */ "CASE",
++  /*  146 */ "WHEN",
++  /*  147 */ "THEN",
++  /*  148 */ "ELSE",
++  /*  149 */ "INDEX",
++  /*  150 */ "ALTER",
++  /*  151 */ "ADD",
++  /*  152 */ "WINDOW",
++  /*  153 */ "OVER",
++  /*  154 */ "FILTER",
++  /*  155 */ "input",
++  /*  156 */ "cmdlist",
++  /*  157 */ "ecmd",
++  /*  158 */ "cmdx",
++  /*  159 */ "explain",
++  /*  160 */ "cmd",
++  /*  161 */ "transtype",
++  /*  162 */ "trans_opt",
++  /*  163 */ "nm",
++  /*  164 */ "savepoint_opt",
++  /*  165 */ "create_table",
++  /*  166 */ "create_table_args",
++  /*  167 */ "createkw",
++  /*  168 */ "temp",
++  /*  169 */ "ifnotexists",
++  /*  170 */ "dbnm",
++  /*  171 */ "columnlist",
++  /*  172 */ "conslist_opt",
++  /*  173 */ "table_options",
++  /*  174 */ "select",
++  /*  175 */ "columnname",
++  /*  176 */ "carglist",
++  /*  177 */ "typetoken",
++  /*  178 */ "typename",
++  /*  179 */ "signed",
++  /*  180 */ "plus_num",
++  /*  181 */ "minus_num",
++  /*  182 */ "scanpt",
++  /*  183 */ "ccons",
++  /*  184 */ "term",
++  /*  185 */ "expr",
++  /*  186 */ "onconf",
++  /*  187 */ "sortorder",
++  /*  188 */ "autoinc",
++  /*  189 */ "eidlist_opt",
++  /*  190 */ "refargs",
++  /*  191 */ "defer_subclause",
++  /*  192 */ "refarg",
++  /*  193 */ "refact",
++  /*  194 */ "init_deferred_pred_opt",
++  /*  195 */ "conslist",
++  /*  196 */ "tconscomma",
++  /*  197 */ "tcons",
++  /*  198 */ "sortlist",
++  /*  199 */ "eidlist",
++  /*  200 */ "defer_subclause_opt",
++  /*  201 */ "orconf",
++  /*  202 */ "resolvetype",
++  /*  203 */ "raisetype",
++  /*  204 */ "ifexists",
++  /*  205 */ "fullname",
++  /*  206 */ "selectnowith",
++  /*  207 */ "oneselect",
++  /*  208 */ "wqlist",
++  /*  209 */ "multiselect_op",
++  /*  210 */ "distinct",
++  /*  211 */ "selcollist",
++  /*  212 */ "from",
++  /*  213 */ "where_opt",
++  /*  214 */ "groupby_opt",
++  /*  215 */ "having_opt",
++  /*  216 */ "orderby_opt",
++  /*  217 */ "limit_opt",
++  /*  218 */ "window_clause",
++  /*  219 */ "values",
++  /*  220 */ "nexprlist",
++  /*  221 */ "sclp",
++  /*  222 */ "as",
++  /*  223 */ "seltablist",
++  /*  224 */ "stl_prefix",
++  /*  225 */ "joinop",
++  /*  226 */ "indexed_opt",
++  /*  227 */ "on_opt",
++  /*  228 */ "using_opt",
++  /*  229 */ "exprlist",
++  /*  230 */ "xfullname",
++  /*  231 */ "idlist",
++  /*  232 */ "with",
++  /*  233 */ "setlist",
++  /*  234 */ "insert_cmd",
++  /*  235 */ "idlist_opt",
++  /*  236 */ "upsert",
++  /*  237 */ "over_clause",
++  /*  238 */ "likeop",
++  /*  239 */ "between_op",
++  /*  240 */ "in_op",
++  /*  241 */ "paren_exprlist",
++  /*  242 */ "case_operand",
++  /*  243 */ "case_exprlist",
++  /*  244 */ "case_else",
++  /*  245 */ "uniqueflag",
++  /*  246 */ "collate",
++  /*  247 */ "nmnum",
++  /*  248 */ "trigger_decl",
++  /*  249 */ "trigger_cmd_list",
++  /*  250 */ "trigger_time",
++  /*  251 */ "trigger_event",
++  /*  252 */ "foreach_clause",
++  /*  253 */ "when_clause",
++  /*  254 */ "trigger_cmd",
++  /*  255 */ "trnm",
++  /*  256 */ "tridxby",
++  /*  257 */ "database_kw_opt",
++  /*  258 */ "key_opt",
++  /*  259 */ "add_column_fullname",
++  /*  260 */ "kwcolumn_opt",
++  /*  261 */ "create_vtab",
++  /*  262 */ "vtabarglist",
++  /*  263 */ "vtabarg",
++  /*  264 */ "vtabargtoken",
++  /*  265 */ "lp",
++  /*  266 */ "anylist",
++  /*  267 */ "windowdefn_list",
++  /*  268 */ "windowdefn",
++  /*  269 */ "window",
++  /*  270 */ "frame_opt",
++  /*  271 */ "part_opt",
++  /*  272 */ "filter_opt",
++  /*  273 */ "range_or_rows",
++  /*  274 */ "frame_bound",
++  /*  275 */ "frame_bound_s",
++  /*  276 */ "frame_bound_e",
+ };
+ #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
+ 
+@@ -141119,251 +148293,285 @@
+  /*  85 */ "multiselect_op ::= UNION ALL",
+  /*  86 */ "multiselect_op ::= EXCEPT|INTERSECT",
+  /*  87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+- /*  88 */ "values ::= VALUES LP nexprlist RP",
+- /*  89 */ "values ::= values COMMA LP exprlist RP",
+- /*  90 */ "distinct ::= DISTINCT",
+- /*  91 */ "distinct ::= ALL",
+- /*  92 */ "distinct ::=",
+- /*  93 */ "sclp ::=",
+- /*  94 */ "selcollist ::= sclp scanpt expr scanpt as",
+- /*  95 */ "selcollist ::= sclp scanpt STAR",
+- /*  96 */ "selcollist ::= sclp scanpt nm DOT STAR",
+- /*  97 */ "as ::= AS nm",
+- /*  98 */ "as ::=",
+- /*  99 */ "from ::=",
+- /* 100 */ "from ::= FROM seltablist",
+- /* 101 */ "stl_prefix ::= seltablist joinop",
+- /* 102 */ "stl_prefix ::=",
+- /* 103 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+- /* 104 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+- /* 105 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+- /* 106 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+- /* 107 */ "dbnm ::=",
+- /* 108 */ "dbnm ::= DOT nm",
+- /* 109 */ "fullname ::= nm",
+- /* 110 */ "fullname ::= nm DOT nm",
+- /* 111 */ "joinop ::= COMMA|JOIN",
+- /* 112 */ "joinop ::= JOIN_KW JOIN",
+- /* 113 */ "joinop ::= JOIN_KW nm JOIN",
+- /* 114 */ "joinop ::= JOIN_KW nm nm JOIN",
+- /* 115 */ "on_opt ::= ON expr",
+- /* 116 */ "on_opt ::=",
+- /* 117 */ "indexed_opt ::=",
+- /* 118 */ "indexed_opt ::= INDEXED BY nm",
+- /* 119 */ "indexed_opt ::= NOT INDEXED",
+- /* 120 */ "using_opt ::= USING LP idlist RP",
+- /* 121 */ "using_opt ::=",
+- /* 122 */ "orderby_opt ::=",
+- /* 123 */ "orderby_opt ::= ORDER BY sortlist",
+- /* 124 */ "sortlist ::= sortlist COMMA expr sortorder",
+- /* 125 */ "sortlist ::= expr sortorder",
+- /* 126 */ "sortorder ::= ASC",
+- /* 127 */ "sortorder ::= DESC",
+- /* 128 */ "sortorder ::=",
+- /* 129 */ "groupby_opt ::=",
+- /* 130 */ "groupby_opt ::= GROUP BY nexprlist",
+- /* 131 */ "having_opt ::=",
+- /* 132 */ "having_opt ::= HAVING expr",
+- /* 133 */ "limit_opt ::=",
+- /* 134 */ "limit_opt ::= LIMIT expr",
+- /* 135 */ "limit_opt ::= LIMIT expr OFFSET expr",
+- /* 136 */ "limit_opt ::= LIMIT expr COMMA expr",
+- /* 137 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+- /* 138 */ "where_opt ::=",
+- /* 139 */ "where_opt ::= WHERE expr",
+- /* 140 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+- /* 141 */ "setlist ::= setlist COMMA nm EQ expr",
+- /* 142 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+- /* 143 */ "setlist ::= nm EQ expr",
+- /* 144 */ "setlist ::= LP idlist RP EQ expr",
+- /* 145 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+- /* 146 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+- /* 147 */ "insert_cmd ::= INSERT orconf",
+- /* 148 */ "insert_cmd ::= REPLACE",
+- /* 149 */ "idlist_opt ::=",
+- /* 150 */ "idlist_opt ::= LP idlist RP",
+- /* 151 */ "idlist ::= idlist COMMA nm",
+- /* 152 */ "idlist ::= nm",
+- /* 153 */ "expr ::= LP expr RP",
+- /* 154 */ "expr ::= ID|INDEXED",
+- /* 155 */ "expr ::= JOIN_KW",
+- /* 156 */ "expr ::= nm DOT nm",
+- /* 157 */ "expr ::= nm DOT nm DOT nm",
+- /* 158 */ "term ::= NULL|FLOAT|BLOB",
+- /* 159 */ "term ::= STRING",
+- /* 160 */ "term ::= INTEGER",
+- /* 161 */ "expr ::= VARIABLE",
+- /* 162 */ "expr ::= expr COLLATE ID|STRING",
+- /* 163 */ "expr ::= CAST LP expr AS typetoken RP",
+- /* 164 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+- /* 165 */ "expr ::= ID|INDEXED LP STAR RP",
+- /* 166 */ "term ::= CTIME_KW",
+- /* 167 */ "expr ::= LP nexprlist COMMA expr RP",
+- /* 168 */ "expr ::= expr AND expr",
+- /* 169 */ "expr ::= expr OR expr",
+- /* 170 */ "expr ::= expr LT|GT|GE|LE expr",
+- /* 171 */ "expr ::= expr EQ|NE expr",
+- /* 172 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+- /* 173 */ "expr ::= expr PLUS|MINUS expr",
+- /* 174 */ "expr ::= expr STAR|SLASH|REM expr",
+- /* 175 */ "expr ::= expr CONCAT expr",
+- /* 176 */ "likeop ::= NOT LIKE_KW|MATCH",
+- /* 177 */ "expr ::= expr likeop expr",
+- /* 178 */ "expr ::= expr likeop expr ESCAPE expr",
+- /* 179 */ "expr ::= expr ISNULL|NOTNULL",
+- /* 180 */ "expr ::= expr NOT NULL",
+- /* 181 */ "expr ::= expr IS expr",
+- /* 182 */ "expr ::= expr IS NOT expr",
+- /* 183 */ "expr ::= NOT expr",
+- /* 184 */ "expr ::= BITNOT expr",
+- /* 185 */ "expr ::= MINUS expr",
+- /* 186 */ "expr ::= PLUS expr",
+- /* 187 */ "between_op ::= BETWEEN",
+- /* 188 */ "between_op ::= NOT BETWEEN",
+- /* 189 */ "expr ::= expr between_op expr AND expr",
+- /* 190 */ "in_op ::= IN",
+- /* 191 */ "in_op ::= NOT IN",
+- /* 192 */ "expr ::= expr in_op LP exprlist RP",
+- /* 193 */ "expr ::= LP select RP",
+- /* 194 */ "expr ::= expr in_op LP select RP",
+- /* 195 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+- /* 196 */ "expr ::= EXISTS LP select RP",
+- /* 197 */ "expr ::= CASE case_operand case_exprlist case_else END",
+- /* 198 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+- /* 199 */ "case_exprlist ::= WHEN expr THEN expr",
+- /* 200 */ "case_else ::= ELSE expr",
+- /* 201 */ "case_else ::=",
+- /* 202 */ "case_operand ::= expr",
+- /* 203 */ "case_operand ::=",
+- /* 204 */ "exprlist ::=",
+- /* 205 */ "nexprlist ::= nexprlist COMMA expr",
+- /* 206 */ "nexprlist ::= expr",
+- /* 207 */ "paren_exprlist ::=",
+- /* 208 */ "paren_exprlist ::= LP exprlist RP",
+- /* 209 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+- /* 210 */ "uniqueflag ::= UNIQUE",
+- /* 211 */ "uniqueflag ::=",
+- /* 212 */ "eidlist_opt ::=",
+- /* 213 */ "eidlist_opt ::= LP eidlist RP",
+- /* 214 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+- /* 215 */ "eidlist ::= nm collate sortorder",
+- /* 216 */ "collate ::=",
+- /* 217 */ "collate ::= COLLATE ID|STRING",
+- /* 218 */ "cmd ::= DROP INDEX ifexists fullname",
+- /* 219 */ "cmd ::= VACUUM",
+- /* 220 */ "cmd ::= VACUUM nm",
+- /* 221 */ "cmd ::= PRAGMA nm dbnm",
+- /* 222 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+- /* 223 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+- /* 224 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+- /* 225 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+- /* 226 */ "plus_num ::= PLUS INTEGER|FLOAT",
+- /* 227 */ "minus_num ::= MINUS INTEGER|FLOAT",
+- /* 228 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+- /* 229 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+- /* 230 */ "trigger_time ::= BEFORE|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 scanpt",
+- /* 244 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt",
+- /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+- /* 246 */ "trigger_cmd ::= scanpt select scanpt",
+- /* 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 ::= 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 ::=",
+- /* 319 */ "foreach_clause ::= FOR EACH ROW",
+- /* 320 */ "trnm ::= nm",
+- /* 321 */ "tridxby ::=",
+- /* 322 */ "database_kw_opt ::= DATABASE",
+- /* 323 */ "database_kw_opt ::=",
+- /* 324 */ "kwcolumn_opt ::=",
+- /* 325 */ "kwcolumn_opt ::= COLUMNKW",
+- /* 326 */ "vtabarglist ::= vtabarg",
+- /* 327 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+- /* 328 */ "vtabarg ::= vtabarg vtabargtoken",
+- /* 329 */ "anylist ::=",
+- /* 330 */ "anylist ::= anylist LP anylist RP",
+- /* 331 */ "anylist ::= anylist ANY",
+- /* 332 */ "with ::=",
++ /*  88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
++ /*  89 */ "values ::= VALUES LP nexprlist RP",
++ /*  90 */ "values ::= values COMMA LP nexprlist RP",
++ /*  91 */ "distinct ::= DISTINCT",
++ /*  92 */ "distinct ::= ALL",
++ /*  93 */ "distinct ::=",
++ /*  94 */ "sclp ::=",
++ /*  95 */ "selcollist ::= sclp scanpt expr scanpt as",
++ /*  96 */ "selcollist ::= sclp scanpt STAR",
++ /*  97 */ "selcollist ::= sclp scanpt nm DOT STAR",
++ /*  98 */ "as ::= AS nm",
++ /*  99 */ "as ::=",
++ /* 100 */ "from ::=",
++ /* 101 */ "from ::= FROM seltablist",
++ /* 102 */ "stl_prefix ::= seltablist joinop",
++ /* 103 */ "stl_prefix ::=",
++ /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
++ /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
++ /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
++ /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
++ /* 108 */ "dbnm ::=",
++ /* 109 */ "dbnm ::= DOT nm",
++ /* 110 */ "fullname ::= nm",
++ /* 111 */ "fullname ::= nm DOT nm",
++ /* 112 */ "xfullname ::= nm",
++ /* 113 */ "xfullname ::= nm DOT nm",
++ /* 114 */ "xfullname ::= nm DOT nm AS nm",
++ /* 115 */ "xfullname ::= nm AS nm",
++ /* 116 */ "joinop ::= COMMA|JOIN",
++ /* 117 */ "joinop ::= JOIN_KW JOIN",
++ /* 118 */ "joinop ::= JOIN_KW nm JOIN",
++ /* 119 */ "joinop ::= JOIN_KW nm nm JOIN",
++ /* 120 */ "on_opt ::= ON expr",
++ /* 121 */ "on_opt ::=",
++ /* 122 */ "indexed_opt ::=",
++ /* 123 */ "indexed_opt ::= INDEXED BY nm",
++ /* 124 */ "indexed_opt ::= NOT INDEXED",
++ /* 125 */ "using_opt ::= USING LP idlist RP",
++ /* 126 */ "using_opt ::=",
++ /* 127 */ "orderby_opt ::=",
++ /* 128 */ "orderby_opt ::= ORDER BY sortlist",
++ /* 129 */ "sortlist ::= sortlist COMMA expr sortorder",
++ /* 130 */ "sortlist ::= expr sortorder",
++ /* 131 */ "sortorder ::= ASC",
++ /* 132 */ "sortorder ::= DESC",
++ /* 133 */ "sortorder ::=",
++ /* 134 */ "groupby_opt ::=",
++ /* 135 */ "groupby_opt ::= GROUP BY nexprlist",
++ /* 136 */ "having_opt ::=",
++ /* 137 */ "having_opt ::= HAVING expr",
++ /* 138 */ "limit_opt ::=",
++ /* 139 */ "limit_opt ::= LIMIT expr",
++ /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr",
++ /* 141 */ "limit_opt ::= LIMIT expr COMMA expr",
++ /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
++ /* 143 */ "where_opt ::=",
++ /* 144 */ "where_opt ::= WHERE expr",
++ /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
++ /* 146 */ "setlist ::= setlist COMMA nm EQ expr",
++ /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
++ /* 148 */ "setlist ::= nm EQ expr",
++ /* 149 */ "setlist ::= LP idlist RP EQ expr",
++ /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
++ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
++ /* 152 */ "upsert ::=",
++ /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
++ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
++ /* 155 */ "upsert ::= ON CONFLICT DO NOTHING",
++ /* 156 */ "insert_cmd ::= INSERT orconf",
++ /* 157 */ "insert_cmd ::= REPLACE",
++ /* 158 */ "idlist_opt ::=",
++ /* 159 */ "idlist_opt ::= LP idlist RP",
++ /* 160 */ "idlist ::= idlist COMMA nm",
++ /* 161 */ "idlist ::= nm",
++ /* 162 */ "expr ::= LP expr RP",
++ /* 163 */ "expr ::= ID|INDEXED",
++ /* 164 */ "expr ::= JOIN_KW",
++ /* 165 */ "expr ::= nm DOT nm",
++ /* 166 */ "expr ::= nm DOT nm DOT nm",
++ /* 167 */ "term ::= NULL|FLOAT|BLOB",
++ /* 168 */ "term ::= STRING",
++ /* 169 */ "term ::= INTEGER",
++ /* 170 */ "expr ::= VARIABLE",
++ /* 171 */ "expr ::= expr COLLATE ID|STRING",
++ /* 172 */ "expr ::= CAST LP expr AS typetoken RP",
++ /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
++ /* 174 */ "expr ::= ID|INDEXED LP STAR RP",
++ /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
++ /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
++ /* 177 */ "term ::= CTIME_KW",
++ /* 178 */ "expr ::= LP nexprlist COMMA expr RP",
++ /* 179 */ "expr ::= expr AND expr",
++ /* 180 */ "expr ::= expr OR expr",
++ /* 181 */ "expr ::= expr LT|GT|GE|LE expr",
++ /* 182 */ "expr ::= expr EQ|NE expr",
++ /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
++ /* 184 */ "expr ::= expr PLUS|MINUS expr",
++ /* 185 */ "expr ::= expr STAR|SLASH|REM expr",
++ /* 186 */ "expr ::= expr CONCAT expr",
++ /* 187 */ "likeop ::= NOT LIKE_KW|MATCH",
++ /* 188 */ "expr ::= expr likeop expr",
++ /* 189 */ "expr ::= expr likeop expr ESCAPE expr",
++ /* 190 */ "expr ::= expr ISNULL|NOTNULL",
++ /* 191 */ "expr ::= expr NOT NULL",
++ /* 192 */ "expr ::= expr IS expr",
++ /* 193 */ "expr ::= expr IS NOT expr",
++ /* 194 */ "expr ::= NOT expr",
++ /* 195 */ "expr ::= BITNOT expr",
++ /* 196 */ "expr ::= PLUS|MINUS expr",
++ /* 197 */ "between_op ::= BETWEEN",
++ /* 198 */ "between_op ::= NOT BETWEEN",
++ /* 199 */ "expr ::= expr between_op expr AND expr",
++ /* 200 */ "in_op ::= IN",
++ /* 201 */ "in_op ::= NOT IN",
++ /* 202 */ "expr ::= expr in_op LP exprlist RP",
++ /* 203 */ "expr ::= LP select RP",
++ /* 204 */ "expr ::= expr in_op LP select RP",
++ /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist",
++ /* 206 */ "expr ::= EXISTS LP select RP",
++ /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END",
++ /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
++ /* 209 */ "case_exprlist ::= WHEN expr THEN expr",
++ /* 210 */ "case_else ::= ELSE expr",
++ /* 211 */ "case_else ::=",
++ /* 212 */ "case_operand ::= expr",
++ /* 213 */ "case_operand ::=",
++ /* 214 */ "exprlist ::=",
++ /* 215 */ "nexprlist ::= nexprlist COMMA expr",
++ /* 216 */ "nexprlist ::= expr",
++ /* 217 */ "paren_exprlist ::=",
++ /* 218 */ "paren_exprlist ::= LP exprlist RP",
++ /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
++ /* 220 */ "uniqueflag ::= UNIQUE",
++ /* 221 */ "uniqueflag ::=",
++ /* 222 */ "eidlist_opt ::=",
++ /* 223 */ "eidlist_opt ::= LP eidlist RP",
++ /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder",
++ /* 225 */ "eidlist ::= nm collate sortorder",
++ /* 226 */ "collate ::=",
++ /* 227 */ "collate ::= COLLATE ID|STRING",
++ /* 228 */ "cmd ::= DROP INDEX ifexists fullname",
++ /* 229 */ "cmd ::= VACUUM",
++ /* 230 */ "cmd ::= VACUUM nm",
++ /* 231 */ "cmd ::= PRAGMA nm dbnm",
++ /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
++ /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
++ /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
++ /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
++ /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT",
++ /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT",
++ /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
++ /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
++ /* 240 */ "trigger_time ::= BEFORE|AFTER",
++ /* 241 */ "trigger_time ::= INSTEAD OF",
++ /* 242 */ "trigger_time ::=",
++ /* 243 */ "trigger_event ::= DELETE|INSERT",
++ /* 244 */ "trigger_event ::= UPDATE",
++ /* 245 */ "trigger_event ::= UPDATE OF idlist",
++ /* 246 */ "when_clause ::=",
++ /* 247 */ "when_clause ::= WHEN expr",
++ /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
++ /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI",
++ /* 250 */ "trnm ::= nm DOT nm",
++ /* 251 */ "tridxby ::= INDEXED BY nm",
++ /* 252 */ "tridxby ::= NOT INDEXED",
++ /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
++ /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
++ /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
++ /* 256 */ "trigger_cmd ::= scanpt select scanpt",
++ /* 257 */ "expr ::= RAISE LP IGNORE RP",
++ /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP",
++ /* 259 */ "raisetype ::= ROLLBACK",
++ /* 260 */ "raisetype ::= ABORT",
++ /* 261 */ "raisetype ::= FAIL",
++ /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname",
++ /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
++ /* 264 */ "cmd ::= DETACH database_kw_opt expr",
++ /* 265 */ "key_opt ::=",
++ /* 266 */ "key_opt ::= KEY expr",
++ /* 267 */ "cmd ::= REINDEX",
++ /* 268 */ "cmd ::= REINDEX nm dbnm",
++ /* 269 */ "cmd ::= ANALYZE",
++ /* 270 */ "cmd ::= ANALYZE nm dbnm",
++ /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
++ /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
++ /* 273 */ "add_column_fullname ::= fullname",
++ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
++ /* 275 */ "cmd ::= create_vtab",
++ /* 276 */ "cmd ::= create_vtab LP vtabarglist RP",
++ /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
++ /* 278 */ "vtabarg ::=",
++ /* 279 */ "vtabargtoken ::= ANY",
++ /* 280 */ "vtabargtoken ::= lp anylist RP",
++ /* 281 */ "lp ::= LP",
++ /* 282 */ "with ::= WITH wqlist",
++ /* 283 */ "with ::= WITH RECURSIVE wqlist",
++ /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP",
++ /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
++ /* 286 */ "windowdefn_list ::= windowdefn",
++ /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
++ /* 288 */ "windowdefn ::= nm AS window",
++ /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP",
++ /* 290 */ "part_opt ::= PARTITION BY nexprlist",
++ /* 291 */ "part_opt ::=",
++ /* 292 */ "frame_opt ::=",
++ /* 293 */ "frame_opt ::= range_or_rows frame_bound_s",
++ /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
++ /* 295 */ "range_or_rows ::= RANGE",
++ /* 296 */ "range_or_rows ::= ROWS",
++ /* 297 */ "frame_bound_s ::= frame_bound",
++ /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
++ /* 299 */ "frame_bound_e ::= frame_bound",
++ /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
++ /* 301 */ "frame_bound ::= expr PRECEDING",
++ /* 302 */ "frame_bound ::= CURRENT ROW",
++ /* 303 */ "frame_bound ::= expr FOLLOWING",
++ /* 304 */ "window_clause ::= WINDOW windowdefn_list",
++ /* 305 */ "over_clause ::= filter_opt OVER window",
++ /* 306 */ "over_clause ::= filter_opt OVER nm",
++ /* 307 */ "filter_opt ::=",
++ /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP",
++ /* 309 */ "input ::= cmdlist",
++ /* 310 */ "cmdlist ::= cmdlist ecmd",
++ /* 311 */ "cmdlist ::= ecmd",
++ /* 312 */ "ecmd ::= SEMI",
++ /* 313 */ "ecmd ::= cmdx SEMI",
++ /* 314 */ "ecmd ::= explain cmdx",
++ /* 315 */ "trans_opt ::=",
++ /* 316 */ "trans_opt ::= TRANSACTION",
++ /* 317 */ "trans_opt ::= TRANSACTION nm",
++ /* 318 */ "savepoint_opt ::= SAVEPOINT",
++ /* 319 */ "savepoint_opt ::=",
++ /* 320 */ "cmd ::= create_table create_table_args",
++ /* 321 */ "columnlist ::= columnlist COMMA columnname carglist",
++ /* 322 */ "columnlist ::= columnname carglist",
++ /* 323 */ "nm ::= ID|INDEXED",
++ /* 324 */ "nm ::= STRING",
++ /* 325 */ "nm ::= JOIN_KW",
++ /* 326 */ "typetoken ::= typename",
++ /* 327 */ "typename ::= ID|STRING",
++ /* 328 */ "signed ::= plus_num",
++ /* 329 */ "signed ::= minus_num",
++ /* 330 */ "carglist ::= carglist ccons",
++ /* 331 */ "carglist ::=",
++ /* 332 */ "ccons ::= NULL onconf",
++ /* 333 */ "conslist_opt ::= COMMA conslist",
++ /* 334 */ "conslist ::= conslist tconscomma tcons",
++ /* 335 */ "conslist ::= tcons",
++ /* 336 */ "tconscomma ::=",
++ /* 337 */ "defer_subclause_opt ::= defer_subclause",
++ /* 338 */ "resolvetype ::= raisetype",
++ /* 339 */ "selectnowith ::= oneselect",
++ /* 340 */ "oneselect ::= values",
++ /* 341 */ "sclp ::= selcollist COMMA",
++ /* 342 */ "as ::= ID|STRING",
++ /* 343 */ "expr ::= term",
++ /* 344 */ "likeop ::= LIKE_KW|MATCH",
++ /* 345 */ "exprlist ::= nexprlist",
++ /* 346 */ "nmnum ::= plus_num",
++ /* 347 */ "nmnum ::= nm",
++ /* 348 */ "nmnum ::= ON",
++ /* 349 */ "nmnum ::= DELETE",
++ /* 350 */ "nmnum ::= DEFAULT",
++ /* 351 */ "plus_num ::= INTEGER|FLOAT",
++ /* 352 */ "foreach_clause ::=",
++ /* 353 */ "foreach_clause ::= FOR EACH ROW",
++ /* 354 */ "trnm ::= nm",
++ /* 355 */ "tridxby ::=",
++ /* 356 */ "database_kw_opt ::= DATABASE",
++ /* 357 */ "database_kw_opt ::=",
++ /* 358 */ "kwcolumn_opt ::=",
++ /* 359 */ "kwcolumn_opt ::= COLUMNKW",
++ /* 360 */ "vtabarglist ::= vtabarg",
++ /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
++ /* 362 */ "vtabarg ::= vtabarg vtabargtoken",
++ /* 363 */ "anylist ::=",
++ /* 364 */ "anylist ::= anylist LP anylist RP",
++ /* 365 */ "anylist ::= anylist ANY",
++ /* 366 */ "with ::=",
+ };
+ #endif /* NDEBUG */
+ 
+@@ -141412,28 +148620,29 @@
+ 
+ /* Initialize a new parser that has already been allocated.
+ */
+-SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
+-  yyParser *pParser = (yyParser*)yypParser;
++SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){
++  yyParser *yypParser = (yyParser*)yypRawParser;
++  sqlite3ParserCTX_STORE
+ #ifdef YYTRACKMAXSTACKDEPTH
+-  pParser->yyhwm = 0;
++  yypParser->yyhwm = 0;
+ #endif
+ #if YYSTACKDEPTH<=0
+-  pParser->yytos = NULL;
+-  pParser->yystack = NULL;
+-  pParser->yystksz = 0;
+-  if( yyGrowStack(pParser) ){
+-    pParser->yystack = &pParser->yystk0;
+-    pParser->yystksz = 1;
++  yypParser->yytos = NULL;
++  yypParser->yystack = NULL;
++  yypParser->yystksz = 0;
++  if( yyGrowStack(yypParser) ){
++    yypParser->yystack = &yypParser->yystk0;
++    yypParser->yystksz = 1;
+   }
+ #endif
+ #ifndef YYNOERRORRECOVERY
+-  pParser->yyerrcnt = -1;
++  yypParser->yyerrcnt = -1;
+ #endif
+-  pParser->yytos = pParser->yystack;
+-  pParser->yystack[0].stateno = 0;
+-  pParser->yystack[0].major = 0;
++  yypParser->yytos = yypParser->yystack;
++  yypParser->yystack[0].stateno = 0;
++  yypParser->yystack[0].major = 0;
+ #if YYSTACKDEPTH>0
+-  pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1];
++  yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
+ #endif
+ }
+ 
+@@ -141450,11 +148659,14 @@
+ ** A pointer to a parser.  This pointer is used in subsequent calls
+ ** to sqlite3Parser and sqlite3ParserFree.
+ */
+-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
+-  yyParser *pParser;
+-  pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
+-  if( pParser ) sqlite3ParserInit(pParser);
+-  return pParser;
++SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){
++  yyParser *yypParser;
++  yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
++  if( yypParser ){
++    sqlite3ParserCTX_STORE
++    sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM);
++  }
++  return (void*)yypParser;
+ }
+ #endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+ 
+@@ -141471,7 +148683,8 @@
+   YYCODETYPE yymajor,     /* Type code for object to destroy */
+   YYMINORTYPE *yypminor   /* The object to be destroyed */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+   switch( yymajor ){
+     /* Here is inserted the actions which take place when a
+     ** terminal or non-terminal is destroyed.  This can happen
+@@ -141484,74 +148697,98 @@
+     ** inside the C code.
+     */
+ /********* Begin destructor definitions ***************************************/
+-    case 163: /* select */
+-    case 195: /* selectnowith */
+-    case 196: /* oneselect */
+-    case 207: /* values */
++    case 174: /* select */
++    case 206: /* selectnowith */
++    case 207: /* oneselect */
++    case 219: /* values */
+ {
+-sqlite3SelectDelete(pParse->db, (yypminor->yy387));
++sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+ }
+       break;
+-    case 173: /* term */
+-    case 174: /* expr */
+-    case 202: /* where_opt */
+-    case 204: /* having_opt */
+-    case 216: /* on_opt */
+-    case 227: /* case_operand */
+-    case 229: /* case_else */
+-    case 238: /* when_clause */
+-    case 243: /* key_opt */
++    case 184: /* term */
++    case 185: /* expr */
++    case 213: /* where_opt */
++    case 215: /* having_opt */
++    case 227: /* on_opt */
++    case 242: /* case_operand */
++    case 244: /* case_else */
++    case 253: /* when_clause */
++    case 258: /* key_opt */
++    case 272: /* filter_opt */
+ {
+-sqlite3ExprDelete(pParse->db, (yypminor->yy314));
++sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+ }
+       break;
+-    case 178: /* eidlist_opt */
+-    case 187: /* sortlist */
+-    case 188: /* eidlist */
+-    case 200: /* selcollist */
+-    case 203: /* groupby_opt */
+-    case 205: /* orderby_opt */
+-    case 208: /* nexprlist */
+-    case 209: /* exprlist */
+-    case 210: /* sclp */
+-    case 220: /* setlist */
+-    case 226: /* paren_exprlist */
+-    case 228: /* case_exprlist */
++    case 189: /* eidlist_opt */
++    case 198: /* sortlist */
++    case 199: /* eidlist */
++    case 211: /* selcollist */
++    case 214: /* groupby_opt */
++    case 216: /* orderby_opt */
++    case 220: /* nexprlist */
++    case 221: /* sclp */
++    case 229: /* exprlist */
++    case 233: /* setlist */
++    case 241: /* paren_exprlist */
++    case 243: /* case_exprlist */
++    case 271: /* part_opt */
+ {
+-sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
++sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
+ }
+       break;
+-    case 194: /* fullname */
+-    case 201: /* from */
+-    case 212: /* seltablist */
+-    case 213: /* stl_prefix */
++    case 205: /* fullname */
++    case 212: /* from */
++    case 223: /* seltablist */
++    case 224: /* stl_prefix */
++    case 230: /* xfullname */
+ {
+-sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
++sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
+ }
+       break;
+-    case 197: /* wqlist */
++    case 208: /* wqlist */
+ {
+-sqlite3WithDelete(pParse->db, (yypminor->yy451));
++sqlite3WithDelete(pParse->db, (yypminor->yy449));
+ }
+       break;
+-    case 217: /* using_opt */
+-    case 218: /* idlist */
+-    case 222: /* idlist_opt */
++    case 218: /* window_clause */
++    case 267: /* windowdefn_list */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy384));
++sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
+ }
+       break;
+-    case 234: /* trigger_cmd_list */
+-    case 239: /* trigger_cmd */
++    case 228: /* using_opt */
++    case 231: /* idlist */
++    case 235: /* idlist_opt */
+ {
+-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
++sqlite3IdListDelete(pParse->db, (yypminor->yy48));
+ }
+       break;
+-    case 236: /* trigger_event */
++    case 237: /* over_clause */
++    case 268: /* windowdefn */
++    case 269: /* window */
++    case 270: /* frame_opt */
+ {
+-sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
++sqlite3WindowDelete(pParse->db, (yypminor->yy327));
+ }
+       break;
++    case 249: /* trigger_cmd_list */
++    case 254: /* trigger_cmd */
++{
++sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
++}
++      break;
++    case 251: /* trigger_event */
++{
++sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
++}
++      break;
++    case 274: /* frame_bound */
++    case 275: /* frame_bound_s */
++    case 276: /* frame_bound_e */
++{
++sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
++}
++      break;
+ /********* End destructor definitions *****************************************/
+     default:  break;   /* If no destructor action specified: do nothing */
+   }
+@@ -141661,13 +148898,12 @@
+ ** Find the appropriate action for a parser given the terminal
+ ** look-ahead token iLookAhead.
+ */
+-static unsigned int yy_find_shift_action(
+-  yyParser *pParser,        /* The parser */
+-  YYCODETYPE iLookAhead     /* The look-ahead token */
++static YYACTIONTYPE yy_find_shift_action(
++  YYCODETYPE iLookAhead,    /* The look-ahead token */
++  YYACTIONTYPE stateno      /* Current state number */
+ ){
+   int i;
+-  int stateno = pParser->yytos->stateno;
+- 
++
+   if( stateno>YY_MAX_SHIFT ) return stateno;
+   assert( stateno <= YY_SHIFT_COUNT );
+ #if defined(YYCOVERAGE)
+@@ -141676,11 +148912,11 @@
+   do{
+     i = yy_shift_ofst[stateno];
+     assert( i>=0 );
+-    assert( i+YYNTOKEN<=(int)sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) );
++    /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */
+     assert( iLookAhead!=YYNOCODE );
+     assert( iLookAhead < YYNTOKEN );
+     i += iLookAhead;
+-    if( yy_lookahead[i]!=iLookAhead ){
++    if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){
+ #ifdef YYFALLBACK
+       YYCODETYPE iFallback;            /* Fallback token */
+       if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+@@ -141706,6 +148942,7 @@
+ #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+           j<YY_ACTTAB_COUNT &&
+ #endif
++          j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) &&
+           yy_lookahead[j]==YYWILDCARD && iLookAhead>0
+         ){
+ #ifndef NDEBUG
+@@ -141730,8 +148967,8 @@
+ ** Find the appropriate action for a parser given the non-terminal
+ ** look-ahead token iLookAhead.
+ */
+-static int yy_find_reduce_action(
+-  int stateno,              /* Current state number */
++static YYACTIONTYPE yy_find_reduce_action(
++  YYACTIONTYPE stateno,     /* Current state number */
+   YYCODETYPE iLookAhead     /* The look-ahead token */
+ ){
+   int i;
+@@ -141760,7 +148997,8 @@
+ ** The following routine is called if the stack overflows.
+ */
+ static void yyStackOverflow(yyParser *yypParser){
+-   sqlite3ParserARG_FETCH;
++   sqlite3ParserARG_FETCH
++   sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+    if( yyTraceFILE ){
+      fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+@@ -141773,7 +149011,8 @@
+ 
+   sqlite3ErrorMsg(pParse, "parser stack overflow");
+ /******** End %stack_overflow code ********************************************/
+-   sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
++   sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
++   sqlite3ParserCTX_STORE
+ }
+ 
+ /*
+@@ -141802,8 +149041,8 @@
+ */
+ static void yy_shift(
+   yyParser *yypParser,          /* The parser to be shifted */
+-  int yyNewState,               /* The new state to shift in */
+-  int yyMajor,                  /* The major token to shift in */
++  YYACTIONTYPE yyNewState,      /* The new state to shift in */
++  YYCODETYPE yyMajor,           /* The major token to shift in */
+   sqlite3ParserTOKENTYPE yyMinor        /* The minor token to shift in */
+ ){
+   yyStackEntry *yytos;
+@@ -141833,8 +149072,8 @@
+     yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
+   }
+   yytos = yypParser->yytos;
+-  yytos->stateno = (YYACTIONTYPE)yyNewState;
+-  yytos->major = (YYCODETYPE)yyMajor;
++  yytos->stateno = yyNewState;
++  yytos->major = yyMajor;
+   yytos->minor.yy0 = yyMinor;
+   yyTraceShift(yypParser, yyNewState, "Shift");
+ }
+@@ -141846,339 +149085,373 @@
+   YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
+   signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
+ } yyRuleInfo[] = {
+-  {  147,   -1 }, /* (0) explain ::= EXPLAIN */
+-  {  147,   -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
+-  {  148,   -1 }, /* (2) cmdx ::= cmd */
+-  {  149,   -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
+-  {  150,    0 }, /* (4) transtype ::= */
+-  {  150,   -1 }, /* (5) transtype ::= DEFERRED */
+-  {  150,   -1 }, /* (6) transtype ::= IMMEDIATE */
+-  {  150,   -1 }, /* (7) transtype ::= EXCLUSIVE */
+-  {  149,   -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
+-  {  149,   -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
+-  {  149,   -2 }, /* (10) cmd ::= SAVEPOINT nm */
+-  {  149,   -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
+-  {  149,   -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+-  {  154,   -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+-  {  156,   -1 }, /* (14) createkw ::= CREATE */
+-  {  158,    0 }, /* (15) ifnotexists ::= */
+-  {  158,   -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
+-  {  157,   -1 }, /* (17) temp ::= TEMP */
+-  {  157,    0 }, /* (18) temp ::= */
+-  {  155,   -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+-  {  155,   -2 }, /* (20) create_table_args ::= AS select */
+-  {  162,    0 }, /* (21) table_options ::= */
+-  {  162,   -2 }, /* (22) table_options ::= WITHOUT nm */
+-  {  164,   -2 }, /* (23) columnname ::= nm typetoken */
+-  {  166,    0 }, /* (24) typetoken ::= */
+-  {  166,   -4 }, /* (25) typetoken ::= typename LP signed RP */
+-  {  166,   -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+-  {  167,   -2 }, /* (27) typename ::= typename ID|STRING */
+-  {  171,    0 }, /* (28) scanpt ::= */
+-  {  172,   -2 }, /* (29) ccons ::= CONSTRAINT nm */
+-  {  172,   -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
+-  {  172,   -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
+-  {  172,   -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
+-  {  172,   -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
+-  {  172,   -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
+-  {  172,   -3 }, /* (35) ccons ::= NOT NULL onconf */
+-  {  172,   -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+-  {  172,   -2 }, /* (37) ccons ::= UNIQUE onconf */
+-  {  172,   -4 }, /* (38) ccons ::= CHECK LP expr RP */
+-  {  172,   -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
+-  {  172,   -1 }, /* (40) ccons ::= defer_subclause */
+-  {  172,   -2 }, /* (41) ccons ::= COLLATE ID|STRING */
+-  {  177,    0 }, /* (42) autoinc ::= */
+-  {  177,   -1 }, /* (43) autoinc ::= AUTOINCR */
+-  {  179,    0 }, /* (44) refargs ::= */
+-  {  179,   -2 }, /* (45) refargs ::= refargs refarg */
+-  {  181,   -2 }, /* (46) refarg ::= MATCH nm */
+-  {  181,   -3 }, /* (47) refarg ::= ON INSERT refact */
+-  {  181,   -3 }, /* (48) refarg ::= ON DELETE refact */
+-  {  181,   -3 }, /* (49) refarg ::= ON UPDATE refact */
+-  {  182,   -2 }, /* (50) refact ::= SET NULL */
+-  {  182,   -2 }, /* (51) refact ::= SET DEFAULT */
+-  {  182,   -1 }, /* (52) refact ::= CASCADE */
+-  {  182,   -1 }, /* (53) refact ::= RESTRICT */
+-  {  182,   -2 }, /* (54) refact ::= NO ACTION */
+-  {  180,   -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+-  {  180,   -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+-  {  183,    0 }, /* (57) init_deferred_pred_opt ::= */
+-  {  183,   -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+-  {  183,   -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+-  {  161,    0 }, /* (60) conslist_opt ::= */
+-  {  185,   -1 }, /* (61) tconscomma ::= COMMA */
+-  {  186,   -2 }, /* (62) tcons ::= CONSTRAINT nm */
+-  {  186,   -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+-  {  186,   -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
+-  {  186,   -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
+-  {  186,  -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+-  {  189,    0 }, /* (67) defer_subclause_opt ::= */
+-  {  175,    0 }, /* (68) onconf ::= */
+-  {  175,   -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
+-  {  190,    0 }, /* (70) orconf ::= */
+-  {  190,   -2 }, /* (71) orconf ::= OR resolvetype */
+-  {  191,   -1 }, /* (72) resolvetype ::= IGNORE */
+-  {  191,   -1 }, /* (73) resolvetype ::= REPLACE */
+-  {  149,   -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
+-  {  193,   -2 }, /* (75) ifexists ::= IF EXISTS */
+-  {  193,    0 }, /* (76) ifexists ::= */
+-  {  149,   -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+-  {  149,   -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
+-  {  149,   -1 }, /* (79) cmd ::= select */
+-  {  163,   -3 }, /* (80) select ::= WITH wqlist selectnowith */
+-  {  163,   -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
+-  {  163,   -1 }, /* (82) select ::= selectnowith */
+-  {  195,   -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
+-  {  198,   -1 }, /* (84) multiselect_op ::= UNION */
+-  {  198,   -2 }, /* (85) multiselect_op ::= UNION ALL */
+-  {  198,   -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
+-  {  196,   -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+-  {  207,   -4 }, /* (88) values ::= VALUES LP nexprlist RP */
+-  {  207,   -5 }, /* (89) values ::= values COMMA LP exprlist RP */
+-  {  199,   -1 }, /* (90) distinct ::= DISTINCT */
+-  {  199,   -1 }, /* (91) distinct ::= ALL */
+-  {  199,    0 }, /* (92) distinct ::= */
+-  {  210,    0 }, /* (93) sclp ::= */
+-  {  200,   -5 }, /* (94) selcollist ::= sclp scanpt expr scanpt as */
+-  {  200,   -3 }, /* (95) selcollist ::= sclp scanpt STAR */
+-  {  200,   -5 }, /* (96) selcollist ::= sclp scanpt nm DOT STAR */
+-  {  211,   -2 }, /* (97) as ::= AS nm */
+-  {  211,    0 }, /* (98) as ::= */
+-  {  201,    0 }, /* (99) from ::= */
+-  {  201,   -2 }, /* (100) from ::= FROM seltablist */
+-  {  213,   -2 }, /* (101) stl_prefix ::= seltablist joinop */
+-  {  213,    0 }, /* (102) stl_prefix ::= */
+-  {  212,   -7 }, /* (103) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+-  {  212,   -9 }, /* (104) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+-  {  212,   -7 }, /* (105) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+-  {  212,   -7 }, /* (106) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+-  {  159,    0 }, /* (107) dbnm ::= */
+-  {  159,   -2 }, /* (108) dbnm ::= DOT nm */
+-  {  194,   -1 }, /* (109) fullname ::= nm */
+-  {  194,   -3 }, /* (110) fullname ::= nm DOT nm */
+-  {  214,   -1 }, /* (111) joinop ::= COMMA|JOIN */
+-  {  214,   -2 }, /* (112) joinop ::= JOIN_KW JOIN */
+-  {  214,   -3 }, /* (113) joinop ::= JOIN_KW nm JOIN */
+-  {  214,   -4 }, /* (114) joinop ::= JOIN_KW nm nm JOIN */
+-  {  216,   -2 }, /* (115) on_opt ::= ON expr */
+-  {  216,    0 }, /* (116) on_opt ::= */
+-  {  215,    0 }, /* (117) indexed_opt ::= */
+-  {  215,   -3 }, /* (118) indexed_opt ::= INDEXED BY nm */
+-  {  215,   -2 }, /* (119) indexed_opt ::= NOT INDEXED */
+-  {  217,   -4 }, /* (120) using_opt ::= USING LP idlist RP */
+-  {  217,    0 }, /* (121) using_opt ::= */
+-  {  205,    0 }, /* (122) orderby_opt ::= */
+-  {  205,   -3 }, /* (123) orderby_opt ::= ORDER BY sortlist */
+-  {  187,   -4 }, /* (124) sortlist ::= sortlist COMMA expr sortorder */
+-  {  187,   -2 }, /* (125) sortlist ::= expr sortorder */
+-  {  176,   -1 }, /* (126) sortorder ::= ASC */
+-  {  176,   -1 }, /* (127) sortorder ::= DESC */
+-  {  176,    0 }, /* (128) sortorder ::= */
+-  {  203,    0 }, /* (129) groupby_opt ::= */
+-  {  203,   -3 }, /* (130) groupby_opt ::= GROUP BY nexprlist */
+-  {  204,    0 }, /* (131) having_opt ::= */
+-  {  204,   -2 }, /* (132) having_opt ::= HAVING expr */
+-  {  206,    0 }, /* (133) limit_opt ::= */
+-  {  206,   -2 }, /* (134) limit_opt ::= LIMIT expr */
+-  {  206,   -4 }, /* (135) limit_opt ::= LIMIT expr OFFSET expr */
+-  {  206,   -4 }, /* (136) limit_opt ::= LIMIT expr COMMA expr */
+-  {  149,   -6 }, /* (137) cmd ::= with DELETE FROM fullname indexed_opt where_opt */
+-  {  202,    0 }, /* (138) where_opt ::= */
+-  {  202,   -2 }, /* (139) where_opt ::= WHERE expr */
+-  {  149,   -8 }, /* (140) cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
+-  {  220,   -5 }, /* (141) setlist ::= setlist COMMA nm EQ expr */
+-  {  220,   -7 }, /* (142) setlist ::= setlist COMMA LP idlist RP EQ expr */
+-  {  220,   -3 }, /* (143) setlist ::= nm EQ expr */
+-  {  220,   -5 }, /* (144) setlist ::= LP idlist RP EQ expr */
+-  {  149,   -6 }, /* (145) cmd ::= with insert_cmd INTO fullname idlist_opt select */
+-  {  149,   -7 }, /* (146) cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
+-  {  221,   -2 }, /* (147) insert_cmd ::= INSERT orconf */
+-  {  221,   -1 }, /* (148) insert_cmd ::= REPLACE */
+-  {  222,    0 }, /* (149) idlist_opt ::= */
+-  {  222,   -3 }, /* (150) idlist_opt ::= LP idlist RP */
+-  {  218,   -3 }, /* (151) idlist ::= idlist COMMA nm */
+-  {  218,   -1 }, /* (152) idlist ::= nm */
+-  {  174,   -3 }, /* (153) expr ::= LP expr RP */
+-  {  174,   -1 }, /* (154) expr ::= ID|INDEXED */
+-  {  174,   -1 }, /* (155) expr ::= JOIN_KW */
+-  {  174,   -3 }, /* (156) expr ::= nm DOT nm */
+-  {  174,   -5 }, /* (157) expr ::= nm DOT nm DOT nm */
+-  {  173,   -1 }, /* (158) term ::= NULL|FLOAT|BLOB */
+-  {  173,   -1 }, /* (159) term ::= STRING */
+-  {  173,   -1 }, /* (160) term ::= INTEGER */
+-  {  174,   -1 }, /* (161) expr ::= VARIABLE */
+-  {  174,   -3 }, /* (162) expr ::= expr COLLATE ID|STRING */
+-  {  174,   -6 }, /* (163) expr ::= CAST LP expr AS typetoken RP */
+-  {  174,   -5 }, /* (164) expr ::= ID|INDEXED LP distinct exprlist RP */
+-  {  174,   -4 }, /* (165) expr ::= ID|INDEXED LP STAR RP */
+-  {  173,   -1 }, /* (166) term ::= CTIME_KW */
+-  {  174,   -5 }, /* (167) expr ::= LP nexprlist COMMA expr RP */
+-  {  174,   -3 }, /* (168) expr ::= expr AND expr */
+-  {  174,   -3 }, /* (169) expr ::= expr OR expr */
+-  {  174,   -3 }, /* (170) expr ::= expr LT|GT|GE|LE expr */
+-  {  174,   -3 }, /* (171) expr ::= expr EQ|NE expr */
+-  {  174,   -3 }, /* (172) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+-  {  174,   -3 }, /* (173) expr ::= expr PLUS|MINUS expr */
+-  {  174,   -3 }, /* (174) expr ::= expr STAR|SLASH|REM expr */
+-  {  174,   -3 }, /* (175) expr ::= expr CONCAT expr */
+-  {  223,   -2 }, /* (176) likeop ::= NOT LIKE_KW|MATCH */
+-  {  174,   -3 }, /* (177) expr ::= expr likeop expr */
+-  {  174,   -5 }, /* (178) expr ::= expr likeop expr ESCAPE expr */
+-  {  174,   -2 }, /* (179) expr ::= expr ISNULL|NOTNULL */
+-  {  174,   -3 }, /* (180) expr ::= expr NOT NULL */
+-  {  174,   -3 }, /* (181) expr ::= expr IS expr */
+-  {  174,   -4 }, /* (182) expr ::= expr IS NOT expr */
+-  {  174,   -2 }, /* (183) expr ::= NOT expr */
+-  {  174,   -2 }, /* (184) expr ::= BITNOT expr */
+-  {  174,   -2 }, /* (185) expr ::= MINUS expr */
+-  {  174,   -2 }, /* (186) expr ::= PLUS expr */
+-  {  224,   -1 }, /* (187) between_op ::= BETWEEN */
+-  {  224,   -2 }, /* (188) between_op ::= NOT BETWEEN */
+-  {  174,   -5 }, /* (189) expr ::= expr between_op expr AND expr */
+-  {  225,   -1 }, /* (190) in_op ::= IN */
+-  {  225,   -2 }, /* (191) in_op ::= NOT IN */
+-  {  174,   -5 }, /* (192) expr ::= expr in_op LP exprlist RP */
+-  {  174,   -3 }, /* (193) expr ::= LP select RP */
+-  {  174,   -5 }, /* (194) expr ::= expr in_op LP select RP */
+-  {  174,   -5 }, /* (195) expr ::= expr in_op nm dbnm paren_exprlist */
+-  {  174,   -4 }, /* (196) expr ::= EXISTS LP select RP */
+-  {  174,   -5 }, /* (197) expr ::= CASE case_operand case_exprlist case_else END */
+-  {  228,   -5 }, /* (198) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+-  {  228,   -4 }, /* (199) case_exprlist ::= WHEN expr THEN expr */
+-  {  229,   -2 }, /* (200) case_else ::= ELSE expr */
+-  {  229,    0 }, /* (201) case_else ::= */
+-  {  227,   -1 }, /* (202) case_operand ::= expr */
+-  {  227,    0 }, /* (203) case_operand ::= */
+-  {  209,    0 }, /* (204) exprlist ::= */
+-  {  208,   -3 }, /* (205) nexprlist ::= nexprlist COMMA expr */
+-  {  208,   -1 }, /* (206) nexprlist ::= expr */
+-  {  226,    0 }, /* (207) paren_exprlist ::= */
+-  {  226,   -3 }, /* (208) paren_exprlist ::= LP exprlist RP */
+-  {  149,  -12 }, /* (209) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+-  {  230,   -1 }, /* (210) uniqueflag ::= UNIQUE */
+-  {  230,    0 }, /* (211) uniqueflag ::= */
+-  {  178,    0 }, /* (212) eidlist_opt ::= */
+-  {  178,   -3 }, /* (213) eidlist_opt ::= LP eidlist RP */
+-  {  188,   -5 }, /* (214) eidlist ::= eidlist COMMA nm collate sortorder */
+-  {  188,   -3 }, /* (215) eidlist ::= nm collate sortorder */
+-  {  231,    0 }, /* (216) collate ::= */
+-  {  231,   -2 }, /* (217) collate ::= COLLATE ID|STRING */
+-  {  149,   -4 }, /* (218) cmd ::= DROP INDEX ifexists fullname */
+-  {  149,   -1 }, /* (219) cmd ::= VACUUM */
+-  {  149,   -2 }, /* (220) cmd ::= VACUUM nm */
+-  {  149,   -3 }, /* (221) cmd ::= PRAGMA nm dbnm */
+-  {  149,   -5 }, /* (222) cmd ::= PRAGMA nm dbnm EQ nmnum */
+-  {  149,   -6 }, /* (223) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+-  {  149,   -5 }, /* (224) cmd ::= PRAGMA nm dbnm EQ minus_num */
+-  {  149,   -6 }, /* (225) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+-  {  169,   -2 }, /* (226) plus_num ::= PLUS INTEGER|FLOAT */
+-  {  170,   -2 }, /* (227) minus_num ::= MINUS INTEGER|FLOAT */
+-  {  149,   -5 }, /* (228) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+-  {  233,  -11 }, /* (229) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+-  {  235,   -1 }, /* (230) trigger_time ::= BEFORE|AFTER */
+-  {  235,   -2 }, /* (231) trigger_time ::= INSTEAD OF */
+-  {  235,    0 }, /* (232) trigger_time ::= */
+-  {  236,   -1 }, /* (233) trigger_event ::= DELETE|INSERT */
+-  {  236,   -1 }, /* (234) trigger_event ::= UPDATE */
+-  {  236,   -3 }, /* (235) trigger_event ::= UPDATE OF idlist */
+-  {  238,    0 }, /* (236) when_clause ::= */
+-  {  238,   -2 }, /* (237) when_clause ::= WHEN expr */
+-  {  234,   -3 }, /* (238) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+-  {  234,   -2 }, /* (239) trigger_cmd_list ::= trigger_cmd SEMI */
+-  {  240,   -3 }, /* (240) trnm ::= nm DOT nm */
+-  {  241,   -3 }, /* (241) tridxby ::= INDEXED BY nm */
+-  {  241,   -2 }, /* (242) tridxby ::= NOT INDEXED */
+-  {  239,   -8 }, /* (243) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+-  {  239,   -7 }, /* (244) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt */
+-  {  239,   -6 }, /* (245) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+-  {  239,   -3 }, /* (246) trigger_cmd ::= scanpt select scanpt */
+-  {  174,   -4 }, /* (247) expr ::= RAISE LP IGNORE RP */
+-  {  174,   -6 }, /* (248) expr ::= RAISE LP raisetype COMMA nm RP */
+-  {  192,   -1 }, /* (249) raisetype ::= ROLLBACK */
+-  {  192,   -1 }, /* (250) raisetype ::= ABORT */
+-  {  192,   -1 }, /* (251) raisetype ::= FAIL */
+-  {  149,   -4 }, /* (252) cmd ::= DROP TRIGGER ifexists fullname */
+-  {  149,   -6 }, /* (253) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+-  {  149,   -3 }, /* (254) cmd ::= DETACH database_kw_opt expr */
+-  {  243,    0 }, /* (255) key_opt ::= */
+-  {  243,   -2 }, /* (256) key_opt ::= KEY expr */
+-  {  149,   -1 }, /* (257) cmd ::= REINDEX */
+-  {  149,   -3 }, /* (258) cmd ::= REINDEX nm dbnm */
+-  {  149,   -1 }, /* (259) cmd ::= ANALYZE */
+-  {  149,   -3 }, /* (260) cmd ::= ANALYZE nm dbnm */
+-  {  149,   -6 }, /* (261) cmd ::= ALTER TABLE fullname RENAME TO nm */
+-  {  149,   -7 }, /* (262) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+-  {  244,   -1 }, /* (263) add_column_fullname ::= fullname */
+-  {  149,   -1 }, /* (264) cmd ::= create_vtab */
+-  {  149,   -4 }, /* (265) cmd ::= create_vtab LP vtabarglist RP */
+-  {  246,   -8 }, /* (266) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+-  {  248,    0 }, /* (267) vtabarg ::= */
+-  {  249,   -1 }, /* (268) vtabargtoken ::= ANY */
+-  {  249,   -3 }, /* (269) vtabargtoken ::= lp anylist RP */
+-  {  250,   -1 }, /* (270) lp ::= LP */
+-  {  219,   -2 }, /* (271) with ::= WITH wqlist */
+-  {  219,   -3 }, /* (272) with ::= WITH RECURSIVE wqlist */
+-  {  197,   -6 }, /* (273) wqlist ::= nm eidlist_opt AS LP select RP */
+-  {  197,   -8 }, /* (274) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+-  {  144,   -1 }, /* (275) input ::= cmdlist */
+-  {  145,   -2 }, /* (276) cmdlist ::= cmdlist ecmd */
+-  {  145,   -1 }, /* (277) cmdlist ::= ecmd */
+-  {  146,   -1 }, /* (278) ecmd ::= SEMI */
+-  {  146,   -3 }, /* (279) ecmd ::= explain cmdx SEMI */
+-  {  147,    0 }, /* (280) explain ::= */
+-  {  151,    0 }, /* (281) trans_opt ::= */
+-  {  151,   -1 }, /* (282) trans_opt ::= TRANSACTION */
+-  {  151,   -2 }, /* (283) trans_opt ::= TRANSACTION nm */
+-  {  153,   -1 }, /* (284) savepoint_opt ::= SAVEPOINT */
+-  {  153,    0 }, /* (285) savepoint_opt ::= */
+-  {  149,   -2 }, /* (286) cmd ::= create_table create_table_args */
+-  {  160,   -4 }, /* (287) columnlist ::= columnlist COMMA columnname carglist */
+-  {  160,   -2 }, /* (288) columnlist ::= columnname carglist */
+-  {  152,   -1 }, /* (289) nm ::= ID|INDEXED */
+-  {  152,   -1 }, /* (290) nm ::= STRING */
+-  {  152,   -1 }, /* (291) nm ::= JOIN_KW */
+-  {  166,   -1 }, /* (292) typetoken ::= typename */
+-  {  167,   -1 }, /* (293) typename ::= ID|STRING */
+-  {  168,   -1 }, /* (294) signed ::= plus_num */
+-  {  168,   -1 }, /* (295) signed ::= minus_num */
+-  {  165,   -2 }, /* (296) carglist ::= carglist ccons */
+-  {  165,    0 }, /* (297) carglist ::= */
+-  {  172,   -2 }, /* (298) ccons ::= NULL onconf */
+-  {  161,   -2 }, /* (299) conslist_opt ::= COMMA conslist */
+-  {  184,   -3 }, /* (300) conslist ::= conslist tconscomma tcons */
+-  {  184,   -1 }, /* (301) conslist ::= tcons */
+-  {  185,    0 }, /* (302) tconscomma ::= */
+-  {  189,   -1 }, /* (303) defer_subclause_opt ::= defer_subclause */
+-  {  191,   -1 }, /* (304) resolvetype ::= raisetype */
+-  {  195,   -1 }, /* (305) selectnowith ::= oneselect */
+-  {  196,   -1 }, /* (306) oneselect ::= values */
+-  {  210,   -2 }, /* (307) sclp ::= selcollist COMMA */
+-  {  211,   -1 }, /* (308) as ::= ID|STRING */
+-  {  174,   -1 }, /* (309) expr ::= term */
+-  {  223,   -1 }, /* (310) likeop ::= LIKE_KW|MATCH */
+-  {  209,   -1 }, /* (311) exprlist ::= nexprlist */
+-  {  232,   -1 }, /* (312) nmnum ::= plus_num */
+-  {  232,   -1 }, /* (313) nmnum ::= nm */
+-  {  232,   -1 }, /* (314) nmnum ::= ON */
+-  {  232,   -1 }, /* (315) nmnum ::= DELETE */
+-  {  232,   -1 }, /* (316) nmnum ::= DEFAULT */
+-  {  169,   -1 }, /* (317) plus_num ::= INTEGER|FLOAT */
+-  {  237,    0 }, /* (318) foreach_clause ::= */
+-  {  237,   -3 }, /* (319) foreach_clause ::= FOR EACH ROW */
+-  {  240,   -1 }, /* (320) trnm ::= nm */
+-  {  241,    0 }, /* (321) tridxby ::= */
+-  {  242,   -1 }, /* (322) database_kw_opt ::= DATABASE */
+-  {  242,    0 }, /* (323) database_kw_opt ::= */
+-  {  245,    0 }, /* (324) kwcolumn_opt ::= */
+-  {  245,   -1 }, /* (325) kwcolumn_opt ::= COLUMNKW */
+-  {  247,   -1 }, /* (326) vtabarglist ::= vtabarg */
+-  {  247,   -3 }, /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */
+-  {  248,   -2 }, /* (328) vtabarg ::= vtabarg vtabargtoken */
+-  {  251,    0 }, /* (329) anylist ::= */
+-  {  251,   -4 }, /* (330) anylist ::= anylist LP anylist RP */
+-  {  251,   -2 }, /* (331) anylist ::= anylist ANY */
+-  {  219,    0 }, /* (332) with ::= */
++  {  159,   -1 }, /* (0) explain ::= EXPLAIN */
++  {  159,   -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
++  {  158,   -1 }, /* (2) cmdx ::= cmd */
++  {  160,   -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
++  {  161,    0 }, /* (4) transtype ::= */
++  {  161,   -1 }, /* (5) transtype ::= DEFERRED */
++  {  161,   -1 }, /* (6) transtype ::= IMMEDIATE */
++  {  161,   -1 }, /* (7) transtype ::= EXCLUSIVE */
++  {  160,   -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
++  {  160,   -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
++  {  160,   -2 }, /* (10) cmd ::= SAVEPOINT nm */
++  {  160,   -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
++  {  160,   -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
++  {  165,   -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
++  {  167,   -1 }, /* (14) createkw ::= CREATE */
++  {  169,    0 }, /* (15) ifnotexists ::= */
++  {  169,   -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
++  {  168,   -1 }, /* (17) temp ::= TEMP */
++  {  168,    0 }, /* (18) temp ::= */
++  {  166,   -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
++  {  166,   -2 }, /* (20) create_table_args ::= AS select */
++  {  173,    0 }, /* (21) table_options ::= */
++  {  173,   -2 }, /* (22) table_options ::= WITHOUT nm */
++  {  175,   -2 }, /* (23) columnname ::= nm typetoken */
++  {  177,    0 }, /* (24) typetoken ::= */
++  {  177,   -4 }, /* (25) typetoken ::= typename LP signed RP */
++  {  177,   -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
++  {  178,   -2 }, /* (27) typename ::= typename ID|STRING */
++  {  182,    0 }, /* (28) scanpt ::= */
++  {  183,   -2 }, /* (29) ccons ::= CONSTRAINT nm */
++  {  183,   -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
++  {  183,   -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
++  {  183,   -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
++  {  183,   -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
++  {  183,   -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
++  {  183,   -3 }, /* (35) ccons ::= NOT NULL onconf */
++  {  183,   -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
++  {  183,   -2 }, /* (37) ccons ::= UNIQUE onconf */
++  {  183,   -4 }, /* (38) ccons ::= CHECK LP expr RP */
++  {  183,   -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
++  {  183,   -1 }, /* (40) ccons ::= defer_subclause */
++  {  183,   -2 }, /* (41) ccons ::= COLLATE ID|STRING */
++  {  188,    0 }, /* (42) autoinc ::= */
++  {  188,   -1 }, /* (43) autoinc ::= AUTOINCR */
++  {  190,    0 }, /* (44) refargs ::= */
++  {  190,   -2 }, /* (45) refargs ::= refargs refarg */
++  {  192,   -2 }, /* (46) refarg ::= MATCH nm */
++  {  192,   -3 }, /* (47) refarg ::= ON INSERT refact */
++  {  192,   -3 }, /* (48) refarg ::= ON DELETE refact */
++  {  192,   -3 }, /* (49) refarg ::= ON UPDATE refact */
++  {  193,   -2 }, /* (50) refact ::= SET NULL */
++  {  193,   -2 }, /* (51) refact ::= SET DEFAULT */
++  {  193,   -1 }, /* (52) refact ::= CASCADE */
++  {  193,   -1 }, /* (53) refact ::= RESTRICT */
++  {  193,   -2 }, /* (54) refact ::= NO ACTION */
++  {  191,   -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
++  {  191,   -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
++  {  194,    0 }, /* (57) init_deferred_pred_opt ::= */
++  {  194,   -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
++  {  194,   -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
++  {  172,    0 }, /* (60) conslist_opt ::= */
++  {  196,   -1 }, /* (61) tconscomma ::= COMMA */
++  {  197,   -2 }, /* (62) tcons ::= CONSTRAINT nm */
++  {  197,   -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
++  {  197,   -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
++  {  197,   -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
++  {  197,  -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
++  {  200,    0 }, /* (67) defer_subclause_opt ::= */
++  {  186,    0 }, /* (68) onconf ::= */
++  {  186,   -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
++  {  201,    0 }, /* (70) orconf ::= */
++  {  201,   -2 }, /* (71) orconf ::= OR resolvetype */
++  {  202,   -1 }, /* (72) resolvetype ::= IGNORE */
++  {  202,   -1 }, /* (73) resolvetype ::= REPLACE */
++  {  160,   -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
++  {  204,   -2 }, /* (75) ifexists ::= IF EXISTS */
++  {  204,    0 }, /* (76) ifexists ::= */
++  {  160,   -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
++  {  160,   -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
++  {  160,   -1 }, /* (79) cmd ::= select */
++  {  174,   -3 }, /* (80) select ::= WITH wqlist selectnowith */
++  {  174,   -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
++  {  174,   -1 }, /* (82) select ::= selectnowith */
++  {  206,   -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
++  {  209,   -1 }, /* (84) multiselect_op ::= UNION */
++  {  209,   -2 }, /* (85) multiselect_op ::= UNION ALL */
++  {  209,   -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
++  {  207,   -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
++  {  207,  -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
++  {  219,   -4 }, /* (89) values ::= VALUES LP nexprlist RP */
++  {  219,   -5 }, /* (90) values ::= values COMMA LP nexprlist RP */
++  {  210,   -1 }, /* (91) distinct ::= DISTINCT */
++  {  210,   -1 }, /* (92) distinct ::= ALL */
++  {  210,    0 }, /* (93) distinct ::= */
++  {  221,    0 }, /* (94) sclp ::= */
++  {  211,   -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */
++  {  211,   -3 }, /* (96) selcollist ::= sclp scanpt STAR */
++  {  211,   -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
++  {  222,   -2 }, /* (98) as ::= AS nm */
++  {  222,    0 }, /* (99) as ::= */
++  {  212,    0 }, /* (100) from ::= */
++  {  212,   -2 }, /* (101) from ::= FROM seltablist */
++  {  224,   -2 }, /* (102) stl_prefix ::= seltablist joinop */
++  {  224,    0 }, /* (103) stl_prefix ::= */
++  {  223,   -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++  {  223,   -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
++  {  223,   -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
++  {  223,   -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
++  {  170,    0 }, /* (108) dbnm ::= */
++  {  170,   -2 }, /* (109) dbnm ::= DOT nm */
++  {  205,   -1 }, /* (110) fullname ::= nm */
++  {  205,   -3 }, /* (111) fullname ::= nm DOT nm */
++  {  230,   -1 }, /* (112) xfullname ::= nm */
++  {  230,   -3 }, /* (113) xfullname ::= nm DOT nm */
++  {  230,   -5 }, /* (114) xfullname ::= nm DOT nm AS nm */
++  {  230,   -3 }, /* (115) xfullname ::= nm AS nm */
++  {  225,   -1 }, /* (116) joinop ::= COMMA|JOIN */
++  {  225,   -2 }, /* (117) joinop ::= JOIN_KW JOIN */
++  {  225,   -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */
++  {  225,   -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */
++  {  227,   -2 }, /* (120) on_opt ::= ON expr */
++  {  227,    0 }, /* (121) on_opt ::= */
++  {  226,    0 }, /* (122) indexed_opt ::= */
++  {  226,   -3 }, /* (123) indexed_opt ::= INDEXED BY nm */
++  {  226,   -2 }, /* (124) indexed_opt ::= NOT INDEXED */
++  {  228,   -4 }, /* (125) using_opt ::= USING LP idlist RP */
++  {  228,    0 }, /* (126) using_opt ::= */
++  {  216,    0 }, /* (127) orderby_opt ::= */
++  {  216,   -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */
++  {  198,   -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */
++  {  198,   -2 }, /* (130) sortlist ::= expr sortorder */
++  {  187,   -1 }, /* (131) sortorder ::= ASC */
++  {  187,   -1 }, /* (132) sortorder ::= DESC */
++  {  187,    0 }, /* (133) sortorder ::= */
++  {  214,    0 }, /* (134) groupby_opt ::= */
++  {  214,   -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */
++  {  215,    0 }, /* (136) having_opt ::= */
++  {  215,   -2 }, /* (137) having_opt ::= HAVING expr */
++  {  217,    0 }, /* (138) limit_opt ::= */
++  {  217,   -2 }, /* (139) limit_opt ::= LIMIT expr */
++  {  217,   -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
++  {  217,   -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */
++  {  160,   -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
++  {  213,    0 }, /* (143) where_opt ::= */
++  {  213,   -2 }, /* (144) where_opt ::= WHERE expr */
++  {  160,   -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
++  {  233,   -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */
++  {  233,   -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
++  {  233,   -3 }, /* (148) setlist ::= nm EQ expr */
++  {  233,   -5 }, /* (149) setlist ::= LP idlist RP EQ expr */
++  {  160,   -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
++  {  160,   -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
++  {  236,    0 }, /* (152) upsert ::= */
++  {  236,  -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
++  {  236,   -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
++  {  236,   -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */
++  {  234,   -2 }, /* (156) insert_cmd ::= INSERT orconf */
++  {  234,   -1 }, /* (157) insert_cmd ::= REPLACE */
++  {  235,    0 }, /* (158) idlist_opt ::= */
++  {  235,   -3 }, /* (159) idlist_opt ::= LP idlist RP */
++  {  231,   -3 }, /* (160) idlist ::= idlist COMMA nm */
++  {  231,   -1 }, /* (161) idlist ::= nm */
++  {  185,   -3 }, /* (162) expr ::= LP expr RP */
++  {  185,   -1 }, /* (163) expr ::= ID|INDEXED */
++  {  185,   -1 }, /* (164) expr ::= JOIN_KW */
++  {  185,   -3 }, /* (165) expr ::= nm DOT nm */
++  {  185,   -5 }, /* (166) expr ::= nm DOT nm DOT nm */
++  {  184,   -1 }, /* (167) term ::= NULL|FLOAT|BLOB */
++  {  184,   -1 }, /* (168) term ::= STRING */
++  {  184,   -1 }, /* (169) term ::= INTEGER */
++  {  185,   -1 }, /* (170) expr ::= VARIABLE */
++  {  185,   -3 }, /* (171) expr ::= expr COLLATE ID|STRING */
++  {  185,   -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */
++  {  185,   -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
++  {  185,   -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */
++  {  185,   -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
++  {  185,   -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
++  {  184,   -1 }, /* (177) term ::= CTIME_KW */
++  {  185,   -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */
++  {  185,   -3 }, /* (179) expr ::= expr AND expr */
++  {  185,   -3 }, /* (180) expr ::= expr OR expr */
++  {  185,   -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */
++  {  185,   -3 }, /* (182) expr ::= expr EQ|NE expr */
++  {  185,   -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
++  {  185,   -3 }, /* (184) expr ::= expr PLUS|MINUS expr */
++  {  185,   -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */
++  {  185,   -3 }, /* (186) expr ::= expr CONCAT expr */
++  {  238,   -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */
++  {  185,   -3 }, /* (188) expr ::= expr likeop expr */
++  {  185,   -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */
++  {  185,   -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */
++  {  185,   -3 }, /* (191) expr ::= expr NOT NULL */
++  {  185,   -3 }, /* (192) expr ::= expr IS expr */
++  {  185,   -4 }, /* (193) expr ::= expr IS NOT expr */
++  {  185,   -2 }, /* (194) expr ::= NOT expr */
++  {  185,   -2 }, /* (195) expr ::= BITNOT expr */
++  {  185,   -2 }, /* (196) expr ::= PLUS|MINUS expr */
++  {  239,   -1 }, /* (197) between_op ::= BETWEEN */
++  {  239,   -2 }, /* (198) between_op ::= NOT BETWEEN */
++  {  185,   -5 }, /* (199) expr ::= expr between_op expr AND expr */
++  {  240,   -1 }, /* (200) in_op ::= IN */
++  {  240,   -2 }, /* (201) in_op ::= NOT IN */
++  {  185,   -5 }, /* (202) expr ::= expr in_op LP exprlist RP */
++  {  185,   -3 }, /* (203) expr ::= LP select RP */
++  {  185,   -5 }, /* (204) expr ::= expr in_op LP select RP */
++  {  185,   -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
++  {  185,   -4 }, /* (206) expr ::= EXISTS LP select RP */
++  {  185,   -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
++  {  243,   -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
++  {  243,   -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */
++  {  244,   -2 }, /* (210) case_else ::= ELSE expr */
++  {  244,    0 }, /* (211) case_else ::= */
++  {  242,   -1 }, /* (212) case_operand ::= expr */
++  {  242,    0 }, /* (213) case_operand ::= */
++  {  229,    0 }, /* (214) exprlist ::= */
++  {  220,   -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */
++  {  220,   -1 }, /* (216) nexprlist ::= expr */
++  {  241,    0 }, /* (217) paren_exprlist ::= */
++  {  241,   -3 }, /* (218) paren_exprlist ::= LP exprlist RP */
++  {  160,  -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
++  {  245,   -1 }, /* (220) uniqueflag ::= UNIQUE */
++  {  245,    0 }, /* (221) uniqueflag ::= */
++  {  189,    0 }, /* (222) eidlist_opt ::= */
++  {  189,   -3 }, /* (223) eidlist_opt ::= LP eidlist RP */
++  {  199,   -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
++  {  199,   -3 }, /* (225) eidlist ::= nm collate sortorder */
++  {  246,    0 }, /* (226) collate ::= */
++  {  246,   -2 }, /* (227) collate ::= COLLATE ID|STRING */
++  {  160,   -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */
++  {  160,   -1 }, /* (229) cmd ::= VACUUM */
++  {  160,   -2 }, /* (230) cmd ::= VACUUM nm */
++  {  160,   -3 }, /* (231) cmd ::= PRAGMA nm dbnm */
++  {  160,   -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */
++  {  160,   -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */
++  {  160,   -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */
++  {  160,   -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */
++  {  180,   -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */
++  {  181,   -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */
++  {  160,   -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
++  {  248,  -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
++  {  250,   -1 }, /* (240) trigger_time ::= BEFORE|AFTER */
++  {  250,   -2 }, /* (241) trigger_time ::= INSTEAD OF */
++  {  250,    0 }, /* (242) trigger_time ::= */
++  {  251,   -1 }, /* (243) trigger_event ::= DELETE|INSERT */
++  {  251,   -1 }, /* (244) trigger_event ::= UPDATE */
++  {  251,   -3 }, /* (245) trigger_event ::= UPDATE OF idlist */
++  {  253,    0 }, /* (246) when_clause ::= */
++  {  253,   -2 }, /* (247) when_clause ::= WHEN expr */
++  {  249,   -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
++  {  249,   -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */
++  {  255,   -3 }, /* (250) trnm ::= nm DOT nm */
++  {  256,   -3 }, /* (251) tridxby ::= INDEXED BY nm */
++  {  256,   -2 }, /* (252) tridxby ::= NOT INDEXED */
++  {  254,   -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
++  {  254,   -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
++  {  254,   -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
++  {  254,   -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */
++  {  185,   -4 }, /* (257) expr ::= RAISE LP IGNORE RP */
++  {  185,   -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */
++  {  203,   -1 }, /* (259) raisetype ::= ROLLBACK */
++  {  203,   -1 }, /* (260) raisetype ::= ABORT */
++  {  203,   -1 }, /* (261) raisetype ::= FAIL */
++  {  160,   -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */
++  {  160,   -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
++  {  160,   -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */
++  {  258,    0 }, /* (265) key_opt ::= */
++  {  258,   -2 }, /* (266) key_opt ::= KEY expr */
++  {  160,   -1 }, /* (267) cmd ::= REINDEX */
++  {  160,   -3 }, /* (268) cmd ::= REINDEX nm dbnm */
++  {  160,   -1 }, /* (269) cmd ::= ANALYZE */
++  {  160,   -3 }, /* (270) cmd ::= ANALYZE nm dbnm */
++  {  160,   -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */
++  {  160,   -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
++  {  259,   -1 }, /* (273) add_column_fullname ::= fullname */
++  {  160,   -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
++  {  160,   -1 }, /* (275) cmd ::= create_vtab */
++  {  160,   -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */
++  {  261,   -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
++  {  263,    0 }, /* (278) vtabarg ::= */
++  {  264,   -1 }, /* (279) vtabargtoken ::= ANY */
++  {  264,   -3 }, /* (280) vtabargtoken ::= lp anylist RP */
++  {  265,   -1 }, /* (281) lp ::= LP */
++  {  232,   -2 }, /* (282) with ::= WITH wqlist */
++  {  232,   -3 }, /* (283) with ::= WITH RECURSIVE wqlist */
++  {  208,   -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */
++  {  208,   -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
++  {  267,   -1 }, /* (286) windowdefn_list ::= windowdefn */
++  {  267,   -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */
++  {  268,   -3 }, /* (288) windowdefn ::= nm AS window */
++  {  269,   -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */
++  {  271,   -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */
++  {  271,    0 }, /* (291) part_opt ::= */
++  {  270,    0 }, /* (292) frame_opt ::= */
++  {  270,   -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */
++  {  270,   -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
++  {  273,   -1 }, /* (295) range_or_rows ::= RANGE */
++  {  273,   -1 }, /* (296) range_or_rows ::= ROWS */
++  {  275,   -1 }, /* (297) frame_bound_s ::= frame_bound */
++  {  275,   -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */
++  {  276,   -1 }, /* (299) frame_bound_e ::= frame_bound */
++  {  276,   -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */
++  {  274,   -2 }, /* (301) frame_bound ::= expr PRECEDING */
++  {  274,   -2 }, /* (302) frame_bound ::= CURRENT ROW */
++  {  274,   -2 }, /* (303) frame_bound ::= expr FOLLOWING */
++  {  218,   -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */
++  {  237,   -3 }, /* (305) over_clause ::= filter_opt OVER window */
++  {  237,   -3 }, /* (306) over_clause ::= filter_opt OVER nm */
++  {  272,    0 }, /* (307) filter_opt ::= */
++  {  272,   -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */
++  {  155,   -1 }, /* (309) input ::= cmdlist */
++  {  156,   -2 }, /* (310) cmdlist ::= cmdlist ecmd */
++  {  156,   -1 }, /* (311) cmdlist ::= ecmd */
++  {  157,   -1 }, /* (312) ecmd ::= SEMI */
++  {  157,   -2 }, /* (313) ecmd ::= cmdx SEMI */
++  {  157,   -2 }, /* (314) ecmd ::= explain cmdx */
++  {  162,    0 }, /* (315) trans_opt ::= */
++  {  162,   -1 }, /* (316) trans_opt ::= TRANSACTION */
++  {  162,   -2 }, /* (317) trans_opt ::= TRANSACTION nm */
++  {  164,   -1 }, /* (318) savepoint_opt ::= SAVEPOINT */
++  {  164,    0 }, /* (319) savepoint_opt ::= */
++  {  160,   -2 }, /* (320) cmd ::= create_table create_table_args */
++  {  171,   -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */
++  {  171,   -2 }, /* (322) columnlist ::= columnname carglist */
++  {  163,   -1 }, /* (323) nm ::= ID|INDEXED */
++  {  163,   -1 }, /* (324) nm ::= STRING */
++  {  163,   -1 }, /* (325) nm ::= JOIN_KW */
++  {  177,   -1 }, /* (326) typetoken ::= typename */
++  {  178,   -1 }, /* (327) typename ::= ID|STRING */
++  {  179,   -1 }, /* (328) signed ::= plus_num */
++  {  179,   -1 }, /* (329) signed ::= minus_num */
++  {  176,   -2 }, /* (330) carglist ::= carglist ccons */
++  {  176,    0 }, /* (331) carglist ::= */
++  {  183,   -2 }, /* (332) ccons ::= NULL onconf */
++  {  172,   -2 }, /* (333) conslist_opt ::= COMMA conslist */
++  {  195,   -3 }, /* (334) conslist ::= conslist tconscomma tcons */
++  {  195,   -1 }, /* (335) conslist ::= tcons */
++  {  196,    0 }, /* (336) tconscomma ::= */
++  {  200,   -1 }, /* (337) defer_subclause_opt ::= defer_subclause */
++  {  202,   -1 }, /* (338) resolvetype ::= raisetype */
++  {  206,   -1 }, /* (339) selectnowith ::= oneselect */
++  {  207,   -1 }, /* (340) oneselect ::= values */
++  {  221,   -2 }, /* (341) sclp ::= selcollist COMMA */
++  {  222,   -1 }, /* (342) as ::= ID|STRING */
++  {  185,   -1 }, /* (343) expr ::= term */
++  {  238,   -1 }, /* (344) likeop ::= LIKE_KW|MATCH */
++  {  229,   -1 }, /* (345) exprlist ::= nexprlist */
++  {  247,   -1 }, /* (346) nmnum ::= plus_num */
++  {  247,   -1 }, /* (347) nmnum ::= nm */
++  {  247,   -1 }, /* (348) nmnum ::= ON */
++  {  247,   -1 }, /* (349) nmnum ::= DELETE */
++  {  247,   -1 }, /* (350) nmnum ::= DEFAULT */
++  {  180,   -1 }, /* (351) plus_num ::= INTEGER|FLOAT */
++  {  252,    0 }, /* (352) foreach_clause ::= */
++  {  252,   -3 }, /* (353) foreach_clause ::= FOR EACH ROW */
++  {  255,   -1 }, /* (354) trnm ::= nm */
++  {  256,    0 }, /* (355) tridxby ::= */
++  {  257,   -1 }, /* (356) database_kw_opt ::= DATABASE */
++  {  257,    0 }, /* (357) database_kw_opt ::= */
++  {  260,    0 }, /* (358) kwcolumn_opt ::= */
++  {  260,   -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */
++  {  262,   -1 }, /* (360) vtabarglist ::= vtabarg */
++  {  262,   -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */
++  {  263,   -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */
++  {  266,    0 }, /* (363) anylist ::= */
++  {  266,   -4 }, /* (364) anylist ::= anylist LP anylist RP */
++  {  266,   -2 }, /* (365) anylist ::= anylist ANY */
++  {  232,    0 }, /* (366) with ::= */
+ };
+ 
+ static void yy_accept(yyParser*);  /* Forward Declaration */
+@@ -142193,17 +149466,18 @@
+ ** only called from one place, optimizing compilers will in-line it, which
+ ** means that the extra parameters have no performance impact.
+ */
+-static void yy_reduce(
++static YYACTIONTYPE yy_reduce(
+   yyParser *yypParser,         /* The parser */
+   unsigned int yyruleno,       /* Number of the rule by which to reduce */
+   int yyLookahead,             /* Lookahead token, or YYNOCODE if none */
+   sqlite3ParserTOKENTYPE yyLookaheadToken  /* Value of the lookahead token */
++  sqlite3ParserCTX_PDECL                   /* %extra_context */
+ ){
+   int yygoto;                     /* The next state */
+-  int yyact;                      /* The next action */
++  YYACTIONTYPE yyact;             /* The next action */
+   yyStackEntry *yymsp;            /* The top of the parser's stack */
+   int yysize;                     /* Amount to pop the stack */
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
+   (void)yyLookahead;
+   (void)yyLookaheadToken;
+   yymsp = yypParser->yytos;
+@@ -142234,13 +149508,19 @@
+ #if YYSTACKDEPTH>0 
+     if( yypParser->yytos>=yypParser->yystackEnd ){
+       yyStackOverflow(yypParser);
+-      return;
++      /* The call to yyStackOverflow() above pops the stack until it is
++      ** empty, causing the main parser loop to exit.  So the return value
++      ** is never used and does not matter. */
++      return 0;
+     }
+ #else
+     if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
+       if( yyGrowStack(yypParser) ){
+         yyStackOverflow(yypParser);
+-        return;
++        /* The call to yyStackOverflow() above pops the stack until it is
++        ** empty, causing the main parser loop to exit.  So the return value
++        ** is never used and does not matter. */
++        return 0;
+       }
+       yymsp = yypParser->yytos;
+     }
+@@ -142268,15 +149548,15 @@
+ { sqlite3FinishCoding(pParse); }
+         break;
+       case 3: /* cmd ::= BEGIN transtype trans_opt */
+-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
++{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
+         break;
+       case 4: /* transtype ::= */
+-{yymsp[1].minor.yy4 = TK_DEFERRED;}
++{yymsp[1].minor.yy70 = TK_DEFERRED;}
+         break;
+       case 5: /* transtype ::= DEFERRED */
+       case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
+       case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
+-{yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-X*/}
++{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
+         break;
+       case 8: /* cmd ::= COMMIT|END trans_opt */
+       case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
+@@ -142299,7 +149579,7 @@
+         break;
+       case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ {
+-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
++   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70);
+ }
+         break;
+       case 14: /* createkw ::= CREATE */
+@@ -142312,34 +149592,34 @@
+       case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
+       case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
+       case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
+-      case 92: /* distinct ::= */ yytestcase(yyruleno==92);
+-      case 216: /* collate ::= */ yytestcase(yyruleno==216);
+-{yymsp[1].minor.yy4 = 0;}
++      case 93: /* distinct ::= */ yytestcase(yyruleno==93);
++      case 226: /* collate ::= */ yytestcase(yyruleno==226);
++{yymsp[1].minor.yy70 = 0;}
+         break;
+       case 16: /* ifnotexists ::= IF NOT EXISTS */
+-{yymsp[-2].minor.yy4 = 1;}
++{yymsp[-2].minor.yy70 = 1;}
+         break;
+       case 17: /* temp ::= TEMP */
+       case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
+-{yymsp[0].minor.yy4 = 1;}
++{yymsp[0].minor.yy70 = 1;}
+         break;
+       case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
+ {
+-  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy4,0);
++  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0);
+ }
+         break;
+       case 20: /* create_table_args ::= AS select */
+ {
+-  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
++  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ }
+         break;
+       case 22: /* table_options ::= WITHOUT nm */
+ {
+   if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+-    yymsp[-1].minor.yy4 = TF_WithoutRowid | TF_NoVisibleRowid;
++    yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
+   }else{
+-    yymsp[-1].minor.yy4 = 0;
++    yymsp[-1].minor.yy70 = 0;
+     sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+   }
+ }
+@@ -142349,7 +149629,7 @@
+         break;
+       case 24: /* typetoken ::= */
+       case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
+-      case 98: /* as ::= */ yytestcase(yyruleno==98);
++      case 99: /* as ::= */ yytestcase(yyruleno==99);
+ {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
+         break;
+       case 25: /* typetoken ::= typename LP signed RP */
+@@ -142368,7 +149648,7 @@
+       case 28: /* scanpt ::= */
+ {
+   assert( yyLookahead!=YYNOCODE );
+-  yymsp[1].minor.yy336 = yyLookaheadToken.z;
++  yymsp[1].minor.yy392 = yyLookaheadToken.z;
+ }
+         break;
+       case 29: /* ccons ::= CONSTRAINT nm */
+@@ -142376,18 +149656,18 @@
+ {pParse->constraintName = yymsp[0].minor.yy0;}
+         break;
+       case 30: /* ccons ::= DEFAULT scanpt term scanpt */
+-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy336,yymsp[0].minor.yy336);}
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+         break;
+       case 31: /* ccons ::= DEFAULT LP expr RP */
+-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+         break;
+       case 32: /* ccons ::= DEFAULT PLUS term scanpt */
+-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy336);}
++{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
+         break;
+       case 33: /* ccons ::= DEFAULT MINUS term scanpt */
+ {
+-  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy314, 0);
+-  sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy336);
++  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
++  sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
+ }
+         break;
+       case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
+@@ -142397,174 +149677,174 @@
+     sqlite3ExprIdToTrueFalse(p);
+     testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
+   }
+-  sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
++    sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
+ }
+         break;
+       case 35: /* ccons ::= NOT NULL onconf */
+-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
++{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);}
+         break;
+       case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
++{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
+         break;
+       case 37: /* ccons ::= UNIQUE onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0,
++{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
+                                    SQLITE_IDXTYPE_UNIQUE);}
+         break;
+       case 38: /* ccons ::= CHECK LP expr RP */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy314);}
++{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
+         break;
+       case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
++{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
+         break;
+       case 40: /* ccons ::= defer_subclause */
+-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
++{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
+         break;
+       case 41: /* ccons ::= COLLATE ID|STRING */
+ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
+         break;
+       case 44: /* refargs ::= */
+-{ yymsp[1].minor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
++{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
+         break;
+       case 45: /* refargs ::= refargs refarg */
+-{ yymsp[-1].minor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
++{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
+         break;
+       case 46: /* refarg ::= MATCH nm */
+-{ yymsp[-1].minor.yy215.value = 0;     yymsp[-1].minor.yy215.mask = 0x000000; }
++{ yymsp[-1].minor.yy111.value = 0;     yymsp[-1].minor.yy111.mask = 0x000000; }
+         break;
+       case 47: /* refarg ::= ON INSERT refact */
+-{ yymsp[-2].minor.yy215.value = 0;     yymsp[-2].minor.yy215.mask = 0x000000; }
++{ yymsp[-2].minor.yy111.value = 0;     yymsp[-2].minor.yy111.mask = 0x000000; }
+         break;
+       case 48: /* refarg ::= ON DELETE refact */
+-{ yymsp[-2].minor.yy215.value = yymsp[0].minor.yy4;     yymsp[-2].minor.yy215.mask = 0x0000ff; }
++{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70;     yymsp[-2].minor.yy111.mask = 0x0000ff; }
+         break;
+       case 49: /* refarg ::= ON UPDATE refact */
+-{ yymsp[-2].minor.yy215.value = yymsp[0].minor.yy4<<8;  yymsp[-2].minor.yy215.mask = 0x00ff00; }
++{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8;  yymsp[-2].minor.yy111.mask = 0x00ff00; }
+         break;
+       case 50: /* refact ::= SET NULL */
+-{ yymsp[-1].minor.yy4 = OE_SetNull;  /* EV: R-33326-45252 */}
++{ yymsp[-1].minor.yy70 = OE_SetNull;  /* EV: R-33326-45252 */}
+         break;
+       case 51: /* refact ::= SET DEFAULT */
+-{ yymsp[-1].minor.yy4 = OE_SetDflt;  /* EV: R-33326-45252 */}
++{ yymsp[-1].minor.yy70 = OE_SetDflt;  /* EV: R-33326-45252 */}
+         break;
+       case 52: /* refact ::= CASCADE */
+-{ yymsp[0].minor.yy4 = OE_Cascade;  /* EV: R-33326-45252 */}
++{ yymsp[0].minor.yy70 = OE_Cascade;  /* EV: R-33326-45252 */}
+         break;
+       case 53: /* refact ::= RESTRICT */
+-{ yymsp[0].minor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
++{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
+         break;
+       case 54: /* refact ::= NO ACTION */
+-{ yymsp[-1].minor.yy4 = OE_None;     /* EV: R-33326-45252 */}
++{ yymsp[-1].minor.yy70 = OE_None;     /* EV: R-33326-45252 */}
+         break;
+       case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+-{yymsp[-2].minor.yy4 = 0;}
++{yymsp[-2].minor.yy70 = 0;}
+         break;
+       case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+       case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
+-      case 147: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==147);
+-{yymsp[-1].minor.yy4 = yymsp[0].minor.yy4;}
++      case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
++{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;}
+         break;
+       case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+       case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
+-      case 188: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==188);
+-      case 191: /* in_op ::= NOT IN */ yytestcase(yyruleno==191);
+-      case 217: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==217);
+-{yymsp[-1].minor.yy4 = 1;}
++      case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
++      case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
++      case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
++{yymsp[-1].minor.yy70 = 1;}
+         break;
+       case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+-{yymsp[-1].minor.yy4 = 0;}
++{yymsp[-1].minor.yy70 = 0;}
+         break;
+       case 61: /* tconscomma ::= COMMA */
+ {pParse->constraintName.n = 0;}
+         break;
+       case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
++{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);}
+         break;
+       case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
+-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0,
++{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0,
+                                        SQLITE_IDXTYPE_UNIQUE);}
+         break;
+       case 65: /* tcons ::= CHECK LP expr RP onconf */
+-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy314);}
++{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
+         break;
+       case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ {
+-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
+-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
++    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
++    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
+ }
+         break;
+       case 68: /* onconf ::= */
+       case 70: /* orconf ::= */ yytestcase(yyruleno==70);
+-{yymsp[1].minor.yy4 = OE_Default;}
++{yymsp[1].minor.yy70 = OE_Default;}
+         break;
+       case 69: /* onconf ::= ON CONFLICT resolvetype */
+-{yymsp[-2].minor.yy4 = yymsp[0].minor.yy4;}
++{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
+         break;
+       case 72: /* resolvetype ::= IGNORE */
+-{yymsp[0].minor.yy4 = OE_Ignore;}
++{yymsp[0].minor.yy70 = OE_Ignore;}
+         break;
+       case 73: /* resolvetype ::= REPLACE */
+-      case 148: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==148);
+-{yymsp[0].minor.yy4 = OE_Replace;}
++      case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
++{yymsp[0].minor.yy70 = OE_Replace;}
+         break;
+       case 74: /* cmd ::= DROP TABLE ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
+ }
+         break;
+       case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ {
+-  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy387, yymsp[-7].minor.yy4, yymsp[-5].minor.yy4);
++  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
+ }
+         break;
+       case 78: /* cmd ::= DROP VIEW ifexists fullname */
+ {
+-  sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
++  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
+ }
+         break;
+       case 79: /* cmd ::= select */
+ {
+   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
+-  sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
+-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
++  sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
++  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ }
+         break;
+       case 80: /* select ::= WITH wqlist selectnowith */
+ {
+-  Select *p = yymsp[0].minor.yy387;
++  Select *p = yymsp[0].minor.yy489;
+   if( p ){
+-    p->pWith = yymsp[-1].minor.yy451;
++    p->pWith = yymsp[-1].minor.yy449;
+     parserDoubleLinkSelect(pParse, p);
+   }else{
+-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy451);
++    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+   }
+-  yymsp[-2].minor.yy387 = p;
++  yymsp[-2].minor.yy489 = p;
+ }
+         break;
+       case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
+ {
+-  Select *p = yymsp[0].minor.yy387;
++  Select *p = yymsp[0].minor.yy489;
+   if( p ){
+-    p->pWith = yymsp[-1].minor.yy451;
++    p->pWith = yymsp[-1].minor.yy449;
+     parserDoubleLinkSelect(pParse, p);
+   }else{
+-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy451);
++    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+   }
+-  yymsp[-3].minor.yy387 = p;
++  yymsp[-3].minor.yy489 = p;
+ }
+         break;
+       case 82: /* select ::= selectnowith */
+ {
+-  Select *p = yymsp[0].minor.yy387;
++  Select *p = yymsp[0].minor.yy489;
+   if( p ){
+     parserDoubleLinkSelect(pParse, p);
+   }
+-  yymsp[0].minor.yy387 = p; /*A-overwrites-X*/
++  yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
+ }
+         break;
+       case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ {
+-  Select *pRhs = yymsp[0].minor.yy387;
+-  Select *pLhs = yymsp[-2].minor.yy387;
++  Select *pRhs = yymsp[0].minor.yy489;
++  Select *pLhs = yymsp[-2].minor.yy489;
+   if( pRhs && pRhs->pPrior ){
+     SrcList *pFrom;
+     Token x;
+@@ -142574,158 +149854,142 @@
+     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
+   }
+   if( pRhs ){
+-    pRhs->op = (u8)yymsp[-1].minor.yy4;
++    pRhs->op = (u8)yymsp[-1].minor.yy70;
+     pRhs->pPrior = pLhs;
+     if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
+     pRhs->selFlags &= ~SF_MultiValue;
+-    if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
++    if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
+   }else{
+     sqlite3SelectDelete(pParse->db, pLhs);
+   }
+-  yymsp[-2].minor.yy387 = pRhs;
++  yymsp[-2].minor.yy489 = pRhs;
+ }
+         break;
+       case 84: /* multiselect_op ::= UNION */
+       case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
+-{yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-OP*/}
++{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
+         break;
+       case 85: /* multiselect_op ::= UNION ALL */
+-{yymsp[-1].minor.yy4 = TK_ALL;}
++{yymsp[-1].minor.yy70 = TK_ALL;}
+         break;
+       case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ {
+-#if SELECTTRACE_ENABLED
+-  Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
+-#endif
+-  yymsp[-8].minor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy314);
+-#if SELECTTRACE_ENABLED
+-  /* Populate the Select.zSelName[] string that is used to help with
+-  ** query planner debugging, to differentiate between multiple Select
+-  ** objects in a complex query.
+-  **
+-  ** If the SELECT keyword is immediately followed by a C-style comment
+-  ** then extract the first few alphanumeric characters from within that
+-  ** comment to be the zSelName value.  Otherwise, the label is #N where
+-  ** is an integer that is incremented with each SELECT statement seen.
+-  */
+-  if( yymsp[-8].minor.yy387!=0 ){
+-    const char *z = s.z+6;
+-    int i;
+-    sqlite3_snprintf(sizeof(yymsp[-8].minor.yy387->zSelName), yymsp[-8].minor.yy387->zSelName,"#%d",++pParse->nSelect);
+-    while( z[0]==' ' ) z++;
+-    if( z[0]=='/' && z[1]=='*' ){
+-      z += 2;
+-      while( z[0]==' ' ) z++;
+-      for(i=0; sqlite3Isalnum(z[i]); i++){}
+-      sqlite3_snprintf(sizeof(yymsp[-8].minor.yy387->zSelName), yymsp[-8].minor.yy387->zSelName, "%.*s", i, z);
+-    }
++  yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18);
++}
++        break;
++      case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
++{
++  yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18);
++  if( yymsp[-9].minor.yy489 ){
++    yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327;
++  }else{
++    sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
+   }
+-#endif /* SELECTRACE_ENABLED */
+ }
+         break;
+-      case 88: /* values ::= VALUES LP nexprlist RP */
++      case 89: /* values ::= VALUES LP nexprlist RP */
+ {
+-  yymsp[-3].minor.yy387 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0);
++  yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
+ }
+         break;
+-      case 89: /* values ::= values COMMA LP exprlist RP */
++      case 90: /* values ::= values COMMA LP nexprlist RP */
+ {
+-  Select *pRight, *pLeft = yymsp[-4].minor.yy387;
+-  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0);
++  Select *pRight, *pLeft = yymsp[-4].minor.yy489;
++  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+   if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+   if( pRight ){
+     pRight->op = TK_ALL;
+     pRight->pPrior = pLeft;
+-    yymsp[-4].minor.yy387 = pRight;
++    yymsp[-4].minor.yy489 = pRight;
+   }else{
+-    yymsp[-4].minor.yy387 = pLeft;
++    yymsp[-4].minor.yy489 = pLeft;
+   }
+ }
+         break;
+-      case 90: /* distinct ::= DISTINCT */
+-{yymsp[0].minor.yy4 = SF_Distinct;}
++      case 91: /* distinct ::= DISTINCT */
++{yymsp[0].minor.yy70 = SF_Distinct;}
+         break;
+-      case 91: /* distinct ::= ALL */
+-{yymsp[0].minor.yy4 = SF_All;}
++      case 92: /* distinct ::= ALL */
++{yymsp[0].minor.yy70 = SF_All;}
+         break;
+-      case 93: /* sclp ::= */
+-      case 122: /* orderby_opt ::= */ yytestcase(yyruleno==122);
+-      case 129: /* groupby_opt ::= */ yytestcase(yyruleno==129);
+-      case 204: /* exprlist ::= */ yytestcase(yyruleno==204);
+-      case 207: /* paren_exprlist ::= */ yytestcase(yyruleno==207);
+-      case 212: /* eidlist_opt ::= */ yytestcase(yyruleno==212);
+-{yymsp[1].minor.yy322 = 0;}
++      case 94: /* sclp ::= */
++      case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
++      case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134);
++      case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
++      case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
++      case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
++{yymsp[1].minor.yy420 = 0;}
+         break;
+-      case 94: /* selcollist ::= sclp scanpt expr scanpt as */
++      case 95: /* selcollist ::= sclp scanpt expr scanpt as */
+ {
+-   yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy314);
+-   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1);
+-   sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy336,yymsp[-1].minor.yy336);
++   yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
++   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1);
++   sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392);
+ }
+         break;
+-      case 95: /* selcollist ::= sclp scanpt STAR */
++      case 96: /* selcollist ::= sclp scanpt STAR */
+ {
+   Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
+-  yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p);
++  yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
+ }
+         break;
+-      case 96: /* selcollist ::= sclp scanpt nm DOT STAR */
++      case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
+ {
+   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[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
+ }
+         break;
+-      case 97: /* as ::= AS nm */
+-      case 108: /* dbnm ::= DOT nm */ yytestcase(yyruleno==108);
+-      case 226: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==226);
+-      case 227: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==227);
++      case 98: /* as ::= AS nm */
++      case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
++      case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236);
++      case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237);
+ {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 99: /* from ::= */
+-{yymsp[1].minor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy259));}
++      case 100: /* from ::= */
++{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
+         break;
+-      case 100: /* from ::= FROM seltablist */
++      case 101: /* from ::= FROM seltablist */
+ {
+-  yymsp[-1].minor.yy259 = yymsp[0].minor.yy259;
+-  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy259);
++  yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
++  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
+ }
+         break;
+-      case 101: /* stl_prefix ::= seltablist joinop */
++      case 102: /* stl_prefix ::= seltablist joinop */
+ {
+-   if( ALWAYS(yymsp[-1].minor.yy259 && yymsp[-1].minor.yy259->nSrc>0) ) yymsp[-1].minor.yy259->a[yymsp[-1].minor.yy259->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy4;
++   if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70;
+ }
+         break;
+-      case 102: /* stl_prefix ::= */
+-{yymsp[1].minor.yy259 = 0;}
++      case 103: /* stl_prefix ::= */
++{yymsp[1].minor.yy135 = 0;}
+         break;
+-      case 103: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
++      case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ {
+-  yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy259, &yymsp[-2].minor.yy0);
++  yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0);
+ }
+         break;
+-      case 104: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
++      case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ {
+-  yymsp[-8].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy259,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+-  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy259, yymsp[-4].minor.yy322);
++  yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420);
+ }
+         break;
+-      case 105: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
++      case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ {
+-    yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
++    yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+   }
+         break;
+-      case 106: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
++      case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ {
+-    if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
+-      yymsp[-6].minor.yy259 = yymsp[-4].minor.yy259;
+-    }else if( yymsp[-4].minor.yy259->nSrc==1 ){
+-      yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+-      if( yymsp[-6].minor.yy259 ){
+-        struct SrcList_item *pNew = &yymsp[-6].minor.yy259->a[yymsp[-6].minor.yy259->nSrc-1];
+-        struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
++    if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){
++      yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135;
++    }else if( yymsp[-4].minor.yy135->nSrc==1 ){
++      yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
++      if( yymsp[-6].minor.yy135 ){
++        struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1];
++        struct SrcList_item *pOld = yymsp[-4].minor.yy135->a;
+         pNew->zName = pOld->zName;
+         pNew->zDatabase = pOld->zDatabase;
+         pNew->pSelect = pOld->pSelect;
+@@ -142732,194 +149996,240 @@
+         pOld->zName = pOld->zDatabase = 0;
+         pOld->pSelect = 0;
+       }
+-      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
++      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
+     }else{
+       Select *pSubquery;
+-      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
+-      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0);
+-      yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
++      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135);
++      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0);
++      yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+     }
+   }
+         break;
+-      case 107: /* dbnm ::= */
+-      case 117: /* indexed_opt ::= */ yytestcase(yyruleno==117);
++      case 108: /* dbnm ::= */
++      case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
+ {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
+         break;
+-      case 109: /* fullname ::= nm */
+-{yymsp[0].minor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
++      case 110: /* fullname ::= nm */
++{
++  yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0);
++  if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
++}
++  yymsp[0].minor.yy135 = yylhsminor.yy135;
+         break;
+-      case 110: /* fullname ::= nm DOT nm */
+-{yymsp[-2].minor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 111: /* fullname ::= nm DOT nm */
++{
++  yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
++  if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
++}
++  yymsp[-2].minor.yy135 = yylhsminor.yy135;
+         break;
+-      case 111: /* joinop ::= COMMA|JOIN */
+-{ yymsp[0].minor.yy4 = JT_INNER; }
++      case 112: /* xfullname ::= nm */
++{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+         break;
+-      case 112: /* joinop ::= JOIN_KW JOIN */
+-{yymsp[-1].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
++      case 113: /* xfullname ::= nm DOT nm */
++{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+         break;
+-      case 113: /* joinop ::= JOIN_KW nm JOIN */
+-{yymsp[-2].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
++      case 114: /* xfullname ::= nm DOT nm AS nm */
++{
++   yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
++   if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
++}
+         break;
+-      case 114: /* joinop ::= JOIN_KW nm nm JOIN */
+-{yymsp[-3].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
++      case 115: /* xfullname ::= nm AS nm */
++{  
++   yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
++   if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
++}
+         break;
+-      case 115: /* on_opt ::= ON expr */
+-      case 132: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==132);
+-      case 139: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==139);
+-      case 200: /* case_else ::= ELSE expr */ yytestcase(yyruleno==200);
+-{yymsp[-1].minor.yy314 = yymsp[0].minor.yy314;}
++      case 116: /* joinop ::= COMMA|JOIN */
++{ yymsp[0].minor.yy70 = JT_INNER; }
+         break;
+-      case 116: /* on_opt ::= */
+-      case 131: /* having_opt ::= */ yytestcase(yyruleno==131);
+-      case 133: /* limit_opt ::= */ yytestcase(yyruleno==133);
+-      case 138: /* where_opt ::= */ yytestcase(yyruleno==138);
+-      case 201: /* case_else ::= */ yytestcase(yyruleno==201);
+-      case 203: /* case_operand ::= */ yytestcase(yyruleno==203);
+-{yymsp[1].minor.yy314 = 0;}
++      case 117: /* joinop ::= JOIN_KW JOIN */
++{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
+         break;
+-      case 118: /* indexed_opt ::= INDEXED BY nm */
++      case 118: /* joinop ::= JOIN_KW nm JOIN */
++{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
++        break;
++      case 119: /* joinop ::= JOIN_KW nm nm JOIN */
++{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
++        break;
++      case 120: /* on_opt ::= ON expr */
++      case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
++      case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
++      case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
++{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;}
++        break;
++      case 121: /* on_opt ::= */
++      case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
++      case 138: /* limit_opt ::= */ yytestcase(yyruleno==138);
++      case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
++      case 211: /* case_else ::= */ yytestcase(yyruleno==211);
++      case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
++{yymsp[1].minor.yy18 = 0;}
++        break;
++      case 123: /* indexed_opt ::= INDEXED BY nm */
+ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
+         break;
+-      case 119: /* indexed_opt ::= NOT INDEXED */
++      case 124: /* indexed_opt ::= NOT INDEXED */
+ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
+         break;
+-      case 120: /* using_opt ::= USING LP idlist RP */
+-{yymsp[-3].minor.yy384 = yymsp[-1].minor.yy384;}
++      case 125: /* using_opt ::= USING LP idlist RP */
++{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
+         break;
+-      case 121: /* using_opt ::= */
+-      case 149: /* idlist_opt ::= */ yytestcase(yyruleno==149);
+-{yymsp[1].minor.yy384 = 0;}
++      case 126: /* using_opt ::= */
++      case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
++{yymsp[1].minor.yy48 = 0;}
+         break;
+-      case 123: /* orderby_opt ::= ORDER BY sortlist */
+-      case 130: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==130);
+-{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
++      case 128: /* orderby_opt ::= ORDER BY sortlist */
++      case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
++{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;}
+         break;
+-      case 124: /* sortlist ::= sortlist COMMA expr sortorder */
++      case 129: /* sortlist ::= sortlist COMMA expr sortorder */
+ {
+-  yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy314);
+-  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy322,yymsp[0].minor.yy4);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
++  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
+ }
+         break;
+-      case 125: /* sortlist ::= expr sortorder */
++      case 130: /* sortlist ::= expr sortorder */
+ {
+-  yymsp[-1].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy314); /*A-overwrites-Y*/
+-  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy322,yymsp[0].minor.yy4);
++  yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
++  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
+ }
+         break;
+-      case 126: /* sortorder ::= ASC */
+-{yymsp[0].minor.yy4 = SQLITE_SO_ASC;}
++      case 131: /* sortorder ::= ASC */
++{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
+         break;
+-      case 127: /* sortorder ::= DESC */
+-{yymsp[0].minor.yy4 = SQLITE_SO_DESC;}
++      case 132: /* sortorder ::= DESC */
++{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
+         break;
+-      case 128: /* sortorder ::= */
+-{yymsp[1].minor.yy4 = SQLITE_SO_UNDEFINED;}
++      case 133: /* sortorder ::= */
++{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
+         break;
+-      case 134: /* limit_opt ::= LIMIT expr */
+-{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy314,0);}
++      case 139: /* limit_opt ::= LIMIT expr */
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
+         break;
+-      case 135: /* limit_opt ::= LIMIT expr OFFSET expr */
+-{yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);}
++      case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
++{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+         break;
+-      case 136: /* limit_opt ::= LIMIT expr COMMA expr */
+-{yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy314,yymsp[-2].minor.yy314);}
++      case 141: /* limit_opt ::= LIMIT expr COMMA expr */
++{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
+         break;
+-      case 137: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
++      case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ {
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
+-  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314,0,0);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0);
++  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0);
+ }
+         break;
+-      case 140: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
++      case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ {
+-  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+-  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list"); 
+-  sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy4,0,0);
++  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0);
++  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list"); 
++  sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0);
+ }
+         break;
+-      case 141: /* setlist ::= setlist COMMA nm EQ expr */
++      case 146: /* setlist ::= setlist COMMA nm EQ expr */
+ {
+-  yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy314);
+-  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
++  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1);
+ }
+         break;
+-      case 142: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
++      case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ {
+-  yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy384, yymsp[0].minor.yy314);
++  yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 143: /* setlist ::= nm EQ expr */
++      case 148: /* setlist ::= nm EQ expr */
+ {
+-  yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy314);
+-  sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1);
++  yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
++  sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
+ }
+-  yymsp[-2].minor.yy322 = yylhsminor.yy322;
++  yymsp[-2].minor.yy420 = yylhsminor.yy420;
+         break;
+-      case 144: /* setlist ::= LP idlist RP EQ expr */
++      case 149: /* setlist ::= LP idlist RP EQ expr */
+ {
+-  yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy384, yymsp[0].minor.yy314);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 145: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
++      case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ {
+-  sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy4);
++  sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
+ }
+         break;
+-      case 146: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
++      case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ {
+-  sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy4);
++  sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
+ }
+         break;
+-      case 150: /* idlist_opt ::= LP idlist RP */
+-{yymsp[-2].minor.yy384 = yymsp[-1].minor.yy384;}
++      case 152: /* upsert ::= */
++{ yymsp[1].minor.yy340 = 0; }
+         break;
+-      case 151: /* idlist ::= idlist COMMA nm */
+-{yymsp[-2].minor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
++      case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
++{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);}
+         break;
+-      case 152: /* idlist ::= nm */
+-{yymsp[0].minor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
++      case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
++{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); }
+         break;
+-      case 153: /* expr ::= LP expr RP */
+-{yymsp[-2].minor.yy314 = yymsp[-1].minor.yy314;}
++      case 155: /* upsert ::= ON CONFLICT DO NOTHING */
++{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+         break;
+-      case 154: /* expr ::= ID|INDEXED */
+-      case 155: /* expr ::= JOIN_KW */ yytestcase(yyruleno==155);
+-{yymsp[0].minor.yy314=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 159: /* idlist_opt ::= LP idlist RP */
++{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
+         break;
+-      case 156: /* expr ::= nm DOT nm */
++      case 160: /* idlist ::= idlist COMMA nm */
++{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
++        break;
++      case 161: /* idlist ::= nm */
++{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
++        break;
++      case 162: /* expr ::= LP expr RP */
++{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;}
++        break;
++      case 163: /* expr ::= ID|INDEXED */
++      case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
++{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++        break;
++      case 165: /* expr ::= nm DOT nm */
+ {
+   Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+   Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+-  yylhsminor.yy314 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
++    sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
++  }
++  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ }
+-  yymsp[-2].minor.yy314 = yylhsminor.yy314;
++  yymsp[-2].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 157: /* expr ::= nm DOT nm DOT nm */
++      case 166: /* expr ::= nm DOT nm DOT nm */
+ {
+   Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
+   Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+   Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+   Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
+-  yylhsminor.yy314 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
++  if( IN_RENAME_OBJECT ){
++    sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
++    sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
++  }
++  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ }
+-  yymsp[-4].minor.yy314 = yylhsminor.yy314;
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 158: /* term ::= NULL|FLOAT|BLOB */
+-      case 159: /* term ::= STRING */ yytestcase(yyruleno==159);
+-{yymsp[0].minor.yy314=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
++      case 167: /* term ::= NULL|FLOAT|BLOB */
++      case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
++{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+         break;
+-      case 160: /* term ::= INTEGER */
++      case 169: /* term ::= INTEGER */
+ {
+-  yylhsminor.yy314 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
++  yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ }
+-  yymsp[0].minor.yy314 = yylhsminor.yy314;
++  yymsp[0].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 161: /* expr ::= VARIABLE */
++      case 170: /* expr ::= VARIABLE */
+ {
+   if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
+     u32 n = yymsp[0].minor.yy0.n;
+-    yymsp[0].minor.yy314 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+-    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy314, n);
++    yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
++    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
+   }else{
+     /* When doing a nested parse, one can include terms in an expression
+     ** that look like this:   #1 #2 ...  These terms refer to registers
+@@ -142928,146 +150238,154 @@
+     assert( t.n>=2 );
+     if( pParse->nested==0 ){
+       sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
+-      yymsp[0].minor.yy314 = 0;
++      yymsp[0].minor.yy18 = 0;
+     }else{
+-      yymsp[0].minor.yy314 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+-      if( yymsp[0].minor.yy314 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy314->iTable);
++      yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
++      if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
+     }
+   }
+ }
+         break;
+-      case 162: /* expr ::= expr COLLATE ID|STRING */
++      case 171: /* expr ::= expr COLLATE ID|STRING */
+ {
+-  yymsp[-2].minor.yy314 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy314, &yymsp[0].minor.yy0, 1);
++  yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
+ }
+         break;
+-      case 163: /* expr ::= CAST LP expr AS typetoken RP */
++      case 172: /* expr ::= CAST LP expr AS typetoken RP */
+ {
+-  yymsp[-5].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+-  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy314, yymsp[-3].minor.yy314, 0);
++  yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
++  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0);
+ }
+         break;
+-      case 164: /* expr ::= ID|INDEXED LP distinct exprlist RP */
++      case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ {
+-  if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+-    sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
+-  }
+-  yylhsminor.yy314 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+-  if( yymsp[-2].minor.yy4==SF_Distinct && yylhsminor.yy314 ){
+-    yylhsminor.yy314->flags |= EP_Distinct;
+-  }
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+ }
+-  yymsp[-4].minor.yy314 = yylhsminor.yy314;
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 165: /* expr ::= ID|INDEXED LP STAR RP */
++      case 174: /* expr ::= ID|INDEXED LP STAR RP */
+ {
+-  yylhsminor.yy314 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ }
+-  yymsp[-3].minor.yy314 = yylhsminor.yy314;
++  yymsp[-3].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 166: /* term ::= CTIME_KW */
++      case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ {
+-  yylhsminor.yy314 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
++  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ }
+-  yymsp[0].minor.yy314 = yylhsminor.yy314;
++  yymsp[-5].minor.yy18 = yylhsminor.yy18;
+         break;
+-      case 167: /* expr ::= LP nexprlist COMMA expr RP */
++      case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
+ {
+-  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy314);
+-  yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+-  if( yymsp[-4].minor.yy314 ){
+-    yymsp[-4].minor.yy314->x.pList = pList;
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
++  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
++}
++  yymsp[-4].minor.yy18 = yylhsminor.yy18;
++        break;
++      case 177: /* term ::= CTIME_KW */
++{
++  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
++}
++  yymsp[0].minor.yy18 = yylhsminor.yy18;
++        break;
++      case 178: /* expr ::= LP nexprlist COMMA expr RP */
++{
++  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->x.pList = pList;
+   }else{
+     sqlite3ExprListDelete(pParse->db, pList);
+   }
+ }
+         break;
+-      case 168: /* expr ::= expr AND expr */
+-      case 169: /* expr ::= expr OR expr */ yytestcase(yyruleno==169);
+-      case 170: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==170);
+-      case 171: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==171);
+-      case 172: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==172);
+-      case 173: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==173);
+-      case 174: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==174);
+-      case 175: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==175);
+-{yymsp[-2].minor.yy314=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);}
++      case 179: /* expr ::= expr AND expr */
++      case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
++      case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
++      case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
++      case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
++      case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
++      case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
++      case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
++{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+         break;
+-      case 176: /* likeop ::= NOT LIKE_KW|MATCH */
++      case 187: /* 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 177: /* expr ::= expr likeop expr */
++      case 188: /* 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.yy314);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy314);
+-  yymsp[-2].minor.yy314 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
+-  if( bNot ) yymsp[-2].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy314, 0);
+-  if( yymsp[-2].minor.yy314 ) yymsp[-2].minor.yy314->flags |= EP_InfixFunc;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18);
++  yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
++  if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0);
++  if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 178: /* expr ::= expr likeop expr ESCAPE expr */
++      case 189: /* 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.yy314);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy314);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy314);
+-  yymsp[-4].minor.yy314 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
+-  if( bNot ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
+-  if( yymsp[-4].minor.yy314 ) yymsp[-4].minor.yy314->flags |= EP_InfixFunc;
++  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
++  if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc;
+ }
+         break;
+-      case 179: /* expr ::= expr ISNULL|NOTNULL */
+-{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy314,0);}
++      case 190: /* expr ::= expr ISNULL|NOTNULL */
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
+         break;
+-      case 180: /* expr ::= expr NOT NULL */
+-{yymsp[-2].minor.yy314 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy314,0);}
++      case 191: /* expr ::= expr NOT NULL */
++{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
+         break;
+-      case 181: /* expr ::= expr IS expr */
++      case 192: /* expr ::= expr IS expr */
+ {
+-  yymsp[-2].minor.yy314 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);
+-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy314, yymsp[-2].minor.yy314, TK_ISNULL);
++  yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL);
+ }
+         break;
+-      case 182: /* expr ::= expr IS NOT expr */
++      case 193: /* expr ::= expr IS NOT expr */
+ {
+-  yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy314,yymsp[0].minor.yy314);
+-  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy314, yymsp[-3].minor.yy314, TK_NOTNULL);
++  yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18);
++  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL);
+ }
+         break;
+-      case 183: /* expr ::= NOT expr */
+-      case 184: /* expr ::= BITNOT expr */ yytestcase(yyruleno==184);
+-{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy314, 0);/*A-overwrites-B*/}
++      case 194: /* expr ::= NOT expr */
++      case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
++{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/}
+         break;
+-      case 185: /* expr ::= MINUS expr */
+-{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy314, 0);}
++      case 196: /* expr ::= PLUS|MINUS expr */
++{
++  yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
++  /*A-overwrites-B*/
++}
+         break;
+-      case 186: /* expr ::= PLUS expr */
+-{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy314, 0);}
++      case 197: /* between_op ::= BETWEEN */
++      case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
++{yymsp[0].minor.yy70 = 0;}
+         break;
+-      case 187: /* between_op ::= BETWEEN */
+-      case 190: /* in_op ::= IN */ yytestcase(yyruleno==190);
+-{yymsp[0].minor.yy4 = 0;}
+-        break;
+-      case 189: /* expr ::= expr between_op expr AND expr */
++      case 199: /* expr ::= expr between_op expr AND expr */
+ {
+-  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy314);
+-  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy314);
+-  yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy314, 0);
+-  if( yymsp[-4].minor.yy314 ){
+-    yymsp[-4].minor.yy314->x.pList = pList;
++  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->x.pList = pList;
+   }else{
+     sqlite3ExprListDelete(pParse->db, pList);
+   } 
+-  if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
++  if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ }
+         break;
+-      case 192: /* expr ::= expr in_op LP exprlist RP */
++      case 202: /* expr ::= expr in_op LP exprlist RP */
+ {
+-    if( yymsp[-1].minor.yy322==0 ){
++    if( yymsp[-1].minor.yy420==0 ){
+       /* Expressions of the form
+       **
+       **      expr1 IN ()
+@@ -143076,9 +150394,9 @@
+       ** simplify to constants 0 (false) and 1 (true), respectively,
+       ** regardless of the value of expr1.
+       */
+-      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy314);
+-      yymsp[-4].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy4],1);
+-    }else if( yymsp[-1].minor.yy322->nExpr==1 ){
++      sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18);
++      yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1);
++    }else if( yymsp[-1].minor.yy420->nExpr==1 ){
+       /* Expressions of the form:
+       **
+       **      expr1 IN (?1)
+@@ -143095,9 +150413,9 @@
+       ** affinity or the collating sequence to use for comparison.  Otherwise,
+       ** the semantics would be subtly different from IN or NOT IN.
+       */
+-      Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
+-      yymsp[-1].minor.yy322->a[0].pExpr = 0;
+-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
++      Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr;
++      yymsp[-1].minor.yy420->a[0].pExpr = 0;
++      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+       /* pRHS cannot be NULL because a malloc error would have been detected
+       ** before now and control would have never reached this point */
+       if( ALWAYS(pRHS) ){
+@@ -143104,186 +150422,190 @@
+         pRHS->flags &= ~EP_Collate;
+         pRHS->flags |= EP_Generic;
+       }
+-      yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, yymsp[-3].minor.yy4 ? TK_NE : TK_EQ, yymsp[-4].minor.yy314, pRHS);
++      yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
+     }else{
+-      yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+-      if( yymsp[-4].minor.yy314 ){
+-        yymsp[-4].minor.yy314->x.pList = yymsp[-1].minor.yy322;
+-        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy314);
++      yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++      if( yymsp[-4].minor.yy18 ){
++        yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420;
++        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+       }else{
+-        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
++        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+       }
+-      if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
++      if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+     }
+   }
+         break;
+-      case 193: /* expr ::= LP select RP */
++      case 203: /* expr ::= LP select RP */
+ {
+-    yymsp[-2].minor.yy314 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+-    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy314, yymsp[-1].minor.yy387);
++    yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
+   }
+         break;
+-      case 194: /* expr ::= expr in_op LP select RP */
++      case 204: /* expr ::= expr in_op LP select RP */
+ {
+-    yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+-    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy314, yymsp[-1].minor.yy387);
+-    if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
++    yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489);
++    if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+   }
+         break;
+-      case 195: /* expr ::= expr in_op nm dbnm paren_exprlist */
++      case 205: /* 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);
+-    if( yymsp[0].minor.yy322 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
+-    yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+-    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy314, pSelect);
+-    if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
++    if( yymsp[0].minor.yy420 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420);
++    yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
++    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect);
++    if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+   }
+         break;
+-      case 196: /* expr ::= EXISTS LP select RP */
++      case 206: /* expr ::= EXISTS LP select RP */
+ {
+     Expr *p;
+-    p = yymsp[-3].minor.yy314 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+-    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy387);
++    p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
++    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
+   }
+         break;
+-      case 197: /* expr ::= CASE case_operand case_exprlist case_else END */
++      case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
+ {
+-  yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0);
+-  if( yymsp[-4].minor.yy314 ){
+-    yymsp[-4].minor.yy314->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
+-    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy314);
++  yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0);
++  if( yymsp[-4].minor.yy18 ){
++    yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420;
++    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+   }else{
+-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
+-    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
++    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
++    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
+   }
+ }
+         break;
+-      case 198: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
++      case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ {
+-  yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy314);
+-  yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy314);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
++  yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 199: /* case_exprlist ::= WHEN expr THEN expr */
++      case 209: /* case_exprlist ::= WHEN expr THEN expr */
+ {
+-  yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy314);
+-  yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy314);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
++  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 202: /* case_operand ::= expr */
+-{yymsp[0].minor.yy314 = yymsp[0].minor.yy314; /*A-overwrites-X*/}
++      case 212: /* case_operand ::= expr */
++{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
+         break;
+-      case 205: /* nexprlist ::= nexprlist COMMA expr */
+-{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy314);}
++      case 215: /* nexprlist ::= nexprlist COMMA expr */
++{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
+         break;
+-      case 206: /* nexprlist ::= expr */
+-{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy314); /*A-overwrites-Y*/}
++      case 216: /* nexprlist ::= expr */
++{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
+         break;
+-      case 208: /* paren_exprlist ::= LP exprlist RP */
+-      case 213: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==213);
+-{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
++      case 218: /* paren_exprlist ::= LP exprlist RP */
++      case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
++{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;}
+         break;
+-      case 209: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
++      case 219: /* 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.yy322, yymsp[-10].minor.yy4,
+-                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4, SQLITE_IDXTYPE_APPDEF);
++                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70,
++                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
++  if( IN_RENAME_OBJECT && pParse->pNewIndex ){
++    sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
++  }
+ }
+         break;
+-      case 210: /* uniqueflag ::= UNIQUE */
+-      case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250);
+-{yymsp[0].minor.yy4 = OE_Abort;}
++      case 220: /* uniqueflag ::= UNIQUE */
++      case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
++{yymsp[0].minor.yy70 = OE_Abort;}
+         break;
+-      case 211: /* uniqueflag ::= */
+-{yymsp[1].minor.yy4 = OE_None;}
++      case 221: /* uniqueflag ::= */
++{yymsp[1].minor.yy70 = OE_None;}
+         break;
+-      case 214: /* eidlist ::= eidlist COMMA nm collate sortorder */
++      case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ {
+-  yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
++  yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
+ }
+         break;
+-      case 215: /* eidlist ::= nm collate sortorder */
++      case 225: /* eidlist ::= nm collate sortorder */
+ {
+-  yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4); /*A-overwrites-Y*/
++  yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
+ }
+         break;
+-      case 218: /* cmd ::= DROP INDEX ifexists fullname */
+-{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
++      case 228: /* cmd ::= DROP INDEX ifexists fullname */
++{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
+         break;
+-      case 219: /* cmd ::= VACUUM */
++      case 229: /* cmd ::= VACUUM */
+ {sqlite3Vacuum(pParse,0);}
+         break;
+-      case 220: /* cmd ::= VACUUM nm */
++      case 230: /* cmd ::= VACUUM nm */
+ {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 221: /* cmd ::= PRAGMA nm dbnm */
++      case 231: /* cmd ::= PRAGMA nm dbnm */
+ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
+         break;
+-      case 222: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
++      case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
+         break;
+-      case 223: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
++      case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
+         break;
+-      case 224: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
++      case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
+         break;
+-      case 225: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
++      case 235: /* 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 228: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
++      case 238: /* 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.yy203, &all);
++  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all);
+ }
+         break;
+-      case 229: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
++      case 239: /* 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.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
++  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70);
+   yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
+ }
+         break;
+-      case 230: /* trigger_time ::= BEFORE|AFTER */
+-{ yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-X*/ }
++      case 240: /* trigger_time ::= BEFORE|AFTER */
++{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
+         break;
+-      case 231: /* trigger_time ::= INSTEAD OF */
+-{ yymsp[-1].minor.yy4 = TK_INSTEAD;}
++      case 241: /* trigger_time ::= INSTEAD OF */
++{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
+         break;
+-      case 232: /* trigger_time ::= */
+-{ yymsp[1].minor.yy4 = TK_BEFORE; }
++      case 242: /* trigger_time ::= */
++{ yymsp[1].minor.yy70 = TK_BEFORE; }
+         break;
+-      case 233: /* trigger_event ::= DELETE|INSERT */
+-      case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234);
+-{yymsp[0].minor.yy90.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy90.b = 0;}
++      case 243: /* trigger_event ::= DELETE|INSERT */
++      case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244);
++{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;}
+         break;
+-      case 235: /* trigger_event ::= UPDATE OF idlist */
+-{yymsp[-2].minor.yy90.a = TK_UPDATE; yymsp[-2].minor.yy90.b = yymsp[0].minor.yy384;}
++      case 245: /* trigger_event ::= UPDATE OF idlist */
++{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
+         break;
+-      case 236: /* when_clause ::= */
+-      case 255: /* key_opt ::= */ yytestcase(yyruleno==255);
+-{ yymsp[1].minor.yy314 = 0; }
++      case 246: /* when_clause ::= */
++      case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
++      case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
++{ yymsp[1].minor.yy18 = 0; }
+         break;
+-      case 237: /* when_clause ::= WHEN expr */
+-      case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256);
+-{ yymsp[-1].minor.yy314 = yymsp[0].minor.yy314; }
++      case 247: /* when_clause ::= WHEN expr */
++      case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
++{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
+         break;
+-      case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
++      case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ {
+-  assert( yymsp[-2].minor.yy203!=0 );
+-  yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
+-  yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
++  assert( yymsp[-2].minor.yy207!=0 );
++  yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207;
++  yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ }
+         break;
+-      case 239: /* trigger_cmd_list ::= trigger_cmd SEMI */
++      case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ { 
+-  assert( yymsp[-1].minor.yy203!=0 );
+-  yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
++  assert( yymsp[-1].minor.yy207!=0 );
++  yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ }
+         break;
+-      case 240: /* trnm ::= nm DOT nm */
++      case 250: /* trnm ::= nm DOT nm */
+ {
+   yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
+   sqlite3ErrorMsg(pParse, 
+@@ -143291,7 +150613,7 @@
+         "statements within triggers");
+ }
+         break;
+-      case 241: /* tridxby ::= INDEXED BY nm */
++      case 251: /* tridxby ::= INDEXED BY nm */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
+@@ -143298,7 +150620,7 @@
+         "within triggers");
+ }
+         break;
+-      case 242: /* tridxby ::= NOT INDEXED */
++      case 252: /* tridxby ::= NOT INDEXED */
+ {
+   sqlite3ErrorMsg(pParse,
+         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
+@@ -143305,180 +150627,292 @@
+         "within triggers");
+ }
+         break;
+-      case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+-{yylhsminor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy314, yymsp[-6].minor.yy4, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy336);}
+-  yymsp[-7].minor.yy203 = yylhsminor.yy203;
++      case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
++{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);}
++  yymsp[-7].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 244: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt */
+-{yylhsminor.yy203 = sqlite3TriggerInsertStep(pParse->db,&yymsp[-3].minor.yy0,yymsp[-2].minor.yy384,yymsp[-1].minor.yy387,yymsp[-5].minor.yy4,yymsp[-6].minor.yy336,yymsp[0].minor.yy336);/*yylhsminor.yy203-overwrites-yymsp[-5].minor.yy4*/}
+-  yymsp[-6].minor.yy203 = yylhsminor.yy203;
++      case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
++{
++   yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/
++}
++  yymsp[-7].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+-{yylhsminor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy314, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy336);}
+-  yymsp[-5].minor.yy203 = yylhsminor.yy203;
++      case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
++{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);}
++  yymsp[-5].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 246: /* trigger_cmd ::= scanpt select scanpt */
+-{yylhsminor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy387, yymsp[-2].minor.yy336, yymsp[0].minor.yy336); /*yylhsminor.yy203-overwrites-yymsp[-1].minor.yy387*/}
+-  yymsp[-2].minor.yy203 = yylhsminor.yy203;
++      case 256: /* trigger_cmd ::= scanpt select scanpt */
++{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/}
++  yymsp[-2].minor.yy207 = yylhsminor.yy207;
+         break;
+-      case 247: /* expr ::= RAISE LP IGNORE RP */
++      case 257: /* expr ::= RAISE LP IGNORE RP */
+ {
+-  yymsp[-3].minor.yy314 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
+-  if( yymsp[-3].minor.yy314 ){
+-    yymsp[-3].minor.yy314->affinity = OE_Ignore;
++  yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
++  if( yymsp[-3].minor.yy18 ){
++    yymsp[-3].minor.yy18->affinity = OE_Ignore;
+   }
+ }
+         break;
+-      case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */
++      case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ {
+-  yymsp[-5].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); 
+-  if( yymsp[-5].minor.yy314 ) {
+-    yymsp[-5].minor.yy314->affinity = (char)yymsp[-3].minor.yy4;
++  yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); 
++  if( yymsp[-5].minor.yy18 ) {
++    yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70;
+   }
+ }
+         break;
+-      case 249: /* raisetype ::= ROLLBACK */
+-{yymsp[0].minor.yy4 = OE_Rollback;}
++      case 259: /* raisetype ::= ROLLBACK */
++{yymsp[0].minor.yy70 = OE_Rollback;}
+         break;
+-      case 251: /* raisetype ::= FAIL */
+-{yymsp[0].minor.yy4 = OE_Fail;}
++      case 261: /* raisetype ::= FAIL */
++{yymsp[0].minor.yy70 = OE_Fail;}
+         break;
+-      case 252: /* cmd ::= DROP TRIGGER ifexists fullname */
++      case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
+ {
+-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
++  sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
+ }
+         break;
+-      case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
++      case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ {
+-  sqlite3Attach(pParse, yymsp[-3].minor.yy314, yymsp[-1].minor.yy314, yymsp[0].minor.yy314);
++  sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 254: /* cmd ::= DETACH database_kw_opt expr */
++      case 264: /* cmd ::= DETACH database_kw_opt expr */
+ {
+-  sqlite3Detach(pParse, yymsp[0].minor.yy314);
++  sqlite3Detach(pParse, yymsp[0].minor.yy18);
+ }
+         break;
+-      case 257: /* cmd ::= REINDEX */
++      case 267: /* cmd ::= REINDEX */
+ {sqlite3Reindex(pParse, 0, 0);}
+         break;
+-      case 258: /* cmd ::= REINDEX nm dbnm */
++      case 268: /* cmd ::= REINDEX nm dbnm */
+ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
+         break;
+-      case 259: /* cmd ::= ANALYZE */
++      case 269: /* cmd ::= ANALYZE */
+ {sqlite3Analyze(pParse, 0, 0);}
+         break;
+-      case 260: /* cmd ::= ANALYZE nm dbnm */
++      case 270: /* 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 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ {
+-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
++  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
+ }
+         break;
+-      case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
++      case 272: /* 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 273: /* add_column_fullname ::= fullname */
+ {
+   disableLookaside(pParse);
+-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
++  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+ }
+         break;
+-      case 264: /* cmd ::= create_vtab */
++      case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
++{
++  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
++}
++        break;
++      case 275: /* cmd ::= create_vtab */
+ {sqlite3VtabFinishParse(pParse,0);}
+         break;
+-      case 265: /* cmd ::= create_vtab LP vtabarglist RP */
++      case 276: /* 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 277: /* 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.yy4);
++    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70);
+ }
+         break;
+-      case 267: /* vtabarg ::= */
++      case 278: /* 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 279: /* vtabargtoken ::= ANY */
++      case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
++      case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
+ {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
+         break;
+-      case 271: /* with ::= WITH wqlist */
+-      case 272: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==272);
+-{ sqlite3WithPush(pParse, yymsp[0].minor.yy451, 1); }
++      case 282: /* with ::= WITH wqlist */
++      case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
++{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+         break;
+-      case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
++      case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ {
+-  yymsp[-5].minor.yy451 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387); /*A-overwrites-X*/
++  yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/
+ }
+         break;
+-      case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
++      case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ {
+-  yymsp[-7].minor.yy451 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy451, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
++  yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489);
+ }
+         break;
++      case 286: /* windowdefn_list ::= windowdefn */
++{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
++  yymsp[0].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
++{
++  assert( yymsp[0].minor.yy327!=0 );
++  yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327;
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 288: /* windowdefn ::= nm AS window */
++{
++  if( ALWAYS(yymsp[0].minor.yy327) ){
++    yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
++  }
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
++{
++  yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327;
++  if( ALWAYS(yymsp[-4].minor.yy327) ){
++    yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420;
++    yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420;
++  }
++}
++        break;
++      case 290: /* part_opt ::= PARTITION BY nexprlist */
++{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; }
++        break;
++      case 291: /* part_opt ::= */
++{ yymsp[1].minor.yy420 = 0; }
++        break;
++      case 292: /* frame_opt ::= */
++{ 
++  yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
++}
++        break;
++      case 293: /* frame_opt ::= range_or_rows frame_bound_s */
++{ 
++  yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0);
++}
++  yymsp[-1].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
++{ 
++  yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr);
++}
++  yymsp[-4].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 295: /* range_or_rows ::= RANGE */
++{ yymsp[0].minor.yy70 = TK_RANGE; }
++        break;
++      case 296: /* range_or_rows ::= ROWS */
++{ yymsp[0].minor.yy70 = TK_ROWS;  }
++        break;
++      case 297: /* frame_bound_s ::= frame_bound */
++      case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299);
++{ yylhsminor.yy119 = yymsp[0].minor.yy119; }
++  yymsp[0].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */
++      case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300);
++{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;}
++        break;
++      case 301: /* frame_bound ::= expr PRECEDING */
++{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
++  yymsp[-1].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 302: /* frame_bound ::= CURRENT ROW */
++{ yymsp[-1].minor.yy119.eType = TK_CURRENT  ; yymsp[-1].minor.yy119.pExpr = 0; }
++        break;
++      case 303: /* frame_bound ::= expr FOLLOWING */
++{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
++  yymsp[-1].minor.yy119 = yylhsminor.yy119;
++        break;
++      case 304: /* window_clause ::= WINDOW windowdefn_list */
++{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; }
++        break;
++      case 305: /* over_clause ::= filter_opt OVER window */
++{
++  yylhsminor.yy327 = yymsp[0].minor.yy327;
++  assert( yylhsminor.yy327!=0 );
++  yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 306: /* over_clause ::= filter_opt OVER nm */
++{
++  yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
++  if( yylhsminor.yy327 ){
++    yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
++    yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
++  }else{
++    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
++  }
++}
++  yymsp[-2].minor.yy327 = yylhsminor.yy327;
++        break;
++      case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
++{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
++        break;
+       default:
+-      /* (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);
+-      /* (319) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==319);
+-      /* (320) trnm ::= nm */ yytestcase(yyruleno==320);
+-      /* (321) tridxby ::= */ yytestcase(yyruleno==321);
+-      /* (322) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==322);
+-      /* (323) database_kw_opt ::= */ yytestcase(yyruleno==323);
+-      /* (324) kwcolumn_opt ::= */ yytestcase(yyruleno==324);
+-      /* (325) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==325);
+-      /* (326) vtabarglist ::= vtabarg */ yytestcase(yyruleno==326);
+-      /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==327);
+-      /* (328) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==328);
+-      /* (329) anylist ::= */ yytestcase(yyruleno==329);
+-      /* (330) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==330);
+-      /* (331) anylist ::= anylist ANY */ yytestcase(yyruleno==331);
+-      /* (332) with ::= */ yytestcase(yyruleno==332);
++      /* (309) input ::= cmdlist */ yytestcase(yyruleno==309);
++      /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310);
++      /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311);
++      /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312);
++      /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313);
++      /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314);
++      /* (315) trans_opt ::= */ yytestcase(yyruleno==315);
++      /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316);
++      /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317);
++      /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318);
++      /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319);
++      /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320);
++      /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321);
++      /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322);
++      /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323);
++      /* (324) nm ::= STRING */ yytestcase(yyruleno==324);
++      /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325);
++      /* (326) typetoken ::= typename */ yytestcase(yyruleno==326);
++      /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327);
++      /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328);
++      /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329);
++      /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330);
++      /* (331) carglist ::= */ yytestcase(yyruleno==331);
++      /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332);
++      /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333);
++      /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334);
++      /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335);
++      /* (336) tconscomma ::= */ yytestcase(yyruleno==336);
++      /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337);
++      /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338);
++      /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339);
++      /* (340) oneselect ::= values */ yytestcase(yyruleno==340);
++      /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341);
++      /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342);
++      /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343);
++      /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344);
++      /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345);
++      /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346);
++      /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347);
++      /* (348) nmnum ::= ON */ yytestcase(yyruleno==348);
++      /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349);
++      /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350);
++      /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351);
++      /* (352) foreach_clause ::= */ yytestcase(yyruleno==352);
++      /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353);
++      /* (354) trnm ::= nm */ yytestcase(yyruleno==354);
++      /* (355) tridxby ::= */ yytestcase(yyruleno==355);
++      /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356);
++      /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357);
++      /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358);
++      /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359);
++      /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360);
++      /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361);
++      /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362);
++      /* (363) anylist ::= */ yytestcase(yyruleno==363);
++      /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364);
++      /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365);
++      /* (366) with ::= */ yytestcase(yyruleno==366);
+         break;
+ /********** End reduce actions ************************************************/
+   };
+@@ -143499,6 +150933,7 @@
+   yymsp->stateno = (YYACTIONTYPE)yyact;
+   yymsp->major = (YYCODETYPE)yygoto;
+   yyTraceShift(yypParser, yyact, "... then shift");
++  return yyact;
+ }
+ 
+ /*
+@@ -143508,7 +150943,8 @@
+ static void yy_parse_failed(
+   yyParser *yypParser           /* The parser */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+@@ -143519,7 +150955,8 @@
+   ** parser fails */
+ /************ Begin %parse_failure code ***************************************/
+ /************ End %parse_failure code *****************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ #endif /* YYNOERRORRECOVERY */
+ 
+@@ -143531,7 +150968,8 @@
+   int yymajor,                   /* The major type of the error token */
+   sqlite3ParserTOKENTYPE yyminor         /* The minor type of the error token */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #define TOKEN yyminor
+ /************ Begin %syntax_error code ****************************************/
+ 
+@@ -143542,7 +150980,8 @@
+     sqlite3ErrorMsg(pParse, "incomplete input");
+   }
+ /************ End %syntax_error code ******************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ 
+ /*
+@@ -143551,7 +150990,8 @@
+ static void yy_accept(
+   yyParser *yypParser           /* The parser */
+ ){
+-  sqlite3ParserARG_FETCH;
++  sqlite3ParserARG_FETCH
++  sqlite3ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+@@ -143565,7 +151005,8 @@
+   ** parser accepts */
+ /*********** Begin %parse_accept code *****************************************/
+ /*********** End %parse_accept code *******************************************/
+-  sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3ParserCTX_STORE
+ }
+ 
+ /* The main parser program.
+@@ -143594,7 +151035,7 @@
+   sqlite3ParserARG_PDECL               /* Optional %extra_argument parameter */
+ ){
+   YYMINORTYPE yyminorunion;
+-  unsigned int yyact;   /* The parser action. */
++  YYACTIONTYPE yyact;   /* The parser action. */
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   int yyendofinput;     /* True if we are at the end of input */
+ #endif
+@@ -143601,38 +151042,40 @@
+ #ifdef YYERRORSYMBOL
+   int yyerrorhit = 0;   /* True if yymajor has invoked an error */
+ #endif
+-  yyParser *yypParser;  /* The parser */
++  yyParser *yypParser = (yyParser*)yyp;  /* The parser */
++  sqlite3ParserCTX_FETCH
++  sqlite3ParserARG_STORE
+ 
+-  yypParser = (yyParser*)yyp;
+   assert( yypParser->yytos!=0 );
+ #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
+   yyendofinput = (yymajor==0);
+ #endif
+-  sqlite3ParserARG_STORE;
+ 
++  yyact = yypParser->yytos->stateno;
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+-    int stateno = yypParser->yytos->stateno;
+-    if( stateno < YY_MIN_REDUCE ){
++    if( yyact < YY_MIN_REDUCE ){
+       fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
+-              yyTracePrompt,yyTokenName[yymajor],stateno);
++              yyTracePrompt,yyTokenName[yymajor],yyact);
+     }else{
+       fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+-              yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE);
++              yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE);
+     }
+   }
+ #endif
+ 
+   do{
+-    yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
++    assert( yyact==yypParser->yytos->stateno );
++    yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
+     if( yyact >= YY_MIN_REDUCE ){
+-      yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor);
++      yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,
++                        yyminor sqlite3ParserCTX_PARAM);
+     }else if( yyact <= YY_MAX_SHIFTREDUCE ){
+-      yy_shift(yypParser,yyact,yymajor,yyminor);
++      yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
+ #ifndef YYNOERRORRECOVERY
+       yypParser->yyerrcnt--;
+ #endif
+-      yymajor = YYNOCODE;
++      break;
+     }else if( yyact==YY_ACCEPT_ACTION ){
+       yypParser->yytos--;
+       yy_accept(yypParser);
+@@ -143683,10 +151126,9 @@
+         yymajor = YYNOCODE;
+       }else{
+         while( yypParser->yytos >= yypParser->yystack
+-            && yymx != YYERRORSYMBOL
+             && (yyact = yy_find_reduce_action(
+                         yypParser->yytos->stateno,
+-                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
++                        YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
+         ){
+           yy_pop_parser_stack(yypParser);
+         }
+@@ -143703,6 +151145,8 @@
+       }
+       yypParser->yyerrcnt = 3;
+       yyerrorhit = 1;
++      if( yymajor==YYNOCODE ) break;
++      yyact = yypParser->yytos->stateno;
+ #elif defined(YYNOERRORRECOVERY)
+       /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+       ** do any kind of error recovery.  Instead, simply invoke the syntax
+@@ -143713,8 +151157,7 @@
+       */
+       yy_syntax_error(yypParser,yymajor, yyminor);
+       yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+-      yymajor = YYNOCODE;
+-      
++      break;
+ #else  /* YYERRORSYMBOL is not defined */
+       /* This is what we do if the grammar does not define ERROR:
+       **
+@@ -143736,10 +151179,10 @@
+         yypParser->yyerrcnt = -1;
+ #endif
+       }
+-      yymajor = YYNOCODE;
++      break;
+ #endif
+     }
+-  }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack );
++  }while( yypParser->yytos>yypParser->yystack );
+ #ifndef NDEBUG
+   if( yyTraceFILE ){
+     yyStackEntry *i;
+@@ -143755,6 +151198,21 @@
+   return;
+ }
+ 
++/*
++** Return the fallback token corresponding to canonical token iToken, or
++** 0 if iToken has no fallback.
++*/
++SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){
++#ifdef YYFALLBACK
++  if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){
++    return yyFallback[iToken];
++  }
++#else
++  (void)iToken;
++#endif
++  return 0;
++}
++
+ /************** End of parse.c ***********************************************/
+ /************** Begin file tokenize.c ****************************************/
+ /*
+@@ -143813,11 +151271,12 @@
+ #define CC_TILDA     25    /* '~' */
+ #define CC_DOT       26    /* '.' */
+ #define CC_ILLEGAL   27    /* Illegal character */
++#define CC_NUL       28    /* 0x00 */
+ 
+ static const unsigned char aiClass[] = {
+ #ifdef SQLITE_ASCII
+ /*         x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xa  xb  xc  xd  xe  xf */
+-/* 0x */   27, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
++/* 0x */   28, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7, 27,  7,  7, 27, 27,
+ /* 1x */   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ /* 2x */    7, 15,  8,  5,  4, 22, 24,  8, 17, 18, 21, 20, 23, 11, 26, 16,
+ /* 3x */    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  5, 19, 12, 14, 13,  6,
+@@ -143916,19 +151375,20 @@
+ ** is substantially reduced.  This is important for embedded applications
+ ** on platforms with limited memory.
+ */
+-/* Hash score: 182 */
+-/* zKWText[] encodes 834 bytes of keyword text in 554 bytes */
++/* Hash score: 208 */
++/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */
+ /*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
+ /*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
+ /*   XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY         */
+-/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE         */
+-/*   BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH     */
+-/*   IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN     */
+-/*   WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT         */
+-/*   CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL        */
+-/*   FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING        */
+-/*   VACUUMVIEWINITIALLY                                                */
+-static const char zKWText[553] = {
++/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN      */
++/*   OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH           */
++/*   IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT     */
++/*   WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST         */
++/*   COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED         */
++/*   ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL       */
++/*   ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW      */
++/*   INDOWINITIALLYPRIMARY                                              */
++static const char zKWText[613] = {
+   'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
+   'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
+   'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
+@@ -143941,83 +151401,90 @@
+   'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
+   'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
+   'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
+-  'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
+-  'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
+-  'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
+-  'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
+-  'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
+-  'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
+-  'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
+-  'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
+-  'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
+-  'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
+-  'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
+-  'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
+-  'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
+-  'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
+-  'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
+-  'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
+-  'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
+-  'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
+-  'V','I','E','W','I','N','I','T','I','A','L','L','Y',
++  'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W',
++  'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A',
++  'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
++  'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
++  'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
++  'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A',
++  'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
++  'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O',
++  'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A',
++  'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T',
++  'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C',
++  'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C',
++  'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E',
++  'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R',
++  'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E',
++  'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A',
++  'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L',
++  'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R',
++  'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C',
++  'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O',
++  'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N',
++  'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R',
++  'Y',
+ };
+ /* aKWHash[i] is the hash value for the i-th keyword */
+ static const unsigned char aKWHash[127] = {
+-    76, 105, 117,  74,   0,  45,   0,   0,  82,   0,  77,   0,   0,
+-    42,  12,  78,  15,   0, 116,  85,  54, 112,   0,  19,   0,   0,
+-   121,   0, 119, 115,   0,  22,  93,   0,   9,   0,   0,  70,  71,
+-     0,  69,   6,   0,  48,  90, 102,   0, 118, 101,   0,   0,  44,
+-     0, 103,  24,   0,  17,   0, 122,  53,  23,   0,   5, 110,  25,
+-    96,   0,   0, 124, 106,  60, 123,  57,  28,  55,   0,  91,   0,
+-   100,  26,   0,  99,   0,   0,   0,  95,  92,  97,  88, 109,  14,
+-    39, 108,   0,  81,   0,  18,  89, 111,  32,   0, 120,  80, 113,
+-    62,  46,  84,   0,   0,  94,  40,  59, 114,   0,  36,   0,   0,
+-    29,   0,  86,  63,  64,   0,  20,  61,   0,  56,
++    74, 109, 124,  72, 106,  45,   0,   0,  81,   0,  76,  61,   0,
++    42,  12,  77,  15,   0, 123,  84,  54, 118, 125,  19,   0,   0,
++   130,   0, 128, 121,   0,  22,  96,   0,   9,   0,   0, 115,  69,
++     0,  67,   6,   0,  48,  93, 136,   0, 126, 104,   0,   0,  44,
++     0, 107,  24,   0,  17,   0, 131,  53,  23,   0,   5,  62, 132,
++    99,   0,   0, 135, 110,  60, 134,  57, 113,  55,   0,  94,   0,
++   103,  26,   0, 102,   0,   0,   0,  98,  95, 100, 105, 117,  14,
++    39, 116,   0,  80,   0, 133, 114,  92,  59,   0, 129,  79, 119,
++    86,  46,  83,   0,   0,  97,  40, 122, 120,   0, 127,   0,   0,
++    29,   0,  89,  87,  88,   0,  20,  85, 111,  56,
+ };
+ /* aKWNext[] forms the hash collision chain.  If aKWHash[i]==0
+ ** then the i-th keyword has no more hash collisions.  Otherwise,
+ ** the next keyword with the same hash is aKWHash[i]-1. */
+-static const unsigned char aKWNext[124] = {
++static const unsigned char aKWNext[136] = {
+      0,   0,   0,   0,   4,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   2,   0,   0,   0,   0,   0,   0,  13,   0,   0,   0,   0,
+      0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,  33,   0,  21,   0,   0,   0,   0,   0,  50,
+-     0,  43,   3,  47,   0,   0,   0,   0,  30,   0,  58,   0,  38,
+-     0,   0,   0,   1,  66,   0,   0,  67,   0,  41,   0,   0,   0,
+-     0,   0,   0,  49,  65,   0,   0,   0,   0,  31,  52,  16,  34,
+-    10,   0,   0,   0,   0,   0,   0,   0,  11,  72,  79,   0,   8,
+-     0, 104,  98,   0, 107,   0,  87,   0,  75,  51,   0,  27,  37,
+-    73,  83,   0,  35,  68,   0,   0,
++     0,  43,   3,  47,   0,   0,  32,   0,   0,   0,   0,   0,   0,
++     0,   1,  64,   0,   0,  65,   0,  41,   0,  38,   0,   0,   0,
++     0,   0,  49,  75,   0,   0,  30,   0,  58,   0,   0,   0,  31,
++    63,  16,  34,  10,   0,   0,   0,   0,   0,   0,   0,  11,  70,
++    91,   0,   0,   8,   0, 108,   0, 101,  28,  52,  68,   0, 112,
++     0,  73,  51,   0,  90,  27,  37,   0,  71,  36,  82,   0,  35,
++    66,  25,  18,   0,   0,  78,
+ };
+ /* aKWLen[i] is the length (in bytes) of the i-th keyword */
+-static const unsigned char aKWLen[124] = {
++static const unsigned char aKWLen[136] = {
+      7,   7,   5,   4,   6,   4,   5,   3,   6,   7,   3,   6,   6,
+      7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   6,
+     11,   6,   2,   7,   5,   5,   9,   6,   9,   9,   7,  10,  10,
+      4,   6,   2,   3,   9,   4,   2,   6,   5,   7,   4,   5,   7,
+-     6,   6,   5,   6,   5,   5,   9,   7,   7,   3,   2,   4,   4,
+-     7,   3,   6,   4,   7,   6,  12,   6,   9,   4,   6,   5,   4,
+-     7,   6,   5,   6,   7,   5,   4,   5,   6,   5,   7,   3,   7,
+-    13,   2,   2,   4,   6,   6,   8,   5,  17,  12,   7,   8,   8,
+-     2,   4,   4,   4,   4,   4,   2,   2,   6,   5,   8,   5,   8,
+-     3,   5,   5,   6,   4,   9,   3,
++     6,   6,   5,   6,   5,   5,   5,   7,   7,   4,   2,   7,   3,
++     6,   4,   7,   6,  12,   6,   9,   4,   6,   4,   5,   4,   7,
++     6,   5,   6,   7,   5,   4,   7,   3,   2,   4,   5,   9,   5,
++     6,   3,   7,  13,   2,   2,   4,   6,   6,   8,   5,  17,  12,
++     7,   9,   8,   8,   2,   4,   9,   4,   6,   7,   9,   4,   4,
++     2,   6,   5,   8,   4,   5,   8,   4,   3,   9,   5,   5,   6,
++     4,   6,   2,   9,   3,   7,
+ };
+ /* aKWOffset[i] is the index into zKWText[] of the start of
+ ** the text for the i-th keyword. */
+-static const unsigned short int aKWOffset[124] = {
++static const unsigned short int aKWOffset[136] = {
+      0,   2,   2,   8,   9,  14,  16,  20,  23,  25,  25,  29,  33,
+     36,  41,  46,  48,  53,  54,  59,  62,  65,  67,  69,  78,  81,
+     86,  91,  95,  96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
+    159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
+-   199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
+-   250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
+-   320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
+-   387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
+-   460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
+-   521, 524, 529, 534, 540, 544, 549,
++   199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248,
++   252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321,
++   328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377,
++   381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438,
++   438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519,
++   523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582,
++   588, 591, 594, 597, 602, 606,
+ };
+ /* aKWCode[i] is the parser symbol code for the i-th keyword */
+-static const unsigned char aKWCode[124] = {
++static const unsigned char aKWCode[136] = {
+   TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,     
+   TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,    
+   TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,    
+@@ -144029,20 +151496,23 @@
+   TK_OFFSET,     TK_OF,         TK_SET,        TK_TEMP,       TK_TEMP,       
+   TK_OR,         TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    TK_WITH,       
+   TK_JOIN_KW,    TK_RELEASE,    TK_ATTACH,     TK_HAVING,     TK_GROUP,      
+-  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RECURSIVE,  TK_BETWEEN,    
+-  TK_NOTNULL,    TK_NOT,        TK_NO,         TK_NULL,       TK_LIKE_KW,    
+-  TK_CASCADE,    TK_ASC,        TK_DELETE,     TK_CASE,       TK_COLLATE,    
+-  TK_CREATE,     TK_CTIME_KW,   TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       
+-  TK_INSERT,     TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     
+-  TK_ABORT,      TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       
+-  TK_WHERE,      TK_RENAME,     TK_AFTER,      TK_REPLACE,    TK_AND,        
+-  TK_DEFAULT,    TK_AUTOINCR,   TK_TO,         TK_IN,         TK_CAST,       
+-  TK_COLUMNKW,   TK_COMMIT,     TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   
+-  TK_CTIME_KW,   TK_PRIMARY,    TK_DEFERRED,   TK_DISTINCT,   TK_IS,         
+-  TK_DROP,       TK_FAIL,       TK_FROM,       TK_JOIN_KW,    TK_LIKE_KW,    
+-  TK_BY,         TK_IF,         TK_ISNULL,     TK_ORDER,      TK_RESTRICT,   
+-  TK_JOIN_KW,    TK_ROLLBACK,   TK_ROW,        TK_UNION,      TK_USING,      
+-  TK_VACUUM,     TK_VIEW,       TK_INITIALLY,  TK_ALL,        
++  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_RANGE,      TK_BETWEEN,    
++  TK_NOTHING,    TK_LIKE_KW,    TK_BY,         TK_CASCADE,    TK_ASC,        
++  TK_DELETE,     TK_CASE,       TK_COLLATE,    TK_CREATE,     TK_CTIME_KW,   
++  TK_DETACH,     TK_IMMEDIATE,  TK_JOIN,       TK_INSERT,     TK_LIKE_KW,    
++  TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     TK_ABORT,      
++  TK_VALUES,     TK_VIRTUAL,    TK_LIMIT,      TK_WHEN,       TK_NOTNULL,    
++  TK_NOT,        TK_NO,         TK_NULL,       TK_WHERE,      TK_RECURSIVE,  
++  TK_AFTER,      TK_RENAME,     TK_AND,        TK_DEFAULT,    TK_AUTOINCR,   
++  TK_TO,         TK_IN,         TK_CAST,       TK_COLUMNKW,   TK_COMMIT,     
++  TK_CONFLICT,   TK_JOIN_KW,    TK_CTIME_KW,   TK_CTIME_KW,   TK_CURRENT,    
++  TK_PARTITION,  TK_DEFERRED,   TK_DISTINCT,   TK_IS,         TK_DROP,       
++  TK_PRECEDING,  TK_FAIL,       TK_FILTER,     TK_REPLACE,    TK_FOLLOWING,  
++  TK_FROM,       TK_JOIN_KW,    TK_IF,         TK_ISNULL,     TK_ORDER,      
++  TK_RESTRICT,   TK_OVER,       TK_JOIN_KW,    TK_ROLLBACK,   TK_ROWS,       
++  TK_ROW,        TK_UNBOUNDED,  TK_UNION,      TK_USING,      TK_VACUUM,     
++  TK_VIEW,       TK_WINDOW,     TK_DO,         TK_INITIALLY,  TK_ALL,        
++  TK_PRIMARY,    
+ };
+ /* Check to see if z[0..n-1] is a keyword. If it is, write the
+ ** parser symbol code for that keyword into *pType.  Always
+@@ -144121,72 +151591,84 @@
+       testcase( i==55 ); /* UPDATE */
+       testcase( i==56 ); /* BEGIN */
+       testcase( i==57 ); /* INNER */
+-      testcase( i==58 ); /* RECURSIVE */
++      testcase( i==58 ); /* RANGE */
+       testcase( i==59 ); /* BETWEEN */
+-      testcase( i==60 ); /* NOTNULL */
+-      testcase( i==61 ); /* NOT */
+-      testcase( i==62 ); /* NO */
+-      testcase( i==63 ); /* NULL */
+-      testcase( i==64 ); /* LIKE */
+-      testcase( i==65 ); /* CASCADE */
+-      testcase( i==66 ); /* ASC */
+-      testcase( i==67 ); /* DELETE */
+-      testcase( i==68 ); /* CASE */
+-      testcase( i==69 ); /* COLLATE */
+-      testcase( i==70 ); /* CREATE */
+-      testcase( i==71 ); /* CURRENT_DATE */
+-      testcase( i==72 ); /* DETACH */
+-      testcase( i==73 ); /* IMMEDIATE */
+-      testcase( i==74 ); /* JOIN */
+-      testcase( i==75 ); /* INSERT */
+-      testcase( i==76 ); /* MATCH */
+-      testcase( i==77 ); /* PLAN */
+-      testcase( i==78 ); /* ANALYZE */
+-      testcase( i==79 ); /* PRAGMA */
+-      testcase( i==80 ); /* ABORT */
+-      testcase( i==81 ); /* VALUES */
+-      testcase( i==82 ); /* VIRTUAL */
+-      testcase( i==83 ); /* LIMIT */
+-      testcase( i==84 ); /* WHEN */
+-      testcase( i==85 ); /* WHERE */
+-      testcase( i==86 ); /* RENAME */
+-      testcase( i==87 ); /* AFTER */
+-      testcase( i==88 ); /* REPLACE */
+-      testcase( i==89 ); /* AND */
+-      testcase( i==90 ); /* DEFAULT */
+-      testcase( i==91 ); /* AUTOINCREMENT */
+-      testcase( i==92 ); /* TO */
+-      testcase( i==93 ); /* IN */
+-      testcase( i==94 ); /* CAST */
+-      testcase( i==95 ); /* COLUMN */
+-      testcase( i==96 ); /* COMMIT */
+-      testcase( i==97 ); /* CONFLICT */
+-      testcase( i==98 ); /* CROSS */
+-      testcase( i==99 ); /* CURRENT_TIMESTAMP */
+-      testcase( i==100 ); /* CURRENT_TIME */
+-      testcase( i==101 ); /* PRIMARY */
+-      testcase( i==102 ); /* DEFERRED */
+-      testcase( i==103 ); /* DISTINCT */
+-      testcase( i==104 ); /* IS */
+-      testcase( i==105 ); /* DROP */
+-      testcase( i==106 ); /* FAIL */
+-      testcase( i==107 ); /* FROM */
+-      testcase( i==108 ); /* FULL */
+-      testcase( i==109 ); /* GLOB */
+-      testcase( i==110 ); /* BY */
+-      testcase( i==111 ); /* IF */
+-      testcase( i==112 ); /* ISNULL */
+-      testcase( i==113 ); /* ORDER */
+-      testcase( i==114 ); /* RESTRICT */
+-      testcase( i==115 ); /* RIGHT */
+-      testcase( i==116 ); /* ROLLBACK */
+-      testcase( i==117 ); /* ROW */
+-      testcase( i==118 ); /* UNION */
+-      testcase( i==119 ); /* USING */
+-      testcase( i==120 ); /* VACUUM */
+-      testcase( i==121 ); /* VIEW */
+-      testcase( i==122 ); /* INITIALLY */
+-      testcase( i==123 ); /* ALL */
++      testcase( i==60 ); /* NOTHING */
++      testcase( i==61 ); /* GLOB */
++      testcase( i==62 ); /* BY */
++      testcase( i==63 ); /* CASCADE */
++      testcase( i==64 ); /* ASC */
++      testcase( i==65 ); /* DELETE */
++      testcase( i==66 ); /* CASE */
++      testcase( i==67 ); /* COLLATE */
++      testcase( i==68 ); /* CREATE */
++      testcase( i==69 ); /* CURRENT_DATE */
++      testcase( i==70 ); /* DETACH */
++      testcase( i==71 ); /* IMMEDIATE */
++      testcase( i==72 ); /* JOIN */
++      testcase( i==73 ); /* INSERT */
++      testcase( i==74 ); /* LIKE */
++      testcase( i==75 ); /* MATCH */
++      testcase( i==76 ); /* PLAN */
++      testcase( i==77 ); /* ANALYZE */
++      testcase( i==78 ); /* PRAGMA */
++      testcase( i==79 ); /* ABORT */
++      testcase( i==80 ); /* VALUES */
++      testcase( i==81 ); /* VIRTUAL */
++      testcase( i==82 ); /* LIMIT */
++      testcase( i==83 ); /* WHEN */
++      testcase( i==84 ); /* NOTNULL */
++      testcase( i==85 ); /* NOT */
++      testcase( i==86 ); /* NO */
++      testcase( i==87 ); /* NULL */
++      testcase( i==88 ); /* WHERE */
++      testcase( i==89 ); /* RECURSIVE */
++      testcase( i==90 ); /* AFTER */
++      testcase( i==91 ); /* RENAME */
++      testcase( i==92 ); /* AND */
++      testcase( i==93 ); /* DEFAULT */
++      testcase( i==94 ); /* AUTOINCREMENT */
++      testcase( i==95 ); /* TO */
++      testcase( i==96 ); /* IN */
++      testcase( i==97 ); /* CAST */
++      testcase( i==98 ); /* COLUMN */
++      testcase( i==99 ); /* COMMIT */
++      testcase( i==100 ); /* CONFLICT */
++      testcase( i==101 ); /* CROSS */
++      testcase( i==102 ); /* CURRENT_TIMESTAMP */
++      testcase( i==103 ); /* CURRENT_TIME */
++      testcase( i==104 ); /* CURRENT */
++      testcase( i==105 ); /* PARTITION */
++      testcase( i==106 ); /* DEFERRED */
++      testcase( i==107 ); /* DISTINCT */
++      testcase( i==108 ); /* IS */
++      testcase( i==109 ); /* DROP */
++      testcase( i==110 ); /* PRECEDING */
++      testcase( i==111 ); /* FAIL */
++      testcase( i==112 ); /* FILTER */
++      testcase( i==113 ); /* REPLACE */
++      testcase( i==114 ); /* FOLLOWING */
++      testcase( i==115 ); /* FROM */
++      testcase( i==116 ); /* FULL */
++      testcase( i==117 ); /* IF */
++      testcase( i==118 ); /* ISNULL */
++      testcase( i==119 ); /* ORDER */
++      testcase( i==120 ); /* RESTRICT */
++      testcase( i==121 ); /* OVER */
++      testcase( i==122 ); /* RIGHT */
++      testcase( i==123 ); /* ROLLBACK */
++      testcase( i==124 ); /* ROWS */
++      testcase( i==125 ); /* ROW */
++      testcase( i==126 ); /* UNBOUNDED */
++      testcase( i==127 ); /* UNION */
++      testcase( i==128 ); /* USING */
++      testcase( i==129 ); /* VACUUM */
++      testcase( i==130 ); /* VIEW */
++      testcase( i==131 ); /* WINDOW */
++      testcase( i==132 ); /* DO */
++      testcase( i==133 ); /* INITIALLY */
++      testcase( i==134 ); /* ALL */
++      testcase( i==135 ); /* PRIMARY */
+       *pType = aKWCode[i];
+       break;
+     }
+@@ -144198,7 +151680,17 @@
+   keywordCode((char*)z, n, &id);
+   return id;
+ }
+-#define SQLITE_N_KEYWORD 124
++#define SQLITE_N_KEYWORD 136
++SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
++  if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;
++  *pzName = zKWText + aKWOffset[i];
++  *pnName = aKWLen[i];
++  return SQLITE_OK;
++}
++SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; }
++SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){
++  return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName);
++}
+ 
+ /************** End of keywordhash.h *****************************************/
+ /************** Continuing where we left off in tokenize.c *******************/
+@@ -144242,13 +151734,87 @@
+ #define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
+ #endif
+ 
+-/* Make the IdChar function accessible from ctime.c */
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
++/* Make the IdChar function accessible from ctime.c and alter.c */
+ SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
+-#endif
+ 
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** Return the id of the next token in string (*pz). Before returning, set
++** (*pz) to point to the byte following the parsed token.
++*/
++static int getToken(const unsigned char **pz){
++  const unsigned char *z = *pz;
++  int t;                          /* Token type to return */
++  do {
++    z += sqlite3GetToken(z, &t);
++  }while( t==TK_SPACE );
++  if( t==TK_ID 
++   || t==TK_STRING 
++   || t==TK_JOIN_KW 
++   || t==TK_WINDOW 
++   || t==TK_OVER 
++   || sqlite3ParserFallback(t)==TK_ID 
++  ){
++    t = TK_ID;
++  }
++  *pz = z;
++  return t;
++}
+ 
+ /*
++** The following three functions are called immediately after the tokenizer
++** reads the keywords WINDOW, OVER and FILTER, respectively, to determine
++** whether the token should be treated as a keyword or an SQL identifier.
++** This cannot be handled by the usual lemon %fallback method, due to
++** the ambiguity in some constructions. e.g.
++**
++**   SELECT sum(x) OVER ...
++**
++** In the above, "OVER" might be a keyword, or it might be an alias for the 
++** sum(x) expression. If a "%fallback ID OVER" directive were added to 
++** grammar, then SQLite would always treat "OVER" as an alias, making it
++** impossible to call a window-function without a FILTER clause.
++**
++** WINDOW is treated as a keyword if:
++**
++**   * the following token is an identifier, or a keyword that can fallback
++**     to being an identifier, and
++**   * the token after than one is TK_AS.
++**
++** OVER is a keyword if:
++**
++**   * the previous token was TK_RP, and
++**   * the next token is either TK_LP or an identifier.
++**
++** FILTER is a keyword if:
++**
++**   * the previous token was TK_RP, and
++**   * the next token is TK_LP.
++*/
++static int analyzeWindowKeyword(const unsigned char *z){
++  int t;
++  t = getToken(&z);
++  if( t!=TK_ID ) return TK_ID;
++  t = getToken(&z);
++  if( t!=TK_AS ) return TK_ID;
++  return TK_WINDOW;
++}
++static int analyzeOverKeyword(const unsigned char *z, int lastToken){
++  if( lastToken==TK_RP ){
++    int t = getToken(&z);
++    if( t==TK_LP || t==TK_ID ) return TK_OVER;
++  }
++  return TK_ID;
++}
++static int analyzeFilterKeyword(const unsigned char *z, int lastToken){
++  if( lastToken==TK_RP && getToken(&z)==TK_LP ){
++    return TK_FILTER;
++  }
++  return TK_ID;
++}
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++
++/*
+ ** Return the length (in bytes) of the token that begins at z[0]. 
+ ** Store the token type in *tokenType before returning.
+ */
+@@ -144515,6 +152081,10 @@
+       i = 1;
+       break;
+     }
++    case CC_NUL: {
++      *tokenType = TK_ILLEGAL;
++      return 0;
++    }
+     default: {
+       *tokenType = TK_ILLEGAL;
+       return 1;
+@@ -144525,7 +152095,74 @@
+   return i;
+ }
+ 
++#ifdef SQLITE_ENABLE_NORMALIZE
+ /*
++** Return the length (in bytes) of the token that begins at z[0].
++** Store the token type in *tokenType before returning.  If flags has
++** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
++** for keywords.  Add SQLITE_TOKEN_QUOTED to flags if the token was
++** actually a quoted identifier.  Add SQLITE_TOKEN_KEYWORD to flags
++** if the token was recognized as a keyword; this is useful when the
++** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
++** to differentiate between a keyword being treated as an identifier
++** (for normalization purposes) and an actual identifier.
++*/
++SQLITE_PRIVATE int sqlite3GetTokenNormalized(
++  const unsigned char *z,
++  int *tokenType,
++  int *flags
++){
++  int n;
++  unsigned char iClass = aiClass[*z];
++  if( iClass==CC_KYWD ){
++    int i;
++    for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
++    if( IdChar(z[i]) ){
++      /* This token started out using characters that can appear in keywords,
++      ** but z[i] is a character not allowed within keywords, so this must
++      ** be an identifier instead */
++      i++;
++      while( IdChar(z[i]) ){ i++; }
++      *tokenType = TK_ID;
++      return i;
++    }
++    *tokenType = TK_ID;
++    n = keywordCode((char*)z, i, tokenType);
++    /* If the token is no longer considered to be an identifier, then it is a
++    ** keyword of some kind.  Make the token back into an identifier and then
++    ** set the SQLITE_TOKEN_KEYWORD flag.  Several non-identifier tokens are
++    ** used verbatim, including IN, IS, NOT, and NULL. */
++    switch( *tokenType ){
++      case TK_ID: {
++        /* do nothing, handled by caller */
++        break;
++      }
++      case TK_IN:
++      case TK_IS:
++      case TK_NOT:
++      case TK_NULL: {
++        *flags |= SQLITE_TOKEN_KEYWORD;
++        break;
++      }
++      default: {
++        *tokenType = TK_ID;
++        *flags |= SQLITE_TOKEN_KEYWORD;
++        break;
++      }
++    }
++  }else{
++    n = sqlite3GetToken(z, tokenType);
++    /* If the token is considered to be an identifier and the character class
++    ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
++    if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
++      *flags |= SQLITE_TOKEN_QUOTED;
++    }
++  }
++  return n;
++}
++#endif /* SQLITE_ENABLE_NORMALIZE */
++
++/*
+ ** 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 
+@@ -144555,9 +152192,9 @@
+   /* sqlite3ParserTrace(stdout, "parser: "); */
+ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+   pEngine = &sEngine;
+-  sqlite3ParserInit(pEngine);
++  sqlite3ParserInit(pEngine, pParse);
+ #else
+-  pEngine = sqlite3ParserAlloc(sqlite3Malloc);
++  pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse);
+   if( pEngine==0 ){
+     sqlite3OomFault(db);
+     return SQLITE_NOMEM_BKPT;
+@@ -144568,47 +152205,64 @@
+   assert( pParse->nVar==0 );
+   assert( pParse->pVList==0 );
+   while( 1 ){
+-    if( zSql[0]!=0 ){
+-      n = sqlite3GetToken((u8*)zSql, &tokenType);
+-      mxSqlLen -= n;
+-      if( mxSqlLen<0 ){
+-        pParse->rc = SQLITE_TOOBIG;
+-        break;
+-      }
+-    }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;
+-      }
+-      n = 0;
++    n = sqlite3GetToken((u8*)zSql, &tokenType);
++    mxSqlLen -= n;
++    if( mxSqlLen<0 ){
++      pParse->rc = SQLITE_TOOBIG;
++      break;
+     }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++    if( tokenType>=TK_WINDOW ){
++      assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
++           || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW 
++      );
++#else
+     if( tokenType>=TK_SPACE ){
+       assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
++#endif /* SQLITE_OMIT_WINDOWFUNC */
+       if( db->u1.isInterrupted ){
+         pParse->rc = SQLITE_INTERRUPT;
+         break;
+       }
+-      if( tokenType==TK_ILLEGAL ){
++      if( tokenType==TK_SPACE ){
++        zSql += n;
++        continue;
++      }
++      if( zSql[0]==0 ){
++        /* 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;
++        }
++        n = 0;
++#ifndef SQLITE_OMIT_WINDOWFUNC
++      }else if( tokenType==TK_WINDOW ){
++        assert( n==6 );
++        tokenType = analyzeWindowKeyword((const u8*)&zSql[6]);
++      }else if( tokenType==TK_OVER ){
++        assert( n==4 );
++        tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
++      }else if( tokenType==TK_FILTER ){
++        assert( n==6 );
++        tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
++#endif /* SQLITE_OMIT_WINDOWFUNC */
++      }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;
+     }
++    pParse->sLastToken.z = zSql;
++    pParse->sLastToken.n = n;
++    sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
++    lastTokenParsed = tokenType;
++    zSql += n;
++    if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+   }
+   assert( nErr==0 );
+-  pParse->zTail = zSql;
+ #ifdef YYTRACKMAXSTACKDEPTH
+   sqlite3_mutex_enter(sqlite3MallocMutex());
+   sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
+@@ -144630,10 +152284,12 @@
+   assert( pzErrMsg!=0 );
+   if( pParse->zErrMsg ){
+     *pzErrMsg = pParse->zErrMsg;
+-    sqlite3_log(pParse->rc, "%s", *pzErrMsg);
++    sqlite3_log(pParse->rc, "%s in \"%s\"", 
++                *pzErrMsg, pParse->zTail);
+     pParse->zErrMsg = 0;
+     nErr++;
+   }
++  pParse->zTail = zSql;
+   if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
+     sqlite3VdbeDelete(pParse->pVdbe);
+     pParse->pVdbe = 0;
+@@ -144649,7 +152305,7 @@
+   sqlite3_free(pParse->apVtabLock);
+ #endif
+ 
+-  if( !IN_DECLARE_VTAB ){
++  if( !IN_SPECIAL_PARSE ){
+     /* If the pParse->declareVtab flag is set, do not delete any table 
+     ** structure built up in pParse->pNewTable. The calling code (see vtab.c)
+     ** will take responsibility for freeing the Table structure.
+@@ -144656,9 +152312,11 @@
+     */
+     sqlite3DeleteTable(db, pParse->pNewTable);
+   }
++  if( !IN_RENAME_OBJECT ){
++    sqlite3DeleteTrigger(db, pParse->pNewTrigger);
++  }
+ 
+   if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
+-  sqlite3DeleteTrigger(db, pParse->pNewTrigger);
+   sqlite3DbFree(db, pParse->pVList);
+   while( pParse->pAinc ){
+     AutoincInfo *p = pParse->pAinc;
+@@ -145708,6 +153366,17 @@
+       break;
+     }
+ 
++#ifdef SQLITE_ENABLE_SORTER_REFERENCES
++    case SQLITE_CONFIG_SORTERREF_SIZE: {
++      int iVal = va_arg(ap, int);
++      if( iVal<0 ){
++        iVal = SQLITE_DEFAULT_SORTERREF_SIZE;
++      }
++      sqlite3GlobalConfig.szSorterRef = (u32)iVal;
++      break;
++    }
++#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
++
+     default: {
+       rc = SQLITE_ERROR;
+       break;
+@@ -145889,6 +153558,8 @@
+         { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,      SQLITE_NoCkptOnClose  },
+         { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
+         { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
++        { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
++        { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
+       };
+       unsigned int i;
+       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
+@@ -145903,7 +153574,7 @@
+             db->flags &= ~aFlagOp[i].mask;
+           }
+           if( oldFlags!=db->flags ){
+-            sqlite3ExpirePreparedStatements(db);
++            sqlite3ExpirePreparedStatements(db, 0);
+           }
+           if( pRes ){
+             *pRes = (db->flags & aFlagOp[i].mask)!=0;
+@@ -145965,6 +153636,15 @@
+ }
+ 
+ /*
++** Return true if CollSeq is the default built-in BINARY.
++*/
++SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){
++  assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
++            || strcmp(p->zName,"BINARY")==0 );
++  return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
++}
++
++/*
+ ** Another built-in collating sequence: NOCASE. 
+ **
+ ** This collating sequence is intended to be used for "case independent
+@@ -146085,7 +153765,7 @@
+   sqlite3BtreeEnterAll(db);
+   for(i=0; i<db->nDb; i++){
+     Schema *pSchema = db->aDb[i].pSchema;
+-    if( db->aDb[i].pSchema ){
++    if( pSchema ){
+       for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
+         Table *pTab = (Table *)sqliteHashData(p);
+         if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
+@@ -146345,8 +154025,8 @@
+   sqlite3VtabRollback(db);
+   sqlite3EndBenignMalloc();
+ 
+-  if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){
+-    sqlite3ExpirePreparedStatements(db);
++  if( schemaChange ){
++    sqlite3ExpirePreparedStatements(db, 0);
+     sqlite3ResetAllSchemasOfConnection(db);
+   }
+   sqlite3BtreeLeaveAll(db);
+@@ -146374,6 +154054,7 @@
+     switch( rc ){
+       case SQLITE_OK:                 zName = "SQLITE_OK";                break;
+       case SQLITE_ERROR:              zName = "SQLITE_ERROR";             break;
++      case SQLITE_ERROR_SNAPSHOT:     zName = "SQLITE_ERROR_SNAPSHOT";    break;
+       case SQLITE_INTERNAL:           zName = "SQLITE_INTERNAL";          break;
+       case SQLITE_PERM:               zName = "SQLITE_PERM";              break;
+       case SQLITE_ABORT:              zName = "SQLITE_ABORT";             break;
+@@ -146737,6 +154418,8 @@
+   void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+   void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+   void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
+   FuncDestructor *pDestructor
+ ){
+   FuncDef *p;
+@@ -146744,12 +154427,14 @@
+   int extraFlags;
+ 
+   assert( sqlite3_mutex_held(db->mutex) );
+-  if( zFunctionName==0 ||
+-      (xSFunc && (xFinal || xStep)) || 
+-      (!xSFunc && (xFinal && !xStep)) ||
+-      (!xSFunc && (!xFinal && xStep)) ||
+-      (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
+-      (255<(nName = sqlite3Strlen30( zFunctionName))) ){
++  assert( xValue==0 || xSFunc==0 );
++  if( zFunctionName==0                /* Must have a valid name */
++   || (xSFunc!=0 && xFinal!=0)        /* Not both xSFunc and xFinal */
++   || ((xFinal==0)!=(xStep==0))       /* Both or neither of xFinal and xStep */
++   || ((xValue==0)!=(xInverse==0))    /* Both or neither of xValue, xInverse */
++   || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
++   || (255<(nName = sqlite3Strlen30( zFunctionName)))
++  ){
+     return SQLITE_MISUSE_BKPT;
+   }
+ 
+@@ -146770,10 +154455,10 @@
+   }else if( enc==SQLITE_ANY ){
+     int rc;
+     rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
+-         pUserData, xSFunc, xStep, xFinal, pDestructor);
++         pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
+     if( rc==SQLITE_OK ){
+       rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
+-          pUserData, xSFunc, xStep, xFinal, pDestructor);
++          pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
+     }
+     if( rc!=SQLITE_OK ){
+       return rc;
+@@ -146790,7 +154475,7 @@
+   ** operation to continue but invalidate all precompiled statements.
+   */
+   p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
+-  if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
++  if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){
+     if( db->nVdbeActive ){
+       sqlite3ErrorWithMsg(db, SQLITE_BUSY, 
+         "unable to delete/modify user-function due to active statements");
+@@ -146797,7 +154482,7 @@
+       assert( !db->mallocFailed );
+       return SQLITE_BUSY;
+     }else{
+-      sqlite3ExpirePreparedStatements(db);
++      sqlite3ExpirePreparedStatements(db, 0);
+     }
+   }
+ 
+@@ -146819,6 +154504,8 @@
+   testcase( p->funcFlags & SQLITE_DETERMINISTIC );
+   p->xSFunc = xSFunc ? xSFunc : xStep;
+   p->xFinalize = xFinal;
++  p->xValue = xValue;
++  p->xInverse = xInverse;
+   p->pUserData = pUserData;
+   p->nArg = (u16)nArg;
+   return SQLITE_OK;
+@@ -146825,32 +154512,24 @@
+ }
+ 
+ /*
+-** Create new user functions.
++** Worker function used by utf-8 APIs that create new functions:
++**
++**    sqlite3_create_function()
++**    sqlite3_create_function_v2()
++**    sqlite3_create_window_function()
+ */
+-SQLITE_API int sqlite3_create_function(
++static int createFunctionApi(
+   sqlite3 *db,
+   const char *zFunc,
+   int nArg,
+   int enc,
+   void *p,
+-  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xFinal)(sqlite3_context*)
+-){
+-  return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep,
+-                                    xFinal, 0);
+-}
+-
+-SQLITE_API int sqlite3_create_function_v2(
+-  sqlite3 *db,
+-  const char *zFunc,
+-  int nArg,
+-  int enc,
+-  void *p,
+-  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
+-  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value**),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+   void (*xFinal)(sqlite3_context*),
+-  void (*xDestroy)(void *)
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
+ ){
+   int rc = SQLITE_ERROR;
+   FuncDestructor *pArg = 0;
+@@ -146862,19 +154541,23 @@
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+   if( xDestroy ){
+-    pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
++    pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor));
+     if( !pArg ){
++      sqlite3OomFault(db);
+       xDestroy(p);
+       goto out;
+     }
++    pArg->nRef = 0;
+     pArg->xDestroy = xDestroy;
+     pArg->pUserData = p;
+   }
+-  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg);
++  rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, 
++      xSFunc, xStep, xFinal, xValue, xInverse, pArg
++  );
+   if( pArg && pArg->nRef==0 ){
+     assert( rc!=SQLITE_OK );
+     xDestroy(p);
+-    sqlite3DbFree(db, pArg);
++    sqlite3_free(pArg);
+   }
+ 
+  out:
+@@ -146883,6 +154566,52 @@
+   return rc;
+ }
+ 
++/*
++** Create new user functions.
++*/
++SQLITE_API int sqlite3_create_function(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
++                                    xFinal, 0, 0, 0);
++}
++SQLITE_API int sqlite3_create_function_v2(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xSFunc)(sqlite3_context*,int,sqlite3_value **),
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*),
++  void (*xDestroy)(void *)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep,
++                                    xFinal, 0, 0, xDestroy);
++}
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunc,
++  int nArg,
++  int enc,
++  void *p,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value **),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
++  void (*xDestroy)(void *)
++){
++  return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep,
++                                    xFinal, xValue, xInverse, xDestroy);
++}
++
+ #ifndef SQLITE_OMIT_UTF16
+ SQLITE_API int sqlite3_create_function16(
+   sqlite3 *db,
+@@ -146903,7 +154632,7 @@
+   sqlite3_mutex_enter(db->mutex);
+   assert( !db->mallocFailed );
+   zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
+-  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0);
++  rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0);
+   sqlite3DbFree(db, zFunc8);
+   rc = sqlite3ApiExit(db, rc);
+   sqlite3_mutex_leave(db->mutex);
+@@ -146913,6 +154642,28 @@
+ 
+ 
+ /*
++** The following is the implementation of an SQL function that always
++** fails with an error message stating that the function is used in the
++** wrong context.  The sqlite3_overload_function() API might construct
++** SQL function that use this routine so that the functions will exist
++** for name resolution but are actually overloaded by the xFindFunction
++** method of virtual tables.
++*/
++static void sqlite3InvalidFunction(
++  sqlite3_context *context,  /* The function calling context */
++  int NotUsed,               /* Number of arguments to the function */
++  sqlite3_value **NotUsed2   /* Value of each argument */
++){
++  const char *zName = (const char*)sqlite3_user_data(context);
++  char *zErr;
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  zErr = sqlite3_mprintf(
++      "unable to use function %s in the requested context", zName);
++  sqlite3_result_error(context, zErr, -1);
++  sqlite3_free(zErr);
++}
++
++/*
+ ** Declare that a function has been overloaded by a virtual table.
+ **
+ ** If the function already exists as a regular global function, then
+@@ -146929,7 +154680,8 @@
+   const char *zName,
+   int nArg
+ ){
+-  int rc = SQLITE_OK;
++  int rc;
++  char *zCopy;
+ 
+ #ifdef SQLITE_ENABLE_API_ARMOR
+   if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
+@@ -146937,13 +154689,13 @@
+   }
+ #endif
+   sqlite3_mutex_enter(db->mutex);
+-  if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
+-    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+-                           0, sqlite3InvalidFunction, 0, 0, 0);
+-  }
+-  rc = sqlite3ApiExit(db, rc);
++  rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
+   sqlite3_mutex_leave(db->mutex);
+-  return rc;
++  if( rc ) return SQLITE_OK;
++  zCopy = sqlite3_mprintf(zName);
++  if( zCopy==0 ) return SQLITE_NOMEM;
++  return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
++                           zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
+ }
+ 
+ #ifndef SQLITE_OMIT_TRACE
+@@ -147505,7 +155257,7 @@
+         "unable to delete/modify collation sequence due to active statements");
+       return SQLITE_BUSY;
+     }
+-    sqlite3ExpirePreparedStatements(db);
++    sqlite3ExpirePreparedStatements(db, 0);
+ 
+     /* If collation sequence pColl was created directly by a call to
+     ** sqlite3_create_collation, and not generated by synthCollSeq(),
+@@ -147994,6 +155746,7 @@
+   db->nDb = 2;
+   db->magic = SQLITE_MAGIC_BUSY;
+   db->aDb = db->aDbStatic;
++  db->lookaside.bDisable = 1;
+ 
+   assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
+   memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
+@@ -148034,6 +155787,9 @@
+ #if defined(SQLITE_ENABLE_QPSG)
+                  | SQLITE_EnableQPSG
+ #endif
++#if defined(SQLITE_DEFAULT_DEFENSIVE)
++                 | SQLITE_Defensive
++#endif
+       ;
+   sqlite3HashInit(&db->aCollSeq);
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
+@@ -148694,6 +156450,9 @@
+     }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
+       *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
+       rc = SQLITE_OK;
++    }else if( op==SQLITE_FCNTL_DATA_VERSION ){
++      *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager);
++      rc = SQLITE_OK;
+     }else{
+       rc = sqlite3OsFileControl(fd, op, pArg);
+     }
+@@ -148916,32 +156675,25 @@
+       break;
+     }
+ 
+-#ifdef SQLITE_N_KEYWORD
+-    /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
++    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
+     **
+-    ** If zWord is a keyword recognized by the parser, then return the
+-    ** number of keywords.  Or if zWord is not a keyword, return 0.
+-    ** 
+-    ** This test feature is only available in the amalgamation since
+-    ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
+-    ** is built using separate source files.
++    ** If parameter onoff is non-zero, subsequent calls to localtime()
++    ** and its variants fail. If onoff is zero, undo this setting.
+     */
+-    case SQLITE_TESTCTRL_ISKEYWORD: {
+-      const char *zWord = va_arg(ap, const char*);
+-      int n = sqlite3Strlen30(zWord);
+-      rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
++    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
++      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
+       break;
+     }
+-#endif 
+ 
+-    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
++    /*   sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
+     **
+-    ** If parameter onoff is non-zero, configure the wrappers so that all
+-    ** subsequent calls to localtime() and variants fail. If onoff is zero,
+-    ** undo this setting.
++    ** If parameter onoff is non-zero, internal-use-only SQL functions
++    ** are visible to ordinary SQL.  This is useful for testing but is
++    ** unsafe because invalid parameters to those internal-use-only functions
++    ** can result in crashes or segfaults.
+     */
+-    case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
+-      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
++    case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
++      sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
+       break;
+     }
+ 
+@@ -148975,7 +156727,8 @@
+     */
+     case SQLITE_TESTCTRL_VDBE_COVERAGE: {
+ #ifdef SQLITE_VDBE_COVERAGE
+-      typedef void (*branch_callback)(void*,int,u8,u8);
++      typedef void (*branch_callback)(void*,unsigned int,
++                                      unsigned char,unsigned char);
+       sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
+       sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
+ #endif
+@@ -149162,7 +156915,7 @@
+     if( iDb==0 || iDb>1 ){
+       Btree *pBt = db->aDb[iDb].pBt;
+       if( 0==sqlite3BtreeIsInTrans(pBt) ){
+-        rc = sqlite3BtreeBeginTrans(pBt, 0);
++        rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+         if( rc==SQLITE_OK ){
+           rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+         }
+@@ -149197,12 +156950,30 @@
+     iDb = sqlite3FindDbName(db, zDb);
+     if( iDb==0 || iDb>1 ){
+       Btree *pBt = db->aDb[iDb].pBt;
+-      if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+-        rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
++      if( sqlite3BtreeIsInTrans(pBt)==0 ){
++        Pager *pPager = sqlite3BtreePager(pBt);
++        int bUnlock = 0;
++        if( sqlite3BtreeIsInReadTrans(pBt) ){
++          if( db->nVdbeActive==0 ){
++            rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot);
++            if( rc==SQLITE_OK ){
++              bUnlock = 1;
++              rc = sqlite3BtreeCommit(pBt);
++            }
++          }
++        }else{
++          rc = SQLITE_OK;
++        }
+         if( rc==SQLITE_OK ){
+-          rc = sqlite3BtreeBeginTrans(pBt, 0);
+-          sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
++          rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot);
+         }
++        if( rc==SQLITE_OK ){
++          rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
++          sqlite3PagerSnapshotOpen(pPager, 0);
++        }
++        if( bUnlock ){
++          sqlite3PagerSnapshotUnlock(pPager);
++        }
+       }
+     }
+   }
+@@ -149232,7 +157003,7 @@
+   if( iDb==0 || iDb>1 ){
+     Btree *pBt = db->aDb[iDb].pBt;
+     if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+-      rc = sqlite3BtreeBeginTrans(pBt, 0);
++      rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+       if( rc==SQLITE_OK ){
+         rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
+         sqlite3BtreeCommit(pBt);
+@@ -150800,7 +158571,7 @@
+ );
+ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
+ #ifdef SQLITE_TEST
+-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
++SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
+ SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
+ #endif
+ 
+@@ -152368,7 +160139,7 @@
+   const char *zCsr = zNode;       /* Cursor to iterate through node */
+   const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
+   char *zBuffer = 0;              /* Buffer to load terms into */
+-  int nAlloc = 0;                 /* Size of allocated buffer */
++  i64 nAlloc = 0;                 /* Size of allocated buffer */
+   int isFirstTerm = 1;            /* True when processing first term on page */
+   sqlite3_int64 iChild;           /* Block id of child node to descend to */
+ 
+@@ -152406,14 +160177,14 @@
+     zCsr += fts3GetVarint32(zCsr, &nSuffix);
+     
+     assert( nPrefix>=0 && nSuffix>=0 );
+-    if( &zCsr[nSuffix]>zEnd ){
++    if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){
+       rc = FTS_CORRUPT_VTAB;
+       goto finish_scan;
+     }
+-    if( nPrefix+nSuffix>nAlloc ){
++    if( (i64)nPrefix+nSuffix>nAlloc ){
+       char *zNew;
+-      nAlloc = (nPrefix+nSuffix) * 2;
+-      zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
++      nAlloc = ((i64)nPrefix+nSuffix) * 2;
++      zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
+       if( !zNew ){
+         rc = SQLITE_NOMEM;
+         goto finish_scan;
+@@ -154355,7 +162126,7 @@
+   int rc = SQLITE_OK;
+   UNUSED_PARAMETER(iSavepoint);
+   assert( ((Fts3Table *)pVtab)->inTransaction );
+-  assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint );
++  assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint );
+   TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint );
+   if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){
+     rc = fts3SyncMethod(pVtab);
+@@ -154393,8 +162164,23 @@
+   return SQLITE_OK;
+ }
+ 
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int fts3ShadowName(const char *zName){
++  static const char *azName[] = {
++    "content", "docsize", "segdir", "segments", "stat", 
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static const sqlite3_module fts3Module = {
+-  /* iVersion      */ 2,
++  /* iVersion      */ 3,
+   /* xCreate       */ fts3CreateMethod,
+   /* xConnect      */ fts3ConnectMethod,
+   /* xBestIndex    */ fts3BestIndexMethod,
+@@ -154417,6 +162203,7 @@
+   /* xSavepoint    */ fts3SavepointMethod,
+   /* xRelease      */ fts3ReleaseMethod,
+   /* xRollbackTo   */ fts3RollbackToMethod,
++  /* xShadowName   */ fts3ShadowName,
+ };
+ 
+ /*
+@@ -154510,7 +162297,7 @@
+ 
+ #ifdef SQLITE_TEST
+   if( rc==SQLITE_OK ){
+-    rc = sqlite3Fts3ExprInitTestInterface(db);
++    rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
+   }
+ #endif
+ 
+@@ -154697,6 +162484,7 @@
+   return rc;
+ }
+ 
++#ifndef SQLITE_DISABLE_FTS4_DEFERRED
+ /*
+ ** This function is called on each phrase after the position lists for
+ ** any deferred tokens have been loaded into memory. It updates the phrases
+@@ -154800,6 +162588,7 @@
+ 
+   return SQLITE_OK;
+ }
++#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
+ 
+ /*
+ ** Maximum number of tokens a phrase may have to be considered for the
+@@ -157048,7 +164837,8 @@
+      0,                           /* xRename       */
+      0,                           /* xSavepoint    */
+      0,                           /* xRelease      */
+-     0                            /* xRollbackTo   */
++     0,                           /* xRollbackTo   */
++     0                            /* xShadowName   */
+   };
+   int rc;                         /* Return code */
+ 
+@@ -158171,34 +165961,6 @@
+ /* #include <stdio.h> */
+ 
+ /*
+-** Function to query the hash-table of tokenizers (see README.tokenizers).
+-*/
+-static int queryTestTokenizer(
+-  sqlite3 *db, 
+-  const char *zName,  
+-  const sqlite3_tokenizer_module **pp
+-){
+-  int rc;
+-  sqlite3_stmt *pStmt;
+-  const char zSql[] = "SELECT fts3_tokenizer(?)";
+-
+-  *pp = 0;
+-  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+-  if( rc!=SQLITE_OK ){
+-    return rc;
+-  }
+-
+-  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
+-  if( SQLITE_ROW==sqlite3_step(pStmt) ){
+-    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
+-      memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
+-    }
+-  }
+-
+-  return sqlite3_finalize(pStmt);
+-}
+-
+-/*
+ ** Return a pointer to a buffer containing a text representation of the
+ ** expression passed as the first argument. The buffer is obtained from
+ ** sqlite3_malloc(). It is the responsibility of the caller to use 
+@@ -158265,12 +166027,12 @@
+ **
+ **   SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
+ */
+-static void fts3ExprTest(
++static void fts3ExprTestCommon(
++  int bRebalance,
+   sqlite3_context *context,
+   int argc,
+   sqlite3_value **argv
+ ){
+-  sqlite3_tokenizer_module const *pModule = 0;
+   sqlite3_tokenizer *pTokenizer = 0;
+   int rc;
+   char **azCol = 0;
+@@ -158280,7 +166042,9 @@
+   int ii;
+   Fts3Expr *pExpr;
+   char *zBuf = 0;
+-  sqlite3 *db = sqlite3_context_db_handle(context);
++  Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
++  const char *zTokenizer = 0;
++  char *zErr = 0;
+ 
+   if( argc<3 ){
+     sqlite3_result_error(context, 
+@@ -158289,24 +166053,18 @@
+     return;
+   }
+ 
+-  rc = queryTestTokenizer(db,
+-                          (const char *)sqlite3_value_text(argv[0]), &pModule);
+-  if( rc==SQLITE_NOMEM ){
+-    sqlite3_result_error_nomem(context);
+-    goto exprtest_out;
+-  }else if( !pModule ){
+-    sqlite3_result_error(context, "No such tokenizer module", -1);
+-    goto exprtest_out;
++  zTokenizer = (const char*)sqlite3_value_text(argv[0]);
++  rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
++  if( rc!=SQLITE_OK ){
++    if( rc==SQLITE_NOMEM ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_error(context, zErr, -1);
++    }
++    sqlite3_free(zErr);
++    return;
+   }
+ 
+-  rc = pModule->xCreate(0, 0, &pTokenizer);
+-  assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
+-  if( rc==SQLITE_NOMEM ){
+-    sqlite3_result_error_nomem(context);
+-    goto exprtest_out;
+-  }
+-  pTokenizer->pModule = pModule;
+-
+   zExpr = (const char *)sqlite3_value_text(argv[1]);
+   nExpr = sqlite3_value_bytes(argv[1]);
+   nCol = argc-2;
+@@ -158319,7 +166077,7 @@
+     azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
+   }
+ 
+-  if( sqlite3_user_data(context) ){
++  if( bRebalance ){
+     char *zDummy = 0;
+     rc = sqlite3Fts3ExprParse(
+         pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
+@@ -158345,23 +166103,38 @@
+   sqlite3Fts3ExprFree(pExpr);
+ 
+ exprtest_out:
+-  if( pModule && pTokenizer ){
+-    rc = pModule->xDestroy(pTokenizer);
++  if( pTokenizer ){
++    rc = pTokenizer->pModule->xDestroy(pTokenizer);
+   }
+   sqlite3_free(azCol);
+ }
+ 
++static void fts3ExprTest(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  fts3ExprTestCommon(0, context, argc, argv);
++}
++static void fts3ExprTestRebalance(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  fts3ExprTestCommon(1, context, argc, argv);
++}
++
+ /*
+ ** Register the query expression parser test function fts3_exprtest() 
+ ** with database connection db. 
+ */
+-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
++SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
+   int rc = sqlite3_create_function(
+-      db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
++      db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
+   );
+   if( rc==SQLITE_OK ){
+     rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", 
+-        -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
++        -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
+     );
+   }
+   return rc;
+@@ -160624,7 +168397,8 @@
+      0,                           /* xRename       */
+      0,                           /* xSavepoint    */
+      0,                           /* xRelease      */
+-     0                            /* xRollbackTo   */
++     0,                           /* xRollbackTo   */
++     0                            /* xShadowName   */
+   };
+   int rc;                         /* Return code */
+ 
+@@ -162012,15 +169786,19 @@
+   ** safe (no risk of overread) even if the node data is corrupted. */
+   pNext += fts3GetVarint32(pNext, &nPrefix);
+   pNext += fts3GetVarint32(pNext, &nSuffix);
+-  if( nPrefix<0 || nSuffix<=0 
+-   || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] 
++  if( nSuffix<=0 
++   || (&pReader->aNode[pReader->nNode] - pNext)<nSuffix
++   || nPrefix>pReader->nTermAlloc
+   ){
+     return FTS_CORRUPT_VTAB;
+   }
+ 
+-  if( nPrefix+nSuffix>pReader->nTermAlloc ){
+-    int nNew = (nPrefix+nSuffix)*2;
+-    char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
++  /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
++  ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
++  ** overflow - hence the (i64) casts.  */
++  if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
++    i64 nNew = ((i64)nPrefix+nSuffix)*2;
++    char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
+     if( !zNew ){
+       return SQLITE_NOMEM;
+     }
+@@ -162042,7 +169820,7 @@
+   ** b-tree node. And that the final byte of the doclist is 0x00. If either 
+   ** of these statements is untrue, then the data structure is corrupt.
+   */
+-  if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] 
++  if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
+    || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
+   ){
+     return FTS_CORRUPT_VTAB;
+@@ -164368,6 +172146,9 @@
+     }
+     p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ 
++    if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){
++      return SQLITE_CORRUPT_VTAB;
++    }
+     blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
+     if( rc==SQLITE_OK ){
+       memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
+@@ -164375,6 +172156,9 @@
+       p->iOff += nSuffix;
+       if( p->iChild==0 ){
+         p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
++        if( (p->nNode-p->iOff)<p->nDoclist ){
++          return SQLITE_CORRUPT_VTAB;
++        }
+         p->aDoclist = &p->aNode[p->iOff];
+         p->iOff += p->nDoclist;
+       }
+@@ -164382,7 +172166,6 @@
+   }
+ 
+   assert( p->iOff<=p->nNode );
+-
+   return rc;
+ }
+ 
+@@ -168795,6 +176578,2550 @@
+ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */
+ 
+ /************** End of fts3_unicode2.c ***************************************/
++/************** Begin file json1.c *******************************************/
++/*
++** 2015-08-12
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This SQLite extension implements JSON functions.  The interface is
++** modeled after MySQL JSON functions:
++**
++**     https://dev.mysql.com/doc/refman/5.7/en/json.html
++**
++** For the time being, all JSON is stored as pure text.  (We might add
++** a JSONB type in the future which stores a binary encoding of JSON in
++** a BLOB, but there is no support for JSONB in the current implementation.
++** This implementation parses JSON text at 250 MB/s, so it is hard to see
++** how JSONB might improve on that.)
++*/
++#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
++#if !defined(SQLITEINT_H)
++/* #include "sqlite3ext.h" */
++#endif
++SQLITE_EXTENSION_INIT1
++/* #include <assert.h> */
++/* #include <string.h> */
++/* #include <stdlib.h> */
++/* #include <stdarg.h> */
++
++/* Mark a function parameter as unused, to suppress nuisance compiler
++** warnings. */
++#ifndef UNUSED_PARAM
++# define UNUSED_PARAM(X)  (void)(X)
++#endif
++
++#ifndef LARGEST_INT64
++# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
++# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
++#endif
++
++/*
++** Versions of isspace(), isalnum() and isdigit() to which it is safe
++** to pass signed char values.
++*/
++#ifdef sqlite3Isdigit
++   /* Use the SQLite core versions if this routine is part of the
++   ** SQLite amalgamation */
++#  define safe_isdigit(x)  sqlite3Isdigit(x)
++#  define safe_isalnum(x)  sqlite3Isalnum(x)
++#  define safe_isxdigit(x) sqlite3Isxdigit(x)
++#else
++   /* Use the standard library for separate compilation */
++#include <ctype.h>  /* amalgamator: keep */
++#  define safe_isdigit(x)  isdigit((unsigned char)(x))
++#  define safe_isalnum(x)  isalnum((unsigned char)(x))
++#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
++#endif
++
++/*
++** Growing our own isspace() routine this way is twice as fast as
++** the library isspace() function, resulting in a 7% overall performance
++** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
++*/
++static const char jsonIsSpace[] = {
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++};
++#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
++
++#ifndef SQLITE_AMALGAMATION
++  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
++  ** but the definitions need to be repeated for separate compilation. */
++  typedef sqlite3_uint64 u64;
++  typedef unsigned int u32;
++  typedef unsigned short int u16;
++  typedef unsigned char u8;
++#endif
++
++/* Objects */
++typedef struct JsonString JsonString;
++typedef struct JsonNode JsonNode;
++typedef struct JsonParse JsonParse;
++
++/* An instance of this object represents a JSON string
++** under construction.  Really, this is a generic string accumulator
++** that can be and is used to create strings other than JSON.
++*/
++struct JsonString {
++  sqlite3_context *pCtx;   /* Function context - put error messages here */
++  char *zBuf;              /* Append JSON content here */
++  u64 nAlloc;              /* Bytes of storage available in zBuf[] */
++  u64 nUsed;               /* Bytes of zBuf[] currently used */
++  u8 bStatic;              /* True if zBuf is static space */
++  u8 bErr;                 /* True if an error has been encountered */
++  char zSpace[100];        /* Initial static space */
++};
++
++/* JSON type values
++*/
++#define JSON_NULL     0
++#define JSON_TRUE     1
++#define JSON_FALSE    2
++#define JSON_INT      3
++#define JSON_REAL     4
++#define JSON_STRING   5
++#define JSON_ARRAY    6
++#define JSON_OBJECT   7
++
++/* The "subtype" set for JSON values */
++#define JSON_SUBTYPE  74    /* Ascii for "J" */
++
++/*
++** Names of the various JSON types:
++*/
++static const char * const jsonType[] = {
++  "null", "true", "false", "integer", "real", "text", "array", "object"
++};
++
++/* Bit values for the JsonNode.jnFlag field
++*/
++#define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
++#define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
++#define JNODE_REMOVE  0x04         /* Do not output */
++#define JNODE_REPLACE 0x08         /* Replace with JsonNode.u.iReplace */
++#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
++#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
++#define JNODE_LABEL   0x40         /* Is a label of an object */
++
++
++/* A single node of parsed JSON
++*/
++struct JsonNode {
++  u8 eType;              /* One of the JSON_ type values */
++  u8 jnFlags;            /* JNODE flags */
++  u32 n;                 /* Bytes of content, or number of sub-nodes */
++  union {
++    const char *zJContent; /* Content for INT, REAL, and STRING */
++    u32 iAppend;           /* More terms for ARRAY and OBJECT */
++    u32 iKey;              /* Key for ARRAY objects in json_tree() */
++    u32 iReplace;          /* Replacement content for JNODE_REPLACE */
++    JsonNode *pPatch;      /* Node chain of patch for JNODE_PATCH */
++  } u;
++};
++
++/* A completely parsed JSON string
++*/
++struct JsonParse {
++  u32 nNode;         /* Number of slots of aNode[] used */
++  u32 nAlloc;        /* Number of slots of aNode[] allocated */
++  JsonNode *aNode;   /* Array of nodes containing the parse */
++  const char *zJson; /* Original JSON string */
++  u32 *aUp;          /* Index of parent of each node */
++  u8 oom;            /* Set to true if out of memory */
++  u8 nErr;           /* Number of errors seen */
++  u16 iDepth;        /* Nesting depth */
++  int nJson;         /* Length of the zJson string in bytes */
++  u32 iHold;         /* Replace cache line with the lowest iHold value */
++};
++
++/*
++** Maximum nesting depth of JSON for this implementation.
++**
++** This limit is needed to avoid a stack overflow in the recursive
++** descent parser.  A depth of 2000 is far deeper than any sane JSON
++** should go.
++*/
++#define JSON_MAX_DEPTH  2000
++
++/**************************************************************************
++** Utility routines for dealing with JsonString objects
++**************************************************************************/
++
++/* Set the JsonString object to an empty string
++*/
++static void jsonZero(JsonString *p){
++  p->zBuf = p->zSpace;
++  p->nAlloc = sizeof(p->zSpace);
++  p->nUsed = 0;
++  p->bStatic = 1;
++}
++
++/* Initialize the JsonString object
++*/
++static void jsonInit(JsonString *p, sqlite3_context *pCtx){
++  p->pCtx = pCtx;
++  p->bErr = 0;
++  jsonZero(p);
++}
++
++
++/* Free all allocated memory and reset the JsonString object back to its
++** initial state.
++*/
++static void jsonReset(JsonString *p){
++  if( !p->bStatic ) sqlite3_free(p->zBuf);
++  jsonZero(p);
++}
++
++
++/* Report an out-of-memory (OOM) condition 
++*/
++static void jsonOom(JsonString *p){
++  p->bErr = 1;
++  sqlite3_result_error_nomem(p->pCtx);
++  jsonReset(p);
++}
++
++/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
++** Return zero on success.  Return non-zero on an OOM error
++*/
++static int jsonGrow(JsonString *p, u32 N){
++  u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
++  char *zNew;
++  if( p->bStatic ){
++    if( p->bErr ) return 1;
++    zNew = sqlite3_malloc64(nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    memcpy(zNew, p->zBuf, (size_t)p->nUsed);
++    p->zBuf = zNew;
++    p->bStatic = 0;
++  }else{
++    zNew = sqlite3_realloc64(p->zBuf, nTotal);
++    if( zNew==0 ){
++      jsonOom(p);
++      return SQLITE_NOMEM;
++    }
++    p->zBuf = zNew;
++  }
++  p->nAlloc = nTotal;
++  return SQLITE_OK;
++}
++
++/* Append N bytes from zIn onto the end of the JsonString string.
++*/
++static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
++  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
++  memcpy(p->zBuf+p->nUsed, zIn, N);
++  p->nUsed += N;
++}
++
++/* Append formatted text (not to exceed N bytes) to the JsonString.
++*/
++static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
++  va_list ap;
++  if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
++  va_start(ap, zFormat);
++  sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
++  va_end(ap);
++  p->nUsed += (int)strlen(p->zBuf+p->nUsed);
++}
++
++/* Append a single character
++*/
++static void jsonAppendChar(JsonString *p, char c){
++  if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
++  p->zBuf[p->nUsed++] = c;
++}
++
++/* Append a comma separator to the output buffer, if the previous
++** character is not '[' or '{'.
++*/
++static void jsonAppendSeparator(JsonString *p){
++  char c;
++  if( p->nUsed==0 ) return;
++  c = p->zBuf[p->nUsed-1];
++  if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
++}
++
++/* Append the N-byte string in zIn to the end of the JsonString string
++** under construction.  Enclose the string in "..." and escape
++** any double-quotes or backslash characters contained within the
++** string.
++*/
++static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
++  u32 i;
++  if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
++  p->zBuf[p->nUsed++] = '"';
++  for(i=0; i<N; i++){
++    unsigned char c = ((unsigned const char*)zIn)[i];
++    if( c=='"' || c=='\\' ){
++      json_simple_escape:
++      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++    }else if( c<=0x1f ){
++      static const char aSpecial[] = {
++         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
++         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
++      };
++      assert( sizeof(aSpecial)==32 );
++      assert( aSpecial['\b']=='b' );
++      assert( aSpecial['\f']=='f' );
++      assert( aSpecial['\n']=='n' );
++      assert( aSpecial['\r']=='r' );
++      assert( aSpecial['\t']=='t' );
++      if( aSpecial[c] ){
++        c = aSpecial[c];
++        goto json_simple_escape;
++      }
++      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
++      p->zBuf[p->nUsed++] = '\\';
++      p->zBuf[p->nUsed++] = 'u';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0';
++      p->zBuf[p->nUsed++] = '0' + (c>>4);
++      c = "0123456789abcdef"[c&0xf];
++    }
++    p->zBuf[p->nUsed++] = c;
++  }
++  p->zBuf[p->nUsed++] = '"';
++  assert( p->nUsed<p->nAlloc );
++}
++
++/*
++** Append a function parameter value to the JSON string under 
++** construction.
++*/
++static void jsonAppendValue(
++  JsonString *p,                 /* Append to this JSON string */
++  sqlite3_value *pValue          /* Value to append */
++){
++  switch( sqlite3_value_type(pValue) ){
++    case SQLITE_NULL: {
++      jsonAppendRaw(p, "null", 4);
++      break;
++    }
++    case SQLITE_INTEGER:
++    case SQLITE_FLOAT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      jsonAppendRaw(p, z, n);
++      break;
++    }
++    case SQLITE_TEXT: {
++      const char *z = (const char*)sqlite3_value_text(pValue);
++      u32 n = (u32)sqlite3_value_bytes(pValue);
++      if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
++        jsonAppendRaw(p, z, n);
++      }else{
++        jsonAppendString(p, z, n);
++      }
++      break;
++    }
++    default: {
++      if( p->bErr==0 ){
++        sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
++        p->bErr = 2;
++        jsonReset(p);
++      }
++      break;
++    }
++  }
++}
++
++
++/* Make the JSON in p the result of the SQL function.
++*/
++static void jsonResult(JsonString *p){
++  if( p->bErr==0 ){
++    sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, 
++                          p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
++                          SQLITE_UTF8);
++    jsonZero(p);
++  }
++  assert( p->bStatic );
++}
++
++/**************************************************************************
++** Utility routines for dealing with JsonNode and JsonParse objects
++**************************************************************************/
++
++/*
++** Return the number of consecutive JsonNode slots need to represent
++** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
++** OBJECT types, the number might be larger.
++**
++** Appended elements are not counted.  The value returned is the number
++** by which the JsonNode counter should increment in order to go to the
++** next peer value.
++*/
++static u32 jsonNodeSize(JsonNode *pNode){
++  return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
++}
++
++/*
++** Reclaim all memory allocated by a JsonParse object.  But do not
++** delete the JsonParse object itself.
++*/
++static void jsonParseReset(JsonParse *pParse){
++  sqlite3_free(pParse->aNode);
++  pParse->aNode = 0;
++  pParse->nNode = 0;
++  pParse->nAlloc = 0;
++  sqlite3_free(pParse->aUp);
++  pParse->aUp = 0;
++}
++
++/*
++** Free a JsonParse object that was obtained from sqlite3_malloc().
++*/
++static void jsonParseFree(JsonParse *pParse){
++  jsonParseReset(pParse);
++  sqlite3_free(pParse);
++}
++
++/*
++** Convert the JsonNode pNode into a pure JSON string and
++** append to pOut.  Subsubstructure is also included.  Return
++** the number of JsonNode objects that are encoded.
++*/
++static void jsonRenderNode(
++  JsonNode *pNode,               /* The node to render */
++  JsonString *pOut,              /* Write JSON here */
++  sqlite3_value **aReplace       /* Replacement values */
++){
++  if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
++    if( pNode->jnFlags & JNODE_REPLACE ){
++      jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
++      return;
++    }
++    pNode = pNode->u.pPatch;
++  }
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      jsonAppendRaw(pOut, "null", 4);
++      break;
++    }
++    case JSON_TRUE: {
++      jsonAppendRaw(pOut, "true", 4);
++      break;
++    }
++    case JSON_FALSE: {
++      jsonAppendRaw(pOut, "false", 5);
++      break;
++    }
++    case JSON_STRING: {
++      if( pNode->jnFlags & JNODE_RAW ){
++        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
++        break;
++      }
++      /* Fall through into the next case */
++    }
++    case JSON_REAL:
++    case JSON_INT: {
++      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
++      break;
++    }
++    case JSON_ARRAY: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '[');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++          }
++          j += jsonNodeSize(&pNode[j]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, ']');
++      break;
++    }
++    case JSON_OBJECT: {
++      u32 j = 1;
++      jsonAppendChar(pOut, '{');
++      for(;;){
++        while( j<=pNode->n ){
++          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
++            jsonAppendSeparator(pOut);
++            jsonRenderNode(&pNode[j], pOut, aReplace);
++            jsonAppendChar(pOut, ':');
++            jsonRenderNode(&pNode[j+1], pOut, aReplace);
++          }
++          j += 1 + jsonNodeSize(&pNode[j+1]);
++        }
++        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
++        pNode = &pNode[pNode->u.iAppend];
++        j = 1;
++      }
++      jsonAppendChar(pOut, '}');
++      break;
++    }
++  }
++}
++
++/*
++** Return a JsonNode and all its descendents as a JSON string.
++*/
++static void jsonReturnJson(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  JsonString s;
++  jsonInit(&s, pCtx);
++  jsonRenderNode(pNode, &s, aReplace);
++  jsonResult(&s);
++  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
++}
++
++/*
++** Make the JsonNode the return value of the function.
++*/
++static void jsonReturn(
++  JsonNode *pNode,            /* Node to return */
++  sqlite3_context *pCtx,      /* Return value for this function */
++  sqlite3_value **aReplace    /* Array of replacement values */
++){
++  switch( pNode->eType ){
++    default: {
++      assert( pNode->eType==JSON_NULL );
++      sqlite3_result_null(pCtx);
++      break;
++    }
++    case JSON_TRUE: {
++      sqlite3_result_int(pCtx, 1);
++      break;
++    }
++    case JSON_FALSE: {
++      sqlite3_result_int(pCtx, 0);
++      break;
++    }
++    case JSON_INT: {
++      sqlite3_int64 i = 0;
++      const char *z = pNode->u.zJContent;
++      if( z[0]=='-' ){ z++; }
++      while( z[0]>='0' && z[0]<='9' ){
++        unsigned v = *(z++) - '0';
++        if( i>=LARGEST_INT64/10 ){
++          if( i>LARGEST_INT64/10 ) goto int_as_real;
++          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
++          if( v==9 ) goto int_as_real;
++          if( v==8 ){
++            if( pNode->u.zJContent[0]=='-' ){
++              sqlite3_result_int64(pCtx, SMALLEST_INT64);
++              goto int_done;
++            }else{
++              goto int_as_real;
++            }
++          }
++        }
++        i = i*10 + v;
++      }
++      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
++      sqlite3_result_int64(pCtx, i);
++      int_done:
++      break;
++      int_as_real: /* fall through to real */;
++    }
++    case JSON_REAL: {
++      double r;
++#ifdef SQLITE_AMALGAMATION
++      const char *z = pNode->u.zJContent;
++      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
++#else
++      r = strtod(pNode->u.zJContent, 0);
++#endif
++      sqlite3_result_double(pCtx, r);
++      break;
++    }
++    case JSON_STRING: {
++#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
++      ** json_insert() and json_replace() and those routines do not
++      ** call jsonReturn() */
++      if( pNode->jnFlags & JNODE_RAW ){
++        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
++                            SQLITE_TRANSIENT);
++      }else 
++#endif
++      assert( (pNode->jnFlags & JNODE_RAW)==0 );
++      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
++        /* JSON formatted without any backslash-escapes */
++        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
++                            SQLITE_TRANSIENT);
++      }else{
++        /* Translate JSON formatted string into raw text */
++        u32 i;
++        u32 n = pNode->n;
++        const char *z = pNode->u.zJContent;
++        char *zOut;
++        u32 j;
++        zOut = sqlite3_malloc( n+1 );
++        if( zOut==0 ){
++          sqlite3_result_error_nomem(pCtx);
++          break;
++        }
++        for(i=1, j=0; i<n-1; i++){
++          char c = z[i];
++          if( c!='\\' ){
++            zOut[j++] = c;
++          }else{
++            c = z[++i];
++            if( c=='u' ){
++              u32 v = 0, k;
++              for(k=0; k<4; i++, k++){
++                assert( i<n-2 );
++                c = z[i+1];
++                assert( safe_isxdigit(c) );
++                if( c<='9' ) v = v*16 + c - '0';
++                else if( c<='F' ) v = v*16 + c - 'A' + 10;
++                else v = v*16 + c - 'a' + 10;
++              }
++              if( v==0 ) break;
++              if( v<=0x7f ){
++                zOut[j++] = (char)v;
++              }else if( v<=0x7ff ){
++                zOut[j++] = (char)(0xc0 | (v>>6));
++                zOut[j++] = 0x80 | (v&0x3f);
++              }else{
++                zOut[j++] = (char)(0xe0 | (v>>12));
++                zOut[j++] = 0x80 | ((v>>6)&0x3f);
++                zOut[j++] = 0x80 | (v&0x3f);
++              }
++            }else{
++              if( c=='b' ){
++                c = '\b';
++              }else if( c=='f' ){
++                c = '\f';
++              }else if( c=='n' ){
++                c = '\n';
++              }else if( c=='r' ){
++                c = '\r';
++              }else if( c=='t' ){
++                c = '\t';
++              }
++              zOut[j++] = c;
++            }
++          }
++        }
++        zOut[j] = 0;
++        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
++      }
++      break;
++    }
++    case JSON_ARRAY:
++    case JSON_OBJECT: {
++      jsonReturnJson(pNode, pCtx, aReplace);
++      break;
++    }
++  }
++}
++
++/* Forward reference */
++static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
++
++/*
++** A macro to hint to the compiler that a function should not be
++** inlined.
++*/
++#if defined(__GNUC__)
++#  define JSON_NOINLINE  __attribute__((noinline))
++#elif defined(_MSC_VER) && _MSC_VER>=1310
++#  define JSON_NOINLINE  __declspec(noinline)
++#else
++#  define JSON_NOINLINE
++#endif
++
++
++static JSON_NOINLINE int jsonParseAddNodeExpand(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  u32 nNew;
++  JsonNode *pNew;
++  assert( pParse->nNode>=pParse->nAlloc );
++  if( pParse->oom ) return -1;
++  nNew = pParse->nAlloc*2 + 10;
++  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
++  if( pNew==0 ){
++    pParse->oom = 1;
++    return -1;
++  }
++  pParse->nAlloc = nNew;
++  pParse->aNode = pNew;
++  assert( pParse->nNode<pParse->nAlloc );
++  return jsonParseAddNode(pParse, eType, n, zContent);
++}
++
++/*
++** Create a new JsonNode instance based on the arguments and append that
++** instance to the JsonParse.  Return the index in pParse->aNode[] of the
++** new node, or -1 if a memory allocation fails.
++*/
++static int jsonParseAddNode(
++  JsonParse *pParse,        /* Append the node to this object */
++  u32 eType,                /* Node type */
++  u32 n,                    /* Content size or sub-node count */
++  const char *zContent      /* Content */
++){
++  JsonNode *p;
++  if( pParse->nNode>=pParse->nAlloc ){
++    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
++  }
++  p = &pParse->aNode[pParse->nNode];
++  p->eType = (u8)eType;
++  p->jnFlags = 0;
++  p->n = n;
++  p->u.zJContent = zContent;
++  return pParse->nNode++;
++}
++
++/*
++** Return true if z[] begins with 4 (or more) hexadecimal digits
++*/
++static int jsonIs4Hex(const char *z){
++  int i;
++  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
++  return 1;
++}
++
++/*
++** Parse a single JSON value which begins at pParse->zJson[i].  Return the
++** index of the first character past the end of the value parsed.
++**
++** Return negative for a syntax error.  Special cases:  return -2 if the
++** first non-whitespace character is '}' and return -3 if the first
++** non-whitespace character is ']'.
++*/
++static int jsonParseValue(JsonParse *pParse, u32 i){
++  char c;
++  u32 j;
++  int iThis;
++  int x;
++  JsonNode *pNode;
++  const char *z = pParse->zJson;
++  while( safe_isspace(z[i]) ){ i++; }
++  if( (c = z[i])=='{' ){
++    /* Parse object */
++    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      if( x<0 ){
++        pParse->iDepth--;
++        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      if( pParse->oom ) return -1;
++      pNode = &pParse->aNode[pParse->nNode-1];
++      if( pNode->eType!=JSON_STRING ) return -1;
++      pNode->jnFlags |= JNODE_LABEL;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      if( z[j]!=':' ) return -1;
++      j++;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ) return -1;
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!='}' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='[' ){
++    /* Parse array */
++    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++    if( iThis<0 ) return -1;
++    for(j=i+1;;j++){
++      while( safe_isspace(z[j]) ){ j++; }
++      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
++      x = jsonParseValue(pParse, j);
++      pParse->iDepth--;
++      if( x<0 ){
++        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
++        return -1;
++      }
++      j = x;
++      while( safe_isspace(z[j]) ){ j++; }
++      c = z[j];
++      if( c==',' ) continue;
++      if( c!=']' ) return -1;
++      break;
++    }
++    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
++    return j+1;
++  }else if( c=='"' ){
++    /* Parse string */
++    u8 jnFlags = 0;
++    j = i+1;
++    for(;;){
++      c = z[j];
++      if( (c & ~0x1f)==0 ){
++        /* Control characters are not allowed in strings */
++        return -1;
++      }
++      if( c=='\\' ){
++        c = z[++j];
++        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
++           || c=='n' || c=='r' || c=='t'
++           || (c=='u' && jsonIs4Hex(z+j+1)) ){
++          jnFlags = JNODE_ESCAPE;
++        }else{
++          return -1;
++        }
++      }else if( c=='"' ){
++        break;
++      }
++      j++;
++    }
++    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
++    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
++    return j+1;
++  }else if( c=='n'
++         && strncmp(z+i,"null",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return i+4;
++  }else if( c=='t'
++         && strncmp(z+i,"true",4)==0
++         && !safe_isalnum(z[i+4]) ){
++    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++    return i+4;
++  }else if( c=='f'
++         && strncmp(z+i,"false",5)==0
++         && !safe_isalnum(z[i+5]) ){
++    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
++    return i+5;
++  }else if( c=='-' || (c>='0' && c<='9') ){
++    /* Parse number */
++    u8 seenDP = 0;
++    u8 seenE = 0;
++    assert( '-' < '0' );
++    if( c<='0' ){
++      j = c=='-' ? i+1 : i;
++      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
++    }
++    j = i+1;
++    for(;; j++){
++      c = z[j];
++      if( c>='0' && c<='9' ) continue;
++      if( c=='.' ){
++        if( z[j-1]=='-' ) return -1;
++        if( seenDP ) return -1;
++        seenDP = 1;
++        continue;
++      }
++      if( c=='e' || c=='E' ){
++        if( z[j-1]<'0' ) return -1;
++        if( seenE ) return -1;
++        seenDP = seenE = 1;
++        c = z[j+1];
++        if( c=='+' || c=='-' ){
++          j++;
++          c = z[j+1];
++        }
++        if( c<'0' || c>'9' ) return -1;
++        continue;
++      }
++      break;
++    }
++    if( z[j-1]<'0' ) return -1;
++    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
++                        j - i, &z[i]);
++    return j;
++  }else if( c=='}' ){
++    return -2;  /* End of {...} */
++  }else if( c==']' ){
++    return -3;  /* End of [...] */
++  }else if( c==0 ){
++    return 0;   /* End of file */
++  }else{
++    return -1;  /* Syntax error */
++  }
++}
++
++/*
++** Parse a complete JSON string.  Return 0 on success or non-zero if there
++** are any errors.  If an error occurs, free all memory associated with
++** pParse.
++**
++** pParse is uninitialized when this routine is called.
++*/
++static int jsonParse(
++  JsonParse *pParse,           /* Initialize and fill this JsonParse object */
++  sqlite3_context *pCtx,       /* Report errors here */
++  const char *zJson            /* Input JSON text to be parsed */
++){
++  int i;
++  memset(pParse, 0, sizeof(*pParse));
++  if( zJson==0 ) return 1;
++  pParse->zJson = zJson;
++  i = jsonParseValue(pParse, 0);
++  if( pParse->oom ) i = -1;
++  if( i>0 ){
++    assert( pParse->iDepth==0 );
++    while( safe_isspace(zJson[i]) ) i++;
++    if( zJson[i] ) i = -1;
++  }
++  if( i<=0 ){
++    if( pCtx!=0 ){
++      if( pParse->oom ){
++        sqlite3_result_error_nomem(pCtx);
++      }else{
++        sqlite3_result_error(pCtx, "malformed JSON", -1);
++      }
++    }
++    jsonParseReset(pParse);
++    return 1;
++  }
++  return 0;
++}
++
++/* Mark node i of pParse as being a child of iParent.  Call recursively
++** to fill in all the descendants of node i.
++*/
++static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
++  JsonNode *pNode = &pParse->aNode[i];
++  u32 j;
++  pParse->aUp[i] = iParent;
++  switch( pNode->eType ){
++    case JSON_ARRAY: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
++        jsonParseFillInParentage(pParse, i+j, i);
++      }
++      break;
++    }
++    case JSON_OBJECT: {
++      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
++        pParse->aUp[i+j] = i;
++        jsonParseFillInParentage(pParse, i+j+1, i);
++      }
++      break;
++    }
++    default: {
++      break;
++    }
++  }
++}
++
++/*
++** Compute the parentage of all nodes in a completed parse.
++*/
++static int jsonParseFindParents(JsonParse *pParse){
++  u32 *aUp;
++  assert( pParse->aUp==0 );
++  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
++  if( aUp==0 ){
++    pParse->oom = 1;
++    return SQLITE_NOMEM;
++  }
++  jsonParseFillInParentage(pParse, 0, 0);
++  return SQLITE_OK;
++}
++
++/*
++** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
++*/
++#define JSON_CACHE_ID  (-429938)  /* First cache entry */
++#define JSON_CACHE_SZ  4          /* Max number of cache entries */
++
++/*
++** Obtain a complete parse of the JSON found in the first argument
++** of the argv array.  Use the sqlite3_get_auxdata() cache for this
++** parse if it is available.  If the cache is not available or if it
++** is no longer valid, parse the JSON again and return the new parse,
++** and also register the new parse so that it will be available for
++** future sqlite3_get_auxdata() calls.
++*/
++static JsonParse *jsonParseCached(
++  sqlite3_context *pCtx,
++  sqlite3_value **argv,
++  sqlite3_context *pErrCtx
++){
++  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
++  int nJson = sqlite3_value_bytes(argv[0]);
++  JsonParse *p;
++  JsonParse *pMatch = 0;
++  int iKey;
++  int iMinKey = 0;
++  u32 iMinHold = 0xffffffff;
++  u32 iMaxHold = 0;
++  if( zJson==0 ) return 0;
++  for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){
++    p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey);
++    if( p==0 ){
++      iMinKey = iKey;
++      break;
++    }
++    if( pMatch==0
++     && p->nJson==nJson
++     && memcmp(p->zJson,zJson,nJson)==0
++    ){
++      p->nErr = 0;
++      pMatch = p;
++    }else if( p->iHold<iMinHold ){
++      iMinHold = p->iHold;
++      iMinKey = iKey;
++    }
++    if( p->iHold>iMaxHold ){
++      iMaxHold = p->iHold;
++    }
++  }
++  if( pMatch ){
++    pMatch->nErr = 0;
++    pMatch->iHold = iMaxHold+1;
++    return pMatch;
++  }
++  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
++  if( p==0 ){
++    sqlite3_result_error_nomem(pCtx);
++    return 0;
++  }
++  memset(p, 0, sizeof(*p));
++  p->zJson = (char*)&p[1];
++  memcpy((char*)p->zJson, zJson, nJson+1);
++  if( jsonParse(p, pErrCtx, p->zJson) ){
++    sqlite3_free(p);
++    return 0;
++  }
++  p->nJson = nJson;
++  p->iHold = iMaxHold+1;
++  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p,
++                      (void(*)(void*))jsonParseFree);
++  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey);
++}
++
++/*
++** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
++** a match.
++*/
++static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
++  if( pNode->jnFlags & JNODE_RAW ){
++    if( pNode->n!=nKey ) return 0;
++    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
++  }else{
++    if( pNode->n!=nKey+2 ) return 0;
++    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
++  }
++}
++
++/* forward declaration */
++static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
++
++/*
++** Search along zPath to find the node specified.  Return a pointer
++** to that node, or NULL if zPath is malformed or if there is no such
++** node.
++**
++** If pApnd!=0, then try to append new nodes to complete zPath if it is
++** possible to do so and if no existing node corresponds to zPath.  If
++** new nodes are appended *pApnd is set to 1.
++*/
++static JsonNode *jsonLookupStep(
++  JsonParse *pParse,      /* The JSON to search */
++  u32 iRoot,              /* Begin the search at this node */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
++){
++  u32 i, j, nKey;
++  const char *zKey;
++  JsonNode *pRoot = &pParse->aNode[iRoot];
++  if( zPath[0]==0 ) return pRoot;
++  if( zPath[0]=='.' ){
++    if( pRoot->eType!=JSON_OBJECT ) return 0;
++    zPath++;
++    if( zPath[0]=='"' ){
++      zKey = zPath + 1;
++      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
++      nKey = i-1;
++      if( zPath[i] ){
++        i++;
++      }else{
++        *pzErr = zPath;
++        return 0;
++      }
++    }else{
++      zKey = zPath;
++      for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
++      nKey = i;
++    }
++    if( nKey==0 ){
++      *pzErr = zPath;
++      return 0;
++    }
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n ){
++        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
++          return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
++        }
++        j++;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( pApnd ){
++      u32 iStart, iLabel;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
++      zPath += i;
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
++      }
++      return pNode;
++    }
++  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
++    if( pRoot->eType!=JSON_ARRAY ) return 0;
++    i = 0;
++    j = 1;
++    while( safe_isdigit(zPath[j]) ){
++      i = i*10 + zPath[j] - '0';
++      j++;
++    }
++    if( zPath[j]!=']' ){
++      *pzErr = zPath;
++      return 0;
++    }
++    zPath += j + 1;
++    j = 1;
++    for(;;){
++      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
++        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
++        j += jsonNodeSize(&pRoot[j]);
++      }
++      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
++      iRoot += pRoot->u.iAppend;
++      pRoot = &pParse->aNode[iRoot];
++      j = 1;
++    }
++    if( j<=pRoot->n ){
++      return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
++    }
++    if( i==0 && pApnd ){
++      u32 iStart;
++      JsonNode *pNode;
++      iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
++      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
++      if( pParse->oom ) return 0;
++      if( pNode ){
++        pRoot = &pParse->aNode[iRoot];
++        pRoot->u.iAppend = iStart - iRoot;
++        pRoot->jnFlags |= JNODE_APPEND;
++      }
++      return pNode;
++    }
++  }else{
++    *pzErr = zPath;
++  }
++  return 0;
++}
++
++/*
++** Append content to pParse that will complete zPath.  Return a pointer
++** to the inserted node, or return NULL if the append fails.
++*/
++static JsonNode *jsonLookupAppend(
++  JsonParse *pParse,     /* Append content to the JSON parse */
++  const char *zPath,     /* Description of content to append */
++  int *pApnd,            /* Set this flag to 1 */
++  const char **pzErr     /* Make this point to any syntax error */
++){
++  *pApnd = 1;
++  if( zPath[0]==0 ){
++    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
++    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
++  }
++  if( zPath[0]=='.' ){
++    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
++  }else if( strncmp(zPath,"[0]",3)==0 ){
++    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
++  }else{
++    return 0;
++  }
++  if( pParse->oom ) return 0;
++  return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
++}
++
++/*
++** Return the text of a syntax error message on a JSON path.  Space is
++** obtained from sqlite3_malloc().
++*/
++static char *jsonPathSyntaxError(const char *zErr){
++  return sqlite3_mprintf("JSON path error near '%q'", zErr);
++}
++
++/*
++** Do a node lookup using zPath.  Return a pointer to the node on success.
++** Return NULL if not found or if there is an error.
++**
++** On an error, write an error message into pCtx and increment the
++** pParse->nErr counter.
++**
++** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
++** nodes are appended.
++*/
++static JsonNode *jsonLookup(
++  JsonParse *pParse,      /* The JSON to search */
++  const char *zPath,      /* The path to search */
++  int *pApnd,             /* Append nodes to complete path if not NULL */
++  sqlite3_context *pCtx   /* Report errors here, if not NULL */
++){
++  const char *zErr = 0;
++  JsonNode *pNode = 0;
++  char *zMsg;
++
++  if( zPath==0 ) return 0;
++  if( zPath[0]!='$' ){
++    zErr = zPath;
++    goto lookup_err;
++  }
++  zPath++;
++  pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
++  if( zErr==0 ) return pNode;
++
++lookup_err:
++  pParse->nErr++;
++  assert( zErr!=0 && pCtx!=0 );
++  zMsg = jsonPathSyntaxError(zErr);
++  if( zMsg ){
++    sqlite3_result_error(pCtx, zMsg, -1);
++    sqlite3_free(zMsg);
++  }else{
++    sqlite3_result_error_nomem(pCtx);
++  }
++  return 0;
++}
++
++
++/*
++** Report the wrong number of arguments for json_insert(), json_replace()
++** or json_set().
++*/
++static void jsonWrongNumArgs(
++  sqlite3_context *pCtx,
++  const char *zFuncName
++){
++  char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
++                               zFuncName);
++  sqlite3_result_error(pCtx, zMsg, -1);
++  sqlite3_free(zMsg);     
++}
++
++/*
++** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
++*/
++static void jsonRemoveAllNulls(JsonNode *pNode){
++  int i, n;
++  assert( pNode->eType==JSON_OBJECT );
++  n = pNode->n;
++  for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
++    switch( pNode[i].eType ){
++      case JSON_NULL:
++        pNode[i].jnFlags |= JNODE_REMOVE;
++        break;
++      case JSON_OBJECT:
++        jsonRemoveAllNulls(&pNode[i]);
++        break;
++    }
++  }
++}
++
++
++/****************************************************************************
++** SQL functions used for testing and debugging
++****************************************************************************/
++
++#ifdef SQLITE_DEBUG
++/*
++** The json_parse(JSON) function returns a string which describes
++** a parse of the JSON provided.  Or it returns NULL if JSON is not
++** well-formed.
++*/
++static void jsonParseFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString s;       /* Output string - not real JSON */
++  JsonParse x;        /* The parse */
++  u32 i;
++
++  assert( argc==1 );
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  jsonParseFindParents(&x);
++  jsonInit(&s, ctx);
++  for(i=0; i<x.nNode; i++){
++    const char *zType;
++    if( x.aNode[i].jnFlags & JNODE_LABEL ){
++      assert( x.aNode[i].eType==JSON_STRING );
++      zType = "label";
++    }else{
++      zType = jsonType[x.aNode[i].eType];
++    }
++    jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
++               i, zType, x.aNode[i].n, x.aUp[i]);
++    if( x.aNode[i].u.zJContent!=0 ){
++      jsonAppendRaw(&s, " ", 1);
++      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
++    }
++    jsonAppendRaw(&s, "\n", 1);
++  }
++  jsonParseReset(&x);
++  jsonResult(&s);
++}
++
++/*
++** The json_test1(JSON) function return true (1) if the input is JSON
++** text generated by another json function.  It returns (0) if the input
++** is not known to be JSON.
++*/
++static void jsonTest1Func(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  UNUSED_PARAM(argc);
++  sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
++}
++#endif /* SQLITE_DEBUG */
++
++/****************************************************************************
++** Scalar SQL function implementations
++****************************************************************************/
++
++/*
++** Implementation of the json_QUOTE(VALUE) function.  Return a JSON value
++** corresponding to the SQL value input.  Mostly this means putting 
++** double-quotes around strings and returning the unquoted string "null"
++** when given a NULL input.
++*/
++static void jsonQuoteFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString jx;
++  UNUSED_PARAM(argc);
++
++  jsonInit(&jx, ctx);
++  jsonAppendValue(&jx, argv[0]);
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++/*
++** Implementation of the json_array(VALUE,...) function.  Return a JSON
++** array that contains all values given in arguments.  Or if any argument
++** is a BLOB, throw an error.
++*/
++static void jsonArrayFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=0; i<argc; i++){
++    jsonAppendSeparator(&jx);
++    jsonAppendValue(&jx, argv[i]);
++  }
++  jsonAppendChar(&jx, ']');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_array_length(JSON)
++** json_array_length(JSON, PATH)
++**
++** Return the number of elements in the top-level JSON array.  
++** Return 0 if the input is not a well-formed JSON array.
++*/
++static void jsonArrayLengthFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  sqlite3_int64 n = 0;
++  u32 i;
++  JsonNode *pNode;
++
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  assert( p->nNode );
++  if( argc==2 ){
++    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++  }else{
++    pNode = p->aNode;
++  }
++  if( pNode==0 ){
++    return;
++  }
++  if( pNode->eType==JSON_ARRAY ){
++    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
++    for(i=1; i<=pNode->n; n++){
++      i += jsonNodeSize(&pNode[i]);
++    }
++  }
++  sqlite3_result_int64(ctx, n);
++}
++
++/*
++** json_extract(JSON, PATH, ...)
++**
++** Return the element described by PATH.  Return NULL if there is no
++** PATH element.  If there are multiple PATHs, then return a JSON array
++** with the result from each path.  Throw an error if the JSON or any PATH
++** is malformed.
++*/
++static void jsonExtractFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  JsonString jx;
++  int i;
++
++  if( argc<2 ) return;
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '[');
++  for(i=1; i<argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++    if( p->nErr ) break;
++    if( argc>2 ){
++      jsonAppendSeparator(&jx);
++      if( pNode ){
++        jsonRenderNode(pNode, &jx, 0);
++      }else{
++        jsonAppendRaw(&jx, "null", 4);
++      }
++    }else if( pNode ){
++      jsonReturn(pNode, ctx, 0);
++    }
++  }
++  if( argc>2 && i==argc ){
++    jsonAppendChar(&jx, ']');
++    jsonResult(&jx);
++    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++  }
++  jsonReset(&jx);
++}
++
++/* This is the RFC 7396 MergePatch algorithm.
++*/
++static JsonNode *jsonMergePatch(
++  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
++  u32 iTarget,         /* Node of the TARGET in pParse */
++  JsonNode *pPatch     /* The PATCH */
++){
++  u32 i, j;
++  u32 iRoot;
++  JsonNode *pTarget;
++  if( pPatch->eType!=JSON_OBJECT ){
++    return pPatch;
++  }
++  assert( iTarget>=0 && iTarget<pParse->nNode );
++  pTarget = &pParse->aNode[iTarget];
++  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
++  if( pTarget->eType!=JSON_OBJECT ){
++    jsonRemoveAllNulls(pPatch);
++    return pPatch;
++  }
++  iRoot = iTarget;
++  for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
++    u32 nKey;
++    const char *zKey;
++    assert( pPatch[i].eType==JSON_STRING );
++    assert( pPatch[i].jnFlags & JNODE_LABEL );
++    nKey = pPatch[i].n;
++    zKey = pPatch[i].u.zJContent;
++    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
++      assert( pTarget[j].eType==JSON_STRING );
++      assert( pTarget[j].jnFlags & JNODE_LABEL );
++      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
++      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
++        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
++        if( pPatch[i+1].eType==JSON_NULL ){
++          pTarget[j+1].jnFlags |= JNODE_REMOVE;
++        }else{
++          JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
++          if( pNew==0 ) return 0;
++          pTarget = &pParse->aNode[iTarget];
++          if( pNew!=&pTarget[j+1] ){
++            pTarget[j+1].u.pPatch = pNew;
++            pTarget[j+1].jnFlags |= JNODE_PATCH;
++          }
++        }
++        break;
++      }
++    }
++    if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
++      int iStart, iPatch;
++      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
++      jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
++      iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
++      if( pParse->oom ) return 0;
++      jsonRemoveAllNulls(pPatch);
++      pTarget = &pParse->aNode[iTarget];
++      pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
++      pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
++      iRoot = iStart;
++      pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
++      pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
++    }
++  }
++  return pTarget;
++}
++
++/*
++** Implementation of the json_mergepatch(JSON1,JSON2) function.  Return a JSON
++** object that is the result of running the RFC 7396 MergePatch() algorithm
++** on the two arguments.
++*/
++static void jsonPatchFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;     /* The JSON that is being patched */
++  JsonParse y;     /* The patch */
++  JsonNode *pResult;   /* The result of the merge */
++
++  UNUSED_PARAM(argc);
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
++    jsonParseReset(&x);
++    return;
++  }
++  pResult = jsonMergePatch(&x, 0, y.aNode);
++  assert( pResult!=0 || x.oom );
++  if( pResult ){
++    jsonReturnJson(pResult, ctx, 0);
++  }else{
++    sqlite3_result_error_nomem(ctx);
++  }
++  jsonParseReset(&x);
++  jsonParseReset(&y);
++}
++
++
++/*
++** Implementation of the json_object(NAME,VALUE,...) function.  Return a JSON
++** object that contains all name/value given in arguments.  Or if any name
++** is not a string or if any value is a BLOB, throw an error.
++*/
++static void jsonObjectFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  JsonString jx;
++  const char *z;
++  u32 n;
++
++  if( argc&1 ){
++    sqlite3_result_error(ctx, "json_object() requires an even number "
++                                  "of arguments", -1);
++    return;
++  }
++  jsonInit(&jx, ctx);
++  jsonAppendChar(&jx, '{');
++  for(i=0; i<argc; i+=2){
++    if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
++      sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
++      jsonReset(&jx);
++      return;
++    }
++    jsonAppendSeparator(&jx);
++    z = (const char*)sqlite3_value_text(argv[i]);
++    n = (u32)sqlite3_value_bytes(argv[i]);
++    jsonAppendString(&jx, z, n);
++    jsonAppendChar(&jx, ':');
++    jsonAppendValue(&jx, argv[i+1]);
++  }
++  jsonAppendChar(&jx, '}');
++  jsonResult(&jx);
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++
++
++/*
++** json_remove(JSON, PATH, ...)
++**
++** Remove the named elements from JSON and return the result.  malformed
++** JSON or PATH arguments result in an error.
++*/
++static void jsonRemoveFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i++){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    if( zPath==0 ) goto remove_done;
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto remove_done;
++    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
++  }
++  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
++    jsonReturnJson(x.aNode, ctx, 0);
++  }
++remove_done:
++  jsonParseReset(&x);
++}
++
++/*
++** json_replace(JSON, PATH, VALUE, ...)
++**
++** Replace the value at PATH with VALUE.  If PATH does not already exist,
++** this routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonReplaceFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, "replace");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    pNode = jsonLookup(&x, zPath, 0, ctx);
++    if( x.nErr ) goto replace_err;
++    if( pNode ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++replace_err:
++  jsonParseReset(&x);
++}
++
++/*
++** json_set(JSON, PATH, VALUE, ...)
++**
++** Set the value at PATH to VALUE.  Create the PATH if it does not already
++** exist.  Overwrite existing values that do exist.
++** If JSON or PATH is malformed, throw an error.
++**
++** json_insert(JSON, PATH, VALUE, ...)
++**
++** Create PATH and initialize it to VALUE.  If PATH already exists, this
++** routine is a no-op.  If JSON or PATH is malformed, throw an error.
++*/
++static void jsonSetFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse x;          /* The parse */
++  JsonNode *pNode;
++  const char *zPath;
++  u32 i;
++  int bApnd;
++  int bIsSet = *(int*)sqlite3_user_data(ctx);
++
++  if( argc<1 ) return;
++  if( (argc&1)==0 ) {
++    jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
++    return;
++  }
++  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
++  assert( x.nNode );
++  for(i=1; i<(u32)argc; i+=2){
++    zPath = (const char*)sqlite3_value_text(argv[i]);
++    bApnd = 0;
++    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
++    if( x.oom ){
++      sqlite3_result_error_nomem(ctx);
++      goto jsonSetDone;
++    }else if( x.nErr ){
++      goto jsonSetDone;
++    }else if( pNode && (bApnd || bIsSet) ){
++      pNode->jnFlags |= (u8)JNODE_REPLACE;
++      pNode->u.iReplace = i + 1;
++    }
++  }
++  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
++    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
++  }else{
++    jsonReturnJson(x.aNode, ctx, argv);
++  }
++jsonSetDone:
++  jsonParseReset(&x);
++}
++
++/*
++** json_type(JSON)
++** json_type(JSON, PATH)
++**
++** Return the top-level "type" of a JSON string.  Throw an error if
++** either the JSON or PATH inputs are not well-formed.
++*/
++static void jsonTypeFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  const char *zPath;
++  JsonNode *pNode;
++
++  p = jsonParseCached(ctx, argv, ctx);
++  if( p==0 ) return;
++  if( argc==2 ){
++    zPath = (const char*)sqlite3_value_text(argv[1]);
++    pNode = jsonLookup(p, zPath, 0, ctx);
++  }else{
++    pNode = p->aNode;
++  }
++  if( pNode ){
++    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
++  }
++}
++
++/*
++** json_valid(JSON)
++**
++** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
++** Return 0 otherwise.
++*/
++static void jsonValidFunc(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonParse *p;          /* The parse */
++  UNUSED_PARAM(argc);
++  p = jsonParseCached(ctx, argv, 0);
++  sqlite3_result_int(ctx, p!=0);
++}
++
++
++/****************************************************************************
++** Aggregate SQL function implementations
++****************************************************************************/
++/*
++** json_group_array(VALUE)
++**
++** Return a JSON array composed of all values in the aggregate.
++*/
++static void jsonArrayStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '[');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    jsonAppendValue(pStr, argv[0]);
++  }
++}
++static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    pStr->pCtx = ctx;
++    jsonAppendChar(pStr, ']');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else if( isFinal ){
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
++      pStr->nUsed--;
++    }
++  }else{
++    sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++static void jsonArrayValue(sqlite3_context *ctx){
++  jsonArrayCompute(ctx, 0);
++}
++static void jsonArrayFinal(sqlite3_context *ctx){
++  jsonArrayCompute(ctx, 1);
++}
++
++#ifndef SQLITE_OMIT_WINDOWFUNC
++/*
++** This method works for both json_group_array() and json_group_object().
++** It works by removing the first element of the group by searching forward
++** to the first comma (",") that is not within a string and deleting all
++** text through that comma.
++*/
++static void jsonGroupInverse(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  int i;
++  int inStr = 0;
++  char *z;
++  JsonString *pStr;
++  UNUSED_PARAM(argc);
++  UNUSED_PARAM(argv);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++#ifdef NEVER
++  /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
++  ** always have been called to initalize it */
++  if( NEVER(!pStr) ) return;
++#endif
++  z = pStr->zBuf;
++  for(i=1; z[i]!=',' || inStr; i++){
++    assert( i<pStr->nUsed );
++    if( z[i]=='"' ){
++      inStr = !inStr;
++    }else if( z[i]=='\\' ){
++      i++;
++    }
++  }
++  pStr->nUsed -= i;      
++  memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
++}
++#else
++# define jsonGroupInverse 0
++#endif
++
++
++/*
++** json_group_obj(NAME,VALUE)
++**
++** Return a JSON object composed of all names and values in the aggregate.
++*/
++static void jsonObjectStep(
++  sqlite3_context *ctx,
++  int argc,
++  sqlite3_value **argv
++){
++  JsonString *pStr;
++  const char *z;
++  u32 n;
++  UNUSED_PARAM(argc);
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
++  if( pStr ){
++    if( pStr->zBuf==0 ){
++      jsonInit(pStr, ctx);
++      jsonAppendChar(pStr, '{');
++    }else{
++      jsonAppendChar(pStr, ',');
++      pStr->pCtx = ctx;
++    }
++    z = (const char*)sqlite3_value_text(argv[0]);
++    n = (u32)sqlite3_value_bytes(argv[0]);
++    jsonAppendString(pStr, z, n);
++    jsonAppendChar(pStr, ':');
++    jsonAppendValue(pStr, argv[1]);
++  }
++}
++static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
++  JsonString *pStr;
++  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
++  if( pStr ){
++    jsonAppendChar(pStr, '}');
++    if( pStr->bErr ){
++      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
++      assert( pStr->bStatic );
++    }else if( isFinal ){
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
++                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
++      pStr->bStatic = 1;
++    }else{
++      sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
++      pStr->nUsed--;
++    }
++  }else{
++    sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
++  }
++  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
++}
++static void jsonObjectValue(sqlite3_context *ctx){
++  jsonObjectCompute(ctx, 0);
++}
++static void jsonObjectFinal(sqlite3_context *ctx){
++  jsonObjectCompute(ctx, 1);
++}
++
++
++
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++/****************************************************************************
++** The json_each virtual table
++****************************************************************************/
++typedef struct JsonEachCursor JsonEachCursor;
++struct JsonEachCursor {
++  sqlite3_vtab_cursor base;  /* Base class - must be first */
++  u32 iRowid;                /* The rowid */
++  u32 iBegin;                /* The first node of the scan */
++  u32 i;                     /* Index in sParse.aNode[] of current row */
++  u32 iEnd;                  /* EOF when i equals or exceeds this value */
++  u8 eType;                  /* Type of top-level element */
++  u8 bRecursive;             /* True for json_tree().  False for json_each() */
++  char *zJson;               /* Input JSON */
++  char *zRoot;               /* Path by which to filter zJson */
++  JsonParse sParse;          /* Parse of the input JSON */
++};
++
++/* Constructor for the json_each virtual table */
++static int jsonEachConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  sqlite3_vtab *pNew;
++  int rc;
++
++/* Column numbers */
++#define JEACH_KEY     0
++#define JEACH_VALUE   1
++#define JEACH_TYPE    2
++#define JEACH_ATOM    3
++#define JEACH_ID      4
++#define JEACH_PARENT  5
++#define JEACH_FULLKEY 6
++#define JEACH_PATH    7
++/* The xBestIndex method assumes that the JSON and ROOT columns are
++** the last two columns in the table.  Should this ever changes, be
++** sure to update the xBestIndex method. */
++#define JEACH_JSON    8
++#define JEACH_ROOT    9
++
++  UNUSED_PARAM(pzErr);
++  UNUSED_PARAM(argv);
++  UNUSED_PARAM(argc);
++  UNUSED_PARAM(pAux);
++  rc = sqlite3_declare_vtab(db, 
++     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
++                    "json HIDDEN,root HIDDEN)");
++  if( rc==SQLITE_OK ){
++    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
++    if( pNew==0 ) return SQLITE_NOMEM;
++    memset(pNew, 0, sizeof(*pNew));
++  }
++  return rc;
++}
++
++/* destructor for json_each virtual table */
++static int jsonEachDisconnect(sqlite3_vtab *pVtab){
++  sqlite3_free(pVtab);
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_each(). */
++static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  JsonEachCursor *pCur;
++
++  UNUSED_PARAM(p);
++  pCur = sqlite3_malloc( sizeof(*pCur) );
++  if( pCur==0 ) return SQLITE_NOMEM;
++  memset(pCur, 0, sizeof(*pCur));
++  *ppCursor = &pCur->base;
++  return SQLITE_OK;
++}
++
++/* constructor for a JsonEachCursor object for json_tree(). */
++static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
++  int rc = jsonEachOpenEach(p, ppCursor);
++  if( rc==SQLITE_OK ){
++    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
++    pCur->bRecursive = 1;
++  }
++  return rc;
++}
++
++/* Reset a JsonEachCursor back to its original state.  Free any memory
++** held. */
++static void jsonEachCursorReset(JsonEachCursor *p){
++  sqlite3_free(p->zJson);
++  sqlite3_free(p->zRoot);
++  jsonParseReset(&p->sParse);
++  p->iRowid = 0;
++  p->i = 0;
++  p->iEnd = 0;
++  p->eType = 0;
++  p->zJson = 0;
++  p->zRoot = 0;
++}
++
++/* Destructor for a jsonEachCursor object */
++static int jsonEachClose(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  jsonEachCursorReset(p);
++  sqlite3_free(cur);
++  return SQLITE_OK;
++}
++
++/* Return TRUE if the jsonEachCursor object has been advanced off the end
++** of the JSON object */
++static int jsonEachEof(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  return p->i >= p->iEnd;
++}
++
++/* Advance the cursor to the next element for json_tree() */
++static int jsonEachNext(sqlite3_vtab_cursor *cur){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  if( p->bRecursive ){
++    if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
++    p->i++;
++    p->iRowid++;
++    if( p->i<p->iEnd ){
++      u32 iUp = p->sParse.aUp[p->i];
++      JsonNode *pUp = &p->sParse.aNode[iUp];
++      p->eType = pUp->eType;
++      if( pUp->eType==JSON_ARRAY ){
++        if( iUp==p->i-1 ){
++          pUp->u.iKey = 0;
++        }else{
++          pUp->u.iKey++;
++        }
++      }
++    }
++  }else{
++    switch( p->eType ){
++      case JSON_ARRAY: {
++        p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
++        p->iRowid++;
++        break;
++      }
++      case JSON_OBJECT: {
++        p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
++        p->iRowid++;
++        break;
++      }
++      default: {
++        p->i = p->iEnd;
++        break;
++      }
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Append the name of the path for element i to pStr
++*/
++static void jsonEachComputePath(
++  JsonEachCursor *p,       /* The cursor */
++  JsonString *pStr,        /* Write the path here */
++  u32 i                    /* Path to this element */
++){
++  JsonNode *pNode, *pUp;
++  u32 iUp;
++  if( i==0 ){
++    jsonAppendChar(pStr, '$');
++    return;
++  }
++  iUp = p->sParse.aUp[i];
++  jsonEachComputePath(p, pStr, iUp);
++  pNode = &p->sParse.aNode[i];
++  pUp = &p->sParse.aNode[iUp];
++  if( pUp->eType==JSON_ARRAY ){
++    jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
++  }else{
++    assert( pUp->eType==JSON_OBJECT );
++    if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
++    assert( pNode->eType==JSON_STRING );
++    assert( pNode->jnFlags & JNODE_LABEL );
++    jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
++  }
++}
++
++/* Return the value of a column */
++static int jsonEachColumn(
++  sqlite3_vtab_cursor *cur,   /* The cursor */
++  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
++  int i                       /* Which column to return */
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  JsonNode *pThis = &p->sParse.aNode[p->i];
++  switch( i ){
++    case JEACH_KEY: {
++      if( p->i==0 ) break;
++      if( p->eType==JSON_OBJECT ){
++        jsonReturn(pThis, ctx, 0);
++      }else if( p->eType==JSON_ARRAY ){
++        u32 iKey;
++        if( p->bRecursive ){
++          if( p->iRowid==0 ) break;
++          iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
++        }else{
++          iKey = p->iRowid;
++        }
++        sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
++      }
++      break;
++    }
++    case JEACH_VALUE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_TYPE: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_ATOM: {
++      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
++      if( pThis->eType>=JSON_ARRAY ) break;
++      jsonReturn(pThis, ctx, 0);
++      break;
++    }
++    case JEACH_ID: {
++      sqlite3_result_int64(ctx, 
++         (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
++      break;
++    }
++    case JEACH_PARENT: {
++      if( p->i>p->iBegin && p->bRecursive ){
++        sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
++      }
++      break;
++    }
++    case JEACH_FULLKEY: {
++      JsonString x;
++      jsonInit(&x, ctx);
++      if( p->bRecursive ){
++        jsonEachComputePath(p, &x, p->i);
++      }else{
++        if( p->zRoot ){
++          jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
++        }else{
++          jsonAppendChar(&x, '$');
++        }
++        if( p->eType==JSON_ARRAY ){
++          jsonPrintf(30, &x, "[%d]", p->iRowid);
++        }else if( p->eType==JSON_OBJECT ){
++          jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
++        }
++      }
++      jsonResult(&x);
++      break;
++    }
++    case JEACH_PATH: {
++      if( p->bRecursive ){
++        JsonString x;
++        jsonInit(&x, ctx);
++        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
++        jsonResult(&x);
++        break;
++      }
++      /* For json_each() path and root are the same so fall through
++      ** into the root case */
++    }
++    default: {
++      const char *zRoot = p->zRoot;
++      if( zRoot==0 ) zRoot = "$";
++      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
++      break;
++    }
++    case JEACH_JSON: {
++      assert( i==JEACH_JSON );
++      sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Return the current rowid value */
++static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  *pRowid = p->iRowid;
++  return SQLITE_OK;
++}
++
++/* The query strategy is to look for an equality constraint on the json
++** column.  Without such a constraint, the table cannot operate.  idxNum is
++** 1 if the constraint is found, 3 if the constraint and zRoot are found,
++** and 0 otherwise.
++*/
++static int jsonEachBestIndex(
++  sqlite3_vtab *tab,
++  sqlite3_index_info *pIdxInfo
++){
++  int i;                     /* Loop counter or computed array index */
++  int aIdx[2];               /* Index of constraints for JSON and ROOT */
++  int unusableMask = 0;      /* Mask of unusable JSON and ROOT constraints */
++  int idxMask = 0;           /* Mask of usable == constraints JSON and ROOT */
++  const struct sqlite3_index_constraint *pConstraint;
++
++  /* This implementation assumes that JSON and ROOT are the last two
++  ** columns in the table */
++  assert( JEACH_ROOT == JEACH_JSON+1 );
++  UNUSED_PARAM(tab);
++  aIdx[0] = aIdx[1] = -1;
++  pConstraint = pIdxInfo->aConstraint;
++  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
++    int iCol;
++    int iMask;
++    if( pConstraint->iColumn < JEACH_JSON ) continue;
++    iCol = pConstraint->iColumn - JEACH_JSON;
++    assert( iCol==0 || iCol==1 );
++    iMask = 1 << iCol;
++    if( pConstraint->usable==0 ){
++      unusableMask |= iMask;
++    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
++      aIdx[iCol] = i;
++      idxMask |= iMask;
++    }
++  }
++  if( (unusableMask & ~idxMask)!=0 ){
++    /* If there are any unusable constraints on JSON or ROOT, then reject
++    ** this entire plan */
++    return SQLITE_CONSTRAINT;
++  }
++  if( aIdx[0]<0 ){
++    /* No JSON input.  Leave estimatedCost at the huge value that it was
++    ** initialized to to discourage the query planner from selecting this
++    ** plan. */
++    pIdxInfo->idxNum = 0;
++  }else{
++    pIdxInfo->estimatedCost = 1.0;
++    i = aIdx[0];
++    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[i].omit = 1;
++    if( aIdx[1]<0 ){
++      pIdxInfo->idxNum = 1;  /* Only JSON supplied.  Plan 1 */
++    }else{
++      i = aIdx[1];
++      pIdxInfo->aConstraintUsage[i].argvIndex = 2;
++      pIdxInfo->aConstraintUsage[i].omit = 1;
++      pIdxInfo->idxNum = 3;  /* Both JSON and ROOT are supplied.  Plan 3 */
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* Start a search on a new JSON string */
++static int jsonEachFilter(
++  sqlite3_vtab_cursor *cur,
++  int idxNum, const char *idxStr,
++  int argc, sqlite3_value **argv
++){
++  JsonEachCursor *p = (JsonEachCursor*)cur;
++  const char *z;
++  const char *zRoot = 0;
++  sqlite3_int64 n;
++
++  UNUSED_PARAM(idxStr);
++  UNUSED_PARAM(argc);
++  jsonEachCursorReset(p);
++  if( idxNum==0 ) return SQLITE_OK;
++  z = (const char*)sqlite3_value_text(argv[0]);
++  if( z==0 ) return SQLITE_OK;
++  n = sqlite3_value_bytes(argv[0]);
++  p->zJson = sqlite3_malloc64( n+1 );
++  if( p->zJson==0 ) return SQLITE_NOMEM;
++  memcpy(p->zJson, z, (size_t)n+1);
++  if( jsonParse(&p->sParse, 0, p->zJson) ){
++    int rc = SQLITE_NOMEM;
++    if( p->sParse.oom==0 ){
++      sqlite3_free(cur->pVtab->zErrMsg);
++      cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
++      if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
++    }
++    jsonEachCursorReset(p);
++    return rc;
++  }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
++    jsonEachCursorReset(p);
++    return SQLITE_NOMEM;
++  }else{
++    JsonNode *pNode = 0;
++    if( idxNum==3 ){
++      const char *zErr = 0;
++      zRoot = (const char*)sqlite3_value_text(argv[1]);
++      if( zRoot==0 ) return SQLITE_OK;
++      n = sqlite3_value_bytes(argv[1]);
++      p->zRoot = sqlite3_malloc64( n+1 );
++      if( p->zRoot==0 ) return SQLITE_NOMEM;
++      memcpy(p->zRoot, zRoot, (size_t)n+1);
++      if( zRoot[0]!='$' ){
++        zErr = zRoot;
++      }else{
++        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
++      }
++      if( zErr ){
++        sqlite3_free(cur->pVtab->zErrMsg);
++        cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
++        jsonEachCursorReset(p);
++        return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
++      }else if( pNode==0 ){
++        return SQLITE_OK;
++      }
++    }else{
++      pNode = p->sParse.aNode;
++    }
++    p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
++    p->eType = pNode->eType;
++    if( p->eType>=JSON_ARRAY ){
++      pNode->u.iKey = 0;
++      p->iEnd = p->i + pNode->n + 1;
++      if( p->bRecursive ){
++        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
++        if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
++          p->i--;
++        }
++      }else{
++        p->i++;
++      }
++    }else{
++      p->iEnd = p->i+1;
++    }
++  }
++  return SQLITE_OK;
++}
++
++/* The methods of the json_each virtual table */
++static sqlite3_module jsonEachModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenEach,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
++};
++
++/* The methods of the json_tree virtual table. */
++static sqlite3_module jsonTreeModule = {
++  0,                         /* iVersion */
++  0,                         /* xCreate */
++  jsonEachConnect,           /* xConnect */
++  jsonEachBestIndex,         /* xBestIndex */
++  jsonEachDisconnect,        /* xDisconnect */
++  0,                         /* xDestroy */
++  jsonEachOpenTree,          /* xOpen - open a cursor */
++  jsonEachClose,             /* xClose - close a cursor */
++  jsonEachFilter,            /* xFilter - configure scan constraints */
++  jsonEachNext,              /* xNext - advance a cursor */
++  jsonEachEof,               /* xEof - check for end of scan */
++  jsonEachColumn,            /* xColumn - read data */
++  jsonEachRowid,             /* xRowid - read data */
++  0,                         /* xUpdate */
++  0,                         /* xBegin */
++  0,                         /* xSync */
++  0,                         /* xCommit */
++  0,                         /* xRollback */
++  0,                         /* xFindMethod */
++  0,                         /* xRename */
++  0,                         /* xSavepoint */
++  0,                         /* xRelease */
++  0,                         /* xRollbackTo */
++  0                          /* xShadowName */
++};
++#endif /* SQLITE_OMIT_VIRTUALTABLE */
++
++/****************************************************************************
++** The following routines are the only publically visible identifiers in this
++** file.  Call the following routines in order to register the various SQL
++** functions and the virtual table implemented by this file.
++****************************************************************************/
++
++SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
++  int rc = SQLITE_OK;
++  unsigned int i;
++  static const struct {
++     const char *zName;
++     int nArg;
++     int flag;
++     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
++  } aFunc[] = {
++    { "json",                 1, 0,   jsonRemoveFunc        },
++    { "json_array",          -1, 0,   jsonArrayFunc         },
++    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
++    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
++    { "json_extract",        -1, 0,   jsonExtractFunc       },
++    { "json_insert",         -1, 0,   jsonSetFunc           },
++    { "json_object",         -1, 0,   jsonObjectFunc        },
++    { "json_patch",           2, 0,   jsonPatchFunc         },
++    { "json_quote",           1, 0,   jsonQuoteFunc         },
++    { "json_remove",         -1, 0,   jsonRemoveFunc        },
++    { "json_replace",        -1, 0,   jsonReplaceFunc       },
++    { "json_set",            -1, 1,   jsonSetFunc           },
++    { "json_type",            1, 0,   jsonTypeFunc          },
++    { "json_type",            2, 0,   jsonTypeFunc          },
++    { "json_valid",           1, 0,   jsonValidFunc         },
++
++#if SQLITE_DEBUG
++    /* DEBUG and TESTING functions */
++    { "json_parse",           1, 0,   jsonParseFunc         },
++    { "json_test1",           1, 0,   jsonTest1Func         },
++#endif
++  };
++  static const struct {
++     const char *zName;
++     int nArg;
++     void (*xStep)(sqlite3_context*,int,sqlite3_value**);
++     void (*xFinal)(sqlite3_context*);
++     void (*xValue)(sqlite3_context*);
++  } aAgg[] = {
++    { "json_group_array",     1,
++      jsonArrayStep,   jsonArrayFinal,  jsonArrayValue  },
++    { "json_group_object",    2,
++      jsonObjectStep,  jsonObjectFinal, jsonObjectValue },
++  };
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  static const struct {
++     const char *zName;
++     sqlite3_module *pModule;
++  } aMod[] = {
++    { "json_each",            &jsonEachModule               },
++    { "json_tree",            &jsonTreeModule               },
++  };
++#endif
++  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
++                                 (void*)&aFunc[i].flag,
++                                 aFunc[i].xFunc, 0, 0);
++  }
++#ifndef SQLITE_OMIT_WINDOWFUNC
++  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
++                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
++                                 aAgg[i].xStep, aAgg[i].xFinal,
++                                 aAgg[i].xValue, jsonGroupInverse, 0);
++  }
++#endif
++#ifndef SQLITE_OMIT_VIRTUALTABLE
++  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
++  }
++#endif
++  return rc;
++}
++
++
++#ifndef SQLITE_CORE
++#ifdef _WIN32
++__declspec(dllexport)
++#endif
++SQLITE_API int sqlite3_json_init(
++  sqlite3 *db, 
++  char **pzErrMsg, 
++  const sqlite3_api_routines *pApi
++){
++  SQLITE_EXTENSION_INIT2(pApi);
++  (void)pzErrMsg;  /* Unused parameter */
++  return sqlite3Json1Init(db);
++}
++#endif
++#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
++
++/************** End of json1.c ***********************************************/
+ /************** Begin file rtree.c *******************************************/
+ /*
+ ** 2001 September 15
+@@ -168822,7 +179149,7 @@
+ **
+ **   CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
+ **   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+-**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
++**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
+ **
+ ** The data for each node of the r-tree structure is stored in the %_node
+ ** table. For each node that is not the root node of the r-tree, there is
+@@ -168829,7 +179156,8 @@
+ ** an entry in the %_parent table associating the node with its parent.
+ ** And for each row of data in the table, there is an entry in the %_rowid
+ ** table that maps from the entries rowid to the id of the node that it
+-** is stored on.
++** is stored on.  If the r-tree contains auxiliary columns, those are stored
++** on the end of the %_rowid table.
+ **
+ ** The root node of an r-tree always exists, even if the r-tree table is
+ ** empty. The nodeno of the root node is always 1. All other nodes in the
+@@ -168892,6 +179220,9 @@
+ /* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
+ #define RTREE_MAX_DIMENSIONS 5
+ 
++/* Maximum number of auxiliary columns */
++#define RTREE_MAX_AUX_COLUMN 100
++
+ /* Size of hash table Rtree.aHash. This hash table is not expected to
+ ** ever contain very many entries, so a fixed number of buckets is 
+ ** used.
+@@ -168920,6 +179251,8 @@
+   u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
+   u8 nBytesPerCell;           /* Bytes consumed per cell */
+   u8 inWrTrans;               /* True if inside write transaction */
++  u8 nAux;                    /* # of auxiliary columns in %_rowid */
++  u8 nAuxNotNull;             /* Number of initial not-null aux columns */
+   int iDepth;                 /* Current depth of the r-tree structure */
+   char *zDb;                  /* Name of database containing r-tree table */
+   char *zName;                /* Name of r-tree table */ 
+@@ -168926,6 +179259,8 @@
+   u32 nBusy;                  /* Current number of users of this structure */
+   i64 nRowEst;                /* Estimated number of rows in this table */
+   u32 nCursor;                /* Number of open cursors */
++  u32 nNodeRef;               /* Number RtreeNodes with positive nRef */
++  char *zReadAuxSql;          /* SQL for statement to read aux data */
+ 
+   /* List of nodes removed during a CondenseTree operation. List is
+   ** linked together via the pointer normally used for hash chains -
+@@ -168952,6 +179287,9 @@
+   sqlite3_stmt *pWriteParent;
+   sqlite3_stmt *pDeleteParent;
+ 
++  /* Statement for writing to the "aux:" fields, if there are any */
++  sqlite3_stmt *pWriteAux;
++
+   RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
+ };
+ 
+@@ -169028,6 +179366,7 @@
+   sqlite3_vtab_cursor base;         /* Base class.  Must be first */
+   u8 atEOF;                         /* True if at end of search */
+   u8 bPoint;                        /* True if sPoint is valid */
++  u8 bAuxValid;                     /* True if pReadAux is valid */
+   int iStrategy;                    /* Copy of idxNum search parameter */
+   int nConstraint;                  /* Number of entries in aConstraint */
+   RtreeConstraint *aConstraint;     /* Search constraints. */
+@@ -169035,6 +179374,7 @@
+   int nPoint;                       /* Number of slots used in aPoint[] */
+   int mxLevel;                      /* iLevel value for root of the tree */
+   RtreeSearchPoint *aPoint;         /* Priority queue for search points */
++  sqlite3_stmt *pReadAux;           /* Statement to read aux-data */
+   RtreeSearchPoint sPoint;          /* Cached next search point */
+   RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */
+   u32 anQueue[RTREE_MAX_DEPTH+1];   /* Number of queued entries by iLevel */
+@@ -169321,6 +179661,7 @@
+ */
+ static void nodeReference(RtreeNode *p){
+   if( p ){
++    assert( p->nRef>0 );
+     p->nRef++;
+   }
+ }
+@@ -169388,6 +179729,7 @@
+     memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
+     pNode->zData = (u8 *)&pNode[1];
+     pNode->nRef = 1;
++    pRtree->nNodeRef++;
+     pNode->pParent = pParent;
+     pNode->isDirty = 1;
+     nodeReference(pParent);
+@@ -169421,10 +179763,10 @@
+   /* Check if the requested node is already in the hash table. If so,
+   ** increase its reference count and return it.
+   */
+-  if( (pNode = nodeHashLookup(pRtree, iNode)) ){
++  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
+     assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
+     if( pParent && !pNode->pParent ){
+-      nodeReference(pParent);
++      pParent->nRef++;
+       pNode->pParent = pParent;
+     }
+     pNode->nRef++;
+@@ -169463,6 +179805,7 @@
+       pNode->pParent = pParent;
+       pNode->zData = (u8 *)&pNode[1];
+       pNode->nRef = 1;
++      pRtree->nNodeRef++;
+       pNode->iNode = iNode;
+       pNode->isDirty = 0;
+       pNode->pNext = 0;
+@@ -169503,7 +179846,10 @@
+     }
+     *ppNode = pNode;
+   }else{
+-    sqlite3_free(pNode);
++    if( pNode ){
++      pRtree->nNodeRef--;
++      sqlite3_free(pNode);
++    }
+     *ppNode = 0;
+   }
+ 
+@@ -169600,8 +179946,10 @@
+   int rc = SQLITE_OK;
+   if( pNode ){
+     assert( pNode->nRef>0 );
++    assert( pRtree->nNodeRef>0 );
+     pNode->nRef--;
+     if( pNode->nRef==0 ){
++      pRtree->nNodeRef--;
+       if( pNode->iNode==1 ){
+         pRtree->iDepth = -1;
+       }
+@@ -169718,8 +180066,9 @@
+   pRtree->nBusy--;
+   if( pRtree->nBusy==0 ){
+     pRtree->inWrTrans = 0;
+-    pRtree->nCursor = 0;
++    assert( pRtree->nCursor==0 );
+     nodeBlobReset(pRtree);
++    assert( pRtree->nNodeRef==0 );
+     sqlite3_finalize(pRtree->pWriteNode);
+     sqlite3_finalize(pRtree->pDeleteNode);
+     sqlite3_finalize(pRtree->pReadRowid);
+@@ -169728,6 +180077,8 @@
+     sqlite3_finalize(pRtree->pReadParent);
+     sqlite3_finalize(pRtree->pWriteParent);
+     sqlite3_finalize(pRtree->pDeleteParent);
++    sqlite3_finalize(pRtree->pWriteAux);
++    sqlite3_free(pRtree->zReadAuxSql);
+     sqlite3_free(pRtree);
+   }
+ }
+@@ -169816,6 +180167,7 @@
+   RtreeCursor *pCsr = (RtreeCursor *)cur;
+   assert( pRtree->nCursor>0 );
+   freeCursorConstraints(pCsr);
++  sqlite3_finalize(pCsr->pReadAux);
+   sqlite3_free(pCsr->aPoint);
+   for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
+   sqlite3_free(pCsr);
+@@ -170187,7 +180539,7 @@
+       if( ii<RTREE_CACHE_SZ ){
+         assert( pCur->aNode[ii]==0 );
+         pCur->aNode[ii] = pCur->aNode[0];
+-       }else{
++      }else{
+         nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
+       }
+       pCur->aNode[0] = 0;
+@@ -170358,6 +180710,10 @@
+ 
+   /* Move to the next entry that matches the configured constraints. */
+   RTREE_QUEUE_TRACE(pCsr, "POP-Nx:");
++  if( pCsr->bAuxValid ){
++    pCsr->bAuxValid = 0;
++    sqlite3_reset(pCsr->pReadAux);
++  }
+   rtreeSearchPointPop(pCsr);
+   rc = rtreeStepToLeaf(pCsr);
+   return rc;
+@@ -170392,7 +180748,7 @@
+   if( p==0 ) return SQLITE_OK;
+   if( i==0 ){
+     sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
+-  }else{
++  }else if( i<=pRtree->nDim2 ){
+     nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+@@ -170403,7 +180759,27 @@
+       assert( pRtree->eCoordType==RTREE_COORD_INT32 );
+       sqlite3_result_int(ctx, c.i);
+     }
+-  }
++  }else{
++    if( !pCsr->bAuxValid ){
++      if( pCsr->pReadAux==0 ){
++        rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
++                                &pCsr->pReadAux, 0);
++        if( rc ) return rc;
++      }
++      sqlite3_bind_int64(pCsr->pReadAux, 1, 
++          nodeGetRowid(pRtree, pNode, p->iCell));
++      rc = sqlite3_step(pCsr->pReadAux);
++      if( rc==SQLITE_ROW ){
++        pCsr->bAuxValid = 1;
++      }else{
++        sqlite3_reset(pCsr->pReadAux);
++        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++        return rc;
++      }
++    }
++    sqlite3_result_value(ctx,
++         sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1));
++  }  
+   return SQLITE_OK;
+ }
+ 
+@@ -170481,6 +180857,7 @@
+   int ii;
+   int rc = SQLITE_OK;
+   int iCell = 0;
++  sqlite3_stmt *pStmt;
+ 
+   rtreeReference(pRtree);
+ 
+@@ -170487,8 +180864,10 @@
+   /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
+   freeCursorConstraints(pCsr);
+   sqlite3_free(pCsr->aPoint);
++  pStmt = pCsr->pReadAux;
+   memset(pCsr, 0, sizeof(RtreeCursor));
+   pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
++  pCsr->pReadAux = pStmt;
+ 
+   pCsr->iStrategy = idxNum;
+   if( idxNum==1 ){
+@@ -170651,10 +181030,14 @@
+       */ 
+       pIdxInfo->estimatedCost = 30.0;
+       pIdxInfo->estimatedRows = 1;
++      pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
+       return SQLITE_OK;
+     }
+ 
+-    if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
++    if( p->usable
++    && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
++        || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
++    ){
+       u8 op;
+       switch( p->op ){
+         case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
+@@ -171227,7 +181610,7 @@
+   }else{
+     pLeft = pNode;
+     pRight = nodeNew(pRtree, pLeft->pParent);
+-    nodeReference(pLeft);
++    pLeft->nRef++;
+   }
+ 
+   if( !pLeft || !pRight ){
+@@ -171636,7 +182019,7 @@
+ /*
+ ** Select a currently unused rowid for a new r-tree record.
+ */
+-static int newRowid(Rtree *pRtree, i64 *piRowid){
++static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){
+   int rc;
+   sqlite3_bind_null(pRtree->pWriteRowid, 1);
+   sqlite3_bind_null(pRtree->pWriteRowid, 2);
+@@ -171717,6 +182100,7 @@
+       rc = reinsertNodeContent(pRtree, pLeaf);
+     }
+     pRtree->pDeleted = pLeaf->pNext;
++    pRtree->nNodeRef--;
+     sqlite3_free(pLeaf);
+   }
+ 
+@@ -171813,7 +182197,7 @@
+ static int rtreeUpdate(
+   sqlite3_vtab *pVtab, 
+   int nData, 
+-  sqlite3_value **azData, 
++  sqlite3_value **aData, 
+   sqlite_int64 *pRowid
+ ){
+   Rtree *pRtree = (Rtree *)pVtab;
+@@ -171821,6 +182205,12 @@
+   RtreeCell cell;                 /* New cell to insert if nData>1 */
+   int bHaveRowid = 0;             /* Set to 1 after new rowid is determined */
+ 
++  if( pRtree->nNodeRef ){
++    /* Unable to write to the btree while another cursor is reading from it,
++    ** since the write might do a rebalance which would disrupt the read
++    ** cursor. */
++    return SQLITE_LOCKED_VTAB;
++  }
+   rtreeReference(pRtree);
+   assert(nData>=1);
+ 
+@@ -171839,8 +182229,10 @@
+   */
+   if( nData>1 ){
+     int ii;
++    int nn = nData - 4;
+ 
+-    /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
++    if( nn > pRtree->nDim2 ) nn = pRtree->nDim2;
++    /* Populate the cell.aCoord[] array. The first coordinate is aData[3].
+     **
+     ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
+     ** with "column" that are interpreted as table constraints.
+@@ -171848,13 +182240,12 @@
+     ** This problem was discovered after years of use, so we silently ignore
+     ** these kinds of misdeclared tables to avoid breaking any legacy.
+     */
+-    assert( nData<=(pRtree->nDim2 + 3) );
+ 
+ #ifndef SQLITE_RTREE_INT_ONLY
+     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+-      for(ii=0; ii<nData-4; ii+=2){
+-        cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
+-        cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
++      for(ii=0; ii<nn; ii+=2){
++        cell.aCoord[ii].f = rtreeValueDown(aData[ii+3]);
++        cell.aCoord[ii+1].f = rtreeValueUp(aData[ii+4]);
+         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
+           rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+@@ -171863,9 +182254,9 @@
+     }else
+ #endif
+     {
+-      for(ii=0; ii<nData-4; ii+=2){
+-        cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
+-        cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
++      for(ii=0; ii<nn; ii+=2){
++        cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]);
++        cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]);
+         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
+           rc = rtreeConstraintError(pRtree, ii+1);
+           goto constraint;
+@@ -171875,10 +182266,10 @@
+ 
+     /* If a rowid value was supplied, check if it is already present in 
+     ** the table. If so, the constraint has failed. */
+-    if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){
+-      cell.iRowid = sqlite3_value_int64(azData[2]);
+-      if( sqlite3_value_type(azData[0])==SQLITE_NULL
+-       || sqlite3_value_int64(azData[0])!=cell.iRowid
++    if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){
++      cell.iRowid = sqlite3_value_int64(aData[2]);
++      if( sqlite3_value_type(aData[0])==SQLITE_NULL
++       || sqlite3_value_int64(aData[0])!=cell.iRowid
+       ){
+         int steprc;
+         sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
+@@ -171897,16 +182288,16 @@
+     }
+   }
+ 
+-  /* If azData[0] is not an SQL NULL value, it is the rowid of a
++  /* If aData[0] is not an SQL NULL value, it is the rowid of a
+   ** record to delete from the r-tree table. The following block does
+   ** just that.
+   */
+-  if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
+-    rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0]));
++  if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){
++    rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0]));
+   }
+ 
+-  /* If the azData[] array contains more than one element, elements
+-  ** (azData[2]..azData[argc-1]) contain a new record to insert into
++  /* If the aData[] array contains more than one element, elements
++  ** (aData[2]..aData[argc-1]) contain a new record to insert into
+   ** the r-tree structure.
+   */
+   if( rc==SQLITE_OK && nData>1 ){
+@@ -171915,7 +182306,7 @@
+ 
+     /* Figure out the rowid of the new row. */
+     if( bHaveRowid==0 ){
+-      rc = newRowid(pRtree, &cell.iRowid);
++      rc = rtreeNewRowid(pRtree, &cell.iRowid);
+     }
+     *pRowid = cell.iRowid;
+ 
+@@ -171931,6 +182322,16 @@
+         rc = rc2;
+       }
+     }
++    if( pRtree->nAux ){
++      sqlite3_stmt *pUp = pRtree->pWriteAux;
++      int jj;
++      sqlite3_bind_int64(pUp, 1, *pRowid);
++      for(jj=0; jj<pRtree->nAux; jj++){
++        sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
++      }
++      sqlite3_step(pUp);
++      rc = sqlite3_reset(pUp);
++    }
+   }
+ 
+ constraint:
+@@ -171997,7 +182398,7 @@
+ */
+ static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){
+   Rtree *pRtree = (Rtree *)pVtab;
+-  int iwt = pRtree->inWrTrans;
++  u8 iwt = pRtree->inWrTrans;
+   UNUSED_PARAMETER(iSavepoint);
+   pRtree->inWrTrans = 0;
+   nodeBlobReset(pRtree);
+@@ -172049,8 +182450,24 @@
+   return rc;
+ }
+ 
++
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int rtreeShadowName(const char *zName){
++  static const char *azName[] = {
++    "node", "parent", "rowid"
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static sqlite3_module rtreeModule = {
+-  2,                          /* iVersion */
++  3,                          /* iVersion */
+   rtreeCreate,                /* xCreate - create a table */
+   rtreeConnect,               /* xConnect - connect to an existing table */
+   rtreeBestIndex,             /* xBestIndex - Determine search strategy */
+@@ -172073,6 +182490,7 @@
+   rtreeSavepoint,             /* xSavepoint */
+   0,                          /* xRelease */
+   0,                          /* xRollbackTo */
++  rtreeShadowName             /* xShadowName */
+ };
+ 
+ static int rtreeSqlInit(
+@@ -172087,18 +182505,18 @@
+   #define N_STATEMENT 8
+   static const char *azSql[N_STATEMENT] = {
+     /* Write the xxx_node table */
+-    "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
++    "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_node' WHERE nodeno = ?1",
+ 
+     /* Read and write the xxx_rowid table */
+-    "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
+-    "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
++    "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = ?1",
++    "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_rowid' WHERE rowid = ?1",
+ 
+     /* Read and write the xxx_parent table */
+-    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
+-    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
+-    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
++    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
++    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
++    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
+   };
+   sqlite3_stmt **appStmt[N_STATEMENT];
+   int i;
+@@ -172106,14 +182524,25 @@
+   pRtree->db = db;
+ 
+   if( isCreate ){
+-    char *zCreate = sqlite3_mprintf(
+-"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
+-"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
+-"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,"
+-                                  " parentnode INTEGER);"
+-"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
+-      zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
+-    );
++    char *zCreate;
++    sqlite3_str *p = sqlite3_str_new(db);
++    int ii;
++    sqlite3_str_appendf(p,
++       "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno",
++       zDb, zPrefix);
++    for(ii=0; ii<pRtree->nAux; ii++){
++      sqlite3_str_appendf(p,",a%d",ii);
++    }
++    sqlite3_str_appendf(p,
++      ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);",
++      zDb, zPrefix);
++    sqlite3_str_appendf(p,
++    "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);",
++      zDb, zPrefix);
++    sqlite3_str_appendf(p,
++       "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))",
++       zDb, zPrefix, pRtree->iNodeSize);
++    zCreate = sqlite3_str_finish(p);
+     if( !zCreate ){
+       return SQLITE_NOMEM;
+     }
+@@ -172135,7 +182564,17 @@
+ 
+   rc = rtreeQueryStat1(db, pRtree);
+   for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
+-    char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
++    char *zSql;
++    const char *zFormat;
++    if( i!=3 || pRtree->nAux==0 ){
++       zFormat = azSql[i];
++    }else {
++       /* An UPSERT is very slightly slower than REPLACE, but it is needed
++       ** if there are auxiliary columns */
++       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
++                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
++    }
++    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
+     if( zSql ){
+       rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
+                               appStmt[i], 0); 
+@@ -172144,6 +182583,36 @@
+     }
+     sqlite3_free(zSql);
+   }
++  if( pRtree->nAux ){
++    pRtree->zReadAuxSql = sqlite3_mprintf(
++       "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1",
++       zDb, zPrefix);
++    if( pRtree->zReadAuxSql==0 ){
++      rc = SQLITE_NOMEM;
++    }else{
++      sqlite3_str *p = sqlite3_str_new(db);
++      int ii;
++      char *zSql;
++      sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
++      for(ii=0; ii<pRtree->nAux; ii++){
++        if( ii ) sqlite3_str_append(p, ",", 1);
++        if( ii<pRtree->nAuxNotNull ){
++          sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
++        }else{
++          sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
++        }
++      }
++      sqlite3_str_appendf(p, " WHERE rowid=?1");
++      zSql = sqlite3_str_finish(p);
++      if( zSql==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
++                                &pRtree->pWriteAux, 0); 
++        sqlite3_free(zSql);
++      }
++    }
++  }
+ 
+   return rc;
+ }
+@@ -172246,17 +182715,22 @@
+   int nDb;              /* Length of string argv[1] */
+   int nName;            /* Length of string argv[2] */
+   int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32);
++  sqlite3_str *pSql;
++  char *zSql;
++  int ii = 4;
++  int iErr;
+ 
+   const char *aErrMsg[] = {
+     0,                                                    /* 0 */
+     "Wrong number of columns for an rtree table",         /* 1 */
+     "Too few columns for an rtree table",                 /* 2 */
+-    "Too many columns for an rtree table"                 /* 3 */
++    "Too many columns for an rtree table",                /* 3 */
++    "Auxiliary rtree columns must be last"                /* 4 */
+   };
+ 
+-  int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
+-  if( aErrMsg[iErr] ){
+-    *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
++  assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */
++  if( argc>RTREE_MAX_AUX_COLUMN+3 ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[3]);
+     return SQLITE_ERROR;
+   }
+ 
+@@ -172274,53 +182748,73 @@
+   pRtree->base.pModule = &rtreeModule;
+   pRtree->zDb = (char *)&pRtree[1];
+   pRtree->zName = &pRtree->zDb[nDb+1];
+-  pRtree->nDim = (u8)((argc-4)/2);
+-  pRtree->nDim2 = pRtree->nDim*2;
+-  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
+   pRtree->eCoordType = (u8)eCoordType;
+   memcpy(pRtree->zDb, argv[1], nDb);
+   memcpy(pRtree->zName, argv[2], nName);
+ 
+-  /* Figure out the node size to use. */
+-  rc = getNodeSize(db, pRtree, isCreate, pzErr);
+ 
+   /* Create/Connect to the underlying relational database schema. If
+   ** that is successful, call sqlite3_declare_vtab() to configure
+   ** the r-tree table schema.
+   */
+-  if( rc==SQLITE_OK ){
+-    if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
+-      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  pSql = sqlite3_str_new(db);
++  sqlite3_str_appendf(pSql, "CREATE TABLE x(%s", argv[3]);
++  for(ii=4; ii<argc; ii++){
++    if( argv[ii][0]=='+' ){
++      pRtree->nAux++;
++      sqlite3_str_appendf(pSql, ",%s", argv[ii]+1);
++    }else if( pRtree->nAux>0 ){
++      break;
+     }else{
+-      char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
+-      char *zTmp;
+-      int ii;
+-      for(ii=4; zSql && ii<argc; ii++){
+-        zTmp = zSql;
+-        zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
+-        sqlite3_free(zTmp);
+-      }
+-      if( zSql ){
+-        zTmp = zSql;
+-        zSql = sqlite3_mprintf("%s);", zTmp);
+-        sqlite3_free(zTmp);
+-      }
+-      if( !zSql ){
+-        rc = SQLITE_NOMEM;
+-      }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
+-        *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+-      }
+-      sqlite3_free(zSql);
++      pRtree->nDim2++;
++      sqlite3_str_appendf(pSql, ",%s", argv[ii]);
+     }
+   }
+-
+-  if( rc==SQLITE_OK ){
+-    *ppVtab = (sqlite3_vtab *)pRtree;
++  sqlite3_str_appendf(pSql, ");");
++  zSql = sqlite3_str_finish(pSql);
++  if( !zSql ){
++    rc = SQLITE_NOMEM;
++  }else if( ii<argc ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[4]);
++    rc = SQLITE_ERROR;
++  }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++  sqlite3_free(zSql);
++  if( rc ) goto rtreeInit_fail;
++  pRtree->nDim = pRtree->nDim2/2;
++  if( pRtree->nDim<1 ){
++    iErr = 2;
++  }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){
++    iErr = 3;
++  }else if( pRtree->nDim2 % 2 ){
++    iErr = 1;
+   }else{
+-    assert( *ppVtab==0 );
+-    assert( pRtree->nBusy==1 );
+-    rtreeRelease(pRtree);
++    iErr = 0;
+   }
++  if( iErr ){
++    *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
++    goto rtreeInit_fail;
++  }
++  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
++
++  /* Figure out the node size to use. */
++  rc = getNodeSize(db, pRtree, isCreate, pzErr);
++  if( rc ) goto rtreeInit_fail;
++  rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
++  if( rc ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    goto rtreeInit_fail;
++  }
++
++  *ppVtab = (sqlite3_vtab *)pRtree;
++  return SQLITE_OK;
++
++rtreeInit_fail:
++  if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
++  assert( *ppVtab==0 );
++  assert( pRtree->nBusy==1 );
++  rtreeRelease(pRtree);
+   return rc;
+ }
+ 
+@@ -172549,7 +183043,7 @@
+ ** two tables are:
+ **
+ **   CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+-**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
++**   CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...)
+ **
+ ** In both cases, this function checks that there exists an entry with
+ ** IPK value iKey and the second column set to iVal.
+@@ -172564,8 +183058,8 @@
+   int rc;
+   sqlite3_stmt *pStmt;
+   const char *azSql[2] = {
+-    "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?",
+-    "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?"
++    "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1",
++    "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1"
+   };
+ 
+   assert( bLeaf==0 || bLeaf==1 );
+@@ -172749,6 +183243,7 @@
+   RtreeCheck check;               /* Common context for various routines */
+   sqlite3_stmt *pStmt = 0;        /* Used to find column count of rtree table */
+   int bEnd = 0;                   /* True if transaction should be closed */
++  int nAux = 0;                   /* Number of extra columns. */
+ 
+   /* Initialize the context object */
+   memset(&check, 0, sizeof(check));
+@@ -172764,11 +183259,21 @@
+     bEnd = 1;
+   }
+ 
++  /* Find the number of auxiliary columns */
++  if( check.rc==SQLITE_OK ){
++    pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
++    if( pStmt ){
++      nAux = sqlite3_column_count(pStmt) - 2;
++      sqlite3_finalize(pStmt);
++    }
++    check.rc = SQLITE_OK;
++  }
++
+   /* Find number of dimensions in the rtree table. */
+   pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
+   if( pStmt ){
+     int rc;
+-    check.nDim = (sqlite3_column_count(pStmt) - 1) / 2;
++    check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;
+     if( check.nDim<1 ){
+       rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
+     }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
+@@ -172864,8 +183369,1813 @@
+   }
+ }
+ 
++/* Conditionally include the geopoly code */
++#ifdef SQLITE_ENABLE_GEOPOLY
++/************** Include geopoly.c in the middle of rtree.c *******************/
++/************** Begin file geopoly.c *****************************************/
++/*
++** 2018-05-25
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file implements an alternative R-Tree virtual table that
++** uses polygons to express the boundaries of 2-dimensional objects.
++**
++** This file is #include-ed onto the end of "rtree.c" so that it has
++** access to all of the R-Tree internals.
++*/
++/* #include <stdlib.h> */
+ 
++/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */
++#ifdef GEOPOLY_ENABLE_DEBUG
++  static int geo_debug = 0;
++# define GEODEBUG(X) if(geo_debug)printf X
++#else
++# define GEODEBUG(X)
++#endif
++
++#ifndef JSON_NULL   /* The following stuff repeats things found in json1 */
+ /*
++** Versions of isspace(), isalnum() and isdigit() to which it is safe
++** to pass signed char values.
++*/
++#ifdef sqlite3Isdigit
++   /* Use the SQLite core versions if this routine is part of the
++   ** SQLite amalgamation */
++#  define safe_isdigit(x)  sqlite3Isdigit(x)
++#  define safe_isalnum(x)  sqlite3Isalnum(x)
++#  define safe_isxdigit(x) sqlite3Isxdigit(x)
++#else
++   /* Use the standard library for separate compilation */
++#include <ctype.h>  /* amalgamator: keep */
++#  define safe_isdigit(x)  isdigit((unsigned char)(x))
++#  define safe_isalnum(x)  isalnum((unsigned char)(x))
++#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
++#endif
++
++/*
++** Growing our own isspace() routine this way is twice as fast as
++** the library isspace() function.
++*/
++static const char geopolyIsSpace[] = {
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
++};
++#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x])
++#endif /* JSON NULL - back to original code */
++
++/* Compiler and version */
++#ifndef GCC_VERSION
++#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
++#else
++# define GCC_VERSION 0
++#endif
++#endif
++#ifndef MSVC_VERSION
++#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
++# define MSVC_VERSION _MSC_VER
++#else
++# define MSVC_VERSION 0
++#endif
++#endif
++
++/* Datatype for coordinates
++*/
++typedef float GeoCoord;
++
++/*
++** Internal representation of a polygon.
++**
++** The polygon consists of a sequence of vertexes.  There is a line
++** segment between each pair of vertexes, and one final segment from
++** the last vertex back to the first.  (This differs from the GeoJSON
++** standard in which the final vertex is a repeat of the first.)
++**
++** The polygon follows the right-hand rule.  The area to the right of
++** each segment is "outside" and the area to the left is "inside".
++**
++** The on-disk representation consists of a 4-byte header followed by
++** the values.  The 4-byte header is:
++**
++**      encoding    (1 byte)   0=big-endian, 1=little-endian
++**      nvertex     (3 bytes)  Number of vertexes as a big-endian integer
++**
++** Enough space is allocated for 4 coordinates, to work around over-zealous
++** warnings coming from some compiler (notably, clang). In reality, the size
++** of each GeoPoly memory allocate is adjusted as necessary so that the
++** GeoPoly.a[] array at the end is the appropriate size.
++*/
++typedef struct GeoPoly GeoPoly;
++struct GeoPoly {
++  int nVertex;          /* Number of vertexes */
++  unsigned char hdr[4]; /* Header for on-disk representation */
++  GeoCoord a[8];        /* 2*nVertex values. X (longitude) first, then Y */
++};
++
++/* The size of a memory allocation needed for a GeoPoly object sufficient
++** to hold N coordinate pairs.
++*/
++#define GEOPOLY_SZ(N)  (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
++
++/*
++** State of a parse of a GeoJSON input.
++*/
++typedef struct GeoParse GeoParse;
++struct GeoParse {
++  const unsigned char *z;   /* Unparsed input */
++  int nVertex;              /* Number of vertexes in a[] */
++  int nAlloc;               /* Space allocated to a[] */
++  int nErr;                 /* Number of errors encountered */
++  GeoCoord *a;          /* Array of vertexes.  From sqlite3_malloc64() */
++};
++
++/* Do a 4-byte byte swap */
++static void geopolySwab32(unsigned char *a){
++  unsigned char t = a[0];
++  a[0] = a[3];
++  a[3] = t;
++  t = a[1];
++  a[1] = a[2];
++  a[2] = t;
++}
++
++/* Skip whitespace.  Return the next non-whitespace character. */
++static char geopolySkipSpace(GeoParse *p){
++  while( safe_isspace(p->z[0]) ) p->z++;
++  return p->z[0];
++}
++
++/* Parse out a number.  Write the value into *pVal if pVal!=0.
++** return non-zero on success and zero if the next token is not a number.
++*/
++static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
++  char c = geopolySkipSpace(p);
++  const unsigned char *z = p->z;
++  int j = 0;
++  int seenDP = 0;
++  int seenE = 0;
++  if( c=='-' ){
++    j = 1;
++    c = z[j];
++  }
++  if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
++  for(;; j++){
++    c = z[j];
++    if( safe_isdigit(c) ) continue;
++    if( c=='.' ){
++      if( z[j-1]=='-' ) return 0;
++      if( seenDP ) return 0;
++      seenDP = 1;
++      continue;
++    }
++    if( c=='e' || c=='E' ){
++      if( z[j-1]<'0' ) return 0;
++      if( seenE ) return -1;
++      seenDP = seenE = 1;
++      c = z[j+1];
++      if( c=='+' || c=='-' ){
++        j++;
++        c = z[j+1];
++      }
++      if( c<'0' || c>'9' ) return 0;
++      continue;
++    }
++    break;
++  }
++  if( z[j-1]<'0' ) return 0;
++  if( pVal ){
++#ifdef SQLITE_AMALGAMATION
++     /* The sqlite3AtoF() routine is much much faster than atof(), if it
++     ** is available */
++     double r;
++     (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
++     *pVal = r;
++#else
++     *pVal = (GeoCoord)atof((const char*)p->z);
++#endif
++  }
++  p->z += j;
++  return 1;
++}
++
++/*
++** If the input is a well-formed JSON array of coordinates with at least
++** four coordinates and where each coordinate is itself a two-value array,
++** then convert the JSON into a GeoPoly object and return a pointer to
++** that object.
++**
++** If any error occurs, return NULL.
++*/
++static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
++  GeoParse s;
++  int rc = SQLITE_OK;
++  memset(&s, 0, sizeof(s));
++  s.z = z;
++  if( geopolySkipSpace(&s)=='[' ){
++    s.z++;
++    while( geopolySkipSpace(&s)=='[' ){
++      int ii = 0;
++      char c;
++      s.z++;
++      if( s.nVertex>=s.nAlloc ){
++        GeoCoord *aNew;
++        s.nAlloc = s.nAlloc*2 + 16;
++        aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 );
++        if( aNew==0 ){
++          rc = SQLITE_NOMEM;
++          s.nErr++;
++          break;
++        }
++        s.a = aNew;
++      }
++      while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){
++        ii++;
++        if( ii==2 ) s.nVertex++;
++        c = geopolySkipSpace(&s);
++        s.z++;
++        if( c==',' ) continue;
++        if( c==']' && ii>=2 ) break;
++        s.nErr++;
++        rc = SQLITE_ERROR;
++        goto parse_json_err;
++      }
++      if( geopolySkipSpace(&s)==',' ){
++        s.z++;
++        continue;
++      }
++      break;
++    }
++    if( geopolySkipSpace(&s)==']'
++     && s.nVertex>=4
++     && s.a[0]==s.a[s.nVertex*2-2]
++     && s.a[1]==s.a[s.nVertex*2-1]
++     && (s.z++, geopolySkipSpace(&s)==0)
++    ){
++      GeoPoly *pOut;
++      int x = 1;
++      s.nVertex--;  /* Remove the redundant vertex at the end */
++      pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
++      x = 1;
++      if( pOut==0 ) goto parse_json_err;
++      pOut->nVertex = s.nVertex;
++      memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
++      pOut->hdr[0] = *(unsigned char*)&x;
++      pOut->hdr[1] = (s.nVertex>>16)&0xff;
++      pOut->hdr[2] = (s.nVertex>>8)&0xff;
++      pOut->hdr[3] = s.nVertex&0xff;
++      sqlite3_free(s.a);
++      if( pRc ) *pRc = SQLITE_OK;
++      return pOut;
++    }else{
++      s.nErr++;
++      rc = SQLITE_ERROR;
++    }
++  }
++parse_json_err:
++  if( pRc ) *pRc = rc;
++  sqlite3_free(s.a);
++  return 0;
++}
++
++/*
++** Given a function parameter, try to interpret it as a polygon, either
++** in the binary format or JSON text.  Compute a GeoPoly object and
++** return a pointer to that object.  Or if the input is not a well-formed
++** polygon, put an error message in sqlite3_context and return NULL.
++*/
++static GeoPoly *geopolyFuncParam(
++  sqlite3_context *pCtx,      /* Context for error messages */
++  sqlite3_value *pVal,        /* The value to decode */
++  int *pRc                    /* Write error here */
++){
++  GeoPoly *p = 0;
++  int nByte;
++  if( sqlite3_value_type(pVal)==SQLITE_BLOB
++   && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
++  ){
++    const unsigned char *a = sqlite3_value_blob(pVal);
++    int nVertex;
++    nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
++    if( (a[0]==0 || a[0]==1)
++     && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
++    ){
++      p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) );
++      if( p==0 ){
++        if( pRc ) *pRc = SQLITE_NOMEM;
++        if( pCtx ) sqlite3_result_error_nomem(pCtx);
++      }else{
++        int x = 1;
++        p->nVertex = nVertex;
++        memcpy(p->hdr, a, nByte);
++        if( a[0] != *(unsigned char*)&x ){
++          int ii;
++          for(ii=0; ii<nVertex*2; ii++){
++            geopolySwab32((unsigned char*)&p->a[ii]);
++          }
++          p->hdr[0] ^= 1;
++        }
++      }
++    }
++    if( pRc ) *pRc = SQLITE_OK;
++    return p;
++  }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){
++    const unsigned char *zJson = sqlite3_value_text(pVal);
++    if( zJson==0 ){
++      if( pRc ) *pRc = SQLITE_NOMEM;
++      return 0;
++    }
++    return geopolyParseJson(zJson, pRc);
++  }else{
++    if( pRc ) *pRc = SQLITE_ERROR;
++    return 0;
++  }
++}
++
++/*
++** Implementation of the geopoly_blob(X) function.
++**
++** If the input is a well-formed Geopoly BLOB or JSON string
++** then return the BLOB representation of the polygon.  Otherwise
++** return NULL.
++*/
++static void geopolyBlobFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL function:     geopoly_json(X)
++**
++** Interpret X as a polygon and render it as a JSON array
++** of coordinates.  Or, if X is not a valid polygon, return NULL.
++*/
++static void geopolyJsonFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3 *db = sqlite3_context_db_handle(context);
++    sqlite3_str *x = sqlite3_str_new(db);
++    int i;
++    sqlite3_str_append(x, "[", 1);
++    for(i=0; i<p->nVertex; i++){
++      sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
++    }
++    sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
++    sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL function:     geopoly_svg(X, ....)
++**
++** Interpret X as a polygon and render it as a SVG <polyline>.
++** Additional arguments are added as attributes to the <polyline>.
++*/
++static void geopolySvgFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3 *db = sqlite3_context_db_handle(context);
++    sqlite3_str *x = sqlite3_str_new(db);
++    int i;
++    char cSep = '\'';
++    sqlite3_str_appendf(x, "<polyline points=");
++    for(i=0; i<p->nVertex; i++){
++      sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]);
++      cSep = ' ';
++    }
++    sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
++    for(i=1; i<argc; i++){
++      const char *z = (const char*)sqlite3_value_text(argv[i]);
++      if( z && z[0] ){
++        sqlite3_str_appendf(x, " %s", z);
++      }
++    }
++    sqlite3_str_appendf(x, "></polyline>");
++    sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** SQL Function:      geopoly_xform(poly, A, B, C, D, E, F)
++**
++** Transform and/or translate a polygon as follows:
++**
++**      x1 = A*x0 + B*y0 + E
++**      y1 = C*x0 + D*y0 + F
++**
++** For a translation:
++**
++**      geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset)
++**
++** Rotate by R around the point (0,0):
++**
++**      geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0)
++*/
++static void geopolyXformFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  double A = sqlite3_value_double(argv[1]);
++  double B = sqlite3_value_double(argv[2]);
++  double C = sqlite3_value_double(argv[3]);
++  double D = sqlite3_value_double(argv[4]);
++  double E = sqlite3_value_double(argv[5]);
++  double F = sqlite3_value_double(argv[6]);
++  GeoCoord x1, y1, x0, y0;
++  int ii;
++  if( p ){
++    for(ii=0; ii<p->nVertex; ii++){
++      x0 = p->a[ii*2];
++      y0 = p->a[ii*2+1];
++      x1 = (GeoCoord)(A*x0 + B*y0 + E);
++      y1 = (GeoCoord)(C*x0 + D*y0 + F);
++      p->a[ii*2] = x1;
++      p->a[ii*2+1] = y1;
++    }
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** Compute the area enclosed by the polygon.
++**
++** This routine can also be used to detect polygons that rotate in
++** the wrong direction.  Polygons are suppose to be counter-clockwise (CCW).
++** This routine returns a negative value for clockwise (CW) polygons.
++*/
++static double geopolyArea(GeoPoly *p){
++  double rArea = 0.0;
++  int ii;
++  for(ii=0; ii<p->nVertex-1; ii++){
++    rArea += (p->a[ii*2] - p->a[ii*2+2])           /* (x0 - x1) */
++              * (p->a[ii*2+1] + p->a[ii*2+3])      /* (y0 + y1) */
++              * 0.5;
++  }
++  rArea += (p->a[ii*2] - p->a[0])                  /* (xN - x0) */
++           * (p->a[ii*2+1] + p->a[1])              /* (yN + y0) */
++           * 0.5;
++  return rArea;
++}
++
++/*
++** Implementation of the geopoly_area(X) function.
++**
++** If the input is a well-formed Geopoly BLOB then return the area
++** enclosed by the polygon.  If the polygon circulates clockwise instead
++** of counterclockwise (as it should) then return the negative of the
++** enclosed area.  Otherwise return NULL.
++*/
++static void geopolyAreaFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    sqlite3_result_double(context, geopolyArea(p));
++    sqlite3_free(p);
++  }            
++}
++
++/*
++** Implementation of the geopoly_ccw(X) function.
++**
++** If the rotation of polygon X is clockwise (incorrect) instead of
++** counter-clockwise (the correct winding order according to RFC7946)
++** then reverse the order of the vertexes in polygon X.  
++**
++** In other words, this routine returns a CCW polygon regardless of the
++** winding order of its input.
++**
++** Use this routine to sanitize historical inputs that that sometimes
++** contain polygons that wind in the wrong direction.
++*/
++static void geopolyCcwFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
++  if( p ){
++    if( geopolyArea(p)<0.0 ){
++      int ii, jj;
++      for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
++        GeoCoord t = p->a[ii];
++        p->a[ii] = p->a[jj];
++        p->a[jj] = t;
++        t = p->a[ii+1];
++        p->a[ii+1] = p->a[jj+1];
++        p->a[jj+1] = t;
++      }
++    }
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }            
++}
++
++#define GEOPOLY_PI 3.1415926535897932385
++
++/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
++*/
++static double geopolySine(double r){
++  assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
++  if( r>=1.5*GEOPOLY_PI ){
++    r -= 2.0*GEOPOLY_PI;
++  }
++  if( r>=0.5*GEOPOLY_PI ){
++    return -geopolySine(r-GEOPOLY_PI);
++  }else{
++    double r2 = r*r;
++    double r3 = r2*r;
++    double r5 = r3*r2;
++    return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
++  }
++}
++
++/*
++** Function:   geopoly_regular(X,Y,R,N)
++**
++** Construct a simple, convex, regular polygon centered at X, Y
++** with circumradius R and with N sides.
++*/
++static void geopolyRegularFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  double x = sqlite3_value_double(argv[0]);
++  double y = sqlite3_value_double(argv[1]);
++  double r = sqlite3_value_double(argv[2]);
++  int n = sqlite3_value_int(argv[3]);
++  int i;
++  GeoPoly *p;
++
++  if( n<3 || r<=0.0 ) return;
++  if( n>1000 ) n = 1000;
++  p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
++  if( p==0 ){
++    sqlite3_result_error_nomem(context);
++    return;
++  }
++  i = 1;
++  p->hdr[0] = *(unsigned char*)&i;
++  p->hdr[1] = 0;
++  p->hdr[2] = (n>>8)&0xff;
++  p->hdr[3] = n&0xff;
++  for(i=0; i<n; i++){
++    double rAngle = 2.0*GEOPOLY_PI*i/n;
++    p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
++    p->a[i*2+1] = y + r*geopolySine(rAngle);
++  }
++  sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
++  sqlite3_free(p);
++}
++
++/*
++** If pPoly is a polygon, compute its bounding box. Then:
++**
++**    (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
++**    (2) otherwise, compute a GeoPoly for the bounding box and return the
++**        new GeoPoly
++**
++** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from
++** the bounding box in aCoord and return a pointer to that GeoPoly.
++*/
++static GeoPoly *geopolyBBox(
++  sqlite3_context *context,   /* For recording the error */
++  sqlite3_value *pPoly,       /* The polygon */
++  RtreeCoord *aCoord,         /* Results here */
++  int *pRc                    /* Error code here */
++){
++  GeoPoly *pOut = 0;
++  GeoPoly *p;
++  float mnX, mxX, mnY, mxY;
++  if( pPoly==0 && aCoord!=0 ){
++    p = 0;
++    mnX = aCoord[0].f;
++    mxX = aCoord[1].f;
++    mnY = aCoord[2].f;
++    mxY = aCoord[3].f;
++    goto geopolyBboxFill;
++  }else{
++    p = geopolyFuncParam(context, pPoly, pRc);
++  }
++  if( p ){
++    int ii;
++    mnX = mxX = p->a[0];
++    mnY = mxY = p->a[1];
++    for(ii=1; ii<p->nVertex; ii++){
++      double r = p->a[ii*2];
++      if( r<mnX ) mnX = (float)r;
++      else if( r>mxX ) mxX = (float)r;
++      r = p->a[ii*2+1];
++      if( r<mnY ) mnY = (float)r;
++      else if( r>mxY ) mxY = (float)r;
++    }
++    if( pRc ) *pRc = SQLITE_OK;
++    if( aCoord==0 ){
++      geopolyBboxFill:
++      pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
++      if( pOut==0 ){
++        sqlite3_free(p);
++        if( context ) sqlite3_result_error_nomem(context);
++        if( pRc ) *pRc = SQLITE_NOMEM;
++        return 0;
++      }
++      pOut->nVertex = 4;
++      ii = 1;
++      pOut->hdr[0] = *(unsigned char*)&ii;
++      pOut->hdr[1] = 0;
++      pOut->hdr[2] = 0;
++      pOut->hdr[3] = 4;
++      pOut->a[0] = mnX;
++      pOut->a[1] = mnY;
++      pOut->a[2] = mxX;
++      pOut->a[3] = mnY;
++      pOut->a[4] = mxX;
++      pOut->a[5] = mxY;
++      pOut->a[6] = mnX;
++      pOut->a[7] = mxY;
++    }else{
++      sqlite3_free(p);
++      aCoord[0].f = mnX;
++      aCoord[1].f = mxX;
++      aCoord[2].f = mnY;
++      aCoord[3].f = mxY;
++    }
++  }
++  return pOut;
++}
++
++/*
++** Implementation of the geopoly_bbox(X) SQL function.
++*/
++static void geopolyBBoxFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p = geopolyBBox(context, argv[0], 0, 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++/*
++** State vector for the geopoly_group_bbox() aggregate function.
++*/
++typedef struct GeoBBox GeoBBox;
++struct GeoBBox {
++  int isInit;
++  RtreeCoord a[4];
++};
++
++
++/*
++** Implementation of the geopoly_group_bbox(X) aggregate SQL function.
++*/
++static void geopolyBBoxStep(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  RtreeCoord a[4];
++  int rc = SQLITE_OK;
++  (void)geopolyBBox(context, argv[0], a, &rc);
++  if( rc==SQLITE_OK ){
++    GeoBBox *pBBox;
++    pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox));
++    if( pBBox==0 ) return;
++    if( pBBox->isInit==0 ){
++      pBBox->isInit = 1;
++      memcpy(pBBox->a, a, sizeof(RtreeCoord)*4);
++    }else{
++      if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0];
++      if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1];
++      if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2];
++      if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3];
++    }
++  }
++}
++static void geopolyBBoxFinal(
++  sqlite3_context *context
++){
++  GeoPoly *p;
++  GeoBBox *pBBox;
++  pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0);
++  if( pBBox==0 ) return;
++  p = geopolyBBox(context, 0, pBBox->a, 0);
++  if( p ){
++    sqlite3_result_blob(context, p->hdr, 
++       4+8*p->nVertex, SQLITE_TRANSIENT);
++    sqlite3_free(p);
++  }
++}
++
++
++/*
++** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2).
++** Returns:
++**
++**    +2  x0,y0 is on the line segement
++**
++**    +1  x0,y0 is beneath line segment
++**
++**    0   x0,y0 is not on or beneath the line segment or the line segment
++**        is vertical and x0,y0 is not on the line segment
++**
++** The left-most coordinate min(x1,x2) is not considered to be part of
++** the line segment for the purposes of this analysis.
++*/
++static int pointBeneathLine(
++  double x0, double y0,
++  double x1, double y1,
++  double x2, double y2
++){
++  double y;
++  if( x0==x1 && y0==y1 ) return 2;
++  if( x1<x2 ){
++    if( x0<=x1 || x0>x2 ) return 0;
++  }else if( x1>x2 ){
++    if( x0<=x2 || x0>x1 ) return 0;
++  }else{
++    /* Vertical line segment */
++    if( x0!=x1 ) return 0;
++    if( y0<y1 && y0<y2 ) return 0;
++    if( y0>y1 && y0>y2 ) return 0;
++    return 2;
++  }
++  y = y1 + (y2-y1)*(x0-x1)/(x2-x1);
++  if( y0==y ) return 2;
++  if( y0<y ) return 1;
++  return 0;
++}
++
++/*
++** SQL function:    geopoly_contains_point(P,X,Y)
++**
++** Return +2 if point X,Y is within polygon P.
++** Return +1 if point X,Y is on the polygon boundary.
++** Return 0 if point X,Y is outside the polygon
++*/
++static void geopolyContainsPointFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  double x0 = sqlite3_value_double(argv[1]);
++  double y0 = sqlite3_value_double(argv[2]);
++  int v = 0;
++  int cnt = 0;
++  int ii;
++  if( p1==0 ) return;
++  for(ii=0; ii<p1->nVertex-1; ii++){
++    v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
++                               p1->a[ii*2+2],p1->a[ii*2+3]);
++    if( v==2 ) break;
++    cnt += v;
++  }
++  if( v!=2 ){
++    v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
++                               p1->a[0],p1->a[1]);
++  }
++  if( v==2 ){
++    sqlite3_result_int(context, 1);
++  }else if( ((v+cnt)&1)==0 ){
++    sqlite3_result_int(context, 0);
++  }else{
++    sqlite3_result_int(context, 2);
++  }
++  sqlite3_free(p1);
++}
++
++/* Forward declaration */
++static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2);
++
++/*
++** SQL function:    geopoly_within(P1,P2)
++**
++** Return +2 if P1 and P2 are the same polygon
++** Return +1 if P2 is contained within P1
++** Return 0 if any part of P2 is on the outside of P1
++**
++*/
++static void geopolyWithinFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
++  if( p1 && p2 ){
++    int x = geopolyOverlap(p1, p2);
++    if( x<0 ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0);
++    }
++  }
++  sqlite3_free(p1);
++  sqlite3_free(p2);
++}
++
++/* Objects used by the overlap algorihm. */
++typedef struct GeoEvent GeoEvent;
++typedef struct GeoSegment GeoSegment;
++typedef struct GeoOverlap GeoOverlap;
++struct GeoEvent {
++  double x;              /* X coordinate at which event occurs */
++  int eType;             /* 0 for ADD, 1 for REMOVE */
++  GeoSegment *pSeg;      /* The segment to be added or removed */
++  GeoEvent *pNext;       /* Next event in the sorted list */
++};
++struct GeoSegment {
++  double C, B;           /* y = C*x + B */
++  double y;              /* Current y value */
++  float y0;              /* Initial y value */
++  unsigned char side;    /* 1 for p1, 2 for p2 */
++  unsigned int idx;      /* Which segment within the side */
++  GeoSegment *pNext;     /* Next segment in a list sorted by y */
++};
++struct GeoOverlap {
++  GeoEvent *aEvent;          /* Array of all events */
++  GeoSegment *aSegment;      /* Array of all segments */
++  int nEvent;                /* Number of events */
++  int nSegment;              /* Number of segments */
++};
++
++/*
++** Add a single segment and its associated events.
++*/
++static void geopolyAddOneSegment(
++  GeoOverlap *p,
++  GeoCoord x0,
++  GeoCoord y0,
++  GeoCoord x1,
++  GeoCoord y1,
++  unsigned char side,
++  unsigned int idx
++){
++  GeoSegment *pSeg;
++  GeoEvent *pEvent;
++  if( x0==x1 ) return;  /* Ignore vertical segments */
++  if( x0>x1 ){
++    GeoCoord t = x0;
++    x0 = x1;
++    x1 = t;
++    t = y0;
++    y0 = y1;
++    y1 = t;
++  }
++  pSeg = p->aSegment + p->nSegment;
++  p->nSegment++;
++  pSeg->C = (y1-y0)/(x1-x0);
++  pSeg->B = y1 - x1*pSeg->C;
++  pSeg->y0 = y0;
++  pSeg->side = side;
++  pSeg->idx = idx;
++  pEvent = p->aEvent + p->nEvent;
++  p->nEvent++;
++  pEvent->x = x0;
++  pEvent->eType = 0;
++  pEvent->pSeg = pSeg;
++  pEvent = p->aEvent + p->nEvent;
++  p->nEvent++;
++  pEvent->x = x1;
++  pEvent->eType = 1;
++  pEvent->pSeg = pSeg;
++}
++  
++
++
++/*
++** Insert all segments and events for polygon pPoly.
++*/
++static void geopolyAddSegments(
++  GeoOverlap *p,          /* Add segments to this Overlap object */
++  GeoPoly *pPoly,         /* Take all segments from this polygon */
++  unsigned char side      /* The side of pPoly */
++){
++  unsigned int i;
++  GeoCoord *x;
++  for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
++    x = pPoly->a + (i*2);
++    geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
++  }
++  x = pPoly->a + (i*2);
++  geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
++}
++
++/*
++** Merge two lists of sorted events by X coordinate
++*/
++static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){
++  GeoEvent head, *pLast;
++  head.pNext = 0;
++  pLast = &head;
++  while( pRight && pLeft ){
++    if( pRight->x <= pLeft->x ){
++      pLast->pNext = pRight;
++      pLast = pRight;
++      pRight = pRight->pNext;
++    }else{
++      pLast->pNext = pLeft;
++      pLast = pLeft;
++      pLeft = pLeft->pNext;
++    }
++  }
++  pLast->pNext = pRight ? pRight : pLeft;
++  return head.pNext;  
++}
++
++/*
++** Sort an array of nEvent event objects into a list.
++*/
++static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){
++  int mx = 0;
++  int i, j;
++  GeoEvent *p;
++  GeoEvent *a[50];
++  for(i=0; i<nEvent; i++){
++    p = &aEvent[i];
++    p->pNext = 0;
++    for(j=0; j<mx && a[j]; j++){
++      p = geopolyEventMerge(a[j], p);
++      a[j] = 0;
++    }
++    a[j] = p;
++    if( j>=mx ) mx = j+1;
++  }
++  p = 0;
++  for(i=0; i<mx; i++){
++    p = geopolyEventMerge(a[i], p);
++  }
++  return p;
++}
++
++/*
++** Merge two lists of sorted segments by Y, and then by C.
++*/
++static GeoSegment *geopolySegmentMerge(GeoSegment *pLeft, GeoSegment *pRight){
++  GeoSegment head, *pLast;
++  head.pNext = 0;
++  pLast = &head;
++  while( pRight && pLeft ){
++    double r = pRight->y - pLeft->y;
++    if( r==0.0 ) r = pRight->C - pLeft->C;
++    if( r<0.0 ){
++      pLast->pNext = pRight;
++      pLast = pRight;
++      pRight = pRight->pNext;
++    }else{
++      pLast->pNext = pLeft;
++      pLast = pLeft;
++      pLeft = pLeft->pNext;
++    }
++  }
++  pLast->pNext = pRight ? pRight : pLeft;
++  return head.pNext;  
++}
++
++/*
++** Sort a list of GeoSegments in order of increasing Y and in the event of
++** a tie, increasing C (slope).
++*/
++static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
++  int mx = 0;
++  int i;
++  GeoSegment *p;
++  GeoSegment *a[50];
++  while( pList ){
++    p = pList;
++    pList = pList->pNext;
++    p->pNext = 0;
++    for(i=0; i<mx && a[i]; i++){
++      p = geopolySegmentMerge(a[i], p);
++      a[i] = 0;
++    }
++    a[i] = p;
++    if( i>=mx ) mx = i+1;
++  }
++  p = 0;
++  for(i=0; i<mx; i++){
++    p = geopolySegmentMerge(a[i], p);
++  }
++  return p;
++}
++
++/*
++** Determine the overlap between two polygons
++*/
++static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
++  int nVertex = p1->nVertex + p2->nVertex + 2;
++  GeoOverlap *p;
++  int nByte;
++  GeoEvent *pThisEvent;
++  double rX;
++  int rc = 0;
++  int needSort = 0;
++  GeoSegment *pActive = 0;
++  GeoSegment *pSeg;
++  unsigned char aOverlap[4];
++
++  nByte = sizeof(GeoEvent)*nVertex*2 
++           + sizeof(GeoSegment)*nVertex 
++           + sizeof(GeoOverlap);
++  p = sqlite3_malloc( nByte );
++  if( p==0 ) return -1;
++  p->aEvent = (GeoEvent*)&p[1];
++  p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
++  p->nEvent = p->nSegment = 0;
++  geopolyAddSegments(p, p1, 1);
++  geopolyAddSegments(p, p2, 2);
++  pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
++  rX = pThisEvent->x==0.0 ? -1.0 : 0.0;
++  memset(aOverlap, 0, sizeof(aOverlap));
++  while( pThisEvent ){
++    if( pThisEvent->x!=rX ){
++      GeoSegment *pPrev = 0;
++      int iMask = 0;
++      GEODEBUG(("Distinct X: %g\n", pThisEvent->x));
++      rX = pThisEvent->x;
++      if( needSort ){
++        GEODEBUG(("SORT\n"));
++        pActive = geopolySortSegmentsByYAndC(pActive);
++        needSort = 0;
++      }
++      for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++        if( pPrev ){
++          if( pPrev->y!=pSeg->y ){
++            GEODEBUG(("MASK: %d\n", iMask));
++            aOverlap[iMask] = 1;
++          }
++        }
++        iMask ^= pSeg->side;
++        pPrev = pSeg;
++      }
++      pPrev = 0;
++      for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++        double y = pSeg->C*rX + pSeg->B;
++        GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y));
++        pSeg->y = y;
++        if( pPrev ){
++          if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){
++            rc = 1;
++            GEODEBUG(("Crossing: %d.%d and %d.%d\n",
++                    pPrev->side, pPrev->idx,
++                    pSeg->side, pSeg->idx));
++            goto geopolyOverlapDone;
++          }else if( pPrev->y!=pSeg->y ){
++            GEODEBUG(("MASK: %d\n", iMask));
++            aOverlap[iMask] = 1;
++          }
++        }
++        iMask ^= pSeg->side;
++        pPrev = pSeg;
++      }
++    }
++    GEODEBUG(("%s %d.%d C=%g B=%g\n",
++      pThisEvent->eType ? "RM " : "ADD",
++      pThisEvent->pSeg->side, pThisEvent->pSeg->idx,
++      pThisEvent->pSeg->C,
++      pThisEvent->pSeg->B));
++    if( pThisEvent->eType==0 ){
++      /* Add a segment */
++      pSeg = pThisEvent->pSeg;
++      pSeg->y = pSeg->y0;
++      pSeg->pNext = pActive;
++      pActive = pSeg;
++      needSort = 1;
++    }else{
++      /* Remove a segment */
++      if( pActive==pThisEvent->pSeg ){
++        pActive = pActive->pNext;
++      }else{
++        for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
++          if( pSeg->pNext==pThisEvent->pSeg ){
++            pSeg->pNext = pSeg->pNext->pNext;
++            break;
++          }
++        }
++      }
++    }
++    pThisEvent = pThisEvent->pNext;
++  }
++  if( aOverlap[3]==0 ){
++    rc = 0;
++  }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){
++    rc = 3;
++  }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){
++    rc = 2;
++  }else if( aOverlap[1]==0 && aOverlap[2]==0 ){
++    rc = 4;
++  }else{
++    rc = 1;
++  }
++
++geopolyOverlapDone:
++  sqlite3_free(p);
++  return rc;
++}
++
++/*
++** SQL function:    geopoly_overlap(P1,P2)
++**
++** Determine whether or not P1 and P2 overlap. Return value:
++**
++**   0     The two polygons are disjoint
++**   1     They overlap
++**   2     P1 is completely contained within P2
++**   3     P2 is completely contained within P1
++**   4     P1 and P2 are the same polygon
++**   NULL  Either P1 or P2 or both are not valid polygons
++*/
++static void geopolyOverlapFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
++  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
++  if( p1 && p2 ){
++    int x = geopolyOverlap(p1, p2);
++    if( x<0 ){
++      sqlite3_result_error_nomem(context);
++    }else{
++      sqlite3_result_int(context, x);
++    }
++  }
++  sqlite3_free(p1);
++  sqlite3_free(p2);
++}
++
++/*
++** Enable or disable debugging output
++*/
++static void geopolyDebugFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++#ifdef GEOPOLY_ENABLE_DEBUG
++  geo_debug = sqlite3_value_int(argv[0]);
++#endif
++}
++
++/* 
++** This function is the implementation of both the xConnect and xCreate
++** methods of the geopoly virtual table.
++**
++**   argv[0]   -> module name
++**   argv[1]   -> database name
++**   argv[2]   -> table name
++**   argv[...] -> column names...
++*/
++static int geopolyInit(
++  sqlite3 *db,                        /* Database connection */
++  void *pAux,                         /* One of the RTREE_COORD_* constants */
++  int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */
++  sqlite3_vtab **ppVtab,              /* OUT: New virtual table */
++  char **pzErr,                       /* OUT: Error message, if any */
++  int isCreate                        /* True for xCreate, false for xConnect */
++){
++  int rc = SQLITE_OK;
++  Rtree *pRtree;
++  int nDb;              /* Length of string argv[1] */
++  int nName;            /* Length of string argv[2] */
++  sqlite3_str *pSql;
++  char *zSql;
++  int ii;
++
++  sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
++
++  /* Allocate the sqlite3_vtab structure */
++  nDb = (int)strlen(argv[1]);
++  nName = (int)strlen(argv[2]);
++  pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
++  if( !pRtree ){
++    return SQLITE_NOMEM;
++  }
++  memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
++  pRtree->nBusy = 1;
++  pRtree->base.pModule = &rtreeModule;
++  pRtree->zDb = (char *)&pRtree[1];
++  pRtree->zName = &pRtree->zDb[nDb+1];
++  pRtree->eCoordType = RTREE_COORD_REAL32;
++  pRtree->nDim = 2;
++  pRtree->nDim2 = 4;
++  memcpy(pRtree->zDb, argv[1], nDb);
++  memcpy(pRtree->zName, argv[2], nName);
++
++
++  /* Create/Connect to the underlying relational database schema. If
++  ** that is successful, call sqlite3_declare_vtab() to configure
++  ** the r-tree table schema.
++  */
++  pSql = sqlite3_str_new(db);
++  sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape");
++  pRtree->nAux = 1;         /* Add one for _shape */
++  pRtree->nAuxNotNull = 1;  /* The _shape column is always not-null */
++  for(ii=3; ii<argc; ii++){
++    pRtree->nAux++;
++    sqlite3_str_appendf(pSql, ",%s", argv[ii]);
++  }
++  sqlite3_str_appendf(pSql, ");");
++  zSql = sqlite3_str_finish(pSql);
++  if( !zSql ){
++    rc = SQLITE_NOMEM;
++  }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++  }
++  sqlite3_free(zSql);
++  if( rc ) goto geopolyInit_fail;
++  pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
++
++  /* Figure out the node size to use. */
++  rc = getNodeSize(db, pRtree, isCreate, pzErr);
++  if( rc ) goto geopolyInit_fail;
++  rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate);
++  if( rc ){
++    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
++    goto geopolyInit_fail;
++  }
++
++  *ppVtab = (sqlite3_vtab *)pRtree;
++  return SQLITE_OK;
++
++geopolyInit_fail:
++  if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
++  assert( *ppVtab==0 );
++  assert( pRtree->nBusy==1 );
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++
++/* 
++** GEOPOLY virtual table module xCreate method.
++*/
++static int geopolyCreate(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
++}
++
++/* 
++** GEOPOLY virtual table module xConnect method.
++*/
++static int geopolyConnect(
++  sqlite3 *db,
++  void *pAux,
++  int argc, const char *const*argv,
++  sqlite3_vtab **ppVtab,
++  char **pzErr
++){
++  return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
++}
++
++
++/* 
++** GEOPOLY virtual table module xFilter method.
++**
++** Query plans:
++**
++**      1         rowid lookup
++**      2         search for objects overlapping the same bounding box
++**                that contains polygon argv[0]
++**      3         search for objects overlapping the same bounding box
++**                that contains polygon argv[0]
++**      4         full table scan
++*/
++static int geopolyFilter(
++  sqlite3_vtab_cursor *pVtabCursor,     /* The cursor to initialize */
++  int idxNum,                           /* Query plan */
++  const char *idxStr,                   /* Not Used */
++  int argc, sqlite3_value **argv        /* Parameters to the query plan */
++){
++  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
++  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
++  RtreeNode *pRoot = 0;
++  int rc = SQLITE_OK;
++  int iCell = 0;
++  sqlite3_stmt *pStmt;
++
++  rtreeReference(pRtree);
++
++  /* Reset the cursor to the same state as rtreeOpen() leaves it in. */
++  freeCursorConstraints(pCsr);
++  sqlite3_free(pCsr->aPoint);
++  pStmt = pCsr->pReadAux;
++  memset(pCsr, 0, sizeof(RtreeCursor));
++  pCsr->base.pVtab = (sqlite3_vtab*)pRtree;
++  pCsr->pReadAux = pStmt;
++
++  pCsr->iStrategy = idxNum;
++  if( idxNum==1 ){
++    /* Special case - lookup by rowid. */
++    RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
++    RtreeSearchPoint *p;     /* Search point for the leaf */
++    i64 iRowid = sqlite3_value_int64(argv[0]);
++    i64 iNode = 0;
++    rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
++    if( rc==SQLITE_OK && pLeaf!=0 ){
++      p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0);
++      assert( p!=0 );  /* Always returns pCsr->sPoint */
++      pCsr->aNode[0] = pLeaf;
++      p->id = iNode;
++      p->eWithin = PARTLY_WITHIN;
++      rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
++      p->iCell = (u8)iCell;
++      RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
++    }else{
++      pCsr->atEOF = 1;
++    }
++  }else{
++    /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array 
++    ** with the configured constraints. 
++    */
++    rc = nodeAcquire(pRtree, 1, 0, &pRoot);
++    if( rc==SQLITE_OK && idxNum<=3 ){
++      RtreeCoord bbox[4];
++      RtreeConstraint *p;
++      assert( argc==1 );
++      geopolyBBox(0, argv[0], bbox, &rc);
++      if( rc ){
++        goto geopoly_filter_end;
++      }
++      pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
++      pCsr->nConstraint = 4;
++      if( p==0 ){
++        rc = SQLITE_NOMEM;
++      }else{
++        memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4);
++        memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1));
++        if( idxNum==2 ){
++          /* Overlap query */
++          p->op = 'B';
++          p->iCoord = 0;
++          p->u.rValue = bbox[1].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 1;
++          p->u.rValue = bbox[0].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 2;
++          p->u.rValue = bbox[3].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 3;
++          p->u.rValue = bbox[2].f;
++        }else{
++          /* Within query */
++          p->op = 'D';
++          p->iCoord = 0;
++          p->u.rValue = bbox[0].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 1;
++          p->u.rValue = bbox[1].f;
++          p++;
++          p->op = 'D';
++          p->iCoord = 2;
++          p->u.rValue = bbox[2].f;
++          p++;
++          p->op = 'B';
++          p->iCoord = 3;
++          p->u.rValue = bbox[3].f;
++        }
++      }
++    }
++    if( rc==SQLITE_OK ){
++      RtreeSearchPoint *pNew;
++      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
++      if( pNew==0 ){
++        rc = SQLITE_NOMEM;
++        goto geopoly_filter_end;
++      }
++      pNew->id = 1;
++      pNew->iCell = 0;
++      pNew->eWithin = PARTLY_WITHIN;
++      assert( pCsr->bPoint==1 );
++      pCsr->aNode[0] = pRoot;
++      pRoot = 0;
++      RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
++      rc = rtreeStepToLeaf(pCsr);
++    }
++  }
++
++geopoly_filter_end:
++  nodeRelease(pRtree, pRoot);
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++/*
++** Rtree virtual table module xBestIndex method. There are three
++** table scan strategies to choose from (in order from most to 
++** least desirable):
++**
++**   idxNum     idxStr        Strategy
++**   ------------------------------------------------
++**     1        "rowid"       Direct lookup by rowid.
++**     2        "rtree"       R-tree overlap query using geopoly_overlap()
++**     3        "rtree"       R-tree within query using geopoly_within()
++**     4        "fullscan"    full-table scan.
++**   ------------------------------------------------
++*/
++static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
++  int ii;
++  int iRowidTerm = -1;
++  int iFuncTerm = -1;
++  int idxNum = 0;
++
++  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
++    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
++    if( !p->usable ) continue;
++    if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ  ){
++      iRowidTerm = ii;
++      break;
++    }
++    if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
++      /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap()
++      ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within().
++      ** See geopolyFindFunction() */
++      iFuncTerm = ii;
++      idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2;
++    }
++  }
++
++  if( iRowidTerm>=0 ){
++    pIdxInfo->idxNum = 1;
++    pIdxInfo->idxStr = "rowid";
++    pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
++    pIdxInfo->estimatedCost = 30.0;
++    pIdxInfo->estimatedRows = 1;
++    pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
++    return SQLITE_OK;
++  }
++  if( iFuncTerm>=0 ){
++    pIdxInfo->idxNum = idxNum;
++    pIdxInfo->idxStr = "rtree";
++    pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1;
++    pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0;
++    pIdxInfo->estimatedCost = 300.0;
++    pIdxInfo->estimatedRows = 10;
++    return SQLITE_OK;
++  }
++  pIdxInfo->idxNum = 4;
++  pIdxInfo->idxStr = "fullscan";
++  pIdxInfo->estimatedCost = 3000000.0;
++  pIdxInfo->estimatedRows = 100000;
++  return SQLITE_OK;
++}
++
++
++/* 
++** GEOPOLY virtual table module xColumn method.
++*/
++static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
++  Rtree *pRtree = (Rtree *)cur->pVtab;
++  RtreeCursor *pCsr = (RtreeCursor *)cur;
++  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
++  int rc = SQLITE_OK;
++  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
++
++  if( rc ) return rc;
++  if( p==0 ) return SQLITE_OK;
++  if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK;
++  if( i<=pRtree->nAux ){
++    if( !pCsr->bAuxValid ){
++      if( pCsr->pReadAux==0 ){
++        rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0,
++                                &pCsr->pReadAux, 0);
++        if( rc ) return rc;
++      }
++      sqlite3_bind_int64(pCsr->pReadAux, 1, 
++          nodeGetRowid(pRtree, pNode, p->iCell));
++      rc = sqlite3_step(pCsr->pReadAux);
++      if( rc==SQLITE_ROW ){
++        pCsr->bAuxValid = 1;
++      }else{
++        sqlite3_reset(pCsr->pReadAux);
++        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
++        return rc;
++      }
++    }
++    sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2));
++  }
++  return SQLITE_OK;
++}
++
++
++/*
++** The xUpdate method for GEOPOLY module virtual tables.
++**
++** For DELETE:
++**
++**     argv[0] = the rowid to be deleted
++**
++** For INSERT:
++**
++**     argv[0] = SQL NULL
++**     argv[1] = rowid to insert, or an SQL NULL to select automatically
++**     argv[2] = _shape column
++**     argv[3] = first application-defined column....
++**
++** For UPDATE:
++**
++**     argv[0] = rowid to modify.  Never NULL
++**     argv[1] = rowid after the change.  Never NULL
++**     argv[2] = new value for _shape
++**     argv[3] = new value for first application-defined column....
++*/
++static int geopolyUpdate(
++  sqlite3_vtab *pVtab, 
++  int nData, 
++  sqlite3_value **aData, 
++  sqlite_int64 *pRowid
++){
++  Rtree *pRtree = (Rtree *)pVtab;
++  int rc = SQLITE_OK;
++  RtreeCell cell;                 /* New cell to insert if nData>1 */
++  i64 oldRowid;                   /* The old rowid */
++  int oldRowidValid;              /* True if oldRowid is valid */
++  i64 newRowid;                   /* The new rowid */
++  int newRowidValid;              /* True if newRowid is valid */
++  int coordChange = 0;            /* Change in coordinates */
++
++  if( pRtree->nNodeRef ){
++    /* Unable to write to the btree while another cursor is reading from it,
++    ** since the write might do a rebalance which would disrupt the read
++    ** cursor. */
++    return SQLITE_LOCKED_VTAB;
++  }
++  rtreeReference(pRtree);
++  assert(nData>=1);
++
++  oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;;
++  oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0;
++  newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL;
++  newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0;
++  cell.iRowid = newRowid;
++
++  if( nData>1                                 /* not a DELETE */
++   && (!oldRowidValid                         /* INSERT */
++        || !sqlite3_value_nochange(aData[2])  /* UPDATE _shape */
++        || oldRowid!=newRowid)                /* Rowid change */
++  ){
++    geopolyBBox(0, aData[2], cell.aCoord, &rc);
++    if( rc ){
++      if( rc==SQLITE_ERROR ){
++        pVtab->zErrMsg =
++          sqlite3_mprintf("_shape does not contain a valid polygon");
++      }
++      goto geopoly_update_end;
++    }
++    coordChange = 1;
++
++    /* If a rowid value was supplied, check if it is already present in 
++    ** the table. If so, the constraint has failed. */
++    if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){
++      int steprc;
++      sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
++      steprc = sqlite3_step(pRtree->pReadRowid);
++      rc = sqlite3_reset(pRtree->pReadRowid);
++      if( SQLITE_ROW==steprc ){
++        if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
++          rc = rtreeDeleteRowid(pRtree, cell.iRowid);
++        }else{
++          rc = rtreeConstraintError(pRtree, 0);
++        }
++      }
++    }
++  }
++
++  /* If aData[0] is not an SQL NULL value, it is the rowid of a
++  ** record to delete from the r-tree table. The following block does
++  ** just that.
++  */
++  if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){
++    rc = rtreeDeleteRowid(pRtree, oldRowid);
++  }
++
++  /* If the aData[] array contains more than one element, elements
++  ** (aData[2]..aData[argc-1]) contain a new record to insert into
++  ** the r-tree structure.
++  */
++  if( rc==SQLITE_OK && nData>1 && coordChange ){
++    /* Insert the new record into the r-tree */
++    RtreeNode *pLeaf = 0;
++    if( !newRowidValid ){
++      rc = rtreeNewRowid(pRtree, &cell.iRowid);
++    }
++    *pRowid = cell.iRowid;
++    if( rc==SQLITE_OK ){
++      rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
++    }
++    if( rc==SQLITE_OK ){
++      int rc2;
++      pRtree->iReinsertHeight = -1;
++      rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
++      rc2 = nodeRelease(pRtree, pLeaf);
++      if( rc==SQLITE_OK ){
++        rc = rc2;
++      }
++    }
++  }
++
++  /* Change the data */
++  if( rc==SQLITE_OK && nData>1 ){
++    sqlite3_stmt *pUp = pRtree->pWriteAux;
++    int jj;
++    int nChange = 0;
++    sqlite3_bind_int64(pUp, 1, cell.iRowid);
++    assert( pRtree->nAux>=1 );
++    if( sqlite3_value_nochange(aData[2]) ){
++      sqlite3_bind_null(pUp, 2);
++    }else{
++      GeoPoly *p = 0;
++      if( sqlite3_value_type(aData[2])==SQLITE_TEXT
++       && (p = geopolyFuncParam(0, aData[2], &rc))!=0
++       && rc==SQLITE_OK
++      ){
++        sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
++      }else{
++        sqlite3_bind_value(pUp, 2, aData[2]);
++      }
++      sqlite3_free(p);
++      nChange = 1;
++    }
++    for(jj=1; jj<pRtree->nAux; jj++){
++      nChange++;
++      sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
++    }
++    if( nChange ){
++      sqlite3_step(pUp);
++      rc = sqlite3_reset(pUp);
++    }
++  }
++
++geopoly_update_end:
++  rtreeRelease(pRtree);
++  return rc;
++}
++
++/*
++** Report that geopoly_overlap() is an overloaded function suitable
++** for use in xBestIndex.
++*/
++static int geopolyFindFunction(
++  sqlite3_vtab *pVtab,
++  int nArg,
++  const char *zName,
++  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
++  void **ppArg
++){
++  if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){
++    *pxFunc = geopolyOverlapFunc;
++    *ppArg = 0;
++    return SQLITE_INDEX_CONSTRAINT_FUNCTION;
++  }
++  if( sqlite3_stricmp(zName, "geopoly_within")==0 ){
++    *pxFunc = geopolyWithinFunc;
++    *ppArg = 0;
++    return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
++  }
++  return 0;
++}
++
++
++static sqlite3_module geopolyModule = {
++  3,                          /* iVersion */
++  geopolyCreate,              /* xCreate - create a table */
++  geopolyConnect,             /* xConnect - connect to an existing table */
++  geopolyBestIndex,           /* xBestIndex - Determine search strategy */
++  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
++  rtreeDestroy,               /* xDestroy - Drop a table */
++  rtreeOpen,                  /* xOpen - open a cursor */
++  rtreeClose,                 /* xClose - close a cursor */
++  geopolyFilter,              /* xFilter - configure scan constraints */
++  rtreeNext,                  /* xNext - advance a cursor */
++  rtreeEof,                   /* xEof */
++  geopolyColumn,              /* xColumn - read data */
++  rtreeRowid,                 /* xRowid - read data */
++  geopolyUpdate,              /* xUpdate - write data */
++  rtreeBeginTransaction,      /* xBegin - begin transaction */
++  rtreeEndTransaction,        /* xSync - sync transaction */
++  rtreeEndTransaction,        /* xCommit - commit transaction */
++  rtreeEndTransaction,        /* xRollback - rollback transaction */
++  geopolyFindFunction,        /* xFindFunction - function overloading */
++  rtreeRename,                /* xRename - rename the table */
++  rtreeSavepoint,             /* xSavepoint */
++  0,                          /* xRelease */
++  0,                          /* xRollbackTo */
++  rtreeShadowName             /* xShadowName */
++};
++
++static int sqlite3_geopoly_init(sqlite3 *db){
++  int rc = SQLITE_OK;
++  static const struct {
++    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
++    signed char nArg;
++    unsigned char bPure;
++    const char *zName;
++  } aFunc[] = {
++     { geopolyAreaFunc,          1, 1,    "geopoly_area"             },
++     { geopolyBlobFunc,          1, 1,    "geopoly_blob"             },
++     { geopolyJsonFunc,          1, 1,    "geopoly_json"             },
++     { geopolySvgFunc,          -1, 1,    "geopoly_svg"              },
++     { geopolyWithinFunc,        2, 1,    "geopoly_within"           },
++     { geopolyContainsPointFunc, 3, 1,    "geopoly_contains_point"   },
++     { geopolyOverlapFunc,       2, 1,    "geopoly_overlap"          },
++     { geopolyDebugFunc,         1, 0,    "geopoly_debug"            },
++     { geopolyBBoxFunc,          1, 1,    "geopoly_bbox"             },
++     { geopolyXformFunc,         7, 1,    "geopoly_xform"            },
++     { geopolyRegularFunc,       4, 1,    "geopoly_regular"          },
++     { geopolyCcwFunc,           1, 1,    "geopoly_ccw"              },
++  };
++  static const struct {
++    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
++    void (*xFinal)(sqlite3_context*);
++    const char *zName;
++  } aAgg[] = {
++     { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox"    },
++  };
++  int i;
++  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
++    int enc = aFunc[i].bPure ? SQLITE_UTF8|SQLITE_DETERMINISTIC : SQLITE_UTF8;
++    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
++                                 enc, 0,
++                                 aFunc[i].xFunc, 0, 0);
++  }
++  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
++    rc = sqlite3_create_function(db, aAgg[i].zName, 1, SQLITE_UTF8, 0,
++                                 0, aAgg[i].xStep, aAgg[i].xFinal);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_create_module_v2(db, "geopoly", &geopolyModule, 0, 0);
++  }
++  return rc;
++}
++
++/************** End of geopoly.c *********************************************/
++/************** Continuing where we left off in rtree.c **********************/
++#endif
++
++/*
+ ** Register the r-tree module with database handle db. This creates the
+ ** virtual table module "rtree" and the debugging/analysis scalar 
+ ** function "rtreenode".
+@@ -172893,6 +185203,11 @@
+     void *c = (void *)RTREE_COORD_INT32;
+     rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
+   }
++#ifdef SQLITE_ENABLE_GEOPOLY
++  if( rc==SQLITE_OK ){
++    rc = sqlite3_geopoly_init(db);
++  }
++#endif
+ 
+   return rc;
+ }
+@@ -174618,6 +186933,10 @@
+ **
+ ** RBU_STATE_OALSZ:
+ **   Valid if STAGE==1. The size in bytes of the *-oal file.
++**
++** RBU_STATE_DATATBL:
++**   Only valid if STAGE==1. The RBU database name of the table 
++**   currently being read.
+ */
+ #define RBU_STATE_STAGE        1
+ #define RBU_STATE_TBL          2
+@@ -174628,6 +186947,7 @@
+ #define RBU_STATE_COOKIE       7
+ #define RBU_STATE_OALSZ        8
+ #define RBU_STATE_PHASEONESTEP 9
++#define RBU_STATE_DATATBL     10
+ 
+ #define RBU_STAGE_OAL         1
+ #define RBU_STAGE_MOVE        2
+@@ -174670,6 +186990,7 @@
+ struct RbuState {
+   int eStage;
+   char *zTbl;
++  char *zDataTbl;
+   char *zIdx;
+   i64 iWalCksum;
+   int nRow;
+@@ -174864,7 +187185,8 @@
+   sqlite3_vfs *pRealVfs;          /* Underlying VFS */
+   sqlite3_mutex *mutex;           /* Mutex to protect pMain */
+   sqlite3rbu *pRbu;               /* Owner RBU object */
+-  rbu_file *pMain;                /* Linked list of main db files */
++  rbu_file *pMain;                /* List of main db files */
++  rbu_file *pMainRbu;             /* List of main db files with pRbu!=0 */
+ };
+ 
+ /*
+@@ -174893,6 +187215,7 @@
+   const char *zWal;               /* Wal filename for this main db file */
+   rbu_file *pWalFd;               /* Wal file descriptor for this main db */
+   rbu_file *pMainNext;            /* Next MAIN_DB file */
++  rbu_file *pMainRbuNext;         /* Next MAIN_DB file with pRbu!=0 */
+ };
+ 
+ /*
+@@ -176733,6 +189056,7 @@
+ static void rbuFreeState(RbuState *p){
+   if( p ){
+     sqlite3_free(p->zTbl);
++    sqlite3_free(p->zDataTbl);
+     sqlite3_free(p->zIdx);
+     sqlite3_free(p);
+   }
+@@ -176803,6 +189127,10 @@
+         pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
+         break;
+ 
++      case RBU_STATE_DATATBL:
++        pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
++        break;
++
+       default:
+         rc = SQLITE_CORRUPT;
+         break;
+@@ -177577,7 +189905,8 @@
+           "(%d, %lld), "
+           "(%d, %lld), "
+           "(%d, %lld), "
+-          "(%d, %lld) ",
++          "(%d, %lld), "
++          "(%d, %Q)  ",
+           p->zStateDb,
+           RBU_STATE_STAGE, eStage,
+           RBU_STATE_TBL, p->objiter.zTbl, 
+@@ -177587,7 +189916,8 @@
+           RBU_STATE_CKPT, p->iWalCksum,
+           RBU_STATE_COOKIE, (i64)pFd->iCookie,
+           RBU_STATE_OALSZ, p->iOalSz,
+-          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
++          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
++          RBU_STATE_DATATBL, p->objiter.zDataTbl
+       )
+     );
+     assert( pInsert==0 || rc==SQLITE_OK );
+@@ -177843,7 +190173,8 @@
+ 
+     while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
+        || rbuStrCompare(pIter->zIdx, pState->zIdx)
+-       || rbuStrCompare(pIter->zTbl, pState->zTbl) 
++       || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl))
++       || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl))
+     )){
+       rc = rbuObjIterNext(p, pIter);
+     }
+@@ -178482,6 +190813,69 @@
+ }
+ 
+ /*
++** Add an item to the main-db lists, if it is not already present.
++**
++** There are two main-db lists. One for all file descriptors, and one
++** for all file descriptors with rbu_file.pDb!=0. If the argument has
++** rbu_file.pDb!=0, then it is assumed to already be present on the
++** main list and is only added to the pDb!=0 list.
++*/
++static void rbuMainlistAdd(rbu_file *p){
++  rbu_vfs *pRbuVfs = p->pRbuVfs;
++  rbu_file *pIter;
++  assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
++  sqlite3_mutex_enter(pRbuVfs->mutex);
++  if( p->pRbu==0 ){
++    for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
++    p->pMainNext = pRbuVfs->pMain;
++    pRbuVfs->pMain = p;
++  }else{
++    for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
++    if( pIter==0 ){
++      p->pMainRbuNext = pRbuVfs->pMainRbu;
++      pRbuVfs->pMainRbu = p;
++    }
++  }
++  sqlite3_mutex_leave(pRbuVfs->mutex);
++}
++
++/*
++** Remove an item from the main-db lists.
++*/
++static void rbuMainlistRemove(rbu_file *p){
++  rbu_file **pp;
++  sqlite3_mutex_enter(p->pRbuVfs->mutex);
++  for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
++  if( *pp ) *pp = p->pMainNext;
++  p->pMainNext = 0;
++  for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
++  if( *pp ) *pp = p->pMainRbuNext;
++  p->pMainRbuNext = 0;
++  sqlite3_mutex_leave(p->pRbuVfs->mutex);
++}
++
++/*
++** Given that zWal points to a buffer containing a wal file name passed to 
++** either the xOpen() or xAccess() VFS method, search the main-db list for
++** a file-handle opened by the same database connection on the corresponding
++** database file.
++**
++** If parameter bRbu is true, only search for file-descriptors with
++** rbu_file.pDb!=0.
++*/
++static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
++  rbu_file *pDb;
++  sqlite3_mutex_enter(pRbuVfs->mutex);
++  if( bRbu ){
++    for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
++  }else{
++    for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
++  }
++  sqlite3_mutex_leave(pRbuVfs->mutex);
++  return pDb;
++}
++
++/*
+ ** Close an rbu file.
+ */
+ static int rbuVfsClose(sqlite3_file *pFile){
+@@ -178498,11 +190892,7 @@
+   sqlite3_free(p->zDel);
+ 
+   if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+-    rbu_file **pp;
+-    sqlite3_mutex_enter(p->pRbuVfs->mutex);
+-    for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
+-    *pp = p->pMainNext;
+-    sqlite3_mutex_leave(p->pRbuVfs->mutex);
++    rbuMainlistRemove(p);
+     rbuUnlockShm(p);
+     p->pReal->pMethods->xShmUnmap(p->pReal, 0);
+   }
+@@ -178509,6 +190899,7 @@
+   else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
+     rbuUpdateTempSize(p, 0);
+   }
++  assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
+ 
+   /* Close the underlying file handle */
+   rc = p->pReal->pMethods->xClose(p->pReal);
+@@ -178767,6 +191158,9 @@
+       }else if( rc==SQLITE_NOTFOUND ){
+         pRbu->pTargetFd = p;
+         p->pRbu = pRbu;
++        if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
++          rbuMainlistAdd(p);
++        }
+         if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
+         rc = SQLITE_OK;
+       }
+@@ -178928,20 +191322,6 @@
+   return rc;
+ }
+ 
+-/*
+-** Given that zWal points to a buffer containing a wal file name passed to 
+-** either the xOpen() or xAccess() VFS method, return a pointer to the
+-** file-handle opened by the same database connection on the corresponding
+-** database file.
+-*/
+-static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
+-  rbu_file *pDb;
+-  sqlite3_mutex_enter(pRbuVfs->mutex);
+-  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
+-  sqlite3_mutex_leave(pRbuVfs->mutex);
+-  return pDb;
+-}
+-
+ /* 
+ ** A main database named zName has just been opened. The following 
+ ** function returns a pointer to a buffer owned by SQLite that contains
+@@ -179020,7 +191400,7 @@
+       pFd->zWal = rbuMainToWal(zName, flags);
+     }
+     else if( flags & SQLITE_OPEN_WAL ){
+-      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
++      rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
+       if( pDb ){
+         if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+           /* This call is to open a *-wal file. Intead, open the *-oal. This
+@@ -179072,10 +191452,7 @@
+     ** mutex protected linked list of all such files.  */
+     pFile->pMethods = &rbuvfs_io_methods;
+     if( flags & SQLITE_OPEN_MAIN_DB ){
+-      sqlite3_mutex_enter(pRbuVfs->mutex);
+-      pFd->pMainNext = pRbuVfs->pMain;
+-      pRbuVfs->pMain = pFd;
+-      sqlite3_mutex_leave(pRbuVfs->mutex);
++      rbuMainlistAdd(pFd);
+     }
+   }else{
+     sqlite3_free(pFd->zDel);
+@@ -179123,7 +191500,7 @@
+   **      file opened instead.
+   */
+   if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
+-    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
++    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
+     if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+       if( *pResOut ){
+         rc = SQLITE_CANTOPEN;
+@@ -179536,8 +191913,6 @@
+ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+   int i;
+ 
+-  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
+-
+   /* Look for a valid schema=? constraint.  If found, change the idxNum to
+   ** 1 and request the value of that constraint be sent to xFilter.  And
+   ** lower the cost estimate to encourage the constrained version to be
+@@ -179544,9 +191919,9 @@
+   ** used.
+   */
+   for(i=0; i<pIdxInfo->nConstraint; i++){
+-    if( pIdxInfo->aConstraint[i].usable==0 ) continue;
++    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
++    if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
+     if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+-    if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+     pIdxInfo->idxNum = 1;
+     pIdxInfo->estimatedCost = 1.0;
+     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+@@ -179596,7 +191971,7 @@
+   return SQLITE_OK;
+ }
+ 
+-static void statClearPage(StatPage *p){
++static void statClearCells(StatPage *p){
+   int i;
+   if( p->aCell ){
+     for(i=0; i<p->nCell; i++){
+@@ -179604,6 +191979,12 @@
+     }
+     sqlite3_free(p->aCell);
+   }
++  p->nCell = 0;
++  p->aCell = 0;
++}
++
++static void statClearPage(StatPage *p){
++  statClearCells(p);
+   sqlite3PagerUnref(p->pPg);
+   sqlite3_free(p->zPath);
+   memset(p, 0, sizeof(StatPage));
+@@ -179666,22 +192047,33 @@
+   u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
+ 
+   p->flags = aHdr[0];
++  if( p->flags==0x0A || p->flags==0x0D ){
++    isLeaf = 1;
++    nHdr = 8;
++  }else if( p->flags==0x05 || p->flags==0x02 ){
++    isLeaf = 0;
++    nHdr = 12;
++  }else{
++    goto statPageIsCorrupt;
++  }
++  if( p->iPgno==1 ) nHdr += 100;
+   p->nCell = get2byte(&aHdr[3]);
+   p->nMxPayload = 0;
++  szPage = sqlite3BtreeGetPageSize(pBt);
+ 
+-  isLeaf = (p->flags==0x0A || p->flags==0x0D);
+-  nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+-
+   nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
+   nUnused += (int)aHdr[7];
+   iOff = get2byte(&aHdr[1]);
+   while( iOff ){
++    int iNext;
++    if( iOff>=szPage ) goto statPageIsCorrupt;
+     nUnused += get2byte(&aData[iOff+2]);
+-    iOff = get2byte(&aData[iOff]);
++    iNext = get2byte(&aData[iOff]);
++    if( iNext<iOff+4 && iNext>0 ) goto statPageIsCorrupt;
++    iOff = iNext;
+   }
+   p->nUnused = nUnused;
+   p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
+-  szPage = sqlite3BtreeGetPageSize(pBt);
+ 
+   if( p->nCell ){
+     int i;                        /* Used to iterate through cells */
+@@ -179698,6 +192090,7 @@
+       StatCell *pCell = &p->aCell[i];
+ 
+       iOff = get2byte(&aData[nHdr+i*2]);
++      if( iOff<nHdr || iOff>=szPage ) goto statPageIsCorrupt;
+       if( !isLeaf ){
+         pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
+         iOff += 4;
+@@ -179714,13 +192107,14 @@
+         }
+         if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
+         getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
++        if( nLocal<0 ) goto statPageIsCorrupt;
+         pCell->nLocal = nLocal;
+-        assert( nLocal>=0 );
+         assert( nPayload>=(u32)nLocal );
+         assert( nLocal<=(nUsable-35) );
+         if( nPayload>(u32)nLocal ){
+           int j;
+           int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
++          if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
+           pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
+           pCell->nOvfl = nOvfl;
+           pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+@@ -179744,6 +192138,11 @@
+   }
+ 
+   return SQLITE_OK;
++
++statPageIsCorrupt:
++  p->flags = 0;
++  statClearCells(p);
++  return SQLITE_OK;
+ }
+ 
+ /*
+@@ -180039,6 +192438,7 @@
+     0,                            /* xSavepoint */
+     0,                            /* xRelease */
+     0,                            /* xRollbackTo */
++    0                             /* xShadowName */
+   };
+   return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
+ }
+@@ -180169,9 +192569,8 @@
+     if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
+     if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+     if( !p->usable ){
+-      /* No solution.  Use the default SQLITE_BIG_DBL cost */
+-      pIdxInfo->estimatedRows = 0x7fffffff;
+-      return SQLITE_OK;
++      /* No solution. */
++      return SQLITE_CONSTRAINT;
+     }
+     iPlan = 2;
+     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+@@ -180363,6 +192762,10 @@
+   Pager *pPager;
+   int szPage;
+ 
++  if( pTab->db->flags & SQLITE_Defensive ){
++    zErr = "read-only";
++    goto update_fail;
++  }
+   if( argc==1 ){
+     zErr = "cannot delete";
+     goto update_fail;
+@@ -180419,7 +192822,7 @@
+   int i;
+   for(i=0; i<db->nDb; i++){
+     Btree *pBt = db->aDb[i].pBt;
+-    if( pBt ) sqlite3BtreeBeginTrans(pBt, 1);
++    if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0);
+   }
+   return SQLITE_OK;
+ }
+@@ -180453,6 +192856,7 @@
+     0,                            /* xSavepoint */
+     0,                            /* xRelease */
+     0,                            /* xRollbackTo */
++    0                             /* xShadowName */
+   };
+   return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
+ }
+@@ -180489,6 +192893,8 @@
+ # endif
+ #endif
+ 
++static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
++
+ typedef struct SessionHook SessionHook;
+ struct SessionHook {
+   void *pCtx;
+@@ -180551,6 +192957,7 @@
+   SessionInput in;                /* Input buffer or stream */
+   SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
+   int bPatchset;                  /* True if this is a patchset */
++  int bInvert;                    /* True to invert changeset */
+   int rc;                         /* Iterator error code */
+   sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
+   char *zTab;                     /* Current table */
+@@ -180707,6 +193114,42 @@
+ ** The records associated with INSERT changes are in the same format as for
+ ** changesets. It is not possible for a record associated with an INSERT
+ ** change to contain a field set to "undefined".
++**
++** REBASE BLOB FORMAT:
++**
++** A rebase blob may be output by sqlite3changeset_apply_v2() and its 
++** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
++** existing changesets. A rebase blob contains one entry for each conflict
++** resolved using either the OMIT or REPLACE strategies within the apply_v2()
++** call.
++**
++** The format used for a rebase blob is very similar to that used for
++** changesets. All entries related to a single table are grouped together.
++**
++** Each group of entries begins with a table header in changeset format:
++**
++**   1 byte: Constant 0x54 (capital 'T')
++**   Varint: Number of columns in the table.
++**   nCol bytes: 0x01 for PK columns, 0x00 otherwise.
++**   N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
++**
++** Followed by one or more entries associated with the table.
++**
++**   1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
++**   1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
++**   record: (in the record format defined above).
++**
++** In a rebase blob, the first field is set to SQLITE_INSERT if the change
++** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
++** it was a DELETE. The second field is set to 0x01 if the conflict 
++** resolution strategy was REPLACE, or 0x00 if it was OMIT.
++**
++** If the change that caused the conflict was a DELETE, then the single
++** record is a copy of the old.* record from the original changeset. If it
++** was an INSERT, then the single record is a copy of the new.* record. If
++** the conflicting change was an UPDATE, then the single record is a copy
++** of the new.* record with the PK fields filled in based on the original
++** old.* record.
+ */
+ 
+ /*
+@@ -182257,12 +194700,12 @@
+ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
+   if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
+     u8 *aNew;
+-    int nNew = p->nAlloc ? p->nAlloc : 128;
++    i64 nNew = p->nAlloc ? p->nAlloc : 128;
+     do {
+       nNew = nNew*2;
+-    }while( nNew<(p->nBuf+nByte) );
++    }while( (nNew-p->nBuf)<nByte );
+ 
+-    aNew = (u8 *)sqlite3_realloc(p->aBuf, nNew);
++    aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
+     if( 0==aNew ){
+       *pRc = SQLITE_NOMEM;
+     }else{
+@@ -182860,12 +195303,12 @@
+             rc = sqlite3_reset(pSel);
+           }
+ 
+-          /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
++          /* If the buffer is now larger than sessions_strm_chunk_size, pass
+           ** its contents to the xOutput() callback. */
+           if( xOutput 
+            && rc==SQLITE_OK 
+            && buf.nBuf>nNoop 
+-           && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE 
++           && buf.nBuf>sessions_strm_chunk_size 
+           ){
+             rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
+             nNoop = -1;
+@@ -183004,7 +195447,8 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn,
+   int nChangeset,                 /* Size of buffer pChangeset in bytes */
+-  void *pChangeset                /* Pointer to buffer containing changeset */
++  void *pChangeset,               /* Pointer to buffer containing changeset */
++  int bInvert                     /* True to invert changeset */
+ ){
+   sqlite3_changeset_iter *pRet;   /* Iterator to return */
+   int nByte;                      /* Number of bytes to allocate for iterator */
+@@ -183024,6 +195468,7 @@
+   pRet->in.xInput = xInput;
+   pRet->in.pIn = pIn;
+   pRet->in.bEof = (xInput ? 0 : 1);
++  pRet->bInvert = bInvert;
+ 
+   /* Populate the output variable and return success. */
+   *pp = pRet;
+@@ -183038,8 +195483,17 @@
+   int nChangeset,                 /* Size of buffer pChangeset in bytes */
+   void *pChangeset                /* Pointer to buffer containing changeset */
+ ){
+-  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
++  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
+ }
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int nChangeset,                 /* Size of buffer pChangeset in bytes */
++  void *pChangeset,               /* Pointer to buffer containing changeset */
++  int flags
++){
++  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
++  return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
++}
+ 
+ /*
+ ** Streaming version of sqlite3changeset_start().
+@@ -183049,8 +195503,17 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ ){
+-  return sessionChangesetStart(pp, xInput, pIn, 0, 0);
++  return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
+ }
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,    /* OUT: Changeset iterator handle */
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++){
++  int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
++  return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
++}
+ 
+ /*
+ ** If the SessionInput object passed as the only argument is a streaming
+@@ -183057,7 +195520,7 @@
+ ** object and the buffer is full, discard some data to free up space.
+ */
+ static void sessionDiscardData(SessionInput *pIn){
+-  if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
++  if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
+     int nMove = pIn->buf.nBuf - pIn->iNext;
+     assert( nMove>=0 );
+     if( nMove>0 ){
+@@ -183080,7 +195543,7 @@
+   int rc = SQLITE_OK;
+   if( pIn->xInput ){
+     while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
+-      int nNew = SESSIONS_STRM_CHUNK_SIZE;
++      int nNew = sessions_strm_chunk_size;
+ 
+       if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
+       if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
+@@ -183428,10 +195891,10 @@
+     op = p->in.aData[p->in.iNext++];
+   }
+ 
+-  if( p->zTab==0 ){
++  if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
+     /* The first record in the changeset is not a table header. Must be a
+     ** corrupt changeset. */
+-    assert( p->in.iNext==1 );
++    assert( p->in.iNext==1 || p->zTab );
+     return (p->rc = SQLITE_CORRUPT_BKPT);
+   }
+ 
+@@ -183456,33 +195919,39 @@
+     *paRec = &p->in.aData[p->in.iNext];
+     p->in.iNext += *pnRec;
+   }else{
++    sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
++    sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
+ 
+     /* If this is an UPDATE or DELETE, read the old.* record. */
+     if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
+       u8 *abPK = p->bPatchset ? p->abPK : 0;
+-      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
++      p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
+       if( p->rc!=SQLITE_OK ) return p->rc;
+     }
+ 
+     /* If this is an INSERT or UPDATE, read the new.* record. */
+     if( p->op!=SQLITE_DELETE ){
+-      p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
++      p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
+       if( p->rc!=SQLITE_OK ) return p->rc;
+     }
+ 
+-    if( p->bPatchset && p->op==SQLITE_UPDATE ){
++    if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
+       /* If this is an UPDATE that is part of a patchset, then all PK and
+       ** modified fields are present in the new.* record. The old.* record
+       ** is currently completely empty. This block shifts the PK fields from
+       ** new.* to old.*, to accommodate the code that reads these arrays.  */
+       for(i=0; i<p->nCol; i++){
+-        assert( p->apValue[i]==0 );
++        assert( p->bPatchset==0 || p->apValue[i]==0 );
+         if( p->abPK[i] ){
++          assert( p->apValue[i]==0 );
+           p->apValue[i] = p->apValue[i+p->nCol];
+           if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
+           p->apValue[i+p->nCol] = 0;
+         }
+       }
++    }else if( p->bInvert ){
++      if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
++      else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
+     }
+   }
+ 
+@@ -183799,7 +196268,7 @@
+     }
+ 
+     assert( rc==SQLITE_OK );
+-    if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
++    if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
+       rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+       sOut.nBuf = 0;
+       if( rc!=SQLITE_OK ) goto finished_invert;
+@@ -183878,7 +196347,8 @@
+   int bDeferConstraints;          /* True to defer constraints */
+   SessionBuffer constraints;      /* Deferred constraints are stored here */
+   SessionBuffer rebase;           /* Rebase information (if any) here */
+-  int bRebaseStarted;             /* If table header is already in rebase */
++  u8 bRebaseStarted;              /* If table header is already in rebase */
++  u8 bRebase;                     /* True to collect rebase information */
+ };
+ 
+ /*
+@@ -184275,35 +196745,36 @@
+   sqlite3_changeset_iter *pIter   /* Iterator pointing at current change */
+ ){
+   int rc = SQLITE_OK;
+-  int i;
+-  int eOp = pIter->op;
+-  if( p->bRebaseStarted==0 ){
+-    /* Append a table-header to the rebase buffer */
+-    const char *zTab = pIter->zTab;
+-    sessionAppendByte(&p->rebase, 'T', &rc);
+-    sessionAppendVarint(&p->rebase, p->nCol, &rc);
+-    sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
+-    sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
+-    p->bRebaseStarted = 1;
+-  }
++  if( p->bRebase ){
++    int i;
++    int eOp = pIter->op;
++    if( p->bRebaseStarted==0 ){
++      /* Append a table-header to the rebase buffer */
++      const char *zTab = pIter->zTab;
++      sessionAppendByte(&p->rebase, 'T', &rc);
++      sessionAppendVarint(&p->rebase, p->nCol, &rc);
++      sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
++      sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
++      p->bRebaseStarted = 1;
++    }
+ 
+-  assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
+-  assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
++    assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
++    assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
+ 
+-  sessionAppendByte(&p->rebase, 
+-      (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
+-  );
+-  sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
+-  for(i=0; i<p->nCol; i++){
+-    sqlite3_value *pVal = 0;
+-    if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
+-      sqlite3changeset_old(pIter, i, &pVal);
+-    }else{
+-      sqlite3changeset_new(pIter, i, &pVal);
++    sessionAppendByte(&p->rebase, 
++        (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
++        );
++    sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
++    for(i=0; i<p->nCol; i++){
++      sqlite3_value *pVal = 0;
++      if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
++        sqlite3changeset_old(pIter, i, &pVal);
++      }else{
++        sqlite3changeset_new(pIter, i, &pVal);
++      }
++      sessionAppendValue(&p->rebase, pVal, &rc);
+     }
+-    sessionAppendValue(&p->rebase, pVal, &rc);
+   }
+-
+   return rc;
+ }
+ 
+@@ -184646,7 +197117,7 @@
+     SessionBuffer cons = pApply->constraints;
+     memset(&pApply->constraints, 0, sizeof(SessionBuffer));
+ 
+-    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
++    rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
+     if( rc==SQLITE_OK ){
+       int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
+       int rc2;
+@@ -184712,6 +197183,7 @@
+ 
+   pIter->in.bNoDiscard = 1;
+   memset(&sApply, 0, sizeof(sApply));
++  sApply.bRebase = (ppRebase && pnRebase);
+   sqlite3_mutex_enter(sqlite3_db_mutex(db));
+   if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
+     rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
+@@ -184862,7 +197334,8 @@
+     }
+   }
+ 
+-  if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
++  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
++  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
+     *ppRebase = (void*)sApply.rebase.aBuf;
+     *pnRebase = sApply.rebase.nBuf;
+     sApply.rebase.aBuf = 0;
+@@ -184900,7 +197373,8 @@
+   int flags
+ ){
+   sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+-  int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
++  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
++  int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
+   if( rc==SQLITE_OK ){
+     rc = sessionChangesetApply(
+         db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
+@@ -184957,7 +197431,8 @@
+   int flags
+ ){
+   sqlite3_changeset_iter *pIter;  /* Iterator to skip through changeset */  
+-  int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
++  int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
++  int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
+   if( rc==SQLITE_OK ){
+     rc = sessionChangesetApply(
+         db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
+@@ -185330,13 +197805,12 @@
+         sessionAppendByte(&buf, p->op, &rc);
+         sessionAppendByte(&buf, p->bIndirect, &rc);
+         sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
++        if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
++          rc = xOutput(pOut, buf.aBuf, buf.nBuf);
++          buf.nBuf = 0;
++        }
+       }
+     }
+-
+-    if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
+-      rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+-      buf.nBuf = 0;
+-    }
+   }
+ 
+   if( rc==SQLITE_OK ){
+@@ -185727,7 +198201,7 @@
+       sessionAppendByte(&sOut, pIter->bIndirect, &rc);
+       sessionAppendBlob(&sOut, aRec, nRec, &rc);
+     }
+-    if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
++    if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
+       rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
+       sOut.nBuf = 0;
+     }
+@@ -185838,2439 +198312,30 @@
+   }
+ }
+ 
+-#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+-
+-/************** End of sqlite3session.c **************************************/
+-/************** Begin file json1.c *******************************************/
+-/*
+-** 2015-08-12
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-******************************************************************************
+-**
+-** This SQLite extension implements JSON functions.  The interface is
+-** modeled after MySQL JSON functions:
+-**
+-**     https://dev.mysql.com/doc/refman/5.7/en/json.html
+-**
+-** For the time being, all JSON is stored as pure text.  (We might add
+-** a JSONB type in the future which stores a binary encoding of JSON in
+-** a BLOB, but there is no support for JSONB in the current implementation.
+-** This implementation parses JSON text at 250 MB/s, so it is hard to see
+-** how JSONB might improve on that.)
++/* 
++** Global configuration
+ */
+-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
+-#if !defined(SQLITEINT_H)
+-/* #include "sqlite3ext.h" */
+-#endif
+-SQLITE_EXTENSION_INIT1
+-/* #include <assert.h> */
+-/* #include <string.h> */
+-/* #include <stdlib.h> */
+-/* #include <stdarg.h> */
+-
+-/* Mark a function parameter as unused, to suppress nuisance compiler
+-** warnings. */
+-#ifndef UNUSED_PARAM
+-# define UNUSED_PARAM(X)  (void)(X)
+-#endif
+-
+-#ifndef LARGEST_INT64
+-# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+-# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+-#endif
+-
+-/*
+-** Versions of isspace(), isalnum() and isdigit() to which it is safe
+-** to pass signed char values.
+-*/
+-#ifdef sqlite3Isdigit
+-   /* Use the SQLite core versions if this routine is part of the
+-   ** SQLite amalgamation */
+-#  define safe_isdigit(x)  sqlite3Isdigit(x)
+-#  define safe_isalnum(x)  sqlite3Isalnum(x)
+-#  define safe_isxdigit(x) sqlite3Isxdigit(x)
+-#else
+-   /* Use the standard library for separate compilation */
+-#include <ctype.h>  /* amalgamator: keep */
+-#  define safe_isdigit(x)  isdigit((unsigned char)(x))
+-#  define safe_isalnum(x)  isalnum((unsigned char)(x))
+-#  define safe_isxdigit(x) isxdigit((unsigned char)(x))
+-#endif
+-
+-/*
+-** Growing our own isspace() routine this way is twice as fast as
+-** the library isspace() function, resulting in a 7% overall performance
+-** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
+-*/
+-static const char jsonIsSpace[] = {
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
+-};
+-#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
+-
+-#ifndef SQLITE_AMALGAMATION
+-  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
+-  ** but the definitions need to be repeated for separate compilation. */
+-  typedef sqlite3_uint64 u64;
+-  typedef unsigned int u32;
+-  typedef unsigned short int u16;
+-  typedef unsigned char u8;
+-#endif
+-
+-/* Objects */
+-typedef struct JsonString JsonString;
+-typedef struct JsonNode JsonNode;
+-typedef struct JsonParse JsonParse;
+-
+-/* An instance of this object represents a JSON string
+-** under construction.  Really, this is a generic string accumulator
+-** that can be and is used to create strings other than JSON.
+-*/
+-struct JsonString {
+-  sqlite3_context *pCtx;   /* Function context - put error messages here */
+-  char *zBuf;              /* Append JSON content here */
+-  u64 nAlloc;              /* Bytes of storage available in zBuf[] */
+-  u64 nUsed;               /* Bytes of zBuf[] currently used */
+-  u8 bStatic;              /* True if zBuf is static space */
+-  u8 bErr;                 /* True if an error has been encountered */
+-  char zSpace[100];        /* Initial static space */
+-};
+-
+-/* JSON type values
+-*/
+-#define JSON_NULL     0
+-#define JSON_TRUE     1
+-#define JSON_FALSE    2
+-#define JSON_INT      3
+-#define JSON_REAL     4
+-#define JSON_STRING   5
+-#define JSON_ARRAY    6
+-#define JSON_OBJECT   7
+-
+-/* The "subtype" set for JSON values */
+-#define JSON_SUBTYPE  74    /* Ascii for "J" */
+-
+-/*
+-** Names of the various JSON types:
+-*/
+-static const char * const jsonType[] = {
+-  "null", "true", "false", "integer", "real", "text", "array", "object"
+-};
+-
+-/* Bit values for the JsonNode.jnFlag field
+-*/
+-#define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
+-#define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
+-#define JNODE_REMOVE  0x04         /* Do not output */
+-#define JNODE_REPLACE 0x08         /* Replace with JsonNode.u.iReplace */
+-#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
+-#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
+-#define JNODE_LABEL   0x40         /* Is a label of an object */
+-
+-
+-/* A single node of parsed JSON
+-*/
+-struct JsonNode {
+-  u8 eType;              /* One of the JSON_ type values */
+-  u8 jnFlags;            /* JNODE flags */
+-  u32 n;                 /* Bytes of content, or number of sub-nodes */
+-  union {
+-    const char *zJContent; /* Content for INT, REAL, and STRING */
+-    u32 iAppend;           /* More terms for ARRAY and OBJECT */
+-    u32 iKey;              /* Key for ARRAY objects in json_tree() */
+-    u32 iReplace;          /* Replacement content for JNODE_REPLACE */
+-    JsonNode *pPatch;      /* Node chain of patch for JNODE_PATCH */
+-  } u;
+-};
+-
+-/* A completely parsed JSON string
+-*/
+-struct JsonParse {
+-  u32 nNode;         /* Number of slots of aNode[] used */
+-  u32 nAlloc;        /* Number of slots of aNode[] allocated */
+-  JsonNode *aNode;   /* Array of nodes containing the parse */
+-  const char *zJson; /* Original JSON string */
+-  u32 *aUp;          /* Index of parent of each node */
+-  u8 oom;            /* Set to true if out of memory */
+-  u8 nErr;           /* Number of errors seen */
+-  u16 iDepth;        /* Nesting depth */
+-  int nJson;         /* Length of the zJson string in bytes */
+-};
+-
+-/*
+-** Maximum nesting depth of JSON for this implementation.
+-**
+-** This limit is needed to avoid a stack overflow in the recursive
+-** descent parser.  A depth of 2000 is far deeper than any sane JSON
+-** should go.
+-*/
+-#define JSON_MAX_DEPTH  2000
+-
+-/**************************************************************************
+-** Utility routines for dealing with JsonString objects
+-**************************************************************************/
+-
+-/* Set the JsonString object to an empty string
+-*/
+-static void jsonZero(JsonString *p){
+-  p->zBuf = p->zSpace;
+-  p->nAlloc = sizeof(p->zSpace);
+-  p->nUsed = 0;
+-  p->bStatic = 1;
+-}
+-
+-/* Initialize the JsonString object
+-*/
+-static void jsonInit(JsonString *p, sqlite3_context *pCtx){
+-  p->pCtx = pCtx;
+-  p->bErr = 0;
+-  jsonZero(p);
+-}
+-
+-
+-/* Free all allocated memory and reset the JsonString object back to its
+-** initial state.
+-*/
+-static void jsonReset(JsonString *p){
+-  if( !p->bStatic ) sqlite3_free(p->zBuf);
+-  jsonZero(p);
+-}
+-
+-
+-/* Report an out-of-memory (OOM) condition 
+-*/
+-static void jsonOom(JsonString *p){
+-  p->bErr = 1;
+-  sqlite3_result_error_nomem(p->pCtx);
+-  jsonReset(p);
+-}
+-
+-/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
+-** Return zero on success.  Return non-zero on an OOM error
+-*/
+-static int jsonGrow(JsonString *p, u32 N){
+-  u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
+-  char *zNew;
+-  if( p->bStatic ){
+-    if( p->bErr ) return 1;
+-    zNew = sqlite3_malloc64(nTotal);
+-    if( zNew==0 ){
+-      jsonOom(p);
+-      return SQLITE_NOMEM;
+-    }
+-    memcpy(zNew, p->zBuf, (size_t)p->nUsed);
+-    p->zBuf = zNew;
+-    p->bStatic = 0;
+-  }else{
+-    zNew = sqlite3_realloc64(p->zBuf, nTotal);
+-    if( zNew==0 ){
+-      jsonOom(p);
+-      return SQLITE_NOMEM;
+-    }
+-    p->zBuf = zNew;
+-  }
+-  p->nAlloc = nTotal;
+-  return SQLITE_OK;
+-}
+-
+-/* Append N bytes from zIn onto the end of the JsonString string.
+-*/
+-static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
+-  if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
+-  memcpy(p->zBuf+p->nUsed, zIn, N);
+-  p->nUsed += N;
+-}
+-
+-/* Append formatted text (not to exceed N bytes) to the JsonString.
+-*/
+-static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
+-  va_list ap;
+-  if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return;
+-  va_start(ap, zFormat);
+-  sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
+-  va_end(ap);
+-  p->nUsed += (int)strlen(p->zBuf+p->nUsed);
+-}
+-
+-/* Append a single character
+-*/
+-static void jsonAppendChar(JsonString *p, char c){
+-  if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
+-  p->zBuf[p->nUsed++] = c;
+-}
+-
+-/* Append a comma separator to the output buffer, if the previous
+-** character is not '[' or '{'.
+-*/
+-static void jsonAppendSeparator(JsonString *p){
+-  char c;
+-  if( p->nUsed==0 ) return;
+-  c = p->zBuf[p->nUsed-1];
+-  if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
+-}
+-
+-/* Append the N-byte string in zIn to the end of the JsonString string
+-** under construction.  Enclose the string in "..." and escape
+-** any double-quotes or backslash characters contained within the
+-** string.
+-*/
+-static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
+-  u32 i;
+-  if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
+-  p->zBuf[p->nUsed++] = '"';
+-  for(i=0; i<N; i++){
+-    unsigned char c = ((unsigned const char*)zIn)[i];
+-    if( c=='"' || c=='\\' ){
+-      json_simple_escape:
+-      if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
+-      p->zBuf[p->nUsed++] = '\\';
+-    }else if( c<=0x1f ){
+-      static const char aSpecial[] = {
+-         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
+-         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
+-      };
+-      assert( sizeof(aSpecial)==32 );
+-      assert( aSpecial['\b']=='b' );
+-      assert( aSpecial['\f']=='f' );
+-      assert( aSpecial['\n']=='n' );
+-      assert( aSpecial['\r']=='r' );
+-      assert( aSpecial['\t']=='t' );
+-      if( aSpecial[c] ){
+-        c = aSpecial[c];
+-        goto json_simple_escape;
++SQLITE_API int sqlite3session_config(int op, void *pArg){
++  int rc = SQLITE_OK;
++  switch( op ){
++    case SQLITE_SESSION_CONFIG_STRMSIZE: {
++      int *pInt = (int*)pArg;
++      if( *pInt>0 ){
++        sessions_strm_chunk_size = *pInt;
+       }
+-      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
+-      p->zBuf[p->nUsed++] = '\\';
+-      p->zBuf[p->nUsed++] = 'u';
+-      p->zBuf[p->nUsed++] = '0';
+-      p->zBuf[p->nUsed++] = '0';
+-      p->zBuf[p->nUsed++] = '0' + (c>>4);
+-      c = "0123456789abcdef"[c&0xf];
+-    }
+-    p->zBuf[p->nUsed++] = c;
+-  }
+-  p->zBuf[p->nUsed++] = '"';
+-  assert( p->nUsed<p->nAlloc );
+-}
+-
+-/*
+-** Append a function parameter value to the JSON string under 
+-** construction.
+-*/
+-static void jsonAppendValue(
+-  JsonString *p,                 /* Append to this JSON string */
+-  sqlite3_value *pValue          /* Value to append */
+-){
+-  switch( sqlite3_value_type(pValue) ){
+-    case SQLITE_NULL: {
+-      jsonAppendRaw(p, "null", 4);
++      *pInt = sessions_strm_chunk_size;
+       break;
+     }
+-    case SQLITE_INTEGER:
+-    case SQLITE_FLOAT: {
+-      const char *z = (const char*)sqlite3_value_text(pValue);
+-      u32 n = (u32)sqlite3_value_bytes(pValue);
+-      jsonAppendRaw(p, z, n);
++    default:
++      rc = SQLITE_MISUSE;
+       break;
+-    }
+-    case SQLITE_TEXT: {
+-      const char *z = (const char*)sqlite3_value_text(pValue);
+-      u32 n = (u32)sqlite3_value_bytes(pValue);
+-      if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
+-        jsonAppendRaw(p, z, n);
+-      }else{
+-        jsonAppendString(p, z, n);
+-      }
+-      break;
+-    }
+-    default: {
+-      if( p->bErr==0 ){
+-        sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
+-        p->bErr = 2;
+-        jsonReset(p);
+-      }
+-      break;
+-    }
+   }
+-}
+-
+-
+-/* Make the JSON in p the result of the SQL function.
+-*/
+-static void jsonResult(JsonString *p){
+-  if( p->bErr==0 ){
+-    sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, 
+-                          p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
+-                          SQLITE_UTF8);
+-    jsonZero(p);
+-  }
+-  assert( p->bStatic );
+-}
+-
+-/**************************************************************************
+-** Utility routines for dealing with JsonNode and JsonParse objects
+-**************************************************************************/
+-
+-/*
+-** Return the number of consecutive JsonNode slots need to represent
+-** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
+-** OBJECT types, the number might be larger.
+-**
+-** Appended elements are not counted.  The value returned is the number
+-** by which the JsonNode counter should increment in order to go to the
+-** next peer value.
+-*/
+-static u32 jsonNodeSize(JsonNode *pNode){
+-  return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
+-}
+-
+-/*
+-** Reclaim all memory allocated by a JsonParse object.  But do not
+-** delete the JsonParse object itself.
+-*/
+-static void jsonParseReset(JsonParse *pParse){
+-  sqlite3_free(pParse->aNode);
+-  pParse->aNode = 0;
+-  pParse->nNode = 0;
+-  pParse->nAlloc = 0;
+-  sqlite3_free(pParse->aUp);
+-  pParse->aUp = 0;
+-}
+-
+-/*
+-** Free a JsonParse object that was obtained from sqlite3_malloc().
+-*/
+-static void jsonParseFree(JsonParse *pParse){
+-  jsonParseReset(pParse);
+-  sqlite3_free(pParse);
+-}
+-
+-/*
+-** Convert the JsonNode pNode into a pure JSON string and
+-** append to pOut.  Subsubstructure is also included.  Return
+-** the number of JsonNode objects that are encoded.
+-*/
+-static void jsonRenderNode(
+-  JsonNode *pNode,               /* The node to render */
+-  JsonString *pOut,              /* Write JSON here */
+-  sqlite3_value **aReplace       /* Replacement values */
+-){
+-  if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
+-    if( pNode->jnFlags & JNODE_REPLACE ){
+-      jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
+-      return;
+-    }
+-    pNode = pNode->u.pPatch;
+-  }
+-  switch( pNode->eType ){
+-    default: {
+-      assert( pNode->eType==JSON_NULL );
+-      jsonAppendRaw(pOut, "null", 4);
+-      break;
+-    }
+-    case JSON_TRUE: {
+-      jsonAppendRaw(pOut, "true", 4);
+-      break;
+-    }
+-    case JSON_FALSE: {
+-      jsonAppendRaw(pOut, "false", 5);
+-      break;
+-    }
+-    case JSON_STRING: {
+-      if( pNode->jnFlags & JNODE_RAW ){
+-        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
+-        break;
+-      }
+-      /* Fall through into the next case */
+-    }
+-    case JSON_REAL:
+-    case JSON_INT: {
+-      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+-      break;
+-    }
+-    case JSON_ARRAY: {
+-      u32 j = 1;
+-      jsonAppendChar(pOut, '[');
+-      for(;;){
+-        while( j<=pNode->n ){
+-          if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
+-            jsonAppendSeparator(pOut);
+-            jsonRenderNode(&pNode[j], pOut, aReplace);
+-          }
+-          j += jsonNodeSize(&pNode[j]);
+-        }
+-        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+-        pNode = &pNode[pNode->u.iAppend];
+-        j = 1;
+-      }
+-      jsonAppendChar(pOut, ']');
+-      break;
+-    }
+-    case JSON_OBJECT: {
+-      u32 j = 1;
+-      jsonAppendChar(pOut, '{');
+-      for(;;){
+-        while( j<=pNode->n ){
+-          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
+-            jsonAppendSeparator(pOut);
+-            jsonRenderNode(&pNode[j], pOut, aReplace);
+-            jsonAppendChar(pOut, ':');
+-            jsonRenderNode(&pNode[j+1], pOut, aReplace);
+-          }
+-          j += 1 + jsonNodeSize(&pNode[j+1]);
+-        }
+-        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
+-        pNode = &pNode[pNode->u.iAppend];
+-        j = 1;
+-      }
+-      jsonAppendChar(pOut, '}');
+-      break;
+-    }
+-  }
+-}
+-
+-/*
+-** Return a JsonNode and all its descendents as a JSON string.
+-*/
+-static void jsonReturnJson(
+-  JsonNode *pNode,            /* Node to return */
+-  sqlite3_context *pCtx,      /* Return value for this function */
+-  sqlite3_value **aReplace    /* Array of replacement values */
+-){
+-  JsonString s;
+-  jsonInit(&s, pCtx);
+-  jsonRenderNode(pNode, &s, aReplace);
+-  jsonResult(&s);
+-  sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** Make the JsonNode the return value of the function.
+-*/
+-static void jsonReturn(
+-  JsonNode *pNode,            /* Node to return */
+-  sqlite3_context *pCtx,      /* Return value for this function */
+-  sqlite3_value **aReplace    /* Array of replacement values */
+-){
+-  switch( pNode->eType ){
+-    default: {
+-      assert( pNode->eType==JSON_NULL );
+-      sqlite3_result_null(pCtx);
+-      break;
+-    }
+-    case JSON_TRUE: {
+-      sqlite3_result_int(pCtx, 1);
+-      break;
+-    }
+-    case JSON_FALSE: {
+-      sqlite3_result_int(pCtx, 0);
+-      break;
+-    }
+-    case JSON_INT: {
+-      sqlite3_int64 i = 0;
+-      const char *z = pNode->u.zJContent;
+-      if( z[0]=='-' ){ z++; }
+-      while( z[0]>='0' && z[0]<='9' ){
+-        unsigned v = *(z++) - '0';
+-        if( i>=LARGEST_INT64/10 ){
+-          if( i>LARGEST_INT64/10 ) goto int_as_real;
+-          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
+-          if( v==9 ) goto int_as_real;
+-          if( v==8 ){
+-            if( pNode->u.zJContent[0]=='-' ){
+-              sqlite3_result_int64(pCtx, SMALLEST_INT64);
+-              goto int_done;
+-            }else{
+-              goto int_as_real;
+-            }
+-          }
+-        }
+-        i = i*10 + v;
+-      }
+-      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
+-      sqlite3_result_int64(pCtx, i);
+-      int_done:
+-      break;
+-      int_as_real: /* fall through to real */;
+-    }
+-    case JSON_REAL: {
+-      double r;
+-#ifdef SQLITE_AMALGAMATION
+-      const char *z = pNode->u.zJContent;
+-      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
+-#else
+-      r = strtod(pNode->u.zJContent, 0);
+-#endif
+-      sqlite3_result_double(pCtx, r);
+-      break;
+-    }
+-    case JSON_STRING: {
+-#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
+-      ** json_insert() and json_replace() and those routines do not
+-      ** call jsonReturn() */
+-      if( pNode->jnFlags & JNODE_RAW ){
+-        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
+-                            SQLITE_TRANSIENT);
+-      }else 
+-#endif
+-      assert( (pNode->jnFlags & JNODE_RAW)==0 );
+-      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+-        /* JSON formatted without any backslash-escapes */
+-        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
+-                            SQLITE_TRANSIENT);
+-      }else{
+-        /* Translate JSON formatted string into raw text */
+-        u32 i;
+-        u32 n = pNode->n;
+-        const char *z = pNode->u.zJContent;
+-        char *zOut;
+-        u32 j;
+-        zOut = sqlite3_malloc( n+1 );
+-        if( zOut==0 ){
+-          sqlite3_result_error_nomem(pCtx);
+-          break;
+-        }
+-        for(i=1, j=0; i<n-1; i++){
+-          char c = z[i];
+-          if( c!='\\' ){
+-            zOut[j++] = c;
+-          }else{
+-            c = z[++i];
+-            if( c=='u' ){
+-              u32 v = 0, k;
+-              for(k=0; k<4; i++, k++){
+-                assert( i<n-2 );
+-                c = z[i+1];
+-                assert( safe_isxdigit(c) );
+-                if( c<='9' ) v = v*16 + c - '0';
+-                else if( c<='F' ) v = v*16 + c - 'A' + 10;
+-                else v = v*16 + c - 'a' + 10;
+-              }
+-              if( v==0 ) break;
+-              if( v<=0x7f ){
+-                zOut[j++] = (char)v;
+-              }else if( v<=0x7ff ){
+-                zOut[j++] = (char)(0xc0 | (v>>6));
+-                zOut[j++] = 0x80 | (v&0x3f);
+-              }else{
+-                zOut[j++] = (char)(0xe0 | (v>>12));
+-                zOut[j++] = 0x80 | ((v>>6)&0x3f);
+-                zOut[j++] = 0x80 | (v&0x3f);
+-              }
+-            }else{
+-              if( c=='b' ){
+-                c = '\b';
+-              }else if( c=='f' ){
+-                c = '\f';
+-              }else if( c=='n' ){
+-                c = '\n';
+-              }else if( c=='r' ){
+-                c = '\r';
+-              }else if( c=='t' ){
+-                c = '\t';
+-              }
+-              zOut[j++] = c;
+-            }
+-          }
+-        }
+-        zOut[j] = 0;
+-        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
+-      }
+-      break;
+-    }
+-    case JSON_ARRAY:
+-    case JSON_OBJECT: {
+-      jsonReturnJson(pNode, pCtx, aReplace);
+-      break;
+-    }
+-  }
+-}
+-
+-/* Forward reference */
+-static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
+-
+-/*
+-** A macro to hint to the compiler that a function should not be
+-** inlined.
+-*/
+-#if defined(__GNUC__)
+-#  define JSON_NOINLINE  __attribute__((noinline))
+-#elif defined(_MSC_VER) && _MSC_VER>=1310
+-#  define JSON_NOINLINE  __declspec(noinline)
+-#else
+-#  define JSON_NOINLINE
+-#endif
+-
+-
+-static JSON_NOINLINE int jsonParseAddNodeExpand(
+-  JsonParse *pParse,        /* Append the node to this object */
+-  u32 eType,                /* Node type */
+-  u32 n,                    /* Content size or sub-node count */
+-  const char *zContent      /* Content */
+-){
+-  u32 nNew;
+-  JsonNode *pNew;
+-  assert( pParse->nNode>=pParse->nAlloc );
+-  if( pParse->oom ) return -1;
+-  nNew = pParse->nAlloc*2 + 10;
+-  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+-  if( pNew==0 ){
+-    pParse->oom = 1;
+-    return -1;
+-  }
+-  pParse->nAlloc = nNew;
+-  pParse->aNode = pNew;
+-  assert( pParse->nNode<pParse->nAlloc );
+-  return jsonParseAddNode(pParse, eType, n, zContent);
+-}
+-
+-/*
+-** Create a new JsonNode instance based on the arguments and append that
+-** instance to the JsonParse.  Return the index in pParse->aNode[] of the
+-** new node, or -1 if a memory allocation fails.
+-*/
+-static int jsonParseAddNode(
+-  JsonParse *pParse,        /* Append the node to this object */
+-  u32 eType,                /* Node type */
+-  u32 n,                    /* Content size or sub-node count */
+-  const char *zContent      /* Content */
+-){
+-  JsonNode *p;
+-  if( pParse->nNode>=pParse->nAlloc ){
+-    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
+-  }
+-  p = &pParse->aNode[pParse->nNode];
+-  p->eType = (u8)eType;
+-  p->jnFlags = 0;
+-  p->n = n;
+-  p->u.zJContent = zContent;
+-  return pParse->nNode++;
+-}
+-
+-/*
+-** Return true if z[] begins with 4 (or more) hexadecimal digits
+-*/
+-static int jsonIs4Hex(const char *z){
+-  int i;
+-  for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
+-  return 1;
+-}
+-
+-/*
+-** Parse a single JSON value which begins at pParse->zJson[i].  Return the
+-** index of the first character past the end of the value parsed.
+-**
+-** Return negative for a syntax error.  Special cases:  return -2 if the
+-** first non-whitespace character is '}' and return -3 if the first
+-** non-whitespace character is ']'.
+-*/
+-static int jsonParseValue(JsonParse *pParse, u32 i){
+-  char c;
+-  u32 j;
+-  int iThis;
+-  int x;
+-  JsonNode *pNode;
+-  const char *z = pParse->zJson;
+-  while( safe_isspace(z[i]) ){ i++; }
+-  if( (c = z[i])=='{' ){
+-    /* Parse object */
+-    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+-    if( iThis<0 ) return -1;
+-    for(j=i+1;;j++){
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+-      x = jsonParseValue(pParse, j);
+-      if( x<0 ){
+-        pParse->iDepth--;
+-        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
+-        return -1;
+-      }
+-      if( pParse->oom ) return -1;
+-      pNode = &pParse->aNode[pParse->nNode-1];
+-      if( pNode->eType!=JSON_STRING ) return -1;
+-      pNode->jnFlags |= JNODE_LABEL;
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( z[j]!=':' ) return -1;
+-      j++;
+-      x = jsonParseValue(pParse, j);
+-      pParse->iDepth--;
+-      if( x<0 ) return -1;
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      c = z[j];
+-      if( c==',' ) continue;
+-      if( c!='}' ) return -1;
+-      break;
+-    }
+-    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+-    return j+1;
+-  }else if( c=='[' ){
+-    /* Parse array */
+-    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+-    if( iThis<0 ) return -1;
+-    for(j=i+1;;j++){
+-      while( safe_isspace(z[j]) ){ j++; }
+-      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+-      x = jsonParseValue(pParse, j);
+-      pParse->iDepth--;
+-      if( x<0 ){
+-        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+-        return -1;
+-      }
+-      j = x;
+-      while( safe_isspace(z[j]) ){ j++; }
+-      c = z[j];
+-      if( c==',' ) continue;
+-      if( c!=']' ) return -1;
+-      break;
+-    }
+-    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+-    return j+1;
+-  }else if( c=='"' ){
+-    /* Parse string */
+-    u8 jnFlags = 0;
+-    j = i+1;
+-    for(;;){
+-      c = z[j];
+-      if( (c & ~0x1f)==0 ){
+-        /* Control characters are not allowed in strings */
+-        return -1;
+-      }
+-      if( c=='\\' ){
+-        c = z[++j];
+-        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
+-           || c=='n' || c=='r' || c=='t'
+-           || (c=='u' && jsonIs4Hex(z+j+1)) ){
+-          jnFlags = JNODE_ESCAPE;
+-        }else{
+-          return -1;
+-        }
+-      }else if( c=='"' ){
+-        break;
+-      }
+-      j++;
+-    }
+-    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
+-    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
+-    return j+1;
+-  }else if( c=='n'
+-         && strncmp(z+i,"null",4)==0
+-         && !safe_isalnum(z[i+4]) ){
+-    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+-    return i+4;
+-  }else if( c=='t'
+-         && strncmp(z+i,"true",4)==0
+-         && !safe_isalnum(z[i+4]) ){
+-    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+-    return i+4;
+-  }else if( c=='f'
+-         && strncmp(z+i,"false",5)==0
+-         && !safe_isalnum(z[i+5]) ){
+-    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+-    return i+5;
+-  }else if( c=='-' || (c>='0' && c<='9') ){
+-    /* Parse number */
+-    u8 seenDP = 0;
+-    u8 seenE = 0;
+-    assert( '-' < '0' );
+-    if( c<='0' ){
+-      j = c=='-' ? i+1 : i;
+-      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+-    }
+-    j = i+1;
+-    for(;; j++){
+-      c = z[j];
+-      if( c>='0' && c<='9' ) continue;
+-      if( c=='.' ){
+-        if( z[j-1]=='-' ) return -1;
+-        if( seenDP ) return -1;
+-        seenDP = 1;
+-        continue;
+-      }
+-      if( c=='e' || c=='E' ){
+-        if( z[j-1]<'0' ) return -1;
+-        if( seenE ) return -1;
+-        seenDP = seenE = 1;
+-        c = z[j+1];
+-        if( c=='+' || c=='-' ){
+-          j++;
+-          c = z[j+1];
+-        }
+-        if( c<'0' || c>'9' ) return -1;
+-        continue;
+-      }
+-      break;
+-    }
+-    if( z[j-1]<'0' ) return -1;
+-    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
+-                        j - i, &z[i]);
+-    return j;
+-  }else if( c=='}' ){
+-    return -2;  /* End of {...} */
+-  }else if( c==']' ){
+-    return -3;  /* End of [...] */
+-  }else if( c==0 ){
+-    return 0;   /* End of file */
+-  }else{
+-    return -1;  /* Syntax error */
+-  }
+-}
+-
+-/*
+-** Parse a complete JSON string.  Return 0 on success or non-zero if there
+-** are any errors.  If an error occurs, free all memory associated with
+-** pParse.
+-**
+-** pParse is uninitialized when this routine is called.
+-*/
+-static int jsonParse(
+-  JsonParse *pParse,           /* Initialize and fill this JsonParse object */
+-  sqlite3_context *pCtx,       /* Report errors here */
+-  const char *zJson            /* Input JSON text to be parsed */
+-){
+-  int i;
+-  memset(pParse, 0, sizeof(*pParse));
+-  if( zJson==0 ) return 1;
+-  pParse->zJson = zJson;
+-  i = jsonParseValue(pParse, 0);
+-  if( pParse->oom ) i = -1;
+-  if( i>0 ){
+-    assert( pParse->iDepth==0 );
+-    while( safe_isspace(zJson[i]) ) i++;
+-    if( zJson[i] ) i = -1;
+-  }
+-  if( i<=0 ){
+-    if( pCtx!=0 ){
+-      if( pParse->oom ){
+-        sqlite3_result_error_nomem(pCtx);
+-      }else{
+-        sqlite3_result_error(pCtx, "malformed JSON", -1);
+-      }
+-    }
+-    jsonParseReset(pParse);
+-    return 1;
+-  }
+-  return 0;
+-}
+-
+-/* Mark node i of pParse as being a child of iParent.  Call recursively
+-** to fill in all the descendants of node i.
+-*/
+-static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
+-  JsonNode *pNode = &pParse->aNode[i];
+-  u32 j;
+-  pParse->aUp[i] = iParent;
+-  switch( pNode->eType ){
+-    case JSON_ARRAY: {
+-      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){
+-        jsonParseFillInParentage(pParse, i+j, i);
+-      }
+-      break;
+-    }
+-    case JSON_OBJECT: {
+-      for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){
+-        pParse->aUp[i+j] = i;
+-        jsonParseFillInParentage(pParse, i+j+1, i);
+-      }
+-      break;
+-    }
+-    default: {
+-      break;
+-    }
+-  }
+-}
+-
+-/*
+-** Compute the parentage of all nodes in a completed parse.
+-*/
+-static int jsonParseFindParents(JsonParse *pParse){
+-  u32 *aUp;
+-  assert( pParse->aUp==0 );
+-  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+-  if( aUp==0 ){
+-    pParse->oom = 1;
+-    return SQLITE_NOMEM;
+-  }
+-  jsonParseFillInParentage(pParse, 0, 0);
+-  return SQLITE_OK;
+-}
+-
+-/*
+-** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
+-*/
+-#define JSON_CACHE_ID  (-429938)
+-
+-/*
+-** Obtain a complete parse of the JSON found in the first argument
+-** of the argv array.  Use the sqlite3_get_auxdata() cache for this
+-** parse if it is available.  If the cache is not available or if it
+-** is no longer valid, parse the JSON again and return the new parse,
+-** and also register the new parse so that it will be available for
+-** future sqlite3_get_auxdata() calls.
+-*/
+-static JsonParse *jsonParseCached(
+-  sqlite3_context *pCtx,
+-  sqlite3_value **argv
+-){
+-  const char *zJson = (const char*)sqlite3_value_text(argv[0]);
+-  int nJson = sqlite3_value_bytes(argv[0]);
+-  JsonParse *p;
+-  if( zJson==0 ) return 0;
+-  p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+-  if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){
+-    p->nErr = 0;
+-    return p; /* The cached entry matches, so return it */
+-  }
+-  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+-  if( p==0 ){
+-    sqlite3_result_error_nomem(pCtx);
+-    return 0;
+-  }
+-  memset(p, 0, sizeof(*p));
+-  p->zJson = (char*)&p[1];
+-  memcpy((char*)p->zJson, zJson, nJson+1);
+-  if( jsonParse(p, pCtx, p->zJson) ){
+-    sqlite3_free(p);
+-    return 0;
+-  }
+-  p->nJson = nJson;
+-  sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree);
+-  return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID);
+-}
+-
+-/*
+-** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
+-** a match.
+-*/
+-static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
+-  if( pNode->jnFlags & JNODE_RAW ){
+-    if( pNode->n!=nKey ) return 0;
+-    return strncmp(pNode->u.zJContent, zKey, nKey)==0;
+-  }else{
+-    if( pNode->n!=nKey+2 ) return 0;
+-    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
+-  }
+-}
+-
+-/* forward declaration */
+-static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
+-
+-/*
+-** Search along zPath to find the node specified.  Return a pointer
+-** to that node, or NULL if zPath is malformed or if there is no such
+-** node.
+-**
+-** If pApnd!=0, then try to append new nodes to complete zPath if it is
+-** possible to do so and if no existing node corresponds to zPath.  If
+-** new nodes are appended *pApnd is set to 1.
+-*/
+-static JsonNode *jsonLookupStep(
+-  JsonParse *pParse,      /* The JSON to search */
+-  u32 iRoot,              /* Begin the search at this node */
+-  const char *zPath,      /* The path to search */
+-  int *pApnd,             /* Append nodes to complete path if not NULL */
+-  const char **pzErr      /* Make *pzErr point to any syntax error in zPath */
+-){
+-  u32 i, j, nKey;
+-  const char *zKey;
+-  JsonNode *pRoot = &pParse->aNode[iRoot];
+-  if( zPath[0]==0 ) return pRoot;
+-  if( zPath[0]=='.' ){
+-    if( pRoot->eType!=JSON_OBJECT ) return 0;
+-    zPath++;
+-    if( zPath[0]=='"' ){
+-      zKey = zPath + 1;
+-      for(i=1; zPath[i] && zPath[i]!='"'; i++){}
+-      nKey = i-1;
+-      if( zPath[i] ){
+-        i++;
+-      }else{
+-        *pzErr = zPath;
+-        return 0;
+-      }
+-    }else{
+-      zKey = zPath;
+-      for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
+-      nKey = i;
+-    }
+-    if( nKey==0 ){
+-      *pzErr = zPath;
+-      return 0;
+-    }
+-    j = 1;
+-    for(;;){
+-      while( j<=pRoot->n ){
+-        if( jsonLabelCompare(pRoot+j, zKey, nKey) ){
+-          return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr);
+-        }
+-        j++;
+-        j += jsonNodeSize(&pRoot[j]);
+-      }
+-      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+-      iRoot += pRoot->u.iAppend;
+-      pRoot = &pParse->aNode[iRoot];
+-      j = 1;
+-    }
+-    if( pApnd ){
+-      u32 iStart, iLabel;
+-      JsonNode *pNode;
+-      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+-      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+-      zPath += i;
+-      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+-      if( pParse->oom ) return 0;
+-      if( pNode ){
+-        pRoot = &pParse->aNode[iRoot];
+-        pRoot->u.iAppend = iStart - iRoot;
+-        pRoot->jnFlags |= JNODE_APPEND;
+-        pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
+-      }
+-      return pNode;
+-    }
+-  }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){
+-    if( pRoot->eType!=JSON_ARRAY ) return 0;
+-    i = 0;
+-    j = 1;
+-    while( safe_isdigit(zPath[j]) ){
+-      i = i*10 + zPath[j] - '0';
+-      j++;
+-    }
+-    if( zPath[j]!=']' ){
+-      *pzErr = zPath;
+-      return 0;
+-    }
+-    zPath += j + 1;
+-    j = 1;
+-    for(;;){
+-      while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
+-        if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
+-        j += jsonNodeSize(&pRoot[j]);
+-      }
+-      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
+-      iRoot += pRoot->u.iAppend;
+-      pRoot = &pParse->aNode[iRoot];
+-      j = 1;
+-    }
+-    if( j<=pRoot->n ){
+-      return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr);
+-    }
+-    if( i==0 && pApnd ){
+-      u32 iStart;
+-      JsonNode *pNode;
+-      iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
+-      pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
+-      if( pParse->oom ) return 0;
+-      if( pNode ){
+-        pRoot = &pParse->aNode[iRoot];
+-        pRoot->u.iAppend = iStart - iRoot;
+-        pRoot->jnFlags |= JNODE_APPEND;
+-      }
+-      return pNode;
+-    }
+-  }else{
+-    *pzErr = zPath;
+-  }
+-  return 0;
+-}
+-
+-/*
+-** Append content to pParse that will complete zPath.  Return a pointer
+-** to the inserted node, or return NULL if the append fails.
+-*/
+-static JsonNode *jsonLookupAppend(
+-  JsonParse *pParse,     /* Append content to the JSON parse */
+-  const char *zPath,     /* Description of content to append */
+-  int *pApnd,            /* Set this flag to 1 */
+-  const char **pzErr     /* Make this point to any syntax error */
+-){
+-  *pApnd = 1;
+-  if( zPath[0]==0 ){
+-    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+-    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
+-  }
+-  if( zPath[0]=='.' ){
+-    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
+-  }else if( strncmp(zPath,"[0]",3)==0 ){
+-    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
+-  }else{
+-    return 0;
+-  }
+-  if( pParse->oom ) return 0;
+-  return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr);
+-}
+-
+-/*
+-** Return the text of a syntax error message on a JSON path.  Space is
+-** obtained from sqlite3_malloc().
+-*/
+-static char *jsonPathSyntaxError(const char *zErr){
+-  return sqlite3_mprintf("JSON path error near '%q'", zErr);
+-}
+-
+-/*
+-** Do a node lookup using zPath.  Return a pointer to the node on success.
+-** Return NULL if not found or if there is an error.
+-**
+-** On an error, write an error message into pCtx and increment the
+-** pParse->nErr counter.
+-**
+-** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if
+-** nodes are appended.
+-*/
+-static JsonNode *jsonLookup(
+-  JsonParse *pParse,      /* The JSON to search */
+-  const char *zPath,      /* The path to search */
+-  int *pApnd,             /* Append nodes to complete path if not NULL */
+-  sqlite3_context *pCtx   /* Report errors here, if not NULL */
+-){
+-  const char *zErr = 0;
+-  JsonNode *pNode = 0;
+-  char *zMsg;
+-
+-  if( zPath==0 ) return 0;
+-  if( zPath[0]!='$' ){
+-    zErr = zPath;
+-    goto lookup_err;
+-  }
+-  zPath++;
+-  pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
+-  if( zErr==0 ) return pNode;
+-
+-lookup_err:
+-  pParse->nErr++;
+-  assert( zErr!=0 && pCtx!=0 );
+-  zMsg = jsonPathSyntaxError(zErr);
+-  if( zMsg ){
+-    sqlite3_result_error(pCtx, zMsg, -1);
+-    sqlite3_free(zMsg);
+-  }else{
+-    sqlite3_result_error_nomem(pCtx);
+-  }
+-  return 0;
+-}
+-
+-
+-/*
+-** Report the wrong number of arguments for json_insert(), json_replace()
+-** or json_set().
+-*/
+-static void jsonWrongNumArgs(
+-  sqlite3_context *pCtx,
+-  const char *zFuncName
+-){
+-  char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
+-                               zFuncName);
+-  sqlite3_result_error(pCtx, zMsg, -1);
+-  sqlite3_free(zMsg);     
+-}
+-
+-/*
+-** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
+-*/
+-static void jsonRemoveAllNulls(JsonNode *pNode){
+-  int i, n;
+-  assert( pNode->eType==JSON_OBJECT );
+-  n = pNode->n;
+-  for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
+-    switch( pNode[i].eType ){
+-      case JSON_NULL:
+-        pNode[i].jnFlags |= JNODE_REMOVE;
+-        break;
+-      case JSON_OBJECT:
+-        jsonRemoveAllNulls(&pNode[i]);
+-        break;
+-    }
+-  }
+-}
+-
+-
+-/****************************************************************************
+-** SQL functions used for testing and debugging
+-****************************************************************************/
+-
+-#ifdef SQLITE_DEBUG
+-/*
+-** The json_parse(JSON) function returns a string which describes
+-** a parse of the JSON provided.  Or it returns NULL if JSON is not
+-** well-formed.
+-*/
+-static void jsonParseFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString s;       /* Output string - not real JSON */
+-  JsonParse x;        /* The parse */
+-  u32 i;
+-
+-  assert( argc==1 );
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  jsonParseFindParents(&x);
+-  jsonInit(&s, ctx);
+-  for(i=0; i<x.nNode; i++){
+-    const char *zType;
+-    if( x.aNode[i].jnFlags & JNODE_LABEL ){
+-      assert( x.aNode[i].eType==JSON_STRING );
+-      zType = "label";
+-    }else{
+-      zType = jsonType[x.aNode[i].eType];
+-    }
+-    jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
+-               i, zType, x.aNode[i].n, x.aUp[i]);
+-    if( x.aNode[i].u.zJContent!=0 ){
+-      jsonAppendRaw(&s, " ", 1);
+-      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
+-    }
+-    jsonAppendRaw(&s, "\n", 1);
+-  }
+-  jsonParseReset(&x);
+-  jsonResult(&s);
+-}
+-
+-/*
+-** The json_test1(JSON) function return true (1) if the input is JSON
+-** text generated by another json function.  It returns (0) if the input
+-** is not known to be JSON.
+-*/
+-static void jsonTest1Func(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  UNUSED_PARAM(argc);
+-  sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE);
+-}
+-#endif /* SQLITE_DEBUG */
+-
+-/****************************************************************************
+-** Scalar SQL function implementations
+-****************************************************************************/
+-
+-/*
+-** Implementation of the json_QUOTE(VALUE) function.  Return a JSON value
+-** corresponding to the SQL value input.  Mostly this means putting 
+-** double-quotes around strings and returning the unquoted string "null"
+-** when given a NULL input.
+-*/
+-static void jsonQuoteFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString jx;
+-  UNUSED_PARAM(argc);
+-
+-  jsonInit(&jx, ctx);
+-  jsonAppendValue(&jx, argv[0]);
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** Implementation of the json_array(VALUE,...) function.  Return a JSON
+-** array that contains all values given in arguments.  Or if any argument
+-** is a BLOB, throw an error.
+-*/
+-static void jsonArrayFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  int i;
+-  JsonString jx;
+-
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '[');
+-  for(i=0; i<argc; i++){
+-    jsonAppendSeparator(&jx);
+-    jsonAppendValue(&jx, argv[i]);
+-  }
+-  jsonAppendChar(&jx, ']');
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-
+-/*
+-** json_array_length(JSON)
+-** json_array_length(JSON, PATH)
+-**
+-** Return the number of elements in the top-level JSON array.  
+-** Return 0 if the input is not a well-formed JSON array.
+-*/
+-static void jsonArrayLengthFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse *p;          /* The parse */
+-  sqlite3_int64 n = 0;
+-  u32 i;
+-  JsonNode *pNode;
+-
+-  p = jsonParseCached(ctx, argv);
+-  if( p==0 ) return;
+-  assert( p->nNode );
+-  if( argc==2 ){
+-    const char *zPath = (const char*)sqlite3_value_text(argv[1]);
+-    pNode = jsonLookup(p, zPath, 0, ctx);
+-  }else{
+-    pNode = p->aNode;
+-  }
+-  if( pNode==0 ){
+-    return;
+-  }
+-  if( pNode->eType==JSON_ARRAY ){
+-    assert( (pNode->jnFlags & JNODE_APPEND)==0 );
+-    for(i=1; i<=pNode->n; n++){
+-      i += jsonNodeSize(&pNode[i]);
+-    }
+-  }
+-  sqlite3_result_int64(ctx, n);
+-}
+-
+-/*
+-** json_extract(JSON, PATH, ...)
+-**
+-** Return the element described by PATH.  Return NULL if there is no
+-** PATH element.  If there are multiple PATHs, then return a JSON array
+-** with the result from each path.  Throw an error if the JSON or any PATH
+-** is malformed.
+-*/
+-static void jsonExtractFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse *p;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  JsonString jx;
+-  int i;
+-
+-  if( argc<2 ) return;
+-  p = jsonParseCached(ctx, argv);
+-  if( p==0 ) return;
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '[');
+-  for(i=1; i<argc; i++){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    pNode = jsonLookup(p, zPath, 0, ctx);
+-    if( p->nErr ) break;
+-    if( argc>2 ){
+-      jsonAppendSeparator(&jx);
+-      if( pNode ){
+-        jsonRenderNode(pNode, &jx, 0);
+-      }else{
+-        jsonAppendRaw(&jx, "null", 4);
+-      }
+-    }else if( pNode ){
+-      jsonReturn(pNode, ctx, 0);
+-    }
+-  }
+-  if( argc>2 && i==argc ){
+-    jsonAppendChar(&jx, ']');
+-    jsonResult(&jx);
+-    sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-  }
+-  jsonReset(&jx);
+-}
+-
+-/* This is the RFC 7396 MergePatch algorithm.
+-*/
+-static JsonNode *jsonMergePatch(
+-  JsonParse *pParse,   /* The JSON parser that contains the TARGET */
+-  u32 iTarget,         /* Node of the TARGET in pParse */
+-  JsonNode *pPatch     /* The PATCH */
+-){
+-  u32 i, j;
+-  u32 iRoot;
+-  JsonNode *pTarget;
+-  if( pPatch->eType!=JSON_OBJECT ){
+-    return pPatch;
+-  }
+-  assert( iTarget>=0 && iTarget<pParse->nNode );
+-  pTarget = &pParse->aNode[iTarget];
+-  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
+-  if( pTarget->eType!=JSON_OBJECT ){
+-    jsonRemoveAllNulls(pPatch);
+-    return pPatch;
+-  }
+-  iRoot = iTarget;
+-  for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
+-    u32 nKey;
+-    const char *zKey;
+-    assert( pPatch[i].eType==JSON_STRING );
+-    assert( pPatch[i].jnFlags & JNODE_LABEL );
+-    nKey = pPatch[i].n;
+-    zKey = pPatch[i].u.zJContent;
+-    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+-    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
+-      assert( pTarget[j].eType==JSON_STRING );
+-      assert( pTarget[j].jnFlags & JNODE_LABEL );
+-      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+-      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+-        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
+-        if( pPatch[i+1].eType==JSON_NULL ){
+-          pTarget[j+1].jnFlags |= JNODE_REMOVE;
+-        }else{
+-          JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
+-          if( pNew==0 ) return 0;
+-          pTarget = &pParse->aNode[iTarget];
+-          if( pNew!=&pTarget[j+1] ){
+-            pTarget[j+1].u.pPatch = pNew;
+-            pTarget[j+1].jnFlags |= JNODE_PATCH;
+-          }
+-        }
+-        break;
+-      }
+-    }
+-    if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
+-      int iStart, iPatch;
+-      iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+-      jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+-      iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+-      if( pParse->oom ) return 0;
+-      jsonRemoveAllNulls(pPatch);
+-      pTarget = &pParse->aNode[iTarget];
+-      pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
+-      pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
+-      iRoot = iStart;
+-      pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
+-      pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
+-    }
+-  }
+-  return pTarget;
+-}
+-
+-/*
+-** Implementation of the json_mergepatch(JSON1,JSON2) function.  Return a JSON
+-** object that is the result of running the RFC 7396 MergePatch() algorithm
+-** on the two arguments.
+-*/
+-static void jsonPatchFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;     /* The JSON that is being patched */
+-  JsonParse y;     /* The patch */
+-  JsonNode *pResult;   /* The result of the merge */
+-
+-  UNUSED_PARAM(argc);
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
+-    jsonParseReset(&x);
+-    return;
+-  }
+-  pResult = jsonMergePatch(&x, 0, y.aNode);
+-  assert( pResult!=0 || x.oom );
+-  if( pResult ){
+-    jsonReturnJson(pResult, ctx, 0);
+-  }else{
+-    sqlite3_result_error_nomem(ctx);
+-  }
+-  jsonParseReset(&x);
+-  jsonParseReset(&y);
+-}
+-
+-
+-/*
+-** Implementation of the json_object(NAME,VALUE,...) function.  Return a JSON
+-** object that contains all name/value given in arguments.  Or if any name
+-** is not a string or if any value is a BLOB, throw an error.
+-*/
+-static void jsonObjectFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  int i;
+-  JsonString jx;
+-  const char *z;
+-  u32 n;
+-
+-  if( argc&1 ){
+-    sqlite3_result_error(ctx, "json_object() requires an even number "
+-                                  "of arguments", -1);
+-    return;
+-  }
+-  jsonInit(&jx, ctx);
+-  jsonAppendChar(&jx, '{');
+-  for(i=0; i<argc; i+=2){
+-    if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
+-      sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
+-      jsonReset(&jx);
+-      return;
+-    }
+-    jsonAppendSeparator(&jx);
+-    z = (const char*)sqlite3_value_text(argv[i]);
+-    n = (u32)sqlite3_value_bytes(argv[i]);
+-    jsonAppendString(&jx, z, n);
+-    jsonAppendChar(&jx, ':');
+-    jsonAppendValue(&jx, argv[i+1]);
+-  }
+-  jsonAppendChar(&jx, '}');
+-  jsonResult(&jx);
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-
+-/*
+-** json_remove(JSON, PATH, ...)
+-**
+-** Remove the named elements from JSON and return the result.  malformed
+-** JSON or PATH arguments result in an error.
+-*/
+-static void jsonRemoveFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
+-
+-  if( argc<1 ) return;
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i++){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    if( zPath==0 ) goto remove_done;
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-    if( x.nErr ) goto remove_done;
+-    if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
+-  }
+-  if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
+-    jsonReturnJson(x.aNode, ctx, 0);
+-  }
+-remove_done:
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_replace(JSON, PATH, VALUE, ...)
+-**
+-** Replace the value at PATH with VALUE.  If PATH does not already exist,
+-** this routine is a no-op.  If JSON or PATH is malformed, throw an error.
+-*/
+-static void jsonReplaceFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
+-
+-  if( argc<1 ) return;
+-  if( (argc&1)==0 ) {
+-    jsonWrongNumArgs(ctx, "replace");
+-    return;
+-  }
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i+=2){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-    if( x.nErr ) goto replace_err;
+-    if( pNode ){
+-      pNode->jnFlags |= (u8)JNODE_REPLACE;
+-      pNode->u.iReplace = i + 1;
+-    }
+-  }
+-  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+-    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+-  }else{
+-    jsonReturnJson(x.aNode, ctx, argv);
+-  }
+-replace_err:
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_set(JSON, PATH, VALUE, ...)
+-**
+-** Set the value at PATH to VALUE.  Create the PATH if it does not already
+-** exist.  Overwrite existing values that do exist.
+-** If JSON or PATH is malformed, throw an error.
+-**
+-** json_insert(JSON, PATH, VALUE, ...)
+-**
+-** Create PATH and initialize it to VALUE.  If PATH already exists, this
+-** routine is a no-op.  If JSON or PATH is malformed, throw an error.
+-*/
+-static void jsonSetFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  JsonNode *pNode;
+-  const char *zPath;
+-  u32 i;
+-  int bApnd;
+-  int bIsSet = *(int*)sqlite3_user_data(ctx);
+-
+-  if( argc<1 ) return;
+-  if( (argc&1)==0 ) {
+-    jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
+-    return;
+-  }
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  for(i=1; i<(u32)argc; i+=2){
+-    zPath = (const char*)sqlite3_value_text(argv[i]);
+-    bApnd = 0;
+-    pNode = jsonLookup(&x, zPath, &bApnd, ctx);
+-    if( x.oom ){
+-      sqlite3_result_error_nomem(ctx);
+-      goto jsonSetDone;
+-    }else if( x.nErr ){
+-      goto jsonSetDone;
+-    }else if( pNode && (bApnd || bIsSet) ){
+-      pNode->jnFlags |= (u8)JNODE_REPLACE;
+-      pNode->u.iReplace = i + 1;
+-    }
+-  }
+-  if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+-    sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
+-  }else{
+-    jsonReturnJson(x.aNode, ctx, argv);
+-  }
+-jsonSetDone:
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_type(JSON)
+-** json_type(JSON, PATH)
+-**
+-** Return the top-level "type" of a JSON string.  Throw an error if
+-** either the JSON or PATH inputs are not well-formed.
+-*/
+-static void jsonTypeFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  const char *zPath;
+-  JsonNode *pNode;
+-
+-  if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+-  assert( x.nNode );
+-  if( argc==2 ){
+-    zPath = (const char*)sqlite3_value_text(argv[1]);
+-    pNode = jsonLookup(&x, zPath, 0, ctx);
+-  }else{
+-    pNode = x.aNode;
+-  }
+-  if( pNode ){
+-    sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
+-  }
+-  jsonParseReset(&x);
+-}
+-
+-/*
+-** json_valid(JSON)
+-**
+-** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
+-** Return 0 otherwise.
+-*/
+-static void jsonValidFunc(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonParse x;          /* The parse */
+-  int rc = 0;
+-
+-  UNUSED_PARAM(argc);
+-  if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
+-    rc = 1;
+-  }
+-  jsonParseReset(&x);
+-  sqlite3_result_int(ctx, rc);
+-}
+-
+-
+-/****************************************************************************
+-** Aggregate SQL function implementations
+-****************************************************************************/
+-/*
+-** json_group_array(VALUE)
+-**
+-** Return a JSON array composed of all values in the aggregate.
+-*/
+-static void jsonArrayStep(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString *pStr;
+-  UNUSED_PARAM(argc);
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+-  if( pStr ){
+-    if( pStr->zBuf==0 ){
+-      jsonInit(pStr, ctx);
+-      jsonAppendChar(pStr, '[');
+-    }else{
+-      jsonAppendChar(pStr, ',');
+-      pStr->pCtx = ctx;
+-    }
+-    jsonAppendValue(pStr, argv[0]);
+-  }
+-}
+-static void jsonArrayFinal(sqlite3_context *ctx){
+-  JsonString *pStr;
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+-  if( pStr ){
+-    pStr->pCtx = ctx;
+-    jsonAppendChar(pStr, ']');
+-    if( pStr->bErr ){
+-      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+-      assert( pStr->bStatic );
+-    }else{
+-      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+-                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+-      pStr->bStatic = 1;
+-    }
+-  }else{
+-    sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
+-  }
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-/*
+-** json_group_obj(NAME,VALUE)
+-**
+-** Return a JSON object composed of all names and values in the aggregate.
+-*/
+-static void jsonObjectStep(
+-  sqlite3_context *ctx,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  JsonString *pStr;
+-  const char *z;
+-  u32 n;
+-  UNUSED_PARAM(argc);
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
+-  if( pStr ){
+-    if( pStr->zBuf==0 ){
+-      jsonInit(pStr, ctx);
+-      jsonAppendChar(pStr, '{');
+-    }else{
+-      jsonAppendChar(pStr, ',');
+-      pStr->pCtx = ctx;
+-    }
+-    z = (const char*)sqlite3_value_text(argv[0]);
+-    n = (u32)sqlite3_value_bytes(argv[0]);
+-    jsonAppendString(pStr, z, n);
+-    jsonAppendChar(pStr, ':');
+-    jsonAppendValue(pStr, argv[1]);
+-  }
+-}
+-static void jsonObjectFinal(sqlite3_context *ctx){
+-  JsonString *pStr;
+-  pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
+-  if( pStr ){
+-    jsonAppendChar(pStr, '}');
+-    if( pStr->bErr ){
+-      if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
+-      assert( pStr->bStatic );
+-    }else{
+-      sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
+-                          pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free);
+-      pStr->bStatic = 1;
+-    }
+-  }else{
+-    sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
+-  }
+-  sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+-}
+-
+-
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-/****************************************************************************
+-** The json_each virtual table
+-****************************************************************************/
+-typedef struct JsonEachCursor JsonEachCursor;
+-struct JsonEachCursor {
+-  sqlite3_vtab_cursor base;  /* Base class - must be first */
+-  u32 iRowid;                /* The rowid */
+-  u32 iBegin;                /* The first node of the scan */
+-  u32 i;                     /* Index in sParse.aNode[] of current row */
+-  u32 iEnd;                  /* EOF when i equals or exceeds this value */
+-  u8 eType;                  /* Type of top-level element */
+-  u8 bRecursive;             /* True for json_tree().  False for json_each() */
+-  char *zJson;               /* Input JSON */
+-  char *zRoot;               /* Path by which to filter zJson */
+-  JsonParse sParse;          /* Parse of the input JSON */
+-};
+-
+-/* Constructor for the json_each virtual table */
+-static int jsonEachConnect(
+-  sqlite3 *db,
+-  void *pAux,
+-  int argc, const char *const*argv,
+-  sqlite3_vtab **ppVtab,
+-  char **pzErr
+-){
+-  sqlite3_vtab *pNew;
+-  int rc;
+-
+-/* Column numbers */
+-#define JEACH_KEY     0
+-#define JEACH_VALUE   1
+-#define JEACH_TYPE    2
+-#define JEACH_ATOM    3
+-#define JEACH_ID      4
+-#define JEACH_PARENT  5
+-#define JEACH_FULLKEY 6
+-#define JEACH_PATH    7
+-#define JEACH_JSON    8
+-#define JEACH_ROOT    9
+-
+-  UNUSED_PARAM(pzErr);
+-  UNUSED_PARAM(argv);
+-  UNUSED_PARAM(argc);
+-  UNUSED_PARAM(pAux);
+-  rc = sqlite3_declare_vtab(db, 
+-     "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
+-                    "json HIDDEN,root HIDDEN)");
+-  if( rc==SQLITE_OK ){
+-    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+-    if( pNew==0 ) return SQLITE_NOMEM;
+-    memset(pNew, 0, sizeof(*pNew));
+-  }
+   return rc;
+ }
+ 
+-/* destructor for json_each virtual table */
+-static int jsonEachDisconnect(sqlite3_vtab *pVtab){
+-  sqlite3_free(pVtab);
+-  return SQLITE_OK;
+-}
++#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
+ 
+-/* constructor for a JsonEachCursor object for json_each(). */
+-static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+-  JsonEachCursor *pCur;
+-
+-  UNUSED_PARAM(p);
+-  pCur = sqlite3_malloc( sizeof(*pCur) );
+-  if( pCur==0 ) return SQLITE_NOMEM;
+-  memset(pCur, 0, sizeof(*pCur));
+-  *ppCursor = &pCur->base;
+-  return SQLITE_OK;
+-}
+-
+-/* constructor for a JsonEachCursor object for json_tree(). */
+-static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+-  int rc = jsonEachOpenEach(p, ppCursor);
+-  if( rc==SQLITE_OK ){
+-    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
+-    pCur->bRecursive = 1;
+-  }
+-  return rc;
+-}
+-
+-/* Reset a JsonEachCursor back to its original state.  Free any memory
+-** held. */
+-static void jsonEachCursorReset(JsonEachCursor *p){
+-  sqlite3_free(p->zJson);
+-  sqlite3_free(p->zRoot);
+-  jsonParseReset(&p->sParse);
+-  p->iRowid = 0;
+-  p->i = 0;
+-  p->iEnd = 0;
+-  p->eType = 0;
+-  p->zJson = 0;
+-  p->zRoot = 0;
+-}
+-
+-/* Destructor for a jsonEachCursor object */
+-static int jsonEachClose(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  jsonEachCursorReset(p);
+-  sqlite3_free(cur);
+-  return SQLITE_OK;
+-}
+-
+-/* Return TRUE if the jsonEachCursor object has been advanced off the end
+-** of the JSON object */
+-static int jsonEachEof(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  return p->i >= p->iEnd;
+-}
+-
+-/* Advance the cursor to the next element for json_tree() */
+-static int jsonEachNext(sqlite3_vtab_cursor *cur){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  if( p->bRecursive ){
+-    if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++;
+-    p->i++;
+-    p->iRowid++;
+-    if( p->i<p->iEnd ){
+-      u32 iUp = p->sParse.aUp[p->i];
+-      JsonNode *pUp = &p->sParse.aNode[iUp];
+-      p->eType = pUp->eType;
+-      if( pUp->eType==JSON_ARRAY ){
+-        if( iUp==p->i-1 ){
+-          pUp->u.iKey = 0;
+-        }else{
+-          pUp->u.iKey++;
+-        }
+-      }
+-    }
+-  }else{
+-    switch( p->eType ){
+-      case JSON_ARRAY: {
+-        p->i += jsonNodeSize(&p->sParse.aNode[p->i]);
+-        p->iRowid++;
+-        break;
+-      }
+-      case JSON_OBJECT: {
+-        p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]);
+-        p->iRowid++;
+-        break;
+-      }
+-      default: {
+-        p->i = p->iEnd;
+-        break;
+-      }
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* Append the name of the path for element i to pStr
+-*/
+-static void jsonEachComputePath(
+-  JsonEachCursor *p,       /* The cursor */
+-  JsonString *pStr,        /* Write the path here */
+-  u32 i                    /* Path to this element */
+-){
+-  JsonNode *pNode, *pUp;
+-  u32 iUp;
+-  if( i==0 ){
+-    jsonAppendChar(pStr, '$');
+-    return;
+-  }
+-  iUp = p->sParse.aUp[i];
+-  jsonEachComputePath(p, pStr, iUp);
+-  pNode = &p->sParse.aNode[i];
+-  pUp = &p->sParse.aNode[iUp];
+-  if( pUp->eType==JSON_ARRAY ){
+-    jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
+-  }else{
+-    assert( pUp->eType==JSON_OBJECT );
+-    if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
+-    assert( pNode->eType==JSON_STRING );
+-    assert( pNode->jnFlags & JNODE_LABEL );
+-    jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
+-  }
+-}
+-
+-/* Return the value of a column */
+-static int jsonEachColumn(
+-  sqlite3_vtab_cursor *cur,   /* The cursor */
+-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
+-  int i                       /* Which column to return */
+-){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  JsonNode *pThis = &p->sParse.aNode[p->i];
+-  switch( i ){
+-    case JEACH_KEY: {
+-      if( p->i==0 ) break;
+-      if( p->eType==JSON_OBJECT ){
+-        jsonReturn(pThis, ctx, 0);
+-      }else if( p->eType==JSON_ARRAY ){
+-        u32 iKey;
+-        if( p->bRecursive ){
+-          if( p->iRowid==0 ) break;
+-          iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
+-        }else{
+-          iKey = p->iRowid;
+-        }
+-        sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
+-      }
+-      break;
+-    }
+-    case JEACH_VALUE: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      jsonReturn(pThis, ctx, 0);
+-      break;
+-    }
+-    case JEACH_TYPE: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
+-      break;
+-    }
+-    case JEACH_ATOM: {
+-      if( pThis->jnFlags & JNODE_LABEL ) pThis++;
+-      if( pThis->eType>=JSON_ARRAY ) break;
+-      jsonReturn(pThis, ctx, 0);
+-      break;
+-    }
+-    case JEACH_ID: {
+-      sqlite3_result_int64(ctx, 
+-         (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
+-      break;
+-    }
+-    case JEACH_PARENT: {
+-      if( p->i>p->iBegin && p->bRecursive ){
+-        sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]);
+-      }
+-      break;
+-    }
+-    case JEACH_FULLKEY: {
+-      JsonString x;
+-      jsonInit(&x, ctx);
+-      if( p->bRecursive ){
+-        jsonEachComputePath(p, &x, p->i);
+-      }else{
+-        if( p->zRoot ){
+-          jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot));
+-        }else{
+-          jsonAppendChar(&x, '$');
+-        }
+-        if( p->eType==JSON_ARRAY ){
+-          jsonPrintf(30, &x, "[%d]", p->iRowid);
+-        }else{
+-          jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
+-        }
+-      }
+-      jsonResult(&x);
+-      break;
+-    }
+-    case JEACH_PATH: {
+-      if( p->bRecursive ){
+-        JsonString x;
+-        jsonInit(&x, ctx);
+-        jsonEachComputePath(p, &x, p->sParse.aUp[p->i]);
+-        jsonResult(&x);
+-        break;
+-      }
+-      /* For json_each() path and root are the same so fall through
+-      ** into the root case */
+-    }
+-    default: {
+-      const char *zRoot = p->zRoot;
+-      if( zRoot==0 ) zRoot = "$";
+-      sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
+-      break;
+-    }
+-    case JEACH_JSON: {
+-      assert( i==JEACH_JSON );
+-      sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
+-      break;
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* Return the current rowid value */
+-static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  *pRowid = p->iRowid;
+-  return SQLITE_OK;
+-}
+-
+-/* The query strategy is to look for an equality constraint on the json
+-** column.  Without such a constraint, the table cannot operate.  idxNum is
+-** 1 if the constraint is found, 3 if the constraint and zRoot are found,
+-** and 0 otherwise.
+-*/
+-static int jsonEachBestIndex(
+-  sqlite3_vtab *tab,
+-  sqlite3_index_info *pIdxInfo
+-){
+-  int i;
+-  int jsonIdx = -1;
+-  int rootIdx = -1;
+-  const struct sqlite3_index_constraint *pConstraint;
+-
+-  UNUSED_PARAM(tab);
+-  pConstraint = pIdxInfo->aConstraint;
+-  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+-    if( pConstraint->usable==0 ) continue;
+-    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+-    switch( pConstraint->iColumn ){
+-      case JEACH_JSON:   jsonIdx = i;    break;
+-      case JEACH_ROOT:   rootIdx = i;    break;
+-      default:           /* no-op */     break;
+-    }
+-  }
+-  if( jsonIdx<0 ){
+-    pIdxInfo->idxNum = 0;
+-    pIdxInfo->estimatedCost = 1e99;
+-  }else{
+-    pIdxInfo->estimatedCost = 1.0;
+-    pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
+-    pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
+-    if( rootIdx<0 ){
+-      pIdxInfo->idxNum = 1;
+-    }else{
+-      pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
+-      pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
+-      pIdxInfo->idxNum = 3;
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* Start a search on a new JSON string */
+-static int jsonEachFilter(
+-  sqlite3_vtab_cursor *cur,
+-  int idxNum, const char *idxStr,
+-  int argc, sqlite3_value **argv
+-){
+-  JsonEachCursor *p = (JsonEachCursor*)cur;
+-  const char *z;
+-  const char *zRoot = 0;
+-  sqlite3_int64 n;
+-
+-  UNUSED_PARAM(idxStr);
+-  UNUSED_PARAM(argc);
+-  jsonEachCursorReset(p);
+-  if( idxNum==0 ) return SQLITE_OK;
+-  z = (const char*)sqlite3_value_text(argv[0]);
+-  if( z==0 ) return SQLITE_OK;
+-  n = sqlite3_value_bytes(argv[0]);
+-  p->zJson = sqlite3_malloc64( n+1 );
+-  if( p->zJson==0 ) return SQLITE_NOMEM;
+-  memcpy(p->zJson, z, (size_t)n+1);
+-  if( jsonParse(&p->sParse, 0, p->zJson) ){
+-    int rc = SQLITE_NOMEM;
+-    if( p->sParse.oom==0 ){
+-      sqlite3_free(cur->pVtab->zErrMsg);
+-      cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
+-      if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR;
+-    }
+-    jsonEachCursorReset(p);
+-    return rc;
+-  }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){
+-    jsonEachCursorReset(p);
+-    return SQLITE_NOMEM;
+-  }else{
+-    JsonNode *pNode = 0;
+-    if( idxNum==3 ){
+-      const char *zErr = 0;
+-      zRoot = (const char*)sqlite3_value_text(argv[1]);
+-      if( zRoot==0 ) return SQLITE_OK;
+-      n = sqlite3_value_bytes(argv[1]);
+-      p->zRoot = sqlite3_malloc64( n+1 );
+-      if( p->zRoot==0 ) return SQLITE_NOMEM;
+-      memcpy(p->zRoot, zRoot, (size_t)n+1);
+-      if( zRoot[0]!='$' ){
+-        zErr = zRoot;
+-      }else{
+-        pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
+-      }
+-      if( zErr ){
+-        sqlite3_free(cur->pVtab->zErrMsg);
+-        cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
+-        jsonEachCursorReset(p);
+-        return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+-      }else if( pNode==0 ){
+-        return SQLITE_OK;
+-      }
+-    }else{
+-      pNode = p->sParse.aNode;
+-    }
+-    p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
+-    p->eType = pNode->eType;
+-    if( p->eType>=JSON_ARRAY ){
+-      pNode->u.iKey = 0;
+-      p->iEnd = p->i + pNode->n + 1;
+-      if( p->bRecursive ){
+-        p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
+-        if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
+-          p->i--;
+-        }
+-      }else{
+-        p->i++;
+-      }
+-    }else{
+-      p->iEnd = p->i+1;
+-    }
+-  }
+-  return SQLITE_OK;
+-}
+-
+-/* The methods of the json_each virtual table */
+-static sqlite3_module jsonEachModule = {
+-  0,                         /* iVersion */
+-  0,                         /* xCreate */
+-  jsonEachConnect,           /* xConnect */
+-  jsonEachBestIndex,         /* xBestIndex */
+-  jsonEachDisconnect,        /* xDisconnect */
+-  0,                         /* xDestroy */
+-  jsonEachOpenEach,          /* xOpen - open a cursor */
+-  jsonEachClose,             /* xClose - close a cursor */
+-  jsonEachFilter,            /* xFilter - configure scan constraints */
+-  jsonEachNext,              /* xNext - advance a cursor */
+-  jsonEachEof,               /* xEof - check for end of scan */
+-  jsonEachColumn,            /* xColumn - read data */
+-  jsonEachRowid,             /* xRowid - read data */
+-  0,                         /* xUpdate */
+-  0,                         /* xBegin */
+-  0,                         /* xSync */
+-  0,                         /* xCommit */
+-  0,                         /* xRollback */
+-  0,                         /* xFindMethod */
+-  0,                         /* xRename */
+-  0,                         /* xSavepoint */
+-  0,                         /* xRelease */
+-  0                          /* xRollbackTo */
+-};
+-
+-/* The methods of the json_tree virtual table. */
+-static sqlite3_module jsonTreeModule = {
+-  0,                         /* iVersion */
+-  0,                         /* xCreate */
+-  jsonEachConnect,           /* xConnect */
+-  jsonEachBestIndex,         /* xBestIndex */
+-  jsonEachDisconnect,        /* xDisconnect */
+-  0,                         /* xDestroy */
+-  jsonEachOpenTree,          /* xOpen - open a cursor */
+-  jsonEachClose,             /* xClose - close a cursor */
+-  jsonEachFilter,            /* xFilter - configure scan constraints */
+-  jsonEachNext,              /* xNext - advance a cursor */
+-  jsonEachEof,               /* xEof - check for end of scan */
+-  jsonEachColumn,            /* xColumn - read data */
+-  jsonEachRowid,             /* xRowid - read data */
+-  0,                         /* xUpdate */
+-  0,                         /* xBegin */
+-  0,                         /* xSync */
+-  0,                         /* xCommit */
+-  0,                         /* xRollback */
+-  0,                         /* xFindMethod */
+-  0,                         /* xRename */
+-  0,                         /* xSavepoint */
+-  0,                         /* xRelease */
+-  0                          /* xRollbackTo */
+-};
+-#endif /* SQLITE_OMIT_VIRTUALTABLE */
+-
+-/****************************************************************************
+-** The following routines are the only publically visible identifiers in this
+-** file.  Call the following routines in order to register the various SQL
+-** functions and the virtual table implemented by this file.
+-****************************************************************************/
+-
+-SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
+-  int rc = SQLITE_OK;
+-  unsigned int i;
+-  static const struct {
+-     const char *zName;
+-     int nArg;
+-     int flag;
+-     void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+-  } aFunc[] = {
+-    { "json",                 1, 0,   jsonRemoveFunc        },
+-    { "json_array",          -1, 0,   jsonArrayFunc         },
+-    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
+-    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
+-    { "json_extract",        -1, 0,   jsonExtractFunc       },
+-    { "json_insert",         -1, 0,   jsonSetFunc           },
+-    { "json_object",         -1, 0,   jsonObjectFunc        },
+-    { "json_patch",           2, 0,   jsonPatchFunc         },
+-    { "json_quote",           1, 0,   jsonQuoteFunc         },
+-    { "json_remove",         -1, 0,   jsonRemoveFunc        },
+-    { "json_replace",        -1, 0,   jsonReplaceFunc       },
+-    { "json_set",            -1, 1,   jsonSetFunc           },
+-    { "json_type",            1, 0,   jsonTypeFunc          },
+-    { "json_type",            2, 0,   jsonTypeFunc          },
+-    { "json_valid",           1, 0,   jsonValidFunc         },
+-
+-#if SQLITE_DEBUG
+-    /* DEBUG and TESTING functions */
+-    { "json_parse",           1, 0,   jsonParseFunc         },
+-    { "json_test1",           1, 0,   jsonTest1Func         },
+-#endif
+-  };
+-  static const struct {
+-     const char *zName;
+-     int nArg;
+-     void (*xStep)(sqlite3_context*,int,sqlite3_value**);
+-     void (*xFinal)(sqlite3_context*);
+-  } aAgg[] = {
+-    { "json_group_array",     1,   jsonArrayStep,   jsonArrayFinal  },
+-    { "json_group_object",    2,   jsonObjectStep,  jsonObjectFinal },
+-  };
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  static const struct {
+-     const char *zName;
+-     sqlite3_module *pModule;
+-  } aMod[] = {
+-    { "json_each",            &jsonEachModule               },
+-    { "json_tree",            &jsonTreeModule               },
+-  };
+-#endif
+-  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
+-                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
+-                                 (void*)&aFunc[i].flag,
+-                                 aFunc[i].xFunc, 0, 0);
+-  }
+-  for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_function(db, aAgg[i].zName, aAgg[i].nArg,
+-                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+-                                 0, aAgg[i].xStep, aAgg[i].xFinal);
+-  }
+-#ifndef SQLITE_OMIT_VIRTUALTABLE
+-  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
+-    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
+-  }
+-#endif
+-  return rc;
+-}
+-
+-
+-#ifndef SQLITE_CORE
+-#ifdef _WIN32
+-__declspec(dllexport)
+-#endif
+-SQLITE_API int sqlite3_json_init(
+-  sqlite3 *db, 
+-  char **pzErrMsg, 
+-  const sqlite3_api_routines *pApi
+-){
+-  SQLITE_EXTENSION_INIT2(pApi);
+-  (void)pzErrMsg;  /* Unused parameter */
+-  return sqlite3Json1Init(db);
+-}
+-#endif
+-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */
+-
+-/************** End of json1.c ***********************************************/
++/************** End of sqlite3session.c **************************************/
+ /************** Begin file fts5.c ********************************************/
+ 
+ 
+@@ -188729,7 +198794,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -188757,7 +198822,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+@@ -189649,9 +199714,12 @@
+ /**************************************************************************
+ ** Interface to automatically generated code in fts5_unicode2.c. 
+ */
+-static int sqlite3Fts5UnicodeIsalnum(int c);
+ static int sqlite3Fts5UnicodeIsdiacritic(int c);
+ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
++
++static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
++static int sqlite3Fts5UnicodeCategory(int iCode);
++static void sqlite3Fts5UnicodeAscii(u8*, u8*);
+ /*
+ ** End of interface to code in fts5_unicode2.c.
+ **************************************************************************/
+@@ -189699,6 +199767,7 @@
+ ** input grammar file:
+ */
+ /* #include <stdio.h> */
++/* #include <assert.h> */
+ /************ Begin %include sections from the grammar ************************/
+ 
+ /* #include "fts5Int.h" */
+@@ -189767,8 +199836,10 @@
+ **                       zero the stack is dynamically sized using realloc()
+ **    sqlite3Fts5ParserARG_SDECL     A static variable declaration for the %extra_argument
+ **    sqlite3Fts5ParserARG_PDECL     A parameter declaration for the %extra_argument
++**    sqlite3Fts5ParserARG_PARAM     Code to pass %extra_argument as a subroutine parameter
+ **    sqlite3Fts5ParserARG_STORE     Code to store %extra_argument into fts5yypParser
+ **    sqlite3Fts5ParserARG_FETCH     Code to extract %extra_argument from fts5yypParser
++**    sqlite3Fts5ParserCTX_*         As sqlite3Fts5ParserARG_ except for %extra_context
+ **    fts5YYERRORSYMBOL      is the code number of the error symbol.  If not
+ **                       defined, then do no error processing.
+ **    fts5YYNSTATE           the combined number of states.
+@@ -189788,7 +199859,7 @@
+ #endif
+ /************* Begin control #defines *****************************************/
+ #define fts5YYCODETYPE unsigned char
+-#define fts5YYNOCODE 29
++#define fts5YYNOCODE 27
+ #define fts5YYACTIONTYPE unsigned char
+ #define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
+ typedef union {
+@@ -189795,10 +199866,10 @@
+   int fts5yyinit;
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
+   int fts5yy4;
+-  Fts5ExprPhrase* fts5yy11;
+-  Fts5ExprNearset* fts5yy14;
+-  Fts5Colset* fts5yy43;
+-  Fts5ExprNode* fts5yy54;
++  Fts5Colset* fts5yy11;
++  Fts5ExprNode* fts5yy24;
++  Fts5ExprNearset* fts5yy46;
++  Fts5ExprPhrase* fts5yy53;
+ } fts5YYMINORTYPE;
+ #ifndef fts5YYSTACKDEPTH
+ #define fts5YYSTACKDEPTH 100
+@@ -189805,8 +199876,14 @@
+ #endif
+ #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
+ #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
+-#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
+-#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
++#define sqlite3Fts5ParserARG_PARAM ,pParse
++#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
++#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
++#define sqlite3Fts5ParserCTX_SDECL
++#define sqlite3Fts5ParserCTX_PDECL
++#define sqlite3Fts5ParserCTX_PARAM
++#define sqlite3Fts5ParserCTX_FETCH
++#define sqlite3Fts5ParserCTX_STORE
+ #define fts5YYNSTATE             35
+ #define fts5YYNRULE              28
+ #define fts5YYNFTS5TOKEN             16
+@@ -189819,6 +199896,7 @@
+ #define fts5YY_MIN_REDUCE        83
+ #define fts5YY_MAX_REDUCE        110
+ /************* End control #defines *******************************************/
++#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
+ 
+ /* Define the fts5yytestcase() macro to be a no-op if is not already defined
+ ** otherwise.
+@@ -189887,46 +199965,46 @@
+ static const fts5YYACTIONTYPE fts5yy_action[] = {
+  /*     0 */    81,   20,   96,    6,   28,   99,   98,   26,   26,   18,
+  /*    10 */    96,    6,   28,   17,   98,   56,   26,   19,   96,    6,
+- /*    20 */    28,   14,   98,  108,   26,   92,   96,    6,   28,   25,
+- /*    30 */    98,   78,   26,   21,   96,    6,   28,  107,   98,   58,
+- /*    40 */    26,   29,   96,    6,   28,   32,   98,   22,   26,   24,
+- /*    50 */    16,   23,   11,    1,   14,   13,   24,   16,   31,   11,
+- /*    60 */     3,   97,   13,   27,    8,   98,   82,   26,    7,    4,
+- /*    70 */     5,    3,    4,    5,    3,   83,    4,    5,    3,   63,
+- /*    80 */    33,   34,   62,   12,    2,   86,   13,   10,   12,   71,
+- /*    90 */    10,   13,   78,    5,    3,   78,    9,   30,   75,   82,
+- /*   100 */    54,   57,   53,   57,   15,
++ /*    20 */    28,   14,   98,   14,   26,   31,   92,   96,    6,   28,
++ /*    30 */   108,   98,   25,   26,   21,   96,    6,   28,   78,   98,
++ /*    40 */    58,   26,   29,   96,    6,   28,  107,   98,   22,   26,
++ /*    50 */    24,   16,   12,   11,    1,   13,   13,   24,   16,   23,
++ /*    60 */    11,   33,   34,   13,   97,    8,   27,   32,   98,    7,
++ /*    70 */    26,    3,    4,    5,    3,    4,    5,    3,   83,    4,
++ /*    80 */     5,    3,   63,    5,    3,   62,   12,    2,   86,   13,
++ /*    90 */     9,   30,   10,   10,   54,   57,   75,   78,   78,   53,
++ /*   100 */    57,   15,   82,   82,   71,
+ };
+ static const fts5YYCODETYPE fts5yy_lookahead[] = {
+- /*     0 */    17,   18,   19,   20,   21,   23,   23,   25,   25,   18,
+- /*    10 */    19,   20,   21,    7,   23,    9,   25,   18,   19,   20,
+- /*    20 */    21,    9,   23,   27,   25,   18,   19,   20,   21,   25,
+- /*    30 */    23,   15,   25,   18,   19,   20,   21,   27,   23,    9,
+- /*    40 */    25,   18,   19,   20,   21,   14,   23,   22,   25,    6,
+- /*    50 */     7,   22,    9,   10,    9,   12,    6,    7,   13,    9,
+- /*    60 */     3,   19,   12,   21,    5,   23,   28,   25,    5,    1,
+- /*    70 */     2,    3,    1,    2,    3,    0,    1,    2,    3,   11,
+- /*    80 */    25,   26,   11,    9,   10,    5,   12,   10,    9,   11,
+- /*    90 */    10,   12,   15,    2,    3,   15,   24,   25,    9,   28,
+- /*   100 */     8,    9,    8,    9,    9,   28,   28,   28,   28,   28,
+- /*   110 */    28,   28,   28,   28,   28,   28,   28,   28,   28,   28,
+- /*   120 */    28,
++ /*     0 */    16,   17,   18,   19,   20,   22,   22,   24,   24,   17,
++ /*    10 */    18,   19,   20,    7,   22,    9,   24,   17,   18,   19,
++ /*    20 */    20,    9,   22,    9,   24,   13,   17,   18,   19,   20,
++ /*    30 */    26,   22,   24,   24,   17,   18,   19,   20,   15,   22,
++ /*    40 */     9,   24,   17,   18,   19,   20,   26,   22,   21,   24,
++ /*    50 */     6,    7,    9,    9,   10,   12,   12,    6,    7,   21,
++ /*    60 */     9,   24,   25,   12,   18,    5,   20,   14,   22,    5,
++ /*    70 */    24,    3,    1,    2,    3,    1,    2,    3,    0,    1,
++ /*    80 */     2,    3,   11,    2,    3,   11,    9,   10,    5,   12,
++ /*    90 */    23,   24,   10,   10,    8,    9,    9,   15,   15,    8,
++ /*   100 */     9,    9,   27,   27,   11,   27,   27,   27,   27,   27,
++ /*   110 */    27,   27,   27,   27,   27,   27,   27,   27,   27,   27,
++ /*   120 */    27,
+ };
+ #define fts5YY_SHIFT_COUNT    (34)
+ #define fts5YY_SHIFT_MIN      (0)
+-#define fts5YY_SHIFT_MAX      (95)
++#define fts5YY_SHIFT_MAX      (93)
+ static const unsigned char fts5yy_shift_ofst[] = {
+- /*     0 */    43,   43,   43,   43,   43,   43,   50,   74,   79,   45,
+- /*    10 */    12,   80,   77,   12,   16,   16,   30,   30,   68,   71,
+- /*    20 */    75,   91,   92,   94,    6,   31,   31,   59,   63,   57,
+- /*    30 */    31,   89,   95,   31,   78,
++ /*     0 */    44,   44,   44,   44,   44,   44,   51,   77,   43,   12,
++ /*    10 */    14,   83,   82,   14,   23,   23,   31,   31,   71,   74,
++ /*    20 */    78,   81,   86,   91,    6,   53,   53,   60,   64,   68,
++ /*    30 */    53,   87,   92,   53,   93,
+ };
+ #define fts5YY_REDUCE_COUNT (17)
+-#define fts5YY_REDUCE_MIN   (-18)
+-#define fts5YY_REDUCE_MAX   (72)
++#define fts5YY_REDUCE_MIN   (-17)
++#define fts5YY_REDUCE_MAX   (67)
+ static const signed char fts5yy_reduce_ofst[] = {
+- /*     0 */   -17,   -9,   -1,    7,   15,   23,   42,  -18,  -18,   55,
+- /*    10 */    72,   -4,   -4,    4,   -4,   10,   25,   29,
++ /*     0 */   -16,   -8,    0,    9,   17,   25,   46,  -17,  -17,   37,
++ /*    10 */    67,    4,    4,    8,    4,   20,   27,   38,
+ };
+ static const fts5YYACTIONTYPE fts5yy_default[] = {
+  /*     0 */    80,   80,   80,   80,   80,   80,   95,   80,   80,  105,
+@@ -189991,6 +200069,7 @@
+   int fts5yyerrcnt;                 /* Shifts left before out of the error */
+ #endif
+   sqlite3Fts5ParserARG_SDECL                /* A place to hold %extra_argument */
++  sqlite3Fts5ParserCTX_SDECL                /* A place to hold %extra_context */
+ #if fts5YYSTACKDEPTH<=0
+   int fts5yystksz;                  /* Current side of the stack */
+   fts5yyStackEntry *fts5yystack;        /* The parser's stack */
+@@ -190054,18 +200133,17 @@
+   /*   13 */ "COMMA",
+   /*   14 */ "PLUS",
+   /*   15 */ "STAR",
+-  /*   16 */ "error",
+-  /*   17 */ "input",
+-  /*   18 */ "expr",
+-  /*   19 */ "cnearset",
+-  /*   20 */ "exprlist",
+-  /*   21 */ "colset",
+-  /*   22 */ "colsetlist",
+-  /*   23 */ "nearset",
+-  /*   24 */ "nearphrases",
+-  /*   25 */ "phrase",
+-  /*   26 */ "neardist_opt",
+-  /*   27 */ "star_opt",
++  /*   16 */ "input",
++  /*   17 */ "expr",
++  /*   18 */ "cnearset",
++  /*   19 */ "exprlist",
++  /*   20 */ "colset",
++  /*   21 */ "colsetlist",
++  /*   22 */ "nearset",
++  /*   23 */ "nearphrases",
++  /*   24 */ "phrase",
++  /*   25 */ "neardist_opt",
++  /*   26 */ "star_opt",
+ };
+ #endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
+ 
+@@ -190149,28 +200227,29 @@
+ 
+ /* Initialize a new parser that has already been allocated.
+ */
+-static void sqlite3Fts5ParserInit(void *fts5yypParser){
+-  fts5yyParser *pParser = (fts5yyParser*)fts5yypParser;
++static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){
++  fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser;
++  sqlite3Fts5ParserCTX_STORE
+ #ifdef fts5YYTRACKMAXSTACKDEPTH
+-  pParser->fts5yyhwm = 0;
++  fts5yypParser->fts5yyhwm = 0;
+ #endif
+ #if fts5YYSTACKDEPTH<=0
+-  pParser->fts5yytos = NULL;
+-  pParser->fts5yystack = NULL;
+-  pParser->fts5yystksz = 0;
+-  if( fts5yyGrowStack(pParser) ){
+-    pParser->fts5yystack = &pParser->fts5yystk0;
+-    pParser->fts5yystksz = 1;
++  fts5yypParser->fts5yytos = NULL;
++  fts5yypParser->fts5yystack = NULL;
++  fts5yypParser->fts5yystksz = 0;
++  if( fts5yyGrowStack(fts5yypParser) ){
++    fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0;
++    fts5yypParser->fts5yystksz = 1;
+   }
+ #endif
+ #ifndef fts5YYNOERRORRECOVERY
+-  pParser->fts5yyerrcnt = -1;
++  fts5yypParser->fts5yyerrcnt = -1;
+ #endif
+-  pParser->fts5yytos = pParser->fts5yystack;
+-  pParser->fts5yystack[0].stateno = 0;
+-  pParser->fts5yystack[0].major = 0;
++  fts5yypParser->fts5yytos = fts5yypParser->fts5yystack;
++  fts5yypParser->fts5yystack[0].stateno = 0;
++  fts5yypParser->fts5yystack[0].major = 0;
+ #if fts5YYSTACKDEPTH>0
+-  pParser->fts5yystackEnd = &pParser->fts5yystack[fts5YYSTACKDEPTH-1];
++  fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
+ #endif
+ }
+ 
+@@ -190187,11 +200266,14 @@
+ ** A pointer to a parser.  This pointer is used in subsequent calls
+ ** to sqlite3Fts5Parser and sqlite3Fts5ParserFree.
+ */
+-static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
+-  fts5yyParser *pParser;
+-  pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
+-  if( pParser ) sqlite3Fts5ParserInit(pParser);
+-  return pParser;
++static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){
++  fts5yyParser *fts5yypParser;
++  fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
++  if( fts5yypParser ){
++    sqlite3Fts5ParserCTX_STORE
++    sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM);
++  }
++  return (void*)fts5yypParser;
+ }
+ #endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
+ 
+@@ -190208,7 +200290,8 @@
+   fts5YYCODETYPE fts5yymajor,     /* Type code for object to destroy */
+   fts5YYMINORTYPE *fts5yypminor   /* The object to be destroyed */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+   switch( fts5yymajor ){
+     /* Here is inserted the actions which take place when a
+     ** terminal or non-terminal is destroyed.  This can happen
+@@ -190221,33 +200304,33 @@
+     ** inside the C code.
+     */
+ /********* Begin destructor definitions ***************************************/
+-    case 17: /* input */
++    case 16: /* input */
+ {
+  (void)pParse; 
+ }
+       break;
+-    case 18: /* expr */
+-    case 19: /* cnearset */
+-    case 20: /* exprlist */
++    case 17: /* expr */
++    case 18: /* cnearset */
++    case 19: /* exprlist */
+ {
+- sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy54)); 
++ sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); 
+ }
+       break;
+-    case 21: /* colset */
+-    case 22: /* colsetlist */
++    case 20: /* colset */
++    case 21: /* colsetlist */
+ {
+- sqlite3_free((fts5yypminor->fts5yy43)); 
++ sqlite3_free((fts5yypminor->fts5yy11)); 
+ }
+       break;
+-    case 23: /* nearset */
+-    case 24: /* nearphrases */
++    case 22: /* nearset */
++    case 23: /* nearphrases */
+ {
+- sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy14)); 
++ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); 
+ }
+       break;
+-    case 25: /* phrase */
++    case 24: /* phrase */
+ {
+- sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy11)); 
++ sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); 
+ }
+       break;
+ /********* End destructor definitions *****************************************/
+@@ -190359,13 +200442,12 @@
+ ** Find the appropriate action for a parser given the terminal
+ ** look-ahead token iLookAhead.
+ */
+-static unsigned int fts5yy_find_shift_action(
+-  fts5yyParser *pParser,        /* The parser */
+-  fts5YYCODETYPE iLookAhead     /* The look-ahead token */
++static fts5YYACTIONTYPE fts5yy_find_shift_action(
++  fts5YYCODETYPE iLookAhead,    /* The look-ahead token */
++  fts5YYACTIONTYPE stateno      /* Current state number */
+ ){
+   int i;
+-  int stateno = pParser->fts5yytos->stateno;
+- 
++
+   if( stateno>fts5YY_MAX_SHIFT ) return stateno;
+   assert( stateno <= fts5YY_SHIFT_COUNT );
+ #if defined(fts5YYCOVERAGE)
+@@ -190374,11 +200456,11 @@
+   do{
+     i = fts5yy_shift_ofst[stateno];
+     assert( i>=0 );
+-    assert( i+fts5YYNFTS5TOKEN<=(int)sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]) );
++    /* assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD ); */
+     assert( iLookAhead!=fts5YYNOCODE );
+     assert( iLookAhead < fts5YYNFTS5TOKEN );
+     i += iLookAhead;
+-    if( fts5yy_lookahead[i]!=iLookAhead ){
++    if( i>=fts5YY_NLOOKAHEAD || fts5yy_lookahead[i]!=iLookAhead ){
+ #ifdef fts5YYFALLBACK
+       fts5YYCODETYPE iFallback;            /* Fallback token */
+       if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
+@@ -190404,6 +200486,7 @@
+ #if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
+           j<fts5YY_ACTTAB_COUNT &&
+ #endif
++          j<(int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])) &&
+           fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
+         ){
+ #ifndef NDEBUG
+@@ -190428,8 +200511,8 @@
+ ** Find the appropriate action for a parser given the non-terminal
+ ** look-ahead token iLookAhead.
+ */
+-static int fts5yy_find_reduce_action(
+-  int stateno,              /* Current state number */
++static fts5YYACTIONTYPE fts5yy_find_reduce_action(
++  fts5YYACTIONTYPE stateno,     /* Current state number */
+   fts5YYCODETYPE iLookAhead     /* The look-ahead token */
+ ){
+   int i;
+@@ -190458,7 +200541,8 @@
+ ** The following routine is called if the stack overflows.
+ */
+ static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
+-   sqlite3Fts5ParserARG_FETCH;
++   sqlite3Fts5ParserARG_FETCH
++   sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+    if( fts5yyTraceFILE ){
+      fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
+@@ -190471,7 +200555,8 @@
+ 
+   sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
+ /******** End %stack_overflow code ********************************************/
+-   sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
++   sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument var */
++   sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /*
+@@ -190500,8 +200585,8 @@
+ */
+ static void fts5yy_shift(
+   fts5yyParser *fts5yypParser,          /* The parser to be shifted */
+-  int fts5yyNewState,               /* The new state to shift in */
+-  int fts5yyMajor,                  /* The major token to shift in */
++  fts5YYACTIONTYPE fts5yyNewState,      /* The new state to shift in */
++  fts5YYCODETYPE fts5yyMajor,           /* The major token to shift in */
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yyMinor        /* The minor token to shift in */
+ ){
+   fts5yyStackEntry *fts5yytos;
+@@ -190531,8 +200616,8 @@
+     fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
+   }
+   fts5yytos = fts5yypParser->fts5yytos;
+-  fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
+-  fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
++  fts5yytos->stateno = fts5yyNewState;
++  fts5yytos->major = fts5yyMajor;
+   fts5yytos->minor.fts5yy0 = fts5yyMinor;
+   fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
+ }
+@@ -190544,34 +200629,34 @@
+   fts5YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
+   signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
+ } fts5yyRuleInfo[] = {
+-  {   17,   -1 }, /* (0) input ::= expr */
+-  {   21,   -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
+-  {   21,   -3 }, /* (2) colset ::= LCP colsetlist RCP */
+-  {   21,   -1 }, /* (3) colset ::= STRING */
+-  {   21,   -2 }, /* (4) colset ::= MINUS STRING */
+-  {   22,   -2 }, /* (5) colsetlist ::= colsetlist STRING */
+-  {   22,   -1 }, /* (6) colsetlist ::= STRING */
+-  {   18,   -3 }, /* (7) expr ::= expr AND expr */
+-  {   18,   -3 }, /* (8) expr ::= expr OR expr */
+-  {   18,   -3 }, /* (9) expr ::= expr NOT expr */
+-  {   18,   -5 }, /* (10) expr ::= colset COLON LP expr RP */
+-  {   18,   -3 }, /* (11) expr ::= LP expr RP */
+-  {   18,   -1 }, /* (12) expr ::= exprlist */
+-  {   20,   -1 }, /* (13) exprlist ::= cnearset */
+-  {   20,   -2 }, /* (14) exprlist ::= exprlist cnearset */
+-  {   19,   -1 }, /* (15) cnearset ::= nearset */
+-  {   19,   -3 }, /* (16) cnearset ::= colset COLON nearset */
+-  {   23,   -1 }, /* (17) nearset ::= phrase */
+-  {   23,   -2 }, /* (18) nearset ::= CARET phrase */
+-  {   23,   -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+-  {   24,   -1 }, /* (20) nearphrases ::= phrase */
+-  {   24,   -2 }, /* (21) nearphrases ::= nearphrases phrase */
+-  {   26,    0 }, /* (22) neardist_opt ::= */
+-  {   26,   -2 }, /* (23) neardist_opt ::= COMMA STRING */
+-  {   25,   -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
+-  {   25,   -2 }, /* (25) phrase ::= STRING star_opt */
+-  {   27,   -1 }, /* (26) star_opt ::= STAR */
+-  {   27,    0 }, /* (27) star_opt ::= */
++  {   16,   -1 }, /* (0) input ::= expr */
++  {   20,   -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
++  {   20,   -3 }, /* (2) colset ::= LCP colsetlist RCP */
++  {   20,   -1 }, /* (3) colset ::= STRING */
++  {   20,   -2 }, /* (4) colset ::= MINUS STRING */
++  {   21,   -2 }, /* (5) colsetlist ::= colsetlist STRING */
++  {   21,   -1 }, /* (6) colsetlist ::= STRING */
++  {   17,   -3 }, /* (7) expr ::= expr AND expr */
++  {   17,   -3 }, /* (8) expr ::= expr OR expr */
++  {   17,   -3 }, /* (9) expr ::= expr NOT expr */
++  {   17,   -5 }, /* (10) expr ::= colset COLON LP expr RP */
++  {   17,   -3 }, /* (11) expr ::= LP expr RP */
++  {   17,   -1 }, /* (12) expr ::= exprlist */
++  {   19,   -1 }, /* (13) exprlist ::= cnearset */
++  {   19,   -2 }, /* (14) exprlist ::= exprlist cnearset */
++  {   18,   -1 }, /* (15) cnearset ::= nearset */
++  {   18,   -3 }, /* (16) cnearset ::= colset COLON nearset */
++  {   22,   -1 }, /* (17) nearset ::= phrase */
++  {   22,   -2 }, /* (18) nearset ::= CARET phrase */
++  {   22,   -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
++  {   23,   -1 }, /* (20) nearphrases ::= phrase */
++  {   23,   -2 }, /* (21) nearphrases ::= nearphrases phrase */
++  {   25,    0 }, /* (22) neardist_opt ::= */
++  {   25,   -2 }, /* (23) neardist_opt ::= COMMA STRING */
++  {   24,   -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
++  {   24,   -2 }, /* (25) phrase ::= STRING star_opt */
++  {   26,   -1 }, /* (26) star_opt ::= STAR */
++  {   26,    0 }, /* (27) star_opt ::= */
+ };
+ 
+ static void fts5yy_accept(fts5yyParser*);  /* Forward Declaration */
+@@ -190586,17 +200671,18 @@
+ ** only called from one place, optimizing compilers will in-line it, which
+ ** means that the extra parameters have no performance impact.
+ */
+-static void fts5yy_reduce(
++static fts5YYACTIONTYPE fts5yy_reduce(
+   fts5yyParser *fts5yypParser,         /* The parser */
+   unsigned int fts5yyruleno,       /* Number of the rule by which to reduce */
+   int fts5yyLookahead,             /* Lookahead token, or fts5YYNOCODE if none */
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken  /* Value of the lookahead token */
++  sqlite3Fts5ParserCTX_PDECL                   /* %extra_context */
+ ){
+   int fts5yygoto;                     /* The next state */
+-  int fts5yyact;                      /* The next action */
++  fts5YYACTIONTYPE fts5yyact;             /* The next action */
+   fts5yyStackEntry *fts5yymsp;            /* The top of the parser's stack */
+   int fts5yysize;                     /* Amount to pop the stack */
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
+   (void)fts5yyLookahead;
+   (void)fts5yyLookaheadToken;
+   fts5yymsp = fts5yypParser->fts5yytos;
+@@ -190627,13 +200713,19 @@
+ #if fts5YYSTACKDEPTH>0 
+     if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){
+       fts5yyStackOverflow(fts5yypParser);
+-      return;
++      /* The call to fts5yyStackOverflow() above pops the stack until it is
++      ** empty, causing the main parser loop to exit.  So the return value
++      ** is never used and does not matter. */
++      return 0;
+     }
+ #else
+     if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){
+       if( fts5yyGrowStack(fts5yypParser) ){
+         fts5yyStackOverflow(fts5yypParser);
+-        return;
++        /* The call to fts5yyStackOverflow() above pops the stack until it is
++        ** empty, causing the main parser loop to exit.  So the return value
++        ** is never used and does not matter. */
++        return 0;
+       }
+       fts5yymsp = fts5yypParser->fts5yytos;
+     }
+@@ -190652,120 +200744,120 @@
+ /********** Begin reduce actions **********************************************/
+         fts5YYMINORTYPE fts5yylhsminor;
+       case 0: /* input ::= expr */
+-{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy54); }
++{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
+         break;
+       case 1: /* colset ::= MINUS LCP colsetlist RCP */
+ { 
+-    fts5yymsp[-3].minor.fts5yy43 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy43);
++    fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+ }
+         break;
+       case 2: /* colset ::= LCP colsetlist RCP */
+-{ fts5yymsp[-2].minor.fts5yy43 = fts5yymsp[-1].minor.fts5yy43; }
++{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
+         break;
+       case 3: /* colset ::= STRING */
+ {
+-  fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ }
+-  fts5yymsp[0].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
++  fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+         break;
+       case 4: /* colset ::= MINUS STRING */
+ {
+-  fts5yymsp[-1].minor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+-  fts5yymsp[-1].minor.fts5yy43 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy43);
++  fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
++  fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+ }
+         break;
+       case 5: /* colsetlist ::= colsetlist STRING */
+ { 
+-  fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy43, &fts5yymsp[0].minor.fts5yy0); }
+-  fts5yymsp[-1].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
++  fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+         break;
+       case 6: /* colsetlist ::= STRING */
+ { 
+-  fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); 
++  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); 
+ }
+-  fts5yymsp[0].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
++  fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+         break;
+       case 7: /* expr ::= expr AND expr */
+ {
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ }
+-  fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 8: /* expr ::= expr OR expr */
+ {
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ }
+-  fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 9: /* expr ::= expr NOT expr */
+ {
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ }
+-  fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 10: /* expr ::= colset COLON LP expr RP */
+ {
+-  sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy54, fts5yymsp[-4].minor.fts5yy43);
+-  fts5yylhsminor.fts5yy54 = fts5yymsp[-1].minor.fts5yy54;
++  sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
++  fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
+ }
+-  fts5yymsp[-4].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 11: /* expr ::= LP expr RP */
+-{fts5yymsp[-2].minor.fts5yy54 = fts5yymsp[-1].minor.fts5yy54;}
++{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
+         break;
+       case 12: /* expr ::= exprlist */
+       case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
+-{fts5yylhsminor.fts5yy54 = fts5yymsp[0].minor.fts5yy54;}
+-  fts5yymsp[0].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
++  fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 14: /* exprlist ::= exprlist cnearset */
+ {
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54);
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
+ }
+-  fts5yymsp[-1].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 15: /* cnearset ::= nearset */
+ { 
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy14); 
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); 
+ }
+-  fts5yymsp[0].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 16: /* cnearset ::= colset COLON nearset */
+ { 
+-  fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy14); 
+-  sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy54, fts5yymsp[-2].minor.fts5yy43);
++  fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); 
++  sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
+ }
+-  fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
++  fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+         break;
+       case 17: /* nearset ::= phrase */
+-{ fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
+-  fts5yymsp[0].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
++{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
++  fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+       case 18: /* nearset ::= CARET phrase */
+ { 
+-  sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy11);
+-  fts5yymsp[-1].minor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); 
++  sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53);
++  fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); 
+ }
+         break;
+       case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ {
+   sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
+-  sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy14, &fts5yymsp[-1].minor.fts5yy0);
+-  fts5yylhsminor.fts5yy14 = fts5yymsp[-2].minor.fts5yy14;
++  sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
++  fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
+ }
+-  fts5yymsp[-4].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
++  fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+       case 20: /* nearphrases ::= phrase */
+ { 
+-  fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); 
++  fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); 
+ }
+-  fts5yymsp[0].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
++  fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+       case 21: /* nearphrases ::= nearphrases phrase */
+ {
+-  fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy14, fts5yymsp[0].minor.fts5yy11);
++  fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
+ }
+-  fts5yymsp[-1].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
++  fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+         break;
+       case 22: /* neardist_opt ::= */
+ { fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
+@@ -190775,15 +200867,15 @@
+         break;
+       case 24: /* phrase ::= phrase PLUS STRING star_opt */
+ { 
+-  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
++  fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ }
+-  fts5yymsp[-3].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
++  fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+         break;
+       case 25: /* phrase ::= STRING star_opt */
+ { 
+-  fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
++  fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ }
+-  fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
++  fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+         break;
+       case 26: /* star_opt ::= STAR */
+ { fts5yymsp[0].minor.fts5yy4 = 1; }
+@@ -190812,6 +200904,7 @@
+   fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+   fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+   fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
++  return fts5yyact;
+ }
+ 
+ /*
+@@ -190821,7 +200914,8 @@
+ static void fts5yy_parse_failed(
+   fts5yyParser *fts5yypParser           /* The parser */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt);
+@@ -190832,7 +200926,8 @@
+   ** parser fails */
+ /************ Begin %parse_failure code ***************************************/
+ /************ End %parse_failure code *****************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ #endif /* fts5YYNOERRORRECOVERY */
+ 
+@@ -190844,7 +200939,8 @@
+   int fts5yymajor,                   /* The major type of the error token */
+   sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor         /* The minor type of the error token */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #define FTS5TOKEN fts5yyminor
+ /************ Begin %syntax_error code ****************************************/
+ 
+@@ -190853,7 +200949,8 @@
+     pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p
+   );
+ /************ End %syntax_error code ******************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /*
+@@ -190862,7 +200959,8 @@
+ static void fts5yy_accept(
+   fts5yyParser *fts5yypParser           /* The parser */
+ ){
+-  sqlite3Fts5ParserARG_FETCH;
++  sqlite3Fts5ParserARG_FETCH
++  sqlite3Fts5ParserCTX_FETCH
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt);
+@@ -190876,7 +200974,8 @@
+   ** parser accepts */
+ /*********** Begin %parse_accept code *****************************************/
+ /*********** End %parse_accept code *******************************************/
+-  sqlite3Fts5ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */
++  sqlite3Fts5ParserCTX_STORE
+ }
+ 
+ /* The main parser program.
+@@ -190905,7 +201004,7 @@
+   sqlite3Fts5ParserARG_PDECL               /* Optional %extra_argument parameter */
+ ){
+   fts5YYMINORTYPE fts5yyminorunion;
+-  unsigned int fts5yyact;   /* The parser action. */
++  fts5YYACTIONTYPE fts5yyact;   /* The parser action. */
+ #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+   int fts5yyendofinput;     /* True if we are at the end of input */
+ #endif
+@@ -190912,38 +201011,40 @@
+ #ifdef fts5YYERRORSYMBOL
+   int fts5yyerrorhit = 0;   /* True if fts5yymajor has invoked an error */
+ #endif
+-  fts5yyParser *fts5yypParser;  /* The parser */
++  fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp;  /* The parser */
++  sqlite3Fts5ParserCTX_FETCH
++  sqlite3Fts5ParserARG_STORE
+ 
+-  fts5yypParser = (fts5yyParser*)fts5yyp;
+   assert( fts5yypParser->fts5yytos!=0 );
+ #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY)
+   fts5yyendofinput = (fts5yymajor==0);
+ #endif
+-  sqlite3Fts5ParserARG_STORE;
+ 
++  fts5yyact = fts5yypParser->fts5yytos->stateno;
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+-    int stateno = fts5yypParser->fts5yytos->stateno;
+-    if( stateno < fts5YY_MIN_REDUCE ){
++    if( fts5yyact < fts5YY_MIN_REDUCE ){
+       fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
+-              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],stateno);
++              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact);
+     }else{
+       fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+-              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],stateno-fts5YY_MIN_REDUCE);
++              fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],fts5yyact-fts5YY_MIN_REDUCE);
+     }
+   }
+ #endif
+ 
+   do{
+-    fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
++    assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
++    fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
+     if( fts5yyact >= fts5YY_MIN_REDUCE ){
+-      fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor,fts5yyminor);
++      fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor,
++                        fts5yyminor sqlite3Fts5ParserCTX_PARAM);
+     }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+-      fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
++      fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor);
+ #ifndef fts5YYNOERRORRECOVERY
+       fts5yypParser->fts5yyerrcnt--;
+ #endif
+-      fts5yymajor = fts5YYNOCODE;
++      break;
+     }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
+       fts5yypParser->fts5yytos--;
+       fts5yy_accept(fts5yypParser);
+@@ -190994,10 +201095,9 @@
+         fts5yymajor = fts5YYNOCODE;
+       }else{
+         while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
+-            && fts5yymx != fts5YYERRORSYMBOL
+             && (fts5yyact = fts5yy_find_reduce_action(
+                         fts5yypParser->fts5yytos->stateno,
+-                        fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
++                        fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE
+         ){
+           fts5yy_pop_parser_stack(fts5yypParser);
+         }
+@@ -191014,6 +201114,8 @@
+       }
+       fts5yypParser->fts5yyerrcnt = 3;
+       fts5yyerrorhit = 1;
++      if( fts5yymajor==fts5YYNOCODE ) break;
++      fts5yyact = fts5yypParser->fts5yytos->stateno;
+ #elif defined(fts5YYNOERRORRECOVERY)
+       /* If the fts5YYNOERRORRECOVERY macro is defined, then do not attempt to
+       ** do any kind of error recovery.  Instead, simply invoke the syntax
+@@ -191024,8 +201126,7 @@
+       */
+       fts5yy_syntax_error(fts5yypParser,fts5yymajor, fts5yyminor);
+       fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
+-      fts5yymajor = fts5YYNOCODE;
+-      
++      break;
+ #else  /* fts5YYERRORSYMBOL is not defined */
+       /* This is what we do if the grammar does not define ERROR:
+       **
+@@ -191047,10 +201148,10 @@
+         fts5yypParser->fts5yyerrcnt = -1;
+ #endif
+       }
+-      fts5yymajor = fts5YYNOCODE;
++      break;
+ #endif
+     }
+-  }while( fts5yymajor!=fts5YYNOCODE && fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
++  }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack );
+ #ifndef NDEBUG
+   if( fts5yyTraceFILE ){
+     fts5yyStackEntry *i;
+@@ -191067,6 +201168,21 @@
+ }
+ 
+ /*
++** Return the fallback token corresponding to canonical token iToken, or
++** 0 if iToken has no fallback.
++*/
++static int sqlite3Fts5ParserFallback(int iToken){
++#ifdef fts5YYFALLBACK
++  if( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ){
++    return fts5yyFallback[iToken];
++  }
++#else
++  (void)iToken;
++#endif
++  return 0;
++}
++
++/*
+ ** 2014 May 31
+ **
+ ** The author disclaims copyright to this source code.  In place of
+@@ -193176,6 +203292,7 @@
+ /* #include <stdio.h> */
+ static void sqlite3Fts5ParserTrace(FILE*, char*);
+ #endif
++static int sqlite3Fts5ParserFallback(int);
+ 
+ 
+ struct Fts5Expr {
+@@ -195680,6 +205797,7 @@
+   sqlite3_value **apVal           /* Function arguments */
+ ){
+   int iCode;
++  u8 aArr[32];
+   if( nArg!=1 ){
+     sqlite3_result_error(pCtx, 
+         "wrong number of arguments to function fts5_isalnum", -1
+@@ -195686,8 +205804,12 @@
+     );
+     return;
+   }
++  memset(aArr, 0, sizeof(aArr));
++  sqlite3Fts5UnicodeCatParse("L*", aArr);
++  sqlite3Fts5UnicodeCatParse("N*", aArr);
++  sqlite3Fts5UnicodeCatParse("Co", aArr);
+   iCode = sqlite3_value_int(apVal[0]);
+-  sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
++  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
+ }
+ 
+ static void fts5ExprFold(
+@@ -195731,10 +205853,12 @@
+     rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
+   }
+ 
+-  /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
++  /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
++  ** sqlite3Fts5ParserFallback() are unused */
+ #ifndef NDEBUG
+   (void)sqlite3Fts5ParserTrace;
+ #endif
++  (void)sqlite3Fts5ParserFallback;
+ 
+   return rc;
+ }
+@@ -201782,7 +211906,10 @@
+   for(i=0; i<nChar; i++){
+     if( n>=nByte ) return 0;      /* Input contains fewer than nChar chars */
+     if( (unsigned char)p[n++]>=0xc0 ){
+-      while( (p[n] & 0xc0)==0x80 ) n++;
++      while( (p[n] & 0xc0)==0x80 ){
++        n++;
++        if( n>=nByte ) break;
++      }
+     }
+   }
+   return n;
+@@ -201920,7 +212047,7 @@
+       fts5CloseReader(p);
+     }
+ 
+-    *ppIter = &pRet->base;
++    *ppIter = (Fts5IndexIter*)pRet;
+     sqlite3Fts5BufferFree(&buf);
+   }
+   return fts5IndexReturn(p);
+@@ -203307,7 +213434,7 @@
+     case FTS5_SAVEPOINT:
+       assert( p->ts.eState==1 );
+       assert( iSavepoint>=0 );
+-      assert( iSavepoint>p->ts.iSavepoint );
++      assert( iSavepoint>=p->ts.iSavepoint );
+       p->ts.iSavepoint = iSavepoint;
+       break;
+       
+@@ -204232,6 +214359,13 @@
+     assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
+     assert( pCsr->iLastRowid==LARGEST_INT64 );
+     assert( pCsr->iFirstRowid==SMALLEST_INT64 );
++    if( pTab->pSortCsr->bDesc ){
++      pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
++      pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
++    }else{
++      pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
++      pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
++    }
+     pCsr->ePlan = FTS5_PLAN_SOURCE;
+     pCsr->pExpr = pTab->pSortCsr->pExpr;
+     rc = fts5CursorFirst(pTab, pCsr, bDesc);
+@@ -205662,12 +215796,27 @@
+ ){
+   assert( nArg==0 );
+   UNUSED_PARAM2(nArg, apUnused);
+-  sqlite3_result_text(pCtx, "fts5: 2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b", -1, SQLITE_TRANSIENT);
++  sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
+ }
+ 
++/*
++** Return true if zName is the extension on one of the shadow tables used
++** by this module.
++*/
++static int fts5ShadowName(const char *zName){
++  static const char *azName[] = {
++    "config", "content", "data", "docsize", "idx"
++  };
++  unsigned int i;
++  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
++    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
++  }
++  return 0;
++}
++
+ static int fts5Init(sqlite3 *db){
+   static const sqlite3_module fts5Mod = {
+-    /* iVersion      */ 2,
++    /* iVersion      */ 3,
+     /* xCreate       */ fts5CreateMethod,
+     /* xConnect      */ fts5ConnectMethod,
+     /* xBestIndex    */ fts5BestIndexMethod,
+@@ -205690,6 +215839,7 @@
+     /* xSavepoint    */ fts5SavepointMethod,
+     /* xRelease      */ fts5ReleaseMethod,
+     /* xRollbackTo   */ fts5RollbackToMethod,
++    /* xShadowName   */ fts5ShadowName
+   };
+ 
+   int rc;
+@@ -207150,6 +217300,8 @@
+   int bRemoveDiacritic;           /* True if remove_diacritics=1 is set */
+   int nException;
+   int *aiException;
++
++  unsigned char aCategory[32];    /* True for token char categories */
+ };
+ 
+ static int fts5UnicodeAddExceptions(
+@@ -207174,7 +217326,7 @@
+         if( iCode<128 ){
+           p->aTokenChar[iCode] = (unsigned char)bTokenChars;
+         }else{
+-          bToken = sqlite3Fts5UnicodeIsalnum(iCode);
++          bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
+           assert( (bToken==0 || bToken==1) ); 
+           assert( (bTokenChars==0 || bTokenChars==1) );
+           if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
+@@ -207235,6 +217387,21 @@
+   return;
+ }
+ 
++static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
++  const char *z = zCat;
++
++  while( *z ){
++    while( *z==' ' || *z=='\t' ) z++;
++    if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){
++      return SQLITE_ERROR;
++    }
++    while( *z!=' ' && *z!='\t' && *z!='\0' ) z++;
++  }
++
++  sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar);
++  return SQLITE_OK;
++}
++
+ /*
+ ** Create a "unicode61" tokenizer.
+ */
+@@ -207253,9 +217420,10 @@
+   }else{
+     p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
+     if( p ){
++      const char *zCat = "L* N* Co";
+       int i;
+       memset(p, 0, sizeof(Unicode61Tokenizer));
+-      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
++
+       p->bRemoveDiacritic = 1;
+       p->nFold = 64;
+       p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
+@@ -207262,7 +217430,19 @@
+       if( p->aFold==0 ){
+         rc = SQLITE_NOMEM;
+       }
++
++      /* Search for a "categories" argument */
+       for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
++        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
++          zCat = azArg[i+1];
++        }
++      }
++
++      if( rc==SQLITE_OK ){
++        rc = unicodeSetCategories(p, zCat);
++      }
++
++      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
+         const char *zArg = azArg[i+1];
+         if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
+           if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
+@@ -207275,10 +217455,14 @@
+         }else
+         if( 0==sqlite3_stricmp(azArg[i], "separators") ){
+           rc = fts5UnicodeAddExceptions(p, zArg, 0);
++        }else
++        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
++          /* no-op */
+         }else{
+           rc = SQLITE_ERROR;
+         }
+       }
++
+     }else{
+       rc = SQLITE_NOMEM;
+     }
+@@ -207297,8 +217481,10 @@
+ ** character (not a separator).
+ */
+ static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
+-  assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
+-  return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
++  return (
++    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
++    ^ fts5UnicodeIsException(p, iCode)
++  );
+ }
+ 
+ static int fts5UnicodeTokenize(
+@@ -208174,137 +218360,8 @@
+ 
+ /* #include <assert.h> */
+ 
+-/*
+-** Return true if the argument corresponds to a unicode codepoint
+-** classified as either a letter or a number. Otherwise false.
+-**
+-** The results are undefined if the value passed to this function
+-** is less than zero.
+-*/
+-static int sqlite3Fts5UnicodeIsalnum(int c){
+-  /* Each unsigned integer in the following array corresponds to a contiguous
+-  ** range of unicode codepoints that are not either letters or numbers (i.e.
+-  ** codepoints for which this function should return 0).
+-  **
+-  ** The most significant 22 bits in each 32-bit value contain the first 
+-  ** codepoint in the range. The least significant 10 bits are used to store
+-  ** the size of the range (always at least 1). In other words, the value 
+-  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
+-  ** C. It is not possible to represent a range larger than 1023 codepoints 
+-  ** using this format.
+-  */
+-  static const unsigned int aEntry[] = {
+-    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
+-    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
+-    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
+-    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
+-    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
+-    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
+-    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
+-    0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
+-    0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
+-    0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
+-    0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
+-    0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
+-    0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
+-    0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
+-    0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
+-    0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
+-    0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
+-    0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
+-    0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
+-    0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
+-    0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
+-    0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
+-    0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
+-    0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
+-    0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
+-    0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
+-    0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
+-    0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
+-    0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
+-    0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
+-    0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
+-    0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
+-    0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
+-    0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
+-    0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
+-    0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
+-    0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
+-    0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
+-    0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
+-    0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
+-    0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
+-    0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
+-    0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
+-    0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
+-    0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
+-    0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
+-    0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
+-    0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
+-    0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
+-    0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
+-    0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
+-    0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
+-    0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
+-    0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
+-    0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
+-    0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
+-    0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
+-    0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
+-    0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
+-    0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
+-    0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
+-    0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
+-    0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
+-    0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
+-    0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
+-    0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
+-    0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
+-    0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
+-    0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
+-    0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
+-    0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
+-    0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
+-    0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
+-    0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
+-    0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
+-    0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
+-    0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
+-    0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
+-    0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
+-    0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
+-    0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
+-    0x380400F0,
+-  };
+-  static const unsigned int aAscii[4] = {
+-    0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
+-  };
+ 
+-  if( (unsigned int)c<128 ){
+-    return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
+-  }else if( (unsigned int)c<(1<<22) ){
+-    unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
+-    int iRes = 0;
+-    int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
+-    int iLo = 0;
+-    while( iHi>=iLo ){
+-      int iTest = (iHi + iLo) / 2;
+-      if( key >= aEntry[iTest] ){
+-        iRes = iTest;
+-        iLo = iTest+1;
+-      }else{
+-        iHi = iTest-1;
+-      }
+-    }
+-    assert( aEntry[0]<key );
+-    assert( key>=aEntry[iRes] );
+-    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
+-  }
+-  return 1;
+-}
+ 
+-
+ /*
+ ** If the argument is a codepoint corresponding to a lowercase letter
+ ** in the ASCII range with a diacritic added, return the codepoint
+@@ -208515,6 +218572,539 @@
+   return ret;
+ }
+ 
++
++#if 0
++static int sqlite3Fts5UnicodeNCat(void) { 
++  return 32;
++}
++#endif
++
++static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
++  aArray[0] = 1;
++  switch( zCat[0] ){
++    case 'C':
++          switch( zCat[1] ){
++            case 'c': aArray[1] = 1; break;
++            case 'f': aArray[2] = 1; break;
++            case 'n': aArray[3] = 1; break;
++            case 's': aArray[4] = 1; break;
++            case 'o': aArray[31] = 1; break;
++            case '*': 
++              aArray[1] = 1;
++              aArray[2] = 1;
++              aArray[3] = 1;
++              aArray[4] = 1;
++              aArray[31] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'L':
++          switch( zCat[1] ){
++            case 'l': aArray[5] = 1; break;
++            case 'm': aArray[6] = 1; break;
++            case 'o': aArray[7] = 1; break;
++            case 't': aArray[8] = 1; break;
++            case 'u': aArray[9] = 1; break;
++            case 'C': aArray[30] = 1; break;
++            case '*': 
++              aArray[5] = 1;
++              aArray[6] = 1;
++              aArray[7] = 1;
++              aArray[8] = 1;
++              aArray[9] = 1;
++              aArray[30] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'M':
++          switch( zCat[1] ){
++            case 'c': aArray[10] = 1; break;
++            case 'e': aArray[11] = 1; break;
++            case 'n': aArray[12] = 1; break;
++            case '*': 
++              aArray[10] = 1;
++              aArray[11] = 1;
++              aArray[12] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'N':
++          switch( zCat[1] ){
++            case 'd': aArray[13] = 1; break;
++            case 'l': aArray[14] = 1; break;
++            case 'o': aArray[15] = 1; break;
++            case '*': 
++              aArray[13] = 1;
++              aArray[14] = 1;
++              aArray[15] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'P':
++          switch( zCat[1] ){
++            case 'c': aArray[16] = 1; break;
++            case 'd': aArray[17] = 1; break;
++            case 'e': aArray[18] = 1; break;
++            case 'f': aArray[19] = 1; break;
++            case 'i': aArray[20] = 1; break;
++            case 'o': aArray[21] = 1; break;
++            case 's': aArray[22] = 1; break;
++            case '*': 
++              aArray[16] = 1;
++              aArray[17] = 1;
++              aArray[18] = 1;
++              aArray[19] = 1;
++              aArray[20] = 1;
++              aArray[21] = 1;
++              aArray[22] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'S':
++          switch( zCat[1] ){
++            case 'c': aArray[23] = 1; break;
++            case 'k': aArray[24] = 1; break;
++            case 'm': aArray[25] = 1; break;
++            case 'o': aArray[26] = 1; break;
++            case '*': 
++              aArray[23] = 1;
++              aArray[24] = 1;
++              aArray[25] = 1;
++              aArray[26] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++    case 'Z':
++          switch( zCat[1] ){
++            case 'l': aArray[27] = 1; break;
++            case 'p': aArray[28] = 1; break;
++            case 's': aArray[29] = 1; break;
++            case '*': 
++              aArray[27] = 1;
++              aArray[28] = 1;
++              aArray[29] = 1;
++              break;
++            default: return 1;          }
++          break;
++
++  }
++  return 0;
++}
++
++static u16 aFts5UnicodeBlock[] = {
++    0,     1471,  1753,  1760,  1760,  1760,  1760,  1760,  1760,  1760,  
++    1760,  1760,  1760,  1760,  1760,  1763,  1765,  
++  };
++static u16 aFts5UnicodeMap[] = {
++    0,     32,    33,    36,    37,    40,    41,    42,    43,    44,    
++    45,    46,    48,    58,    60,    63,    65,    91,    92,    93,    
++    94,    95,    96,    97,    123,   124,   125,   126,   127,   160,   
++    161,   162,   166,   167,   168,   169,   170,   171,   172,   173,   
++    174,   175,   176,   177,   178,   180,   181,   182,   184,   185,   
++    186,   187,   188,   191,   192,   215,   216,   223,   247,   248,   
++    256,   312,   313,   329,   330,   377,   383,   385,   387,   388,   
++    391,   394,   396,   398,   402,   403,   405,   406,   409,   412,   
++    414,   415,   417,   418,   423,   427,   428,   431,   434,   436,   
++    437,   440,   442,   443,   444,   446,   448,   452,   453,   454,   
++    455,   456,   457,   458,   459,   460,   461,   477,   478,   496,   
++    497,   498,   499,   500,   503,   505,   506,   564,   570,   572,   
++    573,   575,   577,   580,   583,   584,   592,   660,   661,   688,   
++    706,   710,   722,   736,   741,   748,   749,   750,   751,   768,   
++    880,   884,   885,   886,   890,   891,   894,   900,   902,   903,   
++    904,   908,   910,   912,   913,   931,   940,   975,   977,   978,   
++    981,   984,   1008,  1012,  1014,  1015,  1018,  1020,  1021,  1072,  
++    1120,  1154,  1155,  1160,  1162,  1217,  1231,  1232,  1329,  1369,  
++    1370,  1377,  1417,  1418,  1423,  1425,  1470,  1471,  1472,  1473,  
++    1475,  1476,  1478,  1479,  1488,  1520,  1523,  1536,  1542,  1545,  
++    1547,  1548,  1550,  1552,  1563,  1566,  1568,  1600,  1601,  1611,  
++    1632,  1642,  1646,  1648,  1649,  1748,  1749,  1750,  1757,  1758,  
++    1759,  1765,  1767,  1769,  1770,  1774,  1776,  1786,  1789,  1791,  
++    1792,  1807,  1808,  1809,  1810,  1840,  1869,  1958,  1969,  1984,  
++    1994,  2027,  2036,  2038,  2039,  2042,  2048,  2070,  2074,  2075,  
++    2084,  2085,  2088,  2089,  2096,  2112,  2137,  2142,  2208,  2210,  
++    2276,  2304,  2307,  2308,  2362,  2363,  2364,  2365,  2366,  2369,  
++    2377,  2381,  2382,  2384,  2385,  2392,  2402,  2404,  2406,  2416,  
++    2417,  2418,  2425,  2433,  2434,  2437,  2447,  2451,  2474,  2482,  
++    2486,  2492,  2493,  2494,  2497,  2503,  2507,  2509,  2510,  2519,  
++    2524,  2527,  2530,  2534,  2544,  2546,  2548,  2554,  2555,  2561,  
++    2563,  2565,  2575,  2579,  2602,  2610,  2613,  2616,  2620,  2622,  
++    2625,  2631,  2635,  2641,  2649,  2654,  2662,  2672,  2674,  2677,  
++    2689,  2691,  2693,  2703,  2707,  2730,  2738,  2741,  2748,  2749,  
++    2750,  2753,  2759,  2761,  2763,  2765,  2768,  2784,  2786,  2790,  
++    2800,  2801,  2817,  2818,  2821,  2831,  2835,  2858,  2866,  2869,  
++    2876,  2877,  2878,  2879,  2880,  2881,  2887,  2891,  2893,  2902,  
++    2903,  2908,  2911,  2914,  2918,  2928,  2929,  2930,  2946,  2947,  
++    2949,  2958,  2962,  2969,  2972,  2974,  2979,  2984,  2990,  3006,  
++    3008,  3009,  3014,  3018,  3021,  3024,  3031,  3046,  3056,  3059,  
++    3065,  3066,  3073,  3077,  3086,  3090,  3114,  3125,  3133,  3134,  
++    3137,  3142,  3146,  3157,  3160,  3168,  3170,  3174,  3192,  3199,  
++    3202,  3205,  3214,  3218,  3242,  3253,  3260,  3261,  3262,  3263,  
++    3264,  3270,  3271,  3274,  3276,  3285,  3294,  3296,  3298,  3302,  
++    3313,  3330,  3333,  3342,  3346,  3389,  3390,  3393,  3398,  3402,  
++    3405,  3406,  3415,  3424,  3426,  3430,  3440,  3449,  3450,  3458,  
++    3461,  3482,  3507,  3517,  3520,  3530,  3535,  3538,  3542,  3544,  
++    3570,  3572,  3585,  3633,  3634,  3636,  3647,  3648,  3654,  3655,  
++    3663,  3664,  3674,  3713,  3716,  3719,  3722,  3725,  3732,  3737,  
++    3745,  3749,  3751,  3754,  3757,  3761,  3762,  3764,  3771,  3773,  
++    3776,  3782,  3784,  3792,  3804,  3840,  3841,  3844,  3859,  3860,  
++    3861,  3864,  3866,  3872,  3882,  3892,  3893,  3894,  3895,  3896,  
++    3897,  3898,  3899,  3900,  3901,  3902,  3904,  3913,  3953,  3967,  
++    3968,  3973,  3974,  3976,  3981,  3993,  4030,  4038,  4039,  4046,  
++    4048,  4053,  4057,  4096,  4139,  4141,  4145,  4146,  4152,  4153,  
++    4155,  4157,  4159,  4160,  4170,  4176,  4182,  4184,  4186,  4190,  
++    4193,  4194,  4197,  4199,  4206,  4209,  4213,  4226,  4227,  4229,  
++    4231,  4237,  4238,  4239,  4240,  4250,  4253,  4254,  4256,  4295,  
++    4301,  4304,  4347,  4348,  4349,  4682,  4688,  4696,  4698,  4704,  
++    4746,  4752,  4786,  4792,  4800,  4802,  4808,  4824,  4882,  4888,  
++    4957,  4960,  4969,  4992,  5008,  5024,  5120,  5121,  5741,  5743,  
++    5760,  5761,  5787,  5788,  5792,  5867,  5870,  5888,  5902,  5906,  
++    5920,  5938,  5941,  5952,  5970,  5984,  5998,  6002,  6016,  6068,  
++    6070,  6071,  6078,  6086,  6087,  6089,  6100,  6103,  6104,  6107,  
++    6108,  6109,  6112,  6128,  6144,  6150,  6151,  6155,  6158,  6160,  
++    6176,  6211,  6212,  6272,  6313,  6314,  6320,  6400,  6432,  6435,  
++    6439,  6441,  6448,  6450,  6451,  6457,  6464,  6468,  6470,  6480,  
++    6512,  6528,  6576,  6593,  6600,  6608,  6618,  6622,  6656,  6679,  
++    6681,  6686,  6688,  6741,  6742,  6743,  6744,  6752,  6753,  6754,  
++    6755,  6757,  6765,  6771,  6783,  6784,  6800,  6816,  6823,  6824,  
++    6912,  6916,  6917,  6964,  6965,  6966,  6971,  6972,  6973,  6978,  
++    6979,  6981,  6992,  7002,  7009,  7019,  7028,  7040,  7042,  7043,  
++    7073,  7074,  7078,  7080,  7082,  7083,  7084,  7086,  7088,  7098,  
++    7142,  7143,  7144,  7146,  7149,  7150,  7151,  7154,  7164,  7168,  
++    7204,  7212,  7220,  7222,  7227,  7232,  7245,  7248,  7258,  7288,  
++    7294,  7360,  7376,  7379,  7380,  7393,  7394,  7401,  7405,  7406,  
++    7410,  7412,  7413,  7424,  7468,  7531,  7544,  7545,  7579,  7616,  
++    7676,  7680,  7830,  7838,  7936,  7944,  7952,  7960,  7968,  7976,  
++    7984,  7992,  8000,  8008,  8016,  8025,  8027,  8029,  8031,  8033,  
++    8040,  8048,  8064,  8072,  8080,  8088,  8096,  8104,  8112,  8118,  
++    8120,  8124,  8125,  8126,  8127,  8130,  8134,  8136,  8140,  8141,  
++    8144,  8150,  8152,  8157,  8160,  8168,  8173,  8178,  8182,  8184,  
++    8188,  8189,  8192,  8203,  8208,  8214,  8216,  8217,  8218,  8219,  
++    8221,  8222,  8223,  8224,  8232,  8233,  8234,  8239,  8240,  8249,  
++    8250,  8251,  8255,  8257,  8260,  8261,  8262,  8263,  8274,  8275,  
++    8276,  8277,  8287,  8288,  8298,  8304,  8305,  8308,  8314,  8317,  
++    8318,  8319,  8320,  8330,  8333,  8334,  8336,  8352,  8400,  8413,  
++    8417,  8418,  8421,  8448,  8450,  8451,  8455,  8456,  8458,  8459,  
++    8462,  8464,  8467,  8468,  8469,  8470,  8472,  8473,  8478,  8484,  
++    8485,  8486,  8487,  8488,  8489,  8490,  8494,  8495,  8496,  8500,  
++    8501,  8505,  8506,  8508,  8510,  8512,  8517,  8519,  8522,  8523,  
++    8524,  8526,  8527,  8528,  8544,  8579,  8581,  8585,  8592,  8597,  
++    8602,  8604,  8608,  8609,  8611,  8612,  8614,  8615,  8622,  8623,  
++    8654,  8656,  8658,  8659,  8660,  8661,  8692,  8960,  8968,  8972,  
++    8992,  8994,  9001,  9002,  9003,  9084,  9085,  9115,  9140,  9180,  
++    9186,  9216,  9280,  9312,  9372,  9450,  9472,  9655,  9656,  9665,  
++    9666,  9720,  9728,  9839,  9840,  9985,  10088, 10089, 10090, 10091, 
++    10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, 
++    10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, 
++    10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, 
++    10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, 
++    10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, 
++    10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, 
++    11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, 
++    11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, 
++    11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, 
++    11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, 
++    11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, 
++    11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, 
++    11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, 
++    11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, 
++    11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, 
++    12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, 
++    12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, 
++    12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, 
++    12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, 
++    12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, 
++    12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, 
++    12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, 
++    40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, 
++    42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, 
++    42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, 
++    42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, 
++    43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, 
++    43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, 
++    43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, 
++    43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, 
++    43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, 
++    43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, 
++    43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, 
++    43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, 
++    43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, 
++    43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, 
++    44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, 
++    55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, 
++    64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, 
++    64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, 
++    65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, 
++    65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, 
++    65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, 
++    65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, 
++    65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, 
++    65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, 
++    65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, 
++    65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 
++    65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, 
++    65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, 
++    65532, 0,     13,    40,    60,    63,    80,    128,   256,   263,   
++    311,   320,   373,   377,   394,   400,   464,   509,   640,   672,   
++    768,   800,   816,   833,   834,   842,   896,   927,   928,   968,   
++    976,   977,   1024,  1064,  1104,  1184,  2048,  2056,  2058,  2103,  
++    2108,  2111,  2135,  2136,  2304,  2326,  2335,  2336,  2367,  2432,  
++    2494,  2560,  2561,  2565,  2572,  2576,  2581,  2585,  2616,  2623,  
++    2624,  2640,  2656,  2685,  2687,  2816,  2873,  2880,  2904,  2912,  
++    2936,  3072,  3680,  4096,  4097,  4098,  4099,  4152,  4167,  4178,  
++    4198,  4224,  4226,  4227,  4272,  4275,  4279,  4281,  4283,  4285,  
++    4286,  4304,  4336,  4352,  4355,  4391,  4396,  4397,  4406,  4416,  
++    4480,  4482,  4483,  4531,  4534,  4543,  4545,  4549,  4560,  5760,  
++    5803,  5804,  5805,  5806,  5808,  5814,  5815,  5824,  8192,  9216,  
++    9328,  12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, 
++    53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, 
++    53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, 
++    54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, 
++    54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, 
++    54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, 
++    54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, 
++    54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, 
++    55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, 
++    55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, 
++    60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, 
++    61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, 
++    61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, 
++    61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, 
++    61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, 
++    62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, 
++    63045, 63104, 63232, 0,     42710, 42752, 46900, 46912, 47133, 63488, 
++    1,     32,    256,   0,     65533, 
++  };
++static u16 aFts5UnicodeData[] = {
++    1025,  61,    117,   55,    117,   54,    50,    53,    57,    53,    
++    49,    85,    333,   85,    121,   85,    841,   54,    53,    50,    
++    56,    48,    56,    837,   54,    57,    50,    57,    1057,  61,    
++    53,    151,   58,    53,    56,    58,    39,    52,    57,    34,    
++    58,    56,    58,    57,    79,    56,    37,    85,    56,    47,    
++    39,    51,    111,   53,    745,   57,    233,   773,   57,    261,   
++    1822,  37,    542,   37,    1534,  222,   69,    73,    37,    126,   
++    126,   73,    69,    137,   37,    73,    37,    105,   101,   73,    
++    37,    73,    37,    190,   158,   37,    126,   126,   73,    37,    
++    126,   94,    37,    39,    94,    69,    135,   41,    40,    37,    
++    41,    40,    37,    41,    40,    37,    542,   37,    606,   37,    
++    41,    40,    37,    126,   73,    37,    1886,  197,   73,    37,    
++    73,    69,    126,   105,   37,    286,   2181,  39,    869,   582,   
++    152,   390,   472,   166,   248,   38,    56,    38,    568,   3596,  
++    158,   38,    56,    94,    38,    101,   53,    88,    41,    53,    
++    105,   41,    73,    37,    553,   297,   1125,  94,    37,    105,   
++    101,   798,   133,   94,    57,    126,   94,    37,    1641,  1541,  
++    1118,  58,    172,   75,    1790,  478,   37,    2846,  1225,  38,    
++    213,   1253,  53,    49,    55,    1452,  49,    44,    53,    76,    
++    53,    76,    53,    44,    871,   103,   85,    162,   121,   85,    
++    55,    85,    90,    364,   53,    85,    1031,  38,    327,   684,   
++    333,   149,   71,    44,    3175,  53,    39,    236,   34,    58,    
++    204,   70,    76,    58,    140,   71,    333,   103,   90,    39,    
++    469,   34,    39,    44,    967,   876,   2855,  364,   39,    333,   
++    1063,  300,   70,    58,    117,   38,    711,   140,   38,    300,   
++    38,    108,   38,    172,   501,   807,   108,   53,    39,    359,   
++    876,   108,   42,    1735,  44,    42,    44,    39,    106,   268,   
++    138,   44,    74,    39,    236,   327,   76,    85,    333,   53,    
++    38,    199,   231,   44,    74,    263,   71,    711,   231,   39,    
++    135,   44,    39,    106,   140,   74,    74,    44,    39,    42,    
++    71,    103,   76,    333,   71,    87,    207,   58,    55,    76,    
++    42,    199,   71,    711,   231,   71,    71,    71,    44,    106,   
++    76,    76,    108,   44,    135,   39,    333,   76,    103,   44,    
++    76,    42,    295,   103,   711,   231,   71,    167,   44,    39,    
++    106,   172,   76,    42,    74,    44,    39,    71,    76,    333,   
++    53,    55,    44,    74,    263,   71,    711,   231,   71,    167,   
++    44,    39,    42,    44,    42,    140,   74,    74,    44,    44,    
++    42,    71,    103,   76,    333,   58,    39,    207,   44,    39,    
++    199,   103,   135,   71,    39,    71,    71,    103,   391,   74,    
++    44,    74,    106,   106,   44,    39,    42,    333,   111,   218,   
++    55,    58,    106,   263,   103,   743,   327,   167,   39,    108,   
++    138,   108,   140,   76,    71,    71,    76,    333,   239,   58,    
++    74,    263,   103,   743,   327,   167,   44,    39,    42,    44,    
++    170,   44,    74,    74,    76,    74,    39,    71,    76,    333,   
++    71,    74,    263,   103,   1319,  39,    106,   140,   106,   106,   
++    44,    39,    42,    71,    76,    333,   207,   58,    199,   74,    
++    583,   775,   295,   39,    231,   44,    106,   108,   44,    266,   
++    74,    53,    1543,  44,    71,    236,   55,    199,   38,    268,   
++    53,    333,   85,    71,    39,    71,    39,    39,    135,   231,   
++    103,   39,    39,    71,    135,   44,    71,    204,   76,    39,    
++    167,   38,    204,   333,   135,   39,    122,   501,   58,    53,    
++    122,   76,    218,   333,   335,   58,    44,    58,    44,    58,    
++    44,    54,    50,    54,    50,    74,    263,   1159,  460,   42,    
++    172,   53,    76,    167,   364,   1164,  282,   44,    218,   90,    
++    181,   154,   85,    1383,  74,    140,   42,    204,   42,    76,    
++    74,    76,    39,    333,   213,   199,   74,    76,    135,   108,   
++    39,    106,   71,    234,   103,   140,   423,   44,    74,    76,    
++    202,   44,    39,    42,    333,   106,   44,    90,    1225,  41,    
++    41,    1383,  53,    38,    10631, 135,   231,   39,    135,   1319,  
++    135,   1063,  135,   231,   39,    135,   487,   1831,  135,   2151,  
++    108,   309,   655,   519,   346,   2727,  49,    19847, 85,    551,   
++    61,    839,   54,    50,    2407,  117,   110,   423,   135,   108,   
++    583,   108,   85,    583,   76,    423,   103,   76,    1671,  76,    
++    42,    236,   266,   44,    74,    364,   117,   38,    117,   55,    
++    39,    44,    333,   335,   213,   49,    149,   108,   61,    333,   
++    1127,  38,    1671,  1319,  44,    39,    2247,  935,   108,   138,   
++    76,    106,   74,    44,    202,   108,   58,    85,    333,   967,   
++    167,   1415,  554,   231,   74,    333,   47,    1114,  743,   76,    
++    106,   85,    1703,  42,    44,    42,    236,   44,    42,    44,    
++    74,    268,   202,   332,   44,    333,   333,   245,   38,    213,   
++    140,   42,    1511,  44,    42,    172,   42,    44,    170,   44,    
++    74,    231,   333,   245,   346,   300,   314,   76,    42,    967,   
++    42,    140,   74,    76,    42,    44,    74,    71,    333,   1415,  
++    44,    42,    76,    106,   44,    42,    108,   74,    149,   1159,  
++    266,   268,   74,    76,    181,   333,   103,   333,   967,   198,   
++    85,    277,   108,   53,    428,   42,    236,   135,   44,    135,   
++    74,    44,    71,    1413,  2022,  421,   38,    1093,  1190,  1260,  
++    140,   4830,  261,   3166,  261,   265,   197,   201,   261,   265,   
++    261,   265,   197,   201,   261,   41,    41,    41,    94,    229,   
++    265,   453,   261,   264,   261,   264,   261,   264,   165,   69,    
++    137,   40,    56,    37,    120,   101,   69,    137,   40,    120,   
++    133,   69,    137,   120,   261,   169,   120,   101,   69,    137,   
++    40,    88,    381,   162,   209,   85,    52,    51,    54,    84,    
++    51,    54,    52,    277,   59,    60,    162,   61,    309,   52,    
++    51,    149,   80,    117,   57,    54,    50,    373,   57,    53,    
++    48,    341,   61,    162,   194,   47,    38,    207,   121,   54,    
++    50,    38,    335,   121,   54,    50,    422,   855,   428,   139,   
++    44,    107,   396,   90,    41,    154,   41,    90,    37,    105,   
++    69,    105,   37,    58,    41,    90,    57,    169,   218,   41,    
++    58,    41,    58,    41,    58,    137,   58,    37,    137,   37,    
++    135,   37,    90,    69,    73,    185,   94,    101,   58,    57,    
++    90,    37,    58,    527,   1134,  94,    142,   47,    185,   186,   
++    89,    154,   57,    90,    57,    90,    57,    250,   57,    1018,  
++    89,    90,    57,    58,    57,    1018,  8601,  282,   153,   666,   
++    89,    250,   54,    50,    2618,  57,    986,   825,   1306,  217,   
++    602,   1274,  378,   1935,  2522,  719,   5882,  57,    314,   57,    
++    1754,  281,   3578,  57,    4634,  3322,  54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
++    975,   1434,  185,   54,    50,    1017,  54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    537,   8218,  4217,  54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
++    50,    2041,  54,    50,    54,    50,    1049,  54,    50,    8281,  
++    1562,  697,   90,    217,   346,   1513,  1509,  126,   73,    69,    
++    254,   105,   37,    94,    37,    94,    165,   70,    105,   37,    
++    3166,  37,    218,   158,   108,   94,    149,   47,    85,    1221,  
++    37,    37,    1799,  38,    53,    44,    743,   231,   231,   231,   
++    231,   231,   231,   231,   231,   1036,  85,    52,    51,    52,    
++    51,    117,   52,    51,    53,    52,    51,    309,   49,    85,    
++    49,    53,    52,    51,    85,    52,    51,    54,    50,    54,    
++    50,    54,    50,    54,    50,    181,   38,    341,   81,    858,   
++    2874,  6874,  410,   61,    117,   58,    38,    39,    46,    54,    
++    50,    54,    50,    54,    50,    54,    50,    54,    50,    90,    
++    54,    50,    54,    50,    54,    50,    54,    50,    49,    54,    
++    82,    58,    302,   140,   74,    49,    166,   90,    110,   38,    
++    39,    53,    90,    2759,  76,    88,    70,    39,    49,    2887,  
++    53,    102,   39,    1319,  3015,  90,    143,   346,   871,   1178,  
++    519,   1018,  335,   986,   271,   58,    495,   1050,  335,   1274,  
++    495,   2042,  8218,  39,    39,    2074,  39,    39,    679,   38,    
++    36583, 1786,  1287,  198,   85,    8583,  38,    117,   519,   333,   
++    71,    1502,  39,    44,    107,   53,    332,   53,    38,    798,   
++    44,    2247,  334,   76,    213,   760,   294,   88,    478,   69,    
++    2014,  38,    261,   190,   350,   38,    88,    158,   158,   382,   
++    70,    37,    231,   44,    103,   44,    135,   44,    743,   74,    
++    76,    42,    154,   207,   90,    55,    58,    1671,  149,   74,    
++    1607,  522,   44,    85,    333,   588,   199,   117,   39,    333,   
++    903,   268,   85,    743,   364,   74,    53,    935,   108,   42,    
++    1511,  44,    74,    140,   74,    44,    138,   437,   38,    333,   
++    85,    1319,  204,   74,    76,    74,    76,    103,   44,    263,   
++    44,    42,    333,   149,   519,   38,    199,   122,   39,    42,    
++    1543,  44,    39,    108,   71,    76,    167,   76,    39,    44,    
++    39,    71,    38,    85,    359,   42,    76,    74,    85,    39,    
++    70,    42,    44,    199,   199,   199,   231,   231,   1127,  74,    
++    44,    74,    44,    74,    53,    42,    44,    333,   39,    39,    
++    743,   1575,  36,    68,    68,    36,    63,    63,    11719, 3399,  
++    229,   165,   39,    44,    327,   57,    423,   167,   39,    71,    
++    71,    3463,  536,   11623, 54,    50,    2055,  1735,  391,   55,    
++    58,    524,   245,   54,    50,    53,    236,   53,    81,    80,    
++    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
++    54,    50,    54,    50,    54,    50,    85,    54,    50,    149,   
++    112,   117,   149,   49,    54,    50,    54,    50,    54,    50,    
++    117,   57,    49,    121,   53,    55,    85,    167,   4327,  34,    
++    117,   55,    117,   54,    50,    53,    57,    53,    49,    85,    
++    333,   85,    121,   85,    841,   54,    53,    50,    56,    48,    
++    56,    837,   54,    57,    50,    57,    54,    50,    53,    54,    
++    50,    85,    327,   38,    1447,  70,    999,   199,   199,   199,   
++    103,   87,    57,    56,    58,    87,    58,    153,   90,    98,    
++    90,    391,   839,   615,   71,    487,   455,   3943,  117,   1455,  
++    314,   1710,  143,   570,   47,    410,   1466,  44,    935,   1575,  
++    999,   143,   551,   46,    263,   46,    967,   53,    1159,  263,   
++    53,    174,   1289,  1285,  2503,  333,   199,   39,    1415,  71,    
++    39,    743,   53,    271,   711,   207,   53,    839,   53,    1799,  
++    71,    39,    108,   76,    140,   135,   103,   871,   108,   44,    
++    271,   309,   935,   79,    53,    1735,  245,   711,   271,   615,   
++    271,   2343,  1007,  42,    44,    42,    1703,  492,   245,   655,   
++    333,   76,    42,    1447,  106,   140,   74,    76,    85,    34,    
++    149,   807,   333,   108,   1159,  172,   42,    268,   333,   149,   
++    76,    42,    1543,  106,   300,   74,    135,   149,   333,   1383,  
++    44,    42,    44,    74,    204,   42,    44,    333,   28135, 3182,  
++    149,   34279, 18215, 2215,  39,    1482,  140,   422,   71,    7898,  
++    1274,  1946,  74,    108,   122,   202,   258,   268,   90,    236,   
++    986,   140,   1562,  2138,  108,   58,    2810,  591,   841,   837,   
++    841,   229,   581,   841,   837,   41,    73,    41,    73,    137,   
++    265,   133,   37,    229,   357,   841,   837,   73,    137,   265,   
++    233,   837,   73,    137,   169,   41,    233,   837,   841,   837,   
++    841,   837,   841,   837,   841,   837,   841,   837,   841,   901,   
++    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
++    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
++    809,   57,    805,   57,    197,   94,    1613,  135,   871,   71,    
++    39,    39,    327,   135,   39,    39,    39,    39,    39,    39,    
++    103,   71,    39,    39,    39,    39,    39,    39,    71,    39,    
++    135,   231,   135,   135,   39,    327,   551,   103,   167,   551,   
++    89,    1434,  3226,  506,   474,   506,   506,   367,   1018,  1946,  
++    1402,  954,   1402,  314,   90,    1082,  218,   2266,  666,   1210,  
++    186,   570,   2042,  58,    5850,  154,   2010,  154,   794,   2266,  
++    378,   2266,  3738,  39,    39,    39,    39,    39,    39,    17351, 
++    34,    3074,  7692,  63,    63,    
++  };
++
++static int sqlite3Fts5UnicodeCategory(int iCode) { 
++  int iRes = -1;
++  int iHi;
++  int iLo;
++  int ret;
++  u16 iKey;
++
++  if( iCode>=(1<<20) ){
++    return 0;
++  }
++  iLo = aFts5UnicodeBlock[(iCode>>16)];
++  iHi = aFts5UnicodeBlock[1+(iCode>>16)];
++  iKey = (iCode & 0xFFFF);
++  while( iHi>iLo ){
++    int iTest = (iHi + iLo) / 2;
++    assert( iTest>=iLo && iTest<iHi );
++    if( iKey>=aFts5UnicodeMap[iTest] ){
++      iRes = iTest;
++      iLo = iTest+1;
++    }else{
++      iHi = iTest;
++    }
++  }
++
++  if( iRes<0 ) return 0;
++  if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
++  ret = aFts5UnicodeData[iRes] & 0x1F;
++  if( ret!=30 ) return ret;
++  return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9;
++}
++
++static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
++  int i = 0;
++  int iTbl = 0;
++  while( i<128 ){
++    int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
++    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
++    for(; i<128 && i<n; i++){
++      aAscii[i] = (u8)bToken;
++    }
++    iTbl++;
++  }
++}
++
++
+ /*
+ ** 2015 May 30
+ **
+@@ -209294,6 +219884,8 @@
+   i64 *pp = &pCsr->iInstPos;
+   int *po = &pCsr->iInstOff;
+   
++  assert( sqlite3Fts5IterEof(pIter)==0 );
++  assert( pCsr->bEof==0 );
+   while( eDetail==FTS5_DETAIL_NONE
+       || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) 
+   ){
+@@ -209303,7 +219895,7 @@
+     rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+     if( rc==SQLITE_OK ){
+       rc = fts5VocabInstanceNewTerm(pCsr);
+-      if( eDetail==FTS5_DETAIL_NONE ) break;
++      if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
+     }
+     if( rc ){
+       pCsr->bEof = 1;
+@@ -209618,6 +220210,7 @@
+     /* xSavepoint    */ 0,
+     /* xRelease      */ 0,
+     /* xRollbackTo   */ 0,
++    /* xShadowName   */ 0
+   };
+   void *p = (void*)pGlobal;
+ 
+@@ -209625,8 +220218,6 @@
+ }
+ 
+ 
+-
+-
+     
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
+ 
+@@ -209900,6 +220491,7 @@
+   0,                         /* xSavepoint */
+   0,                         /* xRelease */
+   0,                         /* xRollbackTo */
++  0,                         /* xShadowName */
+ };
+ 
+ #endif /* SQLITE_OMIT_VIRTUALTABLE */
+@@ -209932,9 +220524,9 @@
+ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
+ 
+ /************** End of stmt.c ************************************************/
+-#if __LINE__!=209935
++#if __LINE__!=220527
+ #undef SQLITE_SOURCE_ID
+-#define SQLITE_SOURCE_ID      "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd14alt2"
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
+ #endif
+ /* Return the source-id for this library */
+ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+--- contrib/sqlite3/sqlite3.h.orig
++++ contrib/sqlite3/sqlite3.h
+@@ -123,9 +123,9 @@
+ ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
+ ** [sqlite_version()] and [sqlite_source_id()].
+ */
+-#define SQLITE_VERSION        "3.23.1"
+-#define SQLITE_VERSION_NUMBER 3023001
+-#define SQLITE_SOURCE_ID      "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b"
++#define SQLITE_VERSION        "3.26.0"
++#define SQLITE_VERSION_NUMBER 3026000
++#define SQLITE_SOURCE_ID      "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
+ 
+ /*
+ ** CAPI3REF: Run-Time Library Version Numbers
+@@ -472,6 +472,7 @@
+ */
+ #define SQLITE_ERROR_MISSING_COLLSEQ   (SQLITE_ERROR | (1<<8))
+ #define SQLITE_ERROR_RETRY             (SQLITE_ERROR | (2<<8))
++#define SQLITE_ERROR_SNAPSHOT          (SQLITE_ERROR | (3<<8))
+ #define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+ #define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+ #define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+@@ -504,6 +505,7 @@
+ #define SQLITE_IOERR_COMMIT_ATOMIC     (SQLITE_IOERR | (30<<8))
+ #define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8))
+ #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
++#define SQLITE_LOCKED_VTAB             (SQLITE_LOCKED |  (2<<8))
+ #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+ #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
+ #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+@@ -510,7 +512,9 @@
+ #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
+ #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
+ #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
++#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+ #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
++#define SQLITE_CORRUPT_SEQUENCE        (SQLITE_CORRUPT | (2<<8))
+ #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
+ #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
+ #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
+@@ -884,7 +888,8 @@
+ ** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
+ ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
+ ** persistent [WAL | Write Ahead Log] setting.  By default, the auxiliary
+-** write ahead log and shared memory files used for transaction control
++** write ahead log ([WAL file]) and shared memory
++** files used for transaction control
+ ** are automatically deleted when the latest connection to the database
+ ** closes.  Setting persistent WAL mode causes those files to persist after
+ ** close.  Persisting the files is useful when other processes that do not
+@@ -1070,6 +1075,26 @@
+ ** a file lock using the xLock or xShmLock methods of the VFS to wait
+ ** for up to M milliseconds before failing, where M is the single 
+ ** unsigned integer parameter.
++**
++** <li>[[SQLITE_FCNTL_DATA_VERSION]]
++** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
++** a database file.  The argument is a pointer to a 32-bit unsigned integer.
++** The "data version" for the pager is written into the pointer.  The
++** "data version" changes whenever any change occurs to the corresponding
++** database file, either through SQL statements on the same database
++** connection or through transactions committed by separate database
++** connections possibly in other processes. The [sqlite3_total_changes()]
++** interface can be used to find if any database on the connection has changed,
++** but that interface responds to changes on TEMP as well as MAIN and does
++** not provide a mechanism to detect changes to MAIN only.  Also, the
++** [sqlite3_total_changes()] interface responds to internal changes only and
++** omits changes made by other database connections.  The
++** [PRAGMA data_version] command provide a mechanism to detect changes to
++** a single attached database that occur due to other database connections,
++** but omits changes implemented by the database connection on which it is
++** called.  This file control is the only mechanism to detect changes that
++** happen either internally or externally and that are associated with
++** a particular attached database.
+ ** </ul>
+ */
+ #define SQLITE_FCNTL_LOCKSTATE               1
+@@ -1105,6 +1130,7 @@
+ #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
+ #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
+ #define SQLITE_FCNTL_LOCK_TIMEOUT           34
++#define SQLITE_FCNTL_DATA_VERSION           35
+ 
+ /* deprecated names */
+ #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+@@ -1930,6 +1956,22 @@
+ ** I/O required to support statement rollback.
+ ** The default value for this setting is controlled by the
+ ** [SQLITE_STMTJRNL_SPILL] compile-time option.
++**
++** [[SQLITE_CONFIG_SORTERREF_SIZE]]
++** <dt>SQLITE_CONFIG_SORTERREF_SIZE
++** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
++** of type (int) - the new value of the sorter-reference size threshold.
++** Usually, when SQLite uses an external sort to order records according
++** to an ORDER BY clause, all fields required by the caller are present in the
++** sorted records. However, if SQLite determines based on the declared type
++** of a table column that its values are likely to be very large - larger
++** than the configured sorter-reference size threshold - then a reference
++** is stored in each sorted record and the required column values loaded
++** from the database as records are returned in sorted order. The default
++** value for this option is to never use this optimization. Specifying a 
++** negative value for this option restores the default behaviour.
++** This option is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
+ ** </dl>
+ */
+ #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
+@@ -1959,6 +2001,7 @@
+ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
+ #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
+ #define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
++#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+ 
+ /*
+ ** CAPI3REF: Database Connection Configuration Options
+@@ -1974,6 +2017,7 @@
+ ** is invoked.
+ **
+ ** <dl>
++** [[SQLITE_DBCONFIG_LOOKASIDE]]
+ ** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
+ ** <dd> ^This option takes three additional arguments that determine the 
+ ** [lookaside memory allocator] configuration for the [database connection].
+@@ -1996,6 +2040,7 @@
+ ** memory is in use leaves the configuration unchanged and returns 
+ ** [SQLITE_BUSY].)^</dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
+ ** <dd> ^This option is used to enable or disable the enforcement of
+ ** [foreign key constraints].  There should be two additional arguments.
+@@ -2006,6 +2051,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the FK enforcement setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
+ ** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
+ ** There should be two additional arguments.
+@@ -2016,6 +2062,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the trigger setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
+ ** <dd> ^This option is used to enable or disable the two-argument
+ ** version of the [fts3_tokenizer()] function which is part of the
+@@ -2029,6 +2076,7 @@
+ ** following this call.  The second parameter may be a NULL pointer, in
+ ** which case the new setting is not reported back. </dd>
+ **
++** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
+ ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt>
+ ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()]
+ ** interface independently of the [load_extension()] SQL function.
+@@ -2046,7 +2094,7 @@
+ ** be a NULL pointer, in which case the new setting is not reported back.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
++** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+ ** <dd> ^This option is used to change the name of the "main" database
+ ** schema.  ^The sole argument is a pointer to a constant UTF8 string
+ ** which will become the new schema name in place of "main".  ^SQLite
+@@ -2055,6 +2103,7 @@
+ ** until after the database connection closes.
+ ** </dd>
+ **
++** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] 
+ ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+ ** <dd> Usually, when a database in wal mode is closed or detached from a 
+ ** database handle, SQLite checks if this will mean that there are now no 
+@@ -2068,7 +2117,7 @@
+ ** have been disabled - 0 if they are not disabled, 1 if they are.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
++** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
+ ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
+ ** the [query planner stability guarantee] (QPSG).  When the QPSG is active,
+ ** a single SQL query statement will always use the same algorithm regardless
+@@ -2084,7 +2133,7 @@
+ ** following this call.
+ ** </dd>
+ **
+-** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
++** [[SQLITE_DBCONFIG_TRIGGER_EQP]] <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+ ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 
+ ** include output for any operations performed by trigger programs. This
+ ** option is used to set or clear (the default) a flag that governs this
+@@ -2095,6 +2144,39 @@
+ ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 
+ ** it is not disabled, 1 if it is.  
+ ** </dd>
++**
++** [[SQLITE_DBCONFIG_RESET_DATABASE]] <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
++** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
++** [VACUUM] in order to reset a database back to an empty database
++** with no schema and no content. The following process works even for
++** a badly corrupted database file:
++** <ol>
++** <li> If the database connection is newly opened, make sure it has read the
++**      database schema by preparing then discarding some query against the
++**      database, or calling sqlite3_table_column_metadata(), ignoring any
++**      errors.  This step is only necessary if the application desires to keep
++**      the database in WAL mode after the reset if it was in WAL mode before
++**      the reset.  
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
++** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
++** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
++** </ol>
++** Because resetting a database is destructive and irreversible, the
++** process requires the use of this obscure API and multiple steps to help
++** ensure that it does not happen by accident.
++**
++** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
++** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
++** "defensive" flag for a database connection.  When the defensive
++** flag is enabled, language features that allow ordinary SQL to 
++** deliberately corrupt the database file are disabled.  The disabled
++** features include but are not limited to the following:
++** <ul>
++** <li> The [PRAGMA writable_schema=ON] statement.
++** <li> Writes to the [sqlite_dbpage] virtual table.
++** <li> Direct writes to [shadow tables].
++** </ul>
++** </dd>
+ ** </dl>
+ */
+ #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
+@@ -2106,7 +2188,9 @@
+ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      1006 /* int int* */
+ #define SQLITE_DBCONFIG_ENABLE_QPSG           1007 /* int int* */
+ #define SQLITE_DBCONFIG_TRIGGER_EQP           1008 /* int int* */
+-#define SQLITE_DBCONFIG_MAX                   1008 /* Largest DBCONFIG */
++#define SQLITE_DBCONFIG_RESET_DATABASE        1009 /* int int* */
++#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
++#define SQLITE_DBCONFIG_MAX                   1010 /* Largest DBCONFIG */
+ 
+ /*
+ ** CAPI3REF: Enable Or Disable Extended Result Codes
+@@ -2234,12 +2318,17 @@
+ ** program, the value returned reflects the number of rows modified by the 
+ ** previous INSERT, UPDATE or DELETE statement within the same trigger.
+ **
+-** See also the [sqlite3_total_changes()] interface, the
+-** [count_changes pragma], and the [changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_changes()] is running then the value returned
+ ** is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_total_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** </ul>
+ */
+ SQLITE_API int sqlite3_changes(sqlite3*);
+ 
+@@ -2257,13 +2346,26 @@
+ ** count, but those made as part of REPLACE constraint resolution are
+ ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+ ** are not counted.
++**
++** This the [sqlite3_total_changes(D)] interface only reports the number
++** of rows that changed due to SQL statement run against database
++** connection D.  Any changes by other database connections are ignored.
++** To detect changes against a database file from other database
++** connections use the [PRAGMA data_version] command or the
++** [SQLITE_FCNTL_DATA_VERSION] [file control].
+ ** 
+-** See also the [sqlite3_changes()] interface, the
+-** [count_changes pragma], and the [total_changes() SQL function].
+-**
+ ** If a separate thread makes changes on the same database connection
+ ** while [sqlite3_total_changes()] is running then the value
+ ** returned is unpredictable and not meaningful.
++**
++** See also:
++** <ul>
++** <li> the [sqlite3_changes()] interface
++** <li> the [count_changes pragma]
++** <li> the [changes() SQL function]
++** <li> the [data_version pragma]
++** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
++** </ul>
+ */
+ SQLITE_API int sqlite3_total_changes(sqlite3*);
+ 
+@@ -3319,13 +3421,24 @@
+ ** [database connection] D failed, then the sqlite3_errcode(D) interface
+ ** returns the numeric [result code] or [extended result code] for that
+ ** API call.
+-** If the most recent API call was successful,
+-** then the return value from sqlite3_errcode() is undefined.
+ ** ^The sqlite3_extended_errcode()
+ ** interface is the same except that it always returns the 
+ ** [extended result code] even when extended result codes are
+ ** disabled.
+ **
++** The values returned by sqlite3_errcode() and/or
++** sqlite3_extended_errcode() might change with each API call.
++** Except, there are some interfaces that are guaranteed to never
++** change the value of the error code.  The error-code preserving
++** interfaces are:
++**
++** <ul>
++** <li> sqlite3_errcode()
++** <li> sqlite3_extended_errcode()
++** <li> sqlite3_errmsg()
++** <li> sqlite3_errmsg16()
++** </ul>
++**
+ ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
+ ** text that describes the error, as either UTF-8 or UTF-16 respectively.
+ ** ^(Memory to hold the error message string is managed internally.
+@@ -3515,9 +3628,19 @@
+ ** on this hint by avoiding the use of [lookaside memory] so as not to
+ ** deplete the limited store of lookaside memory. Future versions of
+ ** SQLite may act on this hint differently.
++**
++** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
++** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
++** representation of the SQL statement should be calculated and then
++** associated with the prepared statement, which can be obtained via
++** the [sqlite3_normalized_sql()] interface.)^  The semantics used to
++** normalize a SQL statement are unspecified and subject to change.
++** At a minimum, literal values will be replaced with suitable
++** placeholders.
+ ** </dl>
+ */
+ #define SQLITE_PREPARE_PERSISTENT              0x01
++#define SQLITE_PREPARE_NORMALIZE               0x02
+ 
+ /*
+ ** CAPI3REF: Compiling An SQL Statement
+@@ -3675,6 +3798,11 @@
+ ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
+ ** string containing the SQL text of prepared statement P with
+ ** [bound parameters] expanded.
++** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
++** string containing the normalized SQL text of prepared statement P.  The
++** semantics used to normalize a SQL statement are unspecified and subject
++** to change.  At a minimum, literal values will be replaced with suitable
++** placeholders.
+ **
+ ** ^(For example, if a prepared statement is created using the SQL
+ ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
+@@ -3690,8 +3818,9 @@
+ ** bound parameter expansions.  ^The [SQLITE_OMIT_TRACE] compile-time
+ ** option causes sqlite3_expanded_sql() to always return NULL.
+ **
+-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
+-** automatically freed when the prepared statement is finalized.
++** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
++** are managed by SQLite and are automatically freed when the prepared
++** statement is finalized.
+ ** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
+ ** is obtained from [sqlite3_malloc()] and must be free by the application
+ ** by passing it to [sqlite3_free()].
+@@ -3698,6 +3827,7 @@
+ */
+ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
++SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
+ 
+ /*
+ ** CAPI3REF: Determine If An SQL Statement Writes The Database
+@@ -4479,11 +4609,25 @@
+ ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+ ** [sqlite3_free()].
+ **
+-** ^(If a memory allocation error occurs during the evaluation of any
+-** of these routines, a default value is returned.  The default value
+-** is either the integer 0, the floating point number 0.0, or a NULL
+-** pointer.  Subsequent calls to [sqlite3_errcode()] will return
+-** [SQLITE_NOMEM].)^
++** As long as the input parameters are correct, these routines will only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_column_blob()
++** <li> sqlite3_column_text()
++** <li> sqlite3_column_text16()
++** <li> sqlite3_column_bytes()
++** <li> sqlite3_column_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+ SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+@@ -4560,11 +4704,13 @@
+ **
+ ** ^These functions (collectively known as "function creation routines")
+ ** are used to add SQL functions or aggregates or to redefine the behavior
+-** of existing SQL functions or aggregates.  The only differences between
+-** these routines are the text encoding expected for
+-** the second parameter (the name of the function being created)
+-** and the presence or absence of a destructor callback for
+-** the application data pointer.
++** of existing SQL functions or aggregates. The only differences between
++** the three "sqlite3_create_function*" routines are the text encoding 
++** expected for the second parameter (the name of the function being 
++** created) and the presence or absence of a destructor callback for
++** the application data pointer. Function sqlite3_create_window_function()
++** is similar, but allows the user to supply the extra callback functions
++** needed by [aggregate window functions].
+ **
+ ** ^The first parameter is the [database connection] to which the SQL
+ ** function is to be added.  ^If an application uses more than one database
+@@ -4610,7 +4756,8 @@
+ ** ^(The fifth parameter is an arbitrary pointer.  The implementation of the
+ ** function can gain access to this pointer using [sqlite3_user_data()].)^
+ **
+-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
++** ^The sixth, seventh and eighth parameters passed to the three
++** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
+ ** pointers to C-language functions that implement the SQL function or
+ ** aggregate. ^A scalar SQL function requires an implementation of the xFunc
+ ** callback only; NULL pointers must be passed as the xStep and xFinal
+@@ -4619,16 +4766,25 @@
+ ** SQL function or aggregate, pass NULL pointers for all three function
+ ** callbacks.
+ **
+-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
+-** then it is destructor for the application data pointer. 
+-** The destructor is invoked when the function is deleted, either by being
+-** overloaded or when the database connection closes.)^
+-** ^The destructor is also invoked if the call to
+-** sqlite3_create_function_v2() fails.
+-** ^When the destructor callback of the tenth parameter is invoked, it
+-** is passed a single argument which is a copy of the application data 
+-** pointer which was the fifth parameter to sqlite3_create_function_v2().
++** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue 
++** and xInverse) passed to sqlite3_create_window_function are pointers to
++** C-language callbacks that implement the new function. xStep and xFinal
++** must both be non-NULL. xValue and xInverse may either both be NULL, in
++** which case a regular aggregate function is created, or must both be 
++** non-NULL, in which case the new function may be used as either an aggregate
++** or aggregate window function. More details regarding the implementation
++** of aggregate window functions are 
++** [user-defined window functions|available here].
+ **
++** ^(If the final parameter to sqlite3_create_function_v2() or
++** sqlite3_create_window_function() is not NULL, then it is destructor for
++** the application data pointer. The destructor is invoked when the function 
++** is deleted, either by being overloaded or when the database connection 
++** closes.)^ ^The destructor is also invoked if the call to 
++** sqlite3_create_function_v2() fails.  ^When the destructor callback is
++** invoked, it is passed a single argument which is a copy of the application
++** data pointer which was the fifth parameter to sqlite3_create_function_v2().
++**
+ ** ^It is permitted to register multiple implementations of the same
+ ** functions with the same name but with either differing numbers of
+ ** arguments or differing preferred text encodings.  ^SQLite will use
+@@ -4680,6 +4836,18 @@
+   void (*xFinal)(sqlite3_context*),
+   void(*xDestroy)(void*)
+ );
++SQLITE_API int sqlite3_create_window_function(
++  sqlite3 *db,
++  const char *zFunctionName,
++  int nArg,
++  int eTextRep,
++  void *pApp,
++  void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++  void (*xFinal)(sqlite3_context*),
++  void (*xValue)(sqlite3_context*),
++  void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
++  void(*xDestroy)(void*)
++);
+ 
+ /*
+ ** CAPI3REF: Text Encodings
+@@ -4822,6 +4990,28 @@
+ **
+ ** These routines must be called from the same thread as
+ ** the SQL function that supplied the [sqlite3_value*] parameters.
++**
++** As long as the input parameter is correct, these routines can only
++** fail if an out-of-memory error occurs during a format conversion.
++** Only the following subset of interfaces are subject to out-of-memory
++** errors:
++**
++** <ul>
++** <li> sqlite3_value_blob()
++** <li> sqlite3_value_text()
++** <li> sqlite3_value_text16()
++** <li> sqlite3_value_text16le()
++** <li> sqlite3_value_text16be()
++** <li> sqlite3_value_bytes()
++** <li> sqlite3_value_bytes16()
++** </ul>
++**
++** If an out-of-memory error occurs, then the return value from these
++** routines is the same as if the column had contained an SQL NULL value.
++** Valid SQL NULL returns can be distinguished from out-of-memory errors
++** by invoking the [sqlite3_errcode()] immediately after the suspect
++** return value is obtained and before any
++** other SQLite interface is called on the same [database connection].
+ */
+ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+ SQLITE_API double sqlite3_value_double(sqlite3_value*);
+@@ -5493,6 +5683,41 @@
+ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
+ 
+ /*
++** CAPI3REF: Win32 Specific Interface
++**
++** These interfaces are available only on Windows.  The
++** [sqlite3_win32_set_directory] interface is used to set the value associated
++** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
++** zValue, depending on the value of the type parameter.  The zValue parameter
++** should be NULL to cause the previous value to be freed via [sqlite3_free];
++** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
++** prior to being used.  The [sqlite3_win32_set_directory] interface returns
++** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
++** or [SQLITE_NOMEM] if memory could not be allocated.  The value of the
++** [sqlite3_data_directory] variable is intended to act as a replacement for
++** the current directory on the sub-platforms of Win32 where that concept is
++** not present, e.g. WinRT and UWP.  The [sqlite3_win32_set_directory8] and
++** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
++** sqlite3_win32_set_directory interface except the string parameter must be
++** UTF-8 or UTF-16, respectively.
++*/
++SQLITE_API int sqlite3_win32_set_directory(
++  unsigned long type, /* Identifier for directory being set or reset */
++  void *zValue        /* New value for directory being set or reset */
++);
++SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
++SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
++
++/*
++** CAPI3REF: Win32 Directory Types
++**
++** These macros are only available on Windows.  They define the allowed values
++** for the type argument to the [sqlite3_win32_set_directory] interface.
++*/
++#define SQLITE_WIN32_DATA_DIRECTORY_TYPE  1
++#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE  2
++
++/*
+ ** CAPI3REF: Test For Auto-Commit Mode
+ ** KEYWORDS: {autocommit mode}
+ ** METHOD: sqlite3
+@@ -6092,6 +6317,9 @@
+   int (*xSavepoint)(sqlite3_vtab *pVTab, int);
+   int (*xRelease)(sqlite3_vtab *pVTab, int);
+   int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
++  /* The methods above are in versions 1 and 2 of the sqlite_module object.
++  ** Those below are for version 3 and greater. */
++  int (*xShadowName)(const char*);
+ };
+ 
+ /*
+@@ -6224,6 +6452,10 @@
+ 
+ /*
+ ** CAPI3REF: Virtual Table Scan Flags
++**
++** Virtual table implementations are allowed to set the 
++** [sqlite3_index_info].idxFlags field to some combination of
++** these bits.
+ */
+ #define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
+ 
+@@ -6249,6 +6481,7 @@
+ #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+ #define SQLITE_INDEX_CONSTRAINT_ISNULL    71
+ #define SQLITE_INDEX_CONSTRAINT_IS        72
++#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
+ 
+ /*
+ ** CAPI3REF: Register A Virtual Table Implementation
+@@ -6925,6 +7158,7 @@
+ /*
+ ** CAPI3REF: Low-Level Control Of Database Files
+ ** METHOD: sqlite3
++** KEYWORDS: {file control}
+ **
+ ** ^The [sqlite3_file_control()] interface makes a direct call to the
+ ** xFileControl method for the [sqlite3_io_methods] object associated
+@@ -6939,11 +7173,18 @@
+ ** the xFileControl method.  ^The return value of the xFileControl
+ ** method becomes the return value of this routine.
+ **
++** A few opcodes for [sqlite3_file_control()] are handled directly
++** by the SQLite core and never invoke the 
++** sqlite3_io_methods.xFileControl method.
+ ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
+ ** a pointer to the underlying [sqlite3_file] object to be written into
+-** the space pointed to by the 4th parameter.  ^The [SQLITE_FCNTL_FILE_POINTER]
+-** case is a short-circuit path which does not actually invoke the
+-** underlying sqlite3_io_methods.xFileControl method.
++** the space pointed to by the 4th parameter.  The
++** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
++** the [sqlite3_file] object associated with the journal file instead of
++** the main database.  The [SQLITE_FCNTL_VFS_POINTER] opcode returns
++** a pointer to the underlying [sqlite3_vfs] object for the file.
++** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
++** from the pager.
+ **
+ ** ^If the second parameter (zDbName) does not match the name of any
+ ** open database file, then SQLITE_ERROR is returned.  ^This error
+@@ -6999,8 +7240,9 @@
+ #define SQLITE_TESTCTRL_ALWAYS                  13
+ #define SQLITE_TESTCTRL_RESERVE                 14
+ #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
+-#define SQLITE_TESTCTRL_ISKEYWORD               16
++#define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */
+ #define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */
++#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS      17
+ #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
+ #define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
+ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD    19
+@@ -7014,6 +7256,189 @@
+ #define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+ 
+ /*
++** CAPI3REF: SQL Keyword Checking
++**
++** These routines provide access to the set of SQL language keywords 
++** recognized by SQLite.  Applications can uses these routines to determine
++** whether or not a specific identifier needs to be escaped (for example,
++** by enclosing in double-quotes) so as not to confuse the parser.
++**
++** The sqlite3_keyword_count() interface returns the number of distinct
++** keywords understood by SQLite.
++**
++** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
++** makes *Z point to that keyword expressed as UTF8 and writes the number
++** of bytes in the keyword into *L.  The string that *Z points to is not
++** zero-terminated.  The sqlite3_keyword_name(N,Z,L) routine returns
++** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
++** or L are NULL or invalid pointers then calls to
++** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
++**
++** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
++** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
++** if it is and zero if not.
++**
++** The parser used by SQLite is forgiving.  It is often possible to use
++** a keyword as an identifier as long as such use does not result in a
++** parsing ambiguity.  For example, the statement
++** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
++** creates a new table named "BEGIN" with three columns named
++** "REPLACE", "PRAGMA", and "END".  Nevertheless, best practice is to avoid
++** using keywords as identifiers.  Common techniques used to avoid keyword
++** name collisions include:
++** <ul>
++** <li> Put all identifier names inside double-quotes.  This is the official
++**      SQL way to escape identifier names.
++** <li> Put identifier names inside &#91;...&#93;.  This is not standard SQL,
++**      but it is what SQL Server does and so lots of programmers use this
++**      technique.
++** <li> Begin every identifier with the letter "Z" as no SQL keywords start
++**      with "Z".
++** <li> Include a digit somewhere in every identifier name.
++** </ul>
++**
++** Note that the number of keywords understood by SQLite can depend on
++** compile-time options.  For example, "VACUUM" is not a keyword if
++** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
++** new keywords may be added to future releases of SQLite.
++*/
++SQLITE_API int sqlite3_keyword_count(void);
++SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
++SQLITE_API int sqlite3_keyword_check(const char*,int);
++
++/*
++** CAPI3REF: Dynamic String Object
++** KEYWORDS: {dynamic string}
++**
++** An instance of the sqlite3_str object contains a dynamically-sized
++** string under construction.
++**
++** The lifecycle of an sqlite3_str object is as follows:
++** <ol>
++** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
++** <li> ^Text is appended to the sqlite3_str object using various
++** methods, such as [sqlite3_str_appendf()].
++** <li> ^The sqlite3_str object is destroyed and the string it created
++** is returned using the [sqlite3_str_finish()] interface.
++** </ol>
++*/
++typedef struct sqlite3_str sqlite3_str;
++
++/*
++** CAPI3REF: Create A New Dynamic String Object
++** CONSTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_new(D)] interface allocates and initializes
++** a new [sqlite3_str] object.  To avoid memory leaks, the object returned by
++** [sqlite3_str_new()] must be freed by a subsequent call to 
++** [sqlite3_str_finish(X)].
++**
++** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
++** valid [sqlite3_str] object, though in the event of an out-of-memory
++** error the returned object might be a special singleton that will
++** silently reject new text, always return SQLITE_NOMEM from 
++** [sqlite3_str_errcode()], always return 0 for 
++** [sqlite3_str_length()], and always return NULL from
++** [sqlite3_str_finish(X)].  It is always safe to use the value
++** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
++** to any of the other [sqlite3_str] methods.
++**
++** The D parameter to [sqlite3_str_new(D)] may be NULL.  If the
++** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
++** length of the string contained in the [sqlite3_str] object will be
++** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
++** of [SQLITE_MAX_LENGTH].
++*/
++SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
++
++/*
++** CAPI3REF: Finalize A Dynamic String
++** DESTRUCTOR: sqlite3_str
++**
++** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
++** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
++** that contains the constructed string.  The calling application should
++** pass the returned value to [sqlite3_free()] to avoid a memory leak.
++** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
++** errors were encountered during construction of the string.  ^The
++** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
++** string in [sqlite3_str] object X is zero bytes long.
++*/
++SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
++
++/*
++** CAPI3REF: Add Content To A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces add content to an sqlite3_str object previously obtained
++** from [sqlite3_str_new()].
++**
++** ^The [sqlite3_str_appendf(X,F,...)] and 
++** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
++** functionality of SQLite to append formatted text onto the end of 
++** [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
++** onto the end of the [sqlite3_str] object X.  N must be non-negative.
++** S must contain at least N non-zero bytes of content.  To append a
++** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
++** method instead.
++**
++** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
++** zero-terminated string S onto the end of [sqlite3_str] object X.
++**
++** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
++** single-byte character C onto the end of [sqlite3_str] object X.
++** ^This method can be used, for example, to add whitespace indentation.
++**
++** ^The [sqlite3_str_reset(X)] method resets the string under construction
++** inside [sqlite3_str] object X back to zero bytes in length.  
++**
++** These methods do not return a result code.  ^If an error occurs, that fact
++** is recorded in the [sqlite3_str] object and can be recovered by a
++** subsequent call to [sqlite3_str_errcode(X)].
++*/
++SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
++SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
++SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
++SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
++SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
++SQLITE_API void sqlite3_str_reset(sqlite3_str*);
++
++/*
++** CAPI3REF: Status Of A Dynamic String
++** METHOD: sqlite3_str
++**
++** These interfaces return the current status of an [sqlite3_str] object.
++**
++** ^If any prior errors have occurred while constructing the dynamic string
++** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
++** an appropriate error code.  ^The [sqlite3_str_errcode(X)] method returns
++** [SQLITE_NOMEM] following any out-of-memory error, or
++** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
++** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
++**
++** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
++** of the dynamic string under construction in [sqlite3_str] object X.
++** ^The length returned by [sqlite3_str_length(X)] does not include the
++** zero-termination byte.
++**
++** ^The [sqlite3_str_value(X)] method returns a pointer to the current
++** content of the dynamic string under construction in X.  The value
++** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
++** and might be freed or altered by any subsequent method on the same
++** [sqlite3_str] object.  Applications must not used the pointer returned
++** [sqlite3_str_value(X)] after any subsequent method call on the same
++** object.  ^Applications may change the content of the string returned
++** by [sqlite3_str_value(X)] as long as they do not write into any bytes
++** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
++** write any byte after any subsequent sqlite3_str method call.
++*/
++SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
++SQLITE_API int sqlite3_str_length(sqlite3_str*);
++SQLITE_API char *sqlite3_str_value(sqlite3_str*);
++
++/*
+ ** CAPI3REF: SQLite Runtime Status
+ **
+ ** ^These interfaces are used to retrieve runtime status information
+@@ -8230,6 +8655,7 @@
+ ** can use to customize and optimize their behavior.
+ **
+ ** <dl>
++** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
+ ** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
+ ** <dd>Calls of the form
+ ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
+@@ -8282,11 +8708,11 @@
+ ** method of a [virtual table], then it returns true if and only if the
+ ** column is being fetched as part of an UPDATE operation during which the
+ ** column value will not change.  Applications might use this to substitute
+-** a lighter-weight value to return that the corresponding [xUpdate] method
+-** understands as a "no-change" value.
++** a return value that is less expensive to compute and that the corresponding
++** [xUpdate] method understands as a "no-change" value.
+ **
+ ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+-** the column is not changed by the UPDATE statement, they the xColumn
++** the column is not changed by the UPDATE statement, then the xColumn
+ ** method can optionally return without setting a result, without calling
+ ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+ ** In that case, [sqlite3_value_nochange(X)] will return true for the
+@@ -8579,7 +9005,6 @@
+ /*
+ ** CAPI3REF: Database Snapshot
+ ** KEYWORDS: {snapshot} {sqlite3_snapshot}
+-** EXPERIMENTAL
+ **
+ ** An instance of the snapshot object records the state of a [WAL mode]
+ ** database for some specific point in history.
+@@ -8596,11 +9021,6 @@
+ ** version of the database file so that it is possible to later open a new read
+ ** transaction that sees that historical version of the database rather than
+ ** the most recent version.
+-**
+-** The constructor for this object is [sqlite3_snapshot_get()].  The
+-** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
+-** to an historical snapshot (if possible).  The destructor for 
+-** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
+ */
+ typedef struct sqlite3_snapshot {
+   unsigned char hidden[48];
+@@ -8608,7 +9028,7 @@
+ 
+ /*
+ ** CAPI3REF: Record A Database Snapshot
+-** EXPERIMENTAL
++** CONSTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
+ ** new [sqlite3_snapshot] object that records the current state of
+@@ -8624,7 +9044,7 @@
+ ** in this case. 
+ **
+ ** <ul>
+-**   <li> The database handle must be in [autocommit mode].
++**   <li> The database handle must not be in [autocommit mode].
+ **
+ **   <li> Schema S of [database connection] D must be a [WAL mode] database.
+ **
+@@ -8647,7 +9067,7 @@
+ ** to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_get()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
+   sqlite3 *db,
+@@ -8657,24 +9077,35 @@
+ 
+ /*
+ ** CAPI3REF: Start a read transaction on an historical snapshot
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
+-** read transaction for schema S of
+-** [database connection] D such that the read transaction
+-** refers to historical [snapshot] P, rather than the most
+-** recent change to the database.
+-** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
+-** or an appropriate [error code] if it fails.
++** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read 
++** transaction or upgrades an existing one for schema S of 
++** [database connection] D such that the read transaction refers to 
++** historical [snapshot] P, rather than the most recent change to the 
++** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK 
++** on success or an appropriate [error code] if it fails.
+ **
+-** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
+-** the first operation following the [BEGIN] that takes the schema S
+-** out of [autocommit mode].
+-** ^In other words, schema S must not currently be in
+-** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
+-** database connection D must be out of [autocommit mode].
+-** ^A [snapshot] will fail to open if it has been overwritten by a
+-** [checkpoint].
++** ^In order to succeed, the database connection must not be in 
++** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
++** is already a read transaction open on schema S, then the database handle
++** must have no active statements (SELECT statements that have been passed
++** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). 
++** SQLITE_ERROR is returned if either of these conditions is violated, or
++** if schema S does not exist, or if the snapshot object is invalid.
++**
++** ^A call to sqlite3_snapshot_open() will fail to open if the specified
++** snapshot has been overwritten by a [checkpoint]. In this case 
++** SQLITE_ERROR_SNAPSHOT is returned.
++**
++** If there is already a read transaction open when this function is 
++** invoked, then the same read transaction remains open (on the same
++** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
++** is returned. If another error code - for example SQLITE_PROTOCOL or an
++** SQLITE_IOERR error code - is returned, then the final state of the
++** read transaction is undefined. If SQLITE_OK is returned, then the 
++** read transaction is now open on database snapshot P.
++**
+ ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
+ ** database connection D does not know that the database file for
+ ** schema S is in [WAL mode].  A database connection might not know
+@@ -8685,7 +9116,7 @@
+ ** database connection in order to make it ready to use snapshots.)
+ **
+ ** The [sqlite3_snapshot_open()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
+   sqlite3 *db,
+@@ -8695,7 +9126,7 @@
+ 
+ /*
+ ** CAPI3REF: Destroy a snapshot
+-** EXPERIMENTAL
++** DESTRUCTOR: sqlite3_snapshot
+ **
+ ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
+ ** The application must eventually free every [sqlite3_snapshot] object
+@@ -8702,13 +9133,13 @@
+ ** using this routine to avoid a memory leak.
+ **
+ ** The [sqlite3_snapshot_free()] interface is only available when the
+-** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
++** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
+ 
+ /*
+ ** CAPI3REF: Compare the ages of two snapshot handles.
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+ ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
+ ** of two valid snapshot handles. 
+@@ -8727,6 +9158,9 @@
+ ** Otherwise, this API returns a negative value if P1 refers to an older
+ ** snapshot than P2, zero if the two handles refer to the same database
+ ** snapshot, and a positive value if P1 is a newer snapshot than P2.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
+   sqlite3_snapshot *p1,
+@@ -8735,23 +9169,26 @@
+ 
+ /*
+ ** CAPI3REF: Recover snapshots from a wal file
+-** EXPERIMENTAL
++** METHOD: sqlite3_snapshot
+ **
+-** If all connections disconnect from a database file but do not perform
+-** a checkpoint, the existing wal file is opened along with the database
+-** file the next time the database is opened. At this point it is only
+-** possible to successfully call sqlite3_snapshot_open() to open the most
+-** recent snapshot of the database (the one at the head of the wal file),
+-** even though the wal file may contain other valid snapshots for which
+-** clients have sqlite3_snapshot handles.
++** If a [WAL file] remains on disk after all database connections close
++** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
++** or because the last process to have the database opened exited without
++** calling [sqlite3_close()]) and a new connection is subsequently opened
++** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
++** will only be able to open the last transaction added to the WAL file
++** even though the WAL file contains other valid transactions.
+ **
+-** This function attempts to scan the wal file associated with database zDb
++** This function attempts to scan the WAL file associated with database zDb
+ ** of database handle db and make all valid snapshots available to
+ ** sqlite3_snapshot_open(). It is an error if there is already a read
+-** transaction open on the database, or if the database is not a wal mode
++** transaction open on the database, or if the database is not a WAL mode
+ ** database.
+ **
+ ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
++**
++** This interface is only available if SQLite is compiled with the
++** [SQLITE_ENABLE_SNAPSHOT] option.
+ */
+ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+ 
+@@ -8781,7 +9218,7 @@
+ ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
+ ** values of D and S.
+ ** The size of the database is written into *P even if the 
+-** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
++** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
+ ** of the database exists.
+ **
+ ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
+@@ -8862,7 +9299,7 @@
+ ** in the P argument is held in memory obtained from [sqlite3_malloc64()]
+ ** and that SQLite should take ownership of this memory and automatically
+ ** free it when it has finished using it.  Without this flag, the caller
+-** is resposible for freeing any dynamically allocated memory.
++** is responsible for freeing any dynamically allocated memory.
+ **
+ ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
+ ** grow the size of the database using calls to [sqlite3_realloc64()].  This
+@@ -8988,7 +9425,7 @@
+   sqlite3_int64 iRowid;             /* Rowid for current entry */
+   sqlite3_rtree_dbl rParentScore;   /* Score of parent node */
+   int eParentWithin;                /* Visibility of parent node */
+-  int eWithin;                      /* OUT: Visiblity */
++  int eWithin;                      /* OUT: Visibility */
+   sqlite3_rtree_dbl rScore;         /* OUT: Write the score here */
+   /* The following fields are only available in 3.8.11 and later */
+   sqlite3_value **apSqlParam;       /* Original SQL values of parameters */
+@@ -9484,6 +9921,13 @@
+ ** consecutively. There is no chance that the iterator will visit a change 
+ ** the applies to table X, then one for table Y, and then later on visit 
+ ** another change for table X.
++**
++** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
++** may be modified by passing a combination of
++** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
++**
++** Note that the sqlite3changeset_start_v2() API is still <b>experimental</b>
++** and therefore subject to change.
+ */
+ SQLITE_API int sqlite3changeset_start(
+   sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
+@@ -9490,8 +9934,27 @@
+   int nChangeset,                 /* Size of changeset blob in bytes */
+   void *pChangeset                /* Pointer to blob containing changeset */
+ );
++SQLITE_API int sqlite3changeset_start_v2(
++  sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
++  int nChangeset,                 /* Size of changeset blob in bytes */
++  void *pChangeset,               /* Pointer to blob containing changeset */
++  int flags                       /* SESSION_CHANGESETSTART_* flags */
++);
+ 
++/*
++** CAPI3REF: Flags for sqlite3changeset_start_v2
++**
++** The following flags may passed via the 4th parameter to
++** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset while iterating through it. This is equivalent to
++**   inverting a changeset using sqlite3changeset_invert() before applying it.
++**   It is an error to specify this flag with a patchset.
++*/
++#define SQLITE_CHANGESETSTART_INVERT        0x0002
+ 
++
+ /*
+ ** CAPI3REF: Advance A Changeset Iterator
+ ** METHOD: sqlite3_changeset_iter
+@@ -10144,7 +10607,7 @@
+   ),
+   void *pCtx,                     /* First argument passed to xConflict */
+   void **ppRebase, int *pnRebase, /* OUT: Rebase data */
+-  int flags                       /* Combination of SESSION_APPLY_* flags */
++  int flags                       /* SESSION_CHANGESETAPPLY_* flags */
+ );
+ 
+ /*
+@@ -10162,8 +10625,14 @@
+ **   causes the sessions module to omit this savepoint. In this case, if the
+ **   caller has an open transaction or savepoint when apply_v2() is called, 
+ **   it may revert the partially applied changeset by rolling it back.
++**
++** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
++**   Invert the changeset before applying it. This is equivalent to inverting
++**   a changeset using sqlite3changeset_invert() before applying it. It is
++**   an error to specify this flag with a patchset.
+ */
+ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
++#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
+ 
+ /* 
+ ** CAPI3REF: Constants Passed To The Conflict Handler
+@@ -10557,6 +11026,12 @@
+   int (*xInput)(void *pIn, void *pData, int *pnData),
+   void *pIn
+ );
++SQLITE_API int sqlite3changeset_start_v2_strm(
++  sqlite3_changeset_iter **pp,
++  int (*xInput)(void *pIn, void *pData, int *pnData),
++  void *pIn,
++  int flags
++);
+ SQLITE_API int sqlite3session_changeset_strm(
+   sqlite3_session *pSession,
+   int (*xOutput)(void *pOut, const void *pData, int nData),
+@@ -10583,8 +11058,47 @@
+   void *pOut
+ );
+ 
++/*
++** CAPI3REF: Configure global parameters
++**
++** The sqlite3session_config() interface is used to make global configuration
++** changes to the sessions module in order to tune it to the specific needs 
++** of the application.
++**
++** The sqlite3session_config() interface is not threadsafe. If it is invoked
++** while any other thread is inside any other sessions method then the
++** results are undefined. Furthermore, if it is invoked after any sessions
++** related objects have been created, the results are also undefined. 
++**
++** The first argument to the sqlite3session_config() function must be one
++** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The 
++** interpretation of the (void*) value passed as the second parameter and
++** the effect of calling this function depends on the value of the first
++** parameter.
++**
++** <dl>
++** <dt>SQLITE_SESSION_CONFIG_STRMSIZE<dd>
++**    By default, the sessions module streaming interfaces attempt to input
++**    and output data in approximately 1 KiB chunks. This operand may be used
++**    to set and query the value of this configuration setting. The pointer
++**    passed as the second argument must point to a value of type (int).
++**    If this value is greater than 0, it is used as the new streaming data
++**    chunk size for both input and output. Before returning, the (int) value
++**    pointed to by pArg is set to the final value of the streaming interface
++**    chunk size.
++** </dl>
++**
++** This function returns SQLITE_OK if successful, or an SQLite error code
++** otherwise.
++*/
++SQLITE_API int sqlite3session_config(int op, void *pArg);
+ 
+ /*
++** CAPI3REF: Values for sqlite3session_config().
++*/
++#define SQLITE_SESSION_CONFIG_STRMSIZE 1
++
++/*
+ ** Make sure we can call this stuff from C++.
+ */
+ #ifdef __cplusplus
+@@ -11040,7 +11554,7 @@
+ **            This way, even if the tokenizer does not provide synonyms
+ **            when tokenizing query text (it should not - to do would be
+ **            inefficient), it doesn't matter if the user queries for 
+-**            'first + place' or '1st + place', as there are entires in the
++**            'first + place' or '1st + place', as there are entries in the
+ **            FTS index corresponding to both forms of the first token.
+ **   </ol>
+ **
+@@ -11068,7 +11582,7 @@
+ **   extra data to the FTS index or require FTS5 to query for multiple terms,
+ **   so it is efficient in terms of disk space and query speed. However, it
+ **   does not support prefix queries very well. If, as suggested above, the
+-**   token "first" is subsituted for "1st" by the tokenizer, then the query:
++**   token "first" is substituted for "1st" by the tokenizer, then the query:
+ **
+ **   <codeblock>
+ **     ... MATCH '1s*'</codeblock>
+--- contrib/sqlite3/sqlite3ext.h.orig
++++ contrib/sqlite3/sqlite3ext.h
+@@ -295,6 +295,30 @@
+   int (*vtab_nochange)(sqlite3_context*);
+   int (*value_nochange)(sqlite3_value*);
+   const char *(*vtab_collation)(sqlite3_index_info*,int);
++  /* Version 3.24.0 and later */
++  int (*keyword_count)(void);
++  int (*keyword_name)(int,const char**,int*);
++  int (*keyword_check)(const char*,int);
++  sqlite3_str *(*str_new)(sqlite3*);
++  char *(*str_finish)(sqlite3_str*);
++  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
++  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
++  void (*str_append)(sqlite3_str*, const char *zIn, int N);
++  void (*str_appendall)(sqlite3_str*, const char *zIn);
++  void (*str_appendchar)(sqlite3_str*, int N, char C);
++  void (*str_reset)(sqlite3_str*);
++  int (*str_errcode)(sqlite3_str*);
++  int (*str_length)(sqlite3_str*);
++  char *(*str_value)(sqlite3_str*);
++  /* Version 3.25.0 and later */
++  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
++                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
++                            void (*xFinal)(sqlite3_context*),
++                            void (*xValue)(sqlite3_context*),
++                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
++                            void(*xDestroy)(void*));
++  /* Version 3.26.0 and later */
++  const char *(*normalized_sql)(sqlite3_stmt*);
+ };
+ 
+ /*
+@@ -565,6 +589,25 @@
+ #define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
+ #define sqlite3_value_nochange         sqlite3_api->value_nochange
+ #define sqlite3_vtab_collation         sqlite3_api->vtab_collation
++/* Version 3.24.0 and later */
++#define sqlite3_keyword_count          sqlite3_api->keyword_count
++#define sqlite3_keyword_name           sqlite3_api->keyword_name
++#define sqlite3_keyword_check          sqlite3_api->keyword_check
++#define sqlite3_str_new                sqlite3_api->str_new
++#define sqlite3_str_finish             sqlite3_api->str_finish
++#define sqlite3_str_appendf            sqlite3_api->str_appendf
++#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
++#define sqlite3_str_append             sqlite3_api->str_append
++#define sqlite3_str_appendall          sqlite3_api->str_appendall
++#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
++#define sqlite3_str_reset              sqlite3_api->str_reset
++#define sqlite3_str_errcode            sqlite3_api->str_errcode
++#define sqlite3_str_length             sqlite3_api->str_length
++#define sqlite3_str_value              sqlite3_api->str_value
++/* Version 3.25.0 and later */
++#define sqlite3_create_window_function sqlite3_api->create_window_function
++/* Version 3.26.0 and later */
++#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
+ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+ 
+ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+--- contrib/sqlite3/tea/Makefile.in.orig
++++ contrib/sqlite3/tea/Makefile.in
+@@ -0,0 +1,440 @@
++# Makefile.in --
++#
++#	This file is a Makefile for Sample TEA Extension.  If it has the name
++#	"Makefile.in" then it is a template for a Makefile;  to generate the
++#	actual Makefile, run "./configure", which is a configuration script
++#	generated by the "autoconf" program (constructs like "@foo@" will get
++#	replaced in the actual Makefile.
++#
++# Copyright (c) 1999 Scriptics Corporation.
++# Copyright (c) 2002-2005 ActiveState Corporation.
++#
++# See the file "license.terms" for information on usage and redistribution
++# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
++#
++# RCS: @(#) $Id: Makefile.in,v 1.59 2005/07/26 19:17:02 mdejong Exp $
++
++#========================================================================
++# Add additional lines to handle any additional AC_SUBST cases that
++# have been added in a customized configure script.
++#========================================================================
++
++#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
++
++#========================================================================
++# Nothing of the variables below this line should need to be changed.
++# Please check the TARGETS section below to make sure the make targets
++# are correct.
++#========================================================================
++
++#========================================================================
++# The names of the source files is defined in the configure script.
++# The object files are used for linking into the final library.
++# This will be used when a dist target is added to the Makefile.
++# It is not important to specify the directory, as long as it is the
++# $(srcdir) or in the generic, win or unix subdirectory.
++#========================================================================
++
++PKG_SOURCES	= @PKG_SOURCES@
++PKG_OBJECTS	= @PKG_OBJECTS@
++
++PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
++PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
++
++#========================================================================
++# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
++# this package that need to be installed, if any.
++#========================================================================
++
++PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
++
++#========================================================================
++# This is a list of public header files to be installed, if any.
++#========================================================================
++
++PKG_HEADERS	= @PKG_HEADERS@
++
++#========================================================================
++# "PKG_LIB_FILE" refers to the library (dynamic or static as per
++# configuration options) composed of the named objects.
++#========================================================================
++
++PKG_LIB_FILE	= @PKG_LIB_FILE@
++PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
++
++lib_BINARIES	= $(PKG_LIB_FILE)
++BINARIES	= $(lib_BINARIES)
++
++SHELL		= @SHELL@
++
++srcdir		= @srcdir@
++prefix		= @prefix@
++exec_prefix	= @exec_prefix@
++
++bindir		= @bindir@
++libdir		= @libdir@
++datarootdir	= @datarootdir@
++datadir		= @datadir@
++mandir		= @mandir@
++includedir	= @includedir@
++
++DESTDIR		=
++
++PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
++pkgdatadir	= $(datadir)/$(PKG_DIR)
++pkglibdir	= $(libdir)/$(PKG_DIR)
++pkgincludedir	= $(includedir)/$(PKG_DIR)
++
++top_builddir	= .
++
++INSTALL		= @INSTALL@
++INSTALL_PROGRAM	= @INSTALL_PROGRAM@
++INSTALL_DATA	= @INSTALL_DATA@
++INSTALL_SCRIPT	= @INSTALL_SCRIPT@
++
++PACKAGE_NAME	= @PACKAGE_NAME@
++PACKAGE_VERSION	= @PACKAGE_VERSION@
++CC		= @CC@
++CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
++CFLAGS_WARNING	= @CFLAGS_WARNING@
++CLEANFILES	= @CLEANFILES@
++EXEEXT		= @EXEEXT@
++LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
++MAKE_LIB	= @MAKE_LIB@
++MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
++MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
++MAKE_STUB_LIB	= @MAKE_STUB_LIB@
++OBJEXT		= @OBJEXT@
++RANLIB		= @RANLIB@
++RANLIB_STUB	= @RANLIB_STUB@
++SHLIB_CFLAGS	= @SHLIB_CFLAGS@
++SHLIB_LD	= @SHLIB_LD@
++SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
++STLIB_LD	= @STLIB_LD@
++#TCL_DEFS	= @TCL_DEFS@
++TCL_BIN_DIR	= @TCL_BIN_DIR@
++TCL_SRC_DIR	= @TCL_SRC_DIR@
++#TK_BIN_DIR	= @TK_BIN_DIR@
++#TK_SRC_DIR	= @TK_SRC_DIR@
++
++# This is no longer necessary even for packages that use private Tcl headers
++#TCL_TOP_DIR_NATIVE	= @TCL_TOP_DIR_NATIVE@
++# Not used, but retained for reference of what libs Tcl required
++#TCL_LIBS	= @TCL_LIBS@
++
++#========================================================================
++# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
++# package without installing.  The other environment variables allow us
++# to test against an uninstalled Tcl.  Add special env vars that you
++# require for testing here (like TCLX_LIBRARY).
++#========================================================================
++
++EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
++#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
++TCLLIBPATH	= $(top_builddir)
++TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
++		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
++		  PATH="$(EXTRA_PATH):$(PATH)" \
++		  TCLLIBPATH="$(TCLLIBPATH)"
++#		  TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
++
++TCLSH_PROG	= @TCLSH_PROG@
++TCLSH	= $(TCLSH_ENV) $(TCLSH_PROG)
++
++#WISH_PROG	= @WISH_PROG@
++#WISH	= $(TCLSH_ENV) $(WISH_PROG)
++
++
++SHARED_BUILD	= @SHARED_BUILD@
++
++INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ -I$(srcdir)/..
++#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
++
++PKG_CFLAGS	= @PKG_CFLAGS@
++
++# TCL_DEFS is not strictly need here, but if you remove it, then you
++# must make sure that configure.in checks for the necessary components
++# that your library may use.  TCL_DEFS can actually be a problem if
++# you do not compile with a similar machine setup as the Tcl core was
++# compiled with.
++#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
++DEFS		= @DEFS@ $(PKG_CFLAGS)
++
++CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
++
++CPPFLAGS	= @CPPFLAGS@
++LIBS		= @PKG_LIBS@ @LIBS@
++AR		= @AR@
++CFLAGS		= @CFLAGS@
++COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++
++#========================================================================
++# Start of user-definable TARGETS section
++#========================================================================
++
++#========================================================================
++# TEA TARGETS.  Please note that the "libraries:" target refers to platform
++# independent files, and the "binaries:" target inclues executable programs and
++# platform-dependent libraries.  Modify these targets so that they install
++# the various pieces of your package.  The make and install rules
++# for the BINARIES that you specified above have already been done.
++#========================================================================
++
++all: binaries libraries doc
++
++#========================================================================
++# The binaries target builds executable programs, Windows .dll's, unix
++# shared/static libraries, and any other platform-dependent files.
++# The list of targets to build for "binaries:" is specified at the top
++# of the Makefile, in the "BINARIES" variable.
++#========================================================================
++
++binaries: $(BINARIES)
++
++libraries:
++
++
++#========================================================================
++# Your doc target should differentiate from doc builds (by the developer)
++# and doc installs (see install-doc), which just install the docs on the
++# end user machine when building from source.
++#========================================================================
++
++doc:
++	@echo "If you have documentation to create, place the commands to"
++	@echo "build the docs in the 'doc:' target.  For example:"
++	@echo "        xml2nroff sample.xml > sample.n"
++	@echo "        xml2html sample.xml > sample.html"
++
++install: all install-binaries install-libraries install-doc
++
++install-binaries: binaries install-lib-binaries install-bin-binaries
++
++#========================================================================
++# This rule installs platform-independent files, such as header files.
++# The list=...; for p in $$list handles the empty list case x-platform.
++#========================================================================
++
++install-libraries: libraries
++	@mkdir -p $(DESTDIR)$(includedir)
++	@echo "Installing header files in $(DESTDIR)$(includedir)"
++	@list='$(PKG_HEADERS)'; for i in $$list; do \
++	    echo "Installing $(srcdir)/$$i" ; \
++	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
++	done;
++
++#========================================================================
++# Install documentation.  Unix manpages should go in the $(mandir)
++# directory.
++#========================================================================
++
++install-doc: doc
++	@mkdir -p $(DESTDIR)$(mandir)/mann
++	@echo "Installing documentation in $(DESTDIR)$(mandir)"
++	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
++	    echo "Installing $$i"; \
++	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
++	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
++	done
++
++test: binaries libraries
++	@echo "SQLite TEA distribution does not include tests"
++
++shell: binaries libraries
++	@$(TCLSH) $(SCRIPT)
++
++gdb:
++	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)
++
++depend:
++
++#========================================================================
++# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
++# mentioned above.  That will ensure that this target is built when you
++# run "make binaries".
++#
++# The $(PKG_OBJECTS) objects are created and linked into the final
++# library.  In most cases these object files will correspond to the
++# source files above.
++#========================================================================
++
++$(PKG_LIB_FILE): $(PKG_OBJECTS)
++	-rm -f $(PKG_LIB_FILE)
++	${MAKE_LIB}
++	$(RANLIB) $(PKG_LIB_FILE)
++
++$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
++	-rm -f $(PKG_STUB_LIB_FILE)
++	${MAKE_STUB_LIB}
++	$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
++
++#========================================================================
++# We need to enumerate the list of .c to .o lines here.
++#
++# In the following lines, $(srcdir) refers to the toplevel directory
++# containing your extension.  If your sources are in a subdirectory,
++# you will have to modify the paths to reflect this:
++#
++# sample.$(OBJEXT): $(srcdir)/generic/sample.c
++# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
++#
++# Setting the VPATH variable to a list of paths will cause the makefile
++# to look into these paths when resolving .c to .obj dependencies.
++# As necessary, add $(srcdir):$(srcdir)/compat:....
++#========================================================================
++
++VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win
++
++.c.@OBJEXT@:
++	$(COMPILE) -c `@CYGPATH@ $<` -o $@
++
++#========================================================================
++# Distribution creation
++# You may need to tweak this target to make it work correctly.
++#========================================================================
++
++#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
++COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
++DIST_ROOT	= /tmp/dist
++DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)
++
++dist-clean:
++	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
++
++dist: dist-clean
++	mkdir -p $(DIST_DIR)
++	cp -p $(srcdir)/README* $(srcdir)/license* \
++		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
++		$(DIST_DIR)/
++	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
++	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in
++
++	for i in $(srcdir)/*.[ch]; do \
++	    if [ -f $$i ]; then \
++		cp -p $$i $(DIST_DIR)/ ; \
++	    fi; \
++	done;
++
++	mkdir $(DIST_DIR)/tclconfig
++	cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
++		$(DIST_DIR)/tclconfig/
++	chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
++	chmod +x $(DIST_DIR)/tclconfig/install-sh
++
++	list='demos doc generic library mac tests unix win'; \
++	for p in $$list; do \
++	    if test -d $(srcdir)/$$p ; then \
++		mkdir $(DIST_DIR)/$$p; \
++		cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
++	    fi; \
++	done
++
++	(cd $(DIST_ROOT); $(COMPRESS);)
++
++#========================================================================
++# End of user-definable section
++#========================================================================
++
++#========================================================================
++# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
++# variable in configure.in
++#========================================================================
++
++clean:  
++	-test -z "$(BINARIES)" || rm -f $(BINARIES)
++	-rm -f *.$(OBJEXT) core *.core
++	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
++
++distclean: clean
++	-rm -f *.tab.c
++	-rm -f $(CONFIG_CLEAN_FILES)
++	-rm -f config.h config.cache config.log config.status
++
++#========================================================================
++# Install binary object libraries.  On Windows this includes both .dll and
++# .lib files.  Because the .lib files are not explicitly listed anywhere,
++# we need to deduce their existence from the .dll file of the same name.
++# Library files go into the lib directory.
++# In addition, this will generate the pkgIndex.tcl
++# file in the install location (assuming it can find a usable tclsh shell)
++#
++# You should not have to modify this target.
++#========================================================================
++
++install-lib-binaries: binaries
++	@mkdir -p $(DESTDIR)$(pkglibdir)
++	@list='$(lib_BINARIES)'; for p in $$list; do \
++	  if test -f $$p; then \
++	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
++	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
++	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
++	    if test "x$$stub" = "xstub"; then \
++		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
++		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
++	    else \
++		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
++		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
++	    fi; \
++	    ext=`echo $$p|sed -e "s/.*\.//"`; \
++	    if test "x$$ext" = "xdll"; then \
++		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
++		if test -f $$lib; then \
++		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
++	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
++		fi; \
++	    fi; \
++	  fi; \
++	done
++	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
++	  if test -f $(srcdir)/$$p; then \
++	    destp=`basename $$p`; \
++	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
++	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
++	  fi; \
++	done
++	@if test "x$(SHARED_BUILD)" = "x1"; then \
++	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
++	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
++	fi
++
++#========================================================================
++# Install binary executables (e.g. .exe files and dependent .dll files)
++# This is for files that must go in the bin directory (located next to
++# wish and tclsh), like dependent .dll files on Windows.
++#
++# You should not have to modify this target, except to define bin_BINARIES
++# above if necessary.
++#========================================================================
++
++install-bin-binaries: binaries
++	@mkdir -p $(DESTDIR)$(bindir)
++	@list='$(bin_BINARIES)'; for p in $$list; do \
++	  if test -f $$p; then \
++	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
++	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
++	  fi; \
++	done
++
++.SUFFIXES: .c .$(OBJEXT)
++
++Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
++	cd $(top_builddir) \
++	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
++
++uninstall-binaries:
++	list='$(lib_BINARIES)'; for p in $$list; do \
++	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
++	done
++	list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
++	  p=`basename $$p`; \
++	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
++	done
++	list='$(bin_BINARIES)'; for p in $$list; do \
++	  rm -f $(DESTDIR)$(bindir)/$$p; \
++	done
++
++.PHONY: all binaries clean depend distclean doc install libraries test
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+--- contrib/sqlite3/tea/README.orig
++++ contrib/sqlite3/tea/README
+@@ -0,0 +1,36 @@
++This is the SQLite extension for Tcl using the Tcl Extension
++Architecture (TEA).  For additional information on SQLite see
++
++        http://www.sqlite.org/
++
++
++UNIX BUILD
++==========
++
++Building under most UNIX systems is easy, just run the configure script
++and then run make. For more information about the build process, see
++the tcl/unix/README file in the Tcl src dist. The following minimal
++example will install the extension in the /opt/tcl directory.
++
++	$ cd sqlite-*-tea
++	$ ./configure --prefix=/opt/tcl
++	$ make
++	$ make install
++
++WINDOWS BUILD
++=============
++
++The recommended method to build extensions under windows is to use the
++Msys + Mingw build process. This provides a Unix-style build while
++generating native Windows binaries. Using the Msys + Mingw build tools
++means that you can use the same configure script as per the Unix build
++to create a Makefile. See the tcl/win/README file for the URL of
++the Msys + Mingw download.
++
++If you have VC++ then you may wish to use the files in the win
++subdirectory and build the extension using just VC++. These files have
++been designed to be as generic as possible but will require some
++additional maintenance by the project developer to synchronise with
++the TEA configure.in and Makefile.in files. Instructions for using the
++VC++ makefile are written in the first part of the Makefile.vc
++file.
+--- contrib/sqlite3/tea/aclocal.m4.orig
++++ contrib/sqlite3/tea/aclocal.m4
+@@ -0,0 +1,9 @@
++#
++# Include the TEA standard macro set
++#
++
++builtin(include,tclconfig/tcl.m4)
++
++#
++# Add here whatever m4 macros you want to define for your package
++#
+--- contrib/sqlite3/tea/configure.orig
++++ contrib/sqlite3/tea/configure
+@@ -0,0 +1,9977 @@
++#! /bin/sh
++# Guess values for system-dependent variables and create Makefiles.
++# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
++#
++#
++# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
++#
++#
++# This configure script is free software; the Free Software Foundation
++# gives unlimited permission to copy, distribute and modify it.
++## -------------------- ##
++## M4sh Initialization. ##
++## -------------------- ##
++
++# Be more Bourne compatible
++DUALCASE=1; export DUALCASE # for MKS sh
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
++  emulate sh
++  NULLCMD=:
++  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
++  # is contrary to our usage.  Disable this feature.
++  alias -g '${1+"$@"}'='"$@"'
++  setopt NO_GLOB_SUBST
++else
++  case `(set -o) 2>/dev/null` in #(
++  *posix*) :
++    set -o posix ;; #(
++  *) :
++     ;;
++esac
++fi
++
++
++as_nl='
++'
++export as_nl
++# Printing a long string crashes Solaris 7 /usr/bin/printf.
++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
++# Prefer a ksh shell builtin over an external printf program on Solaris,
++# but without wasting forks for bash or zsh.
++if test -z "$BASH_VERSION$ZSH_VERSION" \
++    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
++  as_echo='print -r --'
++  as_echo_n='print -rn --'
++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
++  as_echo='printf %s\n'
++  as_echo_n='printf %s'
++else
++  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
++    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
++    as_echo_n='/usr/ucb/echo -n'
++  else
++    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
++    as_echo_n_body='eval
++      arg=$1;
++      case $arg in #(
++      *"$as_nl"*)
++	expr "X$arg" : "X\\(.*\\)$as_nl";
++	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
++      esac;
++      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
++    '
++    export as_echo_n_body
++    as_echo_n='sh -c $as_echo_n_body as_echo'
++  fi
++  export as_echo_body
++  as_echo='sh -c $as_echo_body as_echo'
++fi
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++  PATH_SEPARATOR=:
++  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
++    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
++      PATH_SEPARATOR=';'
++  }
++fi
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.  Quoting is
++# there to prevent editors from complaining about space-tab.
++# (If _AS_PATH_WALK were called with IFS unset, it would disable word
++# splitting by setting IFS to empty value.)
++IFS=" ""	$as_nl"
++
++# Find who we are.  Look in the path if we contain no directory separator.
++as_myself=
++case $0 in #((
++  *[\\/]* ) as_myself=$0 ;;
++  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++  done
++IFS=$as_save_IFS
++
++     ;;
++esac
++# We did not find ourselves, most probably we were run as `sh COMMAND'
++# in which case we are not to be found in the path.
++if test "x$as_myself" = x; then
++  as_myself=$0
++fi
++if test ! -f "$as_myself"; then
++  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
++  exit 1
++fi
++
++# Unset variables that we do not need and which cause bugs (e.g. in
++# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
++# suppresses any "Segmentation fault" message there.  '((' could
++# trigger a bug in pdksh 5.2.14.
++for as_var in BASH_ENV ENV MAIL MAILPATH
++do eval test x\${$as_var+set} = xset \
++  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
++done
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++LC_ALL=C
++export LC_ALL
++LANGUAGE=C
++export LANGUAGE
++
++# CDPATH.
++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
++
++# Use a proper internal environment variable to ensure we don't fall
++  # into an infinite loop, continuously re-executing ourselves.
++  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
++    _as_can_reexec=no; export _as_can_reexec;
++    # We cannot yet assume a decent shell, so we have to provide a
++# neutralization value for shells without unset; and this also
++# works around shells that cannot unset nonexistent variables.
++# Preserve -v and -x to the replacement shell.
++BASH_ENV=/dev/null
++ENV=/dev/null
++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
++case $- in # ((((
++  *v*x* | *x*v* ) as_opts=-vx ;;
++  *v* ) as_opts=-v ;;
++  *x* ) as_opts=-x ;;
++  * ) as_opts= ;;
++esac
++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
++# Admittedly, this is quite paranoid, since all the known shells bail
++# out after a failed `exec'.
++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
++as_fn_exit 255
++  fi
++  # We don't want this to propagate to other subprocesses.
++          { _as_can_reexec=; unset _as_can_reexec;}
++if test "x$CONFIG_SHELL" = x; then
++  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
++  emulate sh
++  NULLCMD=:
++  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
++  # is contrary to our usage.  Disable this feature.
++  alias -g '\${1+\"\$@\"}'='\"\$@\"'
++  setopt NO_GLOB_SUBST
++else
++  case \`(set -o) 2>/dev/null\` in #(
++  *posix*) :
++    set -o posix ;; #(
++  *) :
++     ;;
++esac
++fi
++"
++  as_required="as_fn_return () { (exit \$1); }
++as_fn_success () { as_fn_return 0; }
++as_fn_failure () { as_fn_return 1; }
++as_fn_ret_success () { return 0; }
++as_fn_ret_failure () { return 1; }
++
++exitcode=0
++as_fn_success || { exitcode=1; echo as_fn_success failed.; }
++as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
++as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
++as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
++if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
++
++else
++  exitcode=1; echo positional parameters were not saved.
++fi
++test x\$exitcode = x0 || exit 1
++test -x / || exit 1"
++  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
++  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
++  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
++  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
++test \$(( 1 + 1 )) = 2 || exit 1"
++  if (eval "$as_required") 2>/dev/null; then :
++  as_have_required=yes
++else
++  as_have_required=no
++fi
++  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
++
++else
++  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++as_found=false
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++  as_found=:
++  case $as_dir in #(
++	 /*)
++	   for as_base in sh bash ksh sh5; do
++	     # Try only shells that exist, to save several forks.
++	     as_shell=$as_dir/$as_base
++	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
++		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
++  CONFIG_SHELL=$as_shell as_have_required=yes
++		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
++  break 2
++fi
++fi
++	   done;;
++       esac
++  as_found=false
++done
++$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
++	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
++  CONFIG_SHELL=$SHELL as_have_required=yes
++fi; }
++IFS=$as_save_IFS
++
++
++      if test "x$CONFIG_SHELL" != x; then :
++  export CONFIG_SHELL
++             # We cannot yet assume a decent shell, so we have to provide a
++# neutralization value for shells without unset; and this also
++# works around shells that cannot unset nonexistent variables.
++# Preserve -v and -x to the replacement shell.
++BASH_ENV=/dev/null
++ENV=/dev/null
++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
++case $- in # ((((
++  *v*x* | *x*v* ) as_opts=-vx ;;
++  *v* ) as_opts=-v ;;
++  *x* ) as_opts=-x ;;
++  * ) as_opts= ;;
++esac
++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
++# Admittedly, this is quite paranoid, since all the known shells bail
++# out after a failed `exec'.
++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
++exit 255
++fi
++
++    if test x$as_have_required = xno; then :
++  $as_echo "$0: This script requires a shell more modern than all"
++  $as_echo "$0: the shells that I found on your system."
++  if test x${ZSH_VERSION+set} = xset ; then
++    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
++    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
++  else
++    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
++$0: including any error possibly output before this
++$0: message. Then install a modern shell, or manually run
++$0: the script under such a shell if you do have one."
++  fi
++  exit 1
++fi
++fi
++fi
++SHELL=${CONFIG_SHELL-/bin/sh}
++export SHELL
++# Unset more variables known to interfere with behavior of common tools.
++CLICOLOR_FORCE= GREP_OPTIONS=
++unset CLICOLOR_FORCE GREP_OPTIONS
++
++## --------------------- ##
++## M4sh Shell Functions. ##
++## --------------------- ##
++# as_fn_unset VAR
++# ---------------
++# Portably unset VAR.
++as_fn_unset ()
++{
++  { eval $1=; unset $1;}
++}
++as_unset=as_fn_unset
++
++# as_fn_set_status STATUS
++# -----------------------
++# Set $? to STATUS, without forking.
++as_fn_set_status ()
++{
++  return $1
++} # as_fn_set_status
++
++# as_fn_exit STATUS
++# -----------------
++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
++as_fn_exit ()
++{
++  set +e
++  as_fn_set_status $1
++  exit $1
++} # as_fn_exit
++
++# as_fn_mkdir_p
++# -------------
++# Create "$as_dir" as a directory, including parents if necessary.
++as_fn_mkdir_p ()
++{
++
++  case $as_dir in #(
++  -*) as_dir=./$as_dir;;
++  esac
++  test -d "$as_dir" || eval $as_mkdir_p || {
++    as_dirs=
++    while :; do
++      case $as_dir in #(
++      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
++      *) as_qdir=$as_dir;;
++      esac
++      as_dirs="'$as_qdir' $as_dirs"
++      as_dir=`$as_dirname -- "$as_dir" ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	 X"$as_dir" : 'X\(//\)[^/]' \| \
++	 X"$as_dir" : 'X\(//\)$' \| \
++	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X"$as_dir" |
++    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)[^/].*/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++      test -d "$as_dir" && break
++    done
++    test -z "$as_dirs" || eval "mkdir $as_dirs"
++  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
++
++
++} # as_fn_mkdir_p
++
++# as_fn_executable_p FILE
++# -----------------------
++# Test if FILE is an executable regular file.
++as_fn_executable_p ()
++{
++  test -f "$1" && test -x "$1"
++} # as_fn_executable_p
++# as_fn_append VAR VALUE
++# ----------------------
++# Append the text in VALUE to the end of the definition contained in VAR. Take
++# advantage of any shell optimizations that allow amortized linear growth over
++# repeated appends, instead of the typical quadratic growth present in naive
++# implementations.
++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
++  eval 'as_fn_append ()
++  {
++    eval $1+=\$2
++  }'
++else
++  as_fn_append ()
++  {
++    eval $1=\$$1\$2
++  }
++fi # as_fn_append
++
++# as_fn_arith ARG...
++# ------------------
++# Perform arithmetic evaluation on the ARGs, and store the result in the
++# global $as_val. Take advantage of shells that can avoid forks. The arguments
++# must be portable across $(()) and expr.
++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
++  eval 'as_fn_arith ()
++  {
++    as_val=$(( $* ))
++  }'
++else
++  as_fn_arith ()
++  {
++    as_val=`expr "$@" || test $? -eq 1`
++  }
++fi # as_fn_arith
++
++
++# as_fn_error STATUS ERROR [LINENO LOG_FD]
++# ----------------------------------------
++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
++# script with STATUS, using 1 if that was 0.
++as_fn_error ()
++{
++  as_status=$1; test $as_status -eq 0 && as_status=1
++  if test "$4"; then
++    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
++  fi
++  $as_echo "$as_me: error: $2" >&2
++  as_fn_exit $as_status
++} # as_fn_error
++
++if expr a : '\(a\)' >/dev/null 2>&1 &&
++   test "X`expr 00001 : '.*\(...\)'`" = X001; then
++  as_expr=expr
++else
++  as_expr=false
++fi
++
++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
++  as_basename=basename
++else
++  as_basename=false
++fi
++
++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
++  as_dirname=dirname
++else
++  as_dirname=false
++fi
++
++as_me=`$as_basename -- "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++	 X"$0" : 'X\(//\)$' \| \
++	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X/"$0" |
++    sed '/^.*\/\([^/][^/]*\)\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\/\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\/\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++
++  as_lineno_1=$LINENO as_lineno_1a=$LINENO
++  as_lineno_2=$LINENO as_lineno_2a=$LINENO
++  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
++  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
++  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
++  sed -n '
++    p
++    /[$]LINENO/=
++  ' <$as_myself |
++    sed '
++      s/[$]LINENO.*/&-/
++      t lineno
++      b
++      :lineno
++      N
++      :loop
++      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
++      t loop
++      s/-\n.*//
++    ' >$as_me.lineno &&
++  chmod +x "$as_me.lineno" ||
++    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
++
++  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
++  # already done that, so ensure we don't try to do so again and fall
++  # in an infinite loop.  This has already happened in practice.
++  _as_can_reexec=no; export _as_can_reexec
++  # Don't try to exec as it changes $[0], causing all sort of problems
++  # (the dirname of $[0] is not the place where we might find the
++  # original and so on.  Autoconf is especially sensitive to this).
++  . "./$as_me.lineno"
++  # Exit status is that of the last command.
++  exit
++}
++
++ECHO_C= ECHO_N= ECHO_T=
++case `echo -n x` in #(((((
++-n*)
++  case `echo 'xy\c'` in
++  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
++  xy)  ECHO_C='\c';;
++  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
++       ECHO_T='	';;
++  esac;;
++*)
++  ECHO_N='-n';;
++esac
++
++rm -f conf$$ conf$$.exe conf$$.file
++if test -d conf$$.dir; then
++  rm -f conf$$.dir/conf$$.file
++else
++  rm -f conf$$.dir
++  mkdir conf$$.dir 2>/dev/null
++fi
++if (echo >conf$$.file) 2>/dev/null; then
++  if ln -s conf$$.file conf$$ 2>/dev/null; then
++    as_ln_s='ln -s'
++    # ... but there are two gotchas:
++    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
++    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
++    # In both cases, we have to default to `cp -pR'.
++    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
++      as_ln_s='cp -pR'
++  elif ln conf$$.file conf$$ 2>/dev/null; then
++    as_ln_s=ln
++  else
++    as_ln_s='cp -pR'
++  fi
++else
++  as_ln_s='cp -pR'
++fi
++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
++rmdir conf$$.dir 2>/dev/null
++
++if mkdir -p . 2>/dev/null; then
++  as_mkdir_p='mkdir -p "$as_dir"'
++else
++  test -d ./-p && rmdir ./-p
++  as_mkdir_p=false
++fi
++
++as_test_x='test -x'
++as_executable_p=as_fn_executable_p
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
++
++
++test -n "$DJDIR" || exec 7<&0 </dev/null
++exec 6>&1
++
++# Name of the host.
++# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
++# so uname gets run too.
++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
++
++#
++# Initializations.
++#
++ac_default_prefix=/usr/local
++ac_clean_files=
++ac_config_libobj_dir=.
++LIBOBJS=
++cross_compiling=no
++subdirs=
++MFLAGS=
++MAKEFLAGS=
++
++# Identity of this package.
++PACKAGE_NAME='sqlite'
++PACKAGE_TARNAME='sqlite'
++PACKAGE_VERSION='3.26.0'
++PACKAGE_STRING='sqlite 3.26.0'
++PACKAGE_BUGREPORT=''
++PACKAGE_URL=''
++
++# Factoring default headers for most tests.
++ac_includes_default="\
++#include <stdio.h>
++#ifdef HAVE_SYS_TYPES_H
++# include <sys/types.h>
++#endif
++#ifdef HAVE_SYS_STAT_H
++# include <sys/stat.h>
++#endif
++#ifdef STDC_HEADERS
++# include <stdlib.h>
++# include <stddef.h>
++#else
++# ifdef HAVE_STDLIB_H
++#  include <stdlib.h>
++# endif
++#endif
++#ifdef HAVE_STRING_H
++# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
++#  include <memory.h>
++# endif
++# include <string.h>
++#endif
++#ifdef HAVE_STRINGS_H
++# include <strings.h>
++#endif
++#ifdef HAVE_INTTYPES_H
++# include <inttypes.h>
++#endif
++#ifdef HAVE_STDINT_H
++# include <stdint.h>
++#endif
++#ifdef HAVE_UNISTD_H
++# include <unistd.h>
++#endif"
++
++ac_subst_vars='LTLIBOBJS
++LIBOBJS
++TCLSH_PROG
++VC_MANIFEST_EMBED_EXE
++VC_MANIFEST_EMBED_DLL
++RANLIB_STUB
++MAKE_STUB_LIB
++MAKE_STATIC_LIB
++MAKE_SHARED_LIB
++MAKE_LIB
++TCL_DBGX
++LDFLAGS_DEFAULT
++CFLAGS_DEFAULT
++LD_LIBRARY_PATH_VAR
++SHLIB_CFLAGS
++SHLIB_LD_LIBS
++SHLIB_LD
++STLIB_LD
++CFLAGS_WARNING
++CFLAGS_OPTIMIZE
++CFLAGS_DEBUG
++RC
++CELIB_DIR
++AR
++SHARED_BUILD
++TCL_THREADS
++TCL_INCLUDES
++PKG_OBJECTS
++PKG_SOURCES
++MATH_LIBS
++EGREP
++GREP
++RANLIB
++SET_MAKE
++INSTALL_SCRIPT
++INSTALL_PROGRAM
++INSTALL_DATA
++INSTALL
++CPP
++TCL_SHLIB_LD_LIBS
++TCL_LD_FLAGS
++TCL_EXTRA_CFLAGS
++TCL_DEFS
++TCL_LIBS
++CLEANFILES
++OBJEXT
++ac_ct_CC
++CPPFLAGS
++LDFLAGS
++CFLAGS
++CC
++TCL_STUB_LIB_SPEC
++TCL_STUB_LIB_FLAG
++TCL_STUB_LIB_FILE
++TCL_LIB_SPEC
++TCL_LIB_FLAG
++TCL_LIB_FILE
++TCL_SRC_DIR
++TCL_BIN_DIR
++TCL_PATCH_LEVEL
++TCL_VERSION
++PKG_CFLAGS
++PKG_LIBS
++PKG_INCLUDES
++PKG_HEADERS
++PKG_TCL_SOURCES
++PKG_STUB_OBJECTS
++PKG_STUB_SOURCES
++PKG_STUB_LIB_FILE
++PKG_LIB_FILE
++EXEEXT
++CYGPATH
++target_alias
++host_alias
++build_alias
++LIBS
++ECHO_T
++ECHO_N
++ECHO_C
++DEFS
++mandir
++localedir
++libdir
++psdir
++pdfdir
++dvidir
++htmldir
++infodir
++docdir
++oldincludedir
++includedir
++localstatedir
++sharedstatedir
++sysconfdir
++datadir
++datarootdir
++libexecdir
++sbindir
++bindir
++program_transform_name
++prefix
++exec_prefix
++PACKAGE_URL
++PACKAGE_BUGREPORT
++PACKAGE_STRING
++PACKAGE_VERSION
++PACKAGE_TARNAME
++PACKAGE_NAME
++PATH_SEPARATOR
++SHELL'
++ac_subst_files=''
++ac_user_opts='
++enable_option_checking
++with_tcl
++with_system_sqlite
++with_tclinclude
++enable_threads
++enable_shared
++enable_64bit
++enable_64bit_vis
++enable_rpath
++enable_wince
++with_celib
++enable_symbols
++'
++      ac_precious_vars='build_alias
++host_alias
++target_alias
++CC
++CFLAGS
++LDFLAGS
++LIBS
++CPPFLAGS
++CPP'
++
++
++# Initialize some variables set by options.
++ac_init_help=
++ac_init_version=false
++ac_unrecognized_opts=
++ac_unrecognized_sep=
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++cache_file=/dev/null
++exec_prefix=NONE
++no_create=
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++srcdir=
++verbose=
++x_includes=NONE
++x_libraries=NONE
++
++# Installation directory options.
++# These are left unexpanded so users can "make install exec_prefix=/foo"
++# and all the variables that are supposed to be based on exec_prefix
++# by default will actually change.
++# Use braces instead of parens because sh, perl, etc. also accept them.
++# (The list follows the same order as the GNU Coding Standards.)
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datarootdir='${prefix}/share'
++datadir='${datarootdir}'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
++infodir='${datarootdir}/info'
++htmldir='${docdir}'
++dvidir='${docdir}'
++pdfdir='${docdir}'
++psdir='${docdir}'
++libdir='${exec_prefix}/lib'
++localedir='${datarootdir}/locale'
++mandir='${datarootdir}/man'
++
++ac_prev=
++ac_dashdash=
++for ac_option
++do
++  # If the previous option needs an argument, assign it.
++  if test -n "$ac_prev"; then
++    eval $ac_prev=\$ac_option
++    ac_prev=
++    continue
++  fi
++
++  case $ac_option in
++  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
++  *=)   ac_optarg= ;;
++  *)    ac_optarg=yes ;;
++  esac
++
++  # Accept the important Cygnus configure options, so we can diagnose typos.
++
++  case $ac_dashdash$ac_option in
++  --)
++    ac_dashdash=yes ;;
++
++  -bindir | --bindir | --bindi | --bind | --bin | --bi)
++    ac_prev=bindir ;;
++  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++    bindir=$ac_optarg ;;
++
++  -build | --build | --buil | --bui | --bu)
++    ac_prev=build_alias ;;
++  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++    build_alias=$ac_optarg ;;
++
++  -cache-file | --cache-file | --cache-fil | --cache-fi \
++  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++    ac_prev=cache_file ;;
++  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++    cache_file=$ac_optarg ;;
++
++  --config-cache | -C)
++    cache_file=config.cache ;;
++
++  -datadir | --datadir | --datadi | --datad)
++    ac_prev=datadir ;;
++  -datadir=* | --datadir=* | --datadi=* | --datad=*)
++    datadir=$ac_optarg ;;
++
++  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
++  | --dataroo | --dataro | --datar)
++    ac_prev=datarootdir ;;
++  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
++  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
++    datarootdir=$ac_optarg ;;
++
++  -disable-* | --disable-*)
++    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
++    # Reject names that are not valid shell variable names.
++    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
++      as_fn_error $? "invalid feature name: $ac_useropt"
++    ac_useropt_orig=$ac_useropt
++    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++    case $ac_user_opts in
++      *"
++"enable_$ac_useropt"
++"*) ;;
++      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
++	 ac_unrecognized_sep=', ';;
++    esac
++    eval enable_$ac_useropt=no ;;
++
++  -docdir | --docdir | --docdi | --doc | --do)
++    ac_prev=docdir ;;
++  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
++    docdir=$ac_optarg ;;
++
++  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
++    ac_prev=dvidir ;;
++  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
++    dvidir=$ac_optarg ;;
++
++  -enable-* | --enable-*)
++    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
++    # Reject names that are not valid shell variable names.
++    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
++      as_fn_error $? "invalid feature name: $ac_useropt"
++    ac_useropt_orig=$ac_useropt
++    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++    case $ac_user_opts in
++      *"
++"enable_$ac_useropt"
++"*) ;;
++      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
++	 ac_unrecognized_sep=', ';;
++    esac
++    eval enable_$ac_useropt=\$ac_optarg ;;
++
++  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++  | --exec | --exe | --ex)
++    ac_prev=exec_prefix ;;
++  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++  | --exec=* | --exe=* | --ex=*)
++    exec_prefix=$ac_optarg ;;
++
++  -gas | --gas | --ga | --g)
++    # Obsolete; use --with-gas.
++    with_gas=yes ;;
++
++  -help | --help | --hel | --he | -h)
++    ac_init_help=long ;;
++  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
++    ac_init_help=recursive ;;
++  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
++    ac_init_help=short ;;
++
++  -host | --host | --hos | --ho)
++    ac_prev=host_alias ;;
++  -host=* | --host=* | --hos=* | --ho=*)
++    host_alias=$ac_optarg ;;
++
++  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
++    ac_prev=htmldir ;;
++  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
++  | --ht=*)
++    htmldir=$ac_optarg ;;
++
++  -includedir | --includedir | --includedi | --included | --include \
++  | --includ | --inclu | --incl | --inc)
++    ac_prev=includedir ;;
++  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++  | --includ=* | --inclu=* | --incl=* | --inc=*)
++    includedir=$ac_optarg ;;
++
++  -infodir | --infodir | --infodi | --infod | --info | --inf)
++    ac_prev=infodir ;;
++  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++    infodir=$ac_optarg ;;
++
++  -libdir | --libdir | --libdi | --libd)
++    ac_prev=libdir ;;
++  -libdir=* | --libdir=* | --libdi=* | --libd=*)
++    libdir=$ac_optarg ;;
++
++  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++  | --libexe | --libex | --libe)
++    ac_prev=libexecdir ;;
++  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++  | --libexe=* | --libex=* | --libe=*)
++    libexecdir=$ac_optarg ;;
++
++  -localedir | --localedir | --localedi | --localed | --locale)
++    ac_prev=localedir ;;
++  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
++    localedir=$ac_optarg ;;
++
++  -localstatedir | --localstatedir | --localstatedi | --localstated \
++  | --localstate | --localstat | --localsta | --localst | --locals)
++    ac_prev=localstatedir ;;
++  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
++    localstatedir=$ac_optarg ;;
++
++  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++    ac_prev=mandir ;;
++  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++    mandir=$ac_optarg ;;
++
++  -nfp | --nfp | --nf)
++    # Obsolete; use --without-fp.
++    with_fp=no ;;
++
++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++  | --no-cr | --no-c | -n)
++    no_create=yes ;;
++
++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++    no_recursion=yes ;;
++
++  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++  | --oldin | --oldi | --old | --ol | --o)
++    ac_prev=oldincludedir ;;
++  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++    oldincludedir=$ac_optarg ;;
++
++  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++    ac_prev=prefix ;;
++  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++    prefix=$ac_optarg ;;
++
++  -program-prefix | --program-prefix | --program-prefi | --program-pref \
++  | --program-pre | --program-pr | --program-p)
++    ac_prev=program_prefix ;;
++  -program-prefix=* | --program-prefix=* | --program-prefi=* \
++  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++    program_prefix=$ac_optarg ;;
++
++  -program-suffix | --program-suffix | --program-suffi | --program-suff \
++  | --program-suf | --program-su | --program-s)
++    ac_prev=program_suffix ;;
++  -program-suffix=* | --program-suffix=* | --program-suffi=* \
++  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++    program_suffix=$ac_optarg ;;
++
++  -program-transform-name | --program-transform-name \
++  | --program-transform-nam | --program-transform-na \
++  | --program-transform-n | --program-transform- \
++  | --program-transform | --program-transfor \
++  | --program-transfo | --program-transf \
++  | --program-trans | --program-tran \
++  | --progr-tra | --program-tr | --program-t)
++    ac_prev=program_transform_name ;;
++  -program-transform-name=* | --program-transform-name=* \
++  | --program-transform-nam=* | --program-transform-na=* \
++  | --program-transform-n=* | --program-transform-=* \
++  | --program-transform=* | --program-transfor=* \
++  | --program-transfo=* | --program-transf=* \
++  | --program-trans=* | --program-tran=* \
++  | --progr-tra=* | --program-tr=* | --program-t=*)
++    program_transform_name=$ac_optarg ;;
++
++  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
++    ac_prev=pdfdir ;;
++  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
++    pdfdir=$ac_optarg ;;
++
++  -psdir | --psdir | --psdi | --psd | --ps)
++    ac_prev=psdir ;;
++  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
++    psdir=$ac_optarg ;;
++
++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++  | -silent | --silent | --silen | --sile | --sil)
++    silent=yes ;;
++
++  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++    ac_prev=sbindir ;;
++  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++  | --sbi=* | --sb=*)
++    sbindir=$ac_optarg ;;
++
++  -sharedstatedir | --sharedstatedir | --sharedstatedi \
++  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++  | --sharedst | --shareds | --shared | --share | --shar \
++  | --sha | --sh)
++    ac_prev=sharedstatedir ;;
++  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++  | --sha=* | --sh=*)
++    sharedstatedir=$ac_optarg ;;
++
++  -site | --site | --sit)
++    ac_prev=site ;;
++  -site=* | --site=* | --sit=*)
++    site=$ac_optarg ;;
++
++  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++    ac_prev=srcdir ;;
++  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++    srcdir=$ac_optarg ;;
++
++  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++  | --syscon | --sysco | --sysc | --sys | --sy)
++    ac_prev=sysconfdir ;;
++  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++    sysconfdir=$ac_optarg ;;
++
++  -target | --target | --targe | --targ | --tar | --ta | --t)
++    ac_prev=target_alias ;;
++  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++    target_alias=$ac_optarg ;;
++
++  -v | -verbose | --verbose | --verbos | --verbo | --verb)
++    verbose=yes ;;
++
++  -version | --version | --versio | --versi | --vers | -V)
++    ac_init_version=: ;;
++
++  -with-* | --with-*)
++    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
++    # Reject names that are not valid shell variable names.
++    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
++      as_fn_error $? "invalid package name: $ac_useropt"
++    ac_useropt_orig=$ac_useropt
++    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++    case $ac_user_opts in
++      *"
++"with_$ac_useropt"
++"*) ;;
++      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
++	 ac_unrecognized_sep=', ';;
++    esac
++    eval with_$ac_useropt=\$ac_optarg ;;
++
++  -without-* | --without-*)
++    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
++    # Reject names that are not valid shell variable names.
++    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
++      as_fn_error $? "invalid package name: $ac_useropt"
++    ac_useropt_orig=$ac_useropt
++    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
++    case $ac_user_opts in
++      *"
++"with_$ac_useropt"
++"*) ;;
++      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
++	 ac_unrecognized_sep=', ';;
++    esac
++    eval with_$ac_useropt=no ;;
++
++  --x)
++    # Obsolete; use --with-x.
++    with_x=yes ;;
++
++  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++  | --x-incl | --x-inc | --x-in | --x-i)
++    ac_prev=x_includes ;;
++  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++    x_includes=$ac_optarg ;;
++
++  -x-libraries | --x-libraries | --x-librarie | --x-librari \
++  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++    ac_prev=x_libraries ;;
++  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++    x_libraries=$ac_optarg ;;
++
++  -*) as_fn_error $? "unrecognized option: \`$ac_option'
++Try \`$0 --help' for more information"
++    ;;
++
++  *=*)
++    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
++    # Reject names that are not valid shell variable names.
++    case $ac_envvar in #(
++      '' | [0-9]* | *[!_$as_cr_alnum]* )
++      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
++    esac
++    eval $ac_envvar=\$ac_optarg
++    export $ac_envvar ;;
++
++  *)
++    # FIXME: should be removed in autoconf 3.0.
++    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
++    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
++      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
++    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
++    ;;
++
++  esac
++done
++
++if test -n "$ac_prev"; then
++  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
++  as_fn_error $? "missing argument to $ac_option"
++fi
++
++if test -n "$ac_unrecognized_opts"; then
++  case $enable_option_checking in
++    no) ;;
++    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
++    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
++  esac
++fi
++
++# Check all directory arguments for consistency.
++for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
++		datadir sysconfdir sharedstatedir localstatedir includedir \
++		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
++		libdir localedir mandir
++do
++  eval ac_val=\$$ac_var
++  # Remove trailing slashes.
++  case $ac_val in
++    */ )
++      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
++      eval $ac_var=\$ac_val;;
++  esac
++  # Be sure to have absolute directory names.
++  case $ac_val in
++    [\\/$]* | ?:[\\/]* )  continue;;
++    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
++  esac
++  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
++done
++
++# There might be people who depend on the old broken behavior: `$host'
++# used to hold the argument of --host etc.
++# FIXME: To remove some day.
++build=$build_alias
++host=$host_alias
++target=$target_alias
++
++# FIXME: To remove some day.
++if test "x$host_alias" != x; then
++  if test "x$build_alias" = x; then
++    cross_compiling=maybe
++  elif test "x$build_alias" != "x$host_alias"; then
++    cross_compiling=yes
++  fi
++fi
++
++ac_tool_prefix=
++test -n "$host_alias" && ac_tool_prefix=$host_alias-
++
++test "$silent" = yes && exec 6>/dev/null
++
++
++ac_pwd=`pwd` && test -n "$ac_pwd" &&
++ac_ls_di=`ls -di .` &&
++ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
++  as_fn_error $? "working directory cannot be determined"
++test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
++  as_fn_error $? "pwd does not report name of working directory"
++
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++  ac_srcdir_defaulted=yes
++  # Try the directory containing this script, then the parent directory.
++  ac_confdir=`$as_dirname -- "$as_myself" ||
++$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	 X"$as_myself" : 'X\(//\)[^/]' \| \
++	 X"$as_myself" : 'X\(//\)$' \| \
++	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X"$as_myself" |
++    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)[^/].*/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++  srcdir=$ac_confdir
++  if test ! -r "$srcdir/$ac_unique_file"; then
++    srcdir=..
++  fi
++else
++  ac_srcdir_defaulted=no
++fi
++if test ! -r "$srcdir/$ac_unique_file"; then
++  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
++  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
++fi
++ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
++ac_abs_confdir=`(
++	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
++	pwd)`
++# When building in place, set srcdir=.
++if test "$ac_abs_confdir" = "$ac_pwd"; then
++  srcdir=.
++fi
++# Remove unnecessary trailing slashes from srcdir.
++# Double slashes in file names in object file debugging info
++# mess up M-x gdb in Emacs.
++case $srcdir in
++*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
++esac
++for ac_var in $ac_precious_vars; do
++  eval ac_env_${ac_var}_set=\${${ac_var}+set}
++  eval ac_env_${ac_var}_value=\$${ac_var}
++  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
++  eval ac_cv_env_${ac_var}_value=\$${ac_var}
++done
++
++#
++# Report the --help message.
++#
++if test "$ac_init_help" = "long"; then
++  # Omit some internal or obsolete options to make the list less imposing.
++  # This message is too long to be a string in the A/UX 3.1 sh.
++  cat <<_ACEOF
++\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
++
++Usage: $0 [OPTION]... [VAR=VALUE]...
++
++To assign environment variables (e.g., CC, CFLAGS...), specify them as
++VAR=VALUE.  See below for descriptions of some of the useful variables.
++
++Defaults for the options are specified in brackets.
++
++Configuration:
++  -h, --help              display this help and exit
++      --help=short        display options specific to this package
++      --help=recursive    display the short help of all the included packages
++  -V, --version           display version information and exit
++  -q, --quiet, --silent   do not print \`checking ...' messages
++      --cache-file=FILE   cache test results in FILE [disabled]
++  -C, --config-cache      alias for \`--cache-file=config.cache'
++  -n, --no-create         do not create output files
++      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
++
++Installation directories:
++  --prefix=PREFIX         install architecture-independent files in PREFIX
++                          [$ac_default_prefix]
++  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
++                          [PREFIX]
++
++By default, \`make install' will install all the files in
++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
++an installation prefix other than \`$ac_default_prefix' using \`--prefix',
++for instance \`--prefix=\$HOME'.
++
++For better control, use the options below.
++
++Fine tuning of the installation directories:
++  --bindir=DIR            user executables [EPREFIX/bin]
++  --sbindir=DIR           system admin executables [EPREFIX/sbin]
++  --libexecdir=DIR        program executables [EPREFIX/libexec]
++  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
++  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
++  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
++  --libdir=DIR            object code libraries [EPREFIX/lib]
++  --includedir=DIR        C header files [PREFIX/include]
++  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
++  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
++  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
++  --infodir=DIR           info documentation [DATAROOTDIR/info]
++  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
++  --mandir=DIR            man documentation [DATAROOTDIR/man]
++  --docdir=DIR            documentation root [DATAROOTDIR/doc/sqlite]
++  --htmldir=DIR           html documentation [DOCDIR]
++  --dvidir=DIR            dvi documentation [DOCDIR]
++  --pdfdir=DIR            pdf documentation [DOCDIR]
++  --psdir=DIR             ps documentation [DOCDIR]
++_ACEOF
++
++  cat <<\_ACEOF
++_ACEOF
++fi
++
++if test -n "$ac_init_help"; then
++  case $ac_init_help in
++     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
++   esac
++  cat <<\_ACEOF
++
++Optional Features:
++  --disable-option-checking  ignore unrecognized --enable/--with options
++  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
++  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
++  --enable-threads        build with threads
++  --enable-shared         build and link with shared libraries (default: on)
++  --enable-64bit          enable 64bit support (default: off)
++  --enable-64bit-vis      enable 64bit Sparc VIS support (default: off)
++  --disable-rpath         disable rpath support (default: on)
++  --enable-wince          enable Win/CE support (where applicable)
++  --enable-symbols        build with debugging symbols (default: off)
++
++Optional Packages:
++  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
++  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
++  --with-tcl              directory containing tcl configuration
++                          (tclConfig.sh)
++  --with-system-sqlite    use a system-supplied libsqlite3 instead of the
++                          bundled one
++  --with-tclinclude       directory containing the public Tcl header files
++  --with-celib=DIR        use Windows/CE support library from DIR
++
++Some influential environment variables:
++  CC          C compiler command
++  CFLAGS      C compiler flags
++  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
++              nonstandard directory <lib dir>
++  LIBS        libraries to pass to the linker, e.g. -l<library>
++  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
++              you have headers in a nonstandard directory <include dir>
++  CPP         C preprocessor
++
++Use these variables to override the choices made by `configure' or to help
++it to find libraries and programs with nonstandard names/locations.
++
++Report bugs to the package provider.
++_ACEOF
++ac_status=$?
++fi
++
++if test "$ac_init_help" = "recursive"; then
++  # If there are subdirs, report their specific --help.
++  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
++    test -d "$ac_dir" ||
++      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
++      continue
++    ac_builddir=.
++
++case "$ac_dir" in
++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
++*)
++  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
++  # A ".." for each directory in $ac_dir_suffix.
++  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
++  case $ac_top_builddir_sub in
++  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
++  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
++  esac ;;
++esac
++ac_abs_top_builddir=$ac_pwd
++ac_abs_builddir=$ac_pwd$ac_dir_suffix
++# for backward compatibility:
++ac_top_builddir=$ac_top_build_prefix
++
++case $srcdir in
++  .)  # We are building in place.
++    ac_srcdir=.
++    ac_top_srcdir=$ac_top_builddir_sub
++    ac_abs_top_srcdir=$ac_pwd ;;
++  [\\/]* | ?:[\\/]* )  # Absolute name.
++    ac_srcdir=$srcdir$ac_dir_suffix;
++    ac_top_srcdir=$srcdir
++    ac_abs_top_srcdir=$srcdir ;;
++  *) # Relative name.
++    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
++    ac_top_srcdir=$ac_top_build_prefix$srcdir
++    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
++esac
++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
++
++    cd "$ac_dir" || { ac_status=$?; continue; }
++    # Check for guested configure.
++    if test -f "$ac_srcdir/configure.gnu"; then
++      echo &&
++      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
++    elif test -f "$ac_srcdir/configure"; then
++      echo &&
++      $SHELL "$ac_srcdir/configure" --help=recursive
++    else
++      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
++    fi || ac_status=$?
++    cd "$ac_pwd" || { ac_status=$?; break; }
++  done
++fi
++
++test -n "$ac_init_help" && exit $ac_status
++if $ac_init_version; then
++  cat <<\_ACEOF
++sqlite configure 3.26.0
++generated by GNU Autoconf 2.69
++
++Copyright (C) 2012 Free Software Foundation, Inc.
++This configure script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it.
++_ACEOF
++  exit
++fi
++
++## ------------------------ ##
++## Autoconf initialization. ##
++## ------------------------ ##
++
++# ac_fn_c_try_compile LINENO
++# --------------------------
++# Try to compile conftest.$ac_ext, and return whether this succeeded.
++ac_fn_c_try_compile ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  rm -f conftest.$ac_objext
++  if { { ac_try="$ac_compile"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_compile") 2>conftest.err
++  ac_status=$?
++  if test -s conftest.err; then
++    grep -v '^ *+' conftest.err >conftest.er1
++    cat conftest.er1 >&5
++    mv -f conftest.er1 conftest.err
++  fi
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; } && {
++	 test -z "$ac_c_werror_flag" ||
++	 test ! -s conftest.err
++       } && test -s conftest.$ac_objext; then :
++  ac_retval=0
++else
++  $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++	ac_retval=1
++fi
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++  as_fn_set_status $ac_retval
++
++} # ac_fn_c_try_compile
++
++# ac_fn_c_try_cpp LINENO
++# ----------------------
++# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
++ac_fn_c_try_cpp ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  if { { ac_try="$ac_cpp conftest.$ac_ext"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
++  ac_status=$?
++  if test -s conftest.err; then
++    grep -v '^ *+' conftest.err >conftest.er1
++    cat conftest.er1 >&5
++    mv -f conftest.er1 conftest.err
++  fi
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; } > conftest.i && {
++	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
++	 test ! -s conftest.err
++       }; then :
++  ac_retval=0
++else
++  $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++    ac_retval=1
++fi
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++  as_fn_set_status $ac_retval
++
++} # ac_fn_c_try_cpp
++
++# ac_fn_c_try_run LINENO
++# ----------------------
++# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
++# that executables *can* be run.
++ac_fn_c_try_run ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  if { { ac_try="$ac_link"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_link") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
++  { { case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_try") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then :
++  ac_retval=0
++else
++  $as_echo "$as_me: program exited with status $ac_status" >&5
++       $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++       ac_retval=$ac_status
++fi
++  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++  as_fn_set_status $ac_retval
++
++} # ac_fn_c_try_run
++
++# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
++# -------------------------------------------------------
++# Tests whether HEADER exists and can be compiled using the include files in
++# INCLUDES, setting the cache variable VAR accordingly.
++ac_fn_c_check_header_compile ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$4
++#include <$2>
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  eval "$3=yes"
++else
++  eval "$3=no"
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++
++} # ac_fn_c_check_header_compile
++
++# ac_fn_c_try_link LINENO
++# -----------------------
++# Try to link conftest.$ac_ext, and return whether this succeeded.
++ac_fn_c_try_link ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  rm -f conftest.$ac_objext conftest$ac_exeext
++  if { { ac_try="$ac_link"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_link") 2>conftest.err
++  ac_status=$?
++  if test -s conftest.err; then
++    grep -v '^ *+' conftest.err >conftest.er1
++    cat conftest.er1 >&5
++    mv -f conftest.er1 conftest.err
++  fi
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; } && {
++	 test -z "$ac_c_werror_flag" ||
++	 test ! -s conftest.err
++       } && test -s conftest$ac_exeext && {
++	 test "$cross_compiling" = yes ||
++	 test -x conftest$ac_exeext
++       }; then :
++  ac_retval=0
++else
++  $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++	ac_retval=1
++fi
++  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
++  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
++  # interfere with the next link command; also delete a directory that is
++  # left behind by Apple's compiler.  We do this before executing the actions.
++  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++  as_fn_set_status $ac_retval
++
++} # ac_fn_c_try_link
++
++# ac_fn_c_check_func LINENO FUNC VAR
++# ----------------------------------
++# Tests whether FUNC exists, setting the cache variable VAR accordingly
++ac_fn_c_check_func ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
++   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
++#define $2 innocuous_$2
++
++/* System header to define __stub macros and hopefully few prototypes,
++    which can conflict with char $2 (); below.
++    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++    <limits.h> exists even on freestanding compilers.  */
++
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
++
++#undef $2
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char $2 ();
++/* The GNU C library defines this for functions which it implements
++    to always fail with ENOSYS.  Some functions are actually named
++    something starting with __ and the normal name is an alias.  */
++#if defined __stub_$2 || defined __stub___$2
++choke me
++#endif
++
++int
++main ()
++{
++return $2 ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  eval "$3=yes"
++else
++  eval "$3=no"
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++
++} # ac_fn_c_check_func
++
++# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
++# -------------------------------------------------------
++# Tests whether HEADER exists, giving a warning if it cannot be compiled using
++# the include files in INCLUDES and setting the cache variable VAR
++# accordingly.
++ac_fn_c_check_header_mongrel ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  if eval \${$3+:} false; then :
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++else
++  # Is the header compilable?
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
++$as_echo_n "checking $2 usability... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$4
++#include <$2>
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_header_compiler=yes
++else
++  ac_header_compiler=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
++$as_echo "$ac_header_compiler" >&6; }
++
++# Is the header present?
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
++$as_echo_n "checking $2 presence... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <$2>
++_ACEOF
++if ac_fn_c_try_cpp "$LINENO"; then :
++  ac_header_preproc=yes
++else
++  ac_header_preproc=no
++fi
++rm -f conftest.err conftest.i conftest.$ac_ext
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
++$as_echo "$ac_header_preproc" >&6; }
++
++# So?  What about this header?
++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
++  yes:no: )
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
++$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
++    ;;
++  no:yes:* )
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
++$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
++$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
++$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
++$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
++    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
++$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
++    ;;
++esac
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
++$as_echo_n "checking for $2... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  eval "$3=\$ac_header_compiler"
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++fi
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++
++} # ac_fn_c_check_header_mongrel
++
++# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
++# ---------------------------------------------
++# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
++# accordingly.
++ac_fn_c_check_decl ()
++{
++  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++  as_decl_name=`echo $2|sed 's/ *(.*//'`
++  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
++$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
++if eval \${$3+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$4
++int
++main ()
++{
++#ifndef $as_decl_name
++#ifdef __cplusplus
++  (void) $as_decl_use;
++#else
++  (void) $as_decl_name;
++#endif
++#endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  eval "$3=yes"
++else
++  eval "$3=no"
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++eval ac_res=\$$3
++	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
++
++} # ac_fn_c_check_decl
++cat >config.log <<_ACEOF
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++
++It was created by sqlite $as_me 3.26.0, which was
++generated by GNU Autoconf 2.69.  Invocation command line was
++
++  $ $0 $@
++
++_ACEOF
++exec 5>>config.log
++{
++cat <<_ASUNAME
++## --------- ##
++## Platform. ##
++## --------- ##
++
++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
++uname -m = `(uname -m) 2>/dev/null || echo unknown`
++uname -r = `(uname -r) 2>/dev/null || echo unknown`
++uname -s = `(uname -s) 2>/dev/null || echo unknown`
++uname -v = `(uname -v) 2>/dev/null || echo unknown`
++
++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
++/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
++
++/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
++/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
++/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
++/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
++/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
++/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
++
++_ASUNAME
++
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    $as_echo "PATH: $as_dir"
++  done
++IFS=$as_save_IFS
++
++} >&5
++
++cat >&5 <<_ACEOF
++
++
++## ----------- ##
++## Core tests. ##
++## ----------- ##
++
++_ACEOF
++
++
++# Keep a trace of the command line.
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Strip out --silent because we don't want to record it for future runs.
++# Also quote any args containing shell meta-characters.
++# Make two passes to allow for proper duplicate-argument suppression.
++ac_configure_args=
++ac_configure_args0=
++ac_configure_args1=
++ac_must_keep_next=false
++for ac_pass in 1 2
++do
++  for ac_arg
++  do
++    case $ac_arg in
++    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
++    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++    | -silent | --silent | --silen | --sile | --sil)
++      continue ;;
++    *\'*)
++      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++    esac
++    case $ac_pass in
++    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
++    2)
++      as_fn_append ac_configure_args1 " '$ac_arg'"
++      if test $ac_must_keep_next = true; then
++	ac_must_keep_next=false # Got value, back to normal.
++      else
++	case $ac_arg in
++	  *=* | --config-cache | -C | -disable-* | --disable-* \
++	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
++	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
++	  | -with-* | --with-* | -without-* | --without-* | --x)
++	    case "$ac_configure_args0 " in
++	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
++	    esac
++	    ;;
++	  -* ) ac_must_keep_next=true ;;
++	esac
++      fi
++      as_fn_append ac_configure_args " '$ac_arg'"
++      ;;
++    esac
++  done
++done
++{ ac_configure_args0=; unset ac_configure_args0;}
++{ ac_configure_args1=; unset ac_configure_args1;}
++
++# When interrupted or exit'd, cleanup temporary files, and complete
++# config.log.  We remove comments because anyway the quotes in there
++# would cause problems or look ugly.
++# WARNING: Use '\'' to represent an apostrophe within the trap.
++# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
++trap 'exit_status=$?
++  # Save into config.log some information that might help in debugging.
++  {
++    echo
++
++    $as_echo "## ---------------- ##
++## Cache variables. ##
++## ---------------- ##"
++    echo
++    # The following way of writing the cache mishandles newlines in values,
++(
++  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
++    eval ac_val=\$$ac_var
++    case $ac_val in #(
++    *${as_nl}*)
++      case $ac_var in #(
++      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
++      esac
++      case $ac_var in #(
++      _ | IFS | as_nl) ;; #(
++      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
++      *) { eval $ac_var=; unset $ac_var;} ;;
++      esac ;;
++    esac
++  done
++  (set) 2>&1 |
++    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
++    *${as_nl}ac_space=\ *)
++      sed -n \
++	"s/'\''/'\''\\\\'\'''\''/g;
++	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
++      ;; #(
++    *)
++      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
++      ;;
++    esac |
++    sort
++)
++    echo
++
++    $as_echo "## ----------------- ##
++## Output variables. ##
++## ----------------- ##"
++    echo
++    for ac_var in $ac_subst_vars
++    do
++      eval ac_val=\$$ac_var
++      case $ac_val in
++      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
++      esac
++      $as_echo "$ac_var='\''$ac_val'\''"
++    done | sort
++    echo
++
++    if test -n "$ac_subst_files"; then
++      $as_echo "## ------------------- ##
++## File substitutions. ##
++## ------------------- ##"
++      echo
++      for ac_var in $ac_subst_files
++      do
++	eval ac_val=\$$ac_var
++	case $ac_val in
++	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
++	esac
++	$as_echo "$ac_var='\''$ac_val'\''"
++      done | sort
++      echo
++    fi
++
++    if test -s confdefs.h; then
++      $as_echo "## ----------- ##
++## confdefs.h. ##
++## ----------- ##"
++      echo
++      cat confdefs.h
++      echo
++    fi
++    test "$ac_signal" != 0 &&
++      $as_echo "$as_me: caught signal $ac_signal"
++    $as_echo "$as_me: exit $exit_status"
++  } >&5
++  rm -f core *.core core.conftest.* &&
++    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
++    exit $exit_status
++' 0
++for ac_signal in 1 2 13 15; do
++  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
++done
++ac_signal=0
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -f -r conftest* confdefs.h
++
++$as_echo "/* confdefs.h */" > confdefs.h
++
++# Predefined preprocessor variables.
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_NAME "$PACKAGE_NAME"
++_ACEOF
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
++_ACEOF
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_VERSION "$PACKAGE_VERSION"
++_ACEOF
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_STRING "$PACKAGE_STRING"
++_ACEOF
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
++_ACEOF
++
++cat >>confdefs.h <<_ACEOF
++#define PACKAGE_URL "$PACKAGE_URL"
++_ACEOF
++
++
++# Let the site file select an alternate cache file if it wants to.
++# Prefer an explicitly selected file to automatically selected ones.
++ac_site_file1=NONE
++ac_site_file2=NONE
++if test -n "$CONFIG_SITE"; then
++  # We do not want a PATH search for config.site.
++  case $CONFIG_SITE in #((
++    -*)  ac_site_file1=./$CONFIG_SITE;;
++    */*) ac_site_file1=$CONFIG_SITE;;
++    *)   ac_site_file1=./$CONFIG_SITE;;
++  esac
++elif test "x$prefix" != xNONE; then
++  ac_site_file1=$prefix/share/config.site
++  ac_site_file2=$prefix/etc/config.site
++else
++  ac_site_file1=$ac_default_prefix/share/config.site
++  ac_site_file2=$ac_default_prefix/etc/config.site
++fi
++for ac_site_file in "$ac_site_file1" "$ac_site_file2"
++do
++  test "x$ac_site_file" = xNONE && continue
++  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
++$as_echo "$as_me: loading site script $ac_site_file" >&6;}
++    sed 's/^/| /' "$ac_site_file" >&5
++    . "$ac_site_file" \
++      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "failed to load site script $ac_site_file
++See \`config.log' for more details" "$LINENO" 5; }
++  fi
++done
++
++if test -r "$cache_file"; then
++  # Some versions of bash will fail to source /dev/null (special files
++  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
++  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
++    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
++$as_echo "$as_me: loading cache $cache_file" >&6;}
++    case $cache_file in
++      [\\/]* | ?:[\\/]* ) . "$cache_file";;
++      *)                      . "./$cache_file";;
++    esac
++  fi
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
++$as_echo "$as_me: creating cache $cache_file" >&6;}
++  >$cache_file
++fi
++
++# Check that the precious variables saved in the cache have kept the same
++# value.
++ac_cache_corrupted=false
++for ac_var in $ac_precious_vars; do
++  eval ac_old_set=\$ac_cv_env_${ac_var}_set
++  eval ac_new_set=\$ac_env_${ac_var}_set
++  eval ac_old_val=\$ac_cv_env_${ac_var}_value
++  eval ac_new_val=\$ac_env_${ac_var}_value
++  case $ac_old_set,$ac_new_set in
++    set,)
++      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
++$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
++      ac_cache_corrupted=: ;;
++    ,set)
++      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
++$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
++      ac_cache_corrupted=: ;;
++    ,);;
++    *)
++      if test "x$ac_old_val" != "x$ac_new_val"; then
++	# differences in whitespace do not lead to failure.
++	ac_old_val_w=`echo x $ac_old_val`
++	ac_new_val_w=`echo x $ac_new_val`
++	if test "$ac_old_val_w" != "$ac_new_val_w"; then
++	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
++$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
++	  ac_cache_corrupted=:
++	else
++	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
++$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
++	  eval $ac_var=\$ac_old_val
++	fi
++	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
++$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
++	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
++$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
++      fi;;
++  esac
++  # Pass precious variables to config.status.
++  if test "$ac_new_set" = set; then
++    case $ac_new_val in
++    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
++    *) ac_arg=$ac_var=$ac_new_val ;;
++    esac
++    case " $ac_configure_args " in
++      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
++      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
++    esac
++  fi
++done
++if $ac_cache_corrupted; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
++$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
++  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
++fi
++## -------------------- ##
++## Main body of script. ##
++## -------------------- ##
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++
++#--------------------------------------------------------------------
++# Call TEA_INIT as the first TEA_ macro to set up initial vars.
++# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
++# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
++#--------------------------------------------------------------------
++
++
++    # TEA extensions pass this us the version of TEA they think they
++    # are compatible with.
++    TEA_VERSION="3.9"
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5
++$as_echo_n "checking for correct TEA configuration... " >&6; }
++    if test x"${PACKAGE_NAME}" = x ; then
++	as_fn_error $? "
++The PACKAGE_NAME variable must be defined by your TEA configure.in" "$LINENO" 5
++    fi
++    if test x"3.9" = x ; then
++	as_fn_error $? "
++TEA version not specified." "$LINENO" 5
++    elif test "3.9" != "${TEA_VERSION}" ; then
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5
++$as_echo "warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6; }
++    else
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5
++$as_echo "ok (TEA ${TEA_VERSION})" >&6; }
++    fi
++
++    # If the user did not set CFLAGS, set it now to keep macros
++    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
++    if test "${CFLAGS+set}" != "set" ; then
++	CFLAGS=""
++    fi
++
++    case "`uname -s`" in
++	*win32*|*WIN32*|*MINGW32_*)
++	    # Extract the first word of "cygpath", so it can be a program name with args.
++set dummy cygpath; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CYGPATH+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CYGPATH"; then
++  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CYGPATH="cygpath -w"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
++fi
++fi
++CYGPATH=$ac_cv_prog_CYGPATH
++if test -n "$CYGPATH"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5
++$as_echo "$CYGPATH" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++	    EXEEXT=".exe"
++	    TEA_PLATFORM="windows"
++	    ;;
++	*CYGWIN_*)
++	    CYGPATH=echo
++	    EXEEXT=".exe"
++	    # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
++	    ;;
++	*)
++	    CYGPATH=echo
++	    # Maybe we are cross-compiling....
++	    case ${host_alias} in
++		*mingw32*)
++		EXEEXT=".exe"
++		TEA_PLATFORM="windows"
++		;;
++	    *)
++		EXEEXT=""
++		TEA_PLATFORM="unix"
++		;;
++	    esac
++	    ;;
++    esac
++
++    # Check if exec_prefix is set. If not use fall back to prefix.
++    # Note when adjusted, so that TEA_PREFIX can correct for this.
++    # This is needed for recursive configures, since autoconf propagates
++    # $prefix, but not $exec_prefix (doh!).
++    if test x$exec_prefix = xNONE ; then
++	exec_prefix_default=yes
++	exec_prefix=$prefix
++    fi
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5
++$as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;}
++
++
++
++
++    # This package name must be replaced statically for AC_SUBST to work
++
++    # Substitute STUB_LIB_FILE in case package creates a stub library too.
++
++
++    # We AC_SUBST these here to ensure they are subst'ed,
++    # in case the user doesn't call TEA_ADD_...
++
++
++
++
++
++
++
++
++
++ac_aux_dir=
++for ac_dir in tclconfig "$srcdir"/tclconfig; do
++  if test -f "$ac_dir/install-sh"; then
++    ac_aux_dir=$ac_dir
++    ac_install_sh="$ac_aux_dir/install-sh -c"
++    break
++  elif test -f "$ac_dir/install.sh"; then
++    ac_aux_dir=$ac_dir
++    ac_install_sh="$ac_aux_dir/install.sh -c"
++    break
++  elif test -f "$ac_dir/shtool"; then
++    ac_aux_dir=$ac_dir
++    ac_install_sh="$ac_aux_dir/shtool install -c"
++    break
++  fi
++done
++if test -z "$ac_aux_dir"; then
++  as_fn_error $? "cannot find install-sh, install.sh, or shtool in tclconfig \"$srcdir\"/tclconfig" "$LINENO" 5
++fi
++
++# These three variables are undocumented and unsupported,
++# and are intended to be withdrawn in a future Autoconf release.
++# They can cause serious problems if a builder's source tree is in a directory
++# whose full name contains unusual characters.
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
++ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
++
++
++
++#--------------------------------------------------------------------
++# Load the tclConfig.sh file
++#--------------------------------------------------------------------
++
++
++
++    #
++    # Ok, lets find the tcl configuration
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-tcl
++    #
++
++    if test x"${no_tcl}" = x ; then
++	# we reset no_tcl in case something fails here
++	no_tcl=true
++
++# Check whether --with-tcl was given.
++if test "${with_tcl+set}" = set; then :
++  withval=$with_tcl; with_tclconfig="${withval}"
++fi
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
++$as_echo_n "checking for Tcl configuration... " >&6; }
++	if ${ac_cv_c_tclconfig+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++
++	    # First check to see if --with-tcl was specified.
++	    if test x"${with_tclconfig}" != x ; then
++		case "${with_tclconfig}" in
++		    */tclConfig.sh )
++			if test -f "${with_tclconfig}"; then
++			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5
++$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;}
++			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
++			fi ;;
++		esac
++		if test -f "${with_tclconfig}/tclConfig.sh" ; then
++		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
++		else
++		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
++		fi
++	    fi
++
++	    # then check for a private Tcl installation
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in \
++			../tcl \
++			`ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
++			`ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \
++			`ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
++			../../tcl \
++			`ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
++			`ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \
++			`ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
++			../../../tcl \
++			`ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
++			`ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \
++			`ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # on Darwin, check in Framework installation locations
++	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
++			`ls -d /Library/Frameworks 2>/dev/null` \
++			`ls -d /Network/Library/Frameworks 2>/dev/null` \
++			`ls -d /System/Library/Frameworks 2>/dev/null` \
++			; do
++		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # TEA specific: on Windows, check in common installation locations
++	    if test "${TEA_PLATFORM}" = "windows" \
++		-a x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
++			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
++			; do
++		    if test -f "$i/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few common install locations
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d ${libdir} 2>/dev/null` \
++			`ls -d ${exec_prefix}/lib 2>/dev/null` \
++			`ls -d ${prefix}/lib 2>/dev/null` \
++			`ls -d /usr/local/lib 2>/dev/null` \
++			`ls -d /usr/contrib/lib 2>/dev/null` \
++			`ls -d /usr/lib 2>/dev/null` \
++			`ls -d /usr/lib64 2>/dev/null` \
++			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
++			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
++			; do
++		    if test -f "$i/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few other private locations
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in \
++			${srcdir}/../tcl \
++			`ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \
++			`ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \
++			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++fi
++
++
++	if test x"${ac_cv_c_tclconfig}" = x ; then
++	    TCL_BIN_DIR="# no Tcl configs found"
++	    as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5
++	else
++	    no_tcl=
++	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5
++$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
++	fi
++    fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}gcc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="${ac_tool_prefix}gcc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_CC"; then
++  ac_ct_CC=$CC
++  # Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_CC"; then
++  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_CC="gcc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++$as_echo "$ac_ct_CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_CC" = x; then
++    CC=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    CC=$ac_ct_CC
++  fi
++else
++  CC="$ac_cv_prog_CC"
++fi
++
++if test -z "$CC"; then
++          if test -n "$ac_tool_prefix"; then
++    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}cc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="${ac_tool_prefix}cc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++  fi
++fi
++if test -z "$CC"; then
++  # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++  ac_prog_rejected=no
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
++       ac_prog_rejected=yes
++       continue
++     fi
++    ac_cv_prog_CC="cc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++if test $ac_prog_rejected = yes; then
++  # We found a bogon in the path, so make sure we never use it.
++  set dummy $ac_cv_prog_CC
++  shift
++  if test $# != 0; then
++    # We chose a different compiler from the bogus one.
++    # However, it has the same basename, so the bogon will be chosen
++    # first if we set CC to just the basename; use the full file name.
++    shift
++    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
++  fi
++fi
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$CC"; then
++  if test -n "$ac_tool_prefix"; then
++  for ac_prog in cl.exe
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++    test -n "$CC" && break
++  done
++fi
++if test -z "$CC"; then
++  ac_ct_CC=$CC
++  for ac_prog in cl.exe
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_CC"; then
++  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_CC="$ac_prog"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++$as_echo "$ac_ct_CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++  test -n "$ac_ct_CC" && break
++done
++
++  if test "x$ac_ct_CC" = x; then
++    CC=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    CC=$ac_ct_CC
++  fi
++fi
++
++fi
++
++
++test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "no acceptable C compiler found in \$PATH
++See \`config.log' for more details" "$LINENO" 5; }
++
++# Provide some information about the compiler.
++$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
++set X $ac_compile
++ac_compiler=$2
++for ac_option in --version -v -V -qversion; do
++  { { ac_try="$ac_compiler $ac_option >&5"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
++  ac_status=$?
++  if test -s conftest.err; then
++    sed '10a\
++... rest of stderr output deleted ...
++         10q' conftest.err >conftest.er1
++    cat conftest.er1 >&5
++  fi
++  rm -f conftest.er1 conftest.err
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++done
++
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
++# Try to create an executable without -o first, disregard a.out.
++# It will help us diagnose broken compilers, and finding out an intuition
++# of exeext.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
++$as_echo_n "checking whether the C compiler works... " >&6; }
++ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
++
++# The possible output files:
++ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
++
++ac_rmfiles=
++for ac_file in $ac_files
++do
++  case $ac_file in
++    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
++    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
++  esac
++done
++rm -f $ac_rmfiles
++
++if { { ac_try="$ac_link_default"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_link_default") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; then :
++  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
++# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
++# in a Makefile.  We should not override ac_cv_exeext if it was cached,
++# so that the user can short-circuit this test for compilers unknown to
++# Autoconf.
++for ac_file in $ac_files ''
++do
++  test -f "$ac_file" || continue
++  case $ac_file in
++    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
++	;;
++    [ab].out )
++	# We found the default executable, but exeext='' is most
++	# certainly right.
++	break;;
++    *.* )
++	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
++	then :; else
++	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++	fi
++	# We set ac_cv_exeext here because the later test for it is not
++	# safe: cross compilers may not add the suffix if given an `-o'
++	# argument, so we may need to know it at that point already.
++	# Even if this section looks crufty: it has the advantage of
++	# actually working.
++	break;;
++    * )
++	break;;
++  esac
++done
++test "$ac_cv_exeext" = no && ac_cv_exeext=
++
++else
++  ac_file=''
++fi
++if test -z "$ac_file"; then :
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++$as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error 77 "C compiler cannot create executables
++See \`config.log' for more details" "$LINENO" 5; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
++$as_echo_n "checking for C compiler default output file name... " >&6; }
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
++$as_echo "$ac_file" >&6; }
++ac_exeext=$ac_cv_exeext
++
++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
++ac_clean_files=$ac_clean_files_save
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
++$as_echo_n "checking for suffix of executables... " >&6; }
++if { { ac_try="$ac_link"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_link") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; then :
++  # If both `conftest.exe' and `conftest' are `present' (well, observable)
++# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
++# work properly (i.e., refer to `conftest.exe'), while it won't with
++# `rm'.
++for ac_file in conftest.exe conftest conftest.*; do
++  test -f "$ac_file" || continue
++  case $ac_file in
++    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
++    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++	  break;;
++    * ) break;;
++  esac
++done
++else
++  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "cannot compute suffix of executables: cannot compile and link
++See \`config.log' for more details" "$LINENO" 5; }
++fi
++rm -f conftest conftest$ac_cv_exeext
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
++$as_echo "$ac_cv_exeext" >&6; }
++
++rm -f conftest.$ac_ext
++EXEEXT=$ac_cv_exeext
++ac_exeext=$EXEEXT
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdio.h>
++int
++main ()
++{
++FILE *f = fopen ("conftest.out", "w");
++ return ferror (f) || fclose (f) != 0;
++
++  ;
++  return 0;
++}
++_ACEOF
++ac_clean_files="$ac_clean_files conftest.out"
++# Check that the compiler produces executables we can run.  If not, either
++# the compiler is broken, or we cross compile.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
++$as_echo_n "checking whether we are cross compiling... " >&6; }
++if test "$cross_compiling" != yes; then
++  { { ac_try="$ac_link"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_link") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++  if { ac_try='./conftest$ac_cv_exeext'
++  { { case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_try") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; }; then
++    cross_compiling=no
++  else
++    if test "$cross_compiling" = maybe; then
++	cross_compiling=yes
++    else
++	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "cannot run C compiled programs.
++If you meant to cross compile, use \`--host'.
++See \`config.log' for more details" "$LINENO" 5; }
++    fi
++  fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
++$as_echo "$cross_compiling" >&6; }
++
++rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
++ac_clean_files=$ac_clean_files_save
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
++$as_echo_n "checking for suffix of object files... " >&6; }
++if ${ac_cv_objext+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.o conftest.obj
++if { { ac_try="$ac_compile"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_compile") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; then :
++  for ac_file in conftest.o conftest.obj conftest.*; do
++  test -f "$ac_file" || continue;
++  case $ac_file in
++    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
++    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
++       break;;
++  esac
++done
++else
++  $as_echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "cannot compute suffix of object files: cannot compile
++See \`config.log' for more details" "$LINENO" 5; }
++fi
++rm -f conftest.$ac_cv_objext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
++$as_echo "$ac_cv_objext" >&6; }
++OBJEXT=$ac_cv_objext
++ac_objext=$OBJEXT
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
++if ${ac_cv_c_compiler_gnu+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++#ifndef __GNUC__
++       choke me
++#endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_compiler_gnu=yes
++else
++  ac_compiler_gnu=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++ac_cv_c_compiler_gnu=$ac_compiler_gnu
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
++$as_echo "$ac_cv_c_compiler_gnu" >&6; }
++if test $ac_compiler_gnu = yes; then
++  GCC=yes
++else
++  GCC=
++fi
++ac_test_CFLAGS=${CFLAGS+set}
++ac_save_CFLAGS=$CFLAGS
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
++$as_echo_n "checking whether $CC accepts -g... " >&6; }
++if ${ac_cv_prog_cc_g+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_save_c_werror_flag=$ac_c_werror_flag
++   ac_c_werror_flag=yes
++   ac_cv_prog_cc_g=no
++   CFLAGS="-g"
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_g=yes
++else
++  CFLAGS=""
++      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++
++else
++  ac_c_werror_flag=$ac_save_c_werror_flag
++	 CFLAGS="-g"
++	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_g=yes
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++   ac_c_werror_flag=$ac_save_c_werror_flag
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
++$as_echo "$ac_cv_prog_cc_g" >&6; }
++if test "$ac_test_CFLAGS" = set; then
++  CFLAGS=$ac_save_CFLAGS
++elif test $ac_cv_prog_cc_g = yes; then
++  if test "$GCC" = yes; then
++    CFLAGS="-g -O2"
++  else
++    CFLAGS="-g"
++  fi
++else
++  if test "$GCC" = yes; then
++    CFLAGS="-O2"
++  else
++    CFLAGS=
++  fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
++if ${ac_cv_prog_cc_c89+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_cv_prog_cc_c89=no
++ac_save_CC=$CC
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdarg.h>
++#include <stdio.h>
++struct stat;
++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
++struct buf { int x; };
++FILE * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++     char **p;
++     int i;
++{
++  return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++  char *s;
++  va_list v;
++  va_start (v,p);
++  s = g (p, va_arg (v,int));
++  va_end (v);
++  return s;
++}
++
++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
++   function prototypes and stuff, but not '\xHH' hex character constants.
++   These don't provoke an error unfortunately, instead are silently treated
++   as 'x'.  The following induces an error, until -std is added to get
++   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
++   array size at least.  It's necessary to write '\x00'==0 to get something
++   that's true only with -std.  */
++int osf4_cc_array ['\x00' == 0 ? 1 : -1];
++
++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
++   inside strings and character constants.  */
++#define FOO(x) 'x'
++int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
++
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
++int argc;
++char **argv;
++int
++main ()
++{
++return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
++  ;
++  return 0;
++}
++_ACEOF
++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
++	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++do
++  CC="$ac_save_CC $ac_arg"
++  if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_c89=$ac_arg
++fi
++rm -f core conftest.err conftest.$ac_objext
++  test "x$ac_cv_prog_cc_c89" != "xno" && break
++done
++rm -f conftest.$ac_ext
++CC=$ac_save_CC
++
++fi
++# AC_CACHE_VAL
++case "x$ac_cv_prog_cc_c89" in
++  x)
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
++$as_echo "none needed" >&6; } ;;
++  xno)
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
++$as_echo "unsupported" >&6; } ;;
++  *)
++    CC="$CC $ac_cv_prog_cc_c89"
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
++esac
++if test "x$ac_cv_prog_cc_c89" != xno; then :
++
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5
++$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; }
++
++    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
++$as_echo "loading" >&6; }
++	. "${TCL_BIN_DIR}/tclConfig.sh"
++    else
++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5
++$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; }
++    fi
++
++    # eval is required to do the TCL_DBGX substitution
++    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
++    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
++
++    # If the TCL_BIN_DIR is the build directory (not the install directory),
++    # then set the common variable name to the value of the build variables.
++    # For example, the variable TCL_LIB_SPEC will be set to the value
++    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
++    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
++    # installed and uninstalled version of Tcl.
++    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
++        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
++        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
++    elif test "`uname -s`" = "Darwin"; then
++	# If Tcl was built as a framework, attempt to use the libraries
++	# from the framework at the given location so that linking works
++	# against Tcl.framework installed in an arbitrary location.
++	case ${TCL_DEFS} in
++	    *TCL_FRAMEWORK*)
++		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
++		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
++			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
++			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
++			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
++			    break
++			fi
++		    done
++		fi
++		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
++		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
++		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
++		fi
++		;;
++	esac
++    fi
++
++    # eval is required to do the TCL_DBGX substitution
++    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
++    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
++    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
++    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking platform" >&5
++$as_echo_n "checking platform... " >&6; }
++    hold_cc=$CC; CC="$TCL_CC"
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++	    #ifdef _WIN32
++		#error win32
++	    #endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  TEA_PLATFORM="unix"
++else
++  TEA_PLATFORM="windows"
++
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++    CC=$hold_cc
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEA_PLATFORM" >&5
++$as_echo "$TEA_PLATFORM" >&6; }
++
++    # The BUILD_$pkg is to define the correct extern storage class
++    # handling when making this package
++
++cat >>confdefs.h <<_ACEOF
++#define BUILD_${PACKAGE_NAME} /**/
++_ACEOF
++
++    # Do this here as we have fully defined TEA_PLATFORM now
++    if test "${TEA_PLATFORM}" = "windows" ; then
++	EXEEXT=".exe"
++	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
++    fi
++
++    # TEA specific:
++
++
++
++
++
++
++
++
++#--------------------------------------------------------------------
++# Load the tkConfig.sh file if necessary (Tk extension)
++#--------------------------------------------------------------------
++
++#TEA_PATH_TKCONFIG
++#TEA_LOAD_TKCONFIG
++
++#-----------------------------------------------------------------------
++# Handle the --prefix=... option by defaulting to what Tcl gave.
++# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
++#-----------------------------------------------------------------------
++
++
++    if test "${prefix}" = "NONE"; then
++	prefix_default=yes
++	if test x"${TCL_PREFIX}" != x; then
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&5
++$as_echo "$as_me: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" >&6;}
++	    prefix=${TCL_PREFIX}
++	else
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: --prefix defaulting to /usr/local" >&5
++$as_echo "$as_me: --prefix defaulting to /usr/local" >&6;}
++	    prefix=/usr/local
++	fi
++    fi
++    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
++	-o x"${exec_prefix_default}" = x"yes" ; then
++	if test x"${TCL_EXEC_PREFIX}" != x; then
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&5
++$as_echo "$as_me: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" >&6;}
++	    exec_prefix=${TCL_EXEC_PREFIX}
++	else
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: --exec-prefix defaulting to ${prefix}" >&5
++$as_echo "$as_me: --exec-prefix defaulting to ${prefix}" >&6;}
++	    exec_prefix=$prefix
++	fi
++    fi
++
++
++#-----------------------------------------------------------------------
++# Standard compiler checks.
++# This sets up CC by using the CC env var, or looks for gcc otherwise.
++# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
++# the basic setup necessary to compile executables.
++#-----------------------------------------------------------------------
++
++
++    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
++    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
++
++    ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}gcc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="${ac_tool_prefix}gcc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_CC"; then
++  ac_ct_CC=$CC
++  # Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_CC"; then
++  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_CC="gcc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++$as_echo "$ac_ct_CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_CC" = x; then
++    CC=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    CC=$ac_ct_CC
++  fi
++else
++  CC="$ac_cv_prog_CC"
++fi
++
++if test -z "$CC"; then
++          if test -n "$ac_tool_prefix"; then
++    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}cc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="${ac_tool_prefix}cc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++  fi
++fi
++if test -z "$CC"; then
++  # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++  ac_prog_rejected=no
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
++       ac_prog_rejected=yes
++       continue
++     fi
++    ac_cv_prog_CC="cc"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++if test $ac_prog_rejected = yes; then
++  # We found a bogon in the path, so make sure we never use it.
++  set dummy $ac_cv_prog_CC
++  shift
++  if test $# != 0; then
++    # We chose a different compiler from the bogus one.
++    # However, it has the same basename, so the bogon will be chosen
++    # first if we set CC to just the basename; use the full file name.
++    shift
++    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
++  fi
++fi
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$CC"; then
++  if test -n "$ac_tool_prefix"; then
++  for ac_prog in cl.exe
++  do
++    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$CC"; then
++  ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
++$as_echo "$CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++    test -n "$CC" && break
++  done
++fi
++if test -z "$CC"; then
++  ac_ct_CC=$CC
++  for ac_prog in cl.exe
++do
++  # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_CC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_CC"; then
++  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_CC="$ac_prog"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
++$as_echo "$ac_ct_CC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++  test -n "$ac_ct_CC" && break
++done
++
++  if test "x$ac_ct_CC" = x; then
++    CC=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    CC=$ac_ct_CC
++  fi
++fi
++
++fi
++
++
++test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "no acceptable C compiler found in \$PATH
++See \`config.log' for more details" "$LINENO" 5; }
++
++# Provide some information about the compiler.
++$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
++set X $ac_compile
++ac_compiler=$2
++for ac_option in --version -v -V -qversion; do
++  { { ac_try="$ac_compiler $ac_option >&5"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
++$as_echo "$ac_try_echo"; } >&5
++  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
++  ac_status=$?
++  if test -s conftest.err; then
++    sed '10a\
++... rest of stderr output deleted ...
++         10q' conftest.err >conftest.er1
++    cat conftest.er1 >&5
++  fi
++  rm -f conftest.er1 conftest.err
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }
++done
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
++$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
++if ${ac_cv_c_compiler_gnu+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++#ifndef __GNUC__
++       choke me
++#endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_compiler_gnu=yes
++else
++  ac_compiler_gnu=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++ac_cv_c_compiler_gnu=$ac_compiler_gnu
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
++$as_echo "$ac_cv_c_compiler_gnu" >&6; }
++if test $ac_compiler_gnu = yes; then
++  GCC=yes
++else
++  GCC=
++fi
++ac_test_CFLAGS=${CFLAGS+set}
++ac_save_CFLAGS=$CFLAGS
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
++$as_echo_n "checking whether $CC accepts -g... " >&6; }
++if ${ac_cv_prog_cc_g+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_save_c_werror_flag=$ac_c_werror_flag
++   ac_c_werror_flag=yes
++   ac_cv_prog_cc_g=no
++   CFLAGS="-g"
++   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_g=yes
++else
++  CFLAGS=""
++      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++
++else
++  ac_c_werror_flag=$ac_save_c_werror_flag
++	 CFLAGS="-g"
++	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_g=yes
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++   ac_c_werror_flag=$ac_save_c_werror_flag
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
++$as_echo "$ac_cv_prog_cc_g" >&6; }
++if test "$ac_test_CFLAGS" = set; then
++  CFLAGS=$ac_save_CFLAGS
++elif test $ac_cv_prog_cc_g = yes; then
++  if test "$GCC" = yes; then
++    CFLAGS="-g -O2"
++  else
++    CFLAGS="-g"
++  fi
++else
++  if test "$GCC" = yes; then
++    CFLAGS="-O2"
++  else
++    CFLAGS=
++  fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
++$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
++if ${ac_cv_prog_cc_c89+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_cv_prog_cc_c89=no
++ac_save_CC=$CC
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdarg.h>
++#include <stdio.h>
++struct stat;
++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
++struct buf { int x; };
++FILE * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++     char **p;
++     int i;
++{
++  return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++  char *s;
++  va_list v;
++  va_start (v,p);
++  s = g (p, va_arg (v,int));
++  va_end (v);
++  return s;
++}
++
++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
++   function prototypes and stuff, but not '\xHH' hex character constants.
++   These don't provoke an error unfortunately, instead are silently treated
++   as 'x'.  The following induces an error, until -std is added to get
++   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
++   array size at least.  It's necessary to write '\x00'==0 to get something
++   that's true only with -std.  */
++int osf4_cc_array ['\x00' == 0 ? 1 : -1];
++
++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
++   inside strings and character constants.  */
++#define FOO(x) 'x'
++int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
++
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
++int argc;
++char **argv;
++int
++main ()
++{
++return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
++  ;
++  return 0;
++}
++_ACEOF
++for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
++	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++do
++  CC="$ac_save_CC $ac_arg"
++  if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_prog_cc_c89=$ac_arg
++fi
++rm -f core conftest.err conftest.$ac_objext
++  test "x$ac_cv_prog_cc_c89" != "xno" && break
++done
++rm -f conftest.$ac_ext
++CC=$ac_save_CC
++
++fi
++# AC_CACHE_VAL
++case "x$ac_cv_prog_cc_c89" in
++  x)
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
++$as_echo "none needed" >&6; } ;;
++  xno)
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
++$as_echo "unsupported" >&6; } ;;
++  *)
++    CC="$CC $ac_cv_prog_cc_c89"
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
++$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
++esac
++if test "x$ac_cv_prog_cc_c89" != xno; then :
++
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++    ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
++$as_echo_n "checking how to run the C preprocessor... " >&6; }
++# On Suns, sometimes $CPP names a directory.
++if test -n "$CPP" && test -d "$CPP"; then
++  CPP=
++fi
++if test -z "$CPP"; then
++  if ${ac_cv_prog_CPP+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++      # Double quotes because CPP needs to be expanded
++    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
++    do
++      ac_preproc_ok=false
++for ac_c_preproc_warn_flag in '' yes
++do
++  # Use a header file that comes with gcc, so configuring glibc
++  # with a fresh cross-compiler works.
++  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++  # <limits.h> exists even on freestanding compilers.
++  # On the NeXT, cc -E runs the code through the compiler's parser,
++  # not just through cpp. "Syntax error" is here to catch this case.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
++		     Syntax error
++_ACEOF
++if ac_fn_c_try_cpp "$LINENO"; then :
++
++else
++  # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.i conftest.$ac_ext
++
++  # OK, works on sane cases.  Now check whether nonexistent headers
++  # can be detected and how.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <ac_nonexistent.h>
++_ACEOF
++if ac_fn_c_try_cpp "$LINENO"; then :
++  # Broken: success on invalid input.
++continue
++else
++  # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.i conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.i conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then :
++  break
++fi
++
++    done
++    ac_cv_prog_CPP=$CPP
++
++fi
++  CPP=$ac_cv_prog_CPP
++else
++  ac_cv_prog_CPP=$CPP
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
++$as_echo "$CPP" >&6; }
++ac_preproc_ok=false
++for ac_c_preproc_warn_flag in '' yes
++do
++  # Use a header file that comes with gcc, so configuring glibc
++  # with a fresh cross-compiler works.
++  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++  # <limits.h> exists even on freestanding compilers.
++  # On the NeXT, cc -E runs the code through the compiler's parser,
++  # not just through cpp. "Syntax error" is here to catch this case.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
++		     Syntax error
++_ACEOF
++if ac_fn_c_try_cpp "$LINENO"; then :
++
++else
++  # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.i conftest.$ac_ext
++
++  # OK, works on sane cases.  Now check whether nonexistent headers
++  # can be detected and how.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <ac_nonexistent.h>
++_ACEOF
++if ac_fn_c_try_cpp "$LINENO"; then :
++  # Broken: success on invalid input.
++continue
++else
++  # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.i conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.i conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then :
++
++else
++  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
++See \`config.log' for more details" "$LINENO" 5; }
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++    INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
++
++    INSTALL_DATA="\${INSTALL} -m 644"
++
++    INSTALL_PROGRAM="\${INSTALL}"
++
++    INSTALL_SCRIPT="\${INSTALL}"
++
++
++    #--------------------------------------------------------------------
++    # Checks to see if the make program sets the $MAKE variable.
++    #--------------------------------------------------------------------
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
++$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
++set x ${MAKE-make}
++ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
++if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat >conftest.make <<\_ACEOF
++SHELL = /bin/sh
++all:
++	@echo '@@@%%%=$(MAKE)=@@@%%%'
++_ACEOF
++# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
++case `${MAKE-make} -f conftest.make 2>/dev/null` in
++  *@@@%%%=?*=@@@%%%*)
++    eval ac_cv_prog_make_${ac_make}_set=yes;;
++  *)
++    eval ac_cv_prog_make_${ac_make}_set=no;;
++esac
++rm -f conftest.make
++fi
++if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++  SET_MAKE=
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++  SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++
++    #--------------------------------------------------------------------
++    # Find ranlib
++    #--------------------------------------------------------------------
++
++    if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_RANLIB+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$RANLIB"; then
++  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
++$as_echo "$RANLIB" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++  ac_ct_RANLIB=$RANLIB
++  # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_RANLIB"; then
++  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_RANLIB="ranlib"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
++$as_echo "$ac_ct_RANLIB" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_RANLIB" = x; then
++    RANLIB=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    RANLIB=$ac_ct_RANLIB
++  fi
++else
++  RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++
++    #--------------------------------------------------------------------
++    # Determines the correct binary file extension (.o, .obj, .exe etc.)
++    #--------------------------------------------------------------------
++
++
++
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
++$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
++if ${ac_cv_path_GREP+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -z "$GREP"; then
++  ac_path_GREP_found=false
++  # Loop through the user's path and test for each of PROGNAME-LIST
++  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_prog in grep ggrep; do
++    for ac_exec_ext in '' $ac_executable_extensions; do
++      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
++      as_fn_executable_p "$ac_path_GREP" || continue
++# Check for GNU ac_path_GREP and select it if it is found.
++  # Check for GNU $ac_path_GREP
++case `"$ac_path_GREP" --version 2>&1` in
++*GNU*)
++  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
++*)
++  ac_count=0
++  $as_echo_n 0123456789 >"conftest.in"
++  while :
++  do
++    cat "conftest.in" "conftest.in" >"conftest.tmp"
++    mv "conftest.tmp" "conftest.in"
++    cp "conftest.in" "conftest.nl"
++    $as_echo 'GREP' >> "conftest.nl"
++    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
++    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
++    as_fn_arith $ac_count + 1 && ac_count=$as_val
++    if test $ac_count -gt ${ac_path_GREP_max-0}; then
++      # Best one so far, save it but keep looking for a better one
++      ac_cv_path_GREP="$ac_path_GREP"
++      ac_path_GREP_max=$ac_count
++    fi
++    # 10*(2^10) chars as input seems more than enough
++    test $ac_count -gt 10 && break
++  done
++  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
++esac
++
++      $ac_path_GREP_found && break 3
++    done
++  done
++  done
++IFS=$as_save_IFS
++  if test -z "$ac_cv_path_GREP"; then
++    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
++  fi
++else
++  ac_cv_path_GREP=$GREP
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
++$as_echo "$ac_cv_path_GREP" >&6; }
++ GREP="$ac_cv_path_GREP"
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
++$as_echo_n "checking for egrep... " >&6; }
++if ${ac_cv_path_EGREP+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
++   then ac_cv_path_EGREP="$GREP -E"
++   else
++     if test -z "$EGREP"; then
++  ac_path_EGREP_found=false
++  # Loop through the user's path and test for each of PROGNAME-LIST
++  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_prog in egrep; do
++    for ac_exec_ext in '' $ac_executable_extensions; do
++      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
++      as_fn_executable_p "$ac_path_EGREP" || continue
++# Check for GNU ac_path_EGREP and select it if it is found.
++  # Check for GNU $ac_path_EGREP
++case `"$ac_path_EGREP" --version 2>&1` in
++*GNU*)
++  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
++*)
++  ac_count=0
++  $as_echo_n 0123456789 >"conftest.in"
++  while :
++  do
++    cat "conftest.in" "conftest.in" >"conftest.tmp"
++    mv "conftest.tmp" "conftest.in"
++    cp "conftest.in" "conftest.nl"
++    $as_echo 'EGREP' >> "conftest.nl"
++    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
++    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
++    as_fn_arith $ac_count + 1 && ac_count=$as_val
++    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
++      # Best one so far, save it but keep looking for a better one
++      ac_cv_path_EGREP="$ac_path_EGREP"
++      ac_path_EGREP_max=$ac_count
++    fi
++    # 10*(2^10) chars as input seems more than enough
++    test $ac_count -gt 10 && break
++  done
++  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
++esac
++
++      $ac_path_EGREP_found && break 3
++    done
++  done
++  done
++IFS=$as_save_IFS
++  if test -z "$ac_cv_path_EGREP"; then
++    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
++  fi
++else
++  ac_cv_path_EGREP=$EGREP
++fi
++
++   fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
++$as_echo "$ac_cv_path_EGREP" >&6; }
++ EGREP="$ac_cv_path_EGREP"
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
++$as_echo_n "checking for ANSI C header files... " >&6; }
++if ${ac_cv_header_stdc+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++#include <stdarg.h>
++#include <string.h>
++#include <float.h>
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_header_stdc=yes
++else
++  ac_cv_header_stdc=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++if test $ac_cv_header_stdc = yes; then
++  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <string.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "memchr" >/dev/null 2>&1; then :
++
++else
++  ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++if test $ac_cv_header_stdc = yes; then
++  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "free" >/dev/null 2>&1; then :
++
++else
++  ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++if test $ac_cv_header_stdc = yes; then
++  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
++  if test "$cross_compiling" = yes; then :
++  :
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <ctype.h>
++#include <stdlib.h>
++#if ((' ' & 0x0FF) == 0x020)
++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
++#else
++# define ISLOWER(c) \
++		   (('a' <= (c) && (c) <= 'i') \
++		     || ('j' <= (c) && (c) <= 'r') \
++		     || ('s' <= (c) && (c) <= 'z'))
++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
++#endif
++
++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
++int
++main ()
++{
++  int i;
++  for (i = 0; i < 256; i++)
++    if (XOR (islower (i), ISLOWER (i))
++	|| toupper (i) != TOUPPER (i))
++      return 2;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_run "$LINENO"; then :
++
++else
++  ac_cv_header_stdc=no
++fi
++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
++  conftest.$ac_objext conftest.beam conftest.$ac_ext
++fi
++
++fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
++$as_echo "$ac_cv_header_stdc" >&6; }
++if test $ac_cv_header_stdc = yes; then
++
++$as_echo "#define STDC_HEADERS 1" >>confdefs.h
++
++fi
++
++# On IRIX 5.3, sys/types and inttypes.h are conflicting.
++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
++		  inttypes.h stdint.h unistd.h
++do :
++  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
++"
++if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
++  cat >>confdefs.h <<_ACEOF
++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
++
++
++
++    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
++
++
++    #------------------------------------------------------------------------
++    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
++    # It makes compiling go faster.  (This is only a performance feature.)
++    #------------------------------------------------------------------------
++
++    if test -z "$no_pipe" -a -n "$GCC"; then
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
++$as_echo_n "checking if the compiler understands -pipe... " >&6; }
++if ${tcl_cv_cc_pipe+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
++	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_cc_pipe=yes
++else
++  tcl_cv_cc_pipe=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++	    CFLAGS=$hold_cflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
++$as_echo "$tcl_cv_cc_pipe" >&6; }
++	if test $tcl_cv_cc_pipe = yes; then
++	    CFLAGS="$CFLAGS -pipe"
++	fi
++    fi
++
++    #--------------------------------------------------------------------
++    # Common compiler flag setup
++    #--------------------------------------------------------------------
++
++     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
++$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
++if ${ac_cv_c_bigendian+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_cv_c_bigendian=unknown
++    # See if we're dealing with a universal compiler.
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#ifndef __APPLE_CC__
++	       not a universal capable compiler
++	     #endif
++	     typedef int dummy;
++
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++
++	# Check for potential -arch flags.  It is not universal unless
++	# there are at least two -arch flags with different values.
++	ac_arch=
++	ac_prev=
++	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
++	 if test -n "$ac_prev"; then
++	   case $ac_word in
++	     i?86 | x86_64 | ppc | ppc64)
++	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
++		 ac_arch=$ac_word
++	       else
++		 ac_cv_c_bigendian=universal
++		 break
++	       fi
++	       ;;
++	   esac
++	   ac_prev=
++	 elif test "x$ac_word" = "x-arch"; then
++	   ac_prev=arch
++	 fi
++       done
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++    if test $ac_cv_c_bigendian = unknown; then
++      # See if sys/param.h defines the BYTE_ORDER macro.
++      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/types.h>
++	     #include <sys/param.h>
++
++int
++main ()
++{
++#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
++		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
++		     && LITTLE_ENDIAN)
++	      bogus endian macros
++	     #endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  # It does; now see whether it defined to BIG_ENDIAN or not.
++	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/types.h>
++		#include <sys/param.h>
++
++int
++main ()
++{
++#if BYTE_ORDER != BIG_ENDIAN
++		 not big endian
++		#endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_c_bigendian=yes
++else
++  ac_cv_c_bigendian=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++    fi
++    if test $ac_cv_c_bigendian = unknown; then
++      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
++      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <limits.h>
++
++int
++main ()
++{
++#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
++	      bogus endian macros
++	     #endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  # It does; now see whether it defined to _BIG_ENDIAN or not.
++	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <limits.h>
++
++int
++main ()
++{
++#ifndef _BIG_ENDIAN
++		 not big endian
++		#endif
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_c_bigendian=yes
++else
++  ac_cv_c_bigendian=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++    fi
++    if test $ac_cv_c_bigendian = unknown; then
++      # Compile a test program.
++      if test "$cross_compiling" = yes; then :
++  # Try to guess by grepping values from an object file.
++	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++short int ascii_mm[] =
++		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
++		short int ascii_ii[] =
++		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
++		int use_ascii (int i) {
++		  return ascii_mm[i] + ascii_ii[i];
++		}
++		short int ebcdic_ii[] =
++		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
++		short int ebcdic_mm[] =
++		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
++		int use_ebcdic (int i) {
++		  return ebcdic_mm[i] + ebcdic_ii[i];
++		}
++		extern int foo;
++
++int
++main ()
++{
++return use_ascii (foo) == use_ebcdic (foo);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
++	      ac_cv_c_bigendian=yes
++	    fi
++	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
++	      if test "$ac_cv_c_bigendian" = unknown; then
++		ac_cv_c_bigendian=no
++	      else
++		# finding both strings is unlikely to happen, but who knows?
++		ac_cv_c_bigendian=unknown
++	      fi
++	    fi
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$ac_includes_default
++int
++main ()
++{
++
++	     /* Are we little or big endian?  From Harbison&Steele.  */
++	     union
++	     {
++	       long int l;
++	       char c[sizeof (long int)];
++	     } u;
++	     u.l = 1;
++	     return u.c[sizeof (long int) - 1] == 1;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_run "$LINENO"; then :
++  ac_cv_c_bigendian=no
++else
++  ac_cv_c_bigendian=yes
++fi
++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
++  conftest.$ac_objext conftest.beam conftest.$ac_ext
++fi
++
++    fi
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
++$as_echo "$ac_cv_c_bigendian" >&6; }
++ case $ac_cv_c_bigendian in #(
++   yes)
++     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
++;; #(
++   no)
++      ;; #(
++   universal)
++
++$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
++
++     ;; #(
++   *)
++     as_fn_error $? "unknown endianness
++ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
++ esac
++
++    if test "${TEA_PLATFORM}" = "unix" ; then
++
++    #--------------------------------------------------------------------
++    # On a few very rare systems, all of the libm.a stuff is
++    # already in libc.a.  Set compiler flags accordingly.
++    # Also, Linux requires the "ieee" library for math to work
++    # right (and it must appear before "-lm").
++    #--------------------------------------------------------------------
++
++    ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin"
++if test "x$ac_cv_func_sin" = xyes; then :
++  MATH_LIBS=""
++else
++  MATH_LIBS="-lm"
++fi
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
++$as_echo_n "checking for main in -lieee... " >&6; }
++if ${ac_cv_lib_ieee_main+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lieee  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++
++int
++main ()
++{
++return main ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_ieee_main=yes
++else
++  ac_cv_lib_ieee_main=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
++$as_echo "$ac_cv_lib_ieee_main" >&6; }
++if test "x$ac_cv_lib_ieee_main" = xyes; then :
++  MATH_LIBS="-lieee $MATH_LIBS"
++fi
++
++
++    #--------------------------------------------------------------------
++    # Interactive UNIX requires -linet instead of -lsocket, plus it
++    # needs net/errno.h to define the socket-related error codes.
++    #--------------------------------------------------------------------
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5
++$as_echo_n "checking for main in -linet... " >&6; }
++if ${ac_cv_lib_inet_main+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-linet  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++
++int
++main ()
++{
++return main ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_inet_main=yes
++else
++  ac_cv_lib_inet_main=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5
++$as_echo "$ac_cv_lib_inet_main" >&6; }
++if test "x$ac_cv_lib_inet_main" = xyes; then :
++  LIBS="$LIBS -linet"
++fi
++
++    ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default"
++if test "x$ac_cv_header_net_errno_h" = xyes; then :
++
++
++$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h
++
++fi
++
++
++
++    #--------------------------------------------------------------------
++    #	Check for the existence of the -lsocket and -lnsl libraries.
++    #	The order here is important, so that they end up in the right
++    #	order in the command line generated by make.  Here are some
++    #	special considerations:
++    #	1. Use "connect" and "accept" to check for -lsocket, and
++    #	   "gethostbyname" to check for -lnsl.
++    #	2. Use each function name only once:  can't redo a check because
++    #	   autoconf caches the results of the last check and won't redo it.
++    #	3. Use -lnsl and -lsocket only if they supply procedures that
++    #	   aren't already present in the normal libraries.  This is because
++    #	   IRIX 5.2 has libraries, but they aren't needed and they're
++    #	   bogus:  they goof up name resolution if used.
++    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
++    #	   To get around this problem, check for both libraries together
++    #	   if -lsocket doesn't work by itself.
++    #--------------------------------------------------------------------
++
++    tcl_checkBoth=0
++    ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
++if test "x$ac_cv_func_connect" = xyes; then :
++  tcl_checkSocket=0
++else
++  tcl_checkSocket=1
++fi
++
++    if test "$tcl_checkSocket" = 1; then
++	ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
++if test "x$ac_cv_func_setsockopt" = xyes; then :
++
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
++$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
++if ${ac_cv_lib_socket_setsockopt+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lsocket  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char setsockopt ();
++int
++main ()
++{
++return setsockopt ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_socket_setsockopt=yes
++else
++  ac_cv_lib_socket_setsockopt=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
++$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
++if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
++  LIBS="$LIBS -lsocket"
++else
++  tcl_checkBoth=1
++fi
++
++fi
++
++    fi
++    if test "$tcl_checkBoth" = 1; then
++	tk_oldLibs=$LIBS
++	LIBS="$LIBS -lsocket -lnsl"
++	ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept"
++if test "x$ac_cv_func_accept" = xyes; then :
++  tcl_checkNsl=0
++else
++  LIBS=$tk_oldLibs
++fi
++
++    fi
++    ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
++if test "x$ac_cv_func_gethostbyname" = xyes; then :
++
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
++$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
++if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lnsl  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char gethostbyname ();
++int
++main ()
++{
++return gethostbyname ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_nsl_gethostbyname=yes
++else
++  ac_cv_lib_nsl_gethostbyname=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
++$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
++if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
++  LIBS="$LIBS -lnsl"
++fi
++
++fi
++
++
++    # TEA specific: Don't perform the eval of the libraries here because
++    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
++
++    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
++
++
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5
++$as_echo_n "checking dirent.h... " >&6; }
++if ${tcl_cv_dirent_h+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/types.h>
++#include <dirent.h>
++int
++main ()
++{
++
++#ifndef _POSIX_SOURCE
++#   ifdef __Lynx__
++	/*
++	 * Generate compilation error to make the test fail:  Lynx headers
++	 * are only valid if really in the POSIX environment.
++	 */
++
++	missing_procedure();
++#   endif
++#endif
++DIR *d;
++struct dirent *entryPtr;
++char *p;
++d = opendir("foobar");
++entryPtr = readdir(d);
++p = entryPtr->d_name;
++closedir(d);
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_dirent_h=yes
++else
++  tcl_cv_dirent_h=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5
++$as_echo "$tcl_cv_dirent_h" >&6; }
++
++    if test $tcl_cv_dirent_h = no; then
++
++$as_echo "#define NO_DIRENT_H 1" >>confdefs.h
++
++    fi
++
++    # TEA specific:
++    ac_fn_c_check_header_mongrel "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default"
++if test "x$ac_cv_header_errno_h" = xyes; then :
++
++else
++
++$as_echo "#define NO_ERRNO_H 1" >>confdefs.h
++
++fi
++
++
++    ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
++if test "x$ac_cv_header_float_h" = xyes; then :
++
++else
++
++$as_echo "#define NO_FLOAT_H 1" >>confdefs.h
++
++fi
++
++
++    ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default"
++if test "x$ac_cv_header_values_h" = xyes; then :
++
++else
++
++$as_echo "#define NO_VALUES_H 1" >>confdefs.h
++
++fi
++
++
++    ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default"
++if test "x$ac_cv_header_limits_h" = xyes; then :
++
++$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h
++
++else
++
++$as_echo "#define NO_LIMITS_H 1" >>confdefs.h
++
++fi
++
++
++    ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
++if test "x$ac_cv_header_stdlib_h" = xyes; then :
++  tcl_ok=1
++else
++  tcl_ok=0
++fi
++
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "strtol" >/dev/null 2>&1; then :
++
++else
++  tcl_ok=0
++fi
++rm -f conftest*
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "strtoul" >/dev/null 2>&1; then :
++
++else
++  tcl_ok=0
++fi
++rm -f conftest*
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "strtod" >/dev/null 2>&1; then :
++
++else
++  tcl_ok=0
++fi
++rm -f conftest*
++
++    if test $tcl_ok = 0; then
++
++$as_echo "#define NO_STDLIB_H 1" >>confdefs.h
++
++    fi
++    ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
++if test "x$ac_cv_header_string_h" = xyes; then :
++  tcl_ok=1
++else
++  tcl_ok=0
++fi
++
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <string.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "strstr" >/dev/null 2>&1; then :
++
++else
++  tcl_ok=0
++fi
++rm -f conftest*
++
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <string.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "strerror" >/dev/null 2>&1; then :
++
++else
++  tcl_ok=0
++fi
++rm -f conftest*
++
++
++    # See also memmove check below for a place where NO_STRING_H can be
++    # set and why.
++
++    if test $tcl_ok = 0; then
++
++$as_echo "#define NO_STRING_H 1" >>confdefs.h
++
++    fi
++
++    ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
++if test "x$ac_cv_header_sys_wait_h" = xyes; then :
++
++else
++
++$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h
++
++fi
++
++
++    ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
++if test "x$ac_cv_header_dlfcn_h" = xyes; then :
++
++else
++
++$as_echo "#define NO_DLFCN_H 1" >>confdefs.h
++
++fi
++
++
++
++    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
++    for ac_header in sys/param.h
++do :
++  ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
++if test "x$ac_cv_header_sys_param_h" = xyes; then :
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_SYS_PARAM_H 1
++_ACEOF
++
++fi
++
++done
++
++
++	# Let the user call this, because if it triggers, they will
++	# need a compat/strtod.c that is correct.  Users can also
++	# use Tcl_GetDouble(FromObj) instead.
++	#TEA_BUGGY_STRTOD
++    fi
++
++
++#-----------------------------------------------------------------------
++# __CHANGE__
++# Specify the C source files to compile in TEA_ADD_SOURCES,
++# public headers that need to be installed in TEA_ADD_HEADERS,
++# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
++# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
++# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
++# and PKG_TCL_SOURCES.
++#-----------------------------------------------------------------------
++
++
++    vars="tclsqlite3.c"
++    for i in $vars; do
++	case $i in
++	    \$*)
++		# allow $-var names
++		PKG_SOURCES="$PKG_SOURCES $i"
++		PKG_OBJECTS="$PKG_OBJECTS $i"
++		;;
++	    *)
++		# check for existence - allows for generic/win/unix VPATH
++		# To add more dirs here (like 'src'), you have to update VPATH
++		# in Makefile.in as well
++		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
++		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
++		    -a ! -f "${srcdir}/macosx/$i" \
++		    ; then
++		    as_fn_error $? "could not find source file '$i'" "$LINENO" 5
++		fi
++		PKG_SOURCES="$PKG_SOURCES $i"
++		# this assumes it is in a VPATH dir
++		i=`basename $i`
++		# handle user calling this before or after TEA_SETUP_COMPILER
++		if test x"${OBJEXT}" != x ; then
++		    j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
++		else
++		    j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
++		fi
++		PKG_OBJECTS="$PKG_OBJECTS $j"
++		;;
++	esac
++    done
++
++
++
++
++    vars=""
++    for i in $vars; do
++	# check for existence, be strict because it is installed
++	if test ! -f "${srcdir}/$i" ; then
++	    as_fn_error $? "could not find header file '${srcdir}/$i'" "$LINENO" 5
++	fi
++	PKG_HEADERS="$PKG_HEADERS $i"
++    done
++
++
++
++    vars="-I\"`\${CYGPATH} \${srcdir}/generic`\""
++    for i in $vars; do
++	PKG_INCLUDES="$PKG_INCLUDES $i"
++    done
++
++
++
++    vars=""
++    for i in $vars; do
++	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
++	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
++	    i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
++	fi
++	PKG_LIBS="$PKG_LIBS $i"
++    done
++
++
++
++    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_FTS3=1"
++
++
++
++    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_3_SUFFIX_ONLY=1"
++
++
++
++    PKG_CFLAGS="$PKG_CFLAGS -DSQLITE_ENABLE_RTREE=1"
++
++
++
++    vars=""
++    for i in $vars; do
++	# check for existence - allows for generic/win/unix VPATH
++	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
++	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
++	    -a ! -f "${srcdir}/macosx/$i" \
++	    ; then
++	    as_fn_error $? "could not find stub source file '$i'" "$LINENO" 5
++	fi
++	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
++	# this assumes it is in a VPATH dir
++	i=`basename $i`
++	# handle user calling this before or after TEA_SETUP_COMPILER
++	if test x"${OBJEXT}" != x ; then
++	    j="`echo $i | sed -e 's/\.[^.]*$//'`.${OBJEXT}"
++	else
++	    j="`echo $i | sed -e 's/\.[^.]*$//'`.\${OBJEXT}"
++	fi
++	PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
++    done
++
++
++
++
++    vars=""
++    for i in $vars; do
++	# check for existence, be strict because it is installed
++	if test ! -f "${srcdir}/$i" ; then
++	    as_fn_error $? "could not find tcl source file '${srcdir}/$i'" "$LINENO" 5
++	fi
++	PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
++    done
++
++
++
++#--------------------------------------------------------------------
++# The --with-system-sqlite causes the TCL bindings to SQLite to use
++# the system shared library for SQLite rather than statically linking
++# against its own private copy.  This is dangerous and leads to
++# undersirable dependences and is not recommended.
++# Patchs from rmax.
++#--------------------------------------------------------------------
++
++# Check whether --with-system-sqlite was given.
++if test "${with_system_sqlite+set}" = set; then :
++  withval=$with_system_sqlite;
++else
++  with_system_sqlite=no
++fi
++
++if test x$with_system_sqlite != xno; then
++ ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default"
++if test "x$ac_cv_header_sqlite3_h" = xyes; then :
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_initialize in -lsqlite3" >&5
++$as_echo_n "checking for sqlite3_initialize in -lsqlite3... " >&6; }
++if ${ac_cv_lib_sqlite3_sqlite3_initialize+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lsqlite3  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char sqlite3_initialize ();
++int
++main ()
++{
++return sqlite3_initialize ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_sqlite3_sqlite3_initialize=yes
++else
++  ac_cv_lib_sqlite3_sqlite3_initialize=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_initialize" >&5
++$as_echo "$ac_cv_lib_sqlite3_sqlite3_initialize" >&6; }
++if test "x$ac_cv_lib_sqlite3_sqlite3_initialize" = xyes; then :
++  $as_echo "#define USE_SYSTEM_SQLITE 1" >>confdefs.h
++
++      LIBS="$LIBS -lsqlite3"
++fi
++
++fi
++
++
++fi
++
++#--------------------------------------------------------------------
++# __CHANGE__
++# Choose which headers you need.  Extension authors should try very
++# hard to only rely on the Tcl public header files.  Internal headers
++# contain private data structures and are subject to change without
++# notice.
++# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
++#--------------------------------------------------------------------
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5
++$as_echo_n "checking for Tcl public headers... " >&6; }
++
++
++# Check whether --with-tclinclude was given.
++if test "${with_tclinclude+set}" = set; then :
++  withval=$with_tclinclude; with_tclinclude=${withval}
++fi
++
++
++    if ${ac_cv_c_tclh+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	# Use the value from --with-tclinclude, if it was given
++
++	if test x"${with_tclinclude}" != x ; then
++	    if test -f "${with_tclinclude}/tcl.h" ; then
++		ac_cv_c_tclh=${with_tclinclude}
++	    else
++		as_fn_error $? "${with_tclinclude} directory does not contain tcl.h" "$LINENO" 5
++	    fi
++	else
++	    list=""
++	    if test "`uname -s`" = "Darwin"; then
++		# If Tcl was built as a framework, attempt to use
++		# the framework's Headers directory
++		case ${TCL_DEFS} in
++		    *TCL_FRAMEWORK*)
++			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
++			;;
++		esac
++	    fi
++
++	    # Look in the source dir only if Tcl is not installed,
++	    # and in that situation, look there before installed locations.
++	    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++		list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
++	    fi
++
++	    # Check order: pkg --prefix location, Tcl's --prefix location,
++	    # relative to directory of tclConfig.sh.
++
++	    eval "temp_includedir=${includedir}"
++	    list="$list \
++		`ls -d ${temp_includedir}        2>/dev/null` \
++		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
++		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
++	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
++		list="$list /usr/local/include /usr/include"
++		if test x"${TCL_INCLUDE_SPEC}" != x ; then
++		    d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
++		    list="$list `ls -d ${d} 2>/dev/null`"
++		fi
++	    fi
++	    for i in $list ; do
++		if test -f "$i/tcl.h" ; then
++		    ac_cv_c_tclh=$i
++		    break
++		fi
++	    done
++	fi
++
++fi
++
++
++    # Print a message based on how we determined the include path
++
++    if test x"${ac_cv_c_tclh}" = x ; then
++	as_fn_error $? "tcl.h not found.  Please specify its location with --with-tclinclude" "$LINENO" 5
++    else
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5
++$as_echo "${ac_cv_c_tclh}" >&6; }
++    fi
++
++    # Convert to a native path and substitute into the output files.
++
++    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
++
++    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
++
++
++
++#TEA_PRIVATE_TCL_HEADERS
++
++#TEA_PUBLIC_TK_HEADERS
++#TEA_PRIVATE_TK_HEADERS
++#TEA_PATH_X
++
++#--------------------------------------------------------------------
++# Check whether --enable-threads or --disable-threads was given.
++# This auto-enables if Tcl was compiled threaded.
++#--------------------------------------------------------------------
++
++
++    # Check whether --enable-threads was given.
++if test "${enable_threads+set}" = set; then :
++  enableval=$enable_threads; tcl_ok=$enableval
++else
++  tcl_ok=yes
++fi
++
++
++    if test "${enable_threads+set}" = set; then
++	enableval="$enable_threads"
++	tcl_ok=$enableval
++    else
++	tcl_ok=yes
++    fi
++
++    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
++	TCL_THREADS=1
++
++	if test "${TEA_PLATFORM}" != "windows" ; then
++	    # We are always OK on Windows, so check what this platform wants:
++
++	    # USE_THREAD_ALLOC tells us to try the special thread-based
++	    # allocator that significantly reduces lock contention
++
++$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h
++
++
++$as_echo "#define _REENTRANT 1" >>confdefs.h
++
++	    if test "`uname -s`" = "SunOS" ; then
++
++$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
++
++	    fi
++
++$as_echo "#define _THREAD_SAFE 1" >>confdefs.h
++
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
++$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
++if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lpthread  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char pthread_mutex_init ();
++int
++main ()
++{
++return pthread_mutex_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_pthread_pthread_mutex_init=yes
++else
++  ac_cv_lib_pthread_pthread_mutex_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
++$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
++if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++	    if test "$tcl_ok" = "no"; then
++		# Check a little harder for __pthread_mutex_init in the same
++		# library, as some systems hide it there until pthread.h is
++		# defined.  We could alternatively do an AC_TRY_COMPILE with
++		# pthread.h, but that will work with libpthread really doesn't
++		# exist, like AIX 4.2.  [Bug: 4359]
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5
++$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; }
++if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lpthread  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char __pthread_mutex_init ();
++int
++main ()
++{
++return __pthread_mutex_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_pthread___pthread_mutex_init=yes
++else
++  ac_cv_lib_pthread___pthread_mutex_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
++$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
++if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++	    fi
++
++	    if test "$tcl_ok" = "yes"; then
++		# The space is needed
++		THREADS_LIBS=" -lpthread"
++	    else
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5
++$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; }
++if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lpthreads  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char pthread_mutex_init ();
++int
++main ()
++{
++return pthread_mutex_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_pthreads_pthread_mutex_init=yes
++else
++  ac_cv_lib_pthreads_pthread_mutex_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
++$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
++if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++		if test "$tcl_ok" = "yes"; then
++		    # The space is needed
++		    THREADS_LIBS=" -lpthreads"
++		else
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5
++$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; }
++if ${ac_cv_lib_c_pthread_mutex_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lc  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char pthread_mutex_init ();
++int
++main ()
++{
++return pthread_mutex_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_c_pthread_mutex_init=yes
++else
++  ac_cv_lib_c_pthread_mutex_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5
++$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; }
++if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++		    if test "$tcl_ok" = "no"; then
++			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5
++$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; }
++if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lc_r  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char pthread_mutex_init ();
++int
++main ()
++{
++return pthread_mutex_init ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_c_r_pthread_mutex_init=yes
++else
++  ac_cv_lib_c_r_pthread_mutex_init=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
++$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
++if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++			if test "$tcl_ok" = "yes"; then
++			    # The space is needed
++			    THREADS_LIBS=" -pthread"
++			else
++			    TCL_THREADS=0
++			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&5
++$as_echo "$as_me: WARNING: Do not know how to find pthread lib on your system - thread support disabled" >&2;}
++			fi
++		    fi
++		fi
++	    fi
++	fi
++    else
++	TCL_THREADS=0
++    fi
++    # Do checking message here to not mess up interleaved configure output
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5
++$as_echo_n "checking for building with threads... " >&6; }
++    if test "${TCL_THREADS}" = 1; then
++
++$as_echo "#define TCL_THREADS 1" >>confdefs.h
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5
++$as_echo "yes (default)" >&6; }
++    else
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++    fi
++    # TCL_THREADS sanity checking.  See if our request for building with
++    # threads is the same as the way Tcl was built.  If not, warn the user.
++    case ${TCL_DEFS} in
++	*THREADS=1*)
++	    if test "${TCL_THREADS}" = "0"; then
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
++    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
++    that IS thread-enabled.  It is recommended to use --enable-threads." >&5
++$as_echo "$as_me: WARNING:
++    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
++    that IS thread-enabled.  It is recommended to use --enable-threads." >&2;}
++	    fi
++	    ;;
++	*)
++	    if test "${TCL_THREADS}" = "1"; then
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
++    --enable-threads requested, but building against a Tcl that is NOT
++    thread-enabled.  This is an OK configuration that will also run in
++    a thread-enabled core." >&5
++$as_echo "$as_me: WARNING:
++    --enable-threads requested, but building against a Tcl that is NOT
++    thread-enabled.  This is an OK configuration that will also run in
++    a thread-enabled core." >&2;}
++	    fi
++	    ;;
++    esac
++
++
++if test "${TCL_THREADS}" = "1" ; then
++
++$as_echo "#define SQLITE_THREADSAFE 1" >>confdefs.h
++
++    # Not automatically added by Tcl because its assumed Tcl links to them,
++    # but it may not if it isn't really a threaded build.
++
++    vars="$THREADS_LIBS"
++    for i in $vars; do
++	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
++	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
++	    i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
++	fi
++	PKG_LIBS="$PKG_LIBS $i"
++    done
++
++
++else
++
++$as_echo "#define SQLITE_THREADSAFE 0" >>confdefs.h
++
++fi
++
++#--------------------------------------------------------------------
++# The statement below defines a collection of symbols related to
++# building as a shared library instead of a static library.
++#--------------------------------------------------------------------
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
++$as_echo_n "checking how to build libraries... " >&6; }
++    # Check whether --enable-shared was given.
++if test "${enable_shared+set}" = set; then :
++  enableval=$enable_shared; tcl_ok=$enableval
++else
++  tcl_ok=yes
++fi
++
++
++    if test "${enable_shared+set}" = set; then
++	enableval="$enable_shared"
++	tcl_ok=$enableval
++    else
++	tcl_ok=yes
++    fi
++
++    if test "$tcl_ok" = "yes" ; then
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
++$as_echo "shared" >&6; }
++	SHARED_BUILD=1
++    else
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
++$as_echo "static" >&6; }
++	SHARED_BUILD=0
++
++$as_echo "#define STATIC_BUILD 1" >>confdefs.h
++
++    fi
++
++
++
++#--------------------------------------------------------------------
++# This macro figures out what flags to use with the compiler/linker
++# when building shared/static debug/optimized objects.  This information
++# can be taken from the tclConfig.sh file, but this figures it all out.
++#--------------------------------------------------------------------
++
++if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_RANLIB+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$RANLIB"; then
++  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
++$as_echo "$RANLIB" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++  ac_ct_RANLIB=$RANLIB
++  # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_RANLIB"; then
++  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_RANLIB="ranlib"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
++$as_echo "$ac_ct_RANLIB" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_RANLIB" = x; then
++    RANLIB=":"
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    RANLIB=$ac_ct_RANLIB
++  fi
++else
++  RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++
++
++
++    # Step 0.a: Enable 64 bit support?
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
++$as_echo_n "checking if 64bit support is requested... " >&6; }
++    # Check whether --enable-64bit was given.
++if test "${enable_64bit+set}" = set; then :
++  enableval=$enable_64bit; do64bit=$enableval
++else
++  do64bit=no
++fi
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
++$as_echo "$do64bit" >&6; }
++
++    # Step 0.b: Enable Solaris 64 bit VIS support?
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
++$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; }
++    # Check whether --enable-64bit-vis was given.
++if test "${enable_64bit_vis+set}" = set; then :
++  enableval=$enable_64bit_vis; do64bitVIS=$enableval
++else
++  do64bitVIS=no
++fi
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
++$as_echo "$do64bitVIS" >&6; }
++    # Force 64bit on with VIS
++    if test "$do64bitVIS" = "yes"; then :
++  do64bit=yes
++fi
++
++    # Step 0.c: Check if visibility support is available. Do this here so
++    # that platform specific alternatives can be used below if this fails.
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
++$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
++if ${tcl_cv_cc_visibility_hidden+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
++	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++	    extern __attribute__((__visibility__("hidden"))) void f(void);
++	    void f(void) {}
++int
++main ()
++{
++f();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_cc_visibility_hidden=yes
++else
++  tcl_cv_cc_visibility_hidden=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++	CFLAGS=$hold_cflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
++$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
++    if test $tcl_cv_cc_visibility_hidden = yes; then :
++
++
++$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
++
++
++$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
++
++
++fi
++
++    # Step 0.d: Disable -rpath support?
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
++$as_echo_n "checking if rpath support is requested... " >&6; }
++    # Check whether --enable-rpath was given.
++if test "${enable_rpath+set}" = set; then :
++  enableval=$enable_rpath; doRpath=$enableval
++else
++  doRpath=yes
++fi
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
++$as_echo "$doRpath" >&6; }
++
++    # TEA specific: Cross-compiling options for Windows/CE builds?
++
++    if test "${TEA_PLATFORM}" = windows; then :
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if Windows/CE build is requested" >&5
++$as_echo_n "checking if Windows/CE build is requested... " >&6; }
++	# Check whether --enable-wince was given.
++if test "${enable_wince+set}" = set; then :
++  enableval=$enable_wince; doWince=$enableval
++else
++  doWince=no
++fi
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $doWince" >&5
++$as_echo "$doWince" >&6; }
++
++fi
++
++    # Set the variable "system" to hold the name and version number
++    # for the system.
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
++$as_echo_n "checking system version... " >&6; }
++if ${tcl_cv_sys_version+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	# TEA specific:
++	if test "${TEA_PLATFORM}" = "windows" ; then
++	    tcl_cv_sys_version=windows
++	else
++	    tcl_cv_sys_version=`uname -s`-`uname -r`
++	    if test "$?" -ne 0 ; then
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
++$as_echo "$as_me: WARNING: can't find uname command" >&2;}
++		tcl_cv_sys_version=unknown
++	    else
++		if test "`uname -s`" = "AIX" ; then
++		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
++		fi
++	    fi
++	fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
++$as_echo "$tcl_cv_sys_version" >&6; }
++    system=$tcl_cv_sys_version
++
++
++    # Require ranlib early so we can override it in special cases below.
++
++
++
++    # Set configuration options based on system name and version.
++    # This is similar to Tcl's unix/tcl.m4 except that we've added a
++    # "windows" case and removed some core-only vars.
++
++    do64bit_ok=no
++    # default to '{$LIBS}' and set to "" on per-platform necessary basis
++    SHLIB_LD_LIBS='${LIBS}'
++    # When ld needs options to work in 64-bit mode, put them in
++    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
++    # is disabled by the user. [Bug 1016796]
++    LDFLAGS_ARCH=""
++    UNSHARED_LIB_SUFFIX=""
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
++    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
++    TCL_LIB_VERSIONS_OK=ok
++    CFLAGS_DEBUG=-g
++    if test "$GCC" = yes; then :
++
++	CFLAGS_OPTIMIZE=-O2
++	CFLAGS_WARNING="-Wall"
++
++else
++
++	CFLAGS_OPTIMIZE=-O
++	CFLAGS_WARNING=""
++
++fi
++    if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ar; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_AR+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$AR"; then
++  ac_cv_prog_AR="$AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_AR="${ac_tool_prefix}ar"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++AR=$ac_cv_prog_AR
++if test -n "$AR"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
++$as_echo "$AR" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_AR"; then
++  ac_ct_AR=$AR
++  # Extract the first word of "ar", so it can be a program name with args.
++set dummy ar; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_AR+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_AR"; then
++  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_AR="ar"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_AR=$ac_cv_prog_ac_ct_AR
++if test -n "$ac_ct_AR"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
++$as_echo "$ac_ct_AR" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_AR" = x; then
++    AR=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    AR=$ac_ct_AR
++  fi
++else
++  AR="$ac_cv_prog_AR"
++fi
++
++    STLIB_LD='${AR} cr'
++    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
++    if test "x$SHLIB_VERSION" = x; then :
++  SHLIB_VERSION="1.0"
++fi
++    case $system in
++	# TEA specific:
++	windows)
++	    # This is a 2-stage check to make sure we have the 64-bit SDK
++	    # We have to know where the SDK is installed.
++	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
++	    # MACHINE is IX86 for LINK, but this is used by the manifest,
++	    # which requires x86|amd64|ia64.
++	    MACHINE="X86"
++	    if test "$do64bit" != "no" ; then
++		if test "x${MSSDK}x" = "xx" ; then
++		    MSSDK="C:/Progra~1/Microsoft Platform SDK"
++		fi
++		MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
++		PATH64=""
++		case "$do64bit" in
++		    amd64|x64|yes)
++			MACHINE="AMD64" ; # default to AMD64 64-bit build
++			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
++			;;
++		    ia64)
++			MACHINE="IA64"
++			PATH64="${MSSDK}/Bin/Win64"
++			;;
++		esac
++		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5
++$as_echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;}
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ensure latest Platform SDK is installed" >&5
++$as_echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;}
++		    do64bit="no"
++		else
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: result:    Using 64-bit $MACHINE mode" >&5
++$as_echo "   Using 64-bit $MACHINE mode" >&6; }
++		    do64bit_ok="yes"
++		fi
++	    fi
++
++	    if test "$doWince" != "no" ; then
++		if test "$do64bit" != "no" ; then
++		    as_fn_error $? "Windows/CE and 64-bit builds incompatible" "$LINENO" 5
++		fi
++		if test "$GCC" = "yes" ; then
++		    as_fn_error $? "Windows/CE and GCC builds incompatible" "$LINENO" 5
++		fi
++
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-celib
++
++    if test x"${no_celib}" = x ; then
++	# we reset no_celib in case something fails here
++	no_celib=true
++
++# Check whether --with-celib was given.
++if test "${with_celib+set}" = set; then :
++  withval=$with_celib; with_celibconfig=${withval}
++fi
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows/CE celib directory" >&5
++$as_echo_n "checking for Windows/CE celib directory... " >&6; }
++	if ${ac_cv_c_celibconfig+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	    # First check to see if --with-celibconfig was specified.
++	    if test x"${with_celibconfig}" != x ; then
++		if test -d "${with_celibconfig}/inc" ; then
++		    ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
++		else
++		    as_fn_error $? "${with_celibconfig} directory doesn't contain inc directory" "$LINENO" 5
++		fi
++	    fi
++
++	    # then check for a celib library
++	    if test x"${ac_cv_c_celibconfig}" = x ; then
++		for i in \
++			../celib-palm-3.0 \
++			../celib \
++			../../celib-palm-3.0 \
++			../../celib \
++			`ls -dr ../celib-*3.[0-9]* 2>/dev/null` \
++			${srcdir}/../celib-palm-3.0 \
++			${srcdir}/../celib \
++			`ls -dr ${srcdir}/../celib-*3.[0-9]* 2>/dev/null` \
++			; do
++		    if test -d "$i/inc" ; then
++			ac_cv_c_celibconfig=`(cd $i; pwd)`
++			break
++		    fi
++		done
++	    fi
++
++fi
++
++	if test x"${ac_cv_c_celibconfig}" = x ; then
++	    as_fn_error $? "Cannot find celib support library directory" "$LINENO" 5
++	else
++	    no_celib=
++	    CELIB_DIR=${ac_cv_c_celibconfig}
++	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $CELIB_DIR" >&5
++$as_echo "found $CELIB_DIR" >&6; }
++	fi
++    fi
++
++		# Set defaults for common evc4/PPC2003 setup
++		# Currently Tcl requires 300+, possibly 420+ for sockets
++		CEVERSION=420; 		# could be 211 300 301 400 420 ...
++		TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
++		ARCH=ARM;		# could be ARM MIPS X86EM ...
++		PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
++		if test "$doWince" != "yes"; then
++		    # If !yes then the user specified something
++		    # Reset ARCH to allow user to skip specifying it
++		    ARCH=
++		    eval `echo $doWince | awk -F, '{ \
++	    if (length($1)) { printf "CEVERSION=\"%s\"\n", $1; \
++	    if ($1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
++	    if (length($2)) { printf "TARGETCPU=\"%s\"\n", toupper($2) }; \
++	    if (length($3)) { printf "ARCH=\"%s\"\n", toupper($3) }; \
++	    if (length($4)) { printf "PLATFORM=\"%s\"\n", $4 }; \
++		    }'`
++		    if test "x${ARCH}" = "x" ; then
++			ARCH=$TARGETCPU;
++		    fi
++		fi
++		OSVERSION=WCE$CEVERSION;
++	    	if test "x${WCEROOT}" = "x" ; then
++			WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
++		    if test ! -d "${WCEROOT}" ; then
++			WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
++		    fi
++		fi
++		if test "x${SDKROOT}" = "x" ; then
++		    SDKROOT="C:/Program Files/Windows CE Tools"
++		    if test ! -d "${SDKROOT}" ; then
++			SDKROOT="C:/Windows CE Tools"
++		    fi
++		fi
++		WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
++		SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
++		if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
++		    -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
++		    as_fn_error $? "could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" "$LINENO" 5
++		    doWince="no"
++		else
++		    # We could PATH_NOSPACE these, but that's not important,
++		    # as long as we quote them when used.
++		    CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
++		    if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
++			CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
++		    fi
++		    CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
++    		fi
++	    fi
++
++	    if test "$GCC" != "yes" ; then
++	        if test "${SHARED_BUILD}" = "0" ; then
++		    runtime=-MT
++	        else
++		    runtime=-MD
++	        fi
++
++                if test "$do64bit" != "no" ; then
++		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
++		    CC="\"${PATH64}/cl.exe\""
++		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
++		    RC="\"${MSSDK}/bin/rc.exe\""
++		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
++		    LINKBIN="\"${PATH64}/link.exe\""
++		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
++		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
++		    # Avoid 'unresolved external symbol __security_cookie'
++		    # errors, c.f. http://support.microsoft.com/?id=894573
++
++    vars="bufferoverflowU.lib"
++    for i in $vars; do
++	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
++	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
++	    i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'`
++	fi
++	PKG_LIBS="$PKG_LIBS $i"
++    done
++
++
++		elif test "$doWince" != "no" ; then
++		    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
++		    if test "${TARGETCPU}" = "X86"; then
++			CC="\"${CEBINROOT}/cl.exe\""
++		    else
++			CC="\"${CEBINROOT}/cl${ARCH}.exe\""
++		    fi
++		    CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
++		    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
++		    arch=`echo ${ARCH} | awk '{print tolower($0)}'`
++		    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
++		    if test "${SHARED_BUILD}" = "1" ; then
++			# Static CE builds require static celib as well
++		    	defs="${defs} _DLL"
++		    fi
++		    for i in $defs ; do
++
++cat >>confdefs.h <<_ACEOF
++#define $i 1
++_ACEOF
++
++		    done
++
++cat >>confdefs.h <<_ACEOF
++#define _WIN32_WCE $CEVERSION
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++#define UNDER_CE $CEVERSION
++_ACEOF
++
++		    CFLAGS_DEBUG="-nologo -Zi -Od"
++		    CFLAGS_OPTIMIZE="-nologo -Ox"
++		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
++		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
++		    LINKBIN="\"${CEBINROOT}/link.exe\""
++
++		else
++		    RC="rc"
++		    lflags="-nologo"
++		    LINKBIN="link"
++		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
++		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
++		fi
++	    fi
++
++	    if test "$GCC" = "yes"; then
++		# mingw gcc mode
++		if test -n "$ac_tool_prefix"; then
++  # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
++set dummy ${ac_tool_prefix}windres; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_RC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$RC"; then
++  ac_cv_prog_RC="$RC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_RC="${ac_tool_prefix}windres"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++RC=$ac_cv_prog_RC
++if test -n "$RC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
++$as_echo "$RC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_prog_RC"; then
++  ac_ct_RC=$RC
++  # Extract the first word of "windres", so it can be a program name with args.
++set dummy windres; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_prog_ac_ct_RC+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test -n "$ac_ct_RC"; then
++  ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    for ac_exec_ext in '' $ac_executable_extensions; do
++  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++    ac_cv_prog_ac_ct_RC="windres"
++    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++    break 2
++  fi
++done
++  done
++IFS=$as_save_IFS
++
++fi
++fi
++ac_ct_RC=$ac_cv_prog_ac_ct_RC
++if test -n "$ac_ct_RC"; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
++$as_echo "$ac_ct_RC" >&6; }
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++  if test "x$ac_ct_RC" = x; then
++    RC=""
++  else
++    case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++    RC=$ac_ct_RC
++  fi
++else
++  RC="$ac_cv_prog_RC"
++fi
++
++		CFLAGS_DEBUG="-g"
++		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
++		SHLIB_LD='${CC} -shared'
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
++		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
++
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5
++$as_echo_n "checking for cross-compile version of gcc... " >&6; }
++if ${ac_cv_cross+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++			    #ifdef _WIN32
++				#error cross-compiler
++			    #endif
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_cross=yes
++else
++  ac_cv_cross=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5
++$as_echo "$ac_cv_cross" >&6; }
++		      if test "$ac_cv_cross" = "yes"; then
++			case "$do64bit" in
++			    amd64|x64|yes)
++				CC="x86_64-w64-mingw32-gcc"
++				LD="x86_64-w64-mingw32-ld"
++				AR="x86_64-w64-mingw32-ar"
++				RANLIB="x86_64-w64-mingw32-ranlib"
++				RC="x86_64-w64-mingw32-windres"
++			    ;;
++			    *)
++				CC="i686-w64-mingw32-gcc"
++				LD="i686-w64-mingw32-ld"
++				AR="i686-w64-mingw32-ar"
++				RANLIB="i686-w64-mingw32-ranlib"
++				RC="i686-w64-mingw32-windres"
++			    ;;
++			esac
++		fi
++
++	    else
++		SHLIB_LD="${LINKBIN} -dll ${lflags}"
++		# link -lib only works when -lib is the first arg
++		STLIB_LD="${LINKBIN} -lib ${lflags}"
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
++		PATHTYPE=-w
++		# For information on what debugtype is most useful, see:
++		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
++		# and also
++		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
++		# This essentially turns it all on.
++		LDFLAGS_DEBUG="-debug -debugtype:cv"
++		LDFLAGS_OPTIMIZE="-release"
++		if test "$doWince" != "no" ; then
++		    LDFLAGS_CONSOLE="-link ${lflags}"
++		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
++		else
++		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
++		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
++		fi
++	    fi
++
++	    SHLIB_SUFFIX=".dll"
++	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
++
++	    TCL_LIB_VERSIONS_OK=nodots
++    	    ;;
++	AIX-*)
++	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then :
++
++		# AIX requires the _r compiler when gcc isn't being used
++		case "${CC}" in
++		    *_r|*_r\ *)
++			# ok ...
++			;;
++		    *)
++			# Make sure only first arg gets _r
++		    	CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
++			;;
++		esac
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
++$as_echo "Using $CC for compiling with threads" >&6; }
++
++fi
++	    LIBS="$LIBS -lc"
++	    SHLIB_CFLAGS=""
++	    SHLIB_SUFFIX=".so"
++
++	    LD_LIBRARY_PATH_VAR="LIBPATH"
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    if test "$do64bit" = yes; then :
++
++		if test "$GCC" = yes; then :
++
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
++
++else
++
++		    do64bit_ok=yes
++		    CFLAGS="$CFLAGS -q64"
++		    LDFLAGS_ARCH="-q64"
++		    RANLIB="${RANLIB} -X64"
++		    AR="${AR} -X64"
++		    SHLIB_LD_FLAGS="-b64"
++
++fi
++
++fi
++
++	    if test "`uname -m`" = ia64; then :
++
++		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
++		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
++		if test "$GCC" = yes; then :
++
++		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++
++else
++
++		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
++
++fi
++		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++
++else
++
++		if test "$GCC" = yes; then :
++
++		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
++
++else
++
++		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
++		    LDFLAGS="$LDFLAGS -brtl"
++
++fi
++		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
++		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++
++fi
++	    ;;
++	BeOS*)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD='${CC} -nostart'
++	    SHLIB_SUFFIX=".so"
++
++	    #-----------------------------------------------------------
++	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
++	    # -lsocket, even if the network functions are in -lnet which
++	    # is always linked to, for compatibility.
++	    #-----------------------------------------------------------
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
++$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
++if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lbind  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char inet_ntoa ();
++int
++main ()
++{
++return inet_ntoa ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_bind_inet_ntoa=yes
++else
++  ac_cv_lib_bind_inet_ntoa=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
++$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
++if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
++  LIBS="$LIBS -lbind -lsocket"
++fi
++
++	    ;;
++	BSD/OS-4.*)
++	    SHLIB_CFLAGS="-export-dynamic -fPIC"
++	    SHLIB_LD='${CC} -shared'
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS="$LDFLAGS -export-dynamic"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	CYGWIN_*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD='${CC} -shared'
++	    SHLIB_SUFFIX=".dll"
++	    EXEEXT=".exe"
++	    do64bit_ok=yes
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	Haiku*)
++	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
++$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
++if ${ac_cv_lib_network_inet_ntoa+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-lnetwork  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char inet_ntoa ();
++int
++main ()
++{
++return inet_ntoa ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_network_inet_ntoa=yes
++else
++  ac_cv_lib_network_inet_ntoa=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
++$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
++if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
++  LIBS="$LIBS -lnetwork"
++fi
++
++	    ;;
++	HP-UX-*.11.*)
++	    # Use updated header definitions where possible
++
++$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
++
++	    # TEA specific: Needed by Tcl, but not most extensions
++	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
++	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
++
++	    if test "`uname -m`" = ia64; then :
++
++		SHLIB_SUFFIX=".so"
++		# Use newer C++ library for C++ extensions
++		#if test "$GCC" != "yes" ; then
++		#   CPPFLAGS="-AA"
++		#fi
++
++else
++
++		SHLIB_SUFFIX=".sl"
++
++fi
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
++$as_echo_n "checking for shl_load in -ldld... " >&6; }
++if ${ac_cv_lib_dld_shl_load+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldld  $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++/* Override any GCC internal prototype to avoid an error.
++   Use char because int might match the return type of a GCC
++   builtin and then its argument prototype would still apply.  */
++#ifdef __cplusplus
++extern "C"
++#endif
++char shl_load ();
++int
++main ()
++{
++return shl_load ();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_lib_dld_shl_load=yes
++else
++  ac_cv_lib_dld_shl_load=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
++$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
++if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
++  tcl_ok=yes
++else
++  tcl_ok=no
++fi
++
++	    if test "$tcl_ok" = yes; then :
++
++		LDFLAGS="$LDFLAGS -Wl,-E"
++		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
++		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
++		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
++
++fi
++	    if test "$GCC" = yes; then :
++
++		SHLIB_LD='${CC} -shared'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++
++else
++
++		CFLAGS="$CFLAGS -z"
++		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
++		#CFLAGS="$CFLAGS +DAportable"
++		SHLIB_CFLAGS="+z"
++		SHLIB_LD="ld -b"
++
++fi
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    if test "$do64bit" = "yes"; then :
++
++		if test "$GCC" = yes; then :
++
++		    case `${CC} -dumpmachine` in
++			hppa64*)
++			    # 64-bit gcc in use.  Fix flags for GNU ld.
++			    do64bit_ok=yes
++			    SHLIB_LD='${CC} -shared'
++			    if test $doRpath = yes; then :
++
++				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++			    ;;
++			*)
++			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
++			    ;;
++		    esac
++
++else
++
++		    do64bit_ok=yes
++		    CFLAGS="$CFLAGS +DD64"
++		    LDFLAGS_ARCH="+DD64"
++
++fi
++
++fi ;;
++	IRIX-6.*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD="ld -n32 -shared -rdata_shared"
++	    SHLIB_SUFFIX=".so"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
++fi
++	    if test "$GCC" = yes; then :
++
++		CFLAGS="$CFLAGS -mabi=n32"
++		LDFLAGS="$LDFLAGS -mabi=n32"
++
++else
++
++		case $system in
++		    IRIX-6.3)
++			# Use to build 6.2 compatible binaries on 6.3.
++			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
++			;;
++		    *)
++			CFLAGS="$CFLAGS -n32"
++			;;
++		esac
++		LDFLAGS="$LDFLAGS -n32"
++
++fi
++	    ;;
++	IRIX64-6.*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD="ld -n32 -shared -rdata_shared"
++	    SHLIB_SUFFIX=".so"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
++fi
++
++	    # Check to enable 64-bit flags for compiler/linker
++
++	    if test "$do64bit" = yes; then :
++
++	        if test "$GCC" = yes; then :
++
++	            { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
++
++else
++
++	            do64bit_ok=yes
++	            SHLIB_LD="ld -64 -shared -rdata_shared"
++	            CFLAGS="$CFLAGS -64"
++	            LDFLAGS_ARCH="-64"
++
++fi
++
++fi
++	    ;;
++	Linux*|GNU*|NetBSD-Debian)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++
++	    # TEA specific:
++	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
++
++	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
++	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    if test "`uname -m`" = "alpha"; then :
++  CFLAGS="$CFLAGS -mieee"
++fi
++	    if test $do64bit = yes; then :
++
++		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
++$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
++if ${tcl_cv_cc_m64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++		    hold_cflags=$CFLAGS
++		    CFLAGS="$CFLAGS -m64"
++		    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_cc_m64=yes
++else
++  tcl_cv_cc_m64=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++		    CFLAGS=$hold_cflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
++$as_echo "$tcl_cv_cc_m64" >&6; }
++		if test $tcl_cv_cc_m64 = yes; then :
++
++		    CFLAGS="$CFLAGS -m64"
++		    do64bit_ok=yes
++
++fi
++
++fi
++
++	    # The combo of gcc + glibc has a bug related to inlining of
++	    # functions like strtod(). The -fno-builtin flag should address
++	    # this problem but it does not work. The -fno-inline flag is kind
++	    # of overkill but it works. Disable inlining only when one of the
++	    # files in compat/*.c is being linked in.
++
++	    if test x"${USE_COMPAT}" != x; then :
++  CFLAGS="$CFLAGS -fno-inline"
++fi
++	    ;;
++	Lynx*)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++	    CFLAGS_OPTIMIZE=-02
++	    SHLIB_LD='${CC} -shared'
++	    LD_FLAGS="-Wl,--export-dynamic"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++	    ;;
++	OpenBSD-*)
++	    arch=`arch -s`
++	    case "$arch" in
++	    vax)
++		SHLIB_SUFFIX=""
++		SHARED_LIB_SUFFIX=""
++		LDFLAGS=""
++		;;
++	    *)
++		SHLIB_CFLAGS="-fPIC"
++		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
++		SHLIB_SUFFIX=".so"
++		if test $doRpath = yes; then :
++
++		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
++		LDFLAGS="-Wl,-export-dynamic"
++		;;
++	    esac
++	    case "$arch" in
++	    vax)
++		CFLAGS_OPTIMIZE="-O1"
++		;;
++	    *)
++		CFLAGS_OPTIMIZE="-O2"
++		;;
++	    esac
++	    if test "${TCL_THREADS}" = "1"; then :
++
++		# On OpenBSD:	Compile with -pthread
++		#		Don't link with -lpthread
++		LIBS=`echo $LIBS | sed s/-lpthread//`
++		CFLAGS="$CFLAGS -pthread"
++
++fi
++	    # OpenBSD doesn't do version numbers with dots.
++	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++	    TCL_LIB_VERSIONS_OK=nodots
++	    ;;
++	NetBSD-*)
++	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS="$LDFLAGS -export-dynamic"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    if test "${TCL_THREADS}" = "1"; then :
++
++		# The -pthread needs to go in the CFLAGS, not LIBS
++		LIBS=`echo $LIBS | sed s/-pthread//`
++		CFLAGS="$CFLAGS -pthread"
++	    	LDFLAGS="$LDFLAGS -pthread"
++
++fi
++	    ;;
++	FreeBSD-*)
++	    # This configuration from FreeBSD Ports.
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD="${CC} -shared"
++	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$@"
++	    TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$@"
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS=""
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++fi
++	    if test "${TCL_THREADS}" = "1"; then :
++
++		# The -pthread needs to go in the LDFLAGS, not LIBS
++		LIBS=`echo $LIBS | sed s/-pthread//`
++		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
++fi
++	    case $system in
++	    FreeBSD-3.*)
++		# Version numbers are dot-stripped by system policy.
++		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
++		TCL_LIB_VERSIONS_OK=nodots
++		;;
++	    esac
++	    ;;
++	Darwin-*)
++	    CFLAGS_OPTIMIZE="-Os"
++	    SHLIB_CFLAGS="-fno-common"
++	    # To avoid discrepancies between what headers configure sees during
++	    # preprocessing tests and compiling tests, move any -isysroot and
++	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
++	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
++		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
++		if ($i~/^(isysroot|mmacosx-version-min)/) print "-"$i}'`"
++	    CFLAGS="`echo " ${CFLAGS}" | \
++		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
++		if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
++	    if test $do64bit = yes; then :
++
++		case `arch` in
++		    ppc)
++			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
++$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
++if ${tcl_cv_cc_arch_ppc64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++			    hold_cflags=$CFLAGS
++			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
++			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_cc_arch_ppc64=yes
++else
++  tcl_cv_cc_arch_ppc64=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++			    CFLAGS=$hold_cflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
++$as_echo "$tcl_cv_cc_arch_ppc64" >&6; }
++			if test $tcl_cv_cc_arch_ppc64 = yes; then :
++
++			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
++			    do64bit_ok=yes
++
++fi;;
++		    i386)
++			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
++$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
++if ${tcl_cv_cc_arch_x86_64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++			    hold_cflags=$CFLAGS
++			    CFLAGS="$CFLAGS -arch x86_64"
++			    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_cc_arch_x86_64=yes
++else
++  tcl_cv_cc_arch_x86_64=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++			    CFLAGS=$hold_cflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
++$as_echo "$tcl_cv_cc_arch_x86_64" >&6; }
++			if test $tcl_cv_cc_arch_x86_64 = yes; then :
++
++			    CFLAGS="$CFLAGS -arch x86_64"
++			    do64bit_ok=yes
++
++fi;;
++		    *)
++			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
++$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
++		esac
++
++else
++
++		# Check for combined 32-bit and 64-bit fat build
++		if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
++		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then :
++
++		    fat_32_64=yes
++fi
++
++fi
++	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
++$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
++if ${tcl_cv_ld_single_module+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
++		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++int i;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_ld_single_module=yes
++else
++  tcl_cv_ld_single_module=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++		LDFLAGS=$hold_ldflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
++$as_echo "$tcl_cv_ld_single_module" >&6; }
++	    if test $tcl_cv_ld_single_module = yes; then :
++
++		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
++
++fi
++	    # TEA specific: link shlib with current and compatibility version flags
++	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([0-9]\{1,5\}\)\(\(\.[0-9]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
++	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
++	    SHLIB_SUFFIX=".dylib"
++	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
++	    if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
++		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then :
++
++		LDFLAGS="$LDFLAGS -prebind"
++fi
++	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
++$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
++if ${tcl_cv_ld_search_paths_first+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
++		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++int i;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_ld_search_paths_first=yes
++else
++  tcl_cv_ld_search_paths_first=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++		LDFLAGS=$hold_ldflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
++$as_echo "$tcl_cv_ld_search_paths_first" >&6; }
++	    if test $tcl_cv_ld_search_paths_first = yes; then :
++
++		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
++
++fi
++	    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
++
++
++$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
++
++		tcl_cv_cc_visibility_hidden=yes
++
++fi
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
++	    # TEA specific: for combined 32 & 64 bit fat builds of Tk
++	    # extensions, verify that 64-bit build is possible.
++	    if test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"; then :
++
++		if test "${TEA_WINDOWINGSYSTEM}" = x11; then :
++
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit X11" >&5
++$as_echo_n "checking for 64-bit X11... " >&6; }
++if ${tcl_cv_lib_x11_64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
++			done
++			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
++			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
++			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <X11/Xlib.h>
++int
++main ()
++{
++XrmInitialize();
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_lib_x11_64=yes
++else
++  tcl_cv_lib_x11_64=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval $v'="$hold_'$v'"'
++			done
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_x11_64" >&5
++$as_echo "$tcl_cv_lib_x11_64" >&6; }
++
++fi
++		if test "${TEA_WINDOWINGSYSTEM}" = aqua; then :
++
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit Tk" >&5
++$as_echo_n "checking for 64-bit Tk... " >&6; }
++if ${tcl_cv_lib_tk_64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
++			done
++			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
++			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
++			cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <tk.h>
++int
++main ()
++{
++Tk_InitStubs(NULL, "", 0);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_lib_tk_64=yes
++else
++  tcl_cv_lib_tk_64=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval $v'="$hold_'$v'"'
++			done
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_tk_64" >&5
++$as_echo "$tcl_cv_lib_tk_64" >&6; }
++
++fi
++		# remove 64-bit arch flags from CFLAGS et al. if configuration
++		# does not support 64-bit.
++		if test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no; then :
++
++		    { $as_echo "$as_me:${as_lineno-$LINENO}: Removing 64-bit architectures from compiler & linker flags" >&5
++$as_echo "$as_me: Removing 64-bit architectures from compiler & linker flags" >&6;}
++		    for v in CFLAGS CPPFLAGS LDFLAGS; do
++			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
++		    done
++fi
++
++fi
++	    ;;
++	OS/390-*)
++	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
++
++$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
++
++	    ;;
++	OSF1-V*)
++	    # Digital OSF/1
++	    SHLIB_CFLAGS=""
++	    if test "$SHARED_BUILD" = 1; then :
++
++	        SHLIB_LD='ld -shared -expect_unresolved "*"'
++
++else
++
++	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
++
++fi
++	    SHLIB_SUFFIX=".so"
++	    if test $doRpath = yes; then :
++
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
++fi
++	    if test "$GCC" = yes; then :
++  CFLAGS="$CFLAGS -mieee"
++else
++
++		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
++fi
++	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
++	    if test "${TCL_THREADS}" = 1; then :
++
++		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
++		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
++		LIBS=`echo $LIBS | sed s/-lpthreads//`
++		if test "$GCC" = yes; then :
++
++		    LIBS="$LIBS -lpthread -lmach -lexc"
++
++else
++
++		    CFLAGS="$CFLAGS -pthread"
++		    LDFLAGS="$LDFLAGS -pthread"
++
++fi
++
++fi
++	    ;;
++	QNX-6*)
++	    # QNX RTP
++	    # This may work for all QNX, but it was only reported for v6.
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD="ld -Bshareable -x"
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	SCO_SV-3.2*)
++	    if test "$GCC" = yes; then :
++
++		SHLIB_CFLAGS="-fPIC -melf"
++		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
++
++else
++
++		SHLIB_CFLAGS="-Kpic -belf"
++		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
++
++fi
++	    SHLIB_LD="ld -G"
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	SunOS-5.[0-6])
++	    # Careful to not let 5.10+ fall into this case
++
++	    # Note: If _REENTRANT isn't defined, then Solaris
++	    # won't define thread-safe library routines.
++
++
++$as_echo "#define _REENTRANT 1" >>confdefs.h
++
++
++$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
++
++
++	    SHLIB_CFLAGS="-KPIC"
++	    SHLIB_SUFFIX=".so"
++	    if test "$GCC" = yes; then :
++
++		SHLIB_LD='${CC} -shared'
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++
++else
++
++		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
++		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++
++fi
++	    ;;
++	SunOS-5*)
++	    # Note: If _REENTRANT isn't defined, then Solaris
++	    # won't define thread-safe library routines.
++
++
++$as_echo "#define _REENTRANT 1" >>confdefs.h
++
++
++$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
++
++
++	    SHLIB_CFLAGS="-KPIC"
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    if test "$do64bit" = yes; then :
++
++		arch=`isainfo`
++		if test "$arch" = "sparcv9 sparc"; then :
++
++		    if test "$GCC" = yes; then :
++
++			if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then :
++
++			    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
++
++else
++
++			    do64bit_ok=yes
++			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
++			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
++			    SHLIB_CFLAGS="-fPIC"
++
++fi
++
++else
++
++			do64bit_ok=yes
++			if test "$do64bitVIS" = yes; then :
++
++			    CFLAGS="$CFLAGS -xarch=v9a"
++			    LDFLAGS_ARCH="-xarch=v9a"
++
++else
++
++			    CFLAGS="$CFLAGS -xarch=v9"
++			    LDFLAGS_ARCH="-xarch=v9"
++
++fi
++			# Solaris 64 uses this as well
++			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
++
++fi
++
++else
++  if test "$arch" = "amd64 i386"; then :
++
++		    if test "$GCC" = yes; then :
++
++			case $system in
++			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
++				do64bit_ok=yes
++				CFLAGS="$CFLAGS -m64"
++				LDFLAGS="$LDFLAGS -m64";;
++			    *)
++				{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
++			esac
++
++else
++
++			do64bit_ok=yes
++			case $system in
++			    SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
++				CFLAGS="$CFLAGS -m64"
++				LDFLAGS="$LDFLAGS -m64";;
++			    *)
++				CFLAGS="$CFLAGS -xarch=amd64"
++				LDFLAGS="$LDFLAGS -xarch=amd64";;
++			esac
++
++fi
++
++else
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
++$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
++fi
++fi
++
++fi
++
++	    SHLIB_SUFFIX=".so"
++	    if test "$GCC" = yes; then :
++
++		SHLIB_LD='${CC} -shared'
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++		if test "$do64bit_ok" = yes; then :
++
++		    if test "$arch" = "sparcv9 sparc"; then :
++
++			# We need to specify -static-libgcc or we need to
++			# add the path to the sparv9 libgcc.
++			# JH: static-libgcc is necessary for core Tcl, but may
++			# not be necessary for extensions.
++			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
++			# for finding sparcv9 libgcc, get the regular libgcc
++			# path, remove so name and append 'sparcv9'
++			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
++			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
++
++else
++  if test "$arch" = "amd64 i386"; then :
++
++			# JH: static-libgcc is necessary for core Tcl, but may
++			# not be necessary for extensions.
++			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
++
++fi
++fi
++
++fi
++
++else
++
++		case $system in
++		    SunOS-5.[1-9][0-9]*)
++			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
++		    *)
++			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
++		esac
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++
++fi
++	    ;;
++	UNIX_SV* | UnixWare-5*)
++	    SHLIB_CFLAGS="-KPIC"
++	    SHLIB_LD='${CC} -G'
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
++	    # that don't grok the -Bexport option.  Test that it does.
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
++$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
++if ${tcl_cv_ld_Bexport+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -Wl,-Bexport"
++		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++int i;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  tcl_cv_ld_Bexport=yes
++else
++  tcl_cv_ld_Bexport=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++	        LDFLAGS=$hold_ldflags
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
++$as_echo "$tcl_cv_ld_Bexport" >&6; }
++	    if test $tcl_cv_ld_Bexport = yes; then :
++
++		LDFLAGS="$LDFLAGS -Wl,-Bexport"
++
++fi
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++    esac
++
++    if test "$do64bit" = yes -a "$do64bit_ok" = no; then :
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
++$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
++
++fi
++
++
++
++    # Add in the arch flags late to ensure it wasn't removed.
++    # Not necessary in TEA, but this is aligned with core
++    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
++
++    # If we're running gcc, then change the C flags for compiling shared
++    # libraries to the right flags for gcc, instead of those for the
++    # standard manufacturer compiler.
++
++    if test "$GCC" = yes; then :
++
++	case $system in
++	    AIX-*) ;;
++	    BSD/OS*) ;;
++	    CYGWIN_*|MINGW32_*) ;;
++	    IRIX*) ;;
++	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
++	    Darwin-*) ;;
++	    SCO_SV-3.2*) ;;
++	    windows) ;;
++	    *) SHLIB_CFLAGS="-fPIC" ;;
++	esac
++fi
++
++    if test "$tcl_cv_cc_visibility_hidden" != yes; then :
++
++
++$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
++
++
++fi
++
++    if test "$SHARED_LIB_SUFFIX" = ""; then :
++
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
++fi
++    if test "$UNSHARED_LIB_SUFFIX" = ""; then :
++
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'
++fi
++
++    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5
++$as_echo_n "checking for SEH support in compiler... " >&6; }
++if ${tcl_cv_seh+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  if test "$cross_compiling" = yes; then :
++  tcl_cv_seh=no
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++#define WIN32_LEAN_AND_MEAN
++#include <windows.h>
++#undef WIN32_LEAN_AND_MEAN
++
++	    int main(int argc, char** argv) {
++		int a, b = 0;
++		__try {
++		    a = 666 / b;
++		}
++		__except (EXCEPTION_EXECUTE_HANDLER) {
++		    return 0;
++		}
++		return 1;
++	    }
++
++_ACEOF
++if ac_fn_c_try_run "$LINENO"; then :
++  tcl_cv_seh=yes
++else
++  tcl_cv_seh=no
++fi
++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
++  conftest.$ac_objext conftest.beam conftest.$ac_ext
++fi
++
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5
++$as_echo "$tcl_cv_seh" >&6; }
++	if test "$tcl_cv_seh" = "no" ; then
++
++$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h
++
++	fi
++
++	#
++	# Check to see if the excpt.h include file provided contains the
++	# definition for EXCEPTION_DISPOSITION; if not, which is the case
++	# with Cygwin's version as of 2002-04-10, define it to be int,
++	# sufficient for getting the current code to work.
++	#
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5
++$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; }
++if ${tcl_cv_eh_disposition+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++#	    define WIN32_LEAN_AND_MEAN
++#	    include <windows.h>
++#	    undef WIN32_LEAN_AND_MEAN
++
++int
++main ()
++{
++
++		EXCEPTION_DISPOSITION x;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_eh_disposition=yes
++else
++  tcl_cv_eh_disposition=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5
++$as_echo "$tcl_cv_eh_disposition" >&6; }
++	if test "$tcl_cv_eh_disposition" = "no" ; then
++
++$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h
++
++	fi
++
++	# Check to see if winnt.h defines CHAR, SHORT, and LONG
++	# even if VOID has already been #defined. The win32api
++	# used by mingw and cygwin is known to do this.
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5
++$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; }
++if ${tcl_cv_winnt_ignore_void+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++#define VOID void
++#define WIN32_LEAN_AND_MEAN
++#include <windows.h>
++#undef WIN32_LEAN_AND_MEAN
++
++int
++main ()
++{
++
++		CHAR c;
++		SHORT s;
++		LONG l;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_winnt_ignore_void=yes
++else
++  tcl_cv_winnt_ignore_void=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5
++$as_echo "$tcl_cv_winnt_ignore_void" >&6; }
++	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
++
++$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h
++
++	fi
++    fi
++
++	# See if the compiler supports casting to a union type.
++	# This is used to stop gcc from printing a compiler
++	# warning when initializing a union member.
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
++$as_echo_n "checking for cast to union support... " >&6; }
++if ${tcl_cv_cast_to_union+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++
++		  union foo { int i; double d; };
++		  union foo f = (union foo) (int) 0;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_cast_to_union=yes
++else
++  tcl_cv_cast_to_union=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
++$as_echo "$tcl_cv_cast_to_union" >&6; }
++	if test "$tcl_cv_cast_to_union" = "yes"; then
++
++$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
++
++	fi
++
++
++
++
++
++
++
++
++
++
++
++
++
++    # These must be called after we do the basic CFLAGS checks and
++    # verify any possible 64-bit or similar switches are necessary
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
++$as_echo_n "checking for required early compiler flags... " >&6; }
++    tcl_flags=""
++
++    if ${tcl_cv_flag__isoc99_source+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <stdlib.h>
++int
++main ()
++{
++char *p = (char *)strtoll; char *q = (char *)strtoull;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__isoc99_source=no
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#define _ISOC99_SOURCE 1
++#include <stdlib.h>
++int
++main ()
++{
++char *p = (char *)strtoll; char *q = (char *)strtoull;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__isoc99_source=yes
++else
++  tcl_cv_flag__isoc99_source=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++
++    if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
++
++$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
++
++	tcl_flags="$tcl_flags _ISOC99_SOURCE"
++    fi
++
++
++    if ${tcl_cv_flag__largefile64_source+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/stat.h>
++int
++main ()
++{
++struct stat64 buf; int i = stat64("/", &buf);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__largefile64_source=no
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#define _LARGEFILE64_SOURCE 1
++#include <sys/stat.h>
++int
++main ()
++{
++struct stat64 buf; int i = stat64("/", &buf);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__largefile64_source=yes
++else
++  tcl_cv_flag__largefile64_source=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++
++    if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
++
++$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
++
++	tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
++    fi
++
++
++    if ${tcl_cv_flag__largefile_source64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/stat.h>
++int
++main ()
++{
++char *p = (char *)open64;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__largefile_source64=no
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#define _LARGEFILE_SOURCE64 1
++#include <sys/stat.h>
++int
++main ()
++{
++char *p = (char *)open64;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_flag__largefile_source64=yes
++else
++  tcl_cv_flag__largefile_source64=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++
++    if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
++
++$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
++
++	tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
++    fi
++
++    if test "x${tcl_flags}" = "x" ; then
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
++$as_echo "none" >&6; }
++    else
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
++$as_echo "${tcl_flags}" >&6; }
++    fi
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
++$as_echo_n "checking for 64-bit integer type... " >&6; }
++    if ${tcl_cv_type_64bit+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	tcl_cv_type_64bit=none
++	# See if the compiler knows natively about __int64
++	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++__int64 value = (__int64) 0;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_type_64bit=__int64
++else
++  tcl_type_64bit="long long"
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++	# See if we should use long anyway  Note that we substitute in the
++	# type that is our current guess for a 64-bit type inside this check
++	# program, so it should be modified only carefully...
++        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++int
++main ()
++{
++switch (0) {
++            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
++        }
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_type_64bit=${tcl_type_64bit}
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++
++    if test "${tcl_cv_type_64bit}" = none ; then
++
++$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5
++$as_echo "using long" >&6; }
++    elif test "${tcl_cv_type_64bit}" = "__int64" \
++		-a "${TEA_PLATFORM}" = "windows" ; then
++	# TEA specific: We actually want to use the default tcl.h checks in
++	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using Tcl header defaults" >&5
++$as_echo "using Tcl header defaults" >&6; }
++    else
++
++cat >>confdefs.h <<_ACEOF
++#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
++_ACEOF
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
++$as_echo "${tcl_cv_type_64bit}" >&6; }
++
++	# Now check for auxiliary declarations
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
++$as_echo_n "checking for struct dirent64... " >&6; }
++if ${tcl_cv_struct_dirent64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/types.h>
++#include <dirent.h>
++int
++main ()
++{
++struct dirent64 p;
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_struct_dirent64=yes
++else
++  tcl_cv_struct_dirent64=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
++$as_echo "$tcl_cv_struct_dirent64" >&6; }
++	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
++
++$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
++
++	fi
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
++$as_echo_n "checking for struct stat64... " >&6; }
++if ${tcl_cv_struct_stat64+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/stat.h>
++int
++main ()
++{
++struct stat64 p;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_struct_stat64=yes
++else
++  tcl_cv_struct_stat64=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
++$as_echo "$tcl_cv_struct_stat64" >&6; }
++	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
++
++$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
++
++	fi
++
++	for ac_func in open64 lseek64
++do :
++  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
++if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
++  cat >>confdefs.h <<_ACEOF
++#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++done
++
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
++$as_echo_n "checking for off64_t... " >&6; }
++	if ${tcl_cv_type_off64_t+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include <sys/types.h>
++int
++main ()
++{
++off64_t offset;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  tcl_cv_type_off64_t=yes
++else
++  tcl_cv_type_off64_t=no
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
++
++			if test "x${tcl_cv_type_off64_t}" = "xyes" && \
++	        test "x${ac_cv_func_lseek64}" = "xyes" && \
++	        test "x${ac_cv_func_open64}" = "xyes" ; then
++
++$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
++
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++	else
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++	fi
++    fi
++
++
++
++#--------------------------------------------------------------------
++# Set the default compiler switches based on the --enable-symbols option.
++#--------------------------------------------------------------------
++
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
++$as_echo_n "checking for build with symbols... " >&6; }
++    # Check whether --enable-symbols was given.
++if test "${enable_symbols+set}" = set; then :
++  enableval=$enable_symbols; tcl_ok=$enableval
++else
++  tcl_ok=no
++fi
++
++    DBGX=""
++    if test "$tcl_ok" = "no"; then
++	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
++	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
++	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++    else
++	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
++	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
++	if test "$tcl_ok" = "yes"; then
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
++$as_echo "yes (standard debugging)" >&6; }
++	fi
++    fi
++    # TEA specific:
++    if test "${TEA_PLATFORM}" != "windows" ; then
++	LDFLAGS_DEFAULT="${LDFLAGS}"
++    fi
++
++
++
++
++    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
++
++$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
++
++    fi
++
++    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
++	if test "$tcl_ok" = "all"; then
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem debugging" >&5
++$as_echo "enabled symbols mem debugging" >&6; }
++	else
++	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
++$as_echo "enabled $tcl_ok debugging" >&6; }
++	fi
++    fi
++
++
++#--------------------------------------------------------------------
++# Everyone should be linking against the Tcl stub library.  If you
++# can't for some reason, remove this definition.  If you aren't using
++# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
++# link against the non-stubbed Tcl library.  Add Tk too if necessary.
++#--------------------------------------------------------------------
++
++
++$as_echo "#define USE_TCL_STUBS 1" >>confdefs.h
++
++#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
++
++
++#--------------------------------------------------------------------
++# Redefine fdatasync as fsync on systems that lack fdatasync
++#--------------------------------------------------------------------
++#
++#AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
++# Check for library functions that SQLite can optionally use.
++for ac_func in fdatasync usleep fullfsync localtime_r gmtime_r
++do :
++  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
++if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
++  cat >>confdefs.h <<_ACEOF
++#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++done
++
++
++ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default"
++if test "x$ac_cv_have_decl_strerror_r" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_STRERROR_R $ac_have_decl
++_ACEOF
++
++for ac_func in strerror_r
++do :
++  ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r"
++if test "x$ac_cv_func_strerror_r" = xyes; then :
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_STRERROR_R 1
++_ACEOF
++
++fi
++done
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5
++$as_echo_n "checking whether strerror_r returns char *... " >&6; }
++if ${ac_cv_func_strerror_r_char_p+:} false; then :
++  $as_echo_n "(cached) " >&6
++else
++
++    ac_cv_func_strerror_r_char_p=no
++    if test $ac_cv_have_decl_strerror_r = yes; then
++      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$ac_includes_default
++int
++main ()
++{
++
++	  char buf[100];
++	  char x = *strerror_r (0, buf, sizeof buf);
++	  char *p = strerror_r (0, buf, sizeof buf);
++	  return !p || x;
++
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++  ac_cv_func_strerror_r_char_p=yes
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++    else
++      # strerror_r is not declared.  Choose between
++      # systems that have relatively inaccessible declarations for the
++      # function.  BeOS and DEC UNIX 4.0 fall in this category, but the
++      # former has a strerror_r that returns char*, while the latter
++      # has a strerror_r that returns `int'.
++      # This test should segfault on the DEC system.
++      if test "$cross_compiling" = yes; then :
++  :
++else
++  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++$ac_includes_default
++	extern char *strerror_r ();
++int
++main ()
++{
++char buf[100];
++	  char x = *strerror_r (0, buf, sizeof buf);
++	  return ! isalpha (x);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_run "$LINENO"; then :
++  ac_cv_func_strerror_r_char_p=yes
++fi
++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
++  conftest.$ac_objext conftest.beam conftest.$ac_ext
++fi
++
++    fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5
++$as_echo "$ac_cv_func_strerror_r_char_p" >&6; }
++if test $ac_cv_func_strerror_r_char_p = yes; then
++
++$as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h
++
++fi
++
++
++
++#--------------------------------------------------------------------
++# This macro generates a line to use when building a library.  It
++# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
++# and TEA_LOAD_TCLCONFIG macros above.
++#--------------------------------------------------------------------
++
++
++    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
++	MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(PKG_OBJECTS)"
++	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\$@ \$(PKG_OBJECTS)"
++	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++
++#if defined(_MSC_VER) && _MSC_VER >= 1400
++print("manifest needed")
++#endif
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++  $EGREP "manifest needed" >/dev/null 2>&1; then :
++
++	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
++	VC_MANIFEST_EMBED_DLL="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;2 ; fi"
++	VC_MANIFEST_EMBED_EXE="if test -f \$@.manifest ; then mt.exe -nologo -manifest \$@.manifest -outputresource:\$@\;1 ; fi"
++	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
++
++    CLEANFILES="$CLEANFILES *.manifest"
++
++
++fi
++rm -f conftest*
++
++	MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\$@ \$(PKG_STUB_OBJECTS)"
++    else
++	MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(PKG_OBJECTS)"
++	MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
++	MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(PKG_STUB_OBJECTS)"
++    fi
++
++    if test "${SHARED_BUILD}" = "1" ; then
++	MAKE_LIB="${MAKE_SHARED_LIB} "
++    else
++	MAKE_LIB="${MAKE_STATIC_LIB} "
++    fi
++
++    #--------------------------------------------------------------------
++    # Shared libraries and static libraries have different names.
++    # Use the double eval to make sure any variables in the suffix is
++    # substituted. (@@@ Might not be necessary anymore)
++    #--------------------------------------------------------------------
++
++    if test "${TEA_PLATFORM}" = "windows" ; then
++	if test "${SHARED_BUILD}" = "1" ; then
++	    # We force the unresolved linking of symbols that are really in
++	    # the private libraries of Tcl and Tk.
++	    if test x"${TK_BIN_DIR}" != x ; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
++	    fi
++	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
++	    if test "$GCC" = "yes"; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
++	    fi
++	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
++	else
++	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
++	    if test "$GCC" = "yes"; then
++		PKG_LIB_FILE=lib${PKG_LIB_FILE}
++	    fi
++	fi
++	# Some packages build their own stubs libraries
++	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
++	if test "$GCC" = "yes"; then
++	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
++	fi
++	# These aren't needed on Windows (either MSVC or gcc)
++	RANLIB=:
++	RANLIB_STUB=:
++    else
++	RANLIB_STUB="${RANLIB}"
++	if test "${SHARED_BUILD}" = "1" ; then
++	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
++	    if test x"${TK_BIN_DIR}" != x ; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
++	    fi
++	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
++	    RANLIB=:
++	else
++	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
++	fi
++	# Some packages build their own stubs libraries
++	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
++    fi
++
++    # These are escaped so that only CFLAGS is picked up at configure time.
++    # The other values will be substituted at make time.
++    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
++    if test "${SHARED_BUILD}" = "1" ; then
++	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
++    fi
++
++
++
++
++
++
++
++
++
++
++#--------------------------------------------------------------------
++# Determine the name of the tclsh and/or wish executables in the
++# Tcl and Tk build directories or the location they were installed
++# into. These paths are used to support running test cases only,
++# the Makefile should not be making use of these paths to generate
++# a pkgIndex.tcl file or anything else at extension build time.
++#--------------------------------------------------------------------
++
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
++$as_echo_n "checking for tclsh... " >&6; }
++    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++        # tclConfig.sh is in Tcl build directory
++        if test "${TEA_PLATFORM}" = "windows"; then
++            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
++        else
++            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
++        fi
++    else
++        # tclConfig.sh is in install location
++        if test "${TEA_PLATFORM}" = "windows"; then
++            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
++        else
++            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
++        fi
++        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
++              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
++              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
++        for i in $list ; do
++            if test -f "$i/${TCLSH_PROG}" ; then
++                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
++                break
++            fi
++        done
++        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
++    fi
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${TCLSH_PROG}" >&5
++$as_echo "${TCLSH_PROG}" >&6; }
++
++
++#TEA_PROG_WISH
++
++#--------------------------------------------------------------------
++# Finally, substitute all of the various values into the Makefile.
++# You may alternatively have a special pkgIndex.tcl.in or other files
++# which require substituting th AC variables in.  Include these here.
++#--------------------------------------------------------------------
++
++ac_config_files="$ac_config_files Makefile pkgIndex.tcl"
++
++cat >confcache <<\_ACEOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs, see configure's option --config-cache.
++# It is not useful on other systems.  If it contains results you don't
++# want to keep, you may remove or edit it.
++#
++# config.status only pays attention to the cache file if you give it
++# the --recheck option to rerun configure.
++#
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
++# loading this file, other *unset* `ac_cv_foo' will be assigned the
++# following values.
++
++_ACEOF
++
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, we kill variables containing newlines.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++(
++  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
++    eval ac_val=\$$ac_var
++    case $ac_val in #(
++    *${as_nl}*)
++      case $ac_var in #(
++      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
++$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
++      esac
++      case $ac_var in #(
++      _ | IFS | as_nl) ;; #(
++      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
++      *) { eval $ac_var=; unset $ac_var;} ;;
++      esac ;;
++    esac
++  done
++
++  (set) 2>&1 |
++    case $as_nl`(ac_space=' '; set) 2>&1` in #(
++    *${as_nl}ac_space=\ *)
++      # `set' does not quote correctly, so add quotes: double-quote
++      # substitution turns \\\\ into \\, and sed turns \\ into \.
++      sed -n \
++	"s/'/'\\\\''/g;
++	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++      ;; #(
++    *)
++      # `set' quotes correctly as required by POSIX, so do not add quotes.
++      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
++      ;;
++    esac |
++    sort
++) |
++  sed '
++     /^ac_cv_env_/b end
++     t clear
++     :clear
++     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++     t end
++     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
++     :end' >>confcache
++if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
++  if test -w "$cache_file"; then
++    if test "x$cache_file" != "x/dev/null"; then
++      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
++$as_echo "$as_me: updating cache $cache_file" >&6;}
++      if test ! -f "$cache_file" || test -h "$cache_file"; then
++	cat confcache >"$cache_file"
++      else
++        case $cache_file in #(
++        */* | ?:*)
++	  mv -f confcache "$cache_file"$$ &&
++	  mv -f "$cache_file"$$ "$cache_file" ;; #(
++        *)
++	  mv -f confcache "$cache_file" ;;
++	esac
++      fi
++    fi
++  else
++    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
++$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
++  fi
++fi
++rm -f confcache
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++#
++# If the first sed substitution is executed (which looks for macros that
++# take arguments), then branch to the quote section.  Otherwise,
++# look for a macro that doesn't take arguments.
++ac_script='
++:mline
++/\\$/{
++ N
++ s,\\\n,,
++ b mline
++}
++t clear
++:clear
++s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
++t quote
++s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
++t quote
++b any
++:quote
++s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
++s/\[/\\&/g
++s/\]/\\&/g
++s/\$/$$/g
++H
++:any
++${
++	g
++	s/^\n//
++	s/\n/ /g
++	p
++}
++'
++DEFS=`sed -n "$ac_script" confdefs.h`
++
++
++ac_libobjs=
++ac_ltlibobjs=
++U=
++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
++  # 1. Remove the extension, and $U if already installed.
++  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
++  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
++  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
++  #    will be set to the directory where LIBOBJS objects are built.
++  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
++  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
++done
++LIBOBJS=$ac_libobjs
++
++LTLIBOBJS=$ac_ltlibobjs
++
++
++
++CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
++
++: "${CONFIG_STATUS=./config.status}"
++ac_write_fail=0
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files $CONFIG_STATUS"
++{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
++$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
++as_write_fail=0
++cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
++#! $SHELL
++# Generated by $as_me.
++# Run this file to recreate the current configuration.
++# Compiler output produced by configure, useful for debugging
++# configure, is in config.log if it exists.
++
++debug=false
++ac_cs_recheck=false
++ac_cs_silent=false
++
++SHELL=\${CONFIG_SHELL-$SHELL}
++export SHELL
++_ASEOF
++cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
++## -------------------- ##
++## M4sh Initialization. ##
++## -------------------- ##
++
++# Be more Bourne compatible
++DUALCASE=1; export DUALCASE # for MKS sh
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
++  emulate sh
++  NULLCMD=:
++  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
++  # is contrary to our usage.  Disable this feature.
++  alias -g '${1+"$@"}'='"$@"'
++  setopt NO_GLOB_SUBST
++else
++  case `(set -o) 2>/dev/null` in #(
++  *posix*) :
++    set -o posix ;; #(
++  *) :
++     ;;
++esac
++fi
++
++
++as_nl='
++'
++export as_nl
++# Printing a long string crashes Solaris 7 /usr/bin/printf.
++as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
++as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
++# Prefer a ksh shell builtin over an external printf program on Solaris,
++# but without wasting forks for bash or zsh.
++if test -z "$BASH_VERSION$ZSH_VERSION" \
++    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
++  as_echo='print -r --'
++  as_echo_n='print -rn --'
++elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
++  as_echo='printf %s\n'
++  as_echo_n='printf %s'
++else
++  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
++    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
++    as_echo_n='/usr/ucb/echo -n'
++  else
++    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
++    as_echo_n_body='eval
++      arg=$1;
++      case $arg in #(
++      *"$as_nl"*)
++	expr "X$arg" : "X\\(.*\\)$as_nl";
++	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
++      esac;
++      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
++    '
++    export as_echo_n_body
++    as_echo_n='sh -c $as_echo_n_body as_echo'
++  fi
++  export as_echo_body
++  as_echo='sh -c $as_echo_body as_echo'
++fi
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++  PATH_SEPARATOR=:
++  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
++    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
++      PATH_SEPARATOR=';'
++  }
++fi
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.  Quoting is
++# there to prevent editors from complaining about space-tab.
++# (If _AS_PATH_WALK were called with IFS unset, it would disable word
++# splitting by setting IFS to empty value.)
++IFS=" ""	$as_nl"
++
++# Find who we are.  Look in the path if we contain no directory separator.
++as_myself=
++case $0 in #((
++  *[\\/]* ) as_myself=$0 ;;
++  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++  IFS=$as_save_IFS
++  test -z "$as_dir" && as_dir=.
++    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++  done
++IFS=$as_save_IFS
++
++     ;;
++esac
++# We did not find ourselves, most probably we were run as `sh COMMAND'
++# in which case we are not to be found in the path.
++if test "x$as_myself" = x; then
++  as_myself=$0
++fi
++if test ! -f "$as_myself"; then
++  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
++  exit 1
++fi
++
++# Unset variables that we do not need and which cause bugs (e.g. in
++# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
++# suppresses any "Segmentation fault" message there.  '((' could
++# trigger a bug in pdksh 5.2.14.
++for as_var in BASH_ENV ENV MAIL MAILPATH
++do eval test x\${$as_var+set} = xset \
++  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
++done
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++LC_ALL=C
++export LC_ALL
++LANGUAGE=C
++export LANGUAGE
++
++# CDPATH.
++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
++
++
++# as_fn_error STATUS ERROR [LINENO LOG_FD]
++# ----------------------------------------
++# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
++# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
++# script with STATUS, using 1 if that was 0.
++as_fn_error ()
++{
++  as_status=$1; test $as_status -eq 0 && as_status=1
++  if test "$4"; then
++    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
++    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
++  fi
++  $as_echo "$as_me: error: $2" >&2
++  as_fn_exit $as_status
++} # as_fn_error
++
++
++# as_fn_set_status STATUS
++# -----------------------
++# Set $? to STATUS, without forking.
++as_fn_set_status ()
++{
++  return $1
++} # as_fn_set_status
++
++# as_fn_exit STATUS
++# -----------------
++# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
++as_fn_exit ()
++{
++  set +e
++  as_fn_set_status $1
++  exit $1
++} # as_fn_exit
++
++# as_fn_unset VAR
++# ---------------
++# Portably unset VAR.
++as_fn_unset ()
++{
++  { eval $1=; unset $1;}
++}
++as_unset=as_fn_unset
++# as_fn_append VAR VALUE
++# ----------------------
++# Append the text in VALUE to the end of the definition contained in VAR. Take
++# advantage of any shell optimizations that allow amortized linear growth over
++# repeated appends, instead of the typical quadratic growth present in naive
++# implementations.
++if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
++  eval 'as_fn_append ()
++  {
++    eval $1+=\$2
++  }'
++else
++  as_fn_append ()
++  {
++    eval $1=\$$1\$2
++  }
++fi # as_fn_append
++
++# as_fn_arith ARG...
++# ------------------
++# Perform arithmetic evaluation on the ARGs, and store the result in the
++# global $as_val. Take advantage of shells that can avoid forks. The arguments
++# must be portable across $(()) and expr.
++if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
++  eval 'as_fn_arith ()
++  {
++    as_val=$(( $* ))
++  }'
++else
++  as_fn_arith ()
++  {
++    as_val=`expr "$@" || test $? -eq 1`
++  }
++fi # as_fn_arith
++
++
++if expr a : '\(a\)' >/dev/null 2>&1 &&
++   test "X`expr 00001 : '.*\(...\)'`" = X001; then
++  as_expr=expr
++else
++  as_expr=false
++fi
++
++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
++  as_basename=basename
++else
++  as_basename=false
++fi
++
++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
++  as_dirname=dirname
++else
++  as_dirname=false
++fi
++
++as_me=`$as_basename -- "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++	 X"$0" : 'X\(//\)$' \| \
++	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X/"$0" |
++    sed '/^.*\/\([^/][^/]*\)\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\/\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\/\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++ECHO_C= ECHO_N= ECHO_T=
++case `echo -n x` in #(((((
++-n*)
++  case `echo 'xy\c'` in
++  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
++  xy)  ECHO_C='\c';;
++  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
++       ECHO_T='	';;
++  esac;;
++*)
++  ECHO_N='-n';;
++esac
++
++rm -f conf$$ conf$$.exe conf$$.file
++if test -d conf$$.dir; then
++  rm -f conf$$.dir/conf$$.file
++else
++  rm -f conf$$.dir
++  mkdir conf$$.dir 2>/dev/null
++fi
++if (echo >conf$$.file) 2>/dev/null; then
++  if ln -s conf$$.file conf$$ 2>/dev/null; then
++    as_ln_s='ln -s'
++    # ... but there are two gotchas:
++    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
++    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
++    # In both cases, we have to default to `cp -pR'.
++    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
++      as_ln_s='cp -pR'
++  elif ln conf$$.file conf$$ 2>/dev/null; then
++    as_ln_s=ln
++  else
++    as_ln_s='cp -pR'
++  fi
++else
++  as_ln_s='cp -pR'
++fi
++rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
++rmdir conf$$.dir 2>/dev/null
++
++
++# as_fn_mkdir_p
++# -------------
++# Create "$as_dir" as a directory, including parents if necessary.
++as_fn_mkdir_p ()
++{
++
++  case $as_dir in #(
++  -*) as_dir=./$as_dir;;
++  esac
++  test -d "$as_dir" || eval $as_mkdir_p || {
++    as_dirs=
++    while :; do
++      case $as_dir in #(
++      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
++      *) as_qdir=$as_dir;;
++      esac
++      as_dirs="'$as_qdir' $as_dirs"
++      as_dir=`$as_dirname -- "$as_dir" ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	 X"$as_dir" : 'X\(//\)[^/]' \| \
++	 X"$as_dir" : 'X\(//\)$' \| \
++	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X"$as_dir" |
++    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)[^/].*/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++      test -d "$as_dir" && break
++    done
++    test -z "$as_dirs" || eval "mkdir $as_dirs"
++  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
++
++
++} # as_fn_mkdir_p
++if mkdir -p . 2>/dev/null; then
++  as_mkdir_p='mkdir -p "$as_dir"'
++else
++  test -d ./-p && rmdir ./-p
++  as_mkdir_p=false
++fi
++
++
++# as_fn_executable_p FILE
++# -----------------------
++# Test if FILE is an executable regular file.
++as_fn_executable_p ()
++{
++  test -f "$1" && test -x "$1"
++} # as_fn_executable_p
++as_test_x='test -x'
++as_executable_p=as_fn_executable_p
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
++
++
++exec 6>&1
++## ----------------------------------- ##
++## Main body of $CONFIG_STATUS script. ##
++## ----------------------------------- ##
++_ASEOF
++test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++# Save the log message, to keep $0 and so on meaningful, and to
++# report actual input values of CONFIG_FILES etc. instead of their
++# values after options handling.
++ac_log="
++This file was extended by sqlite $as_me 3.26.0, which was
++generated by GNU Autoconf 2.69.  Invocation command line was
++
++  CONFIG_FILES    = $CONFIG_FILES
++  CONFIG_HEADERS  = $CONFIG_HEADERS
++  CONFIG_LINKS    = $CONFIG_LINKS
++  CONFIG_COMMANDS = $CONFIG_COMMANDS
++  $ $0 $@
++
++on `(hostname || uname -n) 2>/dev/null | sed 1q`
++"
++
++_ACEOF
++
++case $ac_config_files in *"
++"*) set x $ac_config_files; shift; ac_config_files=$*;;
++esac
++
++
++
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++# Files that config.status was made for.
++config_files="$ac_config_files"
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++ac_cs_usage="\
++\`$as_me' instantiates files and other configuration actions
++from templates according to the current configuration.  Unless the files
++and actions are specified as TAGs, all are instantiated by default.
++
++Usage: $0 [OPTION]... [TAG]...
++
++  -h, --help       print this help, then exit
++  -V, --version    print version number and configuration settings, then exit
++      --config     print configuration, then exit
++  -q, --quiet, --silent
++                   do not print progress messages
++  -d, --debug      don't remove temporary files
++      --recheck    update $as_me by reconfiguring in the same conditions
++      --file=FILE[:TEMPLATE]
++                   instantiate the configuration file FILE
++
++Configuration files:
++$config_files
++
++Report bugs to the package provider."
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
++ac_cs_version="\\
++sqlite config.status 3.26.0
++configured by $0, generated by GNU Autoconf 2.69,
++  with options \\"\$ac_cs_config\\"
++
++Copyright (C) 2012 Free Software Foundation, Inc.
++This config.status script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it."
++
++ac_pwd='$ac_pwd'
++srcdir='$srcdir'
++test -n "\$AWK" || AWK=awk
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++# The default lists apply if the user does not specify any file.
++ac_need_defaults=:
++while test $# != 0
++do
++  case $1 in
++  --*=?*)
++    ac_option=`expr "X$1" : 'X\([^=]*\)='`
++    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
++    ac_shift=:
++    ;;
++  --*=)
++    ac_option=`expr "X$1" : 'X\([^=]*\)='`
++    ac_optarg=
++    ac_shift=:
++    ;;
++  *)
++    ac_option=$1
++    ac_optarg=$2
++    ac_shift=shift
++    ;;
++  esac
++
++  case $ac_option in
++  # Handling of the options.
++  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++    ac_cs_recheck=: ;;
++  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
++    $as_echo "$ac_cs_version"; exit ;;
++  --config | --confi | --conf | --con | --co | --c )
++    $as_echo "$ac_cs_config"; exit ;;
++  --debug | --debu | --deb | --de | --d | -d )
++    debug=: ;;
++  --file | --fil | --fi | --f )
++    $ac_shift
++    case $ac_optarg in
++    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
++    '') as_fn_error $? "missing file argument" ;;
++    esac
++    as_fn_append CONFIG_FILES " '$ac_optarg'"
++    ac_need_defaults=false;;
++  --he | --h |  --help | --hel | -h )
++    $as_echo "$ac_cs_usage"; exit ;;
++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++  | -silent | --silent | --silen | --sile | --sil | --si | --s)
++    ac_cs_silent=: ;;
++
++  # This is an error.
++  -*) as_fn_error $? "unrecognized option: \`$1'
++Try \`$0 --help' for more information." ;;
++
++  *) as_fn_append ac_config_targets " $1"
++     ac_need_defaults=false ;;
++
++  esac
++  shift
++done
++
++ac_configure_extra_args=
++
++if $ac_cs_silent; then
++  exec 6>/dev/null
++  ac_configure_extra_args="$ac_configure_extra_args --silent"
++fi
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++if \$ac_cs_recheck; then
++  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
++  shift
++  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
++  CONFIG_SHELL='$SHELL'
++  export CONFIG_SHELL
++  exec "\$@"
++fi
++
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++exec 5>>config.log
++{
++  echo
++  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
++## Running $as_me. ##
++_ASBOX
++  $as_echo "$ac_log"
++} >&5
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++
++# Handling of arguments.
++for ac_config_target in $ac_config_targets
++do
++  case $ac_config_target in
++    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
++    "pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;
++
++  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
++  esac
++done
++
++
++# If the user did not use the arguments to specify the items to instantiate,
++# then the envvar interface is used.  Set only those that are not.
++# We use the long form for the default assignment because of an extremely
++# bizarre bug on SunOS 4.1.3.
++if $ac_need_defaults; then
++  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
++fi
++
++# Have a temporary directory for convenience.  Make it in the build tree
++# simply because there is no reason against having it here, and in addition,
++# creating and moving files from /tmp can sometimes cause problems.
++# Hook for its removal unless debugging.
++# Note that there is a small window in which the directory will not be cleaned:
++# after its creation but before its name has been assigned to `$tmp'.
++$debug ||
++{
++  tmp= ac_tmp=
++  trap 'exit_status=$?
++  : "${ac_tmp:=$tmp}"
++  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
++' 0
++  trap 'as_fn_exit 1' 1 2 13 15
++}
++# Create a (secure) tmp directory for tmp files.
++
++{
++  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
++  test -d "$tmp"
++}  ||
++{
++  tmp=./conf$$-$RANDOM
++  (umask 077 && mkdir "$tmp")
++} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
++ac_tmp=$tmp
++
++# Set up the scripts for CONFIG_FILES section.
++# No need to generate them if there are no CONFIG_FILES.
++# This happens for instance with `./config.status config.h'.
++if test -n "$CONFIG_FILES"; then
++
++
++ac_cr=`echo X | tr X '\015'`
++# On cygwin, bash can eat \r inside `` if the user requested igncr.
++# But we know of no other shell where ac_cr would be empty at this
++# point, so we can use a bashism as a fallback.
++if test "x$ac_cr" = x; then
++  eval ac_cr=\$\'\\r\'
++fi
++ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
++if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
++  ac_cs_awk_cr='\\r'
++else
++  ac_cs_awk_cr=$ac_cr
++fi
++
++echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
++_ACEOF
++
++
++{
++  echo "cat >conf$$subs.awk <<_ACEOF" &&
++  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
++  echo "_ACEOF"
++} >conf$$subs.sh ||
++  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
++ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
++ac_delim='%!_!# '
++for ac_last_try in false false false false false :; do
++  . ./conf$$subs.sh ||
++    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
++
++  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
++  if test $ac_delim_n = $ac_delim_num; then
++    break
++  elif $ac_last_try; then
++    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
++  else
++    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
++  fi
++done
++rm -f conf$$subs.sh
++
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
++_ACEOF
++sed -n '
++h
++s/^/S["/; s/!.*/"]=/
++p
++g
++s/^[^!]*!//
++:repl
++t repl
++s/'"$ac_delim"'$//
++t delim
++:nl
++h
++s/\(.\{148\}\)..*/\1/
++t more1
++s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
++p
++n
++b repl
++:more1
++s/["\\]/\\&/g; s/^/"/; s/$/"\\/
++p
++g
++s/.\{148\}//
++t nl
++:delim
++h
++s/\(.\{148\}\)..*/\1/
++t more2
++s/["\\]/\\&/g; s/^/"/; s/$/"/
++p
++b
++:more2
++s/["\\]/\\&/g; s/^/"/; s/$/"\\/
++p
++g
++s/.\{148\}//
++t delim
++' <conf$$subs.awk | sed '
++/^[^""]/{
++  N
++  s/\n//
++}
++' >>$CONFIG_STATUS || ac_write_fail=1
++rm -f conf$$subs.awk
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++_ACAWK
++cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
++  for (key in S) S_is_set[key] = 1
++  FS = ""
++
++}
++{
++  line = $ 0
++  nfields = split(line, field, "@")
++  substed = 0
++  len = length(field[1])
++  for (i = 2; i < nfields; i++) {
++    key = field[i]
++    keylen = length(key)
++    if (S_is_set[key]) {
++      value = S[key]
++      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
++      len += length(value) + length(field[++i])
++      substed = 1
++    } else
++      len += 1 + keylen
++  }
++
++  print line
++}
++
++_ACAWK
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
++  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
++else
++  cat
++fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
++  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
++_ACEOF
++
++# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
++# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
++# trailing colons and then remove the whole line if VPATH becomes empty
++# (actually we leave an empty line to preserve line numbers).
++if test "x$srcdir" = x.; then
++  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
++h
++s///
++s/^/:/
++s/[	 ]*$/:/
++s/:\$(srcdir):/:/g
++s/:\${srcdir}:/:/g
++s/:@srcdir@:/:/g
++s/^:*//
++s/:*$//
++x
++s/\(=[	 ]*\).*/\1/
++G
++s/\n//
++s/^[^=]*=[	 ]*$//
++}'
++fi
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++fi # test -n "$CONFIG_FILES"
++
++
++eval set X "  :F $CONFIG_FILES      "
++shift
++for ac_tag
++do
++  case $ac_tag in
++  :[FHLC]) ac_mode=$ac_tag; continue;;
++  esac
++  case $ac_mode$ac_tag in
++  :[FHL]*:*);;
++  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
++  :[FH]-) ac_tag=-:-;;
++  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
++  esac
++  ac_save_IFS=$IFS
++  IFS=:
++  set x $ac_tag
++  IFS=$ac_save_IFS
++  shift
++  ac_file=$1
++  shift
++
++  case $ac_mode in
++  :L) ac_source=$1;;
++  :[FH])
++    ac_file_inputs=
++    for ac_f
++    do
++      case $ac_f in
++      -) ac_f="$ac_tmp/stdin";;
++      *) # Look for the file first in the build tree, then in the source tree
++	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
++	 # because $ac_f cannot contain `:'.
++	 test -f "$ac_f" ||
++	   case $ac_f in
++	   [\\/$]*) false;;
++	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
++	   esac ||
++	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
++      esac
++      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
++      as_fn_append ac_file_inputs " '$ac_f'"
++    done
++
++    # Let's still pretend it is `configure' which instantiates (i.e., don't
++    # use $as_me), people would be surprised to read:
++    #    /* config.h.  Generated by config.status.  */
++    configure_input='Generated from '`
++	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
++	`' by configure.'
++    if test x"$ac_file" != x-; then
++      configure_input="$ac_file.  $configure_input"
++      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
++$as_echo "$as_me: creating $ac_file" >&6;}
++    fi
++    # Neutralize special characters interpreted by sed in replacement strings.
++    case $configure_input in #(
++    *\&* | *\|* | *\\* )
++       ac_sed_conf_input=`$as_echo "$configure_input" |
++       sed 's/[\\\\&|]/\\\\&/g'`;; #(
++    *) ac_sed_conf_input=$configure_input;;
++    esac
++
++    case $ac_tag in
++    *:-:* | *:-) cat >"$ac_tmp/stdin" \
++      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
++    esac
++    ;;
++  esac
++
++  ac_dir=`$as_dirname -- "$ac_file" ||
++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	 X"$ac_file" : 'X\(//\)[^/]' \| \
++	 X"$ac_file" : 'X\(//\)$' \| \
++	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
++$as_echo X"$ac_file" |
++    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)[^/].*/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\/\)$/{
++	    s//\1/
++	    q
++	  }
++	  /^X\(\/\).*/{
++	    s//\1/
++	    q
++	  }
++	  s/.*/./; q'`
++  as_dir="$ac_dir"; as_fn_mkdir_p
++  ac_builddir=.
++
++case "$ac_dir" in
++.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
++*)
++  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
++  # A ".." for each directory in $ac_dir_suffix.
++  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
++  case $ac_top_builddir_sub in
++  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
++  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
++  esac ;;
++esac
++ac_abs_top_builddir=$ac_pwd
++ac_abs_builddir=$ac_pwd$ac_dir_suffix
++# for backward compatibility:
++ac_top_builddir=$ac_top_build_prefix
++
++case $srcdir in
++  .)  # We are building in place.
++    ac_srcdir=.
++    ac_top_srcdir=$ac_top_builddir_sub
++    ac_abs_top_srcdir=$ac_pwd ;;
++  [\\/]* | ?:[\\/]* )  # Absolute name.
++    ac_srcdir=$srcdir$ac_dir_suffix;
++    ac_top_srcdir=$srcdir
++    ac_abs_top_srcdir=$srcdir ;;
++  *) # Relative name.
++    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
++    ac_top_srcdir=$ac_top_build_prefix$srcdir
++    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
++esac
++ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
++
++
++  case $ac_mode in
++  :F)
++  #
++  # CONFIG_FILE
++  #
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++# If the template does not know about datarootdir, expand it.
++# FIXME: This hack should be removed a few years after 2.60.
++ac_datarootdir_hack=; ac_datarootdir_seen=
++ac_sed_dataroot='
++/datarootdir/ {
++  p
++  q
++}
++/@datadir@/p
++/@docdir@/p
++/@infodir@/p
++/@localedir@/p
++/@mandir@/p'
++case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
++*datarootdir*) ac_datarootdir_seen=yes;;
++*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
++$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++  ac_datarootdir_hack='
++  s&@datadir@&$datadir&g
++  s&@docdir@&$docdir&g
++  s&@infodir@&$infodir&g
++  s&@localedir@&$localedir&g
++  s&@mandir@&$mandir&g
++  s&\\\${datarootdir}&$datarootdir&g' ;;
++esac
++_ACEOF
++
++# Neutralize VPATH when `$srcdir' = `.'.
++# Shell code in configure.ac might set extrasub.
++# FIXME: do we really want to maintain this feature?
++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
++ac_sed_extra="$ac_vpsub
++$extrasub
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
++:t
++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
++s|@configure_input@|$ac_sed_conf_input|;t t
++s&@top_builddir@&$ac_top_builddir_sub&;t t
++s&@top_build_prefix@&$ac_top_build_prefix&;t t
++s&@srcdir@&$ac_srcdir&;t t
++s&@abs_srcdir@&$ac_abs_srcdir&;t t
++s&@top_srcdir@&$ac_top_srcdir&;t t
++s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
++s&@builddir@&$ac_builddir&;t t
++s&@abs_builddir@&$ac_abs_builddir&;t t
++s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
++$ac_datarootdir_hack
++"
++eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
++  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
++
++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
++  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
++  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
++      "$ac_tmp/out"`; test -z "$ac_out"; } &&
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
++which seems to be undefined.  Please make sure it is defined" >&5
++$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
++which seems to be undefined.  Please make sure it is defined" >&2;}
++
++  rm -f "$ac_tmp/stdin"
++  case $ac_file in
++  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
++  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
++  esac \
++  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
++ ;;
++
++
++
++  esac
++
++done # for ac_tag
++
++
++as_fn_exit 0
++_ACEOF
++ac_clean_files=$ac_clean_files_save
++
++test $ac_write_fail = 0 ||
++  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
++
++
++# configure is writing to config.log, and then calls config.status.
++# config.status does its own redirection, appending to config.log.
++# Unfortunately, on DOS this fails, as config.log is still kept open
++# by configure, so config.status won't be able to write to it; its
++# output is simply discarded.  So we exec the FD to /dev/null,
++# effectively closing config.log, so it can be properly (re)opened and
++# appended to by config.status.  When coming back to configure, we
++# need to make the FD available again.
++if test "$no_create" != yes; then
++  ac_cs_success=:
++  ac_config_status_args=
++  test "$silent" = yes &&
++    ac_config_status_args="$ac_config_status_args --quiet"
++  exec 5>/dev/null
++  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
++  exec 5>>config.log
++  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
++  # would make configure fail if this is the last instruction.
++  $ac_cs_success || as_fn_exit 1
++fi
++if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
++  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
++$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
++fi
++
+--- contrib/sqlite3/tea/configure.ac.orig
++++ contrib/sqlite3/tea/configure.ac
+@@ -0,0 +1,201 @@
++#!/bin/bash -norc
++dnl	This file is an input file used by the GNU "autoconf" program to
++dnl	generate the file "configure", which is run during Tcl installation
++dnl	to configure the system for the local environment.
++#
++# RCS: @(#) $Id: configure.in,v 1.43 2005/07/26 19:17:05 mdejong Exp $
++
++#-----------------------------------------------------------------------
++# Sample configure.in for Tcl Extensions.  The only places you should
++# need to modify this file are marked by the string __CHANGE__
++#-----------------------------------------------------------------------
++
++#-----------------------------------------------------------------------
++# __CHANGE__
++# Set your package name and version numbers here.
++#
++# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
++# set as provided.  These will also be added as -D defs in your Makefile
++# so you can encode the package version directly into the source files.
++#-----------------------------------------------------------------------
++
++AC_INIT([sqlite], [3.26.0])
++
++#--------------------------------------------------------------------
++# Call TEA_INIT as the first TEA_ macro to set up initial vars.
++# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
++# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
++#--------------------------------------------------------------------
++
++TEA_INIT([3.9])
++
++AC_CONFIG_AUX_DIR(tclconfig)
++
++#--------------------------------------------------------------------
++# Load the tclConfig.sh file
++#--------------------------------------------------------------------
++
++TEA_PATH_TCLCONFIG
++TEA_LOAD_TCLCONFIG
++
++#--------------------------------------------------------------------
++# Load the tkConfig.sh file if necessary (Tk extension)
++#--------------------------------------------------------------------
++
++#TEA_PATH_TKCONFIG
++#TEA_LOAD_TKCONFIG
++
++#-----------------------------------------------------------------------
++# Handle the --prefix=... option by defaulting to what Tcl gave.
++# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
++#-----------------------------------------------------------------------
++
++TEA_PREFIX
++
++#-----------------------------------------------------------------------
++# Standard compiler checks.
++# This sets up CC by using the CC env var, or looks for gcc otherwise.
++# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
++# the basic setup necessary to compile executables.
++#-----------------------------------------------------------------------
++
++TEA_SETUP_COMPILER
++
++#-----------------------------------------------------------------------
++# __CHANGE__
++# Specify the C source files to compile in TEA_ADD_SOURCES,
++# public headers that need to be installed in TEA_ADD_HEADERS,
++# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
++# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
++# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
++# and PKG_TCL_SOURCES.
++#-----------------------------------------------------------------------
++
++TEA_ADD_SOURCES([tclsqlite3.c])
++TEA_ADD_HEADERS([])
++TEA_ADD_INCLUDES([-I\"`\${CYGPATH} \${srcdir}/generic`\"])
++TEA_ADD_LIBS([])
++TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1])
++TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
++TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
++TEA_ADD_STUB_SOURCES([])
++TEA_ADD_TCL_SOURCES([])
++
++#--------------------------------------------------------------------
++# The --with-system-sqlite causes the TCL bindings to SQLite to use
++# the system shared library for SQLite rather than statically linking
++# against its own private copy.  This is dangerous and leads to
++# undersirable dependences and is not recommended.
++# Patchs from rmax.
++#--------------------------------------------------------------------
++AC_ARG_WITH([system-sqlite],
++ [AC_HELP_STRING([--with-system-sqlite],
++   [use a system-supplied libsqlite3 instead of the bundled one])],
++ [], [with_system_sqlite=no])
++if test x$with_system_sqlite != xno; then
++ AC_CHECK_HEADER([sqlite3.h],
++   [AC_CHECK_LIB([sqlite3],[sqlite3_initialize],
++     [AC_DEFINE(USE_SYSTEM_SQLITE)
++      LIBS="$LIBS -lsqlite3"])])
++fi
++
++#--------------------------------------------------------------------
++# __CHANGE__
++# Choose which headers you need.  Extension authors should try very
++# hard to only rely on the Tcl public header files.  Internal headers
++# contain private data structures and are subject to change without
++# notice.
++# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
++#--------------------------------------------------------------------
++
++TEA_PUBLIC_TCL_HEADERS
++#TEA_PRIVATE_TCL_HEADERS
++
++#TEA_PUBLIC_TK_HEADERS
++#TEA_PRIVATE_TK_HEADERS
++#TEA_PATH_X
++
++#--------------------------------------------------------------------
++# Check whether --enable-threads or --disable-threads was given.
++# This auto-enables if Tcl was compiled threaded.
++#--------------------------------------------------------------------
++
++TEA_ENABLE_THREADS
++if test "${TCL_THREADS}" = "1" ; then
++    AC_DEFINE(SQLITE_THREADSAFE, 1, [Trigger sqlite threadsafe build])
++    # Not automatically added by Tcl because its assumed Tcl links to them,
++    # but it may not if it isn't really a threaded build.
++    TEA_ADD_LIBS([$THREADS_LIBS])
++else
++    AC_DEFINE(SQLITE_THREADSAFE, 0, [Trigger sqlite non-threadsafe build])
++fi
++
++#--------------------------------------------------------------------
++# The statement below defines a collection of symbols related to
++# building as a shared library instead of a static library.
++#--------------------------------------------------------------------
++
++TEA_ENABLE_SHARED
++
++#--------------------------------------------------------------------
++# This macro figures out what flags to use with the compiler/linker
++# when building shared/static debug/optimized objects.  This information
++# can be taken from the tclConfig.sh file, but this figures it all out.
++#--------------------------------------------------------------------
++
++TEA_CONFIG_CFLAGS
++
++#--------------------------------------------------------------------
++# Set the default compiler switches based on the --enable-symbols option.
++#--------------------------------------------------------------------
++
++TEA_ENABLE_SYMBOLS
++
++#--------------------------------------------------------------------
++# Everyone should be linking against the Tcl stub library.  If you
++# can't for some reason, remove this definition.  If you aren't using
++# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
++# link against the non-stubbed Tcl library.  Add Tk too if necessary.
++#--------------------------------------------------------------------
++
++AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
++#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
++
++
++#--------------------------------------------------------------------
++# Redefine fdatasync as fsync on systems that lack fdatasync
++#--------------------------------------------------------------------
++#
++#AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
++# Check for library functions that SQLite can optionally use.
++AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
++
++AC_FUNC_STRERROR_R
++
++
++#--------------------------------------------------------------------
++# This macro generates a line to use when building a library.  It
++# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
++# and TEA_LOAD_TCLCONFIG macros above.
++#--------------------------------------------------------------------
++
++TEA_MAKE_LIB
++
++#--------------------------------------------------------------------
++# Determine the name of the tclsh and/or wish executables in the
++# Tcl and Tk build directories or the location they were installed
++# into. These paths are used to support running test cases only,
++# the Makefile should not be making use of these paths to generate
++# a pkgIndex.tcl file or anything else at extension build time.
++#--------------------------------------------------------------------
++
++TEA_PROG_TCLSH
++#TEA_PROG_WISH
++
++#--------------------------------------------------------------------
++# Finally, substitute all of the various values into the Makefile.
++# You may alternatively have a special pkgIndex.tcl.in or other files
++# which require substituting th AC variables in.  Include these here.
++#--------------------------------------------------------------------
++
++AC_OUTPUT([Makefile pkgIndex.tcl])
+--- contrib/sqlite3/tea/doc/sqlite3.n.orig
++++ contrib/sqlite3/tea/doc/sqlite3.n
+@@ -0,0 +1,15 @@
++.TH sqlite3 n 4.1 "Tcl-Extensions"
++.HS sqlite3 tcl
++.BS
++.SH NAME
++sqlite3 \- an interface to the SQLite3 database engine
++.SH SYNOPSIS
++\fBsqlite3\fI command_name ?filename?\fR
++.br
++.SH DESCRIPTION
++SQLite3 is a self-contains, zero-configuration, transactional SQL database
++engine.  This extension provides an easy to use interface for accessing
++SQLite database files from Tcl.
++.PP
++For full documentation see \fIhttp://www.sqlite.org/\fR and
++in particular \fIhttp://www.sqlite.org/tclsqlite.html\fR.
+--- contrib/sqlite3/tea/generic/tclsqlite3.c.orig
++++ contrib/sqlite3/tea/generic/tclsqlite3.c
+@@ -0,0 +1,3793 @@
++#ifdef USE_SYSTEM_SQLITE
++# include <sqlite3.h>
++#else
++#include "sqlite3.c"
++#endif
++/*
++** 2001 September 15
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** A TCL Interface to SQLite.  Append this file to sqlite3.c and
++** compile the whole thing to build a TCL-enabled version of SQLite.
++**
++** Compile-time options:
++**
++**  -DTCLSH         Add a "main()" routine that works as a tclsh.
++**
++**  -DTCLSH_INIT_PROC=name
++**
++**                  Invoke name(interp) to initialize the Tcl interpreter.
++**                  If name(interp) returns a non-NULL string, then run
++**                  that string as a Tcl script to launch the application.
++**                  If name(interp) returns NULL, then run the regular
++**                  tclsh-emulator code.
++*/
++#ifdef TCLSH_INIT_PROC
++# define TCLSH 1
++#endif
++
++/*
++** If requested, include the SQLite compiler options file for MSVC.
++*/
++#if defined(INCLUDE_MSVC_H)
++# include "msvc.h"
++#endif
++
++#if defined(INCLUDE_SQLITE_TCL_H)
++# include "sqlite_tcl.h"
++#else
++# include "tcl.h"
++# ifndef SQLITE_TCLAPI
++#  define SQLITE_TCLAPI
++# endif
++#endif
++#include <errno.h>
++
++/*
++** Some additional include files are needed if this file is not
++** appended to the amalgamation.
++*/
++#ifndef SQLITE_AMALGAMATION
++# include "sqlite3.h"
++# include <stdlib.h>
++# include <string.h>
++# include <assert.h>
++  typedef unsigned char u8;
++#endif
++#include <ctype.h>
++
++/* Used to get the current process ID */
++#if !defined(_WIN32)
++# include <signal.h>
++# include <unistd.h>
++# define GETPID getpid
++#elif !defined(_WIN32_WCE)
++# ifndef SQLITE_AMALGAMATION
++#  ifndef WIN32_LEAN_AND_MEAN
++#   define WIN32_LEAN_AND_MEAN
++#  endif
++#  include <windows.h>
++# endif
++# include <io.h>
++# define isatty(h) _isatty(h)
++# define GETPID (int)GetCurrentProcessId
++#endif
++
++/*
++ * Windows needs to know which symbols to export.  Unix does not.
++ * BUILD_sqlite should be undefined for Unix.
++ */
++#ifdef BUILD_sqlite
++#undef TCL_STORAGE_CLASS
++#define TCL_STORAGE_CLASS DLLEXPORT
++#endif /* BUILD_sqlite */
++
++#define NUM_PREPARED_STMTS 10
++#define MAX_PREPARED_STMTS 100
++
++/* Forward declaration */
++typedef struct SqliteDb SqliteDb;
++
++/*
++** New SQL functions can be created as TCL scripts.  Each such function
++** is described by an instance of the following structure.
++*/
++typedef struct SqlFunc SqlFunc;
++struct SqlFunc {
++  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
++  Tcl_Obj *pScript;     /* The Tcl_Obj representation of the script */
++  SqliteDb *pDb;        /* Database connection that owns this function */
++  int useEvalObjv;      /* True if it is safe to use Tcl_EvalObjv */
++  char *zName;          /* Name of this function */
++  SqlFunc *pNext;       /* Next function on the list of them all */
++};
++
++/*
++** New collation sequences function can be created as TCL scripts.  Each such
++** function is described by an instance of the following structure.
++*/
++typedef struct SqlCollate SqlCollate;
++struct SqlCollate {
++  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
++  char *zScript;        /* The script to be run */
++  SqlCollate *pNext;    /* Next function on the list of them all */
++};
++
++/*
++** Prepared statements are cached for faster execution.  Each prepared
++** statement is described by an instance of the following structure.
++*/
++typedef struct SqlPreparedStmt SqlPreparedStmt;
++struct SqlPreparedStmt {
++  SqlPreparedStmt *pNext;  /* Next in linked list */
++  SqlPreparedStmt *pPrev;  /* Previous on the list */
++  sqlite3_stmt *pStmt;     /* The prepared statement */
++  int nSql;                /* chars in zSql[] */
++  const char *zSql;        /* Text of the SQL statement */
++  int nParm;               /* Size of apParm array */
++  Tcl_Obj **apParm;        /* Array of referenced object pointers */
++};
++
++typedef struct IncrblobChannel IncrblobChannel;
++
++/*
++** There is one instance of this structure for each SQLite database
++** that has been opened by the SQLite TCL interface.
++**
++** If this module is built with SQLITE_TEST defined (to create the SQLite
++** testfixture executable), then it may be configured to use either
++** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
++** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
++*/
++struct SqliteDb {
++  sqlite3 *db;               /* The "real" database structure. MUST BE FIRST */
++  Tcl_Interp *interp;        /* The interpreter used for this database */
++  char *zBusy;               /* The busy callback routine */
++  char *zCommit;             /* The commit hook callback routine */
++  char *zTrace;              /* The trace callback routine */
++  char *zTraceV2;            /* The trace_v2 callback routine */
++  char *zProfile;            /* The profile callback routine */
++  char *zProgress;           /* The progress callback routine */
++  char *zAuth;               /* The authorization callback routine */
++  int disableAuth;           /* Disable the authorizer if it exists */
++  char *zNull;               /* Text to substitute for an SQL NULL value */
++  SqlFunc *pFunc;            /* List of SQL functions */
++  Tcl_Obj *pUpdateHook;      /* Update hook script (if any) */
++  Tcl_Obj *pPreUpdateHook;   /* Pre-update hook script (if any) */
++  Tcl_Obj *pRollbackHook;    /* Rollback hook script (if any) */
++  Tcl_Obj *pWalHook;         /* WAL hook script (if any) */
++  Tcl_Obj *pUnlockNotify;    /* Unlock notify script (if any) */
++  SqlCollate *pCollate;      /* List of SQL collation functions */
++  int rc;                    /* Return code of most recent sqlite3_exec() */
++  Tcl_Obj *pCollateNeeded;   /* Collation needed script */
++  SqlPreparedStmt *stmtList; /* List of prepared statements*/
++  SqlPreparedStmt *stmtLast; /* Last statement in the list */
++  int maxStmt;               /* The next maximum number of stmtList */
++  int nStmt;                 /* Number of statements in stmtList */
++  IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
++  int nStep, nSort, nIndex;  /* Statistics for most recent operation */
++  int nVMStep;               /* Another statistic for most recent operation */
++  int nTransaction;          /* Number of nested [transaction] methods */
++  int openFlags;             /* Flags used to open.  (SQLITE_OPEN_URI) */
++#ifdef SQLITE_TEST
++  int bLegacyPrepare;        /* True to use sqlite3_prepare() */
++#endif
++};
++
++struct IncrblobChannel {
++  sqlite3_blob *pBlob;      /* sqlite3 blob handle */
++  SqliteDb *pDb;            /* Associated database connection */
++  int iSeek;                /* Current seek offset */
++  Tcl_Channel channel;      /* Channel identifier */
++  IncrblobChannel *pNext;   /* Linked list of all open incrblob channels */
++  IncrblobChannel *pPrev;   /* Linked list of all open incrblob channels */
++};
++
++/*
++** Compute a string length that is limited to what can be stored in
++** lower 30 bits of a 32-bit signed integer.
++*/
++static int strlen30(const char *z){
++  const char *z2 = z;
++  while( *z2 ){ z2++; }
++  return 0x3fffffff & (int)(z2 - z);
++}
++
++
++#ifndef SQLITE_OMIT_INCRBLOB
++/*
++** Close all incrblob channels opened using database connection pDb.
++** This is called when shutting down the database connection.
++*/
++static void closeIncrblobChannels(SqliteDb *pDb){
++  IncrblobChannel *p;
++  IncrblobChannel *pNext;
++
++  for(p=pDb->pIncrblob; p; p=pNext){
++    pNext = p->pNext;
++
++    /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
++    ** which deletes the IncrblobChannel structure at *p. So do not
++    ** call Tcl_Free() here.
++    */
++    Tcl_UnregisterChannel(pDb->interp, p->channel);
++  }
++}
++
++/*
++** Close an incremental blob channel.
++*/
++static int SQLITE_TCLAPI incrblobClose(
++  ClientData instanceData,
++  Tcl_Interp *interp
++){
++  IncrblobChannel *p = (IncrblobChannel *)instanceData;
++  int rc = sqlite3_blob_close(p->pBlob);
++  sqlite3 *db = p->pDb->db;
++
++  /* Remove the channel from the SqliteDb.pIncrblob list. */
++  if( p->pNext ){
++    p->pNext->pPrev = p->pPrev;
++  }
++  if( p->pPrev ){
++    p->pPrev->pNext = p->pNext;
++  }
++  if( p->pDb->pIncrblob==p ){
++    p->pDb->pIncrblob = p->pNext;
++  }
++
++  /* Free the IncrblobChannel structure */
++  Tcl_Free((char *)p);
++
++  if( rc!=SQLITE_OK ){
++    Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
++    return TCL_ERROR;
++  }
++  return TCL_OK;
++}
++
++/*
++** Read data from an incremental blob channel.
++*/
++static int SQLITE_TCLAPI incrblobInput(
++  ClientData instanceData,
++  char *buf,
++  int bufSize,
++  int *errorCodePtr
++){
++  IncrblobChannel *p = (IncrblobChannel *)instanceData;
++  int nRead = bufSize;         /* Number of bytes to read */
++  int nBlob;                   /* Total size of the blob */
++  int rc;                      /* sqlite error code */
++
++  nBlob = sqlite3_blob_bytes(p->pBlob);
++  if( (p->iSeek+nRead)>nBlob ){
++    nRead = nBlob-p->iSeek;
++  }
++  if( nRead<=0 ){
++    return 0;
++  }
++
++  rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
++  if( rc!=SQLITE_OK ){
++    *errorCodePtr = rc;
++    return -1;
++  }
++
++  p->iSeek += nRead;
++  return nRead;
++}
++
++/*
++** Write data to an incremental blob channel.
++*/
++static int SQLITE_TCLAPI incrblobOutput(
++  ClientData instanceData,
++  CONST char *buf,
++  int toWrite,
++  int *errorCodePtr
++){
++  IncrblobChannel *p = (IncrblobChannel *)instanceData;
++  int nWrite = toWrite;        /* Number of bytes to write */
++  int nBlob;                   /* Total size of the blob */
++  int rc;                      /* sqlite error code */
++
++  nBlob = sqlite3_blob_bytes(p->pBlob);
++  if( (p->iSeek+nWrite)>nBlob ){
++    *errorCodePtr = EINVAL;
++    return -1;
++  }
++  if( nWrite<=0 ){
++    return 0;
++  }
++
++  rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
++  if( rc!=SQLITE_OK ){
++    *errorCodePtr = EIO;
++    return -1;
++  }
++
++  p->iSeek += nWrite;
++  return nWrite;
++}
++
++/*
++** Seek an incremental blob channel.
++*/
++static int SQLITE_TCLAPI incrblobSeek(
++  ClientData instanceData,
++  long offset,
++  int seekMode,
++  int *errorCodePtr
++){
++  IncrblobChannel *p = (IncrblobChannel *)instanceData;
++
++  switch( seekMode ){
++    case SEEK_SET:
++      p->iSeek = offset;
++      break;
++    case SEEK_CUR:
++      p->iSeek += offset;
++      break;
++    case SEEK_END:
++      p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
++      break;
++
++    default: assert(!"Bad seekMode");
++  }
++
++  return p->iSeek;
++}
++
++
++static void SQLITE_TCLAPI incrblobWatch(
++  ClientData instanceData,
++  int mode
++){
++  /* NO-OP */
++}
++static int SQLITE_TCLAPI incrblobHandle(
++  ClientData instanceData,
++  int dir,
++  ClientData *hPtr
++){
++  return TCL_ERROR;
++}
++
++static Tcl_ChannelType IncrblobChannelType = {
++  "incrblob",                        /* typeName                             */
++  TCL_CHANNEL_VERSION_2,             /* version                              */
++  incrblobClose,                     /* closeProc                            */
++  incrblobInput,                     /* inputProc                            */
++  incrblobOutput,                    /* outputProc                           */
++  incrblobSeek,                      /* seekProc                             */
++  0,                                 /* setOptionProc                        */
++  0,                                 /* getOptionProc                        */
++  incrblobWatch,                     /* watchProc (this is a no-op)          */
++  incrblobHandle,                    /* getHandleProc (always returns error) */
++  0,                                 /* close2Proc                           */
++  0,                                 /* blockModeProc                        */
++  0,                                 /* flushProc                            */
++  0,                                 /* handlerProc                          */
++  0,                                 /* wideSeekProc                         */
++};
++
++/*
++** Create a new incrblob channel.
++*/
++static int createIncrblobChannel(
++  Tcl_Interp *interp,
++  SqliteDb *pDb,
++  const char *zDb,
++  const char *zTable,
++  const char *zColumn,
++  sqlite_int64 iRow,
++  int isReadonly
++){
++  IncrblobChannel *p;
++  sqlite3 *db = pDb->db;
++  sqlite3_blob *pBlob;
++  int rc;
++  int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
++
++  /* This variable is used to name the channels: "incrblob_[incr count]" */
++  static int count = 0;
++  char zChannel[64];
++
++  rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
++  if( rc!=SQLITE_OK ){
++    Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
++    return TCL_ERROR;
++  }
++
++  p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
++  p->iSeek = 0;
++  p->pBlob = pBlob;
++
++  sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
++  p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
++  Tcl_RegisterChannel(interp, p->channel);
++
++  /* Link the new channel into the SqliteDb.pIncrblob list. */
++  p->pNext = pDb->pIncrblob;
++  p->pPrev = 0;
++  if( p->pNext ){
++    p->pNext->pPrev = p;
++  }
++  pDb->pIncrblob = p;
++  p->pDb = pDb;
++
++  Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
++  return TCL_OK;
++}
++#else  /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
++  #define closeIncrblobChannels(pDb)
++#endif
++
++/*
++** Look at the script prefix in pCmd.  We will be executing this script
++** after first appending one or more arguments.  This routine analyzes
++** the script to see if it is safe to use Tcl_EvalObjv() on the script
++** rather than the more general Tcl_EvalEx().  Tcl_EvalObjv() is much
++** faster.
++**
++** Scripts that are safe to use with Tcl_EvalObjv() consists of a
++** command name followed by zero or more arguments with no [...] or $
++** or {...} or ; to be seen anywhere.  Most callback scripts consist
++** of just a single procedure name and they meet this requirement.
++*/
++static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
++  /* We could try to do something with Tcl_Parse().  But we will instead
++  ** just do a search for forbidden characters.  If any of the forbidden
++  ** characters appear in pCmd, we will report the string as unsafe.
++  */
++  const char *z;
++  int n;
++  z = Tcl_GetStringFromObj(pCmd, &n);
++  while( n-- > 0 ){
++    int c = *(z++);
++    if( c=='$' || c=='[' || c==';' ) return 0;
++  }
++  return 1;
++}
++
++/*
++** Find an SqlFunc structure with the given name.  Or create a new
++** one if an existing one cannot be found.  Return a pointer to the
++** structure.
++*/
++static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
++  SqlFunc *p, *pNew;
++  int nName = strlen30(zName);
++  pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
++  pNew->zName = (char*)&pNew[1];
++  memcpy(pNew->zName, zName, nName+1);
++  for(p=pDb->pFunc; p; p=p->pNext){
++    if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
++      Tcl_Free((char*)pNew);
++      return p;
++    }
++  }
++  pNew->interp = pDb->interp;
++  pNew->pDb = pDb;
++  pNew->pScript = 0;
++  pNew->pNext = pDb->pFunc;
++  pDb->pFunc = pNew;
++  return pNew;
++}
++
++/*
++** Free a single SqlPreparedStmt object.
++*/
++static void dbFreeStmt(SqlPreparedStmt *pStmt){
++#ifdef SQLITE_TEST
++  if( sqlite3_sql(pStmt->pStmt)==0 ){
++    Tcl_Free((char *)pStmt->zSql);
++  }
++#endif
++  sqlite3_finalize(pStmt->pStmt);
++  Tcl_Free((char *)pStmt);
++}
++
++/*
++** Finalize and free a list of prepared statements
++*/
++static void flushStmtCache(SqliteDb *pDb){
++  SqlPreparedStmt *pPreStmt;
++  SqlPreparedStmt *pNext;
++
++  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
++    pNext = pPreStmt->pNext;
++    dbFreeStmt(pPreStmt);
++  }
++  pDb->nStmt = 0;
++  pDb->stmtLast = 0;
++  pDb->stmtList = 0;
++}
++
++/*
++** TCL calls this procedure when an sqlite3 database command is
++** deleted.
++*/
++static void SQLITE_TCLAPI DbDeleteCmd(void *db){
++  SqliteDb *pDb = (SqliteDb*)db;
++  flushStmtCache(pDb);
++  closeIncrblobChannels(pDb);
++  sqlite3_close(pDb->db);
++  while( pDb->pFunc ){
++    SqlFunc *pFunc = pDb->pFunc;
++    pDb->pFunc = pFunc->pNext;
++    assert( pFunc->pDb==pDb );
++    Tcl_DecrRefCount(pFunc->pScript);
++    Tcl_Free((char*)pFunc);
++  }
++  while( pDb->pCollate ){
++    SqlCollate *pCollate = pDb->pCollate;
++    pDb->pCollate = pCollate->pNext;
++    Tcl_Free((char*)pCollate);
++  }
++  if( pDb->zBusy ){
++    Tcl_Free(pDb->zBusy);
++  }
++  if( pDb->zTrace ){
++    Tcl_Free(pDb->zTrace);
++  }
++  if( pDb->zTraceV2 ){
++    Tcl_Free(pDb->zTraceV2);
++  }
++  if( pDb->zProfile ){
++    Tcl_Free(pDb->zProfile);
++  }
++  if( pDb->zAuth ){
++    Tcl_Free(pDb->zAuth);
++  }
++  if( pDb->zNull ){
++    Tcl_Free(pDb->zNull);
++  }
++  if( pDb->pUpdateHook ){
++    Tcl_DecrRefCount(pDb->pUpdateHook);
++  }
++  if( pDb->pPreUpdateHook ){
++    Tcl_DecrRefCount(pDb->pPreUpdateHook);
++  }
++  if( pDb->pRollbackHook ){
++    Tcl_DecrRefCount(pDb->pRollbackHook);
++  }
++  if( pDb->pWalHook ){
++    Tcl_DecrRefCount(pDb->pWalHook);
++  }
++  if( pDb->pCollateNeeded ){
++    Tcl_DecrRefCount(pDb->pCollateNeeded);
++  }
++  Tcl_Free((char*)pDb);
++}
++
++/*
++** This routine is called when a database file is locked while trying
++** to execute SQL.
++*/
++static int DbBusyHandler(void *cd, int nTries){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  int rc;
++  char zVal[30];
++
++  sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
++  rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
++  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
++    return 0;
++  }
++  return 1;
++}
++
++#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
++/*
++** This routine is invoked as the 'progress callback' for the database.
++*/
++static int DbProgressHandler(void *cd){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  int rc;
++
++  assert( pDb->zProgress );
++  rc = Tcl_Eval(pDb->interp, pDb->zProgress);
++  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
++    return 1;
++  }
++  return 0;
++}
++#endif
++
++#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
++    !defined(SQLITE_OMIT_DEPRECATED)
++/*
++** This routine is called by the SQLite trace handler whenever a new
++** block of SQL is executed.  The TCL script in pDb->zTrace is executed.
++*/
++static void DbTraceHandler(void *cd, const char *zSql){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  Tcl_DString str;
++
++  Tcl_DStringInit(&str);
++  Tcl_DStringAppend(&str, pDb->zTrace, -1);
++  Tcl_DStringAppendElement(&str, zSql);
++  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
++  Tcl_DStringFree(&str);
++  Tcl_ResetResult(pDb->interp);
++}
++#endif
++
++#ifndef SQLITE_OMIT_TRACE
++/*
++** This routine is called by the SQLite trace_v2 handler whenever a new
++** supported event is generated.  Unsupported event types are ignored.
++** The TCL script in pDb->zTraceV2 is executed, with the arguments for
++** the event appended to it (as list elements).
++*/
++static int DbTraceV2Handler(
++  unsigned type, /* One of the SQLITE_TRACE_* event types. */
++  void *cd,      /* The original context data pointer. */
++  void *pd,      /* Primary event data, depends on event type. */
++  void *xd       /* Extra event data, depends on event type. */
++){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  Tcl_Obj *pCmd;
++
++  switch( type ){
++    case SQLITE_TRACE_STMT: {
++      sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
++      char *zSql = (char *)xd;
++
++      pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
++      Tcl_IncrRefCount(pCmd);
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewStringObj(zSql, -1));
++      Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++      Tcl_DecrRefCount(pCmd);
++      Tcl_ResetResult(pDb->interp);
++      break;
++    }
++    case SQLITE_TRACE_PROFILE: {
++      sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
++      sqlite3_int64 ns = *(sqlite3_int64*)xd;
++
++      pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
++      Tcl_IncrRefCount(pCmd);
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewWideIntObj((Tcl_WideInt)ns));
++      Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++      Tcl_DecrRefCount(pCmd);
++      Tcl_ResetResult(pDb->interp);
++      break;
++    }
++    case SQLITE_TRACE_ROW: {
++      sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
++
++      pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
++      Tcl_IncrRefCount(pCmd);
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
++      Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++      Tcl_DecrRefCount(pCmd);
++      Tcl_ResetResult(pDb->interp);
++      break;
++    }
++    case SQLITE_TRACE_CLOSE: {
++      sqlite3 *db = (sqlite3 *)pd;
++
++      pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
++      Tcl_IncrRefCount(pCmd);
++      Tcl_ListObjAppendElement(pDb->interp, pCmd,
++                               Tcl_NewWideIntObj((Tcl_WideInt)db));
++      Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++      Tcl_DecrRefCount(pCmd);
++      Tcl_ResetResult(pDb->interp);
++      break;
++    }
++  }
++  return SQLITE_OK;
++}
++#endif
++
++#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
++    !defined(SQLITE_OMIT_DEPRECATED)
++/*
++** This routine is called by the SQLite profile handler after a statement
++** SQL has executed.  The TCL script in pDb->zProfile is evaluated.
++*/
++static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  Tcl_DString str;
++  char zTm[100];
++
++  sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
++  Tcl_DStringInit(&str);
++  Tcl_DStringAppend(&str, pDb->zProfile, -1);
++  Tcl_DStringAppendElement(&str, zSql);
++  Tcl_DStringAppendElement(&str, zTm);
++  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
++  Tcl_DStringFree(&str);
++  Tcl_ResetResult(pDb->interp);
++}
++#endif
++
++/*
++** This routine is called when a transaction is committed.  The
++** TCL script in pDb->zCommit is executed.  If it returns non-zero or
++** if it throws an exception, the transaction is rolled back instead
++** of being committed.
++*/
++static int DbCommitHandler(void *cd){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  int rc;
++
++  rc = Tcl_Eval(pDb->interp, pDb->zCommit);
++  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
++    return 1;
++  }
++  return 0;
++}
++
++static void DbRollbackHandler(void *clientData){
++  SqliteDb *pDb = (SqliteDb*)clientData;
++  assert(pDb->pRollbackHook);
++  if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
++    Tcl_BackgroundError(pDb->interp);
++  }
++}
++
++/*
++** This procedure handles wal_hook callbacks.
++*/
++static int DbWalHandler(
++  void *clientData,
++  sqlite3 *db,
++  const char *zDb,
++  int nEntry
++){
++  int ret = SQLITE_OK;
++  Tcl_Obj *p;
++  SqliteDb *pDb = (SqliteDb*)clientData;
++  Tcl_Interp *interp = pDb->interp;
++  assert(pDb->pWalHook);
++
++  assert( db==pDb->db );
++  p = Tcl_DuplicateObj(pDb->pWalHook);
++  Tcl_IncrRefCount(p);
++  Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
++  Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
++  if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
++   || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
++  ){
++    Tcl_BackgroundError(interp);
++  }
++  Tcl_DecrRefCount(p);
++
++  return ret;
++}
++
++#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
++static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
++  char zBuf[64];
++  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
++  Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
++  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
++  Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
++}
++#else
++# define setTestUnlockNotifyVars(x,y,z)
++#endif
++
++#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
++static void DbUnlockNotify(void **apArg, int nArg){
++  int i;
++  for(i=0; i<nArg; i++){
++    const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
++    SqliteDb *pDb = (SqliteDb *)apArg[i];
++    setTestUnlockNotifyVars(pDb->interp, i, nArg);
++    assert( pDb->pUnlockNotify);
++    Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
++    Tcl_DecrRefCount(pDb->pUnlockNotify);
++    pDb->pUnlockNotify = 0;
++  }
++}
++#endif
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++/*
++** Pre-update hook callback.
++*/
++static void DbPreUpdateHandler(
++  void *p,
++  sqlite3 *db,
++  int op,
++  const char *zDb,
++  const char *zTbl,
++  sqlite_int64 iKey1,
++  sqlite_int64 iKey2
++){
++  SqliteDb *pDb = (SqliteDb *)p;
++  Tcl_Obj *pCmd;
++  static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
++
++  assert( (SQLITE_DELETE-1)/9 == 0 );
++  assert( (SQLITE_INSERT-1)/9 == 1 );
++  assert( (SQLITE_UPDATE-1)/9 == 2 );
++  assert( pDb->pPreUpdateHook );
++  assert( db==pDb->db );
++  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
++
++  pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
++  Tcl_IncrRefCount(pCmd);
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
++  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++  Tcl_DecrRefCount(pCmd);
++}
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++
++static void DbUpdateHandler(
++  void *p,
++  int op,
++  const char *zDb,
++  const char *zTbl,
++  sqlite_int64 rowid
++){
++  SqliteDb *pDb = (SqliteDb *)p;
++  Tcl_Obj *pCmd;
++  static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
++
++  assert( (SQLITE_DELETE-1)/9 == 0 );
++  assert( (SQLITE_INSERT-1)/9 == 1 );
++  assert( (SQLITE_UPDATE-1)/9 == 2 );
++
++  assert( pDb->pUpdateHook );
++  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
++
++  pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
++  Tcl_IncrRefCount(pCmd);
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
++  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
++  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
++  Tcl_DecrRefCount(pCmd);
++}
++
++static void tclCollateNeeded(
++  void *pCtx,
++  sqlite3 *db,
++  int enc,
++  const char *zName
++){
++  SqliteDb *pDb = (SqliteDb *)pCtx;
++  Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
++  Tcl_IncrRefCount(pScript);
++  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
++  Tcl_EvalObjEx(pDb->interp, pScript, 0);
++  Tcl_DecrRefCount(pScript);
++}
++
++/*
++** This routine is called to evaluate an SQL collation function implemented
++** using TCL script.
++*/
++static int tclSqlCollate(
++  void *pCtx,
++  int nA,
++  const void *zA,
++  int nB,
++  const void *zB
++){
++  SqlCollate *p = (SqlCollate *)pCtx;
++  Tcl_Obj *pCmd;
++
++  pCmd = Tcl_NewStringObj(p->zScript, -1);
++  Tcl_IncrRefCount(pCmd);
++  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
++  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
++  Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
++  Tcl_DecrRefCount(pCmd);
++  return (atoi(Tcl_GetStringResult(p->interp)));
++}
++
++/*
++** This routine is called to evaluate an SQL function implemented
++** using TCL script.
++*/
++static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
++  SqlFunc *p = sqlite3_user_data(context);
++  Tcl_Obj *pCmd;
++  int i;
++  int rc;
++
++  if( argc==0 ){
++    /* If there are no arguments to the function, call Tcl_EvalObjEx on the
++    ** script object directly.  This allows the TCL compiler to generate
++    ** bytecode for the command on the first invocation and thus make
++    ** subsequent invocations much faster. */
++    pCmd = p->pScript;
++    Tcl_IncrRefCount(pCmd);
++    rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
++    Tcl_DecrRefCount(pCmd);
++  }else{
++    /* If there are arguments to the function, make a shallow copy of the
++    ** script object, lappend the arguments, then evaluate the copy.
++    **
++    ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
++    ** The new Tcl_Obj contains pointers to the original list elements.
++    ** That way, when Tcl_EvalObjv() is run and shimmers the first element
++    ** of the list to tclCmdNameType, that alternate representation will
++    ** be preserved and reused on the next invocation.
++    */
++    Tcl_Obj **aArg;
++    int nArg;
++    if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
++      sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
++      return;
++    }
++    pCmd = Tcl_NewListObj(nArg, aArg);
++    Tcl_IncrRefCount(pCmd);
++    for(i=0; i<argc; i++){
++      sqlite3_value *pIn = argv[i];
++      Tcl_Obj *pVal;
++
++      /* Set pVal to contain the i'th column of this row. */
++      switch( sqlite3_value_type(pIn) ){
++        case SQLITE_BLOB: {
++          int bytes = sqlite3_value_bytes(pIn);
++          pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
++          break;
++        }
++        case SQLITE_INTEGER: {
++          sqlite_int64 v = sqlite3_value_int64(pIn);
++          if( v>=-2147483647 && v<=2147483647 ){
++            pVal = Tcl_NewIntObj((int)v);
++          }else{
++            pVal = Tcl_NewWideIntObj(v);
++          }
++          break;
++        }
++        case SQLITE_FLOAT: {
++          double r = sqlite3_value_double(pIn);
++          pVal = Tcl_NewDoubleObj(r);
++          break;
++        }
++        case SQLITE_NULL: {
++          pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
++          break;
++        }
++        default: {
++          int bytes = sqlite3_value_bytes(pIn);
++          pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
++          break;
++        }
++      }
++      rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
++      if( rc ){
++        Tcl_DecrRefCount(pCmd);
++        sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
++        return;
++      }
++    }
++    if( !p->useEvalObjv ){
++      /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
++      ** is a list without a string representation.  To prevent this from
++      ** happening, make sure pCmd has a valid string representation */
++      Tcl_GetString(pCmd);
++    }
++    rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
++    Tcl_DecrRefCount(pCmd);
++  }
++
++  if( rc && rc!=TCL_RETURN ){
++    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
++  }else{
++    Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
++    int n;
++    u8 *data;
++    const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
++    char c = zType[0];
++    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
++      /* Only return a BLOB type if the Tcl variable is a bytearray and
++      ** has no string representation. */
++      data = Tcl_GetByteArrayFromObj(pVar, &n);
++      sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
++    }else if( c=='b' && strcmp(zType,"boolean")==0 ){
++      Tcl_GetIntFromObj(0, pVar, &n);
++      sqlite3_result_int(context, n);
++    }else if( c=='d' && strcmp(zType,"double")==0 ){
++      double r;
++      Tcl_GetDoubleFromObj(0, pVar, &r);
++      sqlite3_result_double(context, r);
++    }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
++          (c=='i' && strcmp(zType,"int")==0) ){
++      Tcl_WideInt v;
++      Tcl_GetWideIntFromObj(0, pVar, &v);
++      sqlite3_result_int64(context, v);
++    }else{
++      data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
++      sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
++    }
++  }
++}
++
++#ifndef SQLITE_OMIT_AUTHORIZATION
++/*
++** This is the authentication function.  It appends the authentication
++** type code and the two arguments to zCmd[] then invokes the result
++** on the interpreter.  The reply is examined to determine if the
++** authentication fails or succeeds.
++*/
++static int auth_callback(
++  void *pArg,
++  int code,
++  const char *zArg1,
++  const char *zArg2,
++  const char *zArg3,
++  const char *zArg4
++#ifdef SQLITE_USER_AUTHENTICATION
++  ,const char *zArg5
++#endif
++){
++  const char *zCode;
++  Tcl_DString str;
++  int rc;
++  const char *zReply;
++  /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
++  ** callback is a copy of the third parameter to the
++  ** sqlite3_set_authorizer() interface.
++  */
++  SqliteDb *pDb = (SqliteDb*)pArg;
++  if( pDb->disableAuth ) return SQLITE_OK;
++
++  /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
++  ** integer action code that specifies the particular action to be
++  ** authorized. */
++  switch( code ){
++    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
++    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
++    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
++    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
++    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
++    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
++    case SQLITE_CREATE_TEMP_VIEW  : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
++    case SQLITE_CREATE_TRIGGER    : zCode="SQLITE_CREATE_TRIGGER"; break;
++    case SQLITE_CREATE_VIEW       : zCode="SQLITE_CREATE_VIEW"; break;
++    case SQLITE_DELETE            : zCode="SQLITE_DELETE"; break;
++    case SQLITE_DROP_INDEX        : zCode="SQLITE_DROP_INDEX"; break;
++    case SQLITE_DROP_TABLE        : zCode="SQLITE_DROP_TABLE"; break;
++    case SQLITE_DROP_TEMP_INDEX   : zCode="SQLITE_DROP_TEMP_INDEX"; break;
++    case SQLITE_DROP_TEMP_TABLE   : zCode="SQLITE_DROP_TEMP_TABLE"; break;
++    case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
++    case SQLITE_DROP_TEMP_VIEW    : zCode="SQLITE_DROP_TEMP_VIEW"; break;
++    case SQLITE_DROP_TRIGGER      : zCode="SQLITE_DROP_TRIGGER"; break;
++    case SQLITE_DROP_VIEW         : zCode="SQLITE_DROP_VIEW"; break;
++    case SQLITE_INSERT            : zCode="SQLITE_INSERT"; break;
++    case SQLITE_PRAGMA            : zCode="SQLITE_PRAGMA"; break;
++    case SQLITE_READ              : zCode="SQLITE_READ"; break;
++    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
++    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
++    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
++    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
++    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
++    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
++    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
++    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
++    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
++    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
++    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
++    case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break;
++    case SQLITE_RECURSIVE         : zCode="SQLITE_RECURSIVE"; break;
++    default                       : zCode="????"; break;
++  }
++  Tcl_DStringInit(&str);
++  Tcl_DStringAppend(&str, pDb->zAuth, -1);
++  Tcl_DStringAppendElement(&str, zCode);
++  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
++  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
++  Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
++  Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
++#ifdef SQLITE_USER_AUTHENTICATION
++  Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
++#endif
++  rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
++  Tcl_DStringFree(&str);
++  zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
++  if( strcmp(zReply,"SQLITE_OK")==0 ){
++    rc = SQLITE_OK;
++  }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
++    rc = SQLITE_DENY;
++  }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
++    rc = SQLITE_IGNORE;
++  }else{
++    rc = 999;
++  }
++  return rc;
++}
++#endif /* SQLITE_OMIT_AUTHORIZATION */
++
++/*
++** This routine reads a line of text from FILE in, stores
++** the text in memory obtained from malloc() and returns a pointer
++** to the text.  NULL is returned at end of file, or if malloc()
++** fails.
++**
++** The interface is like "readline" but no command-line editing
++** is done.
++**
++** copied from shell.c from '.import' command
++*/
++static char *local_getline(char *zPrompt, FILE *in){
++  char *zLine;
++  int nLine;
++  int n;
++
++  nLine = 100;
++  zLine = malloc( nLine );
++  if( zLine==0 ) return 0;
++  n = 0;
++  while( 1 ){
++    if( n+100>nLine ){
++      nLine = nLine*2 + 100;
++      zLine = realloc(zLine, nLine);
++      if( zLine==0 ) return 0;
++    }
++    if( fgets(&zLine[n], nLine - n, in)==0 ){
++      if( n==0 ){
++        free(zLine);
++        return 0;
++      }
++      zLine[n] = 0;
++      break;
++    }
++    while( zLine[n] ){ n++; }
++    if( n>0 && zLine[n-1]=='\n' ){
++      n--;
++      zLine[n] = 0;
++      break;
++    }
++  }
++  zLine = realloc( zLine, n+1 );
++  return zLine;
++}
++
++
++/*
++** This function is part of the implementation of the command:
++**
++**   $db transaction [-deferred|-immediate|-exclusive] SCRIPT
++**
++** It is invoked after evaluating the script SCRIPT to commit or rollback
++** the transaction or savepoint opened by the [transaction] command.
++*/
++static int SQLITE_TCLAPI DbTransPostCmd(
++  ClientData data[],                   /* data[0] is the Sqlite3Db* for $db */
++  Tcl_Interp *interp,                  /* Tcl interpreter */
++  int result                           /* Result of evaluating SCRIPT */
++){
++  static const char *const azEnd[] = {
++    "RELEASE _tcl_transaction",        /* rc==TCL_ERROR, nTransaction!=0 */
++    "COMMIT",                          /* rc!=TCL_ERROR, nTransaction==0 */
++    "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
++    "ROLLBACK"                         /* rc==TCL_ERROR, nTransaction==0 */
++  };
++  SqliteDb *pDb = (SqliteDb*)data[0];
++  int rc = result;
++  const char *zEnd;
++
++  pDb->nTransaction--;
++  zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
++
++  pDb->disableAuth++;
++  if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
++      /* This is a tricky scenario to handle. The most likely cause of an
++      ** error is that the exec() above was an attempt to commit the
++      ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
++      ** that an IO-error has occurred. In either case, throw a Tcl exception
++      ** and try to rollback the transaction.
++      **
++      ** But it could also be that the user executed one or more BEGIN,
++      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
++      ** this method's logic. Not clear how this would be best handled.
++      */
++    if( rc!=TCL_ERROR ){
++      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
++      rc = TCL_ERROR;
++    }
++    sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
++  }
++  pDb->disableAuth--;
++
++  return rc;
++}
++
++/*
++** Unless SQLITE_TEST is defined, this function is a simple wrapper around
++** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
++** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
++** on whether or not the [db_use_legacy_prepare] command has been used to
++** configure the connection.
++*/
++static int dbPrepare(
++  SqliteDb *pDb,                  /* Database object */
++  const char *zSql,               /* SQL to compile */
++  sqlite3_stmt **ppStmt,          /* OUT: Prepared statement */
++  const char **pzOut              /* OUT: Pointer to next SQL statement */
++){
++  unsigned int prepFlags = 0;
++#ifdef SQLITE_TEST
++  if( pDb->bLegacyPrepare ){
++    return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
++  }
++#endif
++  /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT
++  ** flags, which uses less lookaside memory.  But if the cache is small,
++  ** omit that flag to make full use of lookaside */
++  if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT;
++
++  return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut);
++}
++
++/*
++** Search the cache for a prepared-statement object that implements the
++** first SQL statement in the buffer pointed to by parameter zIn. If
++** no such prepared-statement can be found, allocate and prepare a new
++** one. In either case, bind the current values of the relevant Tcl
++** variables to any $var, :var or @var variables in the statement. Before
++** returning, set *ppPreStmt to point to the prepared-statement object.
++**
++** Output parameter *pzOut is set to point to the next SQL statement in
++** buffer zIn, or to the '\0' byte at the end of zIn if there is no
++** next statement.
++**
++** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
++** and an error message loaded into interpreter pDb->interp.
++*/
++static int dbPrepareAndBind(
++  SqliteDb *pDb,                  /* Database object */
++  char const *zIn,                /* SQL to compile */
++  char const **pzOut,             /* OUT: Pointer to next SQL statement */
++  SqlPreparedStmt **ppPreStmt     /* OUT: Object used to cache statement */
++){
++  const char *zSql = zIn;         /* Pointer to first SQL statement in zIn */
++  sqlite3_stmt *pStmt = 0;        /* Prepared statement object */
++  SqlPreparedStmt *pPreStmt;      /* Pointer to cached statement */
++  int nSql;                       /* Length of zSql in bytes */
++  int nVar = 0;                   /* Number of variables in statement */
++  int iParm = 0;                  /* Next free entry in apParm */
++  char c;
++  int i;
++  Tcl_Interp *interp = pDb->interp;
++
++  *ppPreStmt = 0;
++
++  /* Trim spaces from the start of zSql and calculate the remaining length. */
++  while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
++  nSql = strlen30(zSql);
++
++  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
++    int n = pPreStmt->nSql;
++    if( nSql>=n
++        && memcmp(pPreStmt->zSql, zSql, n)==0
++        && (zSql[n]==0 || zSql[n-1]==';')
++    ){
++      pStmt = pPreStmt->pStmt;
++      *pzOut = &zSql[pPreStmt->nSql];
++
++      /* When a prepared statement is found, unlink it from the
++      ** cache list.  It will later be added back to the beginning
++      ** of the cache list in order to implement LRU replacement.
++      */
++      if( pPreStmt->pPrev ){
++        pPreStmt->pPrev->pNext = pPreStmt->pNext;
++      }else{
++        pDb->stmtList = pPreStmt->pNext;
++      }
++      if( pPreStmt->pNext ){
++        pPreStmt->pNext->pPrev = pPreStmt->pPrev;
++      }else{
++        pDb->stmtLast = pPreStmt->pPrev;
++      }
++      pDb->nStmt--;
++      nVar = sqlite3_bind_parameter_count(pStmt);
++      break;
++    }
++  }
++
++  /* If no prepared statement was found. Compile the SQL text. Also allocate
++  ** a new SqlPreparedStmt structure.  */
++  if( pPreStmt==0 ){
++    int nByte;
++
++    if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
++      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
++      return TCL_ERROR;
++    }
++    if( pStmt==0 ){
++      if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
++        /* A compile-time error in the statement. */
++        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
++        return TCL_ERROR;
++      }else{
++        /* The statement was a no-op.  Continue to the next statement
++        ** in the SQL string.
++        */
++        return TCL_OK;
++      }
++    }
++
++    assert( pPreStmt==0 );
++    nVar = sqlite3_bind_parameter_count(pStmt);
++    nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
++    pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
++    memset(pPreStmt, 0, nByte);
++
++    pPreStmt->pStmt = pStmt;
++    pPreStmt->nSql = (int)(*pzOut - zSql);
++    pPreStmt->zSql = sqlite3_sql(pStmt);
++    pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
++#ifdef SQLITE_TEST
++    if( pPreStmt->zSql==0 ){
++      char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
++      memcpy(zCopy, zSql, pPreStmt->nSql);
++      zCopy[pPreStmt->nSql] = '\0';
++      pPreStmt->zSql = zCopy;
++    }
++#endif
++  }
++  assert( pPreStmt );
++  assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
++  assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
++
++  /* Bind values to parameters that begin with $ or : */
++  for(i=1; i<=nVar; i++){
++    const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
++    if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
++      Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
++      if( pVar ){
++        int n;
++        u8 *data;
++        const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
++        c = zType[0];
++        if( zVar[0]=='@' ||
++           (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
++          /* Load a BLOB type if the Tcl variable is a bytearray and
++          ** it has no string representation or the host
++          ** parameter name begins with "@". */
++          data = Tcl_GetByteArrayFromObj(pVar, &n);
++          sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
++          Tcl_IncrRefCount(pVar);
++          pPreStmt->apParm[iParm++] = pVar;
++        }else if( c=='b' && strcmp(zType,"boolean")==0 ){
++          Tcl_GetIntFromObj(interp, pVar, &n);
++          sqlite3_bind_int(pStmt, i, n);
++        }else if( c=='d' && strcmp(zType,"double")==0 ){
++          double r;
++          Tcl_GetDoubleFromObj(interp, pVar, &r);
++          sqlite3_bind_double(pStmt, i, r);
++        }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
++              (c=='i' && strcmp(zType,"int")==0) ){
++          Tcl_WideInt v;
++          Tcl_GetWideIntFromObj(interp, pVar, &v);
++          sqlite3_bind_int64(pStmt, i, v);
++        }else{
++          data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
++          sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
++          Tcl_IncrRefCount(pVar);
++          pPreStmt->apParm[iParm++] = pVar;
++        }
++      }else{
++        sqlite3_bind_null(pStmt, i);
++      }
++    }
++  }
++  pPreStmt->nParm = iParm;
++  *ppPreStmt = pPreStmt;
++
++  return TCL_OK;
++}
++
++/*
++** Release a statement reference obtained by calling dbPrepareAndBind().
++** There should be exactly one call to this function for each call to
++** dbPrepareAndBind().
++**
++** If the discard parameter is non-zero, then the statement is deleted
++** immediately. Otherwise it is added to the LRU list and may be returned
++** by a subsequent call to dbPrepareAndBind().
++*/
++static void dbReleaseStmt(
++  SqliteDb *pDb,                  /* Database handle */
++  SqlPreparedStmt *pPreStmt,      /* Prepared statement handle to release */
++  int discard                     /* True to delete (not cache) the pPreStmt */
++){
++  int i;
++
++  /* Free the bound string and blob parameters */
++  for(i=0; i<pPreStmt->nParm; i++){
++    Tcl_DecrRefCount(pPreStmt->apParm[i]);
++  }
++  pPreStmt->nParm = 0;
++
++  if( pDb->maxStmt<=0 || discard ){
++    /* If the cache is turned off, deallocated the statement */
++    dbFreeStmt(pPreStmt);
++  }else{
++    /* Add the prepared statement to the beginning of the cache list. */
++    pPreStmt->pNext = pDb->stmtList;
++    pPreStmt->pPrev = 0;
++    if( pDb->stmtList ){
++     pDb->stmtList->pPrev = pPreStmt;
++    }
++    pDb->stmtList = pPreStmt;
++    if( pDb->stmtLast==0 ){
++      assert( pDb->nStmt==0 );
++      pDb->stmtLast = pPreStmt;
++    }else{
++      assert( pDb->nStmt>0 );
++    }
++    pDb->nStmt++;
++
++    /* If we have too many statement in cache, remove the surplus from
++    ** the end of the cache list.  */
++    while( pDb->nStmt>pDb->maxStmt ){
++      SqlPreparedStmt *pLast = pDb->stmtLast;
++      pDb->stmtLast = pLast->pPrev;
++      pDb->stmtLast->pNext = 0;
++      pDb->nStmt--;
++      dbFreeStmt(pLast);
++    }
++  }
++}
++
++/*
++** Structure used with dbEvalXXX() functions:
++**
++**   dbEvalInit()
++**   dbEvalStep()
++**   dbEvalFinalize()
++**   dbEvalRowInfo()
++**   dbEvalColumnValue()
++*/
++typedef struct DbEvalContext DbEvalContext;
++struct DbEvalContext {
++  SqliteDb *pDb;                  /* Database handle */
++  Tcl_Obj *pSql;                  /* Object holding string zSql */
++  const char *zSql;               /* Remaining SQL to execute */
++  SqlPreparedStmt *pPreStmt;      /* Current statement */
++  int nCol;                       /* Number of columns returned by pStmt */
++  int evalFlags;                  /* Flags used */
++  Tcl_Obj *pArray;                /* Name of array variable */
++  Tcl_Obj **apColName;            /* Array of column names */
++};
++
++#define SQLITE_EVAL_WITHOUTNULLS  0x00001  /* Unset array(*) for NULL */
++
++/*
++** Release any cache of column names currently held as part of
++** the DbEvalContext structure passed as the first argument.
++*/
++static void dbReleaseColumnNames(DbEvalContext *p){
++  if( p->apColName ){
++    int i;
++    for(i=0; i<p->nCol; i++){
++      Tcl_DecrRefCount(p->apColName[i]);
++    }
++    Tcl_Free((char *)p->apColName);
++    p->apColName = 0;
++  }
++  p->nCol = 0;
++}
++
++/*
++** Initialize a DbEvalContext structure.
++**
++** If pArray is not NULL, then it contains the name of a Tcl array
++** variable. The "*" member of this array is set to a list containing
++** the names of the columns returned by the statement as part of each
++** call to dbEvalStep(), in order from left to right. e.g. if the names
++** of the returned columns are a, b and c, it does the equivalent of the
++** tcl command:
++**
++**     set ${pArray}(*) {a b c}
++*/
++static void dbEvalInit(
++  DbEvalContext *p,               /* Pointer to structure to initialize */
++  SqliteDb *pDb,                  /* Database handle */
++  Tcl_Obj *pSql,                  /* Object containing SQL script */
++  Tcl_Obj *pArray,                /* Name of Tcl array to set (*) element of */
++  int evalFlags                   /* Flags controlling evaluation */
++){
++  memset(p, 0, sizeof(DbEvalContext));
++  p->pDb = pDb;
++  p->zSql = Tcl_GetString(pSql);
++  p->pSql = pSql;
++  Tcl_IncrRefCount(pSql);
++  if( pArray ){
++    p->pArray = pArray;
++    Tcl_IncrRefCount(pArray);
++  }
++  p->evalFlags = evalFlags;
++}
++
++/*
++** Obtain information about the row that the DbEvalContext passed as the
++** first argument currently points to.
++*/
++static void dbEvalRowInfo(
++  DbEvalContext *p,               /* Evaluation context */
++  int *pnCol,                     /* OUT: Number of column names */
++  Tcl_Obj ***papColName           /* OUT: Array of column names */
++){
++  /* Compute column names */
++  if( 0==p->apColName ){
++    sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
++    int i;                        /* Iterator variable */
++    int nCol;                     /* Number of columns returned by pStmt */
++    Tcl_Obj **apColName = 0;      /* Array of column names */
++
++    p->nCol = nCol = sqlite3_column_count(pStmt);
++    if( nCol>0 && (papColName || p->pArray) ){
++      apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
++      for(i=0; i<nCol; i++){
++        apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
++        Tcl_IncrRefCount(apColName[i]);
++      }
++      p->apColName = apColName;
++    }
++
++    /* If results are being stored in an array variable, then create
++    ** the array(*) entry for that array
++    */
++    if( p->pArray ){
++      Tcl_Interp *interp = p->pDb->interp;
++      Tcl_Obj *pColList = Tcl_NewObj();
++      Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
++
++      for(i=0; i<nCol; i++){
++        Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
++      }
++      Tcl_IncrRefCount(pStar);
++      Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
++      Tcl_DecrRefCount(pStar);
++    }
++  }
++
++  if( papColName ){
++    *papColName = p->apColName;
++  }
++  if( pnCol ){
++    *pnCol = p->nCol;
++  }
++}
++
++/*
++** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
++** returned, then an error message is stored in the interpreter before
++** returning.
++**
++** A return value of TCL_OK means there is a row of data available. The
++** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
++** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
++** is returned, then the SQL script has finished executing and there are
++** no further rows available. This is similar to SQLITE_DONE.
++*/
++static int dbEvalStep(DbEvalContext *p){
++  const char *zPrevSql = 0;       /* Previous value of p->zSql */
++
++  while( p->zSql[0] || p->pPreStmt ){
++    int rc;
++    if( p->pPreStmt==0 ){
++      zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
++      rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
++      if( rc!=TCL_OK ) return rc;
++    }else{
++      int rcs;
++      SqliteDb *pDb = p->pDb;
++      SqlPreparedStmt *pPreStmt = p->pPreStmt;
++      sqlite3_stmt *pStmt = pPreStmt->pStmt;
++
++      rcs = sqlite3_step(pStmt);
++      if( rcs==SQLITE_ROW ){
++        return TCL_OK;
++      }
++      if( p->pArray ){
++        dbEvalRowInfo(p, 0, 0);
++      }
++      rcs = sqlite3_reset(pStmt);
++
++      pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
++      pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
++      pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
++      pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
++      dbReleaseColumnNames(p);
++      p->pPreStmt = 0;
++
++      if( rcs!=SQLITE_OK ){
++        /* If a run-time error occurs, report the error and stop reading
++        ** the SQL.  */
++        dbReleaseStmt(pDb, pPreStmt, 1);
++#if SQLITE_TEST
++        if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
++          /* If the runtime error was an SQLITE_SCHEMA, and the database
++          ** handle is configured to use the legacy sqlite3_prepare()
++          ** interface, retry prepare()/step() on the same SQL statement.
++          ** This only happens once. If there is a second SQLITE_SCHEMA
++          ** error, the error will be returned to the caller. */
++          p->zSql = zPrevSql;
++          continue;
++        }
++#endif
++        Tcl_SetObjResult(pDb->interp,
++                         Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
++        return TCL_ERROR;
++      }else{
++        dbReleaseStmt(pDb, pPreStmt, 0);
++      }
++    }
++  }
++
++  /* Finished */
++  return TCL_BREAK;
++}
++
++/*
++** Free all resources currently held by the DbEvalContext structure passed
++** as the first argument. There should be exactly one call to this function
++** for each call to dbEvalInit().
++*/
++static void dbEvalFinalize(DbEvalContext *p){
++  if( p->pPreStmt ){
++    sqlite3_reset(p->pPreStmt->pStmt);
++    dbReleaseStmt(p->pDb, p->pPreStmt, 0);
++    p->pPreStmt = 0;
++  }
++  if( p->pArray ){
++    Tcl_DecrRefCount(p->pArray);
++    p->pArray = 0;
++  }
++  Tcl_DecrRefCount(p->pSql);
++  dbReleaseColumnNames(p);
++}
++
++/*
++** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
++** the value for the iCol'th column of the row currently pointed to by
++** the DbEvalContext structure passed as the first argument.
++*/
++static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
++  sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
++  switch( sqlite3_column_type(pStmt, iCol) ){
++    case SQLITE_BLOB: {
++      int bytes = sqlite3_column_bytes(pStmt, iCol);
++      const char *zBlob = sqlite3_column_blob(pStmt, iCol);
++      if( !zBlob ) bytes = 0;
++      return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
++    }
++    case SQLITE_INTEGER: {
++      sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
++      if( v>=-2147483647 && v<=2147483647 ){
++        return Tcl_NewIntObj((int)v);
++      }else{
++        return Tcl_NewWideIntObj(v);
++      }
++    }
++    case SQLITE_FLOAT: {
++      return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
++    }
++    case SQLITE_NULL: {
++      return Tcl_NewStringObj(p->pDb->zNull, -1);
++    }
++  }
++
++  return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
++}
++
++/*
++** If using Tcl version 8.6 or greater, use the NR functions to avoid
++** recursive evalution of scripts by the [db eval] and [db trans]
++** commands. Even if the headers used while compiling the extension
++** are 8.6 or newer, the code still tests the Tcl version at runtime.
++** This allows stubs-enabled builds to be used with older Tcl libraries.
++*/
++#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
++# define SQLITE_TCL_NRE 1
++static int DbUseNre(void){
++  int major, minor;
++  Tcl_GetVersion(&major, &minor, 0, 0);
++  return( (major==8 && minor>=6) || major>8 );
++}
++#else
++/*
++** Compiling using headers earlier than 8.6. In this case NR cannot be
++** used, so DbUseNre() to always return zero. Add #defines for the other
++** Tcl_NRxxx() functions to prevent them from causing compilation errors,
++** even though the only invocations of them are within conditional blocks
++** of the form:
++**
++**   if( DbUseNre() ) { ... }
++*/
++# define SQLITE_TCL_NRE 0
++# define DbUseNre() 0
++# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
++# define Tcl_NREvalObj(a,b,c) 0
++# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
++#endif
++
++/*
++** This function is part of the implementation of the command:
++**
++**   $db eval SQL ?ARRAYNAME? SCRIPT
++*/
++static int SQLITE_TCLAPI DbEvalNextCmd(
++  ClientData data[],                   /* data[0] is the (DbEvalContext*) */
++  Tcl_Interp *interp,                  /* Tcl interpreter */
++  int result                           /* Result so far */
++){
++  int rc = result;                     /* Return code */
++
++  /* The first element of the data[] array is a pointer to a DbEvalContext
++  ** structure allocated using Tcl_Alloc(). The second element of data[]
++  ** is a pointer to a Tcl_Obj containing the script to run for each row
++  ** returned by the queries encapsulated in data[0]. */
++  DbEvalContext *p = (DbEvalContext *)data[0];
++  Tcl_Obj *pScript = (Tcl_Obj *)data[1];
++  Tcl_Obj *pArray = p->pArray;
++
++  while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
++    int i;
++    int nCol;
++    Tcl_Obj **apColName;
++    dbEvalRowInfo(p, &nCol, &apColName);
++    for(i=0; i<nCol; i++){
++      if( pArray==0 ){
++        Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
++      }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
++             && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL 
++      ){
++        Tcl_UnsetVar2(interp, Tcl_GetString(pArray), 
++                      Tcl_GetString(apColName[i]), 0);
++      }else{
++        Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
++      }
++    }
++
++    /* The required interpreter variables are now populated with the data
++    ** from the current row. If using NRE, schedule callbacks to evaluate
++    ** script pScript, then to invoke this function again to fetch the next
++    ** row (or clean up if there is no next row or the script throws an
++    ** exception). After scheduling the callbacks, return control to the
++    ** caller.
++    **
++    ** If not using NRE, evaluate pScript directly and continue with the
++    ** next iteration of this while(...) loop.  */
++    if( DbUseNre() ){
++      Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
++      return Tcl_NREvalObj(interp, pScript, 0);
++    }else{
++      rc = Tcl_EvalObjEx(interp, pScript, 0);
++    }
++  }
++
++  Tcl_DecrRefCount(pScript);
++  dbEvalFinalize(p);
++  Tcl_Free((char *)p);
++
++  if( rc==TCL_OK || rc==TCL_BREAK ){
++    Tcl_ResetResult(interp);
++    rc = TCL_OK;
++  }
++  return rc;
++}
++
++/*
++** This function is used by the implementations of the following database
++** handle sub-commands:
++**
++**   $db update_hook ?SCRIPT?
++**   $db wal_hook ?SCRIPT?
++**   $db commit_hook ?SCRIPT?
++**   $db preupdate hook ?SCRIPT?
++*/
++static void DbHookCmd(
++  Tcl_Interp *interp,             /* Tcl interpreter */
++  SqliteDb *pDb,                  /* Database handle */
++  Tcl_Obj *pArg,                  /* SCRIPT argument (or NULL) */
++  Tcl_Obj **ppHook                /* Pointer to member of SqliteDb */
++){
++  sqlite3 *db = pDb->db;
++
++  if( *ppHook ){
++    Tcl_SetObjResult(interp, *ppHook);
++    if( pArg ){
++      Tcl_DecrRefCount(*ppHook);
++      *ppHook = 0;
++    }
++  }
++  if( pArg ){
++    assert( !(*ppHook) );
++    if( Tcl_GetCharLength(pArg)>0 ){
++      *ppHook = pArg;
++      Tcl_IncrRefCount(*ppHook);
++    }
++  }
++
++#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
++  sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
++#endif
++  sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
++  sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
++  sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
++}
++
++/*
++** The "sqlite" command below creates a new Tcl command for each
++** connection it opens to an SQLite database.  This routine is invoked
++** whenever one of those connection-specific commands is executed
++** in Tcl.  For example, if you run Tcl code like this:
++**
++**       sqlite3 db1  "my_database"
++**       db1 close
++**
++** The first command opens a connection to the "my_database" database
++** and calls that connection "db1".  The second command causes this
++** subroutine to be invoked.
++*/
++static int SQLITE_TCLAPI DbObjCmd(
++  void *cd,
++  Tcl_Interp *interp,
++  int objc,
++  Tcl_Obj *const*objv
++){
++  SqliteDb *pDb = (SqliteDb*)cd;
++  int choice;
++  int rc = TCL_OK;
++  static const char *DB_strs[] = {
++    "authorizer",             "backup",                "busy",
++    "cache",                  "changes",               "close",
++    "collate",                "collation_needed",      "commit_hook",
++    "complete",               "copy",                  "deserialize",
++    "enable_load_extension",  "errorcode",             "eval",
++    "exists",                 "function",              "incrblob",
++    "interrupt",              "last_insert_rowid",     "nullvalue",
++    "onecolumn",              "preupdate",             "profile",
++    "progress",               "rekey",                 "restore",
++    "rollback_hook",          "serialize",             "status",
++    "timeout",                "total_changes",         "trace",
++    "trace_v2",               "transaction",           "unlock_notify",
++    "update_hook",            "version",               "wal_hook",
++    0                        
++  };
++  enum DB_enum {
++    DB_AUTHORIZER,            DB_BACKUP,               DB_BUSY,
++    DB_CACHE,                 DB_CHANGES,              DB_CLOSE,
++    DB_COLLATE,               DB_COLLATION_NEEDED,     DB_COMMIT_HOOK,
++    DB_COMPLETE,              DB_COPY,                 DB_DESERIALIZE,
++    DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE,            DB_EVAL,
++    DB_EXISTS,                DB_FUNCTION,             DB_INCRBLOB,
++    DB_INTERRUPT,             DB_LAST_INSERT_ROWID,    DB_NULLVALUE,
++    DB_ONECOLUMN,             DB_PREUPDATE,            DB_PROFILE,
++    DB_PROGRESS,              DB_REKEY,                DB_RESTORE,
++    DB_ROLLBACK_HOOK,         DB_SERIALIZE,            DB_STATUS,
++    DB_TIMEOUT,               DB_TOTAL_CHANGES,        DB_TRACE,
++    DB_TRACE_V2,              DB_TRANSACTION,          DB_UNLOCK_NOTIFY,
++    DB_UPDATE_HOOK,           DB_VERSION,              DB_WAL_HOOK
++  };
++  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
++
++  if( objc<2 ){
++    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
++    return TCL_ERROR;
++  }
++  if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
++    return TCL_ERROR;
++  }
++
++  switch( (enum DB_enum)choice ){
++
++  /*    $db authorizer ?CALLBACK?
++  **
++  ** Invoke the given callback to authorize each SQL operation as it is
++  ** compiled.  5 arguments are appended to the callback before it is
++  ** invoked:
++  **
++  **   (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
++  **   (2) First descriptive name (depends on authorization type)
++  **   (3) Second descriptive name
++  **   (4) Name of the database (ex: "main", "temp")
++  **   (5) Name of trigger that is doing the access
++  **
++  ** The callback should return on of the following strings: SQLITE_OK,
++  ** SQLITE_IGNORE, or SQLITE_DENY.  Any other return value is an error.
++  **
++  ** If this method is invoked with no arguments, the current authorization
++  ** callback string is returned.
++  */
++  case DB_AUTHORIZER: {
++#ifdef SQLITE_OMIT_AUTHORIZATION
++    Tcl_AppendResult(interp, "authorization not available in this build",
++                     (char*)0);
++    return TCL_ERROR;
++#else
++    if( objc>3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zAuth ){
++        Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
++      }
++    }else{
++      char *zAuth;
++      int len;
++      if( pDb->zAuth ){
++        Tcl_Free(pDb->zAuth);
++      }
++      zAuth = Tcl_GetStringFromObj(objv[2], &len);
++      if( zAuth && len>0 ){
++        pDb->zAuth = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zAuth, zAuth, len+1);
++      }else{
++        pDb->zAuth = 0;
++      }
++      if( pDb->zAuth ){
++        typedef int (*sqlite3_auth_cb)(
++           void*,int,const char*,const char*,
++           const char*,const char*);
++        pDb->interp = interp;
++        sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
++      }else{
++        sqlite3_set_authorizer(pDb->db, 0, 0);
++      }
++    }
++#endif
++    break;
++  }
++
++  /*    $db backup ?DATABASE? FILENAME
++  **
++  ** Open or create a database file named FILENAME.  Transfer the
++  ** content of local database DATABASE (default: "main") into the
++  ** FILENAME database.
++  */
++  case DB_BACKUP: {
++    const char *zDestFile;
++    const char *zSrcDb;
++    sqlite3 *pDest;
++    sqlite3_backup *pBackup;
++
++    if( objc==3 ){
++      zSrcDb = "main";
++      zDestFile = Tcl_GetString(objv[2]);
++    }else if( objc==4 ){
++      zSrcDb = Tcl_GetString(objv[2]);
++      zDestFile = Tcl_GetString(objv[3]);
++    }else{
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
++      return TCL_ERROR;
++    }
++    rc = sqlite3_open_v2(zDestFile, &pDest,
++               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
++    if( rc!=SQLITE_OK ){
++      Tcl_AppendResult(interp, "cannot open target database: ",
++           sqlite3_errmsg(pDest), (char*)0);
++      sqlite3_close(pDest);
++      return TCL_ERROR;
++    }
++    pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
++    if( pBackup==0 ){
++      Tcl_AppendResult(interp, "backup failed: ",
++           sqlite3_errmsg(pDest), (char*)0);
++      sqlite3_close(pDest);
++      return TCL_ERROR;
++    }
++    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
++    sqlite3_backup_finish(pBackup);
++    if( rc==SQLITE_DONE ){
++      rc = TCL_OK;
++    }else{
++      Tcl_AppendResult(interp, "backup failed: ",
++           sqlite3_errmsg(pDest), (char*)0);
++      rc = TCL_ERROR;
++    }
++    sqlite3_close(pDest);
++    break;
++  }
++
++  /*    $db busy ?CALLBACK?
++  **
++  ** Invoke the given callback if an SQL statement attempts to open
++  ** a locked database file.
++  */
++  case DB_BUSY: {
++    if( objc>3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zBusy ){
++        Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
++      }
++    }else{
++      char *zBusy;
++      int len;
++      if( pDb->zBusy ){
++        Tcl_Free(pDb->zBusy);
++      }
++      zBusy = Tcl_GetStringFromObj(objv[2], &len);
++      if( zBusy && len>0 ){
++        pDb->zBusy = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zBusy, zBusy, len+1);
++      }else{
++        pDb->zBusy = 0;
++      }
++      if( pDb->zBusy ){
++        pDb->interp = interp;
++        sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
++      }else{
++        sqlite3_busy_handler(pDb->db, 0, 0);
++      }
++    }
++    break;
++  }
++
++  /*     $db cache flush
++  **     $db cache size n
++  **
++  ** Flush the prepared statement cache, or set the maximum number of
++  ** cached statements.
++  */
++  case DB_CACHE: {
++    char *subCmd;
++    int n;
++
++    if( objc<=2 ){
++      Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
++      return TCL_ERROR;
++    }
++    subCmd = Tcl_GetStringFromObj( objv[2], 0 );
++    if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
++      if( objc!=3 ){
++        Tcl_WrongNumArgs(interp, 2, objv, "flush");
++        return TCL_ERROR;
++      }else{
++        flushStmtCache( pDb );
++      }
++    }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
++      if( objc!=4 ){
++        Tcl_WrongNumArgs(interp, 2, objv, "size n");
++        return TCL_ERROR;
++      }else{
++        if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
++          Tcl_AppendResult( interp, "cannot convert \"",
++               Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
++          return TCL_ERROR;
++        }else{
++          if( n<0 ){
++            flushStmtCache( pDb );
++            n = 0;
++          }else if( n>MAX_PREPARED_STMTS ){
++            n = MAX_PREPARED_STMTS;
++          }
++          pDb->maxStmt = n;
++        }
++      }
++    }else{
++      Tcl_AppendResult( interp, "bad option \"",
++          Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
++          (char*)0);
++      return TCL_ERROR;
++    }
++    break;
++  }
++
++  /*     $db changes
++  **
++  ** Return the number of rows that were modified, inserted, or deleted by
++  ** the most recent INSERT, UPDATE or DELETE statement, not including
++  ** any changes made by trigger programs.
++  */
++  case DB_CHANGES: {
++    Tcl_Obj *pResult;
++    if( objc!=2 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "");
++      return TCL_ERROR;
++    }
++    pResult = Tcl_GetObjResult(interp);
++    Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
++    break;
++  }
++
++  /*    $db close
++  **
++  ** Shutdown the database
++  */
++  case DB_CLOSE: {
++    Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
++    break;
++  }
++
++  /*
++  **     $db collate NAME SCRIPT
++  **
++  ** Create a new SQL collation function called NAME.  Whenever
++  ** that function is called, invoke SCRIPT to evaluate the function.
++  */
++  case DB_COLLATE: {
++    SqlCollate *pCollate;
++    char *zName;
++    char *zScript;
++    int nScript;
++    if( objc!=4 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
++      return TCL_ERROR;
++    }
++    zName = Tcl_GetStringFromObj(objv[2], 0);
++    zScript = Tcl_GetStringFromObj(objv[3], &nScript);
++    pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
++    if( pCollate==0 ) return TCL_ERROR;
++    pCollate->interp = interp;
++    pCollate->pNext = pDb->pCollate;
++    pCollate->zScript = (char*)&pCollate[1];
++    pDb->pCollate = pCollate;
++    memcpy(pCollate->zScript, zScript, nScript+1);
++    if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
++        pCollate, tclSqlCollate) ){
++      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
++      return TCL_ERROR;
++    }
++    break;
++  }
++
++  /*
++  **     $db collation_needed SCRIPT
++  **
++  ** Create a new SQL collation function called NAME.  Whenever
++  ** that function is called, invoke SCRIPT to evaluate the function.
++  */
++  case DB_COLLATION_NEEDED: {
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
++      return TCL_ERROR;
++    }
++    if( pDb->pCollateNeeded ){
++      Tcl_DecrRefCount(pDb->pCollateNeeded);
++    }
++    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
++    Tcl_IncrRefCount(pDb->pCollateNeeded);
++    sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
++    break;
++  }
++
++  /*    $db commit_hook ?CALLBACK?
++  **
++  ** Invoke the given callback just before committing every SQL transaction.
++  ** If the callback throws an exception or returns non-zero, then the
++  ** transaction is aborted.  If CALLBACK is an empty string, the callback
++  ** is disabled.
++  */
++  case DB_COMMIT_HOOK: {
++    if( objc>3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zCommit ){
++        Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
++      }
++    }else{
++      const char *zCommit;
++      int len;
++      if( pDb->zCommit ){
++        Tcl_Free(pDb->zCommit);
++      }
++      zCommit = Tcl_GetStringFromObj(objv[2], &len);
++      if( zCommit && len>0 ){
++        pDb->zCommit = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zCommit, zCommit, len+1);
++      }else{
++        pDb->zCommit = 0;
++      }
++      if( pDb->zCommit ){
++        pDb->interp = interp;
++        sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
++      }else{
++        sqlite3_commit_hook(pDb->db, 0, 0);
++      }
++    }
++    break;
++  }
++
++  /*    $db complete SQL
++  **
++  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
++  ** additional lines of input are needed.  This is similar to the
++  ** built-in "info complete" command of Tcl.
++  */
++  case DB_COMPLETE: {
++#ifndef SQLITE_OMIT_COMPLETE
++    Tcl_Obj *pResult;
++    int isComplete;
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
++      return TCL_ERROR;
++    }
++    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
++    pResult = Tcl_GetObjResult(interp);
++    Tcl_SetBooleanObj(pResult, isComplete);
++#endif
++    break;
++  }
++
++  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
++  **
++  ** Copy data into table from filename, optionally using SEPARATOR
++  ** as column separators.  If a column contains a null string, or the
++  ** value of NULLINDICATOR, a NULL is inserted for the column.
++  ** conflict-algorithm is one of the sqlite conflict algorithms:
++  **    rollback, abort, fail, ignore, replace
++  ** On success, return the number of lines processed, not necessarily same
++  ** as 'db changes' due to conflict-algorithm selected.
++  **
++  ** This code is basically an implementation/enhancement of
++  ** the sqlite3 shell.c ".import" command.
++  **
++  ** This command usage is equivalent to the sqlite2.x COPY statement,
++  ** which imports file data into a table using the PostgreSQL COPY file format:
++  **   $db copy $conflit_algo $table_name $filename \t \\N
++  */
++  case DB_COPY: {
++    char *zTable;               /* Insert data into this table */
++    char *zFile;                /* The file from which to extract data */
++    char *zConflict;            /* The conflict algorithm to use */
++    sqlite3_stmt *pStmt;        /* A statement */
++    int nCol;                   /* Number of columns in the table */
++    int nByte;                  /* Number of bytes in an SQL string */
++    int i, j;                   /* Loop counters */
++    int nSep;                   /* Number of bytes in zSep[] */
++    int nNull;                  /* Number of bytes in zNull[] */
++    char *zSql;                 /* An SQL statement */
++    char *zLine;                /* A single line of input from the file */
++    char **azCol;               /* zLine[] broken up into columns */
++    const char *zCommit;        /* How to commit changes */
++    FILE *in;                   /* The input file */
++    int lineno = 0;             /* Line number of input file */
++    char zLineNum[80];          /* Line number print buffer */
++    Tcl_Obj *pResult;           /* interp result */
++
++    const char *zSep;
++    const char *zNull;
++    if( objc<5 || objc>7 ){
++      Tcl_WrongNumArgs(interp, 2, objv,
++         "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
++      return TCL_ERROR;
++    }
++    if( objc>=6 ){
++      zSep = Tcl_GetStringFromObj(objv[5], 0);
++    }else{
++      zSep = "\t";
++    }
++    if( objc>=7 ){
++      zNull = Tcl_GetStringFromObj(objv[6], 0);
++    }else{
++      zNull = "";
++    }
++    zConflict = Tcl_GetStringFromObj(objv[2], 0);
++    zTable = Tcl_GetStringFromObj(objv[3], 0);
++    zFile = Tcl_GetStringFromObj(objv[4], 0);
++    nSep = strlen30(zSep);
++    nNull = strlen30(zNull);
++    if( nSep==0 ){
++      Tcl_AppendResult(interp,"Error: non-null separator required for copy",
++                       (char*)0);
++      return TCL_ERROR;
++    }
++    if(strcmp(zConflict, "rollback") != 0 &&
++       strcmp(zConflict, "abort"   ) != 0 &&
++       strcmp(zConflict, "fail"    ) != 0 &&
++       strcmp(zConflict, "ignore"  ) != 0 &&
++       strcmp(zConflict, "replace" ) != 0 ) {
++      Tcl_AppendResult(interp, "Error: \"", zConflict,
++            "\", conflict-algorithm must be one of: rollback, "
++            "abort, fail, ignore, or replace", (char*)0);
++      return TCL_ERROR;
++    }
++    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
++    if( zSql==0 ){
++      Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
++      return TCL_ERROR;
++    }
++    nByte = strlen30(zSql);
++    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
++    sqlite3_free(zSql);
++    if( rc ){
++      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
++      nCol = 0;
++    }else{
++      nCol = sqlite3_column_count(pStmt);
++    }
++    sqlite3_finalize(pStmt);
++    if( nCol==0 ) {
++      return TCL_ERROR;
++    }
++    zSql = malloc( nByte + 50 + nCol*2 );
++    if( zSql==0 ) {
++      Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
++      return TCL_ERROR;
++    }
++    sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
++         zConflict, zTable);
++    j = strlen30(zSql);
++    for(i=1; i<nCol; i++){
++      zSql[j++] = ',';
++      zSql[j++] = '?';
++    }
++    zSql[j++] = ')';
++    zSql[j] = 0;
++    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
++    free(zSql);
++    if( rc ){
++      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
++      sqlite3_finalize(pStmt);
++      return TCL_ERROR;
++    }
++    in = fopen(zFile, "rb");
++    if( in==0 ){
++      Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
++      sqlite3_finalize(pStmt);
++      return TCL_ERROR;
++    }
++    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
++    if( azCol==0 ) {
++      Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
++      fclose(in);
++      return TCL_ERROR;
++    }
++    (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
++    zCommit = "COMMIT";
++    while( (zLine = local_getline(0, in))!=0 ){
++      char *z;
++      lineno++;
++      azCol[0] = zLine;
++      for(i=0, z=zLine; *z; z++){
++        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
++          *z = 0;
++          i++;
++          if( i<nCol ){
++            azCol[i] = &z[nSep];
++            z += nSep-1;
++          }
++        }
++      }
++      if( i+1!=nCol ){
++        char *zErr;
++        int nErr = strlen30(zFile) + 200;
++        zErr = malloc(nErr);
++        if( zErr ){
++          sqlite3_snprintf(nErr, zErr,
++             "Error: %s line %d: expected %d columns of data but found %d",
++             zFile, lineno, nCol, i+1);
++          Tcl_AppendResult(interp, zErr, (char*)0);
++          free(zErr);
++        }
++        zCommit = "ROLLBACK";
++        break;
++      }
++      for(i=0; i<nCol; i++){
++        /* check for null data, if so, bind as null */
++        if( (nNull>0 && strcmp(azCol[i], zNull)==0)
++          || strlen30(azCol[i])==0
++        ){
++          sqlite3_bind_null(pStmt, i+1);
++        }else{
++          sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
++        }
++      }
++      sqlite3_step(pStmt);
++      rc = sqlite3_reset(pStmt);
++      free(zLine);
++      if( rc!=SQLITE_OK ){
++        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
++        zCommit = "ROLLBACK";
++        break;
++      }
++    }
++    free(azCol);
++    fclose(in);
++    sqlite3_finalize(pStmt);
++    (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
++
++    if( zCommit[0] == 'C' ){
++      /* success, set result as number of lines processed */
++      pResult = Tcl_GetObjResult(interp);
++      Tcl_SetIntObj(pResult, lineno);
++      rc = TCL_OK;
++    }else{
++      /* failure, append lineno where failed */
++      sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
++      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
++                       (char*)0);
++      rc = TCL_ERROR;
++    }
++    break;
++  }
++
++  /*
++  **     $db deserialize ?DATABASE? VALUE
++  **
++  ** Reopen DATABASE (default "main") using the content in $VALUE
++  */
++  case DB_DESERIALIZE: {
++#ifndef SQLITE_ENABLE_DESERIALIZE
++    Tcl_AppendResult(interp, "MEMDB not available in this build",
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    const char *zSchema;
++    Tcl_Obj *pValue;
++    unsigned char *pBA;
++    unsigned char *pData;
++    int len, xrc;
++    
++    if( objc==3 ){
++      zSchema = 0;
++      pValue = objv[2];
++    }else if( objc==4 ){
++      zSchema = Tcl_GetString(objv[2]);
++      pValue = objv[3];
++    }else{
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
++      rc = TCL_ERROR;
++      break;
++    }
++    pBA = Tcl_GetByteArrayFromObj(pValue, &len);
++    pData = sqlite3_malloc64( len );
++    if( pData==0 && len>0 ){
++      Tcl_AppendResult(interp, "out of memory", (char*)0);
++      rc = TCL_ERROR;
++    }else{
++      if( len>0 ) memcpy(pData, pBA, len);
++      xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
++                SQLITE_DESERIALIZE_FREEONCLOSE |
++                SQLITE_DESERIALIZE_RESIZEABLE);
++      if( xrc ){
++        Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
++        rc = TCL_ERROR;
++      }
++    }
++#endif
++    break; 
++  }
++
++  /*
++  **    $db enable_load_extension BOOLEAN
++  **
++  ** Turn the extension loading feature on or off.  It if off by
++  ** default.
++  */
++  case DB_ENABLE_LOAD_EXTENSION: {
++#ifndef SQLITE_OMIT_LOAD_EXTENSION
++    int onoff;
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
++      return TCL_ERROR;
++    }
++    if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
++      return TCL_ERROR;
++    }
++    sqlite3_enable_load_extension(pDb->db, onoff);
++    break;
++#else
++    Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
++                     (char*)0);
++    return TCL_ERROR;
++#endif
++  }
++
++  /*
++  **    $db errorcode
++  **
++  ** Return the numeric error code that was returned by the most recent
++  ** call to sqlite3_exec().
++  */
++  case DB_ERRORCODE: {
++    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
++    break;
++  }
++
++  /*
++  **    $db exists $sql
++  **    $db onecolumn $sql
++  **
++  ** The onecolumn method is the equivalent of:
++  **     lindex [$db eval $sql] 0
++  */
++  case DB_EXISTS:
++  case DB_ONECOLUMN: {
++    Tcl_Obj *pResult = 0;
++    DbEvalContext sEval;
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
++      return TCL_ERROR;
++    }
++
++    dbEvalInit(&sEval, pDb, objv[2], 0, 0);
++    rc = dbEvalStep(&sEval);
++    if( choice==DB_ONECOLUMN ){
++      if( rc==TCL_OK ){
++        pResult = dbEvalColumnValue(&sEval, 0);
++      }else if( rc==TCL_BREAK ){
++        Tcl_ResetResult(interp);
++      }
++    }else if( rc==TCL_BREAK || rc==TCL_OK ){
++      pResult = Tcl_NewBooleanObj(rc==TCL_OK);
++    }
++    dbEvalFinalize(&sEval);
++    if( pResult ) Tcl_SetObjResult(interp, pResult);
++
++    if( rc==TCL_BREAK ){
++      rc = TCL_OK;
++    }
++    break;
++  }
++
++  /*
++  **    $db eval ?options? $sql ?array? ?{  ...code... }?
++  **
++  ** The SQL statement in $sql is evaluated.  For each row, the values are
++  ** placed in elements of the array named "array" and ...code... is executed.
++  ** If "array" and "code" are omitted, then no callback is every invoked.
++  ** If "array" is an empty string, then the values are placed in variables
++  ** that have the same name as the fields extracted by the query.
++  */
++  case DB_EVAL: {
++    int evalFlags = 0;
++    const char *zOpt;
++    while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
++      if( strcmp(zOpt, "-withoutnulls")==0 ){
++        evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
++      }
++      else{
++        Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
++        return TCL_ERROR;
++      }
++      objc--;
++      objv++;
++    }
++    if( objc<3 || objc>5 ){
++      Tcl_WrongNumArgs(interp, 2, objv, 
++          "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
++      return TCL_ERROR;
++    }
++
++    if( objc==3 ){
++      DbEvalContext sEval;
++      Tcl_Obj *pRet = Tcl_NewObj();
++      Tcl_IncrRefCount(pRet);
++      dbEvalInit(&sEval, pDb, objv[2], 0, 0);
++      while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
++        int i;
++        int nCol;
++        dbEvalRowInfo(&sEval, &nCol, 0);
++        for(i=0; i<nCol; i++){
++          Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
++        }
++      }
++      dbEvalFinalize(&sEval);
++      if( rc==TCL_BREAK ){
++        Tcl_SetObjResult(interp, pRet);
++        rc = TCL_OK;
++      }
++      Tcl_DecrRefCount(pRet);
++    }else{
++      ClientData cd2[2];
++      DbEvalContext *p;
++      Tcl_Obj *pArray = 0;
++      Tcl_Obj *pScript;
++
++      if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
++        pArray = objv[3];
++      }
++      pScript = objv[objc-1];
++      Tcl_IncrRefCount(pScript);
++
++      p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
++      dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
++
++      cd2[0] = (void *)p;
++      cd2[1] = (void *)pScript;
++      rc = DbEvalNextCmd(cd2, interp, TCL_OK);
++    }
++    break;
++  }
++
++  /*
++  **     $db function NAME [-argcount N] [-deterministic] SCRIPT
++  **
++  ** Create a new SQL function called NAME.  Whenever that function is
++  ** called, invoke SCRIPT to evaluate the function.
++  */
++  case DB_FUNCTION: {
++    int flags = SQLITE_UTF8;
++    SqlFunc *pFunc;
++    Tcl_Obj *pScript;
++    char *zName;
++    int nArg = -1;
++    int i;
++    if( objc<4 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
++      return TCL_ERROR;
++    }
++    for(i=3; i<(objc-1); i++){
++      const char *z = Tcl_GetString(objv[i]);
++      int n = strlen30(z);
++      if( n>2 && strncmp(z, "-argcount",n)==0 ){
++        if( i==(objc-2) ){
++          Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
++          return TCL_ERROR;
++        }
++        if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
++        if( nArg<0 ){
++          Tcl_AppendResult(interp, "number of arguments must be non-negative",
++                           (char*)0);
++          return TCL_ERROR;
++        }
++        i++;
++      }else
++      if( n>2 && strncmp(z, "-deterministic",n)==0 ){
++        flags |= SQLITE_DETERMINISTIC;
++      }else{
++        Tcl_AppendResult(interp, "bad option \"", z,
++            "\": must be -argcount or -deterministic", (char*)0
++        );
++        return TCL_ERROR;
++      }
++    }
++
++    pScript = objv[objc-1];
++    zName = Tcl_GetStringFromObj(objv[2], 0);
++    pFunc = findSqlFunc(pDb, zName);
++    if( pFunc==0 ) return TCL_ERROR;
++    if( pFunc->pScript ){
++      Tcl_DecrRefCount(pFunc->pScript);
++    }
++    pFunc->pScript = pScript;
++    Tcl_IncrRefCount(pScript);
++    pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
++    rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
++        pFunc, tclSqlFunc, 0, 0);
++    if( rc!=SQLITE_OK ){
++      rc = TCL_ERROR;
++      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
++    }
++    break;
++  }
++
++  /*
++  **     $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
++  */
++  case DB_INCRBLOB: {
++#ifdef SQLITE_OMIT_INCRBLOB
++    Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
++    return TCL_ERROR;
++#else
++    int isReadonly = 0;
++    const char *zDb = "main";
++    const char *zTable;
++    const char *zColumn;
++    Tcl_WideInt iRow;
++
++    /* Check for the -readonly option */
++    if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
++      isReadonly = 1;
++    }
++
++    if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
++      return TCL_ERROR;
++    }
++
++    if( objc==(6+isReadonly) ){
++      zDb = Tcl_GetString(objv[2]);
++    }
++    zTable = Tcl_GetString(objv[objc-3]);
++    zColumn = Tcl_GetString(objv[objc-2]);
++    rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
++
++    if( rc==TCL_OK ){
++      rc = createIncrblobChannel(
++          interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
++      );
++    }
++#endif
++    break;
++  }
++
++  /*
++  **     $db interrupt
++  **
++  ** Interrupt the execution of the inner-most SQL interpreter.  This
++  ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
++  */
++  case DB_INTERRUPT: {
++    sqlite3_interrupt(pDb->db);
++    break;
++  }
++
++  /*
++  **     $db nullvalue ?STRING?
++  **
++  ** Change text used when a NULL comes back from the database. If ?STRING?
++  ** is not present, then the current string used for NULL is returned.
++  ** If STRING is present, then STRING is returned.
++  **
++  */
++  case DB_NULLVALUE: {
++    if( objc!=2 && objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
++      return TCL_ERROR;
++    }
++    if( objc==3 ){
++      int len;
++      char *zNull = Tcl_GetStringFromObj(objv[2], &len);
++      if( pDb->zNull ){
++        Tcl_Free(pDb->zNull);
++      }
++      if( zNull && len>0 ){
++        pDb->zNull = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zNull, zNull, len);
++        pDb->zNull[len] = '\0';
++      }else{
++        pDb->zNull = 0;
++      }
++    }
++    Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
++    break;
++  }
++
++  /*
++  **     $db last_insert_rowid
++  **
++  ** Return an integer which is the ROWID for the most recent insert.
++  */
++  case DB_LAST_INSERT_ROWID: {
++    Tcl_Obj *pResult;
++    Tcl_WideInt rowid;
++    if( objc!=2 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "");
++      return TCL_ERROR;
++    }
++    rowid = sqlite3_last_insert_rowid(pDb->db);
++    pResult = Tcl_GetObjResult(interp);
++    Tcl_SetWideIntObj(pResult, rowid);
++    break;
++  }
++
++  /*
++  ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
++  */
++
++  /*    $db progress ?N CALLBACK?
++  **
++  ** Invoke the given callback every N virtual machine opcodes while executing
++  ** queries.
++  */
++  case DB_PROGRESS: {
++    if( objc==2 ){
++      if( pDb->zProgress ){
++        Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
++      }
++    }else if( objc==4 ){
++      char *zProgress;
++      int len;
++      int N;
++      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
++        return TCL_ERROR;
++      };
++      if( pDb->zProgress ){
++        Tcl_Free(pDb->zProgress);
++      }
++      zProgress = Tcl_GetStringFromObj(objv[3], &len);
++      if( zProgress && len>0 ){
++        pDb->zProgress = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zProgress, zProgress, len+1);
++      }else{
++        pDb->zProgress = 0;
++      }
++#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
++      if( pDb->zProgress ){
++        pDb->interp = interp;
++        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
++      }else{
++        sqlite3_progress_handler(pDb->db, 0, 0, 0);
++      }
++#endif
++    }else{
++      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
++      return TCL_ERROR;
++    }
++    break;
++  }
++
++  /*    $db profile ?CALLBACK?
++  **
++  ** Make arrangements to invoke the CALLBACK routine after each SQL statement
++  ** that has run.  The text of the SQL and the amount of elapse time are
++  ** appended to CALLBACK before the script is run.
++  */
++  case DB_PROFILE: {
++    if( objc>3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zProfile ){
++        Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
++      }
++    }else{
++      char *zProfile;
++      int len;
++      if( pDb->zProfile ){
++        Tcl_Free(pDb->zProfile);
++      }
++      zProfile = Tcl_GetStringFromObj(objv[2], &len);
++      if( zProfile && len>0 ){
++        pDb->zProfile = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zProfile, zProfile, len+1);
++      }else{
++        pDb->zProfile = 0;
++      }
++#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
++    !defined(SQLITE_OMIT_DEPRECATED)
++      if( pDb->zProfile ){
++        pDb->interp = interp;
++        sqlite3_profile(pDb->db, DbProfileHandler, pDb);
++      }else{
++        sqlite3_profile(pDb->db, 0, 0);
++      }
++#endif
++    }
++    break;
++  }
++
++  /*
++  **     $db rekey KEY
++  **
++  ** Change the encryption key on the currently open database.
++  */
++  case DB_REKEY: {
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++    int nKey;
++    void *pKey;
++#endif
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
++      return TCL_ERROR;
++    }
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
++    rc = sqlite3_rekey(pDb->db, pKey, nKey);
++    if( rc ){
++      Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
++      rc = TCL_ERROR;
++    }
++#endif
++    break;
++  }
++
++  /*    $db restore ?DATABASE? FILENAME
++  **
++  ** Open a database file named FILENAME.  Transfer the content
++  ** of FILENAME into the local database DATABASE (default: "main").
++  */
++  case DB_RESTORE: {
++    const char *zSrcFile;
++    const char *zDestDb;
++    sqlite3 *pSrc;
++    sqlite3_backup *pBackup;
++    int nTimeout = 0;
++
++    if( objc==3 ){
++      zDestDb = "main";
++      zSrcFile = Tcl_GetString(objv[2]);
++    }else if( objc==4 ){
++      zDestDb = Tcl_GetString(objv[2]);
++      zSrcFile = Tcl_GetString(objv[3]);
++    }else{
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
++      return TCL_ERROR;
++    }
++    rc = sqlite3_open_v2(zSrcFile, &pSrc,
++                         SQLITE_OPEN_READONLY | pDb->openFlags, 0);
++    if( rc!=SQLITE_OK ){
++      Tcl_AppendResult(interp, "cannot open source database: ",
++           sqlite3_errmsg(pSrc), (char*)0);
++      sqlite3_close(pSrc);
++      return TCL_ERROR;
++    }
++    pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
++    if( pBackup==0 ){
++      Tcl_AppendResult(interp, "restore failed: ",
++           sqlite3_errmsg(pDb->db), (char*)0);
++      sqlite3_close(pSrc);
++      return TCL_ERROR;
++    }
++    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
++              || rc==SQLITE_BUSY ){
++      if( rc==SQLITE_BUSY ){
++        if( nTimeout++ >= 3 ) break;
++        sqlite3_sleep(100);
++      }
++    }
++    sqlite3_backup_finish(pBackup);
++    if( rc==SQLITE_DONE ){
++      rc = TCL_OK;
++    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
++      Tcl_AppendResult(interp, "restore failed: source database busy",
++                       (char*)0);
++      rc = TCL_ERROR;
++    }else{
++      Tcl_AppendResult(interp, "restore failed: ",
++           sqlite3_errmsg(pDb->db), (char*)0);
++      rc = TCL_ERROR;
++    }
++    sqlite3_close(pSrc);
++    break;
++  }
++
++  /*
++  **     $db serialize ?DATABASE?
++  **
++  ** Return a serialization of a database.  
++  */
++  case DB_SERIALIZE: {
++#ifndef SQLITE_ENABLE_DESERIALIZE
++    Tcl_AppendResult(interp, "MEMDB not available in this build",
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
++    sqlite3_int64 sz = 0;
++    unsigned char *pData;
++    if( objc!=2 && objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
++      rc = TCL_ERROR;
++    }else{
++      int needFree;
++      pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
++      if( pData ){
++        needFree = 0;
++      }else{
++        pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
++        needFree = 1;
++      }
++      Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
++      if( needFree ) sqlite3_free(pData);
++    }
++#endif
++    break;
++  }
++
++  /*
++  **     $db status (step|sort|autoindex|vmstep)
++  **
++  ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
++  ** SQLITE_STMTSTATUS_SORT for the most recent eval.
++  */
++  case DB_STATUS: {
++    int v;
++    const char *zOp;
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
++      return TCL_ERROR;
++    }
++    zOp = Tcl_GetString(objv[2]);
++    if( strcmp(zOp, "step")==0 ){
++      v = pDb->nStep;
++    }else if( strcmp(zOp, "sort")==0 ){
++      v = pDb->nSort;
++    }else if( strcmp(zOp, "autoindex")==0 ){
++      v = pDb->nIndex;
++    }else if( strcmp(zOp, "vmstep")==0 ){
++      v = pDb->nVMStep;
++    }else{
++      Tcl_AppendResult(interp,
++            "bad argument: should be autoindex, step, sort or vmstep",
++            (char*)0);
++      return TCL_ERROR;
++    }
++    Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
++    break;
++  }
++
++  /*
++  **     $db timeout MILLESECONDS
++  **
++  ** Delay for the number of milliseconds specified when a file is locked.
++  */
++  case DB_TIMEOUT: {
++    int ms;
++    if( objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
++      return TCL_ERROR;
++    }
++    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
++    sqlite3_busy_timeout(pDb->db, ms);
++    break;
++  }
++
++  /*
++  **     $db total_changes
++  **
++  ** Return the number of rows that were modified, inserted, or deleted
++  ** since the database handle was created.
++  */
++  case DB_TOTAL_CHANGES: {
++    Tcl_Obj *pResult;
++    if( objc!=2 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "");
++      return TCL_ERROR;
++    }
++    pResult = Tcl_GetObjResult(interp);
++    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
++    break;
++  }
++
++  /*    $db trace ?CALLBACK?
++  **
++  ** Make arrangements to invoke the CALLBACK routine for each SQL statement
++  ** that is executed.  The text of the SQL is appended to CALLBACK before
++  ** it is executed.
++  */
++  case DB_TRACE: {
++    if( objc>3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zTrace ){
++        Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
++      }
++    }else{
++      char *zTrace;
++      int len;
++      if( pDb->zTrace ){
++        Tcl_Free(pDb->zTrace);
++      }
++      zTrace = Tcl_GetStringFromObj(objv[2], &len);
++      if( zTrace && len>0 ){
++        pDb->zTrace = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zTrace, zTrace, len+1);
++      }else{
++        pDb->zTrace = 0;
++      }
++#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
++    !defined(SQLITE_OMIT_DEPRECATED)
++      if( pDb->zTrace ){
++        pDb->interp = interp;
++        sqlite3_trace(pDb->db, DbTraceHandler, pDb);
++      }else{
++        sqlite3_trace(pDb->db, 0, 0);
++      }
++#endif
++    }
++    break;
++  }
++
++  /*    $db trace_v2 ?CALLBACK? ?MASK?
++  **
++  ** Make arrangements to invoke the CALLBACK routine for each trace event
++  ** matching the mask that is generated.  The parameters are appended to
++  ** CALLBACK before it is executed.
++  */
++  case DB_TRACE_V2: {
++    if( objc>4 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
++      return TCL_ERROR;
++    }else if( objc==2 ){
++      if( pDb->zTraceV2 ){
++        Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
++      }
++    }else{
++      char *zTraceV2;
++      int len;
++      Tcl_WideInt wMask = 0;
++      if( objc==4 ){
++        static const char *TTYPE_strs[] = {
++          "statement", "profile", "row", "close", 0
++        };
++        enum TTYPE_enum {
++          TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
++        };
++        int i;
++        if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
++          return TCL_ERROR;
++        }
++        for(i=0; i<len; i++){
++          Tcl_Obj *pObj;
++          int ttype;
++          if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
++            return TCL_ERROR;
++          }
++          if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
++                                  0, &ttype)!=TCL_OK ){
++            Tcl_WideInt wType;
++            Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
++            Tcl_IncrRefCount(pError);
++            if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
++              Tcl_DecrRefCount(pError);
++              wMask |= wType;
++            }else{
++              Tcl_SetObjResult(interp, pError);
++              Tcl_DecrRefCount(pError);
++              return TCL_ERROR;
++            }
++          }else{
++            switch( (enum TTYPE_enum)ttype ){
++              case TTYPE_STMT:    wMask |= SQLITE_TRACE_STMT;    break;
++              case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
++              case TTYPE_ROW:     wMask |= SQLITE_TRACE_ROW;     break;
++              case TTYPE_CLOSE:   wMask |= SQLITE_TRACE_CLOSE;   break;
++            }
++          }
++        }
++      }else{
++        wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
++      }
++      if( pDb->zTraceV2 ){
++        Tcl_Free(pDb->zTraceV2);
++      }
++      zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
++      if( zTraceV2 && len>0 ){
++        pDb->zTraceV2 = Tcl_Alloc( len + 1 );
++        memcpy(pDb->zTraceV2, zTraceV2, len+1);
++      }else{
++        pDb->zTraceV2 = 0;
++      }
++#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
++      if( pDb->zTraceV2 ){
++        pDb->interp = interp;
++        sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
++      }else{
++        sqlite3_trace_v2(pDb->db, 0, 0, 0);
++      }
++#endif
++    }
++    break;
++  }
++
++  /*    $db transaction [-deferred|-immediate|-exclusive] SCRIPT
++  **
++  ** Start a new transaction (if we are not already in the midst of a
++  ** transaction) and execute the TCL script SCRIPT.  After SCRIPT
++  ** completes, either commit the transaction or roll it back if SCRIPT
++  ** throws an exception.  Or if no new transation was started, do nothing.
++  ** pass the exception on up the stack.
++  **
++  ** This command was inspired by Dave Thomas's talk on Ruby at the
++  ** 2005 O'Reilly Open Source Convention (OSCON).
++  */
++  case DB_TRANSACTION: {
++    Tcl_Obj *pScript;
++    const char *zBegin = "SAVEPOINT _tcl_transaction";
++    if( objc!=3 && objc!=4 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
++      return TCL_ERROR;
++    }
++
++    if( pDb->nTransaction==0 && objc==4 ){
++      static const char *TTYPE_strs[] = {
++        "deferred",   "exclusive",  "immediate", 0
++      };
++      enum TTYPE_enum {
++        TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
++      };
++      int ttype;
++      if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
++                              0, &ttype) ){
++        return TCL_ERROR;
++      }
++      switch( (enum TTYPE_enum)ttype ){
++        case TTYPE_DEFERRED:    /* no-op */;                 break;
++        case TTYPE_EXCLUSIVE:   zBegin = "BEGIN EXCLUSIVE";  break;
++        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
++      }
++    }
++    pScript = objv[objc-1];
++
++    /* Run the SQLite BEGIN command to open a transaction or savepoint. */
++    pDb->disableAuth++;
++    rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
++    pDb->disableAuth--;
++    if( rc!=SQLITE_OK ){
++      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
++      return TCL_ERROR;
++    }
++    pDb->nTransaction++;
++
++    /* If using NRE, schedule a callback to invoke the script pScript, then
++    ** a second callback to commit (or rollback) the transaction or savepoint
++    ** opened above. If not using NRE, evaluate the script directly, then
++    ** call function DbTransPostCmd() to commit (or rollback) the transaction
++    ** or savepoint.  */
++    if( DbUseNre() ){
++      Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
++      (void)Tcl_NREvalObj(interp, pScript, 0);
++    }else{
++      rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
++    }
++    break;
++  }
++
++  /*
++  **    $db unlock_notify ?script?
++  */
++  case DB_UNLOCK_NOTIFY: {
++#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
++    Tcl_AppendResult(interp, "unlock_notify not available in this build",
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    if( objc!=2 && objc!=3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
++      rc = TCL_ERROR;
++    }else{
++      void (*xNotify)(void **, int) = 0;
++      void *pNotifyArg = 0;
++
++      if( pDb->pUnlockNotify ){
++        Tcl_DecrRefCount(pDb->pUnlockNotify);
++        pDb->pUnlockNotify = 0;
++      }
++
++      if( objc==3 ){
++        xNotify = DbUnlockNotify;
++        pNotifyArg = (void *)pDb;
++        pDb->pUnlockNotify = objv[2];
++        Tcl_IncrRefCount(pDb->pUnlockNotify);
++      }
++
++      if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
++        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
++        rc = TCL_ERROR;
++      }
++    }
++#endif
++    break;
++  }
++
++  /*
++  **    $db preupdate_hook count
++  **    $db preupdate_hook hook ?SCRIPT?
++  **    $db preupdate_hook new INDEX
++  **    $db preupdate_hook old INDEX
++  */
++  case DB_PREUPDATE: {
++#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
++    Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", 
++                     (char*)0);
++    rc = TCL_ERROR;
++#else
++    static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
++    enum DbPreupdateSubCmd {
++      PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
++    };
++    int iSub;
++
++    if( objc<3 ){
++      Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
++    }
++    if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
++      return TCL_ERROR;
++    }
++
++    switch( (enum DbPreupdateSubCmd)iSub ){
++      case PRE_COUNT: {
++        int nCol = sqlite3_preupdate_count(pDb->db);
++        Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
++        break;
++      }
++
++      case PRE_HOOK: {
++        if( objc>4 ){
++          Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
++          return TCL_ERROR;
++        }
++        DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
++        break;
++      }
++
++      case PRE_DEPTH: {
++        Tcl_Obj *pRet;
++        if( objc!=3 ){
++          Tcl_WrongNumArgs(interp, 3, objv, "");
++          return TCL_ERROR;
++        }
++        pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
++        Tcl_SetObjResult(interp, pRet);
++        break;
++      }
++
++      case PRE_NEW:
++      case PRE_OLD: {
++        int iIdx;
++        sqlite3_value *pValue;
++        if( objc!=4 ){
++          Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
++          return TCL_ERROR;
++        }
++        if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
++          return TCL_ERROR;
++        }
++
++        if( iSub==PRE_OLD ){
++          rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
++        }else{
++          assert( iSub==PRE_NEW );
++          rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
++        }
++
++        if( rc==SQLITE_OK ){
++          Tcl_Obj *pObj;
++          pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
++          Tcl_SetObjResult(interp, pObj);
++        }else{
++          Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
++          return TCL_ERROR;
++        }
++      }
++    }
++#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
++    break;
++  }
++
++  /*
++  **    $db wal_hook ?script?
++  **    $db update_hook ?script?
++  **    $db rollback_hook ?script?
++  */
++  case DB_WAL_HOOK:
++  case DB_UPDATE_HOOK:
++  case DB_ROLLBACK_HOOK: {
++    /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
++    ** whether [$db update_hook] or [$db rollback_hook] was invoked.
++    */
++    Tcl_Obj **ppHook = 0;
++    if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
++    if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
++    if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
++    if( objc>3 ){
++       Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
++       return TCL_ERROR;
++    }
++
++    DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
++    break;
++  }
++
++  /*    $db version
++  **
++  ** Return the version string for this database.
++  */
++  case DB_VERSION: {
++    int i;
++    for(i=2; i<objc; i++){
++      const char *zArg = Tcl_GetString(objv[i]);
++      /* Optional arguments to $db version are used for testing purpose */
++#ifdef SQLITE_TEST
++      /* $db version -use-legacy-prepare BOOLEAN
++      **
++      ** Turn the use of legacy sqlite3_prepare() on or off.
++      */
++      if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
++        i++;
++        if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
++          return TCL_ERROR;
++        }
++      }else
++
++      /* $db version -last-stmt-ptr
++      **
++      ** Return a string which is a hex encoding of the pointer to the
++      ** most recent sqlite3_stmt in the statement cache.
++      */
++      if( strcmp(zArg, "-last-stmt-ptr")==0 ){
++        char zBuf[100];
++        sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
++                         pDb->stmtList ? pDb->stmtList->pStmt: 0);
++        Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
++      }else
++#endif /* SQLITE_TEST */
++      {
++        Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
++        return TCL_ERROR;
++      }
++    }
++    if( i==2 ){   
++      Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
++    }
++    break;
++  }
++
++
++  } /* End of the SWITCH statement */
++  return rc;
++}
++
++#if SQLITE_TCL_NRE
++/*
++** Adaptor that provides an objCmd interface to the NRE-enabled
++** interface implementation.
++*/
++static int SQLITE_TCLAPI DbObjCmdAdaptor(
++  void *cd,
++  Tcl_Interp *interp,
++  int objc,
++  Tcl_Obj *const*objv
++){
++  return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
++}
++#endif /* SQLITE_TCL_NRE */
++
++/*
++** Issue the usage message when the "sqlite3" command arguments are
++** incorrect.
++*/
++static int sqliteCmdUsage(
++  Tcl_Interp *interp,
++  Tcl_Obj *const*objv
++){
++  Tcl_WrongNumArgs(interp, 1, objv,
++    "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
++    " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++    " ?-key CODECKEY?"
++#endif
++  );
++  return TCL_ERROR;
++}
++
++/*
++**   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
++**                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
++**
++** This is the main Tcl command.  When the "sqlite" Tcl command is
++** invoked, this routine runs to process that command.
++**
++** The first argument, DBNAME, is an arbitrary name for a new
++** database connection.  This command creates a new command named
++** DBNAME that is used to control that connection.  The database
++** connection is deleted when the DBNAME command is deleted.
++**
++** The second argument is the name of the database file.
++**
++*/
++static int SQLITE_TCLAPI DbMain(
++  void *cd,
++  Tcl_Interp *interp,
++  int objc,
++  Tcl_Obj *const*objv
++){
++  SqliteDb *p;
++  const char *zArg;
++  char *zErrMsg;
++  int i;
++  const char *zFile = 0;
++  const char *zVfs = 0;
++  int flags;
++  Tcl_DString translatedFilename;
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++  void *pKey = 0;
++  int nKey = 0;
++#endif
++  int rc;
++
++  /* In normal use, each TCL interpreter runs in a single thread.  So
++  ** by default, we can turn off mutexing on SQLite database connections.
++  ** However, for testing purposes it is useful to have mutexes turned
++  ** on.  So, by default, mutexes default off.  But if compiled with
++  ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
++  */
++#ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
++  flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
++#else
++  flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
++#endif
++
++  if( objc==1 ) return sqliteCmdUsage(interp, objv);
++  if( objc==2 ){
++    zArg = Tcl_GetStringFromObj(objv[1], 0);
++    if( strcmp(zArg,"-version")==0 ){
++      Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
++      return TCL_OK;
++    }
++    if( strcmp(zArg,"-sourceid")==0 ){
++      Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
++      return TCL_OK;
++    }
++    if( strcmp(zArg,"-has-codec")==0 ){
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++      Tcl_AppendResult(interp,"1",(char*)0);
++#else
++      Tcl_AppendResult(interp,"0",(char*)0);
++#endif
++      return TCL_OK;
++    }
++    if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
++  }
++  for(i=2; i<objc; i++){
++    zArg = Tcl_GetString(objv[i]);
++    if( zArg[0]!='-' ){
++      if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
++      zFile = zArg;
++      continue;
++    }
++    if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
++    i++;
++    if( strcmp(zArg,"-key")==0 ){
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++      pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
++#endif
++    }else if( strcmp(zArg, "-vfs")==0 ){
++      zVfs = Tcl_GetString(objv[i]);
++    }else if( strcmp(zArg, "-readonly")==0 ){
++      int b;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
++      if( b ){
++        flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
++        flags |= SQLITE_OPEN_READONLY;
++      }else{
++        flags &= ~SQLITE_OPEN_READONLY;
++        flags |= SQLITE_OPEN_READWRITE;
++      }
++    }else if( strcmp(zArg, "-create")==0 ){
++      int b;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
++      if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
++        flags |= SQLITE_OPEN_CREATE;
++      }else{
++        flags &= ~SQLITE_OPEN_CREATE;
++      }
++    }else if( strcmp(zArg, "-nomutex")==0 ){
++      int b;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
++      if( b ){
++        flags |= SQLITE_OPEN_NOMUTEX;
++        flags &= ~SQLITE_OPEN_FULLMUTEX;
++      }else{
++        flags &= ~SQLITE_OPEN_NOMUTEX;
++      }
++    }else if( strcmp(zArg, "-fullmutex")==0 ){
++      int b;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
++      if( b ){
++        flags |= SQLITE_OPEN_FULLMUTEX;
++        flags &= ~SQLITE_OPEN_NOMUTEX;
++      }else{
++        flags &= ~SQLITE_OPEN_FULLMUTEX;
++      }
++    }else if( strcmp(zArg, "-uri")==0 ){
++      int b;
++      if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
++      if( b ){
++        flags |= SQLITE_OPEN_URI;
++      }else{
++        flags &= ~SQLITE_OPEN_URI;
++      }
++    }else{
++      Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
++      return TCL_ERROR;
++    }
++  }
++  zErrMsg = 0;
++  p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
++  memset(p, 0, sizeof(*p));
++  if( zFile==0 ) zFile = "";
++  zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
++  rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
++  Tcl_DStringFree(&translatedFilename);
++  if( p->db ){
++    if( SQLITE_OK!=sqlite3_errcode(p->db) ){
++      zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
++      sqlite3_close(p->db);
++      p->db = 0;
++    }
++  }else{
++    zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
++  }
++#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
++  if( p->db ){
++    sqlite3_key(p->db, pKey, nKey);
++  }
++#endif
++  if( p->db==0 ){
++    Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
++    Tcl_Free((char*)p);
++    sqlite3_free(zErrMsg);
++    return TCL_ERROR;
++  }
++  p->maxStmt = NUM_PREPARED_STMTS;
++  p->openFlags = flags & SQLITE_OPEN_URI;
++  p->interp = interp;
++  zArg = Tcl_GetStringFromObj(objv[1], 0);
++  if( DbUseNre() ){
++    Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
++                        (char*)p, DbDeleteCmd);
++  }else{
++    Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
++  }
++  return TCL_OK;
++}
++
++/*
++** Provide a dummy Tcl_InitStubs if we are using this as a static
++** library.
++*/
++#ifndef USE_TCL_STUBS
++# undef  Tcl_InitStubs
++# define Tcl_InitStubs(a,b,c) TCL_VERSION
++#endif
++
++/*
++** Make sure we have a PACKAGE_VERSION macro defined.  This will be
++** defined automatically by the TEA makefile.  But other makefiles
++** do not define it.
++*/
++#ifndef PACKAGE_VERSION
++# define PACKAGE_VERSION SQLITE_VERSION
++#endif
++
++/*
++** Initialize this module.
++**
++** This Tcl module contains only a single new Tcl command named "sqlite".
++** (Hence there is no namespace.  There is no point in using a namespace
++** if the extension only supplies one new name!)  The "sqlite" command is
++** used to open a new SQLite database.  See the DbMain() routine above
++** for additional information.
++**
++** The EXTERN macros are required by TCL in order to work on windows.
++*/
++EXTERN int Sqlite3_Init(Tcl_Interp *interp){
++  int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
++  if( rc==TCL_OK ){
++    Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
++#ifndef SQLITE_3_SUFFIX_ONLY
++    /* The "sqlite" alias is undocumented.  It is here only to support
++    ** legacy scripts.  All new scripts should use only the "sqlite3"
++    ** command. */
++    Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
++#endif
++    rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
++  }
++  return rc;
++}
++EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
++EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
++EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
++
++/* Because it accesses the file-system and uses persistent state, SQLite
++** is not considered appropriate for safe interpreters.  Hence, we cause
++** the _SafeInit() interfaces return TCL_ERROR.
++*/
++EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; }
++EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;}
++
++
++
++#ifndef SQLITE_3_SUFFIX_ONLY
++int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
++int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
++int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
++int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
++#endif
++
++/*
++** If the TCLSH macro is defined, add code to make a stand-alone program.
++*/
++#if defined(TCLSH)
++
++/* This is the main routine for an ordinary TCL shell.  If there are
++** are arguments, run the first argument as a script.  Otherwise,
++** read TCL commands from standard input
++*/
++static const char *tclsh_main_loop(void){
++  static const char zMainloop[] =
++    "if {[llength $argv]>=1} {\n"
++      "set argv0 [lindex $argv 0]\n"
++      "set argv [lrange $argv 1 end]\n"
++      "source $argv0\n"
++    "} else {\n"
++      "set line {}\n"
++      "while {![eof stdin]} {\n"
++        "if {$line!=\"\"} {\n"
++          "puts -nonewline \"> \"\n"
++        "} else {\n"
++          "puts -nonewline \"% \"\n"
++        "}\n"
++        "flush stdout\n"
++        "append line [gets stdin]\n"
++        "if {[info complete $line]} {\n"
++          "if {[catch {uplevel #0 $line} result]} {\n"
++            "puts stderr \"Error: $result\"\n"
++          "} elseif {$result!=\"\"} {\n"
++            "puts $result\n"
++          "}\n"
++          "set line {}\n"
++        "} else {\n"
++          "append line \\n\n"
++        "}\n"
++      "}\n"
++    "}\n"
++  ;
++  return zMainloop;
++}
++
++#define TCLSH_MAIN main   /* Needed to fake out mktclapp */
++int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
++  Tcl_Interp *interp;
++  int i;
++  const char *zScript = 0;
++  char zArgc[32];
++#if defined(TCLSH_INIT_PROC)
++  extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
++#endif
++
++#if !defined(_WIN32_WCE)
++  if( getenv("SQLITE_DEBUG_BREAK") ){
++    if( isatty(0) && isatty(2) ){
++      fprintf(stderr,
++          "attach debugger to process %d and press any key to continue.\n",
++          GETPID());
++      fgetc(stdin);
++    }else{
++#if defined(_WIN32) || defined(WIN32)
++      DebugBreak();
++#elif defined(SIGTRAP)
++      raise(SIGTRAP);
++#endif
++    }
++  }
++#endif
++
++  /* Call sqlite3_shutdown() once before doing anything else. This is to
++  ** test that sqlite3_shutdown() can be safely called by a process before
++  ** sqlite3_initialize() is. */
++  sqlite3_shutdown();
++
++  Tcl_FindExecutable(argv[0]);
++  Tcl_SetSystemEncoding(NULL, "utf-8");
++  interp = Tcl_CreateInterp();
++  Sqlite3_Init(interp);
++
++  sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
++  Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
++  Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
++  Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
++  for(i=1; i<argc; i++){
++    Tcl_SetVar(interp, "argv", argv[i],
++        TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
++  }
++#if defined(TCLSH_INIT_PROC)
++  zScript = TCLSH_INIT_PROC(interp);
++#endif
++  if( zScript==0 ){
++    zScript = tclsh_main_loop();
++  }
++  if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
++    const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
++    if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
++    fprintf(stderr,"%s: %s\n", *argv, zInfo);
++    return 1;
++  }
++  return 0;
++}
++#endif /* TCLSH */
+--- contrib/sqlite3/tea/license.terms.orig
++++ contrib/sqlite3/tea/license.terms
+@@ -0,0 +1,6 @@
++The author disclaims copyright to this source code.  In place of
++a legal notice, here is a blessing:
++
++    May you do good and not evil.
++    May you find forgiveness for yourself and forgive others.
++    May you share freely, never taking more than you give.
+--- contrib/sqlite3/tea/pkgIndex.tcl.in.orig
++++ contrib/sqlite3/tea/pkgIndex.tcl.in
+@@ -0,0 +1,7 @@
++#
++# Tcl package index file
++#
++# Note sqlite*3* init specifically
++#
++package ifneeded sqlite3 @PACKAGE_VERSION@ \
++    [list load [file join $dir @PKG_LIB_FILE@] Sqlite3]
+--- contrib/sqlite3/tea/tclconfig/install-sh.orig
++++ contrib/sqlite3/tea/tclconfig/install-sh
+@@ -0,0 +1,528 @@
++#!/bin/sh
++# install - install a program, script, or datafile
++
++scriptversion=2011-04-20.01; # UTC
++
++# This originates from X11R5 (mit/util/scripts/install.sh), which was
++# later released in X11R6 (xc/config/util/install.sh) with the
++# following copyright and license.
++#
++# Copyright (C) 1994 X Consortium
++#
++# Permission is hereby granted, free of charge, to any person obtaining a copy
++# of this software and associated documentation files (the "Software"), to
++# deal in the Software without restriction, including without limitation the
++# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
++# sell copies of the Software, and to permit persons to whom the Software is
++# furnished to do so, subject to the following conditions:
++#
++# The above copyright notice and this permission notice shall be included in
++# all copies or substantial portions of the Software.
++#
++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
++# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
++# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
++# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++#
++# Except as contained in this notice, the name of the X Consortium shall not
++# be used in advertising or otherwise to promote the sale, use or other deal-
++# ings in this Software without prior written authorization from the X Consor-
++# tium.
++#
++#
++# FSF changes to this file are in the public domain.
++#
++# Calling this script install-sh is preferred over install.sh, to prevent
++# `make' implicit rules from creating a file called install from it
++# when there is no Makefile.
++#
++# This script is compatible with the BSD install script, but was written
++# from scratch.
++
++nl='
++'
++IFS=" ""	$nl"
++
++# set DOITPROG to echo to test this script
++
++# Don't use :- since 4.3BSD and earlier shells don't like it.
++doit=${DOITPROG-}
++if test -z "$doit"; then
++  doit_exec=exec
++else
++  doit_exec=$doit
++fi
++
++# Put in absolute file names if you don't have them in your path;
++# or use environment vars.
++
++chgrpprog=${CHGRPPROG-chgrp}
++chmodprog=${CHMODPROG-chmod}
++chownprog=${CHOWNPROG-chown}
++cmpprog=${CMPPROG-cmp}
++cpprog=${CPPROG-cp}
++mkdirprog=${MKDIRPROG-mkdir}
++mvprog=${MVPROG-mv}
++rmprog=${RMPROG-rm}
++stripprog=${STRIPPROG-strip}
++
++posix_glob='?'
++initialize_posix_glob='
++  test "$posix_glob" != "?" || {
++    if (set -f) 2>/dev/null; then
++      posix_glob=
++    else
++      posix_glob=:
++    fi
++  }
++'
++
++posix_mkdir=
++
++# Desired mode of installed file.
++mode=0755
++
++chgrpcmd=
++chmodcmd=$chmodprog
++chowncmd=
++mvcmd=$mvprog
++rmcmd="$rmprog -f"
++stripcmd=
++
++src=
++dst=
++dir_arg=
++dst_arg=
++
++copy_on_change=false
++no_target_directory=
++
++usage="\
++Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
++   or: $0 [OPTION]... SRCFILES... DIRECTORY
++   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
++   or: $0 [OPTION]... -d DIRECTORIES...
++
++In the 1st form, copy SRCFILE to DSTFILE.
++In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
++In the 4th, create DIRECTORIES.
++
++Options:
++     --help     display this help and exit.
++     --version  display version info and exit.
++
++  -c            (ignored)
++  -C            install only if different (preserve the last data modification time)
++  -d            create directories instead of installing files.
++  -g GROUP      $chgrpprog installed files to GROUP.
++  -m MODE       $chmodprog installed files to MODE.
++  -o USER       $chownprog installed files to USER.
++  -s            $stripprog installed files.
++  -S            $stripprog installed files.
++  -t DIRECTORY  install into DIRECTORY.
++  -T            report an error if DSTFILE is a directory.
++
++Environment variables override the default commands:
++  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
++  RMPROG STRIPPROG
++"
++
++while test $# -ne 0; do
++  case $1 in
++    -c) ;;
++
++    -C) copy_on_change=true;;
++
++    -d) dir_arg=true;;
++
++    -g) chgrpcmd="$chgrpprog $2"
++	shift;;
++
++    --help) echo "$usage"; exit $?;;
++
++    -m) mode=$2
++	case $mode in
++	  *' '* | *'	'* | *'
++'*	  | *'*'* | *'?'* | *'['*)
++	    echo "$0: invalid mode: $mode" >&2
++	    exit 1;;
++	esac
++	shift;;
++
++    -o) chowncmd="$chownprog $2"
++	shift;;
++
++    -s) stripcmd=$stripprog;;
++
++    -S) stripcmd="$stripprog $2"
++	shift;;
++
++    -t) dst_arg=$2
++	shift;;
++
++    -T) no_target_directory=true;;
++
++    --version) echo "$0 $scriptversion"; exit $?;;
++
++    --)	shift
++	break;;
++
++    -*)	echo "$0: invalid option: $1" >&2
++	exit 1;;
++
++    *)  break;;
++  esac
++  shift
++done
++
++if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
++  # When -d is used, all remaining arguments are directories to create.
++  # When -t is used, the destination is already specified.
++  # Otherwise, the last argument is the destination.  Remove it from $@.
++  for arg
++  do
++    if test -n "$dst_arg"; then
++      # $@ is not empty: it contains at least $arg.
++      set fnord "$@" "$dst_arg"
++      shift # fnord
++    fi
++    shift # arg
++    dst_arg=$arg
++  done
++fi
++
++if test $# -eq 0; then
++  if test -z "$dir_arg"; then
++    echo "$0: no input file specified." >&2
++    exit 1
++  fi
++  # It's OK to call `install-sh -d' without argument.
++  # This can happen when creating conditional directories.
++  exit 0
++fi
++
++if test -z "$dir_arg"; then
++  do_exit='(exit $ret); exit $ret'
++  trap "ret=129; $do_exit" 1
++  trap "ret=130; $do_exit" 2
++  trap "ret=141; $do_exit" 13
++  trap "ret=143; $do_exit" 15
++
++  # Set umask so as not to create temps with too-generous modes.
++  # However, 'strip' requires both read and write access to temps.
++  case $mode in
++    # Optimize common cases.
++    *644) cp_umask=133;;
++    *755) cp_umask=22;;
++
++    *[0-7])
++      if test -z "$stripcmd"; then
++	u_plus_rw=
++      else
++	u_plus_rw='% 200'
++      fi
++      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
++    *)
++      if test -z "$stripcmd"; then
++	u_plus_rw=
++      else
++	u_plus_rw=,u+rw
++      fi
++      cp_umask=$mode$u_plus_rw;;
++  esac
++fi
++
++for src
++do
++  # Protect names starting with `-'.
++  case $src in
++    -*) src=./$src;;
++  esac
++
++  if test -n "$dir_arg"; then
++    dst=$src
++    dstdir=$dst
++    test -d "$dstdir"
++    dstdir_status=$?
++  else
++
++    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
++    # might cause directories to be created, which would be especially bad
++    # if $src (and thus $dsttmp) contains '*'.
++    if test ! -f "$src" && test ! -d "$src"; then
++      echo "$0: $src does not exist." >&2
++      exit 1
++    fi
++
++    if test -z "$dst_arg"; then
++      echo "$0: no destination specified." >&2
++      exit 1
++    fi
++
++    dst=$dst_arg
++    # Protect names starting with `-'.
++    case $dst in
++      -*) dst=./$dst;;
++    esac
++
++    # If destination is a directory, append the input filename; won't work
++    # if double slashes aren't ignored.
++    if test -d "$dst"; then
++      if test -n "$no_target_directory"; then
++	echo "$0: $dst_arg: Is a directory" >&2
++	exit 1
++      fi
++      dstdir=$dst
++      dst=$dstdir/`basename "$src"`
++      dstdir_status=0
++    else
++      # Prefer dirname, but fall back on a substitute if dirname fails.
++      dstdir=`
++	(dirname "$dst") 2>/dev/null ||
++	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++	     X"$dst" : 'X\(//\)[^/]' \| \
++	     X"$dst" : 'X\(//\)$' \| \
++	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
++	echo X"$dst" |
++	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\/\)[^/].*/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\/\)$/{
++		   s//\1/
++		   q
++		 }
++		 /^X\(\/\).*/{
++		   s//\1/
++		   q
++		 }
++		 s/.*/./; q'
++      `
++
++      test -d "$dstdir"
++      dstdir_status=$?
++    fi
++  fi
++
++  obsolete_mkdir_used=false
++
++  if test $dstdir_status != 0; then
++    case $posix_mkdir in
++      '')
++	# Create intermediate dirs using mode 755 as modified by the umask.
++	# This is like FreeBSD 'install' as of 1997-10-28.
++	umask=`umask`
++	case $stripcmd.$umask in
++	  # Optimize common cases.
++	  *[2367][2367]) mkdir_umask=$umask;;
++	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
++
++	  *[0-7])
++	    mkdir_umask=`expr $umask + 22 \
++	      - $umask % 100 % 40 + $umask % 20 \
++	      - $umask % 10 % 4 + $umask % 2
++	    `;;
++	  *) mkdir_umask=$umask,go-w;;
++	esac
++
++	# With -d, create the new directory with the user-specified mode.
++	# Otherwise, rely on $mkdir_umask.
++	if test -n "$dir_arg"; then
++	  mkdir_mode=-m$mode
++	else
++	  mkdir_mode=
++	fi
++
++	posix_mkdir=false
++	case $umask in
++	  *[123567][0-7][0-7])
++	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
++	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
++	    ;;
++	  *)
++	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
++	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
++
++	    if (umask $mkdir_umask &&
++		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
++	    then
++	      if test -z "$dir_arg" || {
++		   # Check for POSIX incompatibilities with -m.
++		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
++		   # other-writeable bit of parent directory when it shouldn't.
++		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
++		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
++		   case $ls_ld_tmpdir in
++		     d????-?r-*) different_mode=700;;
++		     d????-?--*) different_mode=755;;
++		     *) false;;
++		   esac &&
++		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
++		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
++		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
++		   }
++		 }
++	      then posix_mkdir=:
++	      fi
++	      rmdir "$tmpdir/d" "$tmpdir"
++	    else
++	      # Remove any dirs left behind by ancient mkdir implementations.
++	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
++	    fi
++	    trap '' 0;;
++	esac;;
++    esac
++
++    if
++      $posix_mkdir && (
++	umask $mkdir_umask &&
++	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
++      )
++    then :
++    else
++
++      # The umask is ridiculous, or mkdir does not conform to POSIX,
++      # or it failed possibly due to a race condition.  Create the
++      # directory the slow way, step by step, checking for races as we go.
++
++      case $dstdir in
++	/*) prefix='/';;
++	-*) prefix='./';;
++	*)  prefix='';;
++      esac
++
++      eval "$initialize_posix_glob"
++
++      oIFS=$IFS
++      IFS=/
++      $posix_glob set -f
++      set fnord $dstdir
++      shift
++      $posix_glob set +f
++      IFS=$oIFS
++
++      prefixes=
++
++      for d
++      do
++	test -z "$d" && continue
++
++	prefix=$prefix$d
++	if test -d "$prefix"; then
++	  prefixes=
++	else
++	  if $posix_mkdir; then
++	    (umask=$mkdir_umask &&
++	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
++	    # Don't fail if two instances are running concurrently.
++	    test -d "$prefix" || exit 1
++	  else
++	    case $prefix in
++	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
++	      *) qprefix=$prefix;;
++	    esac
++	    prefixes="$prefixes '$qprefix'"
++	  fi
++	fi
++	prefix=$prefix/
++      done
++
++      if test -n "$prefixes"; then
++	# Don't fail if two instances are running concurrently.
++	(umask $mkdir_umask &&
++	 eval "\$doit_exec \$mkdirprog $prefixes") ||
++	  test -d "$dstdir" || exit 1
++	obsolete_mkdir_used=true
++      fi
++    fi
++  fi
++
++  if test -n "$dir_arg"; then
++    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
++    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
++    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
++      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
++  else
++
++    # Make a couple of temp file names in the proper directory.
++    dsttmp=$dstdir/_inst.$$_
++    rmtmp=$dstdir/_rm.$$_
++
++    # Trap to clean up those temp files at exit.
++    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
++
++    # Copy the file name to the temp name.
++    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
++
++    # and set any options; do chmod last to preserve setuid bits.
++    #
++    # If any of these fail, we abort the whole thing.  If we want to
++    # ignore errors from any of these, just make sure not to ignore
++    # errors from the above "$doit $cpprog $src $dsttmp" command.
++    #
++    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
++    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
++    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
++    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
++
++    # If -C, don't bother to copy if it wouldn't change the file.
++    if $copy_on_change &&
++       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
++       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
++
++       eval "$initialize_posix_glob" &&
++       $posix_glob set -f &&
++       set X $old && old=:$2:$4:$5:$6 &&
++       set X $new && new=:$2:$4:$5:$6 &&
++       $posix_glob set +f &&
++
++       test "$old" = "$new" &&
++       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
++    then
++      rm -f "$dsttmp"
++    else
++      # Rename the file to the real destination.
++      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
++
++      # The rename failed, perhaps because mv can't rename something else
++      # to itself, or perhaps because mv is so ancient that it does not
++      # support -f.
++      {
++	# Now remove or move aside any old file at destination location.
++	# We try this two ways since rm can't unlink itself on some
++	# systems and the destination file might be busy for other
++	# reasons.  In this case, the final cleanup might fail but the new
++	# file should still install successfully.
++	{
++	  test ! -f "$dst" ||
++	  $doit $rmcmd -f "$dst" 2>/dev/null ||
++	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
++	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
++	  } ||
++	  { echo "$0: cannot unlink or rename $dst" >&2
++	    (exit 1); exit 1
++	  }
++	} &&
++
++	# Now rename the file to the real destination.
++	$doit $mvcmd "$dsttmp" "$dst"
++      }
++    fi || exit 1
++
++    trap '' 0
++  fi
++done
++
++# Local variables:
++# eval: (add-hook 'write-file-hooks 'time-stamp)
++# time-stamp-start: "scriptversion="
++# time-stamp-format: "%:y-%02m-%02d.%02H"
++# time-stamp-time-zone: "UTC"
++# time-stamp-end: "; # UTC"
++# End:
+--- contrib/sqlite3/tea/tclconfig/tcl.m4.orig
++++ contrib/sqlite3/tea/tclconfig/tcl.m4
+@@ -0,0 +1,4168 @@
++# tcl.m4 --
++#
++#	This file provides a set of autoconf macros to help TEA-enable
++#	a Tcl extension.
++#
++# Copyright (c) 1999-2000 Ajuba Solutions.
++# Copyright (c) 2002-2005 ActiveState Corporation.
++#
++# See the file "license.terms" for information on usage and redistribution
++# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
++
++AC_PREREQ(2.57)
++
++dnl TEA extensions pass us the version of TEA they think they
++dnl are compatible with (must be set in TEA_INIT below)
++dnl TEA_VERSION="3.9"
++
++# Possible values for key variables defined:
++#
++# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
++# TEA_PLATFORM        - windows unix
++#
++
++#------------------------------------------------------------------------
++# TEA_PATH_TCLCONFIG --
++#
++#	Locate the tclConfig.sh file and perform a sanity check on
++#	the Tcl compile flags
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--with-tcl=...
++#
++#	Defines the following vars:
++#		TCL_BIN_DIR	Full path to the directory containing
++#				the tclConfig.sh file
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PATH_TCLCONFIG], [
++    dnl TEA specific: Make sure we are initialized
++    AC_REQUIRE([TEA_INIT])
++    #
++    # Ok, lets find the tcl configuration
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-tcl
++    #
++
++    if test x"${no_tcl}" = x ; then
++	# we reset no_tcl in case something fails here
++	no_tcl=true
++	AC_ARG_WITH(tcl,
++	    AC_HELP_STRING([--with-tcl],
++		[directory containing tcl configuration (tclConfig.sh)]),
++	    with_tclconfig="${withval}")
++	AC_MSG_CHECKING([for Tcl configuration])
++	AC_CACHE_VAL(ac_cv_c_tclconfig,[
++
++	    # First check to see if --with-tcl was specified.
++	    if test x"${with_tclconfig}" != x ; then
++		case "${with_tclconfig}" in
++		    */tclConfig.sh )
++			if test -f "${with_tclconfig}"; then
++			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
++			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
++			fi ;;
++		esac
++		if test -f "${with_tclconfig}/tclConfig.sh" ; then
++		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
++		else
++		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
++		fi
++	    fi
++
++	    # then check for a private Tcl installation
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in \
++			../tcl \
++			`ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
++			../../tcl \
++			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
++			../../../tcl \
++			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # on Darwin, check in Framework installation locations
++	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
++			`ls -d /Library/Frameworks 2>/dev/null` \
++			`ls -d /Network/Library/Frameworks 2>/dev/null` \
++			`ls -d /System/Library/Frameworks 2>/dev/null` \
++			; do
++		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # TEA specific: on Windows, check in common installation locations
++	    if test "${TEA_PLATFORM}" = "windows" \
++		-a x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
++			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
++			; do
++		    if test -f "$i/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few common install locations
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in `ls -d ${libdir} 2>/dev/null` \
++			`ls -d ${exec_prefix}/lib 2>/dev/null` \
++			`ls -d ${prefix}/lib 2>/dev/null` \
++			`ls -d /usr/local/lib 2>/dev/null` \
++			`ls -d /usr/contrib/lib 2>/dev/null` \
++			`ls -d /usr/lib 2>/dev/null` \
++			`ls -d /usr/lib64 2>/dev/null` \
++			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
++			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
++			; do
++		    if test -f "$i/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few other private locations
++	    if test x"${ac_cv_c_tclconfig}" = x ; then
++		for i in \
++			${srcdir}/../tcl \
++			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tclConfig.sh" ; then
++			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++	])
++
++	if test x"${ac_cv_c_tclconfig}" = x ; then
++	    TCL_BIN_DIR="# no Tcl configs found"
++	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])
++	else
++	    no_tcl=
++	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
++	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
++	fi
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_PATH_TKCONFIG --
++#
++#	Locate the tkConfig.sh file
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--with-tk=...
++#
++#	Defines the following vars:
++#		TK_BIN_DIR	Full path to the directory containing
++#				the tkConfig.sh file
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PATH_TKCONFIG], [
++    #
++    # Ok, lets find the tk configuration
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-tk
++    #
++
++    if test x"${no_tk}" = x ; then
++	# we reset no_tk in case something fails here
++	no_tk=true
++	AC_ARG_WITH(tk,
++	    AC_HELP_STRING([--with-tk],
++		[directory containing tk configuration (tkConfig.sh)]),
++	    with_tkconfig="${withval}")
++	AC_MSG_CHECKING([for Tk configuration])
++	AC_CACHE_VAL(ac_cv_c_tkconfig,[
++
++	    # First check to see if --with-tkconfig was specified.
++	    if test x"${with_tkconfig}" != x ; then
++		case "${with_tkconfig}" in
++		    */tkConfig.sh )
++			if test -f "${with_tkconfig}"; then
++			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
++			    with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
++			fi ;;
++		esac
++		if test -f "${with_tkconfig}/tkConfig.sh" ; then
++		    ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
++		else
++		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
++		fi
++	    fi
++
++	    # then check for a private Tk library
++	    if test x"${ac_cv_c_tkconfig}" = x ; then
++		for i in \
++			../tk \
++			`ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \
++			../../tk \
++			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
++			../../../tk \
++			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # on Darwin, check in Framework installation locations
++	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
++		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
++			`ls -d /Library/Frameworks 2>/dev/null` \
++			`ls -d /Network/Library/Frameworks 2>/dev/null` \
++			`ls -d /System/Library/Frameworks 2>/dev/null` \
++			; do
++		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few common install locations
++	    if test x"${ac_cv_c_tkconfig}" = x ; then
++		for i in `ls -d ${libdir} 2>/dev/null` \
++			`ls -d ${exec_prefix}/lib 2>/dev/null` \
++			`ls -d ${prefix}/lib 2>/dev/null` \
++			`ls -d /usr/local/lib 2>/dev/null` \
++			`ls -d /usr/contrib/lib 2>/dev/null` \
++			`ls -d /usr/lib 2>/dev/null` \
++			`ls -d /usr/lib64 2>/dev/null` \
++			; do
++		    if test -f "$i/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # TEA specific: on Windows, check in common installation locations
++	    if test "${TEA_PLATFORM}" = "windows" \
++		-a x"${ac_cv_c_tkconfig}" = x ; then
++		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
++			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
++			; do
++		    if test -f "$i/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i; pwd)`"
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few other private locations
++	    if test x"${ac_cv_c_tkconfig}" = x ; then
++		for i in \
++			${srcdir}/../tk \
++			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
++			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
++		    if test "${TEA_PLATFORM}" = "windows" \
++			    -a -f "$i/win/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
++			break
++		    fi
++		    if test -f "$i/unix/tkConfig.sh" ; then
++			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
++			break
++		    fi
++		done
++	    fi
++	])
++
++	if test x"${ac_cv_c_tkconfig}" = x ; then
++	    TK_BIN_DIR="# no Tk configs found"
++	    AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])
++	else
++	    no_tk=
++	    TK_BIN_DIR="${ac_cv_c_tkconfig}"
++	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
++	fi
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_LOAD_TCLCONFIG --
++#
++#	Load the tclConfig.sh file
++#
++# Arguments:
++#
++#	Requires the following vars to be set:
++#		TCL_BIN_DIR
++#
++# Results:
++#
++#	Substitutes the following vars:
++#		TCL_BIN_DIR
++#		TCL_SRC_DIR
++#		TCL_LIB_FILE
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_LOAD_TCLCONFIG], [
++    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
++
++    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
++        AC_MSG_RESULT([loading])
++	. "${TCL_BIN_DIR}/tclConfig.sh"
++    else
++        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
++    fi
++
++    # eval is required to do the TCL_DBGX substitution
++    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
++    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
++
++    # If the TCL_BIN_DIR is the build directory (not the install directory),
++    # then set the common variable name to the value of the build variables.
++    # For example, the variable TCL_LIB_SPEC will be set to the value
++    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
++    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
++    # installed and uninstalled version of Tcl.
++    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
++        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
++        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
++    elif test "`uname -s`" = "Darwin"; then
++	# If Tcl was built as a framework, attempt to use the libraries
++	# from the framework at the given location so that linking works
++	# against Tcl.framework installed in an arbitrary location.
++	case ${TCL_DEFS} in
++	    *TCL_FRAMEWORK*)
++		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
++		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
++			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
++			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
++			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
++			    break
++			fi
++		    done
++		fi
++		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
++		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
++		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
++		fi
++		;;
++	esac
++    fi
++
++    # eval is required to do the TCL_DBGX substitution
++    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
++    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
++    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
++    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""
++
++    AC_SUBST(TCL_VERSION)
++    AC_SUBST(TCL_PATCH_LEVEL)
++    AC_SUBST(TCL_BIN_DIR)
++    AC_SUBST(TCL_SRC_DIR)
++
++    AC_SUBST(TCL_LIB_FILE)
++    AC_SUBST(TCL_LIB_FLAG)
++    AC_SUBST(TCL_LIB_SPEC)
++
++    AC_SUBST(TCL_STUB_LIB_FILE)
++    AC_SUBST(TCL_STUB_LIB_FLAG)
++    AC_SUBST(TCL_STUB_LIB_SPEC)
++
++    AC_MSG_CHECKING([platform])
++    hold_cc=$CC; CC="$TCL_CC"
++    AC_TRY_COMPILE(,[
++	    #ifdef _WIN32
++		#error win32
++	    #endif
++    ], TEA_PLATFORM="unix",
++	    TEA_PLATFORM="windows"
++    )
++    CC=$hold_cc
++    AC_MSG_RESULT($TEA_PLATFORM)
++
++    # The BUILD_$pkg is to define the correct extern storage class
++    # handling when making this package
++    AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
++	    [Building extension source?])
++    # Do this here as we have fully defined TEA_PLATFORM now
++    if test "${TEA_PLATFORM}" = "windows" ; then
++	EXEEXT=".exe"
++	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
++    fi
++
++    # TEA specific:
++    AC_SUBST(CLEANFILES)
++    AC_SUBST(TCL_LIBS)
++    AC_SUBST(TCL_DEFS)
++    AC_SUBST(TCL_EXTRA_CFLAGS)
++    AC_SUBST(TCL_LD_FLAGS)
++    AC_SUBST(TCL_SHLIB_LD_LIBS)
++])
++
++#------------------------------------------------------------------------
++# TEA_LOAD_TKCONFIG --
++#
++#	Load the tkConfig.sh file
++#
++# Arguments:
++#
++#	Requires the following vars to be set:
++#		TK_BIN_DIR
++#
++# Results:
++#
++#	Sets the following vars that should be in tkConfig.sh:
++#		TK_BIN_DIR
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_LOAD_TKCONFIG], [
++    AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
++
++    if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
++        AC_MSG_RESULT([loading])
++	. "${TK_BIN_DIR}/tkConfig.sh"
++    else
++        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
++    fi
++
++    # eval is required to do the TK_DBGX substitution
++    eval "TK_LIB_FILE=\"${TK_LIB_FILE}\""
++    eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\""
++
++    # If the TK_BIN_DIR is the build directory (not the install directory),
++    # then set the common variable name to the value of the build variables.
++    # For example, the variable TK_LIB_SPEC will be set to the value
++    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
++    # instead of TK_BUILD_LIB_SPEC since it will work with both an
++    # installed and uninstalled version of Tcl.
++    if test -f "${TK_BIN_DIR}/Makefile" ; then
++        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
++        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
++        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
++    elif test "`uname -s`" = "Darwin"; then
++	# If Tk was built as a framework, attempt to use the libraries
++	# from the framework at the given location so that linking works
++	# against Tk.framework installed in an arbitrary location.
++	case ${TK_DEFS} in
++	    *TK_FRAMEWORK*)
++		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
++		    for i in "`cd "${TK_BIN_DIR}"; pwd`" \
++			     "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
++			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
++			    TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
++			    break
++			fi
++		    done
++		fi
++		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
++		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
++		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
++		fi
++		;;
++	esac
++    fi
++
++    # eval is required to do the TK_DBGX substitution
++    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
++    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
++    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
++    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""
++
++    # TEA specific: Ensure windowingsystem is defined
++    if test "${TEA_PLATFORM}" = "unix" ; then
++	case ${TK_DEFS} in
++	    *MAC_OSX_TK*)
++		AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
++		TEA_WINDOWINGSYSTEM="aqua"
++		;;
++	    *)
++		TEA_WINDOWINGSYSTEM="x11"
++		;;
++	esac
++    elif test "${TEA_PLATFORM}" = "windows" ; then
++	TEA_WINDOWINGSYSTEM="win32"
++    fi
++
++    AC_SUBST(TK_VERSION)
++    AC_SUBST(TK_BIN_DIR)
++    AC_SUBST(TK_SRC_DIR)
++
++    AC_SUBST(TK_LIB_FILE)
++    AC_SUBST(TK_LIB_FLAG)
++    AC_SUBST(TK_LIB_SPEC)
++
++    AC_SUBST(TK_STUB_LIB_FILE)
++    AC_SUBST(TK_STUB_LIB_FLAG)
++    AC_SUBST(TK_STUB_LIB_SPEC)
++
++    # TEA specific:
++    AC_SUBST(TK_LIBS)
++    AC_SUBST(TK_XINCLUDES)
++])
++
++#------------------------------------------------------------------------
++# TEA_PROG_TCLSH
++#	Determine the fully qualified path name of the tclsh executable
++#	in the Tcl build directory or the tclsh installed in a bin
++#	directory. This macro will correctly determine the name
++#	of the tclsh executable even if tclsh has not yet been
++#	built in the build directory. The tclsh found is always
++#	associated with a tclConfig.sh file. This tclsh should be used
++#	only for running extension test cases. It should never be
++#	or generation of files (like pkgIndex.tcl) at build time.
++#
++# Arguments:
++#	none
++#
++# Results:
++#	Substitutes the following vars:
++#		TCLSH_PROG
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PROG_TCLSH], [
++    AC_MSG_CHECKING([for tclsh])
++    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++        # tclConfig.sh is in Tcl build directory
++        if test "${TEA_PLATFORM}" = "windows"; then
++            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
++        else
++            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
++        fi
++    else
++        # tclConfig.sh is in install location
++        if test "${TEA_PLATFORM}" = "windows"; then
++            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
++        else
++            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
++        fi
++        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
++              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
++              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
++        for i in $list ; do
++            if test -f "$i/${TCLSH_PROG}" ; then
++                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
++                break
++            fi
++        done
++        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
++    fi
++    AC_MSG_RESULT([${TCLSH_PROG}])
++    AC_SUBST(TCLSH_PROG)
++])
++
++#------------------------------------------------------------------------
++# TEA_PROG_WISH
++#	Determine the fully qualified path name of the wish executable
++#	in the Tk build directory or the wish installed in a bin
++#	directory. This macro will correctly determine the name
++#	of the wish executable even if wish has not yet been
++#	built in the build directory. The wish found is always
++#	associated with a tkConfig.sh file. This wish should be used
++#	only for running extension test cases. It should never be
++#	or generation of files (like pkgIndex.tcl) at build time.
++#
++# Arguments:
++#	none
++#
++# Results:
++#	Substitutes the following vars:
++#		WISH_PROG
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PROG_WISH], [
++    AC_MSG_CHECKING([for wish])
++    if test -f "${TK_BIN_DIR}/Makefile" ; then
++        # tkConfig.sh is in Tk build directory
++        if test "${TEA_PLATFORM}" = "windows"; then
++            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
++        else
++            WISH_PROG="${TK_BIN_DIR}/wish"
++        fi
++    else
++        # tkConfig.sh is in install location
++        if test "${TEA_PLATFORM}" = "windows"; then
++            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
++        else
++            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
++        fi
++        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
++              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
++              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
++        for i in $list ; do
++            if test -f "$i/${WISH_PROG}" ; then
++                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
++                break
++            fi
++        done
++        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
++    fi
++    AC_MSG_RESULT([${WISH_PROG}])
++    AC_SUBST(WISH_PROG)
++])
++
++#------------------------------------------------------------------------
++# TEA_ENABLE_SHARED --
++#
++#	Allows the building of shared libraries
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--enable-shared=yes|no
++#
++#	Defines the following vars:
++#		STATIC_BUILD	Used for building import/export libraries
++#				on Windows.
++#
++#	Sets the following vars:
++#		SHARED_BUILD	Value of 1 or 0
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_ENABLE_SHARED], [
++    AC_MSG_CHECKING([how to build libraries])
++    AC_ARG_ENABLE(shared,
++	AC_HELP_STRING([--enable-shared],
++	    [build and link with shared libraries (default: on)]),
++	[tcl_ok=$enableval], [tcl_ok=yes])
++
++    if test "${enable_shared+set}" = set; then
++	enableval="$enable_shared"
++	tcl_ok=$enableval
++    else
++	tcl_ok=yes
++    fi
++
++    if test "$tcl_ok" = "yes" ; then
++	AC_MSG_RESULT([shared])
++	SHARED_BUILD=1
++    else
++	AC_MSG_RESULT([static])
++	SHARED_BUILD=0
++	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])
++    fi
++    AC_SUBST(SHARED_BUILD)
++])
++
++#------------------------------------------------------------------------
++# TEA_ENABLE_THREADS --
++#
++#	Specify if thread support should be enabled.  If "yes" is specified
++#	as an arg (optional), threads are enabled by default, "no" means
++#	threads are disabled.  "yes" is the default.
++#
++#	TCL_THREADS is checked so that if you are compiling an extension
++#	against a threaded core, your extension must be compiled threaded
++#	as well.
++#
++#	Note that it is legal to have a thread enabled extension run in a
++#	threaded or non-threaded Tcl core, but a non-threaded extension may
++#	only run in a non-threaded Tcl core.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--enable-threads
++#
++#	Sets the following vars:
++#		THREADS_LIBS	Thread library(s)
++#
++#	Defines the following vars:
++#		TCL_THREADS
++#		_REENTRANT
++#		_THREAD_SAFE
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_ENABLE_THREADS], [
++    AC_ARG_ENABLE(threads,
++	AC_HELP_STRING([--enable-threads],
++	    [build with threads]),
++	[tcl_ok=$enableval], [tcl_ok=yes])
++
++    if test "${enable_threads+set}" = set; then
++	enableval="$enable_threads"
++	tcl_ok=$enableval
++    else
++	tcl_ok=yes
++    fi
++
++    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
++	TCL_THREADS=1
++
++	if test "${TEA_PLATFORM}" != "windows" ; then
++	    # We are always OK on Windows, so check what this platform wants:
++
++	    # USE_THREAD_ALLOC tells us to try the special thread-based
++	    # allocator that significantly reduces lock contention
++	    AC_DEFINE(USE_THREAD_ALLOC, 1,
++		[Do we want to use the threaded memory allocator?])
++	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
++	    if test "`uname -s`" = "SunOS" ; then
++		AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
++			[Do we really want to follow the standard? Yes we do!])
++	    fi
++	    AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?])
++	    AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no)
++	    if test "$tcl_ok" = "no"; then
++		# Check a little harder for __pthread_mutex_init in the same
++		# library, as some systems hide it there until pthread.h is
++		# defined.  We could alternatively do an AC_TRY_COMPILE with
++		# pthread.h, but that will work with libpthread really doesn't
++		# exist, like AIX 4.2.  [Bug: 4359]
++		AC_CHECK_LIB(pthread, __pthread_mutex_init,
++		    tcl_ok=yes, tcl_ok=no)
++	    fi
++
++	    if test "$tcl_ok" = "yes"; then
++		# The space is needed
++		THREADS_LIBS=" -lpthread"
++	    else
++		AC_CHECK_LIB(pthreads, pthread_mutex_init,
++		    tcl_ok=yes, tcl_ok=no)
++		if test "$tcl_ok" = "yes"; then
++		    # The space is needed
++		    THREADS_LIBS=" -lpthreads"
++		else
++		    AC_CHECK_LIB(c, pthread_mutex_init,
++			tcl_ok=yes, tcl_ok=no)
++		    if test "$tcl_ok" = "no"; then
++			AC_CHECK_LIB(c_r, pthread_mutex_init,
++			    tcl_ok=yes, tcl_ok=no)
++			if test "$tcl_ok" = "yes"; then
++			    # The space is needed
++			    THREADS_LIBS=" -pthread"
++			else
++			    TCL_THREADS=0
++			    AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled])
++			fi
++		    fi
++		fi
++	    fi
++	fi
++    else
++	TCL_THREADS=0
++    fi
++    # Do checking message here to not mess up interleaved configure output
++    AC_MSG_CHECKING([for building with threads])
++    if test "${TCL_THREADS}" = 1; then
++	AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?])
++	AC_MSG_RESULT([yes (default)])
++    else
++	AC_MSG_RESULT([no])
++    fi
++    # TCL_THREADS sanity checking.  See if our request for building with
++    # threads is the same as the way Tcl was built.  If not, warn the user.
++    case ${TCL_DEFS} in
++	*THREADS=1*)
++	    if test "${TCL_THREADS}" = "0"; then
++		AC_MSG_WARN([
++    Building ${PACKAGE_NAME} without threads enabled, but building against Tcl
++    that IS thread-enabled.  It is recommended to use --enable-threads.])
++	    fi
++	    ;;
++	*)
++	    if test "${TCL_THREADS}" = "1"; then
++		AC_MSG_WARN([
++    --enable-threads requested, but building against a Tcl that is NOT
++    thread-enabled.  This is an OK configuration that will also run in
++    a thread-enabled core.])
++	    fi
++	    ;;
++    esac
++    AC_SUBST(TCL_THREADS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ENABLE_SYMBOLS --
++#
++#	Specify if debugging symbols should be used.
++#	Memory (TCL_MEM_DEBUG) debugging can also be enabled.
++#
++# Arguments:
++#	none
++#
++#	TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
++#	the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
++#	Requires the following vars to be set in the Makefile:
++#		CFLAGS_DEFAULT
++#		LDFLAGS_DEFAULT
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--enable-symbols
++#
++#	Defines the following vars:
++#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
++#				Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
++#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
++#				Sets to $(LDFLAGS_OPTIMIZE) if false
++#		DBGX		Formerly used as debug library extension;
++#				always blank now.
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_ENABLE_SYMBOLS], [
++    dnl TEA specific: Make sure we are initialized
++    AC_REQUIRE([TEA_CONFIG_CFLAGS])
++    AC_MSG_CHECKING([for build with symbols])
++    AC_ARG_ENABLE(symbols,
++	AC_HELP_STRING([--enable-symbols],
++	    [build with debugging symbols (default: off)]),
++	[tcl_ok=$enableval], [tcl_ok=no])
++    DBGX=""
++    if test "$tcl_ok" = "no"; then
++	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
++	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
++	AC_MSG_RESULT([no])
++    else
++	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
++	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
++	if test "$tcl_ok" = "yes"; then
++	    AC_MSG_RESULT([yes (standard debugging)])
++	fi
++    fi
++    # TEA specific:
++    if test "${TEA_PLATFORM}" != "windows" ; then
++	LDFLAGS_DEFAULT="${LDFLAGS}"
++    fi
++    AC_SUBST(CFLAGS_DEFAULT)
++    AC_SUBST(LDFLAGS_DEFAULT)
++    AC_SUBST(TCL_DBGX)
++
++    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
++	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
++    fi
++
++    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
++	if test "$tcl_ok" = "all"; then
++	    AC_MSG_RESULT([enabled symbols mem debugging])
++	else
++	    AC_MSG_RESULT([enabled $tcl_ok debugging])
++	fi
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_ENABLE_LANGINFO --
++#
++#	Allows use of modern nl_langinfo check for better l10n.
++#	This is only relevant for Unix.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--enable-langinfo=yes|no (default is yes)
++#
++#	Defines the following vars:
++#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_ENABLE_LANGINFO], [
++    AC_ARG_ENABLE(langinfo,
++	AC_HELP_STRING([--enable-langinfo],
++	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
++	[langinfo_ok=$enableval], [langinfo_ok=yes])
++
++    HAVE_LANGINFO=0
++    if test "$langinfo_ok" = "yes"; then
++	AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no])
++    fi
++    AC_MSG_CHECKING([whether to use nl_langinfo])
++    if test "$langinfo_ok" = "yes"; then
++	AC_CACHE_VAL(tcl_cv_langinfo_h, [
++	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
++		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
++	AC_MSG_RESULT([$tcl_cv_langinfo_h])
++	if test $tcl_cv_langinfo_h = yes; then
++	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
++	fi
++    else
++	AC_MSG_RESULT([$langinfo_ok])
++    fi
++])
++
++#--------------------------------------------------------------------
++# TEA_CONFIG_SYSTEM
++#
++#	Determine what the system is (some things cannot be easily checked
++#	on a feature-driven basis, alas). This can usually be done via the
++#	"uname" command.
++#
++# Arguments:
++#	none
++#
++# Results:
++#	Defines the following var:
++#
++#	system -	System/platform/version identification code.
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_CONFIG_SYSTEM], [
++    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
++	# TEA specific:
++	if test "${TEA_PLATFORM}" = "windows" ; then
++	    tcl_cv_sys_version=windows
++	else
++	    tcl_cv_sys_version=`uname -s`-`uname -r`
++	    if test "$?" -ne 0 ; then
++		AC_MSG_WARN([can't find uname command])
++		tcl_cv_sys_version=unknown
++	    else
++		if test "`uname -s`" = "AIX" ; then
++		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
++		fi
++	    fi
++	fi
++    ])
++    system=$tcl_cv_sys_version
++])
++
++#--------------------------------------------------------------------
++# TEA_CONFIG_CFLAGS
++#
++#	Try to determine the proper flags to pass to the compiler
++#	for building shared libraries and other such nonsense.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines and substitutes the following vars:
++#
++#	DL_OBJS, DL_LIBS - removed for TEA, only needed by core.
++#       LDFLAGS -      Flags to pass to the compiler when linking object
++#                       files into an executable application binary such
++#                       as tclsh.
++#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
++#                       that tell the run-time dynamic linker where to look
++#                       for shared libraries such as libtcl.so.  Depends on
++#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
++#                       be the same as CC_SEARCH_FLAGS if ${CC} is used to link.
++#       CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib",
++#                       that tell the run-time dynamic linker where to look
++#                       for shared libraries such as libtcl.so.  Depends on
++#                       the variable LIB_RUNTIME_DIR in the Makefile.
++#       SHLIB_CFLAGS -  Flags to pass to cc when compiling the components
++#                       of a shared library (may request position-independent
++#                       code, among other things).
++#       SHLIB_LD -      Base command to use for combining object files
++#                       into a shared library.
++#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
++#                       creating shared libraries.  This symbol typically
++#                       goes at the end of the "ld" commands that build
++#                       shared libraries. The value of the symbol defaults to
++#                       "${LIBS}" if all of the dependent libraries should
++#                       be specified when creating a shared library.  If
++#                       dependent libraries should not be specified (as on
++#                       SunOS 4.x, where they cause the link to fail, or in
++#                       general if Tcl and Tk aren't themselves shared
++#                       libraries), then this symbol has an empty string
++#                       as its value.
++#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
++#                       extensions.  An empty string means we don't know how
++#                       to use shared libraries on this platform.
++#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
++#                       in a static or shared library name, using the $PACKAGE_VERSION variable
++#                       to put the version in the right place.  This is used
++#                       by platforms that need non-standard library names.
++#                       Examples:  ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
++#                       to have a version after the .so, and ${PACKAGE_VERSION}.a
++#                       on AIX, since a shared library needs to have
++#                       a .a extension whereas shared objects for loadable
++#                       extensions have a .so extension.  Defaults to
++#                       ${PACKAGE_VERSION}${SHLIB_SUFFIX}.
++#	CFLAGS_DEBUG -
++#			Flags used when running the compiler in debug mode
++#	CFLAGS_OPTIMIZE -
++#			Flags used when running the compiler in optimize mode
++#	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_CONFIG_CFLAGS], [
++    dnl TEA specific: Make sure we are initialized
++    AC_REQUIRE([TEA_INIT])
++
++    # Step 0.a: Enable 64 bit support?
++
++    AC_MSG_CHECKING([if 64bit support is requested])
++    AC_ARG_ENABLE(64bit,
++	AC_HELP_STRING([--enable-64bit],
++	    [enable 64bit support (default: off)]),
++	[do64bit=$enableval], [do64bit=no])
++    AC_MSG_RESULT([$do64bit])
++
++    # Step 0.b: Enable Solaris 64 bit VIS support?
++
++    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
++    AC_ARG_ENABLE(64bit-vis,
++	AC_HELP_STRING([--enable-64bit-vis],
++	    [enable 64bit Sparc VIS support (default: off)]),
++	[do64bitVIS=$enableval], [do64bitVIS=no])
++    AC_MSG_RESULT([$do64bitVIS])
++    # Force 64bit on with VIS
++    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])
++
++    # Step 0.c: Check if visibility support is available. Do this here so
++    # that platform specific alternatives can be used below if this fails.
++
++    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
++	tcl_cv_cc_visibility_hidden, [
++	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
++	AC_TRY_LINK([
++	    extern __attribute__((__visibility__("hidden"))) void f(void);
++	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
++	    tcl_cv_cc_visibility_hidden=no)
++	CFLAGS=$hold_cflags])
++    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
++	AC_DEFINE(MODULE_SCOPE,
++	    [extern __attribute__((__visibility__("hidden")))],
++	    [Compiler support for module scope symbols])
++	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
++    ])
++
++    # Step 0.d: Disable -rpath support?
++
++    AC_MSG_CHECKING([if rpath support is requested])
++    AC_ARG_ENABLE(rpath,
++	AC_HELP_STRING([--disable-rpath],
++	    [disable rpath support (default: on)]),
++	[doRpath=$enableval], [doRpath=yes])
++    AC_MSG_RESULT([$doRpath])
++
++    # TEA specific: Cross-compiling options for Windows/CE builds?
++
++    AS_IF([test "${TEA_PLATFORM}" = windows], [
++	AC_MSG_CHECKING([if Windows/CE build is requested])
++	AC_ARG_ENABLE(wince,
++	    AC_HELP_STRING([--enable-wince],
++		[enable Win/CE support (where applicable)]),
++	    [doWince=$enableval], [doWince=no])
++	AC_MSG_RESULT([$doWince])
++    ])
++
++    # Set the variable "system" to hold the name and version number
++    # for the system.
++
++    TEA_CONFIG_SYSTEM
++
++    # Require ranlib early so we can override it in special cases below.
++
++    AC_REQUIRE([AC_PROG_RANLIB])
++
++    # Set configuration options based on system name and version.
++    # This is similar to Tcl's unix/tcl.m4 except that we've added a
++    # "windows" case and removed some core-only vars.
++
++    do64bit_ok=no
++    # default to '{$LIBS}' and set to "" on per-platform necessary basis
++    SHLIB_LD_LIBS='${LIBS}'
++    # When ld needs options to work in 64-bit mode, put them in
++    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
++    # is disabled by the user. [Bug 1016796]
++    LDFLAGS_ARCH=""
++    UNSHARED_LIB_SUFFIX=""
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
++    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
++    TCL_LIB_VERSIONS_OK=ok
++    CFLAGS_DEBUG=-g
++    AS_IF([test "$GCC" = yes], [
++	CFLAGS_OPTIMIZE=-O2
++	CFLAGS_WARNING="-Wall"
++    ], [
++	CFLAGS_OPTIMIZE=-O
++	CFLAGS_WARNING=""
++    ])
++    AC_CHECK_TOOL(AR, ar)
++    STLIB_LD='${AR} cr'
++    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
++    AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"])
++    case $system in
++	# TEA specific:
++	windows)
++	    # This is a 2-stage check to make sure we have the 64-bit SDK
++	    # We have to know where the SDK is installed.
++	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
++	    # MACHINE is IX86 for LINK, but this is used by the manifest,
++	    # which requires x86|amd64|ia64.
++	    MACHINE="X86"
++	    if test "$do64bit" != "no" ; then
++		if test "x${MSSDK}x" = "xx" ; then
++		    MSSDK="C:/Progra~1/Microsoft Platform SDK"
++		fi
++		MSSDK=`echo "$MSSDK" | sed -e  's!\\\!/!g'`
++		PATH64=""
++		case "$do64bit" in
++		    amd64|x64|yes)
++			MACHINE="AMD64" ; # default to AMD64 64-bit build
++			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
++			;;
++		    ia64)
++			MACHINE="IA64"
++			PATH64="${MSSDK}/Bin/Win64"
++			;;
++		esac
++		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
++		    AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
++		    AC_MSG_WARN([Ensure latest Platform SDK is installed])
++		    do64bit="no"
++		else
++		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
++		    do64bit_ok="yes"
++		fi
++	    fi
++
++	    if test "$doWince" != "no" ; then
++		if test "$do64bit" != "no" ; then
++		    AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible])
++		fi
++		if test "$GCC" = "yes" ; then
++		    AC_MSG_ERROR([Windows/CE and GCC builds incompatible])
++		fi
++		TEA_PATH_CELIB
++		# Set defaults for common evc4/PPC2003 setup
++		# Currently Tcl requires 300+, possibly 420+ for sockets
++		CEVERSION=420; 		# could be 211 300 301 400 420 ...
++		TARGETCPU=ARMV4;	# could be ARMV4 ARM MIPS SH3 X86 ...
++		ARCH=ARM;		# could be ARM MIPS X86EM ...
++		PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002"
++		if test "$doWince" != "yes"; then
++		    # If !yes then the user specified something
++		    # Reset ARCH to allow user to skip specifying it
++		    ARCH=
++		    eval `echo $doWince | awk -F, '{ \
++	    if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \
++	    if ([$]1 < 400)   { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \
++	    if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \
++	    if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \
++	    if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \
++		    }'`
++		    if test "x${ARCH}" = "x" ; then
++			ARCH=$TARGETCPU;
++		    fi
++		fi
++		OSVERSION=WCE$CEVERSION;
++	    	if test "x${WCEROOT}" = "x" ; then
++			WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0"
++		    if test ! -d "${WCEROOT}" ; then
++			WCEROOT="C:/Program Files/Microsoft eMbedded Tools"
++		    fi
++		fi
++		if test "x${SDKROOT}" = "x" ; then
++		    SDKROOT="C:/Program Files/Windows CE Tools"
++		    if test ! -d "${SDKROOT}" ; then
++			SDKROOT="C:/Windows CE Tools"
++		    fi
++		fi
++		WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'`
++		SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'`
++		if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \
++		    -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then
++		    AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]])
++		    doWince="no"
++		else
++		    # We could PATH_NOSPACE these, but that's not important,
++		    # as long as we quote them when used.
++		    CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include"
++		    if test -d "${CEINCLUDE}/${TARGETCPU}" ; then
++			CEINCLUDE="${CEINCLUDE}/${TARGETCPU}"
++		    fi
++		    CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"
++    		fi
++	    fi
++
++	    if test "$GCC" != "yes" ; then
++	        if test "${SHARED_BUILD}" = "0" ; then
++		    runtime=-MT
++	        else
++		    runtime=-MD
++	        fi
++
++                if test "$do64bit" != "no" ; then
++		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
++		    CC="\"${PATH64}/cl.exe\""
++		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
++		    RC="\"${MSSDK}/bin/rc.exe\""
++		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
++		    LINKBIN="\"${PATH64}/link.exe\""
++		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
++		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
++		    # Avoid 'unresolved external symbol __security_cookie'
++		    # errors, c.f. http://support.microsoft.com/?id=894573
++		    TEA_ADD_LIBS([bufferoverflowU.lib])
++		elif test "$doWince" != "no" ; then
++		    CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin"
++		    if test "${TARGETCPU}" = "X86"; then
++			CC="\"${CEBINROOT}/cl.exe\""
++		    else
++			CC="\"${CEBINROOT}/cl${ARCH}.exe\""
++		    fi
++		    CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\""
++		    RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\""
++		    arch=`echo ${ARCH} | awk '{print tolower([$]0)}'`
++		    defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS"
++		    if test "${SHARED_BUILD}" = "1" ; then
++			# Static CE builds require static celib as well
++		    	defs="${defs} _DLL"
++		    fi
++		    for i in $defs ; do
++			AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
++		    done
++		    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
++		    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
++		    CFLAGS_DEBUG="-nologo -Zi -Od"
++		    CFLAGS_OPTIMIZE="-nologo -Ox"
++		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
++		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
++		    LINKBIN="\"${CEBINROOT}/link.exe\""
++		    AC_SUBST(CELIB_DIR)
++		else
++		    RC="rc"
++		    lflags="-nologo"
++		    LINKBIN="link"
++		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
++		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
++		fi
++	    fi
++
++	    if test "$GCC" = "yes"; then
++		# mingw gcc mode
++		AC_CHECK_TOOL(RC, windres)
++		CFLAGS_DEBUG="-g"
++		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
++		SHLIB_LD='${CC} -shared'
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
++		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
++
++		AC_CACHE_CHECK(for cross-compile version of gcc,
++			ac_cv_cross,
++			AC_TRY_COMPILE([
++			    #ifdef _WIN32
++				#error cross-compiler
++			    #endif
++			], [],
++			ac_cv_cross=yes,
++			ac_cv_cross=no)
++		      )
++		      if test "$ac_cv_cross" = "yes"; then
++			case "$do64bit" in
++			    amd64|x64|yes)
++				CC="x86_64-w64-mingw32-gcc"
++				LD="x86_64-w64-mingw32-ld"
++				AR="x86_64-w64-mingw32-ar"
++				RANLIB="x86_64-w64-mingw32-ranlib"
++				RC="x86_64-w64-mingw32-windres"
++			    ;;
++			    *)
++				CC="i686-w64-mingw32-gcc"
++				LD="i686-w64-mingw32-ld"
++				AR="i686-w64-mingw32-ar"
++				RANLIB="i686-w64-mingw32-ranlib"
++				RC="i686-w64-mingw32-windres"
++			    ;;
++			esac
++		fi
++
++	    else
++		SHLIB_LD="${LINKBIN} -dll ${lflags}"
++		# link -lib only works when -lib is the first arg
++		STLIB_LD="${LINKBIN} -lib ${lflags}"
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
++		PATHTYPE=-w
++		# For information on what debugtype is most useful, see:
++		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
++		# and also
++		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
++		# This essentially turns it all on.
++		LDFLAGS_DEBUG="-debug -debugtype:cv"
++		LDFLAGS_OPTIMIZE="-release"
++		if test "$doWince" != "no" ; then
++		    LDFLAGS_CONSOLE="-link ${lflags}"
++		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
++		else
++		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
++		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
++		fi
++	    fi
++
++	    SHLIB_SUFFIX=".dll"
++	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'
++
++	    TCL_LIB_VERSIONS_OK=nodots
++    	    ;;
++	AIX-*)
++	    AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
++		# AIX requires the _r compiler when gcc isn't being used
++		case "${CC}" in
++		    *_r|*_r\ *)
++			# ok ...
++			;;
++		    *)
++			# Make sure only first arg gets _r
++		    	CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
++			;;
++		esac
++		AC_MSG_RESULT([Using $CC for compiling with threads])
++	    ])
++	    LIBS="$LIBS -lc"
++	    SHLIB_CFLAGS=""
++	    SHLIB_SUFFIX=".so"
++
++	    LD_LIBRARY_PATH_VAR="LIBPATH"
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    AS_IF([test "$do64bit" = yes], [
++		AS_IF([test "$GCC" = yes], [
++		    AC_MSG_WARN([64bit mode not supported with GCC on $system])
++		], [
++		    do64bit_ok=yes
++		    CFLAGS="$CFLAGS -q64"
++		    LDFLAGS_ARCH="-q64"
++		    RANLIB="${RANLIB} -X64"
++		    AR="${AR} -X64"
++		    SHLIB_LD_FLAGS="-b64"
++		])
++	    ])
++
++	    AS_IF([test "`uname -m`" = ia64], [
++		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
++		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
++		AS_IF([test "$GCC" = yes], [
++		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		], [
++		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
++		])
++		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++	    ], [
++		AS_IF([test "$GCC" = yes], [
++		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
++		], [
++		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"
++		    LDFLAGS="$LDFLAGS -brtl"
++		])
++		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
++		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    ])
++	    ;;
++	BeOS*)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD='${CC} -nostart'
++	    SHLIB_SUFFIX=".so"
++
++	    #-----------------------------------------------------------
++	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
++	    # -lsocket, even if the network functions are in -lnet which
++	    # is always linked to, for compatibility.
++	    #-----------------------------------------------------------
++	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
++	    ;;
++	BSD/OS-4.*)
++	    SHLIB_CFLAGS="-export-dynamic -fPIC"
++	    SHLIB_LD='${CC} -shared'
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS="$LDFLAGS -export-dynamic"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	CYGWIN_*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD='${CC} -shared'
++	    SHLIB_SUFFIX=".dll"
++	    EXEEXT=".exe"
++	    do64bit_ok=yes
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	Haiku*)
++	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
++	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
++	    ;;
++	HP-UX-*.11.*)
++	    # Use updated header definitions where possible
++	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
++	    # TEA specific: Needed by Tcl, but not most extensions
++	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
++	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library
++
++	    AS_IF([test "`uname -m`" = ia64], [
++		SHLIB_SUFFIX=".so"
++		# Use newer C++ library for C++ extensions
++		#if test "$GCC" != "yes" ; then
++		#   CPPFLAGS="-AA"
++		#fi
++	    ], [
++		SHLIB_SUFFIX=".sl"
++	    ])
++	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
++	    AS_IF([test "$tcl_ok" = yes], [
++		LDFLAGS="$LDFLAGS -Wl,-E"
++		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
++		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
++		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
++	    ])
++	    AS_IF([test "$GCC" = yes], [
++		SHLIB_LD='${CC} -shared'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    ], [
++		CFLAGS="$CFLAGS -z"
++		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
++		#CFLAGS="$CFLAGS +DAportable"
++		SHLIB_CFLAGS="+z"
++		SHLIB_LD="ld -b"
++	    ])
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    AS_IF([test "$do64bit" = "yes"], [
++		AS_IF([test "$GCC" = yes], [
++		    case `${CC} -dumpmachine` in
++			hppa64*)
++			    # 64-bit gcc in use.  Fix flags for GNU ld.
++			    do64bit_ok=yes
++			    SHLIB_LD='${CC} -shared'
++			    AS_IF([test $doRpath = yes], [
++				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++			    ;;
++			*)
++			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
++			    ;;
++		    esac
++		], [
++		    do64bit_ok=yes
++		    CFLAGS="$CFLAGS +DD64"
++		    LDFLAGS_ARCH="+DD64"
++		])
++	    ]) ;;
++	IRIX-6.*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD="ld -n32 -shared -rdata_shared"
++	    SHLIB_SUFFIX=".so"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
++	    AS_IF([test "$GCC" = yes], [
++		CFLAGS="$CFLAGS -mabi=n32"
++		LDFLAGS="$LDFLAGS -mabi=n32"
++	    ], [
++		case $system in
++		    IRIX-6.3)
++			# Use to build 6.2 compatible binaries on 6.3.
++			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
++			;;
++		    *)
++			CFLAGS="$CFLAGS -n32"
++			;;
++		esac
++		LDFLAGS="$LDFLAGS -n32"
++	    ])
++	    ;;
++	IRIX64-6.*)
++	    SHLIB_CFLAGS=""
++	    SHLIB_LD="ld -n32 -shared -rdata_shared"
++	    SHLIB_SUFFIX=".so"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
++
++	    # Check to enable 64-bit flags for compiler/linker
++
++	    AS_IF([test "$do64bit" = yes], [
++	        AS_IF([test "$GCC" = yes], [
++	            AC_MSG_WARN([64bit mode not supported by gcc])
++	        ], [
++	            do64bit_ok=yes
++	            SHLIB_LD="ld -64 -shared -rdata_shared"
++	            CFLAGS="$CFLAGS -64"
++	            LDFLAGS_ARCH="-64"
++	        ])
++	    ])
++	    ;;
++	Linux*|GNU*|NetBSD-Debian)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++
++	    # TEA specific:
++	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
++
++	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
++	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
++	    AS_IF([test $do64bit = yes], [
++		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
++		    hold_cflags=$CFLAGS
++		    CFLAGS="$CFLAGS -m64"
++		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
++		    CFLAGS=$hold_cflags])
++		AS_IF([test $tcl_cv_cc_m64 = yes], [
++		    CFLAGS="$CFLAGS -m64"
++		    do64bit_ok=yes
++		])
++	   ])
++
++	    # The combo of gcc + glibc has a bug related to inlining of
++	    # functions like strtod(). The -fno-builtin flag should address
++	    # this problem but it does not work. The -fno-inline flag is kind
++	    # of overkill but it works. Disable inlining only when one of the
++	    # files in compat/*.c is being linked in.
++
++	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])
++	    ;;
++	Lynx*)
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_SUFFIX=".so"
++	    CFLAGS_OPTIMIZE=-02
++	    SHLIB_LD='${CC} -shared'
++	    LD_FLAGS="-Wl,--export-dynamic"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++	    ;;
++	OpenBSD-*)
++	    arch=`arch -s`
++	    case "$arch" in
++	    vax)
++		SHLIB_SUFFIX=""
++		SHARED_LIB_SUFFIX=""
++		LDFLAGS=""
++		;;
++	    *)
++		SHLIB_CFLAGS="-fPIC"
++		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
++		SHLIB_SUFFIX=".so"
++		AS_IF([test $doRpath = yes], [
++		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
++		LDFLAGS="-Wl,-export-dynamic"
++		;;
++	    esac
++	    case "$arch" in
++	    vax)
++		CFLAGS_OPTIMIZE="-O1"
++		;;
++	    *)
++		CFLAGS_OPTIMIZE="-O2"
++		;;
++	    esac
++	    AS_IF([test "${TCL_THREADS}" = "1"], [
++		# On OpenBSD:	Compile with -pthread
++		#		Don't link with -lpthread
++		LIBS=`echo $LIBS | sed s/-lpthread//`
++		CFLAGS="$CFLAGS -pthread"
++	    ])
++	    # OpenBSD doesn't do version numbers with dots.
++	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++	    TCL_LIB_VERSIONS_OK=nodots
++	    ;;
++	NetBSD-*)
++	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS="$LDFLAGS -export-dynamic"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    AS_IF([test "${TCL_THREADS}" = "1"], [
++		# The -pthread needs to go in the CFLAGS, not LIBS
++		LIBS=`echo $LIBS | sed s/-pthread//`
++		CFLAGS="$CFLAGS -pthread"
++	    	LDFLAGS="$LDFLAGS -pthread"
++	    ])
++	    ;;
++	FreeBSD-*)
++	    # This configuration from FreeBSD Ports.
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD="${CC} -shared"
++	    TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
++	    TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]"
++	    SHLIB_SUFFIX=".so"
++	    LDFLAGS=""
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
++	    AS_IF([test "${TCL_THREADS}" = "1"], [
++		# The -pthread needs to go in the LDFLAGS, not LIBS
++		LIBS=`echo $LIBS | sed s/-pthread//`
++		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
++		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
++	    case $system in
++	    FreeBSD-3.*)
++		# Version numbers are dot-stripped by system policy.
++		TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
++		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
++		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
++		TCL_LIB_VERSIONS_OK=nodots
++		;;
++	    esac
++	    ;;
++	Darwin-*)
++	    CFLAGS_OPTIMIZE="-Os"
++	    SHLIB_CFLAGS="-fno-common"
++	    # To avoid discrepancies between what headers configure sees during
++	    # preprocessing tests and compiling tests, move any -isysroot and
++	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
++	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
++		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
++		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
++	    CFLAGS="`echo " ${CFLAGS}" | \
++		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
++		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
++	    AS_IF([test $do64bit = yes], [
++		case `arch` in
++		    ppc)
++			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
++				tcl_cv_cc_arch_ppc64, [
++			    hold_cflags=$CFLAGS
++			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
++			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
++				    tcl_cv_cc_arch_ppc64=no)
++			    CFLAGS=$hold_cflags])
++			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
++			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
++			    do64bit_ok=yes
++			]);;
++		    i386)
++			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
++				tcl_cv_cc_arch_x86_64, [
++			    hold_cflags=$CFLAGS
++			    CFLAGS="$CFLAGS -arch x86_64"
++			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
++				    tcl_cv_cc_arch_x86_64=no)
++			    CFLAGS=$hold_cflags])
++			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
++			    CFLAGS="$CFLAGS -arch x86_64"
++			    do64bit_ok=yes
++			]);;
++		    *)
++			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
++		esac
++	    ], [
++		# Check for combined 32-bit and 64-bit fat build
++		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
++		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
++		    fat_32_64=yes])
++	    ])
++	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
++	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
++		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
++		LDFLAGS=$hold_ldflags])
++	    AS_IF([test $tcl_cv_ld_single_module = yes], [
++		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
++	    ])
++	    # TEA specific: link shlib with current and compatibility version flags
++	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
++	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
++	    SHLIB_SUFFIX=".dylib"
++	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
++	    AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
++		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
++		LDFLAGS="$LDFLAGS -prebind"])
++	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
++	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
++		    tcl_cv_ld_search_paths_first, [
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
++		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
++			tcl_cv_ld_search_paths_first=no)
++		LDFLAGS=$hold_ldflags])
++	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
++		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
++	    ])
++	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
++		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
++		    [Compiler support for module scope symbols])
++		tcl_cv_cc_visibility_hidden=yes
++	    ])
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
++	    # TEA specific: for combined 32 & 64 bit fat builds of Tk
++	    # extensions, verify that 64-bit build is possible.
++	    AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
++		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
++		    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
++			done
++			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
++			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
++			AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
++			    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval $v'="$hold_'$v'"'
++			done])
++		])
++		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
++		    AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
++			done
++			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
++			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
++			AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
++			    tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
++			for v in CFLAGS CPPFLAGS LDFLAGS; do
++			    eval $v'="$hold_'$v'"'
++			done])
++		])
++		# remove 64-bit arch flags from CFLAGS et al. if configuration
++		# does not support 64-bit.
++		AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
++		    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
++		    for v in CFLAGS CPPFLAGS LDFLAGS; do
++			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
++		    done])
++	    ])
++	    ;;
++	OS/390-*)
++	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
++	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
++		[Should OS/390 do the right thing with sockets?])
++	    ;;
++	OSF1-V*)
++	    # Digital OSF/1
++	    SHLIB_CFLAGS=""
++	    AS_IF([test "$SHARED_BUILD" = 1], [
++	        SHLIB_LD='ld -shared -expect_unresolved "*"'
++	    ], [
++	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
++	    ])
++	    SHLIB_SUFFIX=".so"
++	    AS_IF([test $doRpath = yes], [
++		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
++	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [
++		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])
++	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
++	    AS_IF([test "${TCL_THREADS}" = 1], [
++		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
++		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
++		LIBS=`echo $LIBS | sed s/-lpthreads//`
++		AS_IF([test "$GCC" = yes], [
++		    LIBS="$LIBS -lpthread -lmach -lexc"
++		], [
++		    CFLAGS="$CFLAGS -pthread"
++		    LDFLAGS="$LDFLAGS -pthread"
++		])
++	    ])
++	    ;;
++	QNX-6*)
++	    # QNX RTP
++	    # This may work for all QNX, but it was only reported for v6.
++	    SHLIB_CFLAGS="-fPIC"
++	    SHLIB_LD="ld -Bshareable -x"
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	SCO_SV-3.2*)
++	    AS_IF([test "$GCC" = yes], [
++		SHLIB_CFLAGS="-fPIC -melf"
++		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
++	    ], [
++		SHLIB_CFLAGS="-Kpic -belf"
++		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
++	    ])
++	    SHLIB_LD="ld -G"
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++	SunOS-5.[[0-6]])
++	    # Careful to not let 5.10+ fall into this case
++
++	    # Note: If _REENTRANT isn't defined, then Solaris
++	    # won't define thread-safe library routines.
++
++	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
++	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
++		[Do we really want to follow the standard? Yes we do!])
++
++	    SHLIB_CFLAGS="-KPIC"
++	    SHLIB_SUFFIX=".so"
++	    AS_IF([test "$GCC" = yes], [
++		SHLIB_LD='${CC} -shared'
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    ], [
++		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
++		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++	    ])
++	    ;;
++	SunOS-5*)
++	    # Note: If _REENTRANT isn't defined, then Solaris
++	    # won't define thread-safe library routines.
++
++	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
++	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
++		[Do we really want to follow the standard? Yes we do!])
++
++	    SHLIB_CFLAGS="-KPIC"
++
++	    # Check to enable 64-bit flags for compiler/linker
++	    AS_IF([test "$do64bit" = yes], [
++		arch=`isainfo`
++		AS_IF([test "$arch" = "sparcv9 sparc"], [
++		    AS_IF([test "$GCC" = yes], [
++			AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
++			    AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
++			], [
++			    do64bit_ok=yes
++			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
++			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
++			    SHLIB_CFLAGS="-fPIC"
++			])
++		    ], [
++			do64bit_ok=yes
++			AS_IF([test "$do64bitVIS" = yes], [
++			    CFLAGS="$CFLAGS -xarch=v9a"
++			    LDFLAGS_ARCH="-xarch=v9a"
++			], [
++			    CFLAGS="$CFLAGS -xarch=v9"
++			    LDFLAGS_ARCH="-xarch=v9"
++			])
++			# Solaris 64 uses this as well
++			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
++		    ])
++		], [AS_IF([test "$arch" = "amd64 i386"], [
++		    AS_IF([test "$GCC" = yes], [
++			case $system in
++			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
++				do64bit_ok=yes
++				CFLAGS="$CFLAGS -m64"
++				LDFLAGS="$LDFLAGS -m64";;
++			    *)
++				AC_MSG_WARN([64bit mode not supported with GCC on $system]);;
++			esac
++		    ], [
++			do64bit_ok=yes
++			case $system in
++			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
++				CFLAGS="$CFLAGS -m64"
++				LDFLAGS="$LDFLAGS -m64";;
++			    *)
++				CFLAGS="$CFLAGS -xarch=amd64"
++				LDFLAGS="$LDFLAGS -xarch=amd64";;
++			esac
++		    ])
++		], [AC_MSG_WARN([64bit mode not supported for $arch])])])
++	    ])
++
++	    SHLIB_SUFFIX=".so"
++	    AS_IF([test "$GCC" = yes], [
++		SHLIB_LD='${CC} -shared'
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
++		AS_IF([test "$do64bit_ok" = yes], [
++		    AS_IF([test "$arch" = "sparcv9 sparc"], [
++			# We need to specify -static-libgcc or we need to
++			# add the path to the sparv9 libgcc.
++			# JH: static-libgcc is necessary for core Tcl, but may
++			# not be necessary for extensions.
++			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
++			# for finding sparcv9 libgcc, get the regular libgcc
++			# path, remove so name and append 'sparcv9'
++			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
++			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
++		    ], [AS_IF([test "$arch" = "amd64 i386"], [
++			# JH: static-libgcc is necessary for core Tcl, but may
++			# not be necessary for extensions.
++			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
++		    ])])
++		])
++	    ], [
++		case $system in
++		    SunOS-5.[[1-9]][[0-9]]*)
++			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
++			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
++		    *)
++			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
++		esac
++		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
++		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
++	    ])
++	    ;;
++	UNIX_SV* | UnixWare-5*)
++	    SHLIB_CFLAGS="-KPIC"
++	    SHLIB_LD='${CC} -G'
++	    SHLIB_LD_LIBS=""
++	    SHLIB_SUFFIX=".so"
++	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
++	    # that don't grok the -Bexport option.  Test that it does.
++	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
++		hold_ldflags=$LDFLAGS
++		LDFLAGS="$LDFLAGS -Wl,-Bexport"
++		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
++	        LDFLAGS=$hold_ldflags])
++	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
++		LDFLAGS="$LDFLAGS -Wl,-Bexport"
++	    ])
++	    CC_SEARCH_FLAGS=""
++	    LD_SEARCH_FLAGS=""
++	    ;;
++    esac
++
++    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
++	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
++    ])
++
++dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
++dnl # until the end of configure, as configure's compile and link tests use
++dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
++dnl # preprocessing tests use only CPPFLAGS.
++    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])
++
++    # Add in the arch flags late to ensure it wasn't removed.
++    # Not necessary in TEA, but this is aligned with core
++    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
++
++    # If we're running gcc, then change the C flags for compiling shared
++    # libraries to the right flags for gcc, instead of those for the
++    # standard manufacturer compiler.
++
++    AS_IF([test "$GCC" = yes], [
++	case $system in
++	    AIX-*) ;;
++	    BSD/OS*) ;;
++	    CYGWIN_*|MINGW32_*) ;;
++	    IRIX*) ;;
++	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
++	    Darwin-*) ;;
++	    SCO_SV-3.2*) ;;
++	    windows) ;;
++	    *) SHLIB_CFLAGS="-fPIC" ;;
++	esac])
++
++    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
++	AC_DEFINE(MODULE_SCOPE, [extern],
++	    [No Compiler support for module scope symbols])
++    ])
++
++    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])
++    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
++    # TEA specific: use PACKAGE_VERSION instead of VERSION
++    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])
++
++    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
++	AC_CACHE_CHECK(for SEH support in compiler,
++	    tcl_cv_seh,
++	AC_TRY_RUN([
++#define WIN32_LEAN_AND_MEAN
++#include <windows.h>
++#undef WIN32_LEAN_AND_MEAN
++
++	    int main(int argc, char** argv) {
++		int a, b = 0;
++		__try {
++		    a = 666 / b;
++		}
++		__except (EXCEPTION_EXECUTE_HANDLER) {
++		    return 0;
++		}
++		return 1;
++	    }
++	],
++	    tcl_cv_seh=yes,
++	    tcl_cv_seh=no,
++	    tcl_cv_seh=no)
++	)
++	if test "$tcl_cv_seh" = "no" ; then
++	    AC_DEFINE(HAVE_NO_SEH, 1,
++		    [Defined when mingw does not support SEH])
++	fi
++
++	#
++	# Check to see if the excpt.h include file provided contains the
++	# definition for EXCEPTION_DISPOSITION; if not, which is the case
++	# with Cygwin's version as of 2002-04-10, define it to be int,
++	# sufficient for getting the current code to work.
++	#
++	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
++	    tcl_cv_eh_disposition,
++	    AC_TRY_COMPILE([
++#	    define WIN32_LEAN_AND_MEAN
++#	    include <windows.h>
++#	    undef WIN32_LEAN_AND_MEAN
++	    ],[
++		EXCEPTION_DISPOSITION x;
++	    ],
++		tcl_cv_eh_disposition=yes,
++		tcl_cv_eh_disposition=no)
++	)
++	if test "$tcl_cv_eh_disposition" = "no" ; then
++	AC_DEFINE(EXCEPTION_DISPOSITION, int,
++		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
++	fi
++
++	# Check to see if winnt.h defines CHAR, SHORT, and LONG
++	# even if VOID has already been #defined. The win32api
++	# used by mingw and cygwin is known to do this.
++
++	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
++	    tcl_cv_winnt_ignore_void,
++	    AC_TRY_COMPILE([
++#define VOID void
++#define WIN32_LEAN_AND_MEAN
++#include <windows.h>
++#undef WIN32_LEAN_AND_MEAN
++	    ], [
++		CHAR c;
++		SHORT s;
++		LONG l;
++	    ],
++        tcl_cv_winnt_ignore_void=yes,
++        tcl_cv_winnt_ignore_void=no)
++	)
++	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
++	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
++		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
++	fi
++    fi
++
++	# See if the compiler supports casting to a union type.
++	# This is used to stop gcc from printing a compiler
++	# warning when initializing a union member.
++
++	AC_CACHE_CHECK(for cast to union support,
++	    tcl_cv_cast_to_union,
++	    AC_TRY_COMPILE([],
++	    [
++		  union foo { int i; double d; };
++		  union foo f = (union foo) (int) 0;
++	    ],
++	    tcl_cv_cast_to_union=yes,
++	    tcl_cv_cast_to_union=no)
++	)
++	if test "$tcl_cv_cast_to_union" = "yes"; then
++	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
++		    [Defined when compiler supports casting to union type.])
++	fi
++
++    AC_SUBST(CFLAGS_DEBUG)
++    AC_SUBST(CFLAGS_OPTIMIZE)
++    AC_SUBST(CFLAGS_WARNING)
++
++    AC_SUBST(STLIB_LD)
++    AC_SUBST(SHLIB_LD)
++
++    AC_SUBST(SHLIB_LD_LIBS)
++    AC_SUBST(SHLIB_CFLAGS)
++
++    AC_SUBST(LD_LIBRARY_PATH_VAR)
++
++    # These must be called after we do the basic CFLAGS checks and
++    # verify any possible 64-bit or similar switches are necessary
++    TEA_TCL_EARLY_FLAGS
++    TEA_TCL_64BIT_FLAGS
++])
++
++#--------------------------------------------------------------------
++# TEA_SERIAL_PORT
++#
++#	Determine which interface to use to talk to the serial port.
++#	Note that #include lines must begin in leftmost column for
++#	some compilers to recognize them as preprocessor directives,
++#	and some build environments have stdin not pointing at a
++#	pseudo-terminal (usually /dev/null instead.)
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines only one of the following vars:
++#		HAVE_SYS_MODEM_H
++#		USE_TERMIOS
++#		USE_TERMIO
++#		USE_SGTTY
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_SERIAL_PORT], [
++    AC_CHECK_HEADERS(sys/modem.h)
++    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
++    AC_TRY_RUN([
++#include <termios.h>
++
++int main() {
++    struct termios t;
++    if (tcgetattr(0, &t) == 0) {
++	cfsetospeed(&t, 0);
++	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
++	return 0;
++    }
++    return 1;
++}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
++    if test $tcl_cv_api_serial = no ; then
++	AC_TRY_RUN([
++#include <termio.h>
++
++int main() {
++    struct termio t;
++    if (ioctl(0, TCGETA, &t) == 0) {
++	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
++	return 0;
++    }
++    return 1;
++}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
++    fi
++    if test $tcl_cv_api_serial = no ; then
++	AC_TRY_RUN([
++#include <sgtty.h>
++
++int main() {
++    struct sgttyb t;
++    if (ioctl(0, TIOCGETP, &t) == 0) {
++	t.sg_ospeed = 0;
++	t.sg_flags |= ODDP | EVENP | RAW;
++	return 0;
++    }
++    return 1;
++}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
++    fi
++    if test $tcl_cv_api_serial = no ; then
++	AC_TRY_RUN([
++#include <termios.h>
++#include <errno.h>
++
++int main() {
++    struct termios t;
++    if (tcgetattr(0, &t) == 0
++	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
++	cfsetospeed(&t, 0);
++	t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB;
++	return 0;
++    }
++    return 1;
++}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
++    fi
++    if test $tcl_cv_api_serial = no; then
++	AC_TRY_RUN([
++#include <termio.h>
++#include <errno.h>
++
++int main() {
++    struct termio t;
++    if (ioctl(0, TCGETA, &t) == 0
++	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
++	t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB;
++	return 0;
++    }
++    return 1;
++    }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no)
++    fi
++    if test $tcl_cv_api_serial = no; then
++	AC_TRY_RUN([
++#include <sgtty.h>
++#include <errno.h>
++
++int main() {
++    struct sgttyb t;
++    if (ioctl(0, TIOCGETP, &t) == 0
++	|| errno == ENOTTY || errno == ENXIO || errno == EINVAL) {
++	t.sg_ospeed = 0;
++	t.sg_flags |= ODDP | EVENP | RAW;
++	return 0;
++    }
++    return 1;
++}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none)
++    fi])
++    case $tcl_cv_api_serial in
++	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
++	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
++	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
++    esac
++])
++
++#--------------------------------------------------------------------
++# TEA_MISSING_POSIX_HEADERS
++#
++#	Supply substitutes for missing POSIX header files.  Special
++#	notes:
++#	    - stdlib.h doesn't define strtol, strtoul, or
++#	      strtod in some versions of SunOS
++#	    - some versions of string.h don't declare procedures such
++#	      as strstr
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines some of the following vars:
++#		NO_DIRENT_H
++#		NO_ERRNO_H
++#		NO_VALUES_H
++#		HAVE_LIMITS_H or NO_LIMITS_H
++#		NO_STDLIB_H
++#		NO_STRING_H
++#		NO_SYS_WAIT_H
++#		NO_DLFCN_H
++#		HAVE_SYS_PARAM_H
++#
++#		HAVE_STRING_H ?
++#
++# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
++# CHECK on limits.h
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
++    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
++    AC_TRY_LINK([#include <sys/types.h>
++#include <dirent.h>], [
++#ifndef _POSIX_SOURCE
++#   ifdef __Lynx__
++	/*
++	 * Generate compilation error to make the test fail:  Lynx headers
++	 * are only valid if really in the POSIX environment.
++	 */
++
++	missing_procedure();
++#   endif
++#endif
++DIR *d;
++struct dirent *entryPtr;
++char *p;
++d = opendir("foobar");
++entryPtr = readdir(d);
++p = entryPtr->d_name;
++closedir(d);
++], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])
++
++    if test $tcl_cv_dirent_h = no; then
++	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
++    fi
++
++    # TEA specific:
++    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
++    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
++    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
++    AC_CHECK_HEADER(limits.h,
++	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
++	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
++    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
++    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
++    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
++    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
++    if test $tcl_ok = 0; then
++	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
++    fi
++    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
++    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
++    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
++
++    # See also memmove check below for a place where NO_STRING_H can be
++    # set and why.
++
++    if test $tcl_ok = 0; then
++	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
++    fi
++
++    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
++    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])
++
++    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
++    AC_HAVE_HEADERS(sys/param.h)
++])
++
++#--------------------------------------------------------------------
++# TEA_PATH_X
++#
++#	Locate the X11 header files and the X11 library archive.  Try
++#	the ac_path_x macro first, but if it doesn't find the X stuff
++#	(e.g. because there's no xmkmf program) then check through
++#	a list of possible directories.  Under some conditions the
++#	autoconf macro will return an include directory that contains
++#	no include files, so double-check its result just to be safe.
++#
++#	This should be called after TEA_CONFIG_CFLAGS as setting the
++#	LIBS line can confuse some configure macro magic.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Sets the following vars:
++#		XINCLUDES
++#		XLIBSW
++#		PKG_LIBS (appends to)
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_PATH_X], [
++    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
++	TEA_PATH_UNIX_X
++    fi
++])
++
++AC_DEFUN([TEA_PATH_UNIX_X], [
++    AC_PATH_X
++    not_really_there=""
++    if test "$no_x" = ""; then
++	if test "$x_includes" = ""; then
++	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
++	else
++	    if test ! -r $x_includes/X11/Xlib.h; then
++		not_really_there="yes"
++	    fi
++	fi
++    fi
++    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
++	AC_MSG_CHECKING([for X11 header files])
++	found_xincludes="no"
++	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
++	if test "$found_xincludes" = "no"; then
++	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
++	    for i in $dirs ; do
++		if test -r $i/X11/Xlib.h; then
++		    AC_MSG_RESULT([$i])
++		    XINCLUDES=" -I$i"
++		    found_xincludes="yes"
++		    break
++		fi
++	    done
++	fi
++    else
++	if test "$x_includes" != ""; then
++	    XINCLUDES="-I$x_includes"
++	    found_xincludes="yes"
++	fi
++    fi
++    if test "$found_xincludes" = "no"; then
++	AC_MSG_RESULT([couldn't find any!])
++    fi
++
++    if test "$no_x" = yes; then
++	AC_MSG_CHECKING([for X11 libraries])
++	XLIBSW=nope
++	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
++	for i in $dirs ; do
++	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
++		AC_MSG_RESULT([$i])
++		XLIBSW="-L$i -lX11"
++		x_libraries="$i"
++		break
++	    fi
++	done
++    else
++	if test "$x_libraries" = ""; then
++	    XLIBSW=-lX11
++	else
++	    XLIBSW="-L$x_libraries -lX11"
++	fi
++    fi
++    if test "$XLIBSW" = nope ; then
++	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
++    fi
++    if test "$XLIBSW" = nope ; then
++	AC_MSG_RESULT([could not find any!  Using -lX11.])
++	XLIBSW=-lX11
++    fi
++    # TEA specific:
++    if test x"${XLIBSW}" != x ; then
++	PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
++    fi
++])
++
++#--------------------------------------------------------------------
++# TEA_BLOCKING_STYLE
++#
++#	The statements below check for systems where POSIX-style
++#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
++#	On these systems (mostly older ones), use the old BSD-style
++#	FIONBIO approach instead.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines some of the following vars:
++#		HAVE_SYS_IOCTL_H
++#		HAVE_SYS_FILIO_H
++#		USE_FIONBIO
++#		O_NONBLOCK
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_BLOCKING_STYLE], [
++    AC_CHECK_HEADERS(sys/ioctl.h)
++    AC_CHECK_HEADERS(sys/filio.h)
++    TEA_CONFIG_SYSTEM
++    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
++    case $system in
++	OSF*)
++	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
++	    AC_MSG_RESULT([FIONBIO])
++	    ;;
++	*)
++	    AC_MSG_RESULT([O_NONBLOCK])
++	    ;;
++    esac
++])
++
++#--------------------------------------------------------------------
++# TEA_TIME_HANDLER
++#
++#	Checks how the system deals with time.h, what time structures
++#	are used on the system, and what fields the structures have.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines some of the following vars:
++#		USE_DELTA_FOR_TZ
++#		HAVE_TM_GMTOFF
++#		HAVE_TM_TZADJ
++#		HAVE_TIMEZONE_VAR
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_TIME_HANDLER], [
++    AC_CHECK_HEADERS(sys/time.h)
++    AC_HEADER_TIME
++    AC_STRUCT_TIMEZONE
++
++    AC_CHECK_FUNCS(gmtime_r localtime_r)
++
++    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
++	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;],
++	    tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)])
++    if test $tcl_cv_member_tm_tzadj = yes ; then
++	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
++    fi
++
++    AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [
++	AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;],
++	    tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)])
++    if test $tcl_cv_member_tm_gmtoff = yes ; then
++	AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?])
++    fi
++
++    #
++    # Its important to include time.h in this check, as some systems
++    # (like convex) have timezone functions, etc.
++    #
++    AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [
++	AC_TRY_COMPILE([#include <time.h>],
++	    [extern long timezone;
++	    timezone += 1;
++	    exit (0);],
++	    tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)])
++    if test $tcl_cv_timezone_long = yes ; then
++	AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
++    else
++	#
++	# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
++	#
++	AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [
++	    AC_TRY_COMPILE([#include <time.h>],
++		[extern time_t timezone;
++		timezone += 1;
++		exit (0);],
++		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
++	if test $tcl_cv_timezone_time = yes ; then
++	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
++	fi
++    fi
++])
++
++#--------------------------------------------------------------------
++# TEA_BUGGY_STRTOD
++#
++#	Under Solaris 2.4, strtod returns the wrong value for the
++#	terminating character under some conditions.  Check for this
++#	and if the problem exists use a substitute procedure
++#	"fixstrtod" (provided by Tcl) that corrects the error.
++#	Also, on Compaq's Tru64 Unix 5.0,
++#	strtod(" ") returns 0.0 instead of a failure to convert.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Might defines some of the following vars:
++#		strtod (=fixstrtod)
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_BUGGY_STRTOD], [
++    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
++    if test "$tcl_strtod" = 1; then
++	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
++	    AC_TRY_RUN([
++		extern double strtod();
++		int main() {
++		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
++		    char *term;
++		    double value;
++		    value = strtod(infString, &term);
++		    if ((term != infString) && (term[-1] == 0)) {
++			exit(1);
++		    }
++		    value = strtod(nanString, &term);
++		    if ((term != nanString) && (term[-1] == 0)) {
++			exit(1);
++		    }
++		    value = strtod(spaceString, &term);
++		    if (term == (spaceString+1)) {
++			exit(1);
++		    }
++		    exit(0);
++		}], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
++		    tcl_cv_strtod_buggy=buggy)])
++	if test "$tcl_cv_strtod_buggy" = buggy; then
++	    AC_LIBOBJ([fixstrtod])
++	    USE_COMPAT=1
++	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
++	fi
++    fi
++])
++
++#--------------------------------------------------------------------
++# TEA_TCL_LINK_LIBS
++#
++#	Search for the libraries needed to link the Tcl shell.
++#	Things like the math library (-lm) and socket stuff (-lsocket vs.
++#	-lnsl) are dealt with here.
++#
++# Arguments:
++#	Requires the following vars to be set in the Makefile:
++#		DL_LIBS (not in TEA, only needed in core)
++#		LIBS
++#		MATH_LIBS
++#
++# Results:
++#
++#	Substitutes the following vars:
++#		TCL_LIBS
++#		MATH_LIBS
++#
++#	Might append to the following vars:
++#		LIBS
++#
++#	Might define the following vars:
++#		HAVE_NET_ERRNO_H
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_TCL_LINK_LIBS], [
++    #--------------------------------------------------------------------
++    # On a few very rare systems, all of the libm.a stuff is
++    # already in libc.a.  Set compiler flags accordingly.
++    # Also, Linux requires the "ieee" library for math to work
++    # right (and it must appear before "-lm").
++    #--------------------------------------------------------------------
++
++    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
++    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])
++
++    #--------------------------------------------------------------------
++    # Interactive UNIX requires -linet instead of -lsocket, plus it
++    # needs net/errno.h to define the socket-related error codes.
++    #--------------------------------------------------------------------
++
++    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
++    AC_CHECK_HEADER(net/errno.h, [
++	AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])
++
++    #--------------------------------------------------------------------
++    #	Check for the existence of the -lsocket and -lnsl libraries.
++    #	The order here is important, so that they end up in the right
++    #	order in the command line generated by make.  Here are some
++    #	special considerations:
++    #	1. Use "connect" and "accept" to check for -lsocket, and
++    #	   "gethostbyname" to check for -lnsl.
++    #	2. Use each function name only once:  can't redo a check because
++    #	   autoconf caches the results of the last check and won't redo it.
++    #	3. Use -lnsl and -lsocket only if they supply procedures that
++    #	   aren't already present in the normal libraries.  This is because
++    #	   IRIX 5.2 has libraries, but they aren't needed and they're
++    #	   bogus:  they goof up name resolution if used.
++    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
++    #	   To get around this problem, check for both libraries together
++    #	   if -lsocket doesn't work by itself.
++    #--------------------------------------------------------------------
++
++    tcl_checkBoth=0
++    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
++    if test "$tcl_checkSocket" = 1; then
++	AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
++	    LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
++    fi
++    if test "$tcl_checkBoth" = 1; then
++	tk_oldLibs=$LIBS
++	LIBS="$LIBS -lsocket -lnsl"
++	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
++    fi
++    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
++	    [LIBS="$LIBS -lnsl"])])
++
++    # TEA specific: Don't perform the eval of the libraries here because
++    # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS
++
++    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
++    AC_SUBST(TCL_LIBS)
++    AC_SUBST(MATH_LIBS)
++])
++
++#--------------------------------------------------------------------
++# TEA_TCL_EARLY_FLAGS
++#
++#	Check for what flags are needed to be passed so the correct OS
++#	features are available.
++#
++# Arguments:
++#	None
++#
++# Results:
++#
++#	Might define the following vars:
++#		_ISOC99_SOURCE
++#		_LARGEFILE64_SOURCE
++#		_LARGEFILE_SOURCE64
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_TCL_EARLY_FLAG],[
++    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
++	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
++	    AC_TRY_COMPILE([[#define ]$1[ 1
++]$2], $3,
++		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
++		[tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)))
++    if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
++	AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
++	tcl_flags="$tcl_flags $1"
++    fi
++])
++
++AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
++    AC_MSG_CHECKING([for required early compiler flags])
++    tcl_flags=""
++    TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
++	[char *p = (char *)strtoll; char *q = (char *)strtoull;])
++    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
++	[struct stat64 buf; int i = stat64("/", &buf);])
++    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
++	[char *p = (char *)open64;])
++    if test "x${tcl_flags}" = "x" ; then
++	AC_MSG_RESULT([none])
++    else
++	AC_MSG_RESULT([${tcl_flags}])
++    fi
++])
++
++#--------------------------------------------------------------------
++# TEA_TCL_64BIT_FLAGS
++#
++#	Check for what is defined in the way of 64-bit features.
++#
++# Arguments:
++#	None
++#
++# Results:
++#
++#	Might define the following vars:
++#		TCL_WIDE_INT_IS_LONG
++#		TCL_WIDE_INT_TYPE
++#		HAVE_STRUCT_DIRENT64
++#		HAVE_STRUCT_STAT64
++#		HAVE_TYPE_OFF64_T
++#--------------------------------------------------------------------
++
++AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
++    AC_MSG_CHECKING([for 64-bit integer type])
++    AC_CACHE_VAL(tcl_cv_type_64bit,[
++	tcl_cv_type_64bit=none
++	# See if the compiler knows natively about __int64
++	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
++	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
++	# See if we should use long anyway  Note that we substitute in the
++	# type that is our current guess for a 64-bit type inside this check
++	# program, so it should be modified only carefully...
++        AC_TRY_COMPILE(,[switch (0) {
++            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
++        }],tcl_cv_type_64bit=${tcl_type_64bit})])
++    if test "${tcl_cv_type_64bit}" = none ; then
++	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
++	AC_MSG_RESULT([using long])
++    elif test "${tcl_cv_type_64bit}" = "__int64" \
++		-a "${TEA_PLATFORM}" = "windows" ; then
++	# TEA specific: We actually want to use the default tcl.h checks in
++	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
++	AC_MSG_RESULT([using Tcl header defaults])
++    else
++	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
++	    [What type should be used to define wide integers?])
++	AC_MSG_RESULT([${tcl_cv_type_64bit}])
++
++	# Now check for auxiliary declarations
++	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
++	    AC_TRY_COMPILE([#include <sys/types.h>
++#include <dirent.h>],[struct dirent64 p;],
++		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
++	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
++	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
++	fi
++
++	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
++	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
++],
++		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
++	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
++	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])
++	fi
++
++	AC_CHECK_FUNCS(open64 lseek64)
++	AC_MSG_CHECKING([for off64_t])
++	AC_CACHE_VAL(tcl_cv_type_off64_t,[
++	    AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset;
++],
++		tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)])
++	dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
++	dnl functions lseek64 and open64 are defined.
++	if test "x${tcl_cv_type_off64_t}" = "xyes" && \
++	        test "x${ac_cv_func_lseek64}" = "xyes" && \
++	        test "x${ac_cv_func_open64}" = "xyes" ; then
++	    AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
++	    AC_MSG_RESULT([yes])
++	else
++	    AC_MSG_RESULT([no])
++	fi
++    fi
++])
++
++##
++## Here ends the standard Tcl configuration bits and starts the
++## TEA specific functions
++##
++
++#------------------------------------------------------------------------
++# TEA_INIT --
++#
++#	Init various Tcl Extension Architecture (TEA) variables.
++#	This should be the first called TEA_* macro.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		CYGPATH
++#		EXEEXT
++#	Defines only:
++#		TEA_VERSION
++#		TEA_INITED
++#		TEA_PLATFORM (windows or unix)
++#
++# "cygpath" is used on windows to generate native path names for include
++# files. These variables should only be used with the compiler and linker
++# since they generate native path names.
++#
++# EXEEXT
++#	Select the executable extension based on the host type.  This
++#	is a lightweight replacement for AC_EXEEXT that doesn't require
++#	a compiler.
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_INIT], [
++    # TEA extensions pass this us the version of TEA they think they
++    # are compatible with.
++    TEA_VERSION="3.9"
++
++    AC_MSG_CHECKING([for correct TEA configuration])
++    if test x"${PACKAGE_NAME}" = x ; then
++	AC_MSG_ERROR([
++The PACKAGE_NAME variable must be defined by your TEA configure.in])
++    fi
++    if test x"$1" = x ; then
++	AC_MSG_ERROR([
++TEA version not specified.])
++    elif test "$1" != "${TEA_VERSION}" ; then
++	AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
++    else
++	AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])
++    fi
++
++    # If the user did not set CFLAGS, set it now to keep macros
++    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
++    if test "${CFLAGS+set}" != "set" ; then
++	CFLAGS=""
++    fi
++
++    case "`uname -s`" in
++	*win32*|*WIN32*|*MINGW32_*)
++	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
++	    EXEEXT=".exe"
++	    TEA_PLATFORM="windows"
++	    ;;
++	*CYGWIN_*)
++	    CYGPATH=echo
++	    EXEEXT=".exe"
++	    # TEA_PLATFORM is determined later in LOAD_TCLCONFIG
++	    ;;
++	*)
++	    CYGPATH=echo
++	    # Maybe we are cross-compiling....
++	    case ${host_alias} in
++		*mingw32*)
++		EXEEXT=".exe"
++		TEA_PLATFORM="windows"
++		;;
++	    *)
++		EXEEXT=""
++		TEA_PLATFORM="unix"
++		;;
++	    esac
++	    ;;
++    esac
++
++    # Check if exec_prefix is set. If not use fall back to prefix.
++    # Note when adjusted, so that TEA_PREFIX can correct for this.
++    # This is needed for recursive configures, since autoconf propagates
++    # $prefix, but not $exec_prefix (doh!).
++    if test x$exec_prefix = xNONE ; then
++	exec_prefix_default=yes
++	exec_prefix=$prefix
++    fi
++
++    AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])
++
++    AC_SUBST(EXEEXT)
++    AC_SUBST(CYGPATH)
++
++    # This package name must be replaced statically for AC_SUBST to work
++    AC_SUBST(PKG_LIB_FILE)
++    # Substitute STUB_LIB_FILE in case package creates a stub library too.
++    AC_SUBST(PKG_STUB_LIB_FILE)
++
++    # We AC_SUBST these here to ensure they are subst'ed,
++    # in case the user doesn't call TEA_ADD_...
++    AC_SUBST(PKG_STUB_SOURCES)
++    AC_SUBST(PKG_STUB_OBJECTS)
++    AC_SUBST(PKG_TCL_SOURCES)
++    AC_SUBST(PKG_HEADERS)
++    AC_SUBST(PKG_INCLUDES)
++    AC_SUBST(PKG_LIBS)
++    AC_SUBST(PKG_CFLAGS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_SOURCES --
++#
++#	Specify one or more source files.  Users should check for
++#	the right platform before adding to their list.
++#	It is not important to specify the directory, as long as it is
++#	in the generic, win or unix subdirectory of $(srcdir).
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_SOURCES
++#		PKG_OBJECTS
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_SOURCES], [
++    vars="$@"
++    for i in $vars; do
++	case $i in
++	    [\$]*)
++		# allow $-var names
++		PKG_SOURCES="$PKG_SOURCES $i"
++		PKG_OBJECTS="$PKG_OBJECTS $i"
++		;;
++	    *)
++		# check for existence - allows for generic/win/unix VPATH
++		# To add more dirs here (like 'src'), you have to update VPATH
++		# in Makefile.in as well
++		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
++		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
++		    -a ! -f "${srcdir}/macosx/$i" \
++		    ; then
++		    AC_MSG_ERROR([could not find source file '$i'])
++		fi
++		PKG_SOURCES="$PKG_SOURCES $i"
++		# this assumes it is in a VPATH dir
++		i=`basename $i`
++		# handle user calling this before or after TEA_SETUP_COMPILER
++		if test x"${OBJEXT}" != x ; then
++		    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
++		else
++		    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
++		fi
++		PKG_OBJECTS="$PKG_OBJECTS $j"
++		;;
++	esac
++    done
++    AC_SUBST(PKG_SOURCES)
++    AC_SUBST(PKG_OBJECTS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_STUB_SOURCES --
++#
++#	Specify one or more source files.  Users should check for
++#	the right platform before adding to their list.
++#	It is not important to specify the directory, as long as it is
++#	in the generic, win or unix subdirectory of $(srcdir).
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_STUB_SOURCES
++#		PKG_STUB_OBJECTS
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_STUB_SOURCES], [
++    vars="$@"
++    for i in $vars; do
++	# check for existence - allows for generic/win/unix VPATH
++	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
++	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
++	    -a ! -f "${srcdir}/macosx/$i" \
++	    ; then
++	    AC_MSG_ERROR([could not find stub source file '$i'])
++	fi
++	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
++	# this assumes it is in a VPATH dir
++	i=`basename $i`
++	# handle user calling this before or after TEA_SETUP_COMPILER
++	if test x"${OBJEXT}" != x ; then
++	    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}"
++	else
++	    j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}"
++	fi
++	PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j"
++    done
++    AC_SUBST(PKG_STUB_SOURCES)
++    AC_SUBST(PKG_STUB_OBJECTS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_TCL_SOURCES --
++#
++#	Specify one or more Tcl source files.  These should be platform
++#	independent runtime files.
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_TCL_SOURCES
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_TCL_SOURCES], [
++    vars="$@"
++    for i in $vars; do
++	# check for existence, be strict because it is installed
++	if test ! -f "${srcdir}/$i" ; then
++	    AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i'])
++	fi
++	PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i"
++    done
++    AC_SUBST(PKG_TCL_SOURCES)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_HEADERS --
++#
++#	Specify one or more source headers.  Users should check for
++#	the right platform before adding to their list.
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_HEADERS
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_HEADERS], [
++    vars="$@"
++    for i in $vars; do
++	# check for existence, be strict because it is installed
++	if test ! -f "${srcdir}/$i" ; then
++	    AC_MSG_ERROR([could not find header file '${srcdir}/$i'])
++	fi
++	PKG_HEADERS="$PKG_HEADERS $i"
++    done
++    AC_SUBST(PKG_HEADERS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_INCLUDES --
++#
++#	Specify one or more include dirs.  Users should check for
++#	the right platform before adding to their list.
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_INCLUDES
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_INCLUDES], [
++    vars="$@"
++    for i in $vars; do
++	PKG_INCLUDES="$PKG_INCLUDES $i"
++    done
++    AC_SUBST(PKG_INCLUDES)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_LIBS --
++#
++#	Specify one or more libraries.  Users should check for
++#	the right platform before adding to their list.  For Windows,
++#	libraries provided in "foo.lib" format will be converted to
++#	"-lfoo" when using GCC (mingw).
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_LIBS
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_LIBS], [
++    vars="$@"
++    for i in $vars; do
++	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then
++	    # Convert foo.lib to -lfoo for GCC.  No-op if not *.lib
++	    i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'`
++	fi
++	PKG_LIBS="$PKG_LIBS $i"
++    done
++    AC_SUBST(PKG_LIBS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_CFLAGS --
++#
++#	Specify one or more CFLAGS.  Users should check for
++#	the right platform before adding to their list.
++#
++# Arguments:
++#	one or more file names
++#
++# Results:
++#
++#	Defines and substs the following vars:
++#		PKG_CFLAGS
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_CFLAGS], [
++    PKG_CFLAGS="$PKG_CFLAGS $@"
++    AC_SUBST(PKG_CFLAGS)
++])
++
++#------------------------------------------------------------------------
++# TEA_ADD_CLEANFILES --
++#
++#	Specify one or more CLEANFILES.
++#
++# Arguments:
++#	one or more file names to clean target
++#
++# Results:
++#
++#	Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_ADD_CLEANFILES], [
++    CLEANFILES="$CLEANFILES $@"
++])
++
++#------------------------------------------------------------------------
++# TEA_PREFIX --
++#
++#	Handle the --prefix=... option by defaulting to what Tcl gave
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	If --prefix or --exec-prefix was not specified, $prefix and
++#	$exec_prefix will be set to the values given to Tcl when it was
++#	configured.
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_PREFIX], [
++    if test "${prefix}" = "NONE"; then
++	prefix_default=yes
++	if test x"${TCL_PREFIX}" != x; then
++	    AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}])
++	    prefix=${TCL_PREFIX}
++	else
++	    AC_MSG_NOTICE([--prefix defaulting to /usr/local])
++	    prefix=/usr/local
++	fi
++    fi
++    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \
++	-o x"${exec_prefix_default}" = x"yes" ; then
++	if test x"${TCL_EXEC_PREFIX}" != x; then
++	    AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}])
++	    exec_prefix=${TCL_EXEC_PREFIX}
++	else
++	    AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}])
++	    exec_prefix=$prefix
++	fi
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_SETUP_COMPILER_CC --
++#
++#	Do compiler checks the way we want.  This is just a replacement
++#	for AC_PROG_CC in TEA configure.in files to make them cleaner.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Sets up CC var and other standard bits we need to make executables.
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_SETUP_COMPILER_CC], [
++    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
++    # in this macro, they need to go into TEA_SETUP_COMPILER instead.
++
++    AC_PROG_CC
++    AC_PROG_CPP
++
++    INSTALL="\$(SHELL) \$(srcdir)/tclconfig/install-sh -c"
++    AC_SUBST(INSTALL)
++    INSTALL_DATA="\${INSTALL} -m 644"
++    AC_SUBST(INSTALL_DATA)
++    INSTALL_PROGRAM="\${INSTALL}"
++    AC_SUBST(INSTALL_PROGRAM)
++    INSTALL_SCRIPT="\${INSTALL}"
++    AC_SUBST(INSTALL_SCRIPT)
++
++    #--------------------------------------------------------------------
++    # Checks to see if the make program sets the $MAKE variable.
++    #--------------------------------------------------------------------
++
++    AC_PROG_MAKE_SET
++
++    #--------------------------------------------------------------------
++    # Find ranlib
++    #--------------------------------------------------------------------
++
++    AC_CHECK_TOOL(RANLIB, ranlib)
++
++    #--------------------------------------------------------------------
++    # Determines the correct binary file extension (.o, .obj, .exe etc.)
++    #--------------------------------------------------------------------
++
++    AC_OBJEXT
++    AC_EXEEXT
++])
++
++#------------------------------------------------------------------------
++# TEA_SETUP_COMPILER --
++#
++#	Do compiler checks that use the compiler.  This must go after
++#	TEA_SETUP_COMPILER_CC, which does the actual compiler check.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Sets up CC var and other standard bits we need to make executables.
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_SETUP_COMPILER], [
++    # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here.
++    AC_REQUIRE([TEA_SETUP_COMPILER_CC])
++
++    #------------------------------------------------------------------------
++    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
++    # It makes compiling go faster.  (This is only a performance feature.)
++    #------------------------------------------------------------------------
++
++    if test -z "$no_pipe" -a -n "$GCC"; then
++	AC_CACHE_CHECK([if the compiler understands -pipe],
++	    tcl_cv_cc_pipe, [
++	    hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
++	    AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no)
++	    CFLAGS=$hold_cflags])
++	if test $tcl_cv_cc_pipe = yes; then
++	    CFLAGS="$CFLAGS -pipe"
++	fi
++    fi
++
++    #--------------------------------------------------------------------
++    # Common compiler flag setup
++    #--------------------------------------------------------------------
++
++    AC_C_BIGENDIAN
++    if test "${TEA_PLATFORM}" = "unix" ; then
++	TEA_TCL_LINK_LIBS
++	TEA_MISSING_POSIX_HEADERS
++	# Let the user call this, because if it triggers, they will
++	# need a compat/strtod.c that is correct.  Users can also
++	# use Tcl_GetDouble(FromObj) instead.
++	#TEA_BUGGY_STRTOD
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_MAKE_LIB --
++#
++#	Generate a line that can be used to build a shared/unshared library
++#	in a platform independent manner.
++#
++# Arguments:
++#	none
++#
++#	Requires:
++#
++# Results:
++#
++#	Defines the following vars:
++#	CFLAGS -	Done late here to note disturb other AC macros
++#       MAKE_LIB -      Command to execute to build the Tcl library;
++#                       differs depending on whether or not Tcl is being
++#                       compiled as a shared library.
++#	MAKE_SHARED_LIB	Makefile rule for building a shared library
++#	MAKE_STATIC_LIB	Makefile rule for building a static library
++#	MAKE_STUB_LIB	Makefile rule for building a stub library
++#	VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
++#	VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_MAKE_LIB], [
++    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
++	MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
++	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
++	AC_EGREP_CPP([manifest needed], [
++#if defined(_MSC_VER) && _MSC_VER >= 1400
++print("manifest needed")
++#endif
++	], [
++	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
++	VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
++	VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
++	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
++	TEA_ADD_CLEANFILES([*.manifest])
++	])
++	MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)"
++    else
++	MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
++	MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
++	MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
++    fi
++
++    if test "${SHARED_BUILD}" = "1" ; then
++	MAKE_LIB="${MAKE_SHARED_LIB} "
++    else
++	MAKE_LIB="${MAKE_STATIC_LIB} "
++    fi
++
++    #--------------------------------------------------------------------
++    # Shared libraries and static libraries have different names.
++    # Use the double eval to make sure any variables in the suffix is
++    # substituted. (@@@ Might not be necessary anymore)
++    #--------------------------------------------------------------------
++
++    if test "${TEA_PLATFORM}" = "windows" ; then
++	if test "${SHARED_BUILD}" = "1" ; then
++	    # We force the unresolved linking of symbols that are really in
++	    # the private libraries of Tcl and Tk.
++	    if test x"${TK_BIN_DIR}" != x ; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
++	    fi
++	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
++	    if test "$GCC" = "yes"; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
++	    fi
++	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
++	else
++	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
++	    if test "$GCC" = "yes"; then
++		PKG_LIB_FILE=lib${PKG_LIB_FILE}
++	    fi
++	fi
++	# Some packages build their own stubs libraries
++	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
++	if test "$GCC" = "yes"; then
++	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
++	fi
++	# These aren't needed on Windows (either MSVC or gcc)
++	RANLIB=:
++	RANLIB_STUB=:
++    else
++	RANLIB_STUB="${RANLIB}"
++	if test "${SHARED_BUILD}" = "1" ; then
++	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
++	    if test x"${TK_BIN_DIR}" != x ; then
++		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
++	    fi
++	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
++	    RANLIB=:
++	else
++	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
++	fi
++	# Some packages build their own stubs libraries
++	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
++    fi
++
++    # These are escaped so that only CFLAGS is picked up at configure time.
++    # The other values will be substituted at make time.
++    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
++    if test "${SHARED_BUILD}" = "1" ; then
++	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
++    fi
++
++    AC_SUBST(MAKE_LIB)
++    AC_SUBST(MAKE_SHARED_LIB)
++    AC_SUBST(MAKE_STATIC_LIB)
++    AC_SUBST(MAKE_STUB_LIB)
++    AC_SUBST(RANLIB_STUB)
++    AC_SUBST(VC_MANIFEST_EMBED_DLL)
++    AC_SUBST(VC_MANIFEST_EMBED_EXE)
++])
++
++#------------------------------------------------------------------------
++# TEA_LIB_SPEC --
++#
++#	Compute the name of an existing object library located in libdir
++#	from the given base name and produce the appropriate linker flags.
++#
++# Arguments:
++#	basename	The base name of the library without version
++#			numbers, extensions, or "lib" prefixes.
++#	extra_dir	Extra directory in which to search for the
++#			library.  This location is used first, then
++#			$prefix/$exec-prefix, then some defaults.
++#
++# Requires:
++#	TEA_INIT and TEA_PREFIX must be called first.
++#
++# Results:
++#
++#	Defines the following vars:
++#		${basename}_LIB_NAME	The computed library name.
++#		${basename}_LIB_SPEC	The computed linker flags.
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_LIB_SPEC], [
++    AC_MSG_CHECKING([for $1 library])
++
++    # Look in exec-prefix for the library (defined by TEA_PREFIX).
++
++    tea_lib_name_dir="${exec_prefix}/lib"
++
++    # Or in a user-specified location.
++
++    if test x"$2" != x ; then
++	tea_extra_lib_dir=$2
++    else
++	tea_extra_lib_dir=NONE
++    fi
++
++    for i in \
++	    `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
++	    `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
++	    `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
++	    `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
++	    `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
++	    `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
++	    `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
++	    `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
++	    `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
++	    `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
++	if test -f "$i" ; then
++	    tea_lib_name_dir=`dirname $i`
++	    $1_LIB_NAME=`basename $i`
++	    $1_LIB_PATH_NAME=$i
++	    break
++	fi
++    done
++
++    if test "${TEA_PLATFORM}" = "windows"; then
++	$1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\"
++    else
++	# Strip off the leading "lib" and trailing ".a" or ".so"
++
++	tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'`
++	$1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}"
++    fi
++
++    if test "x${$1_LIB_NAME}" = x ; then
++	AC_MSG_ERROR([not found])
++    else
++	AC_MSG_RESULT([${$1_LIB_SPEC}])
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_PRIVATE_TCL_HEADERS --
++#
++#	Locate the private Tcl include files
++#
++# Arguments:
++#
++#	Requires:
++#		TCL_SRC_DIR	Assumes that TEA_LOAD_TCLCONFIG has
++#				already been called.
++#
++# Results:
++#
++#	Substitutes the following vars:
++#		TCL_TOP_DIR_NATIVE
++#		TCL_INCLUDES
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
++    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
++    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
++    AC_MSG_CHECKING([for Tcl private include files])
++
++    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
++    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
++
++    # Check to see if tcl<Plat>Port.h isn't already with the public headers
++    # Don't look for tclInt.h because that resides with tcl.h in the core
++    # sources, but the <plat>Port headers are in a different directory
++    if test "${TEA_PLATFORM}" = "windows" -a \
++	-f "${ac_cv_c_tclh}/tclWinPort.h"; then
++	result="private headers found with public headers"
++    elif test "${TEA_PLATFORM}" = "unix" -a \
++	-f "${ac_cv_c_tclh}/tclUnixPort.h"; then
++	result="private headers found with public headers"
++    else
++	TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
++	if test "${TEA_PLATFORM}" = "windows"; then
++	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
++	else
++	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
++	fi
++	# Overwrite the previous TCL_INCLUDES as this should capture both
++	# public and private headers in the same set.
++	# We want to ensure these are substituted so as not to require
++	# any *_NATIVE vars be defined in the Makefile
++	TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
++	if test "`uname -s`" = "Darwin"; then
++            # If Tcl was built as a framework, attempt to use
++            # the framework's Headers and PrivateHeaders directories
++            case ${TCL_DEFS} in
++	    	*TCL_FRAMEWORK*)
++		    if test -d "${TCL_BIN_DIR}/Headers" -a \
++			    -d "${TCL_BIN_DIR}/PrivateHeaders"; then
++			TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
++		    else
++			TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
++		    fi
++	            ;;
++	    esac
++	    result="Using ${TCL_INCLUDES}"
++	else
++	    if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
++		AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
++	    fi
++	    result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
++	fi
++    fi
++
++    AC_SUBST(TCL_TOP_DIR_NATIVE)
++
++    AC_SUBST(TCL_INCLUDES)
++    AC_MSG_RESULT([${result}])
++])
++
++#------------------------------------------------------------------------
++# TEA_PUBLIC_TCL_HEADERS --
++#
++#	Locate the installed public Tcl header files
++#
++# Arguments:
++#	None.
++#
++# Requires:
++#	CYGPATH must be set
++#
++# Results:
++#
++#	Adds a --with-tclinclude switch to configure.
++#	Result is cached.
++#
++#	Substitutes the following vars:
++#		TCL_INCLUDES
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
++    AC_MSG_CHECKING([for Tcl public headers])
++
++    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
++
++    AC_CACHE_VAL(ac_cv_c_tclh, [
++	# Use the value from --with-tclinclude, if it was given
++
++	if test x"${with_tclinclude}" != x ; then
++	    if test -f "${with_tclinclude}/tcl.h" ; then
++		ac_cv_c_tclh=${with_tclinclude}
++	    else
++		AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
++	    fi
++	else
++	    list=""
++	    if test "`uname -s`" = "Darwin"; then
++		# If Tcl was built as a framework, attempt to use
++		# the framework's Headers directory
++		case ${TCL_DEFS} in
++		    *TCL_FRAMEWORK*)
++			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
++			;;
++		esac
++	    fi
++
++	    # Look in the source dir only if Tcl is not installed,
++	    # and in that situation, look there before installed locations.
++	    if test -f "${TCL_BIN_DIR}/Makefile" ; then
++		list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`"
++	    fi
++
++	    # Check order: pkg --prefix location, Tcl's --prefix location,
++	    # relative to directory of tclConfig.sh.
++
++	    eval "temp_includedir=${includedir}"
++	    list="$list \
++		`ls -d ${temp_includedir}        2>/dev/null` \
++		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
++		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
++	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
++		list="$list /usr/local/include /usr/include"
++		if test x"${TCL_INCLUDE_SPEC}" != x ; then
++		    d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'`
++		    list="$list `ls -d ${d} 2>/dev/null`"
++		fi
++	    fi
++	    for i in $list ; do
++		if test -f "$i/tcl.h" ; then
++		    ac_cv_c_tclh=$i
++		    break
++		fi
++	    done
++	fi
++    ])
++
++    # Print a message based on how we determined the include path
++
++    if test x"${ac_cv_c_tclh}" = x ; then
++	AC_MSG_ERROR([tcl.h not found.  Please specify its location with --with-tclinclude])
++    else
++	AC_MSG_RESULT([${ac_cv_c_tclh}])
++    fi
++
++    # Convert to a native path and substitute into the output files.
++
++    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`
++
++    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
++
++    AC_SUBST(TCL_INCLUDES)
++])
++
++#------------------------------------------------------------------------
++# TEA_PRIVATE_TK_HEADERS --
++#
++#	Locate the private Tk include files
++#
++# Arguments:
++#
++#	Requires:
++#		TK_SRC_DIR	Assumes that TEA_LOAD_TKCONFIG has
++#				 already been called.
++#
++# Results:
++#
++#	Substitutes the following vars:
++#		TK_INCLUDES
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
++    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
++    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
++    AC_MSG_CHECKING([for Tk private include files])
++
++    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
++    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
++
++    # Check to see if tk<Plat>Port.h isn't already with the public headers
++    # Don't look for tkInt.h because that resides with tk.h in the core
++    # sources, but the <plat>Port headers are in a different directory
++    if test "${TEA_PLATFORM}" = "windows" -a \
++	-f "${ac_cv_c_tkh}/tkWinPort.h"; then
++	result="private headers found with public headers"
++    elif test "${TEA_PLATFORM}" = "unix" -a \
++	-f "${ac_cv_c_tkh}/tkUnixPort.h"; then
++	result="private headers found with public headers"
++    else
++	TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
++	TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
++	if test "${TEA_PLATFORM}" = "windows"; then
++	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
++	else
++	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
++	fi
++	# Overwrite the previous TK_INCLUDES as this should capture both
++	# public and private headers in the same set.
++	# We want to ensure these are substituted so as not to require
++	# any *_NATIVE vars be defined in the Makefile
++	TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
++	# Detect and add ttk subdir
++	if test -d "${TK_SRC_DIR}/generic/ttk"; then
++	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
++	fi
++	if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
++	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
++	fi
++	if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
++	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
++	fi
++	if test "`uname -s`" = "Darwin"; then
++	    # If Tk was built as a framework, attempt to use
++	    # the framework's Headers and PrivateHeaders directories
++	    case ${TK_DEFS} in
++		*TK_FRAMEWORK*)
++			if test -d "${TK_BIN_DIR}/Headers" -a \
++				-d "${TK_BIN_DIR}/PrivateHeaders"; then
++			    TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
++			else
++			    TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
++			fi
++			;;
++	    esac
++	    result="Using ${TK_INCLUDES}"
++	else
++	    if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
++	       AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
++	    fi
++	    result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
++	fi
++    fi
++
++    AC_SUBST(TK_TOP_DIR_NATIVE)
++    AC_SUBST(TK_XLIB_DIR_NATIVE)
++
++    AC_SUBST(TK_INCLUDES)
++    AC_MSG_RESULT([${result}])
++])
++
++#------------------------------------------------------------------------
++# TEA_PUBLIC_TK_HEADERS --
++#
++#	Locate the installed public Tk header files
++#
++# Arguments:
++#	None.
++#
++# Requires:
++#	CYGPATH must be set
++#
++# Results:
++#
++#	Adds a --with-tkinclude switch to configure.
++#	Result is cached.
++#
++#	Substitutes the following vars:
++#		TK_INCLUDES
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
++    AC_MSG_CHECKING([for Tk public headers])
++
++    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
++
++    AC_CACHE_VAL(ac_cv_c_tkh, [
++	# Use the value from --with-tkinclude, if it was given
++
++	if test x"${with_tkinclude}" != x ; then
++	    if test -f "${with_tkinclude}/tk.h" ; then
++		ac_cv_c_tkh=${with_tkinclude}
++	    else
++		AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
++	    fi
++	else
++	    list=""
++	    if test "`uname -s`" = "Darwin"; then
++		# If Tk was built as a framework, attempt to use
++		# the framework's Headers directory.
++		case ${TK_DEFS} in
++		    *TK_FRAMEWORK*)
++			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
++			;;
++		esac
++	    fi
++
++	    # Look in the source dir only if Tk is not installed,
++	    # and in that situation, look there before installed locations.
++	    if test -f "${TK_BIN_DIR}/Makefile" ; then
++		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
++	    fi
++
++	    # Check order: pkg --prefix location, Tk's --prefix location,
++	    # relative to directory of tkConfig.sh, Tcl's --prefix location,
++	    # relative to directory of tclConfig.sh.
++
++	    eval "temp_includedir=${includedir}"
++	    list="$list \
++		`ls -d ${temp_includedir}        2>/dev/null` \
++		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
++		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
++		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
++		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
++	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
++		list="$list /usr/local/include /usr/include"
++		if test x"${TK_INCLUDE_SPEC}" != x ; then
++		    d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
++		    list="$list `ls -d ${d} 2>/dev/null`"
++		fi
++	    fi
++	    for i in $list ; do
++		if test -f "$i/tk.h" ; then
++		    ac_cv_c_tkh=$i
++		    break
++		fi
++	    done
++	fi
++    ])
++
++    # Print a message based on how we determined the include path
++
++    if test x"${ac_cv_c_tkh}" = x ; then
++	AC_MSG_ERROR([tk.h not found.  Please specify its location with --with-tkinclude])
++    else
++	AC_MSG_RESULT([${ac_cv_c_tkh}])
++    fi
++
++    # Convert to a native path and substitute into the output files.
++
++    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`
++
++    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
++
++    AC_SUBST(TK_INCLUDES)
++
++    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then
++	# On Windows and Aqua, we need the X compat headers
++	AC_MSG_CHECKING([for X11 header files])
++	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
++	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
++	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
++	    AC_SUBST(TK_XINCLUDES)
++	fi
++	AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_PATH_CONFIG --
++#
++#	Locate the ${1}Config.sh file and perform a sanity check on
++#	the ${1} compile flags.  These are used by packages like
++#	[incr Tk] that load *Config.sh files from more than Tcl and Tk.
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--with-$1=...
++#
++#	Defines the following vars:
++#		$1_BIN_DIR	Full path to the directory containing
++#				the $1Config.sh file
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PATH_CONFIG], [
++    #
++    # Ok, lets find the $1 configuration
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-$1
++    #
++
++    if test x"${no_$1}" = x ; then
++	# we reset no_$1 in case something fails here
++	no_$1=true
++	AC_ARG_WITH($1, [  --with-$1              directory containing $1 configuration ($1Config.sh)], with_$1config=${withval})
++	AC_MSG_CHECKING([for $1 configuration])
++	AC_CACHE_VAL(ac_cv_c_$1config,[
++
++	    # First check to see if --with-$1 was specified.
++	    if test x"${with_$1config}" != x ; then
++		case ${with_$1config} in
++		    */$1Config.sh )
++			if test -f ${with_$1config}; then
++			    AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself])
++			    with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'`
++			fi;;
++		esac
++		if test -f "${with_$1config}/$1Config.sh" ; then
++		    ac_cv_c_$1config=`(cd ${with_$1config}; pwd)`
++		else
++		    AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh])
++		fi
++	    fi
++
++	    # then check for a private $1 installation
++	    if test x"${ac_cv_c_$1config}" = x ; then
++		for i in \
++			../$1 \
++			`ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
++			`ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
++			`ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
++			../../$1 \
++			`ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
++			`ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
++			../../../$1 \
++			`ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
++			`ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
++			`ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
++			${srcdir}/../$1 \
++			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \
++			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \
++			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \
++			`ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \
++			; do
++		    if test -f "$i/$1Config.sh" ; then
++			ac_cv_c_$1config=`(cd $i; pwd)`
++			break
++		    fi
++		    if test -f "$i/unix/$1Config.sh" ; then
++			ac_cv_c_$1config=`(cd $i/unix; pwd)`
++			break
++		    fi
++		done
++	    fi
++
++	    # check in a few common install locations
++	    if test x"${ac_cv_c_$1config}" = x ; then
++		for i in `ls -d ${libdir} 2>/dev/null` \
++			`ls -d ${exec_prefix}/lib 2>/dev/null` \
++			`ls -d ${prefix}/lib 2>/dev/null` \
++			`ls -d /usr/local/lib 2>/dev/null` \
++			`ls -d /usr/contrib/lib 2>/dev/null` \
++			`ls -d /usr/lib 2>/dev/null` \
++			`ls -d /usr/lib64 2>/dev/null` \
++			; do
++		    if test -f "$i/$1Config.sh" ; then
++			ac_cv_c_$1config=`(cd $i; pwd)`
++			break
++		    fi
++		done
++	    fi
++	])
++
++	if test x"${ac_cv_c_$1config}" = x ; then
++	    $1_BIN_DIR="# no $1 configs found"
++	    AC_MSG_WARN([Cannot find $1 configuration definitions])
++	    exit 0
++	else
++	    no_$1=
++	    $1_BIN_DIR=${ac_cv_c_$1config}
++	    AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh])
++	fi
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_LOAD_CONFIG --
++#
++#	Load the $1Config.sh file
++#
++# Arguments:
++#
++#	Requires the following vars to be set:
++#		$1_BIN_DIR
++#
++# Results:
++#
++#	Substitutes the following vars:
++#		$1_SRC_DIR
++#		$1_LIB_FILE
++#		$1_LIB_SPEC
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_LOAD_CONFIG], [
++    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
++
++    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
++        AC_MSG_RESULT([loading])
++	. "${$1_BIN_DIR}/$1Config.sh"
++    else
++        AC_MSG_RESULT([file not found])
++    fi
++
++    #
++    # If the $1_BIN_DIR is the build directory (not the install directory),
++    # then set the common variable name to the value of the build variables.
++    # For example, the variable $1_LIB_SPEC will be set to the value
++    # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC
++    # instead of $1_BUILD_LIB_SPEC since it will work with both an
++    # installed and uninstalled version of Tcl.
++    #
++
++    if test -f "${$1_BIN_DIR}/Makefile" ; then
++	AC_MSG_WARN([Found Makefile - using build library specs for $1])
++        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
++        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
++        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
++        $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
++        $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
++    fi
++
++    AC_SUBST($1_VERSION)
++    AC_SUBST($1_BIN_DIR)
++    AC_SUBST($1_SRC_DIR)
++
++    AC_SUBST($1_LIB_FILE)
++    AC_SUBST($1_LIB_SPEC)
++
++    AC_SUBST($1_STUB_LIB_FILE)
++    AC_SUBST($1_STUB_LIB_SPEC)
++    AC_SUBST($1_STUB_LIB_PATH)
++
++    # Allow the caller to prevent this auto-check by specifying any 2nd arg
++    AS_IF([test "x$2" = x], [
++	# Check both upper and lower-case variants
++	# If a dev wanted non-stubs libs, this function could take an option
++	# to not use _STUB in the paths below
++	AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
++	    [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
++	    [TEA_LOAD_CONFIG_LIB($1_STUB)])
++    ])
++])
++
++#------------------------------------------------------------------------
++# TEA_LOAD_CONFIG_LIB --
++#
++#	Helper function to load correct library from another extension's
++#	${PACKAGE}Config.sh.
++#
++# Results:
++#	Adds to LIBS the appropriate extension library
++#------------------------------------------------------------------------
++AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
++    AC_MSG_CHECKING([For $1 library for LIBS])
++    # This simplifies the use of stub libraries by automatically adding
++    # the stub lib to your path.  Normally this would add to SHLIB_LD_LIBS,
++    # but this is called before CONFIG_CFLAGS.  More importantly, this adds
++    # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
++    if test "x${$1_LIB_SPEC}" != "x" ; then
++	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
++	    TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
++	    AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
++	else
++	    TEA_ADD_LIBS([${$1_LIB_SPEC}])
++	    AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
++	fi
++    else
++	AC_MSG_RESULT([file not found])
++    fi
++])
++
++#------------------------------------------------------------------------
++# TEA_EXPORT_CONFIG --
++#
++#	Define the data to insert into the ${PACKAGE}Config.sh file
++#
++# Arguments:
++#
++#	Requires the following vars to be set:
++#		$1
++#
++# Results:
++#	Substitutes the following vars:
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_EXPORT_CONFIG], [
++    #--------------------------------------------------------------------
++    # These are for $1Config.sh
++    #--------------------------------------------------------------------
++
++    # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
++    eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
++    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
++	eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
++	eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
++    else
++	eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
++	eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
++    fi
++    $1_BUILD_LIB_SPEC="-L`pwd` ${$1_LIB_FLAG}"
++    $1_LIB_SPEC="-L${pkglibdir} ${$1_LIB_FLAG}"
++    $1_BUILD_STUB_LIB_SPEC="-L`pwd` [$]{$1_STUB_LIB_FLAG}"
++    $1_STUB_LIB_SPEC="-L${pkglibdir} [$]{$1_STUB_LIB_FLAG}"
++    $1_BUILD_STUB_LIB_PATH="`pwd`/[$]{PKG_STUB_LIB_FILE}"
++    $1_STUB_LIB_PATH="${pkglibdir}/[$]{PKG_STUB_LIB_FILE}"
++
++    AC_SUBST($1_BUILD_LIB_SPEC)
++    AC_SUBST($1_LIB_SPEC)
++    AC_SUBST($1_BUILD_STUB_LIB_SPEC)
++    AC_SUBST($1_STUB_LIB_SPEC)
++    AC_SUBST($1_BUILD_STUB_LIB_PATH)
++    AC_SUBST($1_STUB_LIB_PATH)
++
++    AC_SUBST(MAJOR_VERSION)
++    AC_SUBST(MINOR_VERSION)
++    AC_SUBST(PATCHLEVEL)
++])
++
++
++#------------------------------------------------------------------------
++# TEA_PATH_CELIB --
++#
++#	Locate Keuchel's celib emulation layer for targeting Win/CE
++#
++# Arguments:
++#	none
++#
++# Results:
++#
++#	Adds the following arguments to configure:
++#		--with-celib=...
++#
++#	Defines the following vars:
++#		CELIB_DIR	Full path to the directory containing
++#				the include and platform lib files
++#------------------------------------------------------------------------
++
++AC_DEFUN([TEA_PATH_CELIB], [
++    # First, look for one uninstalled.
++    # the alternative search directory is invoked by --with-celib
++
++    if test x"${no_celib}" = x ; then
++	# we reset no_celib in case something fails here
++	no_celib=true
++	AC_ARG_WITH(celib,[  --with-celib=DIR        use Windows/CE support library from DIR], with_celibconfig=${withval})
++	AC_MSG_CHECKING([for Windows/CE celib directory])
++	AC_CACHE_VAL(ac_cv_c_celibconfig,[
++	    # First check to see if --with-celibconfig was specified.
++	    if test x"${with_celibconfig}" != x ; then
++		if test -d "${with_celibconfig}/inc" ; then
++		    ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)`
++		else
++		    AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory])
++		fi
++	    fi
++
++	    # then check for a celib library
++	    if test x"${ac_cv_c_celibconfig}" = x ; then
++		for i in \
++			../celib-palm-3.0 \
++			../celib \
++			../../celib-palm-3.0 \
++			../../celib \
++			`ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \
++			${srcdir}/../celib-palm-3.0 \
++			${srcdir}/../celib \
++			`ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \
++			; do
++		    if test -d "$i/inc" ; then
++			ac_cv_c_celibconfig=`(cd $i; pwd)`
++			break
++		    fi
++		done
++	    fi
++	])
++	if test x"${ac_cv_c_celibconfig}" = x ; then
++	    AC_MSG_ERROR([Cannot find celib support library directory])
++	else
++	    no_celib=
++	    CELIB_DIR=${ac_cv_c_celibconfig}
++	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
++	    AC_MSG_RESULT([found $CELIB_DIR])
++	fi
++    fi
++])
++# Local Variables:
++# mode: autoconf
++# End:
+--- contrib/sqlite3/tea/win/makefile.vc.orig
++++ contrib/sqlite3/tea/win/makefile.vc
+@@ -0,0 +1,414 @@
++# makefile.vc --                                               -*- Makefile -*-
++#
++# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
++#
++# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
++# make it suitable as a general package makefile. Look for the word EDIT
++# which marks sections that may need modification. As a minumum you will
++# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
++# relevant to your package.
++#
++# See the file "license.terms" for information on usage and redistribution
++# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
++# 
++# Copyright (c) 1995-1996 Sun Microsystems, Inc.
++# Copyright (c) 1998-2000 Ajuba Solutions.
++# Copyright (c) 2001 ActiveState Corporation.
++# Copyright (c) 2001-2002 David Gravereaux.
++# Copyright (c) 2003 Pat Thoyts
++#
++#-------------------------------------------------------------------------
++# RCS: @(#)$Id: makefile.vc,v 1.4 2004/07/26 08:22:05 patthoyts Exp $
++#-------------------------------------------------------------------------
++
++!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
++MSG = ^
++You will need to run vcvars32.bat from Developer Studio, first, to setup^
++the environment.  Jump to this line to read the new instructions.
++!error $(MSG)
++!endif
++
++#------------------------------------------------------------------------------
++# HOW TO USE this makefile:
++#
++# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
++#     used  as a check to see if vcvars32.bat had been run prior to running
++#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
++#     been set globally and the PATH adjusted.  Either way is valid.
++#
++#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
++#     directory to setup the proper environment, if needed, for your current
++#     setup.  This is a needed bootstrap requirement and allows the swapping of
++#     different environments to be easier.
++#
++# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
++#     vcvars32.bat according to the instructions for it.  This can also turn on
++#     the 64-bit compiler, if your SDK has it.
++#
++# 3)  Targets are:
++#	all       -- Builds everything.
++#       <project> -- Builds the project (eg: nmake sample)
++#	test      -- Builds and runs the test suite.
++#	install   -- Installs the built binaries and libraries to $(INSTALLDIR)
++#		     in an appropriate subdirectory.
++#	clean/realclean/distclean -- varying levels of cleaning.
++#
++# 4)  Macros usable on the commandline:
++#	INSTALLDIR=<path>
++#		Sets where to install Tcl from the built binaries.
++#		C:\Progra~1\Tcl is assumed when not specified.
++#
++#	OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
++#		Sets special options for the core.  The default is for none.
++#		Any combination of the above may be used (comma separated).
++#		'none' will over-ride everything to nothing.
++#
++#		static  =  Builds a static library of the core instead of a
++#			   dll.  The shell will be static (and large), as well.
++#		msvcrt  =  Effects the static option only to switch it from
++#			   using libcmt(d) as the C runtime [by default] to
++#			   msvcrt(d). This is useful for static embedding
++#			   support.
++#		staticpkg = Effects the static option only to switch
++#			   tclshXX.exe to have the dde and reg extension linked
++#			   inside it.
++#		threads =  Turns on full multithreading support.
++#		thrdalloc = Use the thread allocator (shared global free pool).
++#		symbols =  Adds symbols for step debugging.
++#		profile =  Adds profiling hooks.  Map file is assumed.
++#		loimpact =  Adds a flag for how NT treats the heap to keep memory
++#			   in use, low.  This is said to impact alloc performance.
++#
++#	STATS=memdbg,compdbg,none
++#		Sets optional memory and bytecode compiler debugging code added
++#		to the core.  The default is for none.  Any combination of the
++#		above may be used (comma separated).  'none' will over-ride
++#		everything to nothing.
++#
++#		memdbg   = Enables the debugging memory allocator.
++#		compdbg  = Enables byte compilation logging.
++#
++#	MACHINE=(IX86|IA64|ALPHA)
++#		Set the machine type used for the compiler, linker, and
++#		resource compiler.  This hook is needed to tell the tools
++#		when alternate platforms are requested.  IX86 is the default
++#		when not specified.
++#
++#	TMP_DIR=<path>
++#	OUT_DIR=<path>
++#		Hooks to allow the intermediate and output directories to be
++#		changed.  $(OUT_DIR) is assumed to be 
++#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
++#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
++#
++#	TESTPAT=<file>
++#		Reads the tests requested to be run from this file.
++#
++#	CFG_ENCODING=encoding
++#		name of encoding for configuration information. Defaults
++#		to cp1252
++#
++# 5)  Examples:
++#
++#	Basic syntax of calling nmake looks like this:
++#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
++#
++#                        Standard (no frills)
++#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
++#       Setting environment for using Microsoft Visual C++ tools.
++#       c:\tcl_src\win\>nmake -f makefile.vc all
++#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
++#
++#                         Building for Win64
++#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
++#       Setting environment for using Microsoft Visual C++ tools.
++#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
++#       Targeting Windows pre64 RETAIL
++#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
++#
++#------------------------------------------------------------------------------
++#==============================================================================
++###############################################################################
++#------------------------------------------------------------------------------
++
++!if !exist("makefile.vc")
++MSG = ^
++You must run this makefile only from the directory it is in.^
++Please `cd` to its location first.
++!error $(MSG)
++!endif
++
++#-------------------------------------------------------------------------
++# Project specific information (EDIT)
++#
++# You should edit this with the name and version of your project. This
++# information is used to generate the name of the package library and
++# it's install location.
++#
++# For example, the sample extension is  going to build sample04.dll and
++# would install it into $(INSTALLDIR)\lib\sample04
++#
++# You need to specify the object files that need to be linked into your
++# binary here.
++#
++#-------------------------------------------------------------------------
++
++PROJECT = sqlite3
++!include "rules.vc"
++
++# nmakehelp -V <file> <tag> will search the file for tag, skips until a
++#	number and returns all character until a character not in [0-9.ab]
++#	is read.
++
++!if [echo REM = This file is generated from Makefile.vc > versions.vc]
++!endif
++# get project version from row "AC_INIT([sqlite], [3.7.14])"
++!if [echo DOTVERSION = \>> versions.vc] \
++   && [nmakehlp -V ..\configure.in AC_INIT >> versions.vc]
++!endif
++!include "versions.vc"
++
++VERSION         = $(DOTVERSION:.=)
++STUBPREFIX      = $(PROJECT)stub
++
++DLLOBJS = \
++	$(TMP_DIR)\tclsqlite3.obj
++
++#-------------------------------------------------------------------------
++# Target names and paths ( shouldn't need changing )
++#-------------------------------------------------------------------------
++
++BINROOT		= .
++ROOT            = ..
++
++PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
++PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
++PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
++
++PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
++PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
++
++### Make sure we use backslash only.
++PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
++LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
++BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
++DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
++SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
++INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
++
++### The following paths CANNOT have spaces in them.
++GENERICDIR	= $(ROOT)\generic
++WINDIR		= $(ROOT)\win
++LIBDIR          = $(ROOT)\library
++DOCDIR		= $(ROOT)\doc
++TOOLSDIR	= $(ROOT)\tools
++COMPATDIR	= $(ROOT)\compat
++
++#---------------------------------------------------------------------
++# Compile flags
++#---------------------------------------------------------------------
++
++!if !$(DEBUG)
++!if $(OPTIMIZING)
++### This cranks the optimization level to maximize speed
++cdebug	= -O2 -Op -Gs
++!else
++cdebug	=
++!endif
++!else if "$(MACHINE)" == "IA64"
++### Warnings are too many, can't support warnings into errors.
++cdebug	= -Z7 -Od -GZ
++!else
++cdebug	= -Z7 -WX -Od -GZ
++!endif
++
++### Declarations common to all compiler options
++cflags = -nologo -c -W3 -YX -Fp$(TMP_DIR)^\
++
++!if $(MSVCRT)
++!if $(DEBUG)
++crt = -MDd
++!else
++crt = -MD
++!endif
++!else
++!if $(DEBUG)
++crt = -MTd
++!else
++crt = -MT
++!endif
++!endif
++
++INCLUDES	= $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" \
++                  -I"$(ROOT)\.."
++BASE_CLFAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES) \
++                  -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
++                  -DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1
++CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE -DSQLITE_ENABLE_FTS3=1
++TCL_CFLAGS	= -DBUILD_sqlite -DUSE_TCL_STUBS \
++                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" $(BASE_CLFAGS) \
++                  $(OPTDEFINES)
++
++#---------------------------------------------------------------------
++# Link flags
++#---------------------------------------------------------------------
++
++!if $(DEBUG)
++ldebug	= -debug:full -debugtype:cv
++!else
++ldebug	= -release -opt:ref -opt:icf,3
++!endif
++
++### Declarations common to all linker options
++lflags	= -nologo -machine:$(MACHINE) $(ldebug)
++
++!if $(PROFILE)
++lflags	= $(lflags) -profile
++!endif
++
++!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
++### Align sections for PE size savings.
++lflags	= $(lflags) -opt:nowin98
++!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
++### Align sections for speed in loading by choosing the virtual page size.
++lflags	= $(lflags) -align:4096
++!endif
++
++!if $(LOIMPACT)
++lflags	= $(lflags) -ws:aggressive
++!endif
++
++dlllflags = $(lflags) -dll
++conlflags = $(lflags) -subsystem:console
++guilflags = $(lflags) -subsystem:windows
++baselibs   = $(TCLSTUBLIB)
++
++#---------------------------------------------------------------------
++# TclTest flags
++#---------------------------------------------------------------------
++
++!IF "$(TESTPAT)" != ""
++TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
++!ENDIF
++
++#---------------------------------------------------------------------
++# Project specific targets (EDIT)
++#---------------------------------------------------------------------
++
++all:	    setup $(PROJECT)
++$(PROJECT): setup $(PRJLIB)
++install:    install-binaries install-libraries install-docs
++
++# Tests need to ensure we load the right dll file we
++# have to handle the output differently on Win9x.
++#
++!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
++test: setup $(PROJECT)
++        set TCL_LIBRARY=$(ROOT)/library
++        $(TCLSH) <<
++load $(PRJLIB:\=/)
++cd "$(ROOT)/tests"
++set argv "$(TESTFLAGS)"
++source all.tcl
++<<
++!else
++test: setup $(PROJECT)
++        echo Please wait while the test results are collected
++        set TCL_LIBRARY=$(ROOT)/library
++        $(TCLSH) << >tests.log
++load $(PRJLIB:\=/)
++cd "$(ROOT)/tests"
++set argv "$(TESTFLAGS)"
++source all.tcl
++<<
++        type tests.log | more
++!endif
++
++setup:
++	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
++	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
++
++$(PRJLIB): $(DLLOBJS)
++	$(link32) $(dlllflags) -out:$@ $(baselibs) @<<
++$**
++<<
++	-@del $*.exp
++
++$(PRJSTUBLIB): $(PRJSTUBOBJS)
++	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
++
++#---------------------------------------------------------------------
++# Implicit rules
++#---------------------------------------------------------------------
++
++{$(WINDIR)}.c{$(TMP_DIR)}.obj::
++    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
++$<
++<<
++
++{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
++    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
++$<
++<<
++
++{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
++    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
++$<
++<<
++
++{$(WINDIR)}.rc{$(TMP_DIR)}.res:
++	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
++!if $(DEBUG)
++	-d DEBUG \
++!endif
++!if $(TCL_THREADS)
++	-d TCL_THREADS \
++!endif
++!if $(STATIC_BUILD)
++	-d STATIC_BUILD \
++!endif
++	$<
++
++.SUFFIXES:
++.SUFFIXES:.c .rc
++
++#---------------------------------------------------------------------
++# Installation. (EDIT)
++#
++# You may need to modify this section to reflect the final distribution
++# of your files and possibly to generate documentation.
++#
++#---------------------------------------------------------------------
++
++install-binaries:
++	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
++	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
++	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
++
++install-libraries:
++        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
++        @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
++        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
++        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
++package ifneeded $(PROJECT) $(DOTVERSION) \
++    [list load [file join $$dir $(PRJLIBNAME)] sqlite3]
++<<
++
++install-docs:
++	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
++	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
++
++#---------------------------------------------------------------------
++# Clean up
++#---------------------------------------------------------------------
++
++clean:
++	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
++	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
++
++realclean: clean
++	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
++
++distclean: realclean
++	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
++	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+--- contrib/sqlite3/tea/win/nmakehlp.c.orig
++++ contrib/sqlite3/tea/win/nmakehlp.c
+@@ -0,0 +1,694 @@
++/*
++ * ----------------------------------------------------------------------------
++ * nmakehlp.c --
++ *
++ *	This is used to fix limitations within nmake and the environment.
++ *
++ * Copyright (c) 2002 by David Gravereaux.
++ * Copyright (c) 2006 by Pat Thoyts
++ *
++ * See the file "license.terms" for information on usage and redistribution of
++ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
++ * ----------------------------------------------------------------------------
++ */
++
++#define _CRT_SECURE_NO_DEPRECATE
++#include <windows.h>
++#define NO_SHLWAPI_GDI
++#define NO_SHLWAPI_STREAM
++#define NO_SHLWAPI_REG
++#include <shlwapi.h>
++#pragma comment (lib, "user32.lib")
++#pragma comment (lib, "kernel32.lib")
++#pragma comment (lib, "shlwapi.lib")
++#include <stdio.h>
++#include <math.h>
++
++/*
++ * This library is required for x64 builds with _some_ versions of MSVC
++ */
++#if defined(_M_IA64) || defined(_M_AMD64)
++#if _MSC_VER >= 1400 && _MSC_VER < 1500
++#pragma comment(lib, "bufferoverflowU")
++#endif
++#endif
++
++/* ISO hack for dumb VC++ */
++#ifdef _MSC_VER
++#define   snprintf	_snprintf
++#endif
++
++
++
++/* protos */
++
++static int CheckForCompilerFeature(const char *option);
++static int CheckForLinkerFeature(const char *option);
++static int IsIn(const char *string, const char *substring);
++static int SubstituteFile(const char *substs, const char *filename);
++static int QualifyPath(const char *path);
++static const char *GetVersionFromFile(const char *filename, const char *match);
++static DWORD WINAPI ReadFromPipe(LPVOID args);
++
++/* globals */
++
++#define CHUNK	25
++#define STATICBUFFERSIZE    1000
++typedef struct {
++    HANDLE pipe;
++    char buffer[STATICBUFFERSIZE];
++} pipeinfo;
++
++pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
++pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
++
++/*
++ * exitcodes: 0 == no, 1 == yes, 2 == error
++ */
++
++int
++main(
++    int argc,
++    char *argv[])
++{
++    char msg[300];
++    DWORD dwWritten;
++    int chars;
++
++    /*
++     * Make sure children (cl.exe and link.exe) are kept quiet.
++     */
++
++    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
++
++    /*
++     * Make sure the compiler and linker aren't effected by the outside world.
++     */
++
++    SetEnvironmentVariable("CL", "");
++    SetEnvironmentVariable("LINK", "");
++
++    if (argc > 1 && *argv[1] == '-') {
++	switch (*(argv[1]+1)) {
++	case 'c':
++	    if (argc != 3) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++		        "usage: %s -c <compiler option>\n"
++			"Tests for whether cl.exe supports an option\n"
++			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++			&dwWritten, NULL);
++		return 2;
++	    }
++	    return CheckForCompilerFeature(argv[2]);
++	case 'l':
++	    if (argc != 3) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++	       		"usage: %s -l <linker option>\n"
++			"Tests for whether link.exe supports an option\n"
++			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++			&dwWritten, NULL);
++		return 2;
++	    }
++	    return CheckForLinkerFeature(argv[2]);
++	case 'f':
++	    if (argc == 2) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++			"usage: %s -f <string> <substring>\n"
++			"Find a substring within another\n"
++			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++			&dwWritten, NULL);
++		return 2;
++	    } else if (argc == 3) {
++		/*
++		 * If the string is blank, there is no match.
++		 */
++
++		return 0;
++	    } else {
++		return IsIn(argv[2], argv[3]);
++	    }
++	case 's':
++	    if (argc == 2) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++			"usage: %s -s <substitutions file> <file>\n"
++			"Perform a set of string map type substutitions on a file\n"
++			"exitcodes: 0\n",
++			argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++			&dwWritten, NULL);
++		return 2;
++	    }
++	    return SubstituteFile(argv[2], argv[3]);
++	case 'V':
++	    if (argc != 4) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++		    "usage: %s -V filename matchstring\n"
++		    "Extract a version from a file:\n"
++		    "eg: pkgIndex.tcl \"package ifneeded http\"",
++		    argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++		    &dwWritten, NULL);
++		return 0;
++	    }
++	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
++	    return 0;
++	case 'Q':
++	    if (argc != 3) {
++		chars = snprintf(msg, sizeof(msg) - 1,
++		    "usage: %s -Q path\n"
++		    "Emit the fully qualified path\n"
++		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
++		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
++		    &dwWritten, NULL);
++		return 2;
++	    }
++	    return QualifyPath(argv[2]);
++	}
++    }
++    chars = snprintf(msg, sizeof(msg) - 1,
++	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
++	    "This is a little helper app to equalize shell differences between WinNT and\n"
++	    "Win9x and get nmake.exe to accomplish its job.\n",
++	    argv[0]);
++    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
++    return 2;
++}
++
++static int
++CheckForCompilerFeature(
++    const char *option)
++{
++    STARTUPINFO si;
++    PROCESS_INFORMATION pi;
++    SECURITY_ATTRIBUTES sa;
++    DWORD threadID;
++    char msg[300];
++    BOOL ok;
++    HANDLE hProcess, h, pipeThreads[2];
++    char cmdline[100];
++
++    hProcess = GetCurrentProcess();
++
++    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
++    ZeroMemory(&si, sizeof(STARTUPINFO));
++    si.cb = sizeof(STARTUPINFO);
++    si.dwFlags   = STARTF_USESTDHANDLES;
++    si.hStdInput = INVALID_HANDLE_VALUE;
++
++    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
++    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
++    sa.lpSecurityDescriptor = NULL;
++    sa.bInheritHandle = FALSE;
++
++    /*
++     * Create a non-inheritible pipe.
++     */
++
++    CreatePipe(&Out.pipe, &h, &sa, 0);
++
++    /*
++     * Dupe the write side, make it inheritible, and close the original.
++     */
++
++    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
++	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
++
++    /*
++     * Same as above, but for the error side.
++     */
++
++    CreatePipe(&Err.pipe, &h, &sa, 0);
++    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
++	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
++
++    /*
++     * Base command line.
++     */
++
++    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
++
++    /*
++     * Append our option for testing
++     */
++
++    lstrcat(cmdline, option);
++
++    /*
++     * Filename to compile, which exists, but is nothing and empty.
++     */
++
++    lstrcat(cmdline, " .\\nul");
++
++    ok = CreateProcess(
++	    NULL,	    /* Module name. */
++	    cmdline,	    /* Command line. */
++	    NULL,	    /* Process handle not inheritable. */
++	    NULL,	    /* Thread handle not inheritable. */
++	    TRUE,	    /* yes, inherit handles. */
++	    DETACHED_PROCESS, /* No console for you. */
++	    NULL,	    /* Use parent's environment block. */
++	    NULL,	    /* Use parent's starting directory. */
++	    &si,	    /* Pointer to STARTUPINFO structure. */
++	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
++
++    if (!ok) {
++	DWORD err = GetLastError();
++	int chars = snprintf(msg, sizeof(msg) - 1,
++		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
++
++	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
++		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
++		(300-chars), 0);
++	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
++	return 2;
++    }
++
++    /*
++     * Close our references to the write handles that have now been inherited.
++     */
++
++    CloseHandle(si.hStdOutput);
++    CloseHandle(si.hStdError);
++
++    WaitForInputIdle(pi.hProcess, 5000);
++    CloseHandle(pi.hThread);
++
++    /*
++     * Start the pipe reader threads.
++     */
++
++    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
++    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
++
++    /*
++     * Block waiting for the process to end.
++     */
++
++    WaitForSingleObject(pi.hProcess, INFINITE);
++    CloseHandle(pi.hProcess);
++
++    /*
++     * Wait for our pipe to get done reading, should it be a little slow.
++     */
++
++    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
++    CloseHandle(pipeThreads[0]);
++    CloseHandle(pipeThreads[1]);
++
++    /*
++     * Look for the commandline warning code in both streams.
++     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
++     */
++
++    return !(strstr(Out.buffer, "D4002") != NULL
++             || strstr(Err.buffer, "D4002") != NULL
++             || strstr(Out.buffer, "D9002") != NULL
++             || strstr(Err.buffer, "D9002") != NULL
++             || strstr(Out.buffer, "D2021") != NULL
++             || strstr(Err.buffer, "D2021") != NULL);
++}
++
++static int
++CheckForLinkerFeature(
++    const char *option)
++{
++    STARTUPINFO si;
++    PROCESS_INFORMATION pi;
++    SECURITY_ATTRIBUTES sa;
++    DWORD threadID;
++    char msg[300];
++    BOOL ok;
++    HANDLE hProcess, h, pipeThreads[2];
++    char cmdline[100];
++
++    hProcess = GetCurrentProcess();
++
++    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
++    ZeroMemory(&si, sizeof(STARTUPINFO));
++    si.cb = sizeof(STARTUPINFO);
++    si.dwFlags   = STARTF_USESTDHANDLES;
++    si.hStdInput = INVALID_HANDLE_VALUE;
++
++    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
++    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
++    sa.lpSecurityDescriptor = NULL;
++    sa.bInheritHandle = TRUE;
++
++    /*
++     * Create a non-inheritible pipe.
++     */
++
++    CreatePipe(&Out.pipe, &h, &sa, 0);
++
++    /*
++     * Dupe the write side, make it inheritible, and close the original.
++     */
++
++    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
++	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
++
++    /*
++     * Same as above, but for the error side.
++     */
++
++    CreatePipe(&Err.pipe, &h, &sa, 0);
++    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
++	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
++
++    /*
++     * Base command line.
++     */
++
++    lstrcpy(cmdline, "link.exe -nologo ");
++
++    /*
++     * Append our option for testing.
++     */
++
++    lstrcat(cmdline, option);
++
++    ok = CreateProcess(
++	    NULL,	    /* Module name. */
++	    cmdline,	    /* Command line. */
++	    NULL,	    /* Process handle not inheritable. */
++	    NULL,	    /* Thread handle not inheritable. */
++	    TRUE,	    /* yes, inherit handles. */
++	    DETACHED_PROCESS, /* No console for you. */
++	    NULL,	    /* Use parent's environment block. */
++	    NULL,	    /* Use parent's starting directory. */
++	    &si,	    /* Pointer to STARTUPINFO structure. */
++	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
++
++    if (!ok) {
++	DWORD err = GetLastError();
++	int chars = snprintf(msg, sizeof(msg) - 1,
++		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
++
++	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
++		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
++		(300-chars), 0);
++	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
++	return 2;
++    }
++
++    /*
++     * Close our references to the write handles that have now been inherited.
++     */
++
++    CloseHandle(si.hStdOutput);
++    CloseHandle(si.hStdError);
++
++    WaitForInputIdle(pi.hProcess, 5000);
++    CloseHandle(pi.hThread);
++
++    /*
++     * Start the pipe reader threads.
++     */
++
++    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
++    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
++
++    /*
++     * Block waiting for the process to end.
++     */
++
++    WaitForSingleObject(pi.hProcess, INFINITE);
++    CloseHandle(pi.hProcess);
++
++    /*
++     * Wait for our pipe to get done reading, should it be a little slow.
++     */
++
++    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
++    CloseHandle(pipeThreads[0]);
++    CloseHandle(pipeThreads[1]);
++
++    /*
++     * Look for the commandline warning code in the stderr stream.
++     */
++
++    return !(strstr(Out.buffer, "LNK1117") != NULL ||
++	    strstr(Err.buffer, "LNK1117") != NULL ||
++	    strstr(Out.buffer, "LNK4044") != NULL ||
++	    strstr(Err.buffer, "LNK4044") != NULL);
++}
++
++static DWORD WINAPI
++ReadFromPipe(
++    LPVOID args)
++{
++    pipeinfo *pi = (pipeinfo *) args;
++    char *lastBuf = pi->buffer;
++    DWORD dwRead;
++    BOOL ok;
++
++  again:
++    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
++	CloseHandle(pi->pipe);
++	return (DWORD)-1;
++    }
++    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
++    if (!ok || dwRead == 0) {
++	CloseHandle(pi->pipe);
++	return 0;
++    }
++    lastBuf += dwRead;
++    goto again;
++
++    return 0;  /* makes the compiler happy */
++}
++
++static int
++IsIn(
++    const char *string,
++    const char *substring)
++{
++    return (strstr(string, substring) != NULL);
++}
++
++/*
++ * GetVersionFromFile --
++ * 	Looks for a match string in a file and then returns the version
++ * 	following the match where a version is anything acceptable to
++ * 	package provide or package ifneeded.
++ */
++
++static const char *
++GetVersionFromFile(
++    const char *filename,
++    const char *match)
++{
++    size_t cbBuffer = 100;
++    static char szBuffer[100];
++    char *szResult = NULL;
++    FILE *fp = fopen(filename, "rt");
++
++    if (fp != NULL) {
++	/*
++	 * Read data until we see our match string.
++	 */
++
++	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
++	    LPSTR p, q;
++
++	    p = strstr(szBuffer, match);
++	    if (p != NULL) {
++		/*
++		 * Skip to first digit.
++		 */
++
++		while (*p && !isdigit(*p)) {
++		    ++p;
++		}
++
++		/*
++		 * Find ending whitespace.
++		 */
++
++		q = p;
++		while (*q && (isalnum(*q) || *q == '.')) {
++		    ++q;
++		}
++
++		memcpy(szBuffer, p, q - p);
++		szBuffer[q-p] = 0;
++		szResult = szBuffer;
++		break;
++	    }
++	}
++	fclose(fp);
++    }
++    return szResult;
++}
++
++/*
++ * List helpers for the SubstituteFile function
++ */
++
++typedef struct list_item_t {
++    struct list_item_t *nextPtr;
++    char * key;
++    char * value;
++} list_item_t;
++
++/* insert a list item into the list (list may be null) */
++static list_item_t *
++list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
++{
++    list_item_t *itemPtr = malloc(sizeof(list_item_t));
++    if (itemPtr) {
++	itemPtr->key = strdup(key);
++	itemPtr->value = strdup(value);
++	itemPtr->nextPtr = NULL;
++
++	while(*listPtrPtr) {
++	    listPtrPtr = &(*listPtrPtr)->nextPtr;
++	}
++	*listPtrPtr = itemPtr;
++    }
++    return itemPtr;
++}
++
++static void
++list_free(list_item_t **listPtrPtr)
++{
++    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
++    while (listPtr) {
++	tmpPtr = listPtr;
++	listPtr = listPtr->nextPtr;
++	free(tmpPtr->key);
++	free(tmpPtr->value);
++	free(tmpPtr);
++    }
++}
++
++/*
++ * SubstituteFile --
++ *	As windows doesn't provide anything useful like sed and it's unreliable
++ *	to use the tclsh you are building against (consider x-platform builds -
++ *	eg compiling AMD64 target from IX86) we provide a simple substitution
++ *	option here to handle autoconf style substitutions.
++ *	The substitution file is whitespace and line delimited. The file should
++ *	consist of lines matching the regular expression:
++ *	  \s*\S+\s+\S*$
++ *
++ *	Usage is something like:
++ *	  nmakehlp -S << $** > $@
++ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
++ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
++ *        <<
++ */
++
++static int
++SubstituteFile(
++    const char *substitutions,
++    const char *filename)
++{
++    size_t cbBuffer = 1024;
++    static char szBuffer[1024], szCopy[1024];
++    char *szResult = NULL;
++    list_item_t *substPtr = NULL;
++    FILE *fp, *sp;
++
++    fp = fopen(filename, "rt");
++    if (fp != NULL) {
++
++	/*
++	 * Build a list of substutitions from the first filename
++	 */
++
++	sp = fopen(substitutions, "rt");
++	if (sp != NULL) {
++	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
++		unsigned char *ks, *ke, *vs, *ve;
++		ks = (unsigned char*)szBuffer;
++		while (ks && *ks && isspace(*ks)) ++ks;
++		ke = ks;
++		while (ke && *ke && !isspace(*ke)) ++ke;
++		vs = ke;
++		while (vs && *vs && isspace(*vs)) ++vs;
++		ve = vs;
++		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
++		*ke = 0, *ve = 0;
++		list_insert(&substPtr, (char*)ks, (char*)vs);
++	    }
++	    fclose(sp);
++	}
++
++	/* debug: dump the list */
++#ifdef _DEBUG
++	{
++	    int n = 0;
++	    list_item_t *p = NULL;
++	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
++		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
++	    }
++	}
++#endif
++	
++	/*
++	 * Run the substitutions over each line of the input
++	 */
++	
++	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
++	    list_item_t *p = NULL;
++	    for (p = substPtr; p != NULL; p = p->nextPtr) {
++		char *m = strstr(szBuffer, p->key);
++		if (m) {
++		    char *cp, *op, *sp;
++		    cp = szCopy;
++		    op = szBuffer;
++		    while (op != m) *cp++ = *op++;
++		    sp = p->value;
++		    while (sp && *sp) *cp++ = *sp++;
++		    op += strlen(p->key);
++		    while (*op) *cp++ = *op++;
++		    *cp = 0;
++		    memcpy(szBuffer, szCopy, sizeof(szCopy));
++		}
++	    }
++	    printf(szBuffer);
++	}
++	
++	list_free(&substPtr);
++    }
++    fclose(fp);
++    return 0;
++}
++
++/*
++ * QualifyPath --
++ *
++ *	This composes the current working directory with a provided path
++ *	and returns the fully qualified and normalized path.
++ *	Mostly needed to setup paths for testing.
++ */
++
++static int
++QualifyPath(
++    const char *szPath)
++{
++    char szCwd[MAX_PATH + 1];
++    char szTmp[MAX_PATH + 1];
++    char *p;
++    GetCurrentDirectory(MAX_PATH, szCwd);
++    while ((p = strchr(szPath, '/')) && *p)
++	*p = '\\';
++    PathCombine(szTmp, szCwd, szPath);
++    PathCanonicalize(szCwd, szTmp);
++    printf("%s\n", szCwd);
++    return 0;
++}
++
++/*
++ * Local variables:
++ *   mode: c
++ *   c-basic-offset: 4
++ *   fill-column: 78
++ *   indent-tabs-mode: t
++ *   tab-width: 8
++ * End:
++ */
+--- contrib/sqlite3/tea/win/rules.vc.orig
++++ contrib/sqlite3/tea/win/rules.vc
+@@ -0,0 +1,711 @@
++#------------------------------------------------------------------------------
++# rules.vc --
++#
++#	Microsoft Visual C++ makefile include for decoding the commandline
++#	macros.  This file does not need editing to build Tcl.
++#
++# See the file "license.terms" for information on usage and redistribution
++# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
++#
++# Copyright (c) 2001-2003 David Gravereaux.
++# Copyright (c) 2003-2008 Patrick Thoyts
++#------------------------------------------------------------------------------
++
++!ifndef _RULES_VC
++_RULES_VC = 1
++
++cc32		= $(CC)   # built-in default.
++link32		= link
++lib32		= lib
++rc32		= $(RC)   # built-in default.
++
++!ifndef INSTALLDIR
++### Assume the normal default.
++_INSTALLDIR	= C:\Program Files\Tcl
++!else
++### Fix the path separators.
++_INSTALLDIR	= $(INSTALLDIR:/=\)
++!endif
++
++#----------------------------------------------------------
++# Set the proper copy method to avoid overwrite questions
++# to the user when copying files and selecting the right
++# "delete all" method.
++#----------------------------------------------------------
++
++!if "$(OS)" == "Windows_NT"
++RMDIR	= rmdir /S /Q
++ERRNULL  = 2>NUL
++!if ![ver | find "4.0" > nul]
++CPY	= echo y | xcopy /i >NUL
++COPY	= copy >NUL
++!else
++CPY	= xcopy /i /y >NUL
++COPY	= copy /y >NUL
++!endif
++!else # "$(OS)" != "Windows_NT"
++CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
++COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
++RMDIR	= deltree /Y
++NULL    = \NUL # Used in testing directory existence
++ERRNULL = >NUL # Win9x shell cannot redirect stderr
++!endif
++MKDIR   = mkdir
++
++#------------------------------------------------------------------------------
++# Determine the host and target architectures and compiler version.
++#------------------------------------------------------------------------------
++
++_HASH=^#
++_VC_MANIFEST_EMBED_EXE=
++_VC_MANIFEST_EMBED_DLL=
++VCVER=0
++!if ![echo VCVERSION=_MSC_VER > vercl.x] \
++    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
++    && ![echo ARCH=IX86 >> vercl.x] \
++    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
++    && ![echo ARCH=AMD64 >> vercl.x] \
++    && ![echo $(_HASH)endif >> vercl.x] \
++    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
++!include vercl.i
++!if ![echo VCVER= ^\> vercl.vc] \
++    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
++!include vercl.vc
++!endif
++!endif
++!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
++!endif
++
++!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
++NATIVE_ARCH=IX86
++!else
++NATIVE_ARCH=AMD64
++!endif
++
++# Since MSVC8 we must deal with manifest resources.
++!if $(VCVERSION) >= 1400
++_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
++_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
++!endif
++
++!ifndef MACHINE
++MACHINE=$(ARCH)
++!endif
++
++!ifndef CFG_ENCODING
++CFG_ENCODING	= \"cp1252\"
++!endif
++
++!message ===============================================================================
++
++#----------------------------------------------------------
++# build the helper app we need to overcome nmake's limiting
++# environment.
++#----------------------------------------------------------
++
++!if !exist(nmakehlp.exe)
++!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
++!endif
++!endif
++
++#----------------------------------------------------------
++# Test for compiler features
++#----------------------------------------------------------
++
++### test for optimizations
++!if [nmakehlp -c -Ot]
++!message *** Compiler has 'Optimizations'
++OPTIMIZING	= 1
++!else
++!message *** Compiler does not have 'Optimizations'
++OPTIMIZING	= 0
++!endif
++
++OPTIMIZATIONS   =
++
++!if [nmakehlp -c -Ot]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
++!endif
++
++!if [nmakehlp -c -Oi]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
++!endif
++
++!if [nmakehlp -c -Op]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
++!endif
++
++!if [nmakehlp -c -fp:strict]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
++!endif
++
++!if [nmakehlp -c -Gs]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
++!endif
++
++!if [nmakehlp -c -GS]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
++!endif
++
++!if [nmakehlp -c -GL]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
++!endif
++
++DEBUGFLAGS     =
++
++!if [nmakehlp -c -RTC1]
++DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
++!elseif [nmakehlp -c -GZ]
++DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
++!endif
++
++COMPILERFLAGS  =-W3 -DUNICODE -D_UNICODE
++
++# In v13 -GL and -YX are incompatible.
++!if [nmakehlp -c -YX]
++!if ![nmakehlp -c -GL]
++OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
++!endif
++!endif
++
++!if "$(MACHINE)" == "IX86"
++### test for pentium errata
++!if [nmakehlp -c -QI0f]
++!message *** Compiler has 'Pentium 0x0f fix'
++COMPILERFLAGS  = $(COMPILERFLAGS) -QI0f
++!else
++!message *** Compiler does not have 'Pentium 0x0f fix'
++!endif
++!endif
++
++!if "$(MACHINE)" == "IA64"
++### test for Itanium errata
++!if [nmakehlp -c -QIA64_Bx]
++!message *** Compiler has 'B-stepping errata workarounds'
++COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
++!else
++!message *** Compiler does not have 'B-stepping errata workarounds'
++!endif
++!endif
++
++!if "$(MACHINE)" == "IX86"
++### test for -align:4096, when align:512 will do.
++!if [nmakehlp -l -opt:nowin98]
++!message *** Linker has 'Win98 alignment problem'
++ALIGN98_HACK	= 1
++!else
++!message *** Linker does not have 'Win98 alignment problem'
++ALIGN98_HACK	= 0
++!endif
++!else
++ALIGN98_HACK	= 0
++!endif
++
++LINKERFLAGS     =
++
++!if [nmakehlp -l -ltcg]
++LINKERFLAGS     =-ltcg
++!endif
++
++#----------------------------------------------------------
++# Decode the options requested.
++#----------------------------------------------------------
++
++!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
++STATIC_BUILD	= 0
++TCL_THREADS	= 1
++DEBUG		= 0
++SYMBOLS		= 0
++PROFILE		= 0
++PGO		= 0
++MSVCRT		= 0
++LOIMPACT	= 0
++TCL_USE_STATIC_PACKAGES	= 0
++USE_THREAD_ALLOC = 1
++UNCHECKED	= 0
++!else
++!if [nmakehlp -f $(OPTS) "static"]
++!message *** Doing static
++STATIC_BUILD	= 1
++!else
++STATIC_BUILD	= 0
++!endif
++!if [nmakehlp -f $(OPTS) "msvcrt"]
++!message *** Doing msvcrt
++MSVCRT		= 1
++!else
++MSVCRT		= 0
++!endif
++!if [nmakehlp -f $(OPTS) "staticpkg"]
++!message *** Doing staticpkg
++TCL_USE_STATIC_PACKAGES	= 1
++!else
++TCL_USE_STATIC_PACKAGES	= 0
++!endif
++!if [nmakehlp -f $(OPTS) "nothreads"]
++!message *** Compile explicitly for non-threaded tcl
++TCL_THREADS	= 0
++!else
++TCL_THREADS	= 1
++USE_THREAD_ALLOC= 1
++!endif
++!if [nmakehlp -f $(OPTS) "symbols"]
++!message *** Doing symbols
++DEBUG		= 1
++!else
++DEBUG		= 0
++!endif
++!if [nmakehlp -f $(OPTS) "pdbs"]
++!message *** Doing pdbs
++SYMBOLS		= 1
++!else
++SYMBOLS		= 0
++!endif
++!if [nmakehlp -f $(OPTS) "profile"]
++!message *** Doing profile
++PROFILE		= 1
++!else
++PROFILE		= 0
++!endif
++!if [nmakehlp -f $(OPTS) "pgi"]
++!message *** Doing profile guided optimization instrumentation
++PGO		= 1
++!elseif [nmakehlp -f $(OPTS) "pgo"]
++!message *** Doing profile guided optimization
++PGO		= 2
++!else
++PGO		= 0
++!endif
++!if [nmakehlp -f $(OPTS) "loimpact"]
++!message *** Doing loimpact
++LOIMPACT	= 1
++!else
++LOIMPACT	= 0
++!endif
++!if [nmakehlp -f $(OPTS) "thrdalloc"]
++!message *** Doing thrdalloc
++USE_THREAD_ALLOC = 1
++!endif
++!if [nmakehlp -f $(OPTS) "tclalloc"]
++!message *** Doing tclalloc
++USE_THREAD_ALLOC = 0
++!endif
++!if [nmakehlp -f $(OPTS) "unchecked"]
++!message *** Doing unchecked
++UNCHECKED = 1
++!else
++UNCHECKED = 0
++!endif
++!endif
++
++
++!if !$(STATIC_BUILD)
++# Make sure we don't build overly fat DLLs.
++MSVCRT		= 1
++# We shouldn't statically put the extensions inside the shell when dynamic.
++TCL_USE_STATIC_PACKAGES = 0
++!endif
++
++
++#----------------------------------------------------------
++# Figure-out how to name our intermediate and output directories.
++# We wouldn't want different builds to use the same .obj files
++# by accident.
++#----------------------------------------------------------
++
++#----------------------------------------
++# Naming convention:
++#   t = full thread support.
++#   s = static library (as opposed to an
++#	import library)
++#   g = linked to the debug enabled C
++#	run-time.
++#   x = special static build when it
++#	links to the dynamic C run-time.
++#----------------------------------------
++SUFX	    = tsgx
++
++!if $(DEBUG)
++BUILDDIRTOP = Debug
++!else
++BUILDDIRTOP = Release
++!endif
++
++!if "$(MACHINE)" != "IX86"
++BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
++!endif
++!if $(VCVER) > 6
++BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
++!endif
++
++!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
++SUFX	    = $(SUFX:g=)
++!endif
++
++TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
++
++!if !$(STATIC_BUILD)
++TMP_DIRFULL = $(TMP_DIRFULL:Static=)
++SUFX	    = $(SUFX:s=)
++EXT	    = dll
++!if $(MSVCRT)
++TMP_DIRFULL = $(TMP_DIRFULL:X=)
++SUFX	    = $(SUFX:x=)
++!endif
++!else
++TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
++EXT	    = lib
++!if !$(MSVCRT)
++TMP_DIRFULL = $(TMP_DIRFULL:X=)
++SUFX	    = $(SUFX:x=)
++!endif
++!endif
++
++!if !$(TCL_THREADS)
++TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
++SUFX	    = $(SUFX:t=)
++!endif
++
++!ifndef TMP_DIR
++TMP_DIR	    = $(TMP_DIRFULL)
++!ifndef OUT_DIR
++OUT_DIR	    = .\$(BUILDDIRTOP)
++!endif
++!else
++!ifndef OUT_DIR
++OUT_DIR	    = $(TMP_DIR)
++!endif
++!endif
++
++
++#----------------------------------------------------------
++# Decode the statistics requested.
++#----------------------------------------------------------
++
++!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
++TCL_MEM_DEBUG	    = 0
++TCL_COMPILE_DEBUG   = 0
++!else
++!if [nmakehlp -f $(STATS) "memdbg"]
++!message *** Doing memdbg
++TCL_MEM_DEBUG	    = 1
++!else
++TCL_MEM_DEBUG	    = 0
++!endif
++!if [nmakehlp -f $(STATS) "compdbg"]
++!message *** Doing compdbg
++TCL_COMPILE_DEBUG   = 1
++!else
++TCL_COMPILE_DEBUG   = 0
++!endif
++!endif
++
++
++#----------------------------------------------------------
++# Decode the checks requested.
++#----------------------------------------------------------
++
++!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
++TCL_NO_DEPRECATED	    = 0
++WARNINGS		    = -W3
++!else
++!if [nmakehlp -f $(CHECKS) "nodep"]
++!message *** Doing nodep check
++TCL_NO_DEPRECATED	    = 1
++!else
++TCL_NO_DEPRECATED	    = 0
++!endif
++!if [nmakehlp -f $(CHECKS) "fullwarn"]
++!message *** Doing full warnings check
++WARNINGS		    = -W4
++!if [nmakehlp -l -warn:3]
++LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
++!endif
++!else
++WARNINGS		    = -W3
++!endif
++!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
++!message *** Doing 64bit portability warnings
++WARNINGS		    = $(WARNINGS) -Wp64
++!endif
++!endif
++
++!if $(PGO) > 1
++!if [nmakehlp -l -ltcg:pgoptimize]
++LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
++!else
++MSG=^
++This compiler does not support profile guided optimization.
++!error $(MSG)
++!endif
++!elseif $(PGO) > 0
++!if [nmakehlp -l -ltcg:pginstrument]
++LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
++!else
++MSG=^
++This compiler does not support profile guided optimization.
++!error $(MSG)
++!endif
++!endif
++
++#----------------------------------------------------------
++# Set our defines now armed with our options.
++#----------------------------------------------------------
++
++OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
++
++!if $(TCL_MEM_DEBUG)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
++!endif
++!if $(TCL_COMPILE_DEBUG)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
++!endif
++!if $(TCL_THREADS)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
++!if $(USE_THREAD_ALLOC)
++OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
++!endif
++!endif
++!if $(STATIC_BUILD)
++OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
++!endif
++!if $(TCL_NO_DEPRECATED)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
++!endif
++
++!if !$(DEBUG)
++OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
++!if $(OPTIMIZING)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
++!endif
++!endif
++!if $(PROFILE)
++OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
++!endif
++!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
++OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
++!endif
++!if $(VCVERSION) < 1300
++OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
++!endif
++
++#----------------------------------------------------------
++# Locate the Tcl headers to build against
++#----------------------------------------------------------
++
++!if "$(PROJECT)" == "tcl"
++
++_TCL_H          = ..\generic\tcl.h
++
++!else
++
++# If INSTALLDIR set to tcl root dir then reset to the lib dir.
++!if exist("$(_INSTALLDIR)\include\tcl.h")
++_INSTALLDIR=$(_INSTALLDIR)\lib
++!endif
++
++!if !defined(TCLDIR)
++!if exist("$(_INSTALLDIR)\..\include\tcl.h")
++TCLINSTALL	= 1
++_TCLDIR		= $(_INSTALLDIR)\..
++_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
++TCLDIR          = $(_INSTALLDIR)\..
++!else
++MSG=^
++Failed to find tcl.h.  Set the TCLDIR macro.
++!error $(MSG)
++!endif
++!else
++_TCLDIR	= $(TCLDIR:/=\)
++!if exist("$(_TCLDIR)\include\tcl.h")
++TCLINSTALL	= 1
++_TCL_H          = $(_TCLDIR)\include\tcl.h
++!elseif exist("$(_TCLDIR)\generic\tcl.h")
++TCLINSTALL	= 0
++_TCL_H          = $(_TCLDIR)\generic\tcl.h
++!else
++MSG =^
++Failed to find tcl.h.  The TCLDIR macro does not appear correct.
++!error $(MSG)
++!endif
++!endif
++!endif
++
++#--------------------------------------------------------------
++# Extract various version numbers from tcl headers
++# The generated file is then included in the makefile.
++#--------------------------------------------------------------
++
++!if [echo REM = This file is generated from rules.vc > versions.vc]
++!endif
++!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
++   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
++!endif
++!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
++   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
++!endif
++!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
++   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
++!endif
++
++# If building the tcl core then we need additional package versions
++!if "$(PROJECT)" == "tcl"
++!if [echo PKG_HTTP_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
++!endif
++!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
++!endif
++!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
++!endif
++!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
++!endif
++!if [echo PKG_SHELL_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
++!endif
++!if [echo PKG_DDE_VER = \>> versions.vc] \
++   && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
++!endif
++!if [echo PKG_REG_VER =\>> versions.vc] \
++   && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
++!endif
++!endif
++
++!include versions.vc
++
++#--------------------------------------------------------------
++# Setup tcl version dependent stuff headers
++#--------------------------------------------------------------
++
++!if "$(PROJECT)" != "tcl"
++
++TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
++
++!if $(TCL_VERSION) < 81
++TCL_DOES_STUBS	= 0
++!else
++TCL_DOES_STUBS	= 1
++!endif
++
++!if $(TCLINSTALL)
++TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
++!if !exist($(TCLSH)) && $(TCL_THREADS)
++TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
++!endif
++TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
++TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
++TCL_LIBRARY	= $(_TCLDIR)\lib
++TCLREGLIB	= "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib"
++TCLDDELIB	= "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib"
++COFFBASE	= \must\have\tcl\sources\to\build\this\target
++TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
++TCL_INCLUDES    = -I"$(_TCLDIR)\include"
++!else
++TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
++!if !exist($(TCLSH)) && $(TCL_THREADS)
++TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
++!endif
++TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
++TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
++TCL_LIBRARY	= $(_TCLDIR)\library
++TCLREGLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib"
++TCLDDELIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib"
++COFFBASE	= "$(_TCLDIR)\win\coffbase.txt"
++TCLTOOLSDIR	= $(_TCLDIR)\tools
++TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
++!endif
++
++!endif
++
++#-------------------------------------------------------------------------
++# Locate the Tk headers to build against
++#-------------------------------------------------------------------------
++
++!if "$(PROJECT)" == "tk"
++_TK_H          = ..\generic\tk.h
++_INSTALLDIR    = $(_INSTALLDIR)\..
++!endif
++
++!ifdef PROJECT_REQUIRES_TK
++!if !defined(TKDIR)
++!if exist("$(_INSTALLDIR)\..\include\tk.h")
++TKINSTALL      = 1
++_TKDIR         = $(_INSTALLDIR)\..
++_TK_H          = $(_TKDIR)\include\tk.h
++TKDIR          = $(_TKDIR)
++!elseif exist("$(_TCLDIR)\include\tk.h")
++TKINSTALL      = 1
++_TKDIR         = $(_TCLDIR)
++_TK_H          = $(_TKDIR)\include\tk.h
++TKDIR          = $(_TKDIR)
++!endif
++!else
++_TKDIR = $(TKDIR:/=\)
++!if exist("$(_TKDIR)\include\tk.h")
++TKINSTALL      = 1
++_TK_H          = $(_TKDIR)\include\tk.h
++!elseif exist("$(_TKDIR)\generic\tk.h")
++TKINSTALL      = 0
++_TK_H          = $(_TKDIR)\generic\tk.h
++!else
++MSG =^
++Failed to find tk.h. The TKDIR macro does not appear correct.
++!error $(MSG)
++!endif
++!endif
++!endif
++
++#-------------------------------------------------------------------------
++# Extract Tk version numbers
++#-------------------------------------------------------------------------
++
++!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
++
++!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
++   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
++!endif
++!if [echo TK_MINOR_VERSION = \>> versions.vc] \
++   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
++!endif
++!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
++   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
++!endif
++
++!include versions.vc
++
++TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
++TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
++
++!if "$(PROJECT)" != "tk"
++!if $(TKINSTALL)
++WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
++TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
++TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
++TK_INCLUDES     = -I"$(_TKDIR)\include"
++!else
++WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
++TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
++TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
++TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
++!endif
++!endif
++
++!endif
++
++#----------------------------------------------------------
++# Display stats being used.
++#----------------------------------------------------------
++
++!message *** Intermediate directory will be '$(TMP_DIR)'
++!message *** Output directory will be '$(OUT_DIR)'
++!message *** Suffix for binaries will be '$(SUFX)'
++!message *** Optional defines are '$(OPTDEFINES)'
++!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
++!message *** Host architecture is $(NATIVE_ARCH)
++!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
++!message *** Link options '$(LINKERFLAGS)'
++
++!endif
++
diff --git a/share/security/patches/EN-19:03/sqlite-12.patch.asc b/share/security/patches/EN-19:03/sqlite-12.patch.asc
new file mode 100644
index 0000000000..d1709c7258
--- /dev/null
+++ b/share/security/patches/EN-19:03/sqlite-12.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RiZfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJ1DxAAnbAtjFeY6WfYrVaBB1GHJGdIKQrgq3yzHxd3ycQYguOqjHYkagR7TLM4
+Eo7/hUjTos7yvgw7A7IOVg6HqpcTuQNRHu6T5MjnHoNiB5pNgjN/OYlJ1v1nDSRR
+PiNoBX1NhrUiZc8eMblZESdq2COuph9wdLJGiZeA69uTDzLTvnhIvmaFwLBM0ewl
+wqK0ND3Z+bVLxuxdeRI7n616HCkQ9EgP2S8uPONZEmMaI1J00018bGOZTmBYaE9x
+3/LYfR5F1ggBq5J7Vxa62z0s0vVUu8AAIE422MmqpNONgSqRQ7c2tlYi4x8NLLbs
+feKuS6l181m7gN0Jc6OJZfnuEkFC1P8y3Klg9ruERX5kNKGc0cJQ5tTEzGLRxflV
+eHHczHFHe6h45W9LDrkhQgOWF/ofATOIjkch0G3i5aoegBMuf0ISFZaqHm11fxnO
+AAc8HY1pn6qSgMaJH33xAjCdWvGJHv8Dln08Bag9L80qW+7JoGADVTpDqJ9jqENR
+2w/dQH+1AQTH3TVI7GaOYVD2f73o+YJ/SJjJQ6SrvhKaQ0MIzKRwqhsD3DgfG6ux
+FYc6/5mv/yljxBPR/K7FNbd+XIz5SyicoXe7Xkk/GxChtjfKrYwK/LyWIHZfrX9N
+nBNecHd8XRnpEDqdQ2qStNkWdkaX8KixcBhX18SkHDchhjJF7BY=
+=M+mD
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:04/tzdata-2018i.patch b/share/security/patches/EN-19:04/tzdata-2018i.patch
new file mode 100644
index 0000000000..a506ce9e98
--- /dev/null
+++ b/share/security/patches/EN-19:04/tzdata-2018i.patch
@@ -0,0 +1,1448 @@
+--- contrib/tzdata/Makefile.orig
++++ contrib/tzdata/Makefile
+@@ -380,15 +380,18 @@
+ # is typically nicer if it works.
+ KSHELL=		/bin/bash
+ 
++# Name of curl <https://curl.haxx.se/>, used for HTML validation.
++CURL=		curl
++
+ # The path where SGML DTDs are kept and the catalog file(s) to use when
+-# validating.  The default should work on both Debian and Red Hat.
++# validating HTML 4.01.  The default should work on both Debian and Red Hat.
+ SGML_TOPDIR= /usr
+ SGML_DTDDIR= $(SGML_TOPDIR)/share/xml/w3c-sgml-lib/schema/dtd
+ SGML_SEARCH_PATH= $(SGML_DTDDIR)/REC-html401-19991224
+ SGML_CATALOG_FILES= \
+   $(SGML_TOPDIR)/share/doc/w3-recs/html/www.w3.org/TR/1999/REC-html401-19991224/HTML4.cat:$(SGML_TOPDIR)/share/sgml/html/4.01/HTML4.cat
+ 
+-# The name, arguments and environment of a program to validate your web pages.
++# The name, arguments and environment of a program to validate HTML 4.01.
+ # See <http://openjade.sourceforge.net/doc/> for a validator, and
+ # <https://validator.w3.org/source/> for a validation library.
+ # Set VALIDATE=':' if you do not have such a program.
+@@ -488,6 +491,7 @@
+ COMMON=		calendars CONTRIBUTING LICENSE Makefile \
+ 			NEWS README theory.html version
+ WEB_PAGES=	tz-art.html tz-how-to.html tz-link.html
++CHECK_WEB_PAGES=check_tz-art.html check_tz-how-to.html check_tz-link.html
+ DOCS=		$(MANS) date.1 $(MANTXTS) $(WEB_PAGES)
+ PRIMARY_YDATA=	africa antarctica asia australasia \
+ 		europe northamerica southamerica
+@@ -799,9 +803,15 @@
+ 		fi
+ 		touch $@
+ 
+-# This checks only the HTML 4.01 strict page.
+-# To check the the other pages, use <https://validator.w3.org/>.
+-check_web:	tz-how-to.html
++check_web:	$(CHECK_WEB_PAGES)
++check_tz-art.html: tz-art.html
++check_tz-link.html: tz-link.html
++check_tz-art.html check_tz-link.html:
++		$(CURL) -sS --url https://validator.w3.org/nu/ -F out=gnu \
++		    -F file=@$$(expr $@ : 'check_\(.*\)') -o $@.out && \
++		  test ! -s $@.out || { cat $@.out; exit 1; }
++		mv $@.out $@
++check_tz-how-to.html: tz-how-to.html
+ 		$(VALIDATE_ENV) $(VALIDATE) $(VALIDATE_FLAGS) tz-how-to.html
+ 		touch $@
+ 
+@@ -1068,7 +1078,7 @@
+ 
+ .PHONY: ALL INSTALL all
+ .PHONY: check check_time_t_alternatives
+-.PHONY: check_zishrink
++.PHONY: check_web check_zishrink
+ .PHONY: clean clean_misc dummy.zd force_tzs
+ .PHONY: install install_data maintainer-clean names
+ .PHONY: posix_only posix_packrat posix_right public
+--- contrib/tzdata/NEWS.orig
++++ contrib/tzdata/NEWS
+@@ -1,14 +1,103 @@
+ News for the tz database
+ 
++Release 2018i - 2018-12-30 11:05:43 -0800
++
++  Briefly:
++    São Tomé and Príncipe switches from +01 to +00 on 2019-01-01.
++
++  Changes to future timestamps
++
++    Due to a change in government, São Tomé and Príncipe switches back
++    from +01 to +00 on 2019-01-01 at 02:00.  (Thanks to Vadim
++    Nasardinov and Michael Deckers.)
++
++
++Release 2018h - 2018-12-23 17:59:32 -0800
++
++  Briefly:
++    Qyzylorda, Kazakhstan moved from +06 to +05 on 2018-12-21.
++    New zone Asia/Qostanay because Qostanay, Kazakhstan didn't move.
++    Metlakatla, Alaska observes PST this winter only.
++    Guess Morocco will continue to adjust clocks around Ramadan.
++    Add predictions for Iran from 2038 through 2090.
++
++  Changes to future timestamps
++
++    Guess that Morocco will continue to fall back just before and
++    spring forward just after Ramadan, the practice since 2012.
++    (Thanks to Maamar Abdelkader.)  This means Morocco will observe
++    negative DST during Ramadan in main and vanguard formats, and in
++    rearguard format it stays in the +00 timezone and observes
++    ordinary DST in all months other than Ramadan.  As before, extend
++    this guesswork to the year 2037.  As a consequence, Morocco is
++    scheduled to observe three DST transitions in some Gregorian years
++    (e.g., 2033) due to the mismatch between the Gregorian and Islamic
++    calendars.
++
++    The table of exact transitions for Iranian DST has been extended.
++    It formerly cut off before the year 2038 in a nod to 32-bit time_t.
++    It now cuts off before 2091 as there is doubt about how the Persian
++    calendar will treat 2091.  This change predicts DST transitions in
++    2038-9, 2042-3, and 2046-7 to occur one day later than previously
++    predicted.  As before, post-cutoff transitions are approximated.
++
++  Changes to past and future timestamps
++
++    Qyzylorda (aka Kyzylorda) oblast in Kazakhstan moved from +06 to
++    +05 on 2018-12-21.  This is a zone split as Qostanay (aka
++    Kostanay) did not switch, so create a zone Asia/Qostanay.
++
++    Metlakatla moved from Alaska to Pacific standard time on 2018-11-04.
++    It did not change clocks that day and remains on -08 this winter.
++    (Thanks to Ryan Stanley.)  It will revert to the usual Alaska
++    rules next spring, so this change affects only timestamps
++    from 2018-11-04 through 2019-03-10.
++
++  Change to past timestamps
++
++    Kwajalein's 1993-08-20 transition from -12 to +12 was at 24:00,
++    not 00:00.  I transcribed the time incorrectly from Shanks.
++    (Thanks to Phake Nick.)
++
++    Nauru's 1979 transition was on 02-10 at 02:00, not 05-01 at 00:00.
++    (Thanks to Phake Nick.)
++
++    Guam observed DST irregularly from 1959 through 1977.
++    (Thanks to Phake Nick.)
++
++    Hong Kong observed DST in 1941 starting 06-15 (not 04-01), then on
++    10-01 changed standard time to +08:30 (not +08).  Its transition
++    back to +08 after WWII was on 1945-09-15, not the previous day.
++    Its 1904-10-30 change took effect at 01:00 +08 (not 00:00 LMT).
++    (Thanks to Phake Nick, Steve Allen, and Joseph Myers.)  Also,
++    its 1952 fallback was on 11-02 (not 10-25).
++
++    This release contains many changes to timestamps before 1946 due
++    to Japanese possession or occupation of Pacific/Chuuk,
++    Pacific/Guam, Pacific/Kosrae, Pacific/Kwajalein, Pacific/Majuro,
++    Pacific/Nauru, Pacific/Palau, and Pacific/Pohnpei.
++    (Thanks to Phake Nick.)
++
++    Assume that the Spanish East Indies was like the Philippines and
++    observed American time until the end of 1844.  This affects
++    Pacific/Chuuk, Pacific/Kosrae, Pacific/Palau, and Pacific/Pohnpei.
++
++  Changes to past tm_isdst flags
++
++    For the recent Morocco change, the tm_isdst flag should be 1 from
++    2018-10-27 00:00 to 2018-10-28 03:00.  (Thanks to Michael Deckers.)
++    Give a URL to the official decree.  (Thanks to Matt Johnson.)
++
++
+ Release 2018g - 2018-10-26 22:22:45 -0700
+ 
+   Briefly:
+-    Morocco switches to permanent +01 on 2018-10-27.
++    Morocco switches to permanent +01 on 2018-10-28.
+ 
+   Changes to future timestamps
+ 
+-    Morocco switches from +00/+01 to permanent +01 effective 2018-10-27,
+-    so its clocks will not fall back on 2018-10-28 as previously scheduled.
++    Morocco switches from +00/+01 to permanent +01 effective 2018-10-28,
++    so its clocks will not fall back as previously scheduled.
+     (Thanks to Mohamed Essedik Najd and Brian Inglis.)
+ 
+   Changes to code
+@@ -119,7 +208,7 @@
+     localtime.c no longer ignores TZif POSIX-style TZ strings that
+     specify only standard time.  Instead, these TZ strings now
+     override the default time type for timestamps after the last
+-    transition (or for all time stamps if there are no transitions),
++    transition (or for all timestamps if there are no transitions),
+     just as DST strings specifying DST have always done.
+ 
+     leapseconds.awk now outputs "#updated" and "#expires" comments,
+--- contrib/tzdata/africa.orig
++++ contrib/tzdata/africa
+@@ -847,8 +847,41 @@
+ # From Mohamed Essedik Najd (2018-10-26):
+ # Today, a Moroccan government council approved the perpetual addition
+ # of 60 minutes to the regular Moroccan timezone.
+-# From Brian Inglis (2018-10-26):
+-# http://www.maroc.ma/fr/actualites/le-conseil-de-gouvernement-adopte-un-projet-de-decret-relatif-lheure-legale-stipulant-le
++# From Matt Johnson (2018-10-28):
++# http://www.sgg.gov.ma/Portals/1/BO/2018/BO_6720-bis_Ar.pdf
++#
++# From Maamar Abdelkader (2018-11-01):
++# We usually move clocks back the previous week end and come back to the +1
++# the week end after....  The government does not announce yet the decision
++# about this temporary change.  But it s 99% sure that it will be the case,
++# as in previous years.  An unofficial survey was done these days, showing
++# that 64% of asked peopke are ok for moving from +1 to +0 during Ramadan.
++# https://leconomiste.com/article/1035870-enquete-l-economiste-sunergia-64-des-marocains-plebiscitent-le-gmt-pendant-ramadan
++#
++# From Paul Eggert (2018-11-01):
++# For now, guess that Morocco will fall back at 03:00 the last Sunday
++# before Ramadan, and spring forward at 02:00 the first Sunday after
++# Ramadan, as this has been the practice since 2012.  To implement this,
++# transition dates for 2019 through 2037 were determined by running the
++# following program under GNU Emacs 26.1.
++# (let ((islamic-year 1440))
++#   (require 'cal-islam)
++#   (while (< islamic-year 1460)
++#     (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
++#           (b (calendar-islamic-to-absolute (list 10 1 islamic-year)))
++#           (sunday 0))
++#       (while (/= sunday (mod (setq a (1- a)) 7)))
++#       (while (/= sunday (mod b 7))
++#         (setq b (1+ b)))
++#       (setq a (calendar-gregorian-from-absolute a))
++#       (setq b (calendar-gregorian-from-absolute b))
++#       (insert
++#        (format
++#         (concat "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 3:00\t-1:00\t-\n"
++#                 "Rule\tMorocco\t%d\tonly\t-\t%s\t%2d\t 2:00\t0\t-\n")
++#         (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a))
++#         (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b)))))
++#     (setq islamic-year (+ 1 islamic-year))))
+ 
+ # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+ Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	-
+@@ -892,13 +925,53 @@
+ Rule	Morocco	2017	only	-	Jul	 2	 2:00	1:00	-
+ Rule	Morocco	2018	only	-	May	13	 3:00	0	-
+ Rule	Morocco	2018	only	-	Jun	17	 2:00	1:00	-
++Rule	Morocco	2019	only	-	May	 5	 3:00	-1:00	-
++Rule	Morocco	2019	only	-	Jun	 9	 2:00	0	-
++Rule	Morocco	2020	only	-	Apr	19	 3:00	-1:00	-
++Rule	Morocco	2020	only	-	May	24	 2:00	0	-
++Rule	Morocco	2021	only	-	Apr	11	 3:00	-1:00	-
++Rule	Morocco	2021	only	-	May	16	 2:00	0	-
++Rule	Morocco	2022	only	-	Mar	27	 3:00	-1:00	-
++Rule	Morocco	2022	only	-	May	 8	 2:00	0	-
++Rule	Morocco	2023	only	-	Mar	19	 3:00	-1:00	-
++Rule	Morocco	2023	only	-	Apr	23	 2:00	0	-
++Rule	Morocco	2024	only	-	Mar	10	 3:00	-1:00	-
++Rule	Morocco	2024	only	-	Apr	14	 2:00	0	-
++Rule	Morocco	2025	only	-	Feb	23	 3:00	-1:00	-
++Rule	Morocco	2025	only	-	Apr	 6	 2:00	0	-
++Rule	Morocco	2026	only	-	Feb	15	 3:00	-1:00	-
++Rule	Morocco	2026	only	-	Mar	22	 2:00	0	-
++Rule	Morocco	2027	only	-	Feb	 7	 3:00	-1:00	-
++Rule	Morocco	2027	only	-	Mar	14	 2:00	0	-
++Rule	Morocco	2028	only	-	Jan	23	 3:00	-1:00	-
++Rule	Morocco	2028	only	-	Feb	27	 2:00	0	-
++Rule	Morocco	2029	only	-	Jan	14	 3:00	-1:00	-
++Rule	Morocco	2029	only	-	Feb	18	 2:00	0	-
++Rule	Morocco	2029	only	-	Dec	30	 3:00	-1:00	-
++Rule	Morocco	2030	only	-	Feb	10	 2:00	0	-
++Rule	Morocco	2030	only	-	Dec	22	 3:00	-1:00	-
++Rule	Morocco	2031	only	-	Jan	26	 2:00	0	-
++Rule	Morocco	2031	only	-	Dec	14	 3:00	-1:00	-
++Rule	Morocco	2032	only	-	Jan	18	 2:00	0	-
++Rule	Morocco	2032	only	-	Nov	28	 3:00	-1:00	-
++Rule	Morocco	2033	only	-	Jan	 9	 2:00	0	-
++Rule	Morocco	2033	only	-	Nov	20	 3:00	-1:00	-
++Rule	Morocco	2033	only	-	Dec	25	 2:00	0	-
++Rule	Morocco	2034	only	-	Nov	 5	 3:00	-1:00	-
++Rule	Morocco	2034	only	-	Dec	17	 2:00	0	-
++Rule	Morocco	2035	only	-	Oct	28	 3:00	-1:00	-
++Rule	Morocco	2035	only	-	Dec	 2	 2:00	0	-
++Rule	Morocco	2036	only	-	Oct	19	 3:00	-1:00	-
++Rule	Morocco	2036	only	-	Nov	23	 2:00	0	-
++Rule	Morocco	2037	only	-	Oct	 4	 3:00	-1:00	-
++Rule	Morocco	2037	only	-	Nov	15	 2:00	0	-
+ 
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
+ 			 0:00	Morocco	+00/+01	1984 Mar 16
+ 			 1:00	-	+01	1986
+-			 0:00	Morocco	+00/+01	2018 Oct 27
+-			 1:00	-	+01
++			 0:00	Morocco	+00/+01	2018 Oct 28  3:00
++			 1:00	Morocco	+01/+00
+ 
+ # Western Sahara
+ #
+@@ -913,8 +986,8 @@
+ 
+ Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan # El Aaiún
+ 			-1:00	-	-01	1976 Apr 14
+-			 0:00	Morocco	+00/+01	2018 Oct 27
+-			 1:00	-	+01
++			 0:00	Morocco	+00/+01	2018 Oct 28  3:00
++			 1:00	Morocco	+01/+00
+ 
+ # Mozambique
+ #
+@@ -1071,10 +1144,20 @@
+ # the switch is from 01:00 to 02:00 ... [Decree No. 25/2017]
+ # http://www.mnec.gov.st/index.php/publicacoes/documentos/file/90-decreto-lei-n-25-2017
+ 
++# From Vadim Nasardinov (2018-12-29):
++# São Tomé and Príncipe is about to do the following on Jan 1, 2019:
++# https://www.stp-press.st/2018/12/05/governo-jesus-ja-decidiu-repor-hora-legal-sao-tomense/
++#
++# From Michael Deckers (2018-12-30):
++# https://www.legis-palop.org/download.jsp?idFile=102818
++# ... [The legal time of the country, which coincides with universal
++# coordinated time, will be restituted at 2 o'clock on day 1 of January, 2019.]
++
+ Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
+ 			-0:36:45 -	LMT	1912 Jan  1 00:00u # Lisbon MT
+ 			 0:00	-	GMT	2018 Jan  1 01:00
+-			 1:00	-	WAT
++			 1:00	-	WAT	2019 Jan  1 02:00
++			 0:00	-	GMT
+ 
+ # Senegal
+ # See Africa/Abidjan.
+--- contrib/tzdata/asia.orig
++++ contrib/tzdata/asia
+@@ -586,12 +586,82 @@
+ # obtained from
+ # http://www.hko.gov.hk/gts/time/Summertime.htm
+ 
+-# From Arthur David Olson (2009-10-28):
++# From Phake Nick (2018-10-27):
++# According to Singaporean newspaper
++# http://eresources.nlb.gov.sg/newspapers/Digitised/Article/singfreepresswk19041102-1.2.37
++# the day that Hong Kong start using GMT+8 should be Oct 30, 1904.
++#
++# From Paul Eggert (2018-11-17):
++# Hong Kong had a time ball near the Marine Police Station, Tsim Sha Tsui.
++# "The ball was raised manually each day and dropped at exactly 1pm
++# (except on Sundays and Government holidays)."
++# Dyson AD. From Time Ball to Atomic Clock. Hong Kong Government. 1983.
++# <https://www.hko.gov.hk/publica/gen_pub/timeball_atomic_clock.pdf>
++# "From 1904 October 30 the time-ball at Hong Kong has been dropped by order
++# of the Governor of the Colony at 17h 0m 0s G.M.T., which is 23m 18s.14 in
++# advance of 1h 0m 0s of Hong Kong mean time."
++# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
++# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
++#
++# From Joseph Myers (2018-11-18):
++# An astronomer before 1925 referring to GMT would have been using the old
++# astronomical convention where the day started at noon, not midnight.
++#
++# From Steve Allen (2018-11-17):
++# Meteorological Observations made at the Hongkong Observatory in the year 1904
++# page 4 <https://books.google.com/books?id=kgw5AQAAMAAJ&pg=RA4-PA4>
++# ... the log of drop times in Table II shows that on Sunday 1904-10-30 the
++# ball was dropped.  So that looks like a special case drop for the sake
++# of broadcasting the new local time.
++#
++# From Phake Nick (2018-11-18):
++# According to The Hong Kong Weekly Press, 1904-10-29, p.324, the
++# governor of Hong Kong at the time stated that "We are further desired to
++# make it known that the change will be effected by firing the gun and by the
++# dropping of the Ball at 23min. 18sec. before one."
++# From Paul Eggert (2018-11-18):
++# See <https://mmis.hkpl.gov.hk> for this; unfortunately Flash is required.
++
++# From Phake Nick (2018-10-26):
++# I went to check microfilm records stored at Hong Kong Public Library....
++# on September 30 1941, according to Ta Kung Pao (Hong Kong edition), it was
++# stated that fallback would occur on the next day (the 1st)'s "03:00 am (Hong
++# Kong Time 04:00 am)" and the clock will fall back for a half hour. (03:00
++# probably refer to the time commonly used in mainland China at the time given
++# the paper's background) ... the sunrise/sunset time given by South China
++# Morning Post for October 1st was indeed moved by half an hour compares to
++# before.  After that, in December, the battle to capture Hong Kong started and
++# the library doesn't seems to have any record stored about press during that
++# period of time.  Some media resumed publication soon after that within the
++# same month, but there were not much information about time there.  Later they
++# started including a radio program guide when they restored radio service,
++# explicitly mentioning it use Tokyo standard time, and later added a note
++# saying it's half an hour ahead of the old Hong Kong standard time, and it
++# also seems to indicate that Hong Kong was not using GMT+8 when it was
++# captured by Japan.
++#
++# Image of related sections on newspaper:
++# * 1941-09-30, Ta Kung Pao (Hong Kong), "Winter Time start tomorrow".
++#   https://i.imgur.com/6waY51Z.jpg (Chinese)
++# * 1941-09-29, South China Morning Post, Information on sunrise/sunset
++#   time and other things for September 30 and October 1.
++#   https://i.imgur.com/kCiUR78.jpg
++# * 1942-02-05. The Hong Kong News, Radio Program Guide.
++#   https://i.imgur.com/eVvDMzS.jpg
++# * 1941-06-14. Hong Kong Daily Press, Daylight Saving from 3am Tomorrow.
++#   https://i.imgur.com/05KkvtC.png
++# * 1941-09-30, Hong Kong Daily Press, Winter Time Warning.
++#   https://i.imgur.com/dge4kFJ.png
++# Also, the Liberation day of Hong Kong after WWII which British rule
++# over the territory resumed was August 30, 1945, which I think should
++# be the termination date for the use of JST in the territory....
++
++# From Paul Eggert (2018-11-17):
+ # Here are the dates given at
+-# http://www.hko.gov.hk/gts/time/Summertime.htm
+-# as of 2009-10-28:
++# https://www.hko.gov.hk/gts/time/Summertime.htm
++# as of 2014-06-19:
+ # Year        Period
+-# 1941        1 Apr to 30 Sep
++# 1941        15 Jun to 30 Sep
+ # 1942        Whole year
+ # 1943        Whole year
+ # 1944        Whole year
+@@ -602,7 +672,7 @@
+ # 1949        3 Apr to 30 Oct
+ # 1950        2 Apr to 29 Oct
+ # 1951        1 Apr to 28 Oct
+-# 1952        6 Apr to 25 Oct
++# 1952        6 Apr to 2 Nov
+ # 1953        5 Apr to 1 Nov
+ # 1954        21 Mar to 31 Oct
+ # 1955        20 Mar to 6 Nov
+@@ -631,25 +701,25 @@
+ # 1978        Nil
+ # 1979        13 May to 21 Oct
+ # 1980 to Now Nil
+-# The page does not give start or end times of day.
+-# The page does not give a start date for 1942.
+-# The page does not givw an end date for 1945.
+-# The Japanese occupation of Hong Kong began on 1941-12-25.
+-# The Japanese surrender of Hong Kong was signed 1945-09-15.
+-# For lack of anything better, use start of those days as the transition times.
++# The page does not give times of day for transitions,
++# or dates for the 1942 and 1945 transitions.
++# The Japanese occupation of Hong Kong began 1941-12-25.
++# The Japanese surrender of Hong Kong was signed 1945-09-16; see:
++# Heaver S. The days after the Pacific war ended: unsettling times
++# in Hong Kong. Post Magazine. 2016-06-13.
++# https://www.scmp.com/magazines/post-magazine/article/1852990/days-after-pacific-war-ended-unsettling-times-hong-kong
++# For lack of anything better, use start of those days as the
++# transition times.
+ 
+ # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+-Rule	HK	1941	only	-	Apr	1	3:30	1:00	S
+-Rule	HK	1941	only	-	Sep	30	3:30	0	-
+ Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
+ Rule	HK	1946	only	-	Dec	1	3:30	0	-
+ Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
+ Rule	HK	1947	only	-	Dec	30	3:30	0	-
+ Rule	HK	1948	only	-	May	2	3:30	1:00	S
+ Rule	HK	1948	1951	-	Oct	lastSun	3:30	0	-
+-Rule	HK	1952	only	-	Oct	25	3:30	0	-
++Rule	HK	1952	1953	-	Nov	Sun>=1	3:30	0	-
+ Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
+-Rule	HK	1953	only	-	Nov	1	3:30	0	-
+ Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
+ Rule	HK	1954	only	-	Oct	31	3:30	0	-
+ Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
+@@ -659,9 +729,11 @@
+ Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
+ Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+-Zone	Asia/Hong_Kong	7:36:42 -	LMT	1904 Oct 30
+-			8:00	HK	HK%sT	1941 Dec 25
+-			9:00	-	JST	1945 Sep 15
++Zone	Asia/Hong_Kong	7:36:42 -	LMT	1904 Oct 30  0:36:42
++			8:00	-	HKT	1941 Jun 15  3:30
++			8:00	1:00	HKST	1941 Oct  1  4:00
++			8:30	-	HKT	1941 Dec 25
++			9:00	-	JST	1945 Sep 16
+ 			8:00	HK	HK%sT
+ 
+ ###############################################################################
+@@ -1057,6 +1129,16 @@
+ 
+ # India
+ 
++# British astronomer Henry Park Hollis disliked India Standard Time's offset:
++# "A new time system has been proposed for India, Further India, and Burmah.
++# The scheme suggested is that the times of the meridians 5½ and 6½ hours
++# east of Greenwich should be adopted in these territories.  No reason is
++# given why hourly meridians five hours and six hours east should not be
++# chosen; a plan which would bring the time of India into harmony with
++# that of almost the whole of the civilised world."
++# Hollis HP. Universal Time, Longitudes, and Geodesy. Mon Not R Astron Soc.
++# 1905-02-10;65(4):405-6. https://doi.org/10.1093/mnras/65.4.382
++
+ # From Ian P. Beacock, in "A brief history of (modern) time", The Atlantic
+ # https://www.theatlantic.com/technology/archive/2015/12/the-creation-of-modern-time/421419/
+ # (2015-12-22):
+@@ -1227,12 +1309,65 @@
+ # leap year calculation involved.  There has never been any serious
+ # plan to change that law....
+ #
+-# From Paul Eggert (2006-03-22):
++# From Paul Eggert (2018-11-30):
+ # Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
+-# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
+-# stopping after 2037 when 32-bit time_t's overflow.
+-# That cal-persia used Birashk's approximation, which disagrees with the solar
+-# calendar predictions for the year 2025, so I corrected those dates by hand.
++# I used the following code in GNU Emacs 26.1 to generate the "Rule Iran"
++# lines from 2008 through 2087.  Emacs 26.1 uses Ed Reingold's
++# cal-persia implementation of Birashk's approximation, which in the
++# 2008-2087 range disagrees with the the astronomical Persian calendar
++# for Persian years 1404 (Gregorian 2025) and 1437 (Gregorian 2058),
++# so the following code special-case those years.  See Table 15.1, page 264, of:
++# Edward M. Reingold and Nachum Dershowitz, Calendrical Calculations:
++# The Ultimate Edition, Cambridge University Press (2018).
++# https://www.cambridge.org/fr/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition
++# Page 258, footnote 2, of this book says there is some dispute over what will
++# happen in 2091 (and some other years after that), so this code
++# stops in 2087, as 2088 and 2089 agree with the "max" rule below.
++# (cl-loop
++#  initially (require 'cal-persia)
++#  with first-persian-year = 1387
++#  with last-persian-year = 1466
++#  ;; Exceptional years in the above range,
++#  ;; from Reingold & Dershowitz Table 15.1, page 264:
++#  with exceptional-persian-years = '(1404 1437)
++#  with range-start = nil
++#  for persian-year from first-persian-year to last-persian-year
++#  do
++#  (let*
++#      ((exceptional-year-offset
++#        (if (member persian-year exceptional-persian-years) 1 0))
++#       (beg-dst-absolute
++#        (+ (calendar-persian-to-absolute (list 1 1 persian-year))
++#           exceptional-year-offset))
++#       (end-dst-absolute
++#        (+ (calendar-persian-to-absolute (list 6 30 persian-year))
++#           exceptional-year-offset))
++#       (next-year-beg-dst-absolute
++#        (+ (calendar-persian-to-absolute (list 1 1 (1+ persian-year)))
++#           (if (member (1+ persian-year) exceptional-persian-years) 1 0)))
++#       (beg-dst (calendar-gregorian-from-absolute beg-dst-absolute))
++#       (end-dst (calendar-gregorian-from-absolute end-dst-absolute))
++#       (next-year-beg-dst (calendar-gregorian-from-absolute
++#                           next-year-beg-dst-absolute))
++#       (year (calendar-extract-year beg-dst))
++#       (range-end (if range-start year "only")))
++#    (setq range-start (or range-start year))
++#    (when (or (/= (calendar-extract-day beg-dst)
++#                  (calendar-extract-day next-year-beg-dst))
++#              (= persian-year last-persian-year))
++#      (insert
++#       (format
++#        "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t1:00\t-\n"
++#        range-start range-end
++#        (calendar-month-name (calendar-extract-month beg-dst) t)
++#        (calendar-extract-day beg-dst)))
++#      (insert
++#       (format
++#        "Rule\tIran\t%d\t%s\t-\t%s\t%2d\t24:00\t0\t-\n"
++#        range-start range-end
++#        (calendar-month-name (calendar-extract-month end-dst) t)
++#        (calendar-extract-day end-dst)))
++#      (setq range-start nil))))
+ #
+ # From Oscar van Vlijmen (2005-03-30), writing about future
+ # discrepancies between cal-persia and the Iranian calendar:
+@@ -1267,61 +1402,113 @@
+ # thirtieth day of Shahrivar.
+ #
+ # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+-Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	-
+-Rule	Iran	1978	only	-	Oct	21	0:00	0	-
+-Rule	Iran	1979	only	-	Sep	19	0:00	0	-
+-Rule	Iran	1980	only	-	Sep	23	0:00	0	-
+-Rule	Iran	1991	only	-	May	 3	0:00	1:00	-
+-Rule	Iran	1992	1995	-	Mar	22	0:00	1:00	-
+-Rule	Iran	1991	1995	-	Sep	22	0:00	0	-
+-Rule	Iran	1996	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	1996	only	-	Sep	21	0:00	0	-
+-Rule	Iran	1997	1999	-	Mar	22	0:00	1:00	-
+-Rule	Iran	1997	1999	-	Sep	22	0:00	0	-
+-Rule	Iran	2000	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2000	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2001	2003	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2001	2003	-	Sep	22	0:00	0	-
+-Rule	Iran	2004	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2004	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2005	only	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2005	only	-	Sep	22	0:00	0	-
+-Rule	Iran	2008	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2008	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2009	2011	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2009	2011	-	Sep	22	0:00	0	-
+-Rule	Iran	2012	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2012	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2013	2015	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2013	2015	-	Sep	22	0:00	0	-
+-Rule	Iran	2016	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2016	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2017	2019	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2017	2019	-	Sep	22	0:00	0	-
+-Rule	Iran	2020	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2020	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2021	2023	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2021	2023	-	Sep	22	0:00	0	-
+-Rule	Iran	2024	only	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2024	only	-	Sep	21	0:00	0	-
+-Rule	Iran	2025	2027	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2025	2027	-	Sep	22	0:00	0	-
+-Rule	Iran	2028	2029	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2028	2029	-	Sep	21	0:00	0	-
+-Rule	Iran	2030	2031	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2030	2031	-	Sep	22	0:00	0	-
+-Rule	Iran	2032	2033	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2032	2033	-	Sep	21	0:00	0	-
+-Rule	Iran	2034	2035	-	Mar	22	0:00	1:00	-
+-Rule	Iran	2034	2035	-	Sep	22	0:00	0	-
+-#
+-# The following rules are approximations starting in the year 2038.
+-# These are the best post-2037 approximations available, given the
+-# restrictions of a single rule using a Gregorian-based data format.
++Rule	Iran	1978	1980	-	Mar	20	24:00	1:00	-
++Rule	Iran	1978	only	-	Oct	20	24:00	0	-
++Rule	Iran	1979	only	-	Sep	18	24:00	0	-
++Rule	Iran	1980	only	-	Sep	22	24:00	0	-
++Rule	Iran	1991	only	-	May	 2	24:00	1:00	-
++Rule	Iran	1992	1995	-	Mar	21	24:00	1:00	-
++Rule	Iran	1991	1995	-	Sep	21	24:00	0	-
++Rule	Iran	1996	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	1996	only	-	Sep	20	24:00	0	-
++Rule	Iran	1997	1999	-	Mar	21	24:00	1:00	-
++Rule	Iran	1997	1999	-	Sep	21	24:00	0	-
++Rule	Iran	2000	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2000	only	-	Sep	20	24:00	0	-
++Rule	Iran	2001	2003	-	Mar	21	24:00	1:00	-
++Rule	Iran	2001	2003	-	Sep	21	24:00	0	-
++Rule	Iran	2004	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2004	only	-	Sep	20	24:00	0	-
++Rule	Iran	2005	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2005	only	-	Sep	21	24:00	0	-
++Rule	Iran	2008	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2008	only	-	Sep	20	24:00	0	-
++Rule	Iran	2009	2011	-	Mar	21	24:00	1:00	-
++Rule	Iran	2009	2011	-	Sep	21	24:00	0	-
++Rule	Iran	2012	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2012	only	-	Sep	20	24:00	0	-
++Rule	Iran	2013	2015	-	Mar	21	24:00	1:00	-
++Rule	Iran	2013	2015	-	Sep	21	24:00	0	-
++Rule	Iran	2016	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2016	only	-	Sep	20	24:00	0	-
++Rule	Iran	2017	2019	-	Mar	21	24:00	1:00	-
++Rule	Iran	2017	2019	-	Sep	21	24:00	0	-
++Rule	Iran	2020	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2020	only	-	Sep	20	24:00	0	-
++Rule	Iran	2021	2023	-	Mar	21	24:00	1:00	-
++Rule	Iran	2021	2023	-	Sep	21	24:00	0	-
++Rule	Iran	2024	only	-	Mar	20	24:00	1:00	-
++Rule	Iran	2024	only	-	Sep	20	24:00	0	-
++Rule	Iran	2025	2027	-	Mar	21	24:00	1:00	-
++Rule	Iran	2025	2027	-	Sep	21	24:00	0	-
++Rule	Iran	2028	2029	-	Mar	20	24:00	1:00	-
++Rule	Iran	2028	2029	-	Sep	20	24:00	0	-
++Rule	Iran	2030	2031	-	Mar	21	24:00	1:00	-
++Rule	Iran	2030	2031	-	Sep	21	24:00	0	-
++Rule	Iran	2032	2033	-	Mar	20	24:00	1:00	-
++Rule	Iran	2032	2033	-	Sep	20	24:00	0	-
++Rule	Iran	2034	2035	-	Mar	21	24:00	1:00	-
++Rule	Iran	2034	2035	-	Sep	21	24:00	0	-
++Rule	Iran	2036	2037	-	Mar	20	24:00	1:00	-
++Rule	Iran	2036	2037	-	Sep	20	24:00	0	-
++Rule	Iran	2038	2039	-	Mar	21	24:00	1:00	-
++Rule	Iran	2038	2039	-	Sep	21	24:00	0	-
++Rule	Iran	2040	2041	-	Mar	20	24:00	1:00	-
++Rule	Iran	2040	2041	-	Sep	20	24:00	0	-
++Rule	Iran	2042	2043	-	Mar	21	24:00	1:00	-
++Rule	Iran	2042	2043	-	Sep	21	24:00	0	-
++Rule	Iran	2044	2045	-	Mar	20	24:00	1:00	-
++Rule	Iran	2044	2045	-	Sep	20	24:00	0	-
++Rule	Iran	2046	2047	-	Mar	21	24:00	1:00	-
++Rule	Iran	2046	2047	-	Sep	21	24:00	0	-
++Rule	Iran	2048	2049	-	Mar	20	24:00	1:00	-
++Rule	Iran	2048	2049	-	Sep	20	24:00	0	-
++Rule	Iran	2050	2051	-	Mar	21	24:00	1:00	-
++Rule	Iran	2050	2051	-	Sep	21	24:00	0	-
++Rule	Iran	2052	2053	-	Mar	20	24:00	1:00	-
++Rule	Iran	2052	2053	-	Sep	20	24:00	0	-
++Rule	Iran	2054	2055	-	Mar	21	24:00	1:00	-
++Rule	Iran	2054	2055	-	Sep	21	24:00	0	-
++Rule	Iran	2056	2057	-	Mar	20	24:00	1:00	-
++Rule	Iran	2056	2057	-	Sep	20	24:00	0	-
++Rule	Iran	2058	2059	-	Mar	21	24:00	1:00	-
++Rule	Iran	2058	2059	-	Sep	21	24:00	0	-
++Rule	Iran	2060	2062	-	Mar	20	24:00	1:00	-
++Rule	Iran	2060	2062	-	Sep	20	24:00	0	-
++Rule	Iran	2063	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2063	only	-	Sep	21	24:00	0	-
++Rule	Iran	2064	2066	-	Mar	20	24:00	1:00	-
++Rule	Iran	2064	2066	-	Sep	20	24:00	0	-
++Rule	Iran	2067	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2067	only	-	Sep	21	24:00	0	-
++Rule	Iran	2068	2070	-	Mar	20	24:00	1:00	-
++Rule	Iran	2068	2070	-	Sep	20	24:00	0	-
++Rule	Iran	2071	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2071	only	-	Sep	21	24:00	0	-
++Rule	Iran	2072	2074	-	Mar	20	24:00	1:00	-
++Rule	Iran	2072	2074	-	Sep	20	24:00	0	-
++Rule	Iran	2075	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2075	only	-	Sep	21	24:00	0	-
++Rule	Iran	2076	2078	-	Mar	20	24:00	1:00	-
++Rule	Iran	2076	2078	-	Sep	20	24:00	0	-
++Rule	Iran	2079	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2079	only	-	Sep	21	24:00	0	-
++Rule	Iran	2080	2082	-	Mar	20	24:00	1:00	-
++Rule	Iran	2080	2082	-	Sep	20	24:00	0	-
++Rule	Iran	2083	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2083	only	-	Sep	21	24:00	0	-
++Rule	Iran	2084	2086	-	Mar	20	24:00	1:00	-
++Rule	Iran	2084	2086	-	Sep	20	24:00	0	-
++Rule	Iran	2087	only	-	Mar	21	24:00	1:00	-
++Rule	Iran	2087	only	-	Sep	21	24:00	0	-
++#
++# The following rules are approximations starting in the year 2088.
++# These are the best post-2088 approximations available, given the
++# restrictions of a single rule using ordinary Gregorian dates.
+ # At some point this table will need to be extended, though quite
+ # possibly Iran will change the rules first.
+-Rule	Iran	2036	max	-	Mar	21	0:00	1:00	-
+-Rule	Iran	2036	max	-	Sep	21	0:00	0	-
++Rule	Iran	2088	max	-	Mar	20	24:00	1:00	-
++Rule	Iran	2088	max	-	Sep	20	24:00	0	-
+ 
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone	Asia/Tehran	3:25:44	-	LMT	1916
+@@ -1691,7 +1878,9 @@
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
+ 			9:00	Japan	J%sT
+-# Since 1938, all Japanese possessions have been like Asia/Tokyo.
++# Since 1938, all Japanese possessions have been like Asia/Tokyo,
++# except that Truk (Chuuk), Ponape (Pohnpei), and Jaluit (Kosrae) did not
++# switch from +10 to +09 until 1941-04-01; see the 'australasia' file.
+ 
+ # Jordan
+ #
+@@ -1981,8 +2170,10 @@
+ # and in Byalokoz) lists Ural river (plus 10 versts on its left bank) in
+ # the third time belt (before 1930 this means +03).
+ 
+-# From Paul Eggert (2016-12-06):
+-# The tables below reflect Golosunov's remarks, with exceptions as noted.
++# From Alexander Konzurovski (2018-12-20):
++# Qyzyolrda Region (Asia/Qyzylorda) is changing its time zone from
++# UTC+6 to UTC+5 effective December 21st, 2018. The legal document is
++# located here: http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
+ 
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ #
+@@ -1996,8 +2187,6 @@
+ 			6:00 RussiaAsia	+06/+07	2004 Oct 31  2:00s
+ 			6:00	-	+06
+ # Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
+-# This currently includes Qostanay (aka Kostanay, Kustanay) (KZ-KUS);
+-# see comments below.
+ Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
+ 			4:00	-	+04	1930 Jun 21
+ 			5:00	-	+05	1981 Apr  1
+@@ -2008,21 +2197,22 @@
+ 			5:00 RussiaAsia	+05/+06	1992 Jan 19  2:00s
+ 			6:00 RussiaAsia	+06/+07	1992 Mar 29  2:00s
+ 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
+-			6:00	-	+06
+-# The following zone is like Asia/Qyzylorda except for being one
+-# hour earlier from 1991-09-29 to 1992-03-29.  The 1991/2 rules for
+-# Qostanay are unclear partly because of the 1997 Turgai
+-# reorganization, so this zone is commented out for now.
+-#Zone	Asia/Qostanay	4:14:20 -	LMT	1924 May  2
+-#			4:00	-	+04	1930 Jun 21
+-#			5:00	-	+05	1981 Apr  1
+-#			5:00	1:00	+06	1981 Oct  1
+-#			6:00	-	+06	1982 Apr  1
+-#			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
+-#			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
+-#			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
+-#			6:00	-	+06
++			6:00	-	+06	2018 Dec 21  0:00
++			5:00	-	+05
+ #
++# Qostanay (aka Kostanay, Kustanay) (KZ-KUS)
++# The 1991/2 rules are unclear partly because of the 1997 Turgai
++# reorganization.
++Zone	Asia/Qostanay	4:14:28 -	LMT	1924 May  2
++			4:00	-	+04	1930 Jun 21
++			5:00	-	+05	1981 Apr  1
++			5:00	1:00	+06	1981 Oct  1
++			6:00	-	+06	1982 Apr  1
++			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
++			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
++			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
++			6:00	-	+06
++
+ # Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
+ Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
+ 			4:00	-	+04	1930 Jun 21
+@@ -2116,21 +2306,43 @@
+ # started at June 1 in that year.  For another example, the article in
+ # 1988 said that DST started at 2:00 AM in that year.
+ 
++# From Phake Nick (2018-10-27):
++# 1. According to official announcement from Korean government, the DST end
++# date in South Korea should be
++# 1955-09-08 without specifying time
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027977557
++# 1956-09-29 without specifying time
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027978341
++# 1957-09-21 24 o'clock
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027979690#3
++# 1958-09-20 24 o'clock
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027981189
++# 1959-09-19 24 o'clock
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0027982974#2
++# 1960-09-17 24 o'clock
++# http://theme.archives.go.kr/next/common/viewEbook.do?singleData=N&archiveEventId=0028044104
++# ...
++# 2.... https://namu.wiki/w/대한민국%20표준시 ... [says]
++# when Korea was using GMT+8:30 as standard time, the international
++# aviation/marine/meteorological industry in the country refused to
++# follow and continued to use GMT+9:00 for interoperability.
++
++
+ # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+-Rule	ROK	1948	only	-	Jun	 1	0:00	1:00	D
+-Rule	ROK	1948	only	-	Sep	13	0:00	0	S
+-Rule	ROK	1949	only	-	Apr	 3	0:00	1:00	D
+-Rule	ROK	1949	1951	-	Sep	Sun>=8	0:00	0	S
+-Rule	ROK	1950	only	-	Apr	 1	0:00	1:00	D
+-Rule	ROK	1951	only	-	May	 6	0:00	1:00	D
+-Rule	ROK	1955	only	-	May	 5	0:00	1:00	D
+-Rule	ROK	1955	only	-	Sep	 9	0:00	0	S
+-Rule	ROK	1956	only	-	May	20	0:00	1:00	D
+-Rule	ROK	1956	only	-	Sep	30	0:00	0	S
+-Rule	ROK	1957	1960	-	May	Sun>=1	0:00	1:00	D
+-Rule	ROK	1957	1960	-	Sep	Sun>=18	0:00	0	S
+-Rule	ROK	1987	1988	-	May	Sun>=8	2:00	1:00	D
+-Rule	ROK	1987	1988	-	Oct	Sun>=8	3:00	0	S
++Rule	ROK	1948	only	-	Jun	 1	 0:00	1:00	D
++Rule	ROK	1948	only	-	Sep	12	24:00	0	S
++Rule	ROK	1949	only	-	Apr	 3	 0:00	1:00	D
++Rule	ROK	1949	1951	-	Sep	Sat>=7	24:00	0	S
++Rule	ROK	1950	only	-	Apr	 1	 0:00	1:00	D
++Rule	ROK	1951	only	-	May	 6	 0:00	1:00	D
++Rule	ROK	1955	only	-	May	 5	 0:00	1:00	D
++Rule	ROK	1955	only	-	Sep	 8	24:00	0	S
++Rule	ROK	1956	only	-	May	20	 0:00	1:00	D
++Rule	ROK	1956	only	-	Sep	29	24:00	0	S
++Rule	ROK	1957	1960	-	May	Sun>=1	 0:00	1:00	D
++Rule	ROK	1957	1960	-	Sep	Sat>=17	24:00	0	S
++Rule	ROK	1987	1988	-	May	Sun>=8	 2:00	1:00	D
++Rule	ROK	1987	1988	-	Oct	Sun>=8	 3:00	0	S
+ 
+ # From Paul Eggert (2016-08-23):
+ # The Korean Wikipedia entry gives the following sources for UT offsets:
+@@ -2920,6 +3132,11 @@
+ # no information
+ 
+ # Philippines
++
++# From Paul Eggert (2018-11-18):
++# The Spanish initially used American (west-of-Greenwich) time.
++# It is unknown what time Manila kept when the British occupied it from
++# 1762-10-06 through 1764-04; for now assume it kept American time.
+ # On 1844-08-16, Narciso Clavería, governor-general of the
+ # Philippines, issued a proclamation announcing that 1844-12-30 was to
+ # be immediately followed by 1845-01-01; see R.H. van Gent's
+@@ -3005,8 +3222,8 @@
+ # going to run on Higgins Time.' And so, until last year, it did."  See:
+ # Antar E. Dinner at When? Saudi Aramco World, 1969 March/April. 2-3.
+ # http://archive.aramcoworld.com/issue/196902/dinner.at.when.htm
+-# newspapers.com says a similar story about Higgins was published in the Port
+-# Angeles (WA) Evening News, 1965-03-10, page 5, but I lack access to the text.
++# Also see: Antar EN. Arabian flying is confusing.
++# Port Angeles (WA) Evening News. 1965-03-10. page 3.
+ #
+ # The TZ database cannot represent quasi-solar time; airline time is the best
+ # we can do.  The 1946 foreign air news digest of the U.S. Civil Aeronautics
+--- contrib/tzdata/australasia.orig
++++ contrib/tzdata/australasia
+@@ -402,10 +402,44 @@
+ # it is uninhabited.
+ 
+ # Guam
++
++# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
++# http://guamlegislature.com/Public_Laws_5th/PL05-025.pdf
++# http://documents.guam.gov/wp-content/uploads/E.O.-59-7-Guam-Daylight-Savings-Time-May-6-1959.pdf
++Rule	Guam	1959	only	-	Jun	27	2:00	1:00	D
++# http://documents.guam.gov/wp-content/uploads/E.O.-61-5-Revocation-of-Daylight-Saving-Time-and-Restoratio.pdf
++Rule	Guam	1961	only	-	Jan	29	2:00	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-67-13-Guam-Daylight-Savings-Time.pdf
++Rule	Guam	1967	only	-	Sep	 1	2:00	1:00	D
++# http://documents.guam.gov/wp-content/uploads/E.O.-69-2-Repeal-of-Guam-Daylight-Saving-Time.pdf
++Rule	Guam	1969	only	-	Jan	26	0:01	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-69-10-Guam-Daylight-Saving-Time.pdf
++Rule	Guam	1969	only	-	Jun	22	2:00	1:00	D
++Rule	Guam	1969	only	-	Aug	31	2:00	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-70-10-Guam-Daylight-Saving-Time.pdf
++# http://documents.guam.gov/wp-content/uploads/E.O.-70-30-End-of-Guam-Daylight-Saving-Time.pdf
++# http://documents.guam.gov/wp-content/uploads/E.O.-71-5-Guam-Daylight-Savings-Time.pdf
++Rule	Guam	1970	1971	-	Apr	lastSun	2:00	1:00	D
++Rule	Guam	1970	1971	-	Sep	Sun>=1	2:00	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-73-28.-Guam-Day-light-Saving-Time.pdf
++Rule	Guam	1973	only	-	Dec	16	2:00	1:00	D
++# http://documents.guam.gov/wp-content/uploads/E.O.-74-7-Guam-Daylight-Savings-Time-Rescinded.pdf
++Rule	Guam	1974	only	-	Feb	24	2:00	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-76-13-Daylight-Savings-Time.pdf
++Rule	Guam	1976	only	-	May	26	2:00	1:00	D
++# http://documents.guam.gov/wp-content/uploads/E.O.-76-25-Revocation-of-E.O.-76-13.pdf
++Rule	Guam	1976	only	-	Aug	22	2:01	0	S
++# http://documents.guam.gov/wp-content/uploads/E.O.-77-4-Daylight-Savings-Time.pdf
++Rule	Guam	1977	only	-	Apr	24	2:00	1:00	D
++# http://documents.guam.gov/wp-content/uploads/E.O.-77-18-Guam-Standard-Time.pdf
++Rule	Guam	1977	only	-	Aug	28	2:00	0	S
++
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
+ 			 9:39:00 -	LMT	1901        # Agana
+-			10:00	-	GST	2000 Dec 23 # Guam
++			10:00	-	GST	1941 Dec 10 # Guam
++			 9:00	-	+09	1944 Jul 31
++			10:00	Guam	G%sT	2000 Dec 23
+ 			10:00	-	ChST	# Chamorro Standard Time
+ Link Pacific/Guam Pacific/Saipan # N Mariana Is
+ 
+@@ -427,31 +461,56 @@
+ 
+ # Marshall Is
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+-Zone Pacific/Majuro	11:24:48 -	LMT	1901
+-			11:00	-	+11	1969 Oct
+-			12:00	-	+12
+-Zone Pacific/Kwajalein	11:09:20 -	LMT	1901
+-			11:00	-	+11	1969 Oct
+-			-12:00	-	-12	1993 Aug 20
+-			12:00	-	+12
++Zone Pacific/Majuro	 11:24:48 -	LMT	1901
++			 11:00	-	+11	1914 Oct
++			  9:00	-	+09	1919 Feb  1
++			 11:00	-	+11	1937
++			 10:00	-	+10	1941 Apr  1
++			  9:00	-	+09	1944 Jan 30
++			 11:00	-	+11	1969 Oct
++			 12:00	-	+12
++Zone Pacific/Kwajalein	 11:09:20 -	LMT	1901
++			 11:00	-	+11	1937
++			 10:00	-	+10	1941 Apr  1
++			  9:00	-	+09	1944 Feb  6
++			 11:00	-	+11	1969 Oct
++			-12:00	-	-12	1993 Aug 20 24:00
++			 12:00	-	+12
+ 
+ # Micronesia
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+-Zone Pacific/Chuuk	10:07:08 -	LMT	1901
+-			10:00	-	+10
+-Zone Pacific/Pohnpei	10:32:52 -	LMT	1901 # Kolonia
+-			11:00	-	+11
+-Zone Pacific/Kosrae	10:51:56 -	LMT	1901
+-			11:00	-	+11	1969 Oct
+-			12:00	-	+12	1999
+-			11:00	-	+11
++Zone Pacific/Chuuk	-13:52:52 -	LMT	1844 Dec 31
++			 10:07:08 -	LMT	1901
++			 10:00	-	+10	1914 Oct
++			  9:00	-	+09	1919 Feb  1
++			 10:00	-	+10	1941 Apr  1
++			  9:00	-	+09	1945 Aug
++			 10:00	-	+10
++Zone Pacific/Pohnpei	-13:27:08 -	LMT	1844 Dec 31	# Kolonia
++			 10:32:52 -	LMT	1901
++			 11:00	-	+11	1914 Oct
++			  9:00	-	+09	1919 Feb  1
++			 11:00	-	+11	1937
++			 10:00	-	+10	1941 Apr  1
++			  9:00	-	+09	1945 Aug
++			 11:00	-	+11
++Zone Pacific/Kosrae	-13:08:04 -	LMT	1844 Dec 31
++			 10:51:56 -	LMT	1901
++			 11:00	-	+11	1914 Oct
++			  9:00	-	+09	1919 Feb  1
++			 11:00	-	+11	1937
++			 10:00	-	+10	1941 Apr  1
++			  9:00	-	+09	1945 Aug
++			 11:00	-	+11	1969 Oct
++			 12:00	-	+12	1999
++			 11:00	-	+11
+ 
+ # Nauru
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15 # Uaobe
+-			11:30	-	+1130	1942 Mar 15
+-			9:00	-	+09	1944 Aug 15
+-			11:30	-	+1130	1979 May
++			11:30	-	+1130	1942 Aug 29
++			 9:00	-	+09	1945 Sep  8
++			11:30	-	+1130	1979 Feb 10  2:00
+ 			12:00	-	+12
+ 
+ # New Caledonia
+@@ -552,8 +611,9 @@
+ 
+ # Palau (Belau)
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+-Zone Pacific/Palau	8:57:56 -	LMT	1901 # Koror
+-			9:00	-	+09
++Zone Pacific/Palau	-15:02:04 -	LMT	1844 Dec 31	# Koror
++			  8:57:56 -	LMT	1901
++			  9:00	-	+09
+ 
+ # Papua New Guinea
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+@@ -815,7 +875,7 @@
+ # tz@iana.org for general use in the future).  For more, please see
+ # the file CONTRIBUTING in the tz distribution.
+ 
+-# From Paul Eggert (2017-02-10):
++# From Paul Eggert (2018-11-18):
+ #
+ # Unless otherwise specified, the source for data through 1990 is:
+ # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+@@ -840,6 +900,7 @@
+ # A reliable and entertaining source about time zones is
+ # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+ #
++# I invented the abbreviation marked "*".
+ # The following abbreviations are from other sources.
+ # Corrections are welcome!
+ #		std	dst
+@@ -847,7 +908,7 @@
+ #	  8:00	AWST	AWDT	Western Australia
+ #	  9:30	ACST	ACDT	Central Australia
+ #	 10:00	AEST	AEDT	Eastern Australia
+-#	 10:00	GST		Guam through 2000
++#	 10:00	GST	GDT*	Guam through 2000
+ #	 10:00	ChST		Chamorro
+ #	 11:30	NZMT	NZST	New Zealand through 1945
+ #	 12:00	NZST	NZDT	New Zealand 1946-present
+@@ -1546,28 +1607,70 @@
+ 
+ # Kwajalein
+ 
+-# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
+-# I wonder what happened in Kwajalein, where there was NO Friday,
+-# 1993-08-20.  Thursday night at midnight Kwajalein switched sides with
+-# respect to the International Date Line, to rejoin its fellow islands,
+-# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
++# From an AP article (1993-08-22):
++# "The nearly 3,000 Americans living on this remote Pacific atoll have a good
++# excuse for not remembering Saturday night: there wasn't one.  Residents were
++# going to bed Friday night and waking up Sunday morning because at midnight
++# -- 8 A.M. Eastern daylight time on Saturday -- Kwajalein was jumping from
++# one side of the international date line to the other."
++# "In Marshall Islands, Friday is followed by Sunday", NY Times. 1993-08-22.
++# https://www.nytimes.com/1993/08/22/world/in-marshall-islands-friday-is-followed-by-sunday.html
++
++# From Phake Nick (2018-10-27):
++# <https://wiki.suikawiki.org/n/南洋群島の標準時> ... pointed out that
++# currently tzdata say Pacific/Kwajalein switched from GMT+11 to GMT-12 in
++# 1969 October without explanation, however an 1993 article from NYT say it
++# synchorized its day with US mainland about 40 years ago and thus the switch
++# should occur at around 1950s instead.
++#
++# From Paul Eggert (2018-11-18):
++# The NYT (actually, AP) article is vague and possibly wrong about this.
++# The article says the earlier switch was "40 years ago when the United States
++# Army established a missile test range here".  However, the Kwajalein Test
++# Center was established on 1960-10-01 and was run by the US Navy.  It was
++# transferred to the US Army on 1964-07-01.  See "Seize the High Ground"
++# <https://history.army.mil/html/books/070/70-88-1/cmhPub_70-88-1.pdf>.
++# Given that Shanks was right on the money about the 1993 change, I'm inclined
++# to take Shanks's word for the 1969 change unless we find better evidence.
+ 
+ 
+ # N Mariana Is, Guam
+ 
++# From Phake Nick (2018-10-27):
++# Guam Island was briefly annexed by Japan during ... year 1941-1944 ...
++# however there are no detailed information about what time it use during that
++# period.  It would probably be reasonable to assume Guam use GMT+9 during
++# that period of time like the surrounding area.
++
++# From Paul Eggert (2018-11-18):
+ # Howse writes (p 153) "The Spaniards, on the other hand, reached the
+ # Philippines and the Ladrones from America," and implies that the Ladrones
+ # (now called the Marianas) kept American date for quite some time.
+ # For now, we assume the Ladrones switched at the same time as the Philippines;
+ # see Asia/Manila.
+-
++#
++# Use 1941-12-10 and 1944-07-31 for Guam WWII transitions, as the rough start
++# and end of Japanese control of Agana.  We don't know whether the Northern
++# Marianas followed Guam's DST rules from 1959 through 1977; for now, assume
++# they did as that avoids the need for a separate zone due to our 1970 cutoff.
++#
+ # US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
+ # under the name "Chamorro Standard Time".  There is no official abbreviation,
+ # but Congressman Robert A. Underwood, author of the bill that became law,
+ # wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+ 
++# See also the commentary for Micronesia.
+ 
+-# Micronesia
++
++# Marshall Is
++# See the commentary for Micronesia.
++
++
++# Micronesia (and nearby)
++
++# From Paul Eggert (2018-11-18):
++# Like the Ladrones (see Guam commentary), assume the Spanish East Indies
++# kept American time until the Philippines switched at the end of 1844.
+ 
+ # Alan Eugene Davis writes (1996-03-16),
+ # "I am certain, having lived there for the past decade, that 'Truk'
+@@ -1583,6 +1686,95 @@
+ # that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
+ # We don't know when Kosrae switched from +12; assume January 1 for now.
+ 
++# From Phake Nick (2018-10-27):
++#
++# From a Japanese wiki site https://wiki.suikawiki.org/n/南洋群島の標準時
++# ...
++# For "Southern Islands" (modern region of Mariana + Palau + Federation of
++# Micronesia + Marshall Islands):
++#
++# A 1906 Japanese magazine shown the Caroline Islands and Mariana Islands
++# who was occupied by Germany at the time as GMT+10, together with the like
++# of German New Guinea.  However there is a marking saying it have not been
++# implemented (yet).  No further information after that were found.
++#
++# Japan invaded those islands in 1914, and records shows that they were
++# instructed to use JST at the time.
++#
++# 1915 January telecommunication record on the Jaluit Atoll shows they use
++# the meridian of 170E as standard time (GMT+11:20), which is similar to the
++# longitude of the atoll.
++# 1915 February record say the 170E standard time is to be used until
++# February 9 noon, and after February 9 noon they are to use JST.
++# However these are time used within the Japanese Military at the time and
++# probably does not reflect the time used by local resident at the time (that
++# is if they keep their own time back then)
++#
++# In January 1919 the occupying force issued a command that split the area
++# into three different timezone with meridian of 135E, 150E, 165E (JST+0, +1,
++# +2), and the command was to become effective from February 1 of the same
++# year.  Despite the target of the command is still only for the occupying
++# force itself, further publication have described the time as the standard
++# time for the occupied area and thus it can probably be seen as such.
++#  * Area that use meridian of 135E: Palau and Yap civil administration area
++#    (Southern Islands Western Standard Time)
++#  * Area that use meridian of 150E: Truk (Chuuk) and Saipan civil
++#    administration area (Southern Islands Central Standard Time)
++#  * Area that use meridian of 165E: Ponape (Pohnpei) and Jaluit civil
++#    administration area (Southern Islands Eastern Standard Time).
++#  * In the next few years Japanese occupation of those islands have been
++#    formalized via League of Nation Mandate (South Pacific Mandate) and formal
++#    governance structure have been established, these district [become
++#    subprefectures] and timezone classification have been inherited as standard
++#    time of the area.
++#  * Saipan subprefecture include Mariana islands (exclude Guam which was
++#    occupied by America at the time), Palau and Yap subprefecture rule the
++#    Western Caroline Islands with 137E longitude as border, Truk and Ponape
++#    subprefecture rule the Eastern Caroline Islands with 154E as border, Ponape
++#    subprefecture also rule part of Marshall Islands to the west of 164E
++#    starting from (1918?) and Jaluit subprefecture rule the rest of the
++#    Marshall Islands.
++#
++# And then in year 1937, an announcement was made to change the time in the
++# area into 2 timezones:
++#  * Area that use meridian of 135E: area administered by Palau, Yap and
++#    Saipan subprefecture (Southern Islands Western Standard Time)
++#  * Area that use meridian of 150E: area administered by Truk (Chuuk),
++#    Ponape (Pohnpei) and Jaluit subprefecture (Southern Islands Eastern
++#    Standard Time)
++#
++# Another announcement issued in 1941 say that on April 1 that year,
++# standard time of the Southern Islands would be changed to use the meridian
++# of 135E (GMT+9), and thus abolishing timezone different within the area.
++#
++# Then Pacific theater of WWII started and Japan slowly lose control on the
++# island.  The webpage I linked above contain no information during this
++# period of time....
++#
++# After the end of WWII, in 1946 February, a document written by the
++# (former?) Japanese military personnel describe there are 3 hours time
++# different between Caroline islands time/Wake island time and the Chungking
++# time, which would mean the time being used there at the time was GMT+10.
++#
++# After that, the area become Trust Territories of the Pacific Islands
++# under American administration from year 1947.  The site listed some
++# American/International books/maps/publications about time used in those
++# area during this period of time but they doesn't seems to be reliable
++# information so it would be the best if someone know where can more reliable
++# information can be found.
++#
++#
++# From Paul Eggert (2018-11-18):
++#
++# For the above, use vague dates like "1914" and "1945" for transitions that
++# plausibly exist but for which the details are not known.  The information
++# for Wake is too sketchy to act on.
++#
++# The 1906 GMT+10 info about German-controlled islands might not have been
++# done, so omit it from the data for now.
++#
++# The Jaluit info governs Kwajalein.
++
+ 
+ # Midway
+ 
+@@ -1600,6 +1792,29 @@
+ # started DST on June 3.  Possibly DST was observed other years
+ # in Midway, but we have no record of it.
+ 
++# Nauru
++
++# From Phake Nick (2018-10-31):
++# Currently, the tz database say Nauru use LMT until 1921, and then
++# switched to GMT+11:30 for the next two decades.
++# However, a number of timezone map published in America/Japan back then
++# showed its timezone as GMT+11 per https://wiki.suikawiki.org/n/ナウルの標準時
++# And it would also be nice if the 1921 transition date could be sourced.
++# ...
++# The "Nauru Standard Time Act 1978 Time Change"
++# http://ronlaw.gov.nr/nauru_lpms/files/gazettes/4b23a17d2030150404db7a5fa5872f52.pdf#page=3
++# based on "Nauru Standard Time Act 1978 Time Change"
++# http://www.paclii.org/nr/legis/num_act/nsta1978207/ defined that "Nauru
++# Alternative Time" (GMT+12) should be in effect from 1979 Feb.
++#
++# From Paul Eggert (2018-11-19):
++# The 1921-01-15 introduction of standard time is in Shanks; it is also in
++# "Standard Time Throughout the World", US National Bureau of Standards (1935),
++# page 3, which does not give the UT offset.  In response to a comment by
++# Phake Nick I set the Nauru time of occupation by Japan to
++# 1942-08-29/1945-09-08 by using dates from:
++# https://en.wikipedia.org/wiki/Japanese_occupation_of_Nauru
++
+ # Norfolk
+ 
+ # From Alexander Krivenyshev (2015-09-23):
+@@ -1615,6 +1830,9 @@
+ # other than in 1974/5.  See:
+ # https://www.timeanddate.com/time/australia/norfolk-island.html
+ 
++# Palau
++# See commentary for Micronesia.
++
+ # Pitcairn
+ 
+ # From Rives McDow (1999-11-08):
+@@ -1779,6 +1997,9 @@
+ # From Paul Eggert (2003-03-23):
+ # We have no other report of DST in Wake Island, so omit this info for now.
+ 
++# See also the commentary for Micronesia.
++
++
+ ###############################################################################
+ 
+ # The International Date Line
+--- contrib/tzdata/leapseconds.orig
++++ contrib/tzdata/leapseconds
+@@ -19,9 +19,12 @@
+ # See: Levine J. Coordinated Universal Time and the leap second.
+ # URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995
+ # <https://ieeexplore.ieee.org/document/7909995>.
++
+ # There were no leap seconds before 1972, because the official mechanism
+ # accounting for the discrepancy between atomic time and the earth's rotation
+-# did not exist.
++# did not exist.  The first ("1 Jan 1972") data line in leap-seconds.list
++# does not denote a leap second; it denotes the start of the current definition
++# of UTC.
+ 
+ # The correction (+ or -) is made at the given time, so lines
+ # will typically look like:
+--- contrib/tzdata/leapseconds.awk.orig
++++ contrib/tzdata/leapseconds.awk
+@@ -24,9 +24,12 @@
+   print "# See: Levine J. Coordinated Universal Time and the leap second."
+   print "# URSI Radio Sci Bull. 2016;89(4):30-6. doi:10.23919/URSIRSB.2016.7909995"
+   print "# <https://ieeexplore.ieee.org/document/7909995>."
++  print ""
+   print "# There were no leap seconds before 1972, because the official mechanism"
+   print "# accounting for the discrepancy between atomic time and the earth's rotation"
+-  print "# did not exist."
++  print "# did not exist.  The first (\"1 Jan 1972\") data line in leap-seconds.list"
++  print "# does not denote a leap second; it denotes the start of the current definition"
++  print"# of UTC."
+   print ""
+   print "# The correction (+ or -) is made at the given time, so lines"
+   print "# will typically look like:"
+--- contrib/tzdata/northamerica.orig
++++ contrib/tzdata/northamerica
+@@ -599,6 +599,17 @@
+ # between AKST and AKDT from now on....
+ # https://www.krbd.org/2015/10/30/annette-island-times-they-are-a-changing/
+ 
++# From Ryan Stanley (2018-11-06):
++# The Metlakatla community in Alaska has decided not to change its
++# clock back an hour starting on November 4th, 2018 (day before yesterday).
++# They will be gmtoff=-28800 year-round.
++# https://www.facebook.com/141055983004923/photos/pb.141055983004923.-2207520000.1541465673./569081370202380/
++
++# From Paul Eggert (2018-12-16):
++# In a 2018-12-11 special election, Metlakatla voted to go back to
++# Alaska time (including daylight saving time) starting next year.
++# https://www.krbd.org/2018/12/12/metlakatla-to-follow-alaska-standard-time-allow-liquor-sales/
++
+ # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+ Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 19 15:33:32
+ 			 -8:57:41 -	LMT	1900 Aug 20 12:00
+@@ -625,6 +636,8 @@
+ 			 -8:00	-	PST	1969
+ 			 -8:00	US	P%sT	1983 Oct 30  2:00
+ 			 -8:00	-	PST	2015 Nov  1  2:00
++			 -9:00	US	AK%sT	2018 Nov  4  2:00
++			 -8:00	-	PST	2019 Mar Sun>=8 3:00
+ 			 -9:00	US	AK%sT
+ Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 19 15:12:18
+ 			 -9:18:55 -	LMT	1900 Aug 20 12:00
+@@ -785,6 +798,22 @@
+ # For a map of Indiana's time zone regions, see:
+ # https://en.wikipedia.org/wiki/Time_in_Indiana
+ #
++# From Paul Eggert (2018-11-30):
++# A brief but entertaining history of time in Indiana describes a 1949 debate
++# in the Indiana House where city legislators (who favored "fast time")
++# tussled with farm legislators (who didn't) over a bill to outlaw DST:
++#  "Lacking enough votes, the city faction tries to filibuster until time runs
++#   out on the session at midnight, but rural champion Rep. Herbert Copeland,
++#   R-Madison, leans over the gallery railing and forces the official clock
++#   back to 9 p.m., breaking it in the process.  The clock sticks on 9 as the
++#   debate rages on into the night.  The filibuster finally dies out and the
++#   bill passes, while outside the chamber, clocks read 3:30 a.m.  In the end,
++#   it doesn't matter which side won.  The law has no enforcement powers and
++#   is simply ignored by fast-time communities."
++# How Indiana went from 'God's time' to split zones and daylight-saving.
++# Indianapolis Star. 2018-11-27 14:58 -05.
++# https://www.indystar.com/story/news/politics/2018/11/27/indianapolis-indiana-time-zone-history-central-eastern-daylight-savings-time/2126300002/
++#
+ # From Paul Eggert (2007-08-17):
+ # Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
+ # with the following exceptions:
+--- contrib/tzdata/theory.html.orig
++++ contrib/tzdata/theory.html
+@@ -406,7 +406,7 @@
+       EAT East Africa,
+       EST/EDT/EWT/EPT/EDDT Eastern [North America],
+       EET/EEST Eastern European,
+-      GST Guam,
++      GST/GDT Guam,
+       HST/HDT/HWT/HPT Hawaii,
+       HKT/HKST Hong Kong,
+       IST India,
+@@ -1238,7 +1238,7 @@
+ use <a href="https://en.wikipedia.org/wiki/Timekeeping_on_Mars">Mars time</a>.
+ Jet Propulsion Laboratory (JPL) coordinators kept Mars time on
+ and off during the
+-<a href="https://en.wikipedia.org/wiki/Mars_Pathfinder#End_of_mission">Mars
++<a href="https://en.wikipedia.org/wiki/Mars_Pathfinder">Mars
+ Pathfinder</a> mission.
+ Some of their family members also adapted to Mars time.
+ Dozens of special Mars watches were built for JPL workers who kept
+@@ -1261,8 +1261,7 @@
+ honor of the British astronomer who built the Greenwich telescope that
+ defines Earth's prime meridian.
+ Mean solar time on the Mars prime meridian is
+-called <a href="https://en.wikipedia.org/wiki/Mars_Coordinated_Time">Mars
+-Coordinated Time (<abbr>MTC</abbr>)</a>.
++called Mars Coordinated Time (<abbr>MTC</abbr>).
+ </p>
+ 
+ <p>
+--- contrib/tzdata/version.orig
++++ contrib/tzdata/version
+@@ -1 +1 @@
+-2018g
++2018i
+--- contrib/tzdata/ziguard.awk.orig
++++ contrib/tzdata/ziguard.awk
+@@ -54,7 +54,7 @@
+     }
+   }
+ 
+-  # If this line should differ due to Namibia using Rule SAVE suffixes,
++  # If this line should differ due to Namibia using negative SAVE values,
+   # uncomment the desired version and comment out the undesired one.
+   Rule_Namibia = /^#?Rule[\t ]+Namibia[\t ]/
+   Zone_using_Namibia_rule \
+@@ -87,6 +87,23 @@
+     sub(/Sat>=8/, "Sun>=9")
+     sub(/25:00/, " 1:00")
+   }
++
++  # In rearguard format, change the Morocco lines with negative SAVE values
++  # to use positive SAVE values.
++  if (!vanguard && $1 == "Rule" && $2 == "Morocco" && $4 == 2018 \
++      && $6 == "Oct") {
++    sub(/\t2018\t/, "\t2017\t")
++  }
++  if (!vanguard && $1 == "Rule" && $2 == "Morocco" && 2019 <= $3) {
++    if ($9 == "0") {
++      sub(/\t0\t/, "\t1:00\t")
++    } else {
++      sub(/\t-1:00\t/, "\t0\t")
++    }
++  }
++  if (!vanguard && $1 == "1:00" && $2 == "Morocco" && $3 == "+01/+00") {
++    sub(/1:00\tMorocco\t\+01\/\+00$/, "0:00\tMorocco\t+00/+01")
++  }
+ }
+ 
+ # If a Link line is followed by a Zone line for the same data, comment
+--- contrib/tzdata/zone.tab.orig
++++ contrib/tzdata/zone.tab
+@@ -239,6 +239,7 @@
+ KY	+1918-08123	America/Cayman
+ KZ	+4315+07657	Asia/Almaty	Kazakhstan (most areas)
+ KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
++KZ	+5312+06337	Asia/Qostanay	Qostanay/Kostanay/Kustanay
+ KZ	+5017+05710	Asia/Aqtobe	Aqtobe/Aktobe
+ KZ	+4431+05016	Asia/Aqtau	Mangghystau/Mankistau
+ KZ	+4707+05156	Asia/Atyrau	Atyrau/Atirau/Gur'yev
+@@ -332,9 +333,9 @@
+ RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
+ RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
+ RU	+4457+03406	Europe/Simferopol	MSK+00 - Crimea
+-RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
+ RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
+ RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
++RU	+4844+04425	Europe/Volgograd	MSK+01 - Volgograd
+ RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
+ RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
+ RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
+--- contrib/tzdata/zone1970.tab.orig
++++ contrib/tzdata/zone1970.tab
+@@ -212,6 +212,7 @@
+ KR	+3733+12658	Asia/Seoul
+ KZ	+4315+07657	Asia/Almaty	Kazakhstan (most areas)
+ KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda/Kyzylorda/Kzyl-Orda
++KZ	+5312+06337	Asia/Qostanay	Qostanay/Kostanay/Kustanay
+ KZ	+5017+05710	Asia/Aqtobe	Aqtöbe/Aktobe
+ KZ	+4431+05016	Asia/Aqtau	Mangghystaū/Mankistau
+ KZ	+4707+05156	Asia/Atyrau	Atyraū/Atirau/Gur'yev
+@@ -290,9 +291,9 @@
+ RU	+5443+02030	Europe/Kaliningrad	MSK-01 - Kaliningrad
+ RU	+554521+0373704	Europe/Moscow	MSK+00 - Moscow area
+ RU	+4457+03406	Europe/Simferopol	MSK+00 - Crimea
+-RU	+4844+04425	Europe/Volgograd	MSK+00 - Volgograd
+ RU	+5836+04939	Europe/Kirov	MSK+00 - Kirov
+ RU	+4621+04803	Europe/Astrakhan	MSK+01 - Astrakhan
++RU	+4844+04425	Europe/Volgograd	MSK+01 - Volgograd
+ RU	+5134+04602	Europe/Saratov	MSK+01 - Saratov
+ RU	+5420+04824	Europe/Ulyanovsk	MSK+01 - Ulyanovsk
+ RU	+5312+05009	Europe/Samara	MSK+01 - Samara, Udmurtia
diff --git a/share/security/patches/EN-19:04/tzdata-2018i.patch.asc b/share/security/patches/EN-19:04/tzdata-2018i.patch.asc
new file mode 100644
index 0000000000..920b446bcd
--- /dev/null
+++ b/share/security/patches/EN-19:04/tzdata-2018i.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2Ri1fFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJtHA/+JOl78JntS1QrQn11yftlRvHgwMHbp8tOpQ9TWNsuw0uBpeIbf8ZqGRaK
+BGMW+Ph77x2dMD8tt8sGYDWy1xsUUVfy7EGF7zEFjCx69hGFxno652/MrGvCYNgo
+tWfbjYJhJsHaplkNFZPdIvtWfQ1IGGHKEUMnTEoCr75NeXscuUCpBtpZFnJdYry+
+EHCHd2/If/49YF0PPs7zctM02KPAb52h+wwdbv19HyBD1UWuqGb3YZEPsH1btSs6
+iAdEut+nrFBt5iL+fJE+CRTFXWyZoU5WD95+fmb4p4dPtisCey5QE0iSN/MCw5xB
+Kj6+MuRJ+jAmWufNE+DIJYbSqosIH9zvDt0NXpgWUOlsdE87jdMGl0DgNK7eaScQ
+5AqeUFFXgv63kHXl90vln/m+rIYI3xjkrAij6mkjDHAIFpE9rKVtQAezbxZ/6p7v
+ZoIY4d8mb8oZhRfwd8/mAvzqTQWFnyw0OImzk7NMLj9a4idq0eTyXq1qbceuc1pt
+QUJtbWfKDptN9GDNPE37FulsiLufaeNPleA54U4XRLyBYMnZfc4yPfdcy8b10GCf
+zwy6bn+mZaFsOkMoLHd2pRV3erdXF8H42qUGAAW9I9Zqy2+hN87IDZ2ZUPHEYdxF
+5+jD/4HsHgFgMjakP/7CJPdcVrf/pyY2PGP1Qf5dS8C4wqvbl/k=
+=9pQl
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-19:05/kqueue.patch b/share/security/patches/EN-19:05/kqueue.patch
new file mode 100644
index 0000000000..944273e4c5
--- /dev/null
+++ b/share/security/patches/EN-19:05/kqueue.patch
@@ -0,0 +1,49 @@
+--- sys/kern/kern_event.c.orig
++++ sys/kern/kern_event.c
+@@ -1296,6 +1296,8 @@
+ 			kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
+ 			    EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
+ 			kn->kn_status = KN_INFLUX|KN_DETACHED;
++			if ((kev->flags & EV_DISABLE) != 0)
++				kn->kn_status |= KN_DISABLED;
+ 
+ 			error = knote_attach(kn, kq);
+ 			KQ_UNLOCK(kq);
+@@ -1332,6 +1334,11 @@
+ 		KNOTE_ACTIVATE(kn, 1);
+ 	}
+ 
++	if ((kev->flags & EV_ENABLE) != 0)
++		kn->kn_status &= ~KN_DISABLED;
++	else if ((kev->flags & EV_DISABLE) != 0)
++		kn->kn_status |= KN_DISABLED;
++
+ 	/*
+ 	 * The user may change some filter values after the initial EV_ADD,
+ 	 * but doing so will not reset any filter which has already been
+@@ -1348,19 +1355,17 @@
+ 		kn->kn_sdata = kev->data;
+ 	}
+ 
++done_ev_add:
+ 	/*
+ 	 * We can get here with kn->kn_knlist == NULL.  This can happen when
+ 	 * the initial attach event decides that the event is "completed" 
+-	 * already.  i.e. filt_procattach is called on a zombie process.  It
+-	 * will call filt_proc which will remove it from the list, and NULL
++	 * already, e.g., filt_procattach() is called on a zombie process.  It
++	 * will call filt_proc() which will remove it from the list, and NULL
+ 	 * kn_knlist.
++	 *
++	 * KN_DISABLED will be stable while the knote is in flux, so the
++	 * unlocked read will not race with an update.
+ 	 */
+-done_ev_add:
+-	if ((kev->flags & EV_ENABLE) != 0)
+-		kn->kn_status &= ~KN_DISABLED;
+-	else if ((kev->flags & EV_DISABLE) != 0)
+-		kn->kn_status |= KN_DISABLED;
+-
+ 	if ((kn->kn_status & KN_DISABLED) == 0)
+ 		event = kn->kn_fop->f_event(kn, 0);
+ 	else
diff --git a/share/security/patches/EN-19:05/kqueue.patch.asc b/share/security/patches/EN-19:05/kqueue.patch.asc
new file mode 100644
index 0000000000..00d917b91e
--- /dev/null
+++ b/share/security/patches/EN-19:05/kqueue.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAlw2RjRfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLrQRAAlMBtUSxbiSdLI8KfeKYj2Xe2cAvVfK+oK+pooErNX6TyofIyewrck4PB
+xZ/c7clZg3WRKAZJ1D6RacF02coBlCJHJbajMtjrIO6p3lXLX7FalxrIc9APiDI1
+n5he7Ij5Uu6FedPqJmSu81wOfInI+mX6vhap2UFrajFXI1iexhT4FiANtHGxTQwG
+I8GlFfptT7QY1dUugt2+KRoYFobUv4SQynhgDb1CfMZ55SCjnkEPIqE6dMsv/f4d
+iKBQoMmI8oBB6LLP1YhsidgG7LS84A+CwGXf9KQHRrugU9pPy2b8nQodGBzfmv4c
+UaVJYO7hIkCof+4loloJrxEATWNnb2V5XlJumY6ENQwCCjttD/TOnfAAbUCkajZW
+t+LZu5MkTZpx/Zyby9ojHl6yd7u7Cc2klN56vyOjGGBZ9PbXjsrwllEonnlHEThY
+NDwcML8kjXPCXwgHtysKTxJKT9HsaG5tL/PMdTeHUwmkAfYyOeOTL14wpoF5//tc
+akIcGw5qQjfFFaFCkfdFwktF63Hdsv8/G56sDBYHsdPE7Bwj4cnJhasWWtUTTN5t
+XOvxoGUMOKwyQ/tUlNHvuyOEieEy781LYqHhVQObI00qkeSOJmwKaDuOjNd64wjv
+2jJ4ZLegckyQlYR4GKGr6L0h6WTyL+d4xXZ7EcOxdkDa/dAYnHQ=
+=Er0a
+-----END PGP SIGNATURE-----
diff --git a/share/xml/notices.xml b/share/xml/notices.xml
index 727498cf8f..bfa31e39f9 100644
--- a/share/xml/notices.xml
+++ b/share/xml/notices.xml
@@ -4,6 +4,39 @@
       $FreeBSD$
     </cvs:keyword>
 
+  <year>
+    <name>2019</name>
+
+    <month>
+      <name>1</name>
+
+      <day>
+	<name>9</name>
+
+	<notice>
+	  <name>FreeBSD-EN-19:05.kqueue</name>
+	</notice>
+
+	<notice>
+	  <name>FreeBSD-EN-19:04.tzdata</name>
+	</notice>
+
+	<notice>
+	  <name>FreeBSD-EN-19:03.sqlite</name>
+	</notice>
+
+	<notice>
+	  <name>FreeBSD-EN-19:02.tcp</name>
+	</notice>
+
+	<notice>
+	  <name>FreeBSD-EN-19:01.cc_cubic</name>
+	</notice>
+
+      </day>
+    </month>
+  </year>
+
   <year>
     <name>2018</name>