Page MenuHomeFreeBSD

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: head/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc
===================================================================
--- head/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc (nonexistent)
+++ head/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/advisories/FreeBSD-EN-19:01.cc_cubic.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/advisories/FreeBSD-EN-19:02.tcp.asc
===================================================================
--- head/share/security/advisories/FreeBSD-EN-19:02.tcp.asc (nonexistent)
+++ head/share/security/advisories/FreeBSD-EN-19:02.tcp.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/advisories/FreeBSD-EN-19:02.tcp.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc
===================================================================
--- head/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc (nonexistent)
+++ head/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/advisories/FreeBSD-EN-19:03.sqlite.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc
===================================================================
--- head/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc (nonexistent)
+++ head/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/advisories/FreeBSD-EN-19:04.tzdata.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc
===================================================================
--- head/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc (nonexistent)
+++ head/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/advisories/FreeBSD-EN-19:05.kqueue.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:01/cc_cubic.patch
===================================================================
--- head/share/security/patches/EN-19:01/cc_cubic.patch (nonexistent)
+++ head/share/security/patches/EN-19:01/cc_cubic.patch (revision 52756)
@@ -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);
+ }
Property changes on: head/share/security/patches/EN-19:01/cc_cubic.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:01/cc_cubic.patch.asc
===================================================================
--- head/share/security/patches/EN-19:01/cc_cubic.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:01/cc_cubic.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:01/cc_cubic.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:02/tcp.patch
===================================================================
--- head/share/security/patches/EN-19:02/tcp.patch (nonexistent)
+++ head/share/security/patches/EN-19:02/tcp.patch (revision 52756)
@@ -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;
Property changes on: head/share/security/patches/EN-19:02/tcp.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:02/tcp.patch.asc
===================================================================
--- head/share/security/patches/EN-19:02/tcp.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:02/tcp.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:02/tcp.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:03/sqlite-11.patch
===================================================================
--- head/share/security/patches/EN-19:03/sqlite-11.patch (nonexistent)
+++ head/share/security/patches/EN-19:03/sqlite-11.patch (revision 52756)
@@ -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;
+ }
Property changes on: head/share/security/patches/EN-19:03/sqlite-11.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:03/sqlite-11.patch.asc
===================================================================
--- head/share/security/patches/EN-19:03/sqlite-11.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:03/sqlite-11.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:03/sqlite-11.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:03/sqlite-12.patch
===================================================================
--- head/share/security/patches/EN-19:03/sqlite-12.patch (nonexistent)
+++ head/share/security/patches/EN-19:03/sqlite-12.patch (revision 52756)
@@ -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
++
Property changes on: head/share/security/patches/EN-19:03/sqlite-12.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:03/sqlite-12.patch.asc
===================================================================
--- head/share/security/patches/EN-19:03/sqlite-12.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:03/sqlite-12.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:03/sqlite-12.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:04/tzdata-2018i.patch
===================================================================
--- head/share/security/patches/EN-19:04/tzdata-2018i.patch (nonexistent)
+++ head/share/security/patches/EN-19:04/tzdata-2018i.patch (revision 52756)
@@ -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
Property changes on: head/share/security/patches/EN-19:04/tzdata-2018i.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:04/tzdata-2018i.patch.asc
===================================================================
--- head/share/security/patches/EN-19:04/tzdata-2018i.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:04/tzdata-2018i.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:04/tzdata-2018i.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:05/kqueue.patch
===================================================================
--- head/share/security/patches/EN-19:05/kqueue.patch (nonexistent)
+++ head/share/security/patches/EN-19:05/kqueue.patch (revision 52756)
@@ -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
Property changes on: head/share/security/patches/EN-19:05/kqueue.patch
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/security/patches/EN-19:05/kqueue.patch.asc
===================================================================
--- head/share/security/patches/EN-19:05/kqueue.patch.asc (nonexistent)
+++ head/share/security/patches/EN-19:05/kqueue.patch.asc (revision 52756)
@@ -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-----
Property changes on: head/share/security/patches/EN-19:05/kqueue.patch.asc
___________________________________________________________________
Added: fbsd:nokeywords
## -0,0 +1 ##
+yes
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: head/share/xml/notices.xml
===================================================================
--- head/share/xml/notices.xml (revision 52755)
+++ head/share/xml/notices.xml (revision 52756)
@@ -1,968 +1,1001 @@
<?xml version="1.0"?>
<advisories>
<cvs:keyword xmlns:cvs="http://www.FreeBSD.org/XML/CVS">
$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>
<month>
<name>12</name>
<day>
<name>19</name>
<notice>
<name>FreeBSD-EN-18:18.zfs</name>
</notice>
<notice>
<name>FreeBSD-EN-18:17.vm</name>
</notice>
<notice>
<name>FreeBSD-EN-18:16.ptrace</name>
</notice>
</day>
</month>
<month>
<name>11</name>
<day>
<name>27</name>
<notice>
<name>FreeBSD-EN-18:15.loader</name>
</notice>
<notice>
<name>FreeBSD-EN-18:14.tzdata</name>
</notice>
<notice>
<name>FreeBSD-EN-18:13.icmp</name>
</notice>
</day>
</month>
<month>
<name>9</name>
<day>
<name>27</name>
<notice>
<name>FreeBSD-EN-18:12.mem</name>
</notice>
<notice>
<name>FreeBSD-EN-18:11.listen</name>
</notice>
<notice>
<name>FreeBSD-EN-18:10.syscall</name>
</notice>
<notice>
<name>FreeBSD-EN-18:09.ip</name>
</notice>
</day>
<day>
<name>12</name>
<notice>
<name>FreeBSD-EN-18:08.lazyfpu</name>
</notice>
</day>
</month>
<month>
<name>6</name>
<day>
<name>21</name>
<notice>
<name>FreeBSD-EN-18:07.pmap</name>
</notice>
</day>
</month>
<month>
<name>5</name>
<day>
<name>8</name>
<notice>
<name>FreeBSD-EN-18:06.tzdata</name>
</notice>
<notice>
<name>FreeBSD-EN-18:05.mem</name>
</notice>
</day>
</month>
<month>
<name>4</name>
<day>
<name>4</name>
<notice>
<name>FreeBSD-EN-18:04.mem</name>
</notice>
<notice>
<name>FreeBSD-EN-18:03.tzdata</name>
</notice>
</day>
</month>
<month>
<name>3</name>
<day>
<name>7</name>
<notice>
<name>FreeBSD-EN-18:02.file</name>
</notice>
<notice>
<name>FreeBSD-EN-18:01.tzdata</name>
</notice>
</day>
</month>
</year>
<year>
<name>2017</name>
<month>
<name>11</name>
<day>
<name>2</name>
<notice>
<name>FreeBSD-EN-17:09.tzdata</name>
</notice>
</day>
</month>
<month>
<name>8</name>
<day>
<name>10</name>
<notice>
<name>FreeBSD-EN-17:08.pf</name>
</notice>
<notice>
<name>FreeBSD-EN-17:07.vnet</name>
</notice>
</day>
</month>
<month>
<name>7</name>
<day>
<name>12</name>
<notice>
<name>FreeBSD-EN-17:06.hyperv</name>
</notice>
</day>
</month>
<month>
<name>4</name>
<day>
<name>12</name>
<notice>
<name>FreeBSD-EN-17:05.xen</name>
</notice>
</day>
</month>
<month>
<name>2</name>
<day>
<name>23</name>
<notice>
<name>FreeBSD-EN-17:04.mandoc</name>
</notice>
<notice>
<name>FreeBSD-EN-17:03.hyperv</name>
</notice>
<notice>
<name>FreeBSD-EN-17:02.yp</name>
</notice>
<notice>
<name>FreeBSD-EN-17:01.pcie</name>
</notice>
</day>
</month>
</year>
<year>
<name>2016</name>
<month>
<name>12</name>
<day>
<name>6</name>
<notice>
<name>FreeBSD-EN-16:21.localedef</name>
</notice>
<notice>
<name>FreeBSD-EN-16:20.tzdata</name>
</notice>
<notice>
<name>FreeBSD-EN-16:19.tzcode</name>
</notice>
</day>
</month>
<month>
<name>10</name>
<day>
<name>25</name>
<notice>
<name>FreeBSD-EN-16:18.loader</name>
</notice>
<notice>
<name>FreeBSD-EN-16:17.vm</name>
</notice>
</day>
</month>
<month>
<name>8</name>
<day>
<name>12</name>
<notice>
<name>FreeBSD-EN-16:16.hv_storvsc</name>
</notice>
<notice>
<name>FreeBSD-EN-16:15.vmbus</name>
</notice>
<notice>
<name>FreeBSD-EN-16:14.hv_storvsc</name>
</notice>
<notice>
<name>FreeBSD-EN-16:13.vmbus</name>
</notice>
<notice>
<name>FreeBSD-EN-16:12.hv_storvsc</name>
</notice>
<notice>
<name>FreeBSD-EN-16:11.vmbus</name>
</notice>
<notice>
<name>FreeBSD-EN-16:10.dhclient</name>
</notice>
</day>
</month>
<month>
<name>7</name>
<day>
<name>25</name>
<notice>
<name>FreeBSD-EN-16:09.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>5</name>
<day>
<name>4</name>
<notice>
<name>FreeBSD-EN-16:08.zfs</name>
</notice>
<notice>
<name>FreeBSD-EN-16:07.ipi</name>
</notice>
<notice>
<name>FreeBSD-EN-16:06.libc</name>
</notice>
</day>
</month>
<month>
<name>3</name>
<day>
<name>16</name>
<notice>
<name>FreeBSD-EN-16:05.hv_netvsc</name>
</notice>
<notice>
<name>FreeBSD-EN-16:04.hyperv</name>
</notice>
</day>
</month>
<month>
<name>1</name>
<day>
<name>14</name>
<notice>
<name>FreeBSD-EN-16:03.yplib</name>
</notice>
<notice>
<name>FreeBSD-EN-16:02.pf</name>
</notice>
<notice>
<name>FreeBSD-EN-16:01.filemon</name>
</notice>
</day>
</month>
</year>
<year>
<name>2015</name>
<month>
<name>11</name>
<day>
<name>4</name>
<notice>
<name>FreeBSD-EN-15:20.vm</name>
</notice>
<notice>
<name>FreeBSD-EN-15:19.kqueue</name>
</notice>
</day>
</month>
<month>
<name>9</name>
<day>
<name>16</name>
<notice>
<name>FreeBSD-EN-15:18.pkg</name>
</notice>
<notice>
<name>FreeBSD-EN-15:17.libc</name>
</notice>
<notice>
<name>FreeBSD-EN-15:16.pw</name>
</notice>
</day>
</month>
<month>
<name>8</name>
<day>
<name>25</name>
<notice>
<name>FreeBSD-EN-15:15.pkg</name>
</notice>
<notice>
<name>FreeBSD-EN-15:14.ixgbe</name>
</notice>
</day>
<day>
<name>18</name>
<notice>
<name>FreeBSD-EN-15:13.vidcontrol</name>
</notice>
<notice>
<name>FreeBSD-EN-15:12.netstat</name>
</notice>
<notice>
<name>FreeBSD-EN-15:11.toolchain</name>
</notice>
</day>
</month>
<month>
<name>6</name>
<day>
<name>30</name>
<notice>
<name>FreeBSD-EN-15:10.iconv</name>
</notice>
<notice>
<name>FreeBSD-EN-15:09.xlocale</name>
</notice>
</day>
<day>
<name>18</name>
<notice>
<name>FreeBSD-EN-15:08.sendmail</name>
</notice>
</day>
<day>
<name>9</name>
<notice>
<name>FreeBSD-EN-15:07.zfs</name>
</notice>
<notice>
<name>FreeBSD-EN-15:06.file</name>
</notice>
</day>
</month>
<month>
<name>5</name>
<day>
<name>13</name>
<notice>
<name>FreeBSD-EN-15:05.ufs</name>
</notice>
<notice>
<name>FreeBSD-EN-15:04.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>2</name>
<day>
<name>25</name>
<notice>
<name>FreeBSD-EN-15:03.freebsd-update</name>
</notice>
<notice>
<name>FreeBSD-EN-15:02.openssl</name>
</notice>
<notice>
<name>FreeBSD-EN-15:01.vt</name>
</notice>
</day>
</month>
</year>
<year>
<name>2014</name>
<month>
<name>12</name>
<day>
<name>23</name>
<notice>
<name>FreeBSD-EN-14:13.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>11</name>
<day>
<name>04</name>
<notice>
<name>FreeBSD-EN-14:12.zfs</name>
</notice>
</day>
</month>
<month>
<name>10</name>
<day>
<name>22</name>
<notice>
<name>FreeBSD-EN-14:11.crypt</name>
</notice>
<notice>
<name>FreeBSD-EN-14:10.tzdata</name>
</notice>
</day>
</month>
<month>
<name>7</name>
<day>
<name>8</name>
<notice>
<name>FreeBSD-EN-14:09.jail</name>
</notice>
</day>
</month>
<month>
<name>6</name>
<day>
<name>24</name>
<notice>
<name>FreeBSD-EN-14:08.heimdal</name>
</notice>
<notice>
<name>FreeBSD-EN-14:07.pmap</name>
</notice>
</day>
<day>
<name>3</name>
<notice>
<name>FreeBSD-EN-14:06.exec</name>
</notice>
</day>
</month>
<month>
<name>5</name>
<day>
<name>13</name>
<notice>
<name>FreeBSD-EN-14:05.ciss</name>
</notice>
<notice>
<name>FreeBSD-EN-14:04.kldxref</name>
</notice>
<notice>
<name>FreeBSD-EN-14:03.pkg</name>
</notice>
</day>
</month>
<month>
<name>1</name>
<day>
<name>14</name>
<notice>
<name>FreeBSD-EN-14:02.mmap</name>
</notice>
<notice>
<name>FreeBSD-EN-14:01.random</name>
</notice>
</day>
</month>
</year>
<year>
<name>2013</name>
<month>
<name>11</name>
<day>
<name>28</name>
<notice>
<name>FreeBSD-EN-13:05.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>10</name>
<day>
<name>26</name>
<notice>
<name>FreeBSD-EN-13:04.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>8</name>
<day>
<name>22</name>
<notice>
<name>FreeBSD-EN-13:03.mfi</name>
</notice>
</day>
</month>
<month>
<name>6</name>
<day>
<name>28</name>
<notice>
<name>FreeBSD-EN-13:01.fxp</name>
</notice>
<notice>
<name>FreeBSD-EN-13:02.vtnet</name>
</notice>
</day>
</month>
</year>
<year>
<name>2012</name>
<month>
<name>6</name>
<day>
<name>12</name>
<notice>
<name>FreeBSD-EN-12:02.ipv6refcount</name>
</notice>
</day>
</month>
<month>
<name>1</name>
<day>
<name>4</name>
<notice>
<name>FreeBSD-EN-12:01.freebsd-update</name>
</notice>
</day>
</month>
</year>
<year>
<name>2010</name>
<month>
<name>2</name>
<day>
<name>27</name>
<notice>
<name>FreeBSD-EN-10:02.sched_ule</name>
</notice>
</day>
</month>
<month>
<name>1</name>
<day>
<name>6</name>
<notice>
<name>FreeBSD-EN-10:01.freebsd</name>
</notice>
</day>
</month>
</year>
<year>
<name>2009</name>
<month>
<name>10</name>
<day>
<name>2</name>
<notice>
<name>FreeBSD-EN-09:05.null</name>
</notice>
</day>
</month>
<month>
<name>6</name>
<day>
<name>24</name>
<notice>
<name>FreeBSD-EN-09:04.fork</name>
</notice>
<notice>
<name>FreeBSD-EN-09:03.fxp</name>
</notice>
<notice>
<name>FreeBSD-EN-09:02.bce</name>
</notice>
</day>
</month>
<month>
<name>3</name>
<day>
<name>23</name>
<notice>
<name>FreeBSD-EN-09:01.kenv</name>
</notice>
</day>
</month>
</year>
<year>
<name>2008</name>
<month>
<name>6</name>
<day>
<name>19</name>
<notice>
<name>FreeBSD-EN-08:02.tcp</name>
</notice>
</day>
</month>
<month>
<name>4</name>
<day>
<name>17</name>
<notice>
<name>FreeBSD-EN-08:01.libpthread</name>
</notice>
</day>
</month>
</year>
<year>
<name>2007</name>
<month>
<name>3</name>
<day>
<name>15</name>
<notice>
<name>FreeBSD-EN-07:05.freebsd-update</name>
</notice>
</day>
</month>
<month>
<name>2</name>
<day>
<name>28</name>
<notice>
<name>FreeBSD-EN-07:04.zoneinfo</name>
</notice>
<notice>
<name>FreeBSD-EN-07:03.rc.d_jail</name>
</notice>
<notice>
<name>FreeBSD-EN-07:02.net</name>
</notice>
</day>
<day>
<name>14</name>
<notice>
<name>FreeBSD-EN-07:01.nfs</name>
</notice>
</day>
</month>
</year>
<year>
<name>2006</name>
<month>
<name>8</name>
<day>
<name>28</name>
<notice>
<name>FreeBSD-EN-06:02.net</name>
</notice>
</day>
</month>
<month>
<name>7</name>
<day>
<name>7</name>
<notice>
<name>FreeBSD-EN-06:01.jail</name>
</notice>
</day>
</month>
</year>
<year>
<name>2005</name>
<month>
<name>12</name>
<day>
<name>19</name>
<notice>
<name>FreeBSD-EN-05:04.nfs</name>
</notice>
</day>
</month>
<month>
<name>1</name>
<day>
<name>16</name>
<notice>
<name>FreeBSD-EN-05:03.ipi</name>
</notice>
</day>
<day>
<name>6</name>
<notice>
<name>FreeBSD-EN-05:02.sk</name>
</notice>
</day>
<day>
<name>5</name>
<notice>
<name>FreeBSD-EN-05:01.nfs</name>
</notice>
</day>
</month>
</year>
<year>
<name>2004</name>
<month>
<name>6</name>
<day>
<name>28</name>
<notice>
<name>FreeBSD-EN-04:01.twe</name>
</notice>
</day>
</month>
<month>
<name>2</name>
<day>
<name>26</name>
<release>
<name>FreeBSD 5.2.1-RELEASE</name>
</release>
</day>
</month>
</year>
</advisories>

File Metadata

Mime Type
application/octet-stream
Expires
Thu, Apr 25, 7:52 PM (2 d)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
biyOIZNStFYn
Default Alt Text
(5 MB)

Event Timeline