diff --git a/.golangci.yml b/.golangci.yml
index bee342dd75..9c78a83451 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -86,15 +86,6 @@ issues:
     - path: models/issue_comment_list.go
       linters:
         - dupl
-    # "Destroy" is misspelled in github.com/go-macaron/session/session.go:213 so it's not our responsability to fix it
-    - path: modules/session/virtual.go
-      linters:
-        - misspell
-      text: '`Destory` is a misspelling of `Destroy`'
-    - path: modules/session/memory.go
-      linters:
-        - misspell
-      text: '`Destory` is a misspelling of `Destroy`'
     - linters:
         - misspell
       text: '`Unknwon` is a misspelling of `Unknown`'
diff --git a/cmd/dump.go b/cmd/dump.go
index dd1123a254..de289270d4 100644
--- a/cmd/dump.go
+++ b/cmd/dump.go
@@ -17,8 +17,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/cae/zip"
-	"github.com/Unknwon/com"
+	"github.com/unknwon/cae/zip"
+	"github.com/unknwon/com"
 	"github.com/urfave/cli"
 )
 
diff --git a/cmd/serv.go b/cmd/serv.go
index 667c3a317a..6533b0371c 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -22,8 +22,8 @@ import (
 	"code.gitea.io/gitea/modules/private"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/dgrijalva/jwt-go"
+	"github.com/unknwon/com"
 	"github.com/urfave/cli"
 )
 
diff --git a/cmd/web.go b/cmd/web.go
index d8bcba76d1..9a5ce5d2b6 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -18,8 +18,8 @@ import (
 	"code.gitea.io/gitea/routers"
 	"code.gitea.io/gitea/routers/routes"
 
-	"github.com/Unknwon/com"
 	context2 "github.com/gorilla/context"
+	"github.com/unknwon/com"
 	"github.com/urfave/cli"
 	"golang.org/x/crypto/acme/autocert"
 	ini "gopkg.in/ini.v1"
diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go
index 4b39c8e9f2..7e6351cc63 100644
--- a/contrib/pr/checkout.go
+++ b/contrib/pr/checkout.go
@@ -27,9 +27,9 @@ import (
 	"code.gitea.io/gitea/routers"
 	"code.gitea.io/gitea/routers/routes"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
 	context2 "github.com/gorilla/context"
+	"github.com/unknwon/com"
 	"gopkg.in/src-d/go-git.v4"
 	"gopkg.in/src-d/go-git.v4/config"
 	"gopkg.in/src-d/go-git.v4/plumbing"
diff --git a/go.mod b/go.mod
index 804573e0d7..9ed3e64e7e 100644
--- a/go.mod
+++ b/go.mod
@@ -3,12 +3,18 @@ module code.gitea.io/gitea
 go 1.12
 
 require (
+	gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b
+	gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76
+	gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae
+	gitea.com/macaron/cors v0.0.0-20190821152825-7dcef4a17175
+	gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439
+	gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223
+	gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705
+	gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
 	github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34
 	github.com/RoaringBitmap/roaring v0.4.7 // indirect
-	github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca
-	github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755
-	github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966
-	github.com/Unknwon/paginater v0.0.0-20151104151617-7748a72e0141
 	github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470 // indirect
 	github.com/bgentry/speakeasy v0.1.0 // indirect
 	github.com/blevesearch/bleve v0.0.0-20190214220507-05d86ea8f6e3
@@ -16,18 +22,13 @@ require (
 	github.com/blevesearch/go-porterstemmer v0.0.0-20141230013033-23a2c8e5cf1f // indirect
 	github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc // indirect
 	github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26 // indirect
-	github.com/bradfitz/gomemcache v0.0.0-20160117192205-fb1f79c6b65a // indirect
 	github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f
-	github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c // indirect
-	github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a // indirect
 	github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe // indirect
-	github.com/couchbaselabs/go-couchbase v0.0.0-20190117181324-d904413d884d // indirect
 	github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect
 	github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
 	github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 // indirect
 	github.com/denisenkom/go-mssqldb v0.0.0-20190724012636-11b2859924c1
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
-	github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 // indirect
 	github.com/emirpasic/gods v1.12.0
 	github.com/etcd-io/bbolt v1.3.2 // indirect
 	github.com/ethantkoenig/rupture v0.0.0-20180203182544-0a76f03a811a
@@ -42,15 +43,6 @@ require (
 	github.com/gliderlabs/ssh v0.2.2
 	github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd // indirect
 	github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e // indirect
-	github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443
-	github.com/go-macaron/cache v0.0.0-20151013081102-561735312776
-	github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df
-	github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9
-	github.com/go-macaron/csrf v0.0.0-20190131233648-3751b136073c
-	github.com/go-macaron/i18n v0.0.0-20190131234336-56731837a73b
-	github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191
-	github.com/go-macaron/session v0.0.0-20190131233854-0a0a789bf193
-	github.com/go-macaron/toolbox v0.0.0-20180818072302-a77f45a7ce90
 	github.com/go-redis/redis v6.15.2+incompatible
 	github.com/go-sql-driver/mysql v1.4.1
 	github.com/go-xorm/xorm v0.7.4
@@ -69,15 +61,13 @@ require (
 	github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect
 	github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect
 	github.com/lafriks/xormstore v1.1.0
-	github.com/lib/pq v1.1.0
+	github.com/lib/pq v1.2.0
 	github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
 	github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e
-	github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de // indirect
-	github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af // indirect
 	github.com/markbates/goth v1.49.0
 	github.com/mattn/go-isatty v0.0.7
 	github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d // indirect
-	github.com/mattn/go-sqlite3 v1.10.0
+	github.com/mattn/go-sqlite3 v1.11.0
 	github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75
 	github.com/microcosm-cc/bluemonday v0.0.0-20161012083705-f77f16ffc87a
 	github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
@@ -95,13 +85,15 @@ require (
 	github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b // indirect
 	github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc // indirect
 	github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
-	github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d // indirect
-	github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff // indirect
 	github.com/steveyen/gtreap v0.0.0-20150807155958-0abe01ef9be2 // indirect
 	github.com/stretchr/testify v1.3.0
 	github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 // indirect
 	github.com/tinylib/msgp v0.0.0-20180516164116-c8cf64dff200 // indirect
 	github.com/tstranex/u2f v1.0.0
+	github.com/unknwon/cae v0.0.0-20190822084630-55a0b64484a1
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
+	github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
 	github.com/urfave/cli v1.20.0
 	github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 // indirect
 	github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
@@ -114,13 +106,10 @@ require (
 	golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa // indirect
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect
-	gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e // indirect
 	gopkg.in/editorconfig/editorconfig-core-go.v1 v1.3.0
 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
-	gopkg.in/ini.v1 v1.42.0
+	gopkg.in/ini.v1 v1.46.0
 	gopkg.in/ldap.v3 v3.0.2
-	gopkg.in/macaron.v1 v1.3.2
-	gopkg.in/redis.v2 v2.3.2 // indirect
 	gopkg.in/src-d/go-billy.v4 v4.3.2
 	gopkg.in/src-d/go-git.v4 v4.13.1
 	gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
diff --git a/go.sum b/go.sum
index 89a2362e96..55bb94c77f 100644
--- a/go.sum
+++ b/go.sum
@@ -3,6 +3,28 @@ cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
 cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
+gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b h1:vXt85uYV17KURaUlhU7v4GbCShkqRZDSfo0TkC0YCjQ=
+gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b/go.mod h1:Cxadig6POWpPYYSfg23E7jo35Yf0yvsdC1lifoKWmPo=
+gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 h1:mMsMEg90c5KXQgRWsH8D6GHXfZIW1RAe5S9VYIb12lM=
+gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76/go.mod h1:NFHb9Of+LUnU86bU20CiXXg6ZlgCJ4XytP14UsHOXFs=
+gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae h1:9C31eOCpMPbW9rDVq8M1UJ+5HZVYA38HHaKCVcRYDpI=
+gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae/go.mod h1:J5h3N+1nKTXtU1x4GxexaQKgAz8UiWecNwi/CfX7CtQ=
+gitea.com/macaron/cors v0.0.0-20190821152825-7dcef4a17175 h1:ikzdAGB6SsUGByW5wKlK+JwzfgQHX+GJnBwEfsaCTNY=
+gitea.com/macaron/cors v0.0.0-20190821152825-7dcef4a17175/go.mod h1:rtOK4J20kpMD9XcNsnO5YA843YSTe/MUMbDj/TJ/Q7A=
+gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 h1:88c34YM29a1GlWLrLBaG/GTT2htDdJz1u3n9+lmPolg=
+gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439/go.mod h1:IsQPHx73HnnqFBYiVHjg87q4XBZyGXXu77xANukvZuk=
+gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223 h1:iZWwQif/LHMjBgfY/ua8CFVa4XMDfbbs7EZ0Q1dYguU=
+gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223/go.mod h1:+qsc10s4hBsHKU/9luGGumFh4m5FFVc7uih+8/mM1NY=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok=
+gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 h1:mvkQGAlON1Z6Y8pqa/+FpYIskk54mazuECUfZK5oTg0=
+gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA=
+gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14mefLzGluqV7w2mGU3u+iZU+jCeWk=
+gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -12,14 +34,7 @@ github.com/RoaringBitmap/roaring v0.4.7 h1:eGUudvFzvF7Kxh7JjYvXfI1f7l22/2duFby7r
 github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
-github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca h1:xU8R31tsvj6TesCBog973+UgI3TXjh/LqN5clki6hcc=
-github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca/go.mod h1:IRSre9/SEhVuy972TVuJLyaPTS73+8Owhe0Y0l9NXHc=
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
 github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
-github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966 h1:Mp8GNJ/tdTZIEdLdZfykEJaL3mTyEYrSzYNcdoQKpJk=
-github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966/go.mod h1:SFtfq0zFPsENI7DpE87QM2hcYu5QQ0fRdCgP+P1Hrqo=
-github.com/Unknwon/paginater v0.0.0-20151104151617-7748a72e0141 h1:SSvHGK7iMpeypcHjI8UzNMz7zW/K8/dcgqk/82lCYP0=
-github.com/Unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:fw0McLecf/G5NFwddCRmDckU6yovtk1YsgWIoepMbYo=
 github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
 github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -46,23 +61,24 @@ github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc h1:7OfDAkuAGx7
 github.com/blevesearch/segment v0.0.0-20160105220820-db70c57796cc/go.mod h1:IInt5XRvpiGE09KOk9mmCMLjHhydIhNPKPPFLFBB7L8=
 github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26 h1:NGpwhs9FOwddM6TptNrq2ycby4s24TcppSe5uG4DA/Q=
 github.com/boombuler/barcode v0.0.0-20161226211916-fe0f26ff6d26/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
-github.com/bradfitz/gomemcache v0.0.0-20160117192205-fb1f79c6b65a h1:k5TuEkqEYCRs8+66WdOkswWOj+L/YbP5ruainvn94wg=
-github.com/bradfitz/gomemcache v0.0.0-20160117192205-fb1f79c6b65a/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA=
 github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f/go.mod h1:6QaC0vFoKWYDth94dHFNgRT2YkT5FHdQp/Yx15aAAi0=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
-github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c h1:K4FIibkr4//ziZKOKmt4RL0YImuTjLLBtwElf+F2lSQ=
-github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
-github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a h1:Y5XsLCEhtEI8qbD9RP3Qlv5FXdTDHxZM9UPUnMRgBp8=
-github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
+github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d h1:XMf4E1U+b9E3ElF0mjvfXZdflBRZz4gLp16nQ/QSHQM=
+github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b h1:bZ9rKU2/V8sY+NulSfxDOnXTWcs1rySqdF1sVepihvo=
+github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
 github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe h1:2o6Y7KMjJNsuMTF8f2H2eTKRhqH7+bQbjr+D+LnhE5M=
 github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe/go.mod h1:prYTC8EgTu3gwbqJihkud9zRXISvyulAplQ6exdCo1g=
-github.com/couchbaselabs/go-couchbase v0.0.0-20190117181324-d904413d884d h1:lsBRLJe/ET6DjCaRblGwls80dOcOzhFVNJrO6uaMrMQ=
-github.com/couchbaselabs/go-couchbase v0.0.0-20190117181324-d904413d884d/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
+github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8=
+github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
 github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
 github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8=
 github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
 github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
@@ -81,8 +97,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
-github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
 github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
 github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
 github.com/etcd-io/bbolt v1.3.2 h1:RLRQ0TKLX7DlBRXAJHvbmXL17Q3KNnTBtZ9B6Qo+/Y0=
@@ -118,24 +134,6 @@ github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e/go.mod h1:Ogl1T
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443 h1:i801KPR7j76uRMLLlGVyb0hiYbgX1FM5+ur81TJWzIw=
-github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443/go.mod h1:u+H6rwW+HQwUL+w5uaEJSpIlVZDye1o9MB4Su0JfRfM=
-github.com/go-macaron/cache v0.0.0-20151013081102-561735312776 h1:UYIHS1r0WotqB5cIa0PAiV0m6GzD9rDBcn4alp5JgCw=
-github.com/go-macaron/cache v0.0.0-20151013081102-561735312776/go.mod h1:hHAsZm/oBZVcY+S7qdQL6Vbg5VrXF6RuKGuqsszt3Ok=
-github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df h1:MdgvtI3Y1u/DHNj7xUGOqAv+KGoTikjy8xQtCm12L78=
-github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df/go.mod h1:j9TJ+0nwUOWBvNnm0bheHIPFf3cC62EQo7n7O6PbjZA=
-github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9 h1:A0QGzY6UHHEil0I2e7C21JenNNG0mmrj5d9SFWTlgr8=
-github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9/go.mod h1:utmMRnVIrXPSfA9MFcpIYKEpKawjKxf62vv62k4707E=
-github.com/go-macaron/csrf v0.0.0-20190131233648-3751b136073c h1:yCyrJuFaxKX/VoV9hHqYXhkFEMtg+Hxsiitk1z/lHfQ=
-github.com/go-macaron/csrf v0.0.0-20190131233648-3751b136073c/go.mod h1:oZGMxI7MBnicI0jJqJvH4qQzyrWKhtiKxLSJKHC+ydc=
-github.com/go-macaron/i18n v0.0.0-20190131234336-56731837a73b h1:p19t0uFyv0zkBwp4dafzU3EcpHilHNffTVDmxpn/M+w=
-github.com/go-macaron/i18n v0.0.0-20190131234336-56731837a73b/go.mod h1:MePM/dStkAh+PNzAdNSNl4SGDM2EZvZGken+KpJhM7s=
-github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI=
-github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw=
-github.com/go-macaron/session v0.0.0-20190131233854-0a0a789bf193 h1:z/nqwd+ql/r6Q3QGnwNd6B89UjPytM0be5pDQV9TuWw=
-github.com/go-macaron/session v0.0.0-20190131233854-0a0a789bf193/go.mod h1:ScEJm9Gk+ez5JJTml5WlBIqavAfuE5nF8e4Gvyz/X+A=
-github.com/go-macaron/toolbox v0.0.0-20180818072302-a77f45a7ce90 h1:3wYKrRg9IjUMfaf3H0Hh7M5Li9ge79Y7aw2yujHa2jQ=
-github.com/go-macaron/toolbox v0.0.0-20180818072302-a77f45a7ce90/go.mod h1:Ut/NmkIMGVYlEdJBzEZgWVWG5ZpYS9BLmUgXfAgi+qM=
 github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
 github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
@@ -173,8 +171,9 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
@@ -236,8 +235,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/lafriks/xormstore v1.1.0 h1:oq1+gjesu46VkxbCQFGdTPwYyUTeom7aBRziuOSDkw0=
 github.com/lafriks/xormstore v1.1.0/go.mod h1:wqtf8B94a8EtE463Ka1MaUT9ZDRl8FICA0nr65xr2wM=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.1.0 h1:/5u4a+KGJptBRqGzPvYQL9p0d/tPR4S31+Tnzj9lEO4=
-github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=
 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96/go.mod h1:mmIfjCSQlGYXmJ95jFN84AkQFnVABtKuJL8IrzwvUKQ=
 github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e h1:GSprKUrG9wNgwQgROvjPGXmcZrg4OLslOuZGB0uJjx8=
@@ -253,8 +252,9 @@ github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc
 github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d h1:m+dSK37rFf2fqppZhg15yI2IwC9BtucBiRwSDm9VL8g=
 github.com/mattn/go-oci8 v0.0.0-20190320171441-14ba190cf52d/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
-github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75 h1:Pijfgr7ZuvX7QIQiEwLdRVr3RoMG+i0SbBO1Qu+7yVk=
@@ -276,13 +276,15 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
 github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
 github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
+github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
-github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=
 github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
 github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
 github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@@ -329,15 +331,19 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc h1:
 github.com/shurcooL/sanitized_anchor_name v0.0.0-20160918041101-1dba4b3954bc/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
 github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
 github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=
 github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
 github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
+github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
 github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff h1:86HlEv0yBCry9syNuylzqznKXDK11p6D0DT596yNMys=
-github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
 github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
@@ -349,14 +355,23 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66 h1:AwmkkZT+TucFotNCL+aNJ/0KCMsRtlXN9fs8uoOMSRk=
 github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
 github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 h1:HOxvxvnntLiPn123Fk+twfUhCQdMDaqmb0cclArW0T0=
 github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
 github.com/tinylib/msgp v0.0.0-20180516164116-c8cf64dff200 h1:ZVvr38DYEyOPyelySqvF0I9I++85NnUMsWkroBDS4fs=
 github.com/tinylib/msgp v0.0.0-20180516164116-c8cf64dff200/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
 github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
 github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
+github.com/unknwon/cae v0.0.0-20190822084630-55a0b64484a1 h1:SpoCl3+Pta5/ubQyF+Fmx65obtpfkyzeaOIneCE3MTw=
+github.com/unknwon/cae v0.0.0-20190822084630-55a0b64484a1/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbRgofEOX4/3gMiraevQKJdIBhYE=
+github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ=
+github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 h1:Z79lyIznnziKADUf0J7EP8Z4ZL7YJDiPuaazlfUBSy4=
+github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
 github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621 h1:E8u341JM/N8LCnPXBV6ZFD1RKo/j+qHl1XOqSV+GstA=
@@ -375,7 +390,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
 golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -391,6 +406,7 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -413,9 +429,10 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -428,14 +445,17 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa h1:kwa/4M1dbmhZqOIqYiTtbA6JrvPwo1+jqlub2qDXX90=
 golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -446,8 +466,6 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gG
 gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
 gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ=
 gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
-gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e h1:wGA78yza6bu/mWcc4QfBuIEHEtc06xdiU0X8sY36yUU=
-gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e/go.mod h1:xsQCaysVCudhrYTfzYWe577fCe7Ceci+6qjO2Rdc0Z4=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -457,14 +475,12 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
-gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
-gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
+gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag=
+gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ldap.v3 v3.0.2 h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w=
 gopkg.in/ldap.v3 v3.0.2/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
-gopkg.in/macaron.v1 v1.3.2 h1:AvWIaPmwBUA87/OWzePkoxeaw6YJWDfBt1pDFPBnLf8=
-gopkg.in/macaron.v1 v1.3.2/go.mod h1:PrsiawTWAGZs6wFbT5hlr7SQ2Ns9h7cUVtcUu4lQOVo=
-gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=
-gopkg.in/redis.v2 v2.3.2/go.mod h1:4wl9PJ/CqzeHk3LVq1hNLHH8krm3+AXEgut4jVc++LU=
 gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
 gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
 gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=
@@ -479,7 +495,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
-gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go
index 42c271e3af..805a986ae3 100644
--- a/integrations/api_helper_for_declarative_test.go
+++ b/integrations/api_helper_for_declarative_test.go
@@ -14,6 +14,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	api "code.gitea.io/gitea/modules/structs"
+
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go
index ca3d4b2d7a..d9686a063c 100644
--- a/integrations/api_keys_test.go
+++ b/integrations/api_keys_test.go
@@ -10,10 +10,10 @@ import (
 	"net/url"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-
 	"code.gitea.io/gitea/models"
 	api "code.gitea.io/gitea/modules/structs"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestViewDeployKeysNoLogin(t *testing.T) {
diff --git a/integrations/api_user_heatmap_test.go b/integrations/api_user_heatmap_test.go
index 5c65dc1bca..5245bb0a26 100644
--- a/integrations/api_user_heatmap_test.go
+++ b/integrations/api_user_heatmap_test.go
@@ -5,11 +5,13 @@
 package integrations
 
 import (
-	"code.gitea.io/gitea/models"
 	"fmt"
-	"github.com/stretchr/testify/assert"
 	"net/http"
 	"testing"
+
+	"code.gitea.io/gitea/models"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestUserHeatmap(t *testing.T) {
diff --git a/integrations/auth_ldap_test.go b/integrations/auth_ldap_test.go
index 52fe0fd73f..9ea3184ae7 100644
--- a/integrations/auth_ldap_test.go
+++ b/integrations/auth_ldap_test.go
@@ -12,8 +12,8 @@ import (
 
 	"code.gitea.io/gitea/models"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 type ldapUser struct {
diff --git a/integrations/branches_test.go b/integrations/branches_test.go
index e74f338aa2..ea38821d21 100644
--- a/integrations/branches_test.go
+++ b/integrations/branches_test.go
@@ -10,8 +10,8 @@ import (
 	"testing"
 
 	"github.com/PuerkitoBio/goquery"
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func TestViewBranches(t *testing.T) {
diff --git a/integrations/create_no_session_test.go b/integrations/create_no_session_test.go
index 0cdf7e2310..2d21f25005 100644
--- a/integrations/create_no_session_test.go
+++ b/integrations/create_no_session_test.go
@@ -16,7 +16,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/routers/routes"
 
-	"github.com/go-macaron/session"
+	"gitea.com/macaron/session"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/integrations/git_helper_for_declarative_test.go b/integrations/git_helper_for_declarative_test.go
index 6397a5e570..628611d2d7 100644
--- a/integrations/git_helper_for_declarative_test.go
+++ b/integrations/git_helper_for_declarative_test.go
@@ -19,8 +19,9 @@ import (
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/ssh"
-	"github.com/Unknwon/com"
+
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/com"
 )
 
 func withKeyFile(t *testing.T, keyname string, callback func(string)) {
diff --git a/integrations/integration_test.go b/integrations/integration_test.go
index 6597586e53..eaec2d509e 100644
--- a/integrations/integration_test.go
+++ b/integrations/integration_test.go
@@ -27,10 +27,10 @@ import (
 	"code.gitea.io/gitea/routers"
 	"code.gitea.io/gitea/routers/routes"
 
+	"gitea.com/macaron/macaron"
 	"github.com/PuerkitoBio/goquery"
-	"github.com/Unknwon/com"
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/macaron.v1"
+	"github.com/unknwon/com"
 	"gopkg.in/testfixtures.v2"
 )
 
diff --git a/integrations/lfs_getobject_test.go b/integrations/lfs_getobject_test.go
index 567cf13b45..42b64612fd 100644
--- a/integrations/lfs_getobject_test.go
+++ b/integrations/lfs_getobject_test.go
@@ -18,9 +18,9 @@ import (
 	"code.gitea.io/gitea/modules/gzip"
 	"code.gitea.io/gitea/modules/lfs"
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/stretchr/testify/assert"
 
 	gzipp "github.com/klauspost/compress/gzip"
+	"github.com/stretchr/testify/assert"
 )
 
 func GenerateLFSOid(content io.Reader) (string, error) {
diff --git a/integrations/pull_merge_test.go b/integrations/pull_merge_test.go
index 2f4e48f293..27f9fc6bb9 100644
--- a/integrations/pull_merge_test.go
+++ b/integrations/pull_merge_test.go
@@ -15,8 +15,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/test"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func testPullMerge(t *testing.T, session *TestSession, user, repo, pullnum string, mergeStyle models.MergeStyle) *httptest.ResponseRecorder {
diff --git a/integrations/release_test.go b/integrations/release_test.go
index 492d224a53..135607153e 100644
--- a/integrations/release_test.go
+++ b/integrations/release_test.go
@@ -11,8 +11,8 @@ import (
 
 	"code.gitea.io/gitea/modules/test"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title string, preRelease, draft bool) {
diff --git a/integrations/repo_branch_test.go b/integrations/repo_branch_test.go
index a5447cfb66..dbde276993 100644
--- a/integrations/repo_branch_test.go
+++ b/integrations/repo_branch_test.go
@@ -13,8 +13,8 @@ import (
 
 	"code.gitea.io/gitea/modules/test"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func testCreateBranch(t testing.TB, session *TestSession, user, repo, oldRefSubURL, newBranchName string, expectedStatus int) string {
diff --git a/integrations/signin_test.go b/integrations/signin_test.go
index 9eab5b5f03..4a2bb8857a 100644
--- a/integrations/signin_test.go
+++ b/integrations/signin_test.go
@@ -11,8 +11,8 @@ import (
 
 	"code.gitea.io/gitea/models"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func testLoginFailed(t *testing.T, username, password, message string) {
diff --git a/integrations/ssh_key_test.go b/integrations/ssh_key_test.go
index e8fbf17c55..944d2f6bed 100644
--- a/integrations/ssh_key_test.go
+++ b/integrations/ssh_key_test.go
@@ -16,6 +16,7 @@ import (
 
 	"code.gitea.io/gitea/modules/git"
 	api "code.gitea.io/gitea/modules/structs"
+
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/integrations/user_test.go b/integrations/user_test.go
index fd25f1c570..6d67927d16 100644
--- a/integrations/user_test.go
+++ b/integrations/user_test.go
@@ -11,8 +11,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/test"
 
-	"github.com/Unknwon/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 func TestViewUser(t *testing.T) {
diff --git a/models/action.go b/models/action.go
index 9bf2905c99..d3b53f6738 100644
--- a/models/action.go
+++ b/models/action.go
@@ -23,7 +23,7 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"xorm.io/builder"
 )
 
diff --git a/models/admin.go b/models/admin.go
index 4585657e9f..271c5307a0 100644
--- a/models/admin.go
+++ b/models/admin.go
@@ -11,7 +11,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 //NoticeType describes the notice type
diff --git a/models/branches.go b/models/branches.go
index 62b1c208f6..2a99d98955 100644
--- a/models/branches.go
+++ b/models/branches.go
@@ -14,7 +14,7 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/models/git_diff.go b/models/git_diff.go
index 62bb35be07..b822685409 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -25,8 +25,9 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/Unknwon/com"
+
 	"github.com/sergi/go-diff/diffmatchpatch"
+	"github.com/unknwon/com"
 	stdcharset "golang.org/x/net/html/charset"
 	"golang.org/x/text/transform"
 )
diff --git a/models/helper_directory.go b/models/helper_directory.go
index 417402b41c..813f0577bc 100644
--- a/models/helper_directory.go
+++ b/models/helper_directory.go
@@ -14,7 +14,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // LocalCopyPath returns the local repository temporary copy path.
diff --git a/models/issue.go b/models/issue.go
index ddfa2a2e14..fc74c73162 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -19,8 +19,8 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"xorm.io/builder"
 )
 
diff --git a/models/issue_assignees.go b/models/issue_assignees.go
index d88a4218cf..1f504a9950 100644
--- a/models/issue_assignees.go
+++ b/models/issue_assignees.go
@@ -8,8 +8,8 @@ import (
 	"fmt"
 
 	"code.gitea.io/gitea/modules/log"
-
 	api "code.gitea.io/gitea/modules/structs"
+
 	"github.com/go-xorm/xorm"
 )
 
diff --git a/models/issue_comment.go b/models/issue_comment.go
index 7eb13ed7af..ad1a59e9d3 100644
--- a/models/issue_comment.go
+++ b/models/issue_comment.go
@@ -19,8 +19,8 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"xorm.io/builder"
 )
 
diff --git a/models/issue_label.go b/models/issue_label.go
index 7af6060f87..686897f63c 100644
--- a/models/issue_label.go
+++ b/models/issue_label.go
@@ -11,9 +11,9 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/go-xorm/xorm"
-
 	api "code.gitea.io/gitea/modules/structs"
+
+	"github.com/go-xorm/xorm"
 )
 
 var labelColorPattern = regexp.MustCompile("#([a-fA-F0-9]{6})")
diff --git a/models/issue_mail.go b/models/issue_mail.go
index 01a12b16d2..829c4cea78 100644
--- a/models/issue_mail.go
+++ b/models/issue_mail.go
@@ -8,11 +8,11 @@ package models
 import (
 	"fmt"
 
-	"github.com/Unknwon/com"
-
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/setting"
+
+	"github.com/unknwon/com"
 )
 
 func (issue *Issue) mailSubject() string {
diff --git a/models/lfs_lock.go b/models/lfs_lock.go
index c38686796b..7ea1dc8660 100644
--- a/models/lfs_lock.go
+++ b/models/lfs_lock.go
@@ -13,6 +13,7 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 	api "code.gitea.io/gitea/modules/structs"
+
 	"github.com/go-xorm/xorm"
 )
 
diff --git a/models/login_source.go b/models/login_source.go
index f52679dab6..9381ed034f 100644
--- a/models/login_source.go
+++ b/models/login_source.go
@@ -21,8 +21,8 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"xorm.io/core"
 )
 
diff --git a/models/mail.go b/models/mail.go
index 31f22519cf..2c72818cec 100644
--- a/models/mail.go
+++ b/models/mail.go
@@ -17,6 +17,7 @@ import (
 	"code.gitea.io/gitea/modules/markup/markdown"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
+
 	"gopkg.in/gomail.v2"
 )
 
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 9ffcfb4df2..fc086bfd46 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -17,14 +17,14 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
-	"github.com/go-xorm/xorm"
-	gouuid "github.com/satori/go.uuid"
-	ini "gopkg.in/ini.v1"
-
 	"code.gitea.io/gitea/modules/generate"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
+
+	"github.com/go-xorm/xorm"
+	gouuid "github.com/satori/go.uuid"
+	"github.com/unknwon/com"
+	ini "gopkg.in/ini.v1"
 )
 
 const minDBVersion = 4
diff --git a/models/migrations/v13.go b/models/migrations/v13.go
index f81271f981..8b6b38cadf 100644
--- a/models/migrations/v13.go
+++ b/models/migrations/v13.go
@@ -9,8 +9,8 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error {
diff --git a/models/migrations/v19.go b/models/migrations/v19.go
index 44338eb8ba..9793f405ad 100644
--- a/models/migrations/v19.go
+++ b/models/migrations/v19.go
@@ -13,8 +13,8 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 func generateAndMigrateGitHooks(x *xorm.Engine) (err error) {
diff --git a/models/migrations/v21.go b/models/migrations/v21.go
index 890f4de227..65cae2ac03 100644
--- a/models/migrations/v21.go
+++ b/models/migrations/v21.go
@@ -11,8 +11,8 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/models/migrations/v22.go b/models/migrations/v22.go
index 7774f6fd9a..f991ae25fa 100644
--- a/models/migrations/v22.go
+++ b/models/migrations/v22.go
@@ -13,8 +13,8 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 func generateAndMigrateWikiGitHooks(x *xorm.Engine) (err error) {
diff --git a/models/migrations/v26.go b/models/migrations/v26.go
index 636d1f76ca..3d88c62923 100644
--- a/models/migrations/v26.go
+++ b/models/migrations/v26.go
@@ -16,8 +16,8 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 func generateAndMigrateGitHookChains(x *xorm.Engine) (err error) {
diff --git a/models/migrations/v55.go b/models/migrations/v55.go
index 32f4e8ac04..c20c51616e 100644
--- a/models/migrations/v55.go
+++ b/models/migrations/v55.go
@@ -8,6 +8,7 @@ import (
 	"fmt"
 
 	"code.gitea.io/gitea/models"
+
 	"github.com/go-xorm/xorm"
 )
 
diff --git a/models/oauth2_application.go b/models/oauth2_application.go
index 04c3d7721c..46355a0b3f 100644
--- a/models/oauth2_application.go
+++ b/models/oauth2_application.go
@@ -15,10 +15,10 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/dgrijalva/jwt-go"
 	"github.com/go-xorm/xorm"
 	uuid "github.com/satori/go.uuid"
+	"github.com/unknwon/com"
 	"golang.org/x/crypto/bcrypt"
 )
 
diff --git a/models/org.go b/models/org.go
index 7032f6698e..909657cffd 100644
--- a/models/org.go
+++ b/models/org.go
@@ -14,8 +14,8 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/structs"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"xorm.io/builder"
 )
 
diff --git a/models/pull.go b/models/pull.go
index b1ceca472c..ecb5c1345e 100644
--- a/models/pull.go
+++ b/models/pull.go
@@ -25,8 +25,8 @@ import (
 	"code.gitea.io/gitea/modules/sync"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 )
 
 var pullRequestQueue = sync.NewUniqueQueue(setting.Repository.PullRequestQueueLength)
diff --git a/models/repo.go b/models/repo.go
index 50e1ad0bb7..a70350576e 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -36,8 +36,8 @@ import (
 	"code.gitea.io/gitea/modules/sync"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	ini "gopkg.in/ini.v1"
 	"xorm.io/builder"
 )
diff --git a/models/repo_mirror.go b/models/repo_mirror.go
index 02c87daf69..9801c05ae4 100644
--- a/models/repo_mirror.go
+++ b/models/repo_mirror.go
@@ -20,9 +20,9 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
 	"github.com/mcuadros/go-version"
+	"github.com/unknwon/com"
 )
 
 // MirrorQueue holds an UniqueQueue object of the mirror
diff --git a/models/repo_redirect.go b/models/repo_redirect.go
index 8847a0889c..2714121a6c 100644
--- a/models/repo_redirect.go
+++ b/models/repo_redirect.go
@@ -5,8 +5,9 @@
 package models
 
 import (
-	"code.gitea.io/gitea/modules/log"
 	"strings"
+
+	"code.gitea.io/gitea/modules/log"
 )
 
 // RepoRedirect represents that a repo name should be redirected to another
diff --git a/models/repo_test.go b/models/repo_test.go
index 8c3f14695d..bf10de8d99 100644
--- a/models/repo_test.go
+++ b/models/repo_test.go
@@ -14,8 +14,8 @@ import (
 
 	"code.gitea.io/gitea/modules/markup"
 
-	"github.com/Unknwon/com"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/com"
 )
 
 func TestRepo(t *testing.T) {
diff --git a/models/repo_unit.go b/models/repo_unit.go
index b2c88d3193..2fc1c40fa2 100644
--- a/models/repo_unit.go
+++ b/models/repo_unit.go
@@ -9,8 +9,8 @@ import (
 
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"xorm.io/core"
 )
 
diff --git a/models/ssh_key.go b/models/ssh_key.go
index 874f6b19f7..315b32e8d5 100644
--- a/models/ssh_key.go
+++ b/models/ssh_key.go
@@ -28,8 +28,8 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"golang.org/x/crypto/ssh"
 	"xorm.io/builder"
 )
diff --git a/models/unit_tests.go b/models/unit_tests.go
index 9dadf2e128..80dc4feb96 100644
--- a/models/unit_tests.go
+++ b/models/unit_tests.go
@@ -17,9 +17,9 @@ import (
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/com"
 	"gopkg.in/testfixtures.v2"
 	"xorm.io/core"
 )
diff --git a/models/upload.go b/models/upload.go
index 65ce1223c8..65b3220c12 100644
--- a/models/upload.go
+++ b/models/upload.go
@@ -12,10 +12,10 @@ import (
 	"os"
 	"path"
 
-	"github.com/Unknwon/com"
-	gouuid "github.com/satori/go.uuid"
-
 	"code.gitea.io/gitea/modules/setting"
+
+	gouuid "github.com/satori/go.uuid"
+	"github.com/unknwon/com"
 )
 
 //  ____ ___        .__                    .___ ___________.___.__
diff --git a/models/user.go b/models/user.go
index 3c0c581a1d..037ae0397b 100644
--- a/models/user.go
+++ b/models/user.go
@@ -32,8 +32,8 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
 	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
 	"golang.org/x/crypto/argon2"
 	"golang.org/x/crypto/bcrypt"
 	"golang.org/x/crypto/pbkdf2"
diff --git a/models/webhook.go b/models/webhook.go
index 1d41f2a969..4eda08fdb5 100644
--- a/models/webhook.go
+++ b/models/webhook.go
@@ -25,8 +25,8 @@ import (
 	"code.gitea.io/gitea/modules/sync"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/Unknwon/com"
 	gouuid "github.com/satori/go.uuid"
+	"github.com/unknwon/com"
 )
 
 // HookQueue is a global queue of web hooks
diff --git a/models/wiki.go b/models/wiki.go
index d47f58f5a3..0460e0f079 100644
--- a/models/wiki.go
+++ b/models/wiki.go
@@ -15,7 +15,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/sync"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/modules/auth/admin.go b/modules/auth/admin.go
index 8f8dd8f22a..6e225891dd 100644
--- a/modules/auth/admin.go
+++ b/modules/auth/admin.go
@@ -5,9 +5,8 @@
 package auth
 
 import (
-	"gopkg.in/macaron.v1"
-
-	"github.com/go-macaron/binding"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // AdminCreateUserForm form for admin to create user
diff --git a/modules/auth/auth.go b/modules/auth/auth.go
index 1013628073..74a596e8ef 100644
--- a/modules/auth/auth.go
+++ b/modules/auth/auth.go
@@ -10,18 +10,18 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/binding"
-	"github.com/go-macaron/session"
-	gouuid "github.com/satori/go.uuid"
-	"gopkg.in/macaron.v1"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/validation"
+
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/session"
+	gouuid "github.com/satori/go.uuid"
+	"github.com/unknwon/com"
 )
 
 // IsAPIPath if URL is an api path
diff --git a/modules/auth/auth_form.go b/modules/auth/auth_form.go
index e44ef58f8e..358472a385 100644
--- a/modules/auth/auth_form.go
+++ b/modules/auth/auth_form.go
@@ -5,8 +5,8 @@
 package auth
 
 import (
-	"github.com/go-macaron/binding"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // AuthenticationForm form for authentication
diff --git a/modules/auth/openid/openid.go b/modules/auth/openid/openid.go
index ffe0aba2b6..40f38c2d2e 100644
--- a/modules/auth/openid/openid.go
+++ b/modules/auth/openid/openid.go
@@ -5,8 +5,9 @@
 package openid
 
 import (
-	"github.com/yohcop/openid-go"
 	"time"
+
+	"github.com/yohcop/openid-go"
 )
 
 // For the demo, we use in-memory infinite storage nonce and discovery
diff --git a/modules/auth/org.go b/modules/auth/org.go
index d51ab75d3a..367468e587 100644
--- a/modules/auth/org.go
+++ b/modules/auth/org.go
@@ -9,8 +9,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/structs"
 
-	"github.com/go-macaron/binding"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // ________                            .__                __  .__
diff --git a/modules/auth/repo_branch_form.go b/modules/auth/repo_branch_form.go
index 57e63741aa..a4baabe354 100644
--- a/modules/auth/repo_branch_form.go
+++ b/modules/auth/repo_branch_form.go
@@ -5,8 +5,8 @@
 package auth
 
 import (
-	"github.com/go-macaron/binding"
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // NewBranchForm form for creating a new branch
diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go
index cdac210dde..bb9be70e87 100644
--- a/modules/auth/repo_form.go
+++ b/modules/auth/repo_form.go
@@ -13,9 +13,9 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/routers/utils"
 
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/binding"
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 // _______________________________________    _________.______________________ _______________.___.
diff --git a/modules/auth/repo_form_test.go b/modules/auth/repo_form_test.go
index a3369b006e..6bad5d50ba 100644
--- a/modules/auth/repo_form_test.go
+++ b/modules/auth/repo_form_test.go
@@ -8,6 +8,7 @@ import (
 	"testing"
 
 	"code.gitea.io/gitea/modules/setting"
+
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index c117d038be..8ceb961d24 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -11,8 +11,8 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/go-macaron/binding"
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // InstallForm form for installation page
diff --git a/modules/auth/user_form_auth_openid.go b/modules/auth/user_form_auth_openid.go
index 275850d09a..b355825483 100644
--- a/modules/auth/user_form_auth_openid.go
+++ b/modules/auth/user_form_auth_openid.go
@@ -5,8 +5,8 @@
 package auth
 
 import (
-	"github.com/go-macaron/binding"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 )
 
 // SignInOpenIDForm form for signing in with OpenID
diff --git a/modules/base/tool.go b/modules/base/tool.go
index 43678979a5..60d96d57e3 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -29,7 +29,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // EncodeMD5 encodes string to md5 hex value.
diff --git a/modules/cache/cache.go b/modules/cache/cache.go
index a7412f109f..ceb5772fcf 100644
--- a/modules/cache/cache.go
+++ b/modules/cache/cache.go
@@ -10,7 +10,7 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	mc "github.com/go-macaron/cache"
+	mc "gitea.com/macaron/cache"
 )
 
 var conn mc.Cache
diff --git a/modules/context/api.go b/modules/context/api.go
index 0b2f81fd64..024ae487f1 100644
--- a/modules/context/api.go
+++ b/modules/context/api.go
@@ -10,14 +10,13 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/go-macaron/csrf"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/csrf"
+	"gitea.com/macaron/macaron"
 )
 
 // APIContext is a specific macaron context for API service
diff --git a/modules/context/auth.go b/modules/context/auth.go
index 772403bda9..be63720035 100644
--- a/modules/context/auth.go
+++ b/modules/context/auth.go
@@ -10,8 +10,9 @@ import (
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/go-macaron/csrf"
-	macaron "gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/csrf"
+	"gitea.com/macaron/macaron"
 )
 
 // ToggleOptions contains required or check options
diff --git a/modules/context/context.go b/modules/context/context.go
index b7c77ac460..e89b2e25c4 100644
--- a/modules/context/context.go
+++ b/modules/context/context.go
@@ -20,12 +20,13 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/cache"
-	"github.com/go-macaron/csrf"
-	"github.com/go-macaron/i18n"
-	"github.com/go-macaron/session"
-	"gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/cache"
+	"gitea.com/macaron/csrf"
+	"gitea.com/macaron/i18n"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/session"
+	"github.com/unknwon/com"
 )
 
 // Context represents context of a request.
diff --git a/modules/context/org.go b/modules/context/org.go
index 12d5dbfbf9..4867474334 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -9,7 +9,8 @@ import (
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/setting"
-	macaron "gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/macaron"
 )
 
 // Organization contains organization context
diff --git a/modules/context/pagination.go b/modules/context/pagination.go
index 390b4dbdd7..9a6ad0b5c4 100644
--- a/modules/context/pagination.go
+++ b/modules/context/pagination.go
@@ -10,7 +10,7 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/Unknwon/paginater"
+	"github.com/unknwon/paginater"
 )
 
 // Pagination provides a pagination via Paginater and additional configurations for the link params used in rendering
diff --git a/modules/context/panic.go b/modules/context/panic.go
index c251337164..e5ef233629 100644
--- a/modules/context/panic.go
+++ b/modules/context/panic.go
@@ -20,7 +20,8 @@ import (
 	"fmt"
 
 	"code.gitea.io/gitea/modules/log"
-	macaron "gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/macaron"
 )
 
 // Recovery returns a middleware that recovers from any panics and writes a 500 and a log if so.
diff --git a/modules/context/permission.go b/modules/context/permission.go
index 6ac935686b..f2adf896f9 100644
--- a/modules/context/permission.go
+++ b/modules/context/permission.go
@@ -8,7 +8,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/log"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // RequireRepoAdmin returns a macaron middleware for requiring repository admin permission
diff --git a/modules/context/repo.go b/modules/context/repo.go
index 096f3c0a5d..1499145f74 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -18,9 +18,9 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 	"gopkg.in/editorconfig/editorconfig-core-go.v1"
-	"gopkg.in/macaron.v1"
 )
 
 // PullRequest contains informations to make a pull request
diff --git a/modules/git/hook.go b/modules/git/hook.go
index 18c00b5838..e966591668 100644
--- a/modules/git/hook.go
+++ b/modules/git/hook.go
@@ -12,7 +12,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // hookNames is a list of Git server hooks' name that are supported.
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 28e54a1bbc..1a9112132f 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -17,7 +17,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"gopkg.in/src-d/go-billy.v4/osfs"
 	gogit "gopkg.in/src-d/go-git.v4"
 	"gopkg.in/src-d/go-git.v4/plumbing/cache"
diff --git a/modules/git/repo_commitgraph.go b/modules/git/repo_commitgraph.go
index 52263852dc..f3a45d8e6e 100644
--- a/modules/git/repo_commitgraph.go
+++ b/modules/git/repo_commitgraph.go
@@ -10,6 +10,7 @@ import (
 	"path"
 
 	gitealog "code.gitea.io/gitea/modules/log"
+
 	"gopkg.in/src-d/go-git.v4/plumbing/format/commitgraph"
 	cgobject "gopkg.in/src-d/go-git.v4/plumbing/object/commitgraph"
 )
diff --git a/modules/gzip/gzip.go b/modules/gzip/gzip.go
index 0d10071830..d139b09e1c 100644
--- a/modules/gzip/gzip.go
+++ b/modules/gzip/gzip.go
@@ -15,8 +15,8 @@ import (
 	"strings"
 	"sync"
 
+	"gitea.com/macaron/macaron"
 	"github.com/klauspost/compress/gzip"
-	"gopkg.in/macaron.v1"
 )
 
 const (
diff --git a/modules/gzip/gzip_test.go b/modules/gzip/gzip_test.go
index d131e240af..5fc56cc7f0 100644
--- a/modules/gzip/gzip_test.go
+++ b/modules/gzip/gzip_test.go
@@ -12,9 +12,9 @@ import (
 	"net/http/httptest"
 	"testing"
 
+	"gitea.com/macaron/macaron"
 	gzipp "github.com/klauspost/compress/gzip"
 	"github.com/stretchr/testify/assert"
-	macaron "gopkg.in/macaron.v1"
 )
 
 func setup(sampleResponse []byte) (*macaron.Macaron, *[]byte) {
diff --git a/modules/indexer/issues/queue_disk.go b/modules/indexer/issues/queue_disk.go
index e5ac2a7981..b127f8d269 100644
--- a/modules/indexer/issues/queue_disk.go
+++ b/modules/indexer/issues/queue_disk.go
@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"code.gitea.io/gitea/modules/log"
+
 	"github.com/lunny/levelqueue"
 )
 
diff --git a/modules/indexer/issues/queue_redis.go b/modules/indexer/issues/queue_redis.go
index aeccd7920c..0344d3c87a 100644
--- a/modules/indexer/issues/queue_redis.go
+++ b/modules/indexer/issues/queue_redis.go
@@ -12,6 +12,7 @@ import (
 	"time"
 
 	"code.gitea.io/gitea/modules/log"
+
 	"github.com/go-redis/redis"
 )
 
diff --git a/modules/lfs/server.go b/modules/lfs/server.go
index bf5355acfc..652610acf4 100644
--- a/modules/lfs/server.go
+++ b/modules/lfs/server.go
@@ -17,8 +17,8 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
+	"gitea.com/macaron/macaron"
 	"github.com/dgrijalva/jwt-go"
-	"gopkg.in/macaron.v1"
 )
 
 const (
diff --git a/modules/markup/html.go b/modules/markup/html.go
index 28533cdd3f..1ffb7da24c 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -18,7 +18,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"golang.org/x/net/html"
 	"golang.org/x/net/html/atom"
 	"mvdan.cc/xurls/v2"
diff --git a/modules/options/dynamic.go b/modules/options/dynamic.go
index c56d098a2e..7de7cfbd61 100644
--- a/modules/options/dynamic.go
+++ b/modules/options/dynamic.go
@@ -12,7 +12,8 @@ import (
 	"path"
 
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/Unknwon/com"
+
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/modules/options/static.go b/modules/options/static.go
index 629901f740..1cf841ebb1 100644
--- a/modules/options/static.go
+++ b/modules/options/static.go
@@ -12,7 +12,8 @@ import (
 	"path"
 
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/Unknwon/com"
+
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/modules/public/dynamic.go b/modules/public/dynamic.go
index 282db44970..07f83e1f6a 100644
--- a/modules/public/dynamic.go
+++ b/modules/public/dynamic.go
@@ -7,7 +7,7 @@
 package public
 
 import (
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // Static implements the macaron static handler for serving assets.
diff --git a/modules/public/public.go b/modules/public/public.go
index df7027572b..c16c8e0009 100644
--- a/modules/public/public.go
+++ b/modules/public/public.go
@@ -14,7 +14,8 @@ import (
 	"time"
 
 	"code.gitea.io/gitea/modules/setting"
-	"gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/macaron"
 )
 
 //go:generate go run -mod=vendor main.go
diff --git a/modules/public/static.go b/modules/public/static.go
index 054b9a806c..3e8865c3f9 100644
--- a/modules/public/static.go
+++ b/modules/public/static.go
@@ -7,7 +7,7 @@
 package public
 
 import (
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // Static implements the macaron static handler for serving assets.
diff --git a/modules/repofiles/file_test.go b/modules/repofiles/file_test.go
index 00feb93fff..7c45139dd9 100644
--- a/modules/repofiles/file_test.go
+++ b/modules/repofiles/file_test.go
@@ -5,11 +5,11 @@
 package repofiles
 
 import (
-	"code.gitea.io/gitea/modules/setting"
 	"testing"
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/setting"
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/test"
 
diff --git a/modules/session/memory.go b/modules/session/memory.go
index 9c493bfe15..4f72feac9b 100644
--- a/modules/session/memory.go
+++ b/modules/session/memory.go
@@ -22,7 +22,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/go-macaron/session"
+	"gitea.com/macaron/session"
 )
 
 // MemStore represents a in-memory session store implementation.
@@ -148,8 +148,8 @@ func (p *MemProvider) Exist(sid string) bool {
 	return ok
 }
 
-// Destory deletes a session by session ID.
-func (p *MemProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *MemProvider) Destroy(sid string) error {
 	p.lock.Lock()
 	defer p.lock.Unlock()
 
@@ -174,7 +174,7 @@ func (p *MemProvider) Regenerate(oldsid, sid string) (session.RawStore, error) {
 		return nil, err
 	}
 
-	if err = p.Destory(oldsid); err != nil {
+	if err = p.Destroy(oldsid); err != nil {
 		return nil, err
 	}
 
diff --git a/modules/session/virtual.go b/modules/session/virtual.go
index b8ddd2f71b..027960a289 100644
--- a/modules/session/virtual.go
+++ b/modules/session/virtual.go
@@ -10,13 +10,13 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/go-macaron/session"
-	couchbase "github.com/go-macaron/session/couchbase"
-	memcache "github.com/go-macaron/session/memcache"
-	mysql "github.com/go-macaron/session/mysql"
-	nodb "github.com/go-macaron/session/nodb"
-	postgres "github.com/go-macaron/session/postgres"
-	redis "github.com/go-macaron/session/redis"
+	"gitea.com/macaron/session"
+	couchbase "gitea.com/macaron/session/couchbase"
+	memcache "gitea.com/macaron/session/memcache"
+	mysql "gitea.com/macaron/session/mysql"
+	nodb "gitea.com/macaron/session/nodb"
+	postgres "gitea.com/macaron/session/postgres"
+	redis "gitea.com/macaron/session/redis"
 )
 
 // VirtualSessionProvider represents a shadowed session provider implementation.
@@ -75,11 +75,11 @@ func (o *VirtualSessionProvider) Exist(sid string) bool {
 	return true
 }
 
-// Destory deletes a session by session ID.
-func (o *VirtualSessionProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (o *VirtualSessionProvider) Destroy(sid string) error {
 	o.lock.Lock()
 	defer o.lock.Unlock()
-	return o.provider.Destory(sid)
+	return o.provider.Destroy(sid)
 }
 
 // Regenerate regenerates a session store from old session ID to new one.
diff --git a/modules/setting/cache.go b/modules/setting/cache.go
index 1f79404e00..7be24b865f 100644
--- a/modules/setting/cache.go
+++ b/modules/setting/cache.go
@@ -10,8 +10,8 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 
-	_ "github.com/go-macaron/cache/memcache" // memcache plugin for cache
-	_ "github.com/go-macaron/cache/redis"
+	_ "gitea.com/macaron/cache/memcache" // memcache plugin for cache
+	_ "gitea.com/macaron/cache/redis"
 )
 
 // Cache represents cache settings
diff --git a/modules/setting/cors.go b/modules/setting/cors.go
index c1c3bfb813..04f3120536 100644
--- a/modules/setting/cors.go
+++ b/modules/setting/cors.go
@@ -9,7 +9,7 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 
-	"github.com/go-macaron/cors"
+	"gitea.com/macaron/cors"
 )
 
 var (
@@ -28,7 +28,7 @@ func newCORSService() {
 
 	CORSConfig = cors.Options{
 		Scheme:           sec.Key("SCHEME").String(),
-		AllowDomain:      sec.Key("ALLOW_DOMAIN").String(),
+		AllowDomain:      sec.Key("ALLOW_DOMAIN").Strings(","),
 		AllowSubdomain:   sec.Key("ALLOW_SUBDOMAIN").MustBool(),
 		Methods:          sec.Key("METHODS").Strings(","),
 		MaxAgeSeconds:    int(maxAge.Seconds()),
diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go
index 3101ed5452..c692e0fe14 100644
--- a/modules/setting/mailer.go
+++ b/modules/setting/mailer.go
@@ -8,6 +8,7 @@ import (
 	"net/mail"
 
 	"code.gitea.io/gitea/modules/log"
+
 	shellquote "github.com/kballard/go-shellquote"
 )
 
diff --git a/modules/setting/repository.go b/modules/setting/repository.go
index 98e3d6e826..728741576d 100644
--- a/modules/setting/repository.go
+++ b/modules/setting/repository.go
@@ -10,7 +10,8 @@ import (
 	"strings"
 
 	"code.gitea.io/gitea/modules/log"
-	"github.com/Unknwon/com"
+
+	"github.com/unknwon/com"
 )
 
 // enumerates all the policy repository creating
diff --git a/modules/setting/session.go b/modules/setting/session.go
index bed3a9d8c0..6e5a28bb75 100644
--- a/modules/setting/session.go
+++ b/modules/setting/session.go
@@ -12,7 +12,7 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 
-	"github.com/go-macaron/session"
+	"gitea.com/macaron/session"
 )
 
 var (
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 97db7eaf9e..123aa8f103 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -27,10 +27,10 @@ import (
 	_ "code.gitea.io/gitea/modules/minwinsvc" // import minwinsvc for windows services
 	"code.gitea.io/gitea/modules/user"
 
-	"github.com/Unknwon/cae/zip"
-	"github.com/Unknwon/com"
 	shellquote "github.com/kballard/go-shellquote"
 	version "github.com/mcuadros/go-version"
+	"github.com/unknwon/cae/zip"
+	"github.com/unknwon/com"
 	ini "gopkg.in/ini.v1"
 	"strk.kbt.io/projects/go/libravatar"
 )
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go
index 1818f33306..7ff0c32326 100644
--- a/modules/ssh/ssh.go
+++ b/modules/ssh/ssh.go
@@ -22,8 +22,8 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
 	"github.com/gliderlabs/ssh"
+	"github.com/unknwon/com"
 	gossh "golang.org/x/crypto/ssh"
 )
 
diff --git a/modules/sync/unique_queue.go b/modules/sync/unique_queue.go
index ca7c21ac24..de694d8560 100644
--- a/modules/sync/unique_queue.go
+++ b/modules/sync/unique_queue.go
@@ -5,7 +5,7 @@
 package sync
 
 import (
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // UniqueQueue is a queue which guarantees only one instance of same
diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go
index d7c04ccb09..6217f1c3b0 100644
--- a/modules/templates/dynamic.go
+++ b/modules/templates/dynamic.go
@@ -14,8 +14,9 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/modules/templates/static.go b/modules/templates/static.go
index 3aabe17e4f..f7e53ce887 100644
--- a/modules/templates/static.go
+++ b/modules/templates/static.go
@@ -17,8 +17,9 @@ import (
 
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
+
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go
index d5a800d360..92df1c5762 100644
--- a/modules/test/context_tests.go
+++ b/modules/test/context_tests.go
@@ -14,9 +14,9 @@ import (
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/git"
 
-	"github.com/go-macaron/session"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/session"
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/macaron.v1"
 )
 
 // MockContext mock context for unit tests
diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go
index 9ba111e54e..e6c29c19ff 100644
--- a/modules/timeutil/since.go
+++ b/modules/timeutil/since.go
@@ -12,7 +12,7 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/i18n"
+	"github.com/unknwon/i18n"
 )
 
 // Seconds-based time units
diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go
index c016e4ac65..65d481a6aa 100644
--- a/modules/timeutil/since_test.go
+++ b/modules/timeutil/since_test.go
@@ -11,9 +11,9 @@ import (
 
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/i18n"
-	macaroni18n "github.com/go-macaron/i18n"
+	macaroni18n "gitea.com/macaron/i18n"
 	"github.com/stretchr/testify/assert"
+	"github.com/unknwon/i18n"
 )
 
 var BaseDate time.Time
diff --git a/modules/validation/binding.go b/modules/validation/binding.go
index 03b6f6276d..fc420e62fb 100644
--- a/modules/validation/binding.go
+++ b/modules/validation/binding.go
@@ -9,7 +9,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/go-macaron/binding"
+	"gitea.com/macaron/binding"
 )
 
 const (
diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go
index de964a5488..5ac88c9317 100644
--- a/modules/validation/binding_test.go
+++ b/modules/validation/binding_test.go
@@ -9,9 +9,9 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	"github.com/go-macaron/binding"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/macaron"
 	"github.com/stretchr/testify/assert"
-	"gopkg.in/macaron.v1"
 )
 
 const (
diff --git a/modules/validation/helpers_test.go b/modules/validation/helpers_test.go
index 9051ee1a0d..cc2a4b720d 100644
--- a/modules/validation/helpers_test.go
+++ b/modules/validation/helpers_test.go
@@ -7,9 +7,9 @@ package validation
 import (
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-
 	"code.gitea.io/gitea/modules/setting"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func Test_IsValidURL(t *testing.T) {
diff --git a/modules/validation/refname_test.go b/modules/validation/refname_test.go
index 57e3f1bf8e..521a83fa04 100644
--- a/modules/validation/refname_test.go
+++ b/modules/validation/refname_test.go
@@ -7,7 +7,7 @@ package validation
 import (
 	"testing"
 
-	"github.com/go-macaron/binding"
+	"gitea.com/macaron/binding"
 )
 
 var gitRefNameValidationTestCases = []validationTestCase{
diff --git a/modules/validation/validurl_test.go b/modules/validation/validurl_test.go
index ba4d7d53d9..aed7406c0a 100644
--- a/modules/validation/validurl_test.go
+++ b/modules/validation/validurl_test.go
@@ -7,7 +7,7 @@ package validation
 import (
 	"testing"
 
-	"github.com/go-macaron/binding"
+	"gitea.com/macaron/binding"
 )
 
 var urlValidationTestCases = []validationTestCase{
diff --git a/routers/admin/admin.go b/routers/admin/admin.go
index 8339c1eaec..54fbddc58e 100644
--- a/routers/admin/admin.go
+++ b/routers/admin/admin.go
@@ -13,9 +13,6 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/context"
@@ -25,6 +22,9 @@ import (
 	"code.gitea.io/gitea/modules/process"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
+
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/admin/auths.go b/routers/admin/auths.go
index 81751f8955..8e0c27e226 100644
--- a/routers/admin/auths.go
+++ b/routers/admin/auths.go
@@ -16,7 +16,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"xorm.io/core"
 )
 
diff --git a/routers/admin/notice.go b/routers/admin/notice.go
index d2c067c143..ad2bad2163 100644
--- a/routers/admin/notice.go
+++ b/routers/admin/notice.go
@@ -12,7 +12,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/admin/users.go b/routers/admin/users.go
index 8a99de01c2..aa595edad9 100644
--- a/routers/admin/users.go
+++ b/routers/admin/users.go
@@ -7,8 +7,6 @@ package admin
 import (
 	"strings"
 
-	"github.com/Unknwon/com"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/base"
@@ -16,6 +14,8 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/routers"
+
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/admin/users_test.go b/routers/admin/users_test.go
index 17eadd1336..e054524fd1 100644
--- a/routers/admin/users_test.go
+++ b/routers/admin/users_test.go
@@ -10,6 +10,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/test"
+
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go
index c90e739626..cdec9e7fad 100644
--- a/routers/api/v1/admin/org.go
+++ b/routers/api/v1/admin/org.go
@@ -6,10 +6,9 @@
 package admin
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/user"
 )
diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go
index aaa7957a50..1f64b42238 100644
--- a/routers/api/v1/admin/repo.go
+++ b/routers/api/v1/admin/repo.go
@@ -5,9 +5,8 @@
 package admin
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/repo"
 	"code.gitea.io/gitea/routers/api/v1/user"
 )
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index cd308fce51..69dfc89378 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -74,9 +74,9 @@ import (
 	_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
 	"code.gitea.io/gitea/routers/api/v1/user"
 
-	"github.com/go-macaron/binding"
-	"github.com/go-macaron/cors"
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/cors"
+	"gitea.com/macaron/macaron"
 )
 
 func sudo() macaron.Handler {
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
index d2691f8238..90202117cc 100644
--- a/routers/api/v1/convert/convert.go
+++ b/routers/api/v1/convert/convert.go
@@ -15,7 +15,7 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // ToEmail convert models.EmailAddress to api.Email
diff --git a/routers/api/v1/misc/markdown.go b/routers/api/v1/misc/markdown.go
index b00b00c499..23f0b168d0 100644
--- a/routers/api/v1/misc/markdown.go
+++ b/routers/api/v1/misc/markdown.go
@@ -8,11 +8,10 @@ import (
 	"net/http"
 	"strings"
 
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/markup/markdown"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 
 	"mvdan.cc/xurls/v2"
diff --git a/routers/api/v1/misc/markdown_test.go b/routers/api/v1/misc/markdown_test.go
index 6cb6b92f9f..47e99d2f06 100644
--- a/routers/api/v1/misc/markdown_test.go
+++ b/routers/api/v1/misc/markdown_test.go
@@ -13,9 +13,9 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/go-macaron/inject"
+	"gitea.com/macaron/inject"
+	"gitea.com/macaron/macaron"
 	"github.com/stretchr/testify/assert"
-	macaron "gopkg.in/macaron.v1"
 )
 
 const AppURL = "http://localhost:3000/"
diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go
index 128cfec328..3f391e4b2b 100644
--- a/routers/api/v1/org/hook.go
+++ b/routers/api/v1/org/hook.go
@@ -5,10 +5,9 @@
 package org
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/utils"
 )
diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go
index 4ada2d6ef6..370536d22f 100644
--- a/routers/api/v1/org/member.go
+++ b/routers/api/v1/org/member.go
@@ -7,11 +7,10 @@ package org
 import (
 	"fmt"
 
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/user"
 )
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index 2893887a4b..3adc204d3b 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -6,10 +6,9 @@
 package org
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/user"
 )
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 59a000b670..3357c07251 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -6,10 +6,9 @@
 package org
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/user"
 )
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index 1aaae8723b..670123a858 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -8,9 +8,8 @@ package repo
 import (
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/routers/api/v1/convert"
-
 	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
 // GetBranch get a branch of a repository
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index 3ba03e054c..132652e2a9 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -10,7 +10,6 @@ import (
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go
index c004544f58..7231daab29 100644
--- a/routers/api/v1/repo/fork.go
+++ b/routers/api/v1/repo/fork.go
@@ -7,7 +7,6 @@ package repo
 import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 8595be335b..402da82f07 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -16,10 +16,9 @@ import (
 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
 	"code.gitea.io/gitea/modules/notification"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
-
-	api "code.gitea.io/gitea/modules/structs"
 )
 
 // ListIssues list the issues of a repository
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index 14e81222e3..18fa1d3eb2 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -11,7 +11,6 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/notification"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go
index 7c22e6885c..e66bc35e90 100644
--- a/routers/api/v1/repo/issue_label.go
+++ b/routers/api/v1/repo/issue_label.go
@@ -8,7 +8,6 @@ package repo
 import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go
index 194f7d32ce..c38ea05c36 100644
--- a/routers/api/v1/repo/issue_tracked_time.go
+++ b/routers/api/v1/repo/issue_tracked_time.go
@@ -7,7 +7,6 @@ package repo
 import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
index 59782d05f6..42bf024a5f 100644
--- a/routers/api/v1/repo/key.go
+++ b/routers/api/v1/repo/key.go
@@ -10,9 +10,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/routers/api/v1/convert"
-
 	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
 // appendPrivateInformation appends the owner and key type information to api.PublicKey
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index 98ccee37bd..33574c481e 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -10,7 +10,6 @@ import (
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index 0fdcfa355c..9296f22e80 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -8,7 +8,6 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go
index d0eb3d4ae1..67802fd9e7 100644
--- a/routers/api/v1/repo/release_attachment.go
+++ b/routers/api/v1/repo/release_attachment.go
@@ -10,9 +10,8 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
-	"code.gitea.io/gitea/modules/upload"
-
 	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/modules/upload"
 )
 
 // GetReleaseAttachment gets a single attachment of the release
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 8d7e43edff..5fe41927fa 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -17,10 +17,9 @@ import (
 	"code.gitea.io/gitea/modules/migrations"
 	"code.gitea.io/gitea/modules/notification"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 	"code.gitea.io/gitea/routers/api/v1/convert"
-
-	api "code.gitea.io/gitea/modules/structs"
 )
 
 var searchOrderByMap = map[string]map[string]models.SearchOrderBy{
diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go
index 1b2ef0b027..2eb5daeced 100644
--- a/routers/api/v1/repo/star.go
+++ b/routers/api/v1/repo/star.go
@@ -6,7 +6,6 @@ package repo
 
 import (
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go
index b3d16e79bc..48edd22910 100644
--- a/routers/api/v1/repo/status.go
+++ b/routers/api/v1/repo/status.go
@@ -10,7 +10,6 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/repofiles"
-
 	api "code.gitea.io/gitea/modules/structs"
 )
 
diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go
index ec0ea6dada..79ad0e0221 100644
--- a/routers/api/v1/repo/subscriber.go
+++ b/routers/api/v1/repo/subscriber.go
@@ -6,7 +6,6 @@ package repo
 
 import (
 	"code.gitea.io/gitea/modules/context"
-
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go
index ecf580e1b0..1753402d3a 100644
--- a/routers/api/v1/repo/tag.go
+++ b/routers/api/v1/repo/tag.go
@@ -5,11 +5,11 @@
 package repo
 
 import (
-	"code.gitea.io/gitea/modules/context"
-	"code.gitea.io/gitea/routers/api/v1/convert"
 	"net/http"
 
+	"code.gitea.io/gitea/modules/context"
 	api "code.gitea.io/gitea/modules/structs"
+	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
 // ListTags list all the tags of a repository
diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go
index 8e3b476d36..e42a3cb093 100644
--- a/routers/api/v1/user/app.go
+++ b/routers/api/v1/user/app.go
@@ -6,10 +6,9 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 )
 
 // ListAccessTokens list all the access tokens
diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go
index 67659cfb0f..027f4e2763 100644
--- a/routers/api/v1/user/email.go
+++ b/routers/api/v1/user/email.go
@@ -5,11 +5,10 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go
index 078f30af3c..59df9665f4 100644
--- a/routers/api/v1/user/follower.go
+++ b/routers/api/v1/user/follower.go
@@ -5,10 +5,9 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go
index 7bf43c5822..fa85e47a82 100644
--- a/routers/api/v1/user/gpg_key.go
+++ b/routers/api/v1/user/gpg_key.go
@@ -5,10 +5,9 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 )
 
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index e3d7aa4b3e..8425535b10 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -5,11 +5,10 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/repo"
 )
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index e5eec71b60..744e0bf7d5 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -5,10 +5,9 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
+	api "code.gitea.io/gitea/modules/structs"
 )
 
 // getStarredRepos returns the repos that the user with the specified userID has
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index fc3b7a8160..bb1302077b 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -13,7 +13,7 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/convert"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // Search search users
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index f0eb95ac1e..87739b15fb 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -5,11 +5,10 @@
 package user
 
 import (
-	api "code.gitea.io/gitea/modules/structs"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
+	api "code.gitea.io/gitea/modules/structs"
 )
 
 // getWatchedRepos returns the repos that the user with the specified userID is
diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go
index 92846c5f2a..0b00e59ade 100644
--- a/routers/api/v1/utils/hook.go
+++ b/routers/api/v1/utils/hook.go
@@ -15,7 +15,7 @@ import (
 	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/utils"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // GetOrgHook get an organization's webhook. If there is an error, write to
diff --git a/routers/init.go b/routers/init.go
index 26d750d20e..4724da8627 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -22,7 +22,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/ssh"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 func checkRunMode() {
diff --git a/routers/install.go b/routers/install.go
index c95abebea7..6d29bcf887 100644
--- a/routers/install.go
+++ b/routers/install.go
@@ -11,10 +11,6 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/Unknwon/com"
-	"github.com/go-xorm/xorm"
-	"gopkg.in/ini.v1"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/base"
@@ -23,6 +19,10 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/user"
+
+	"github.com/go-xorm/xorm"
+	"github.com/unknwon/com"
+	"gopkg.in/ini.v1"
 )
 
 const (
diff --git a/routers/metrics.go b/routers/metrics.go
index b7711dfced..f2381c2745 100644
--- a/routers/metrics.go
+++ b/routers/metrics.go
@@ -7,10 +7,10 @@ package routers
 import (
 	"crypto/subtle"
 
-	"github.com/prometheus/client_golang/prometheus/promhttp"
-
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/setting"
+
+	"github.com/prometheus/client_golang/prometheus/promhttp"
 )
 
 // Metrics validate auth token and render prometheus metrics
diff --git a/routers/org/members.go b/routers/org/members.go
index 20f80cefcd..f9cb275e83 100644
--- a/routers/org/members.go
+++ b/routers/org/members.go
@@ -5,13 +5,13 @@
 package org
 
 import (
-	"github.com/Unknwon/com"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
+
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/org/teams.go b/routers/org/teams.go
index f662bd92e2..7ead6ea5ff 100644
--- a/routers/org/teams.go
+++ b/routers/org/teams.go
@@ -9,14 +9,14 @@ import (
 	"path"
 	"strings"
 
-	"github.com/Unknwon/com"
-
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/auth"
 	"code.gitea.io/gitea/modules/base"
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/routers/utils"
+
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/private/hook.go b/routers/private/hook.go
index ee77a00321..1f6ab2f673 100644
--- a/routers/private/hook.go
+++ b/routers/private/hook.go
@@ -18,7 +18,7 @@ import (
 	"code.gitea.io/gitea/modules/repofiles"
 	"code.gitea.io/gitea/modules/util"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // HookPreReceive checks whether a individual commit is acceptable
diff --git a/routers/private/internal.go b/routers/private/internal.go
index 11cea8b4b9..3a48f5384d 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -11,7 +11,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/setting"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // CheckInternalToken check internal token is set
diff --git a/routers/private/key.go b/routers/private/key.go
index 8c1dbd40f1..dcf597d6ba 100644
--- a/routers/private/key.go
+++ b/routers/private/key.go
@@ -9,7 +9,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // UpdatePublicKeyInRepo update public key and deploy key updates
diff --git a/routers/private/push_update.go b/routers/private/push_update.go
index 733490ce1c..42eda3178b 100644
--- a/routers/private/push_update.go
+++ b/routers/private/push_update.go
@@ -13,7 +13,7 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/repofiles"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // PushUpdate update public key updates
diff --git a/routers/private/serv.go b/routers/private/serv.go
index 90579a3dcc..71c0f6ea2c 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -15,7 +15,7 @@ import (
 	"code.gitea.io/gitea/modules/private"
 	"code.gitea.io/gitea/modules/setting"
 
-	macaron "gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 // ServNoCommand returns information about the provided keyid
diff --git a/routers/repo/editor_test.go b/routers/repo/editor_test.go
index 7a68ecc9b7..ca00be74b7 100644
--- a/routers/repo/editor_test.go
+++ b/routers/repo/editor_test.go
@@ -5,11 +5,11 @@
 package repo
 
 import (
-	"code.gitea.io/gitea/modules/git"
-	"code.gitea.io/gitea/modules/test"
 	"testing"
 
 	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/git"
+	"code.gitea.io/gitea/modules/test"
 
 	"github.com/stretchr/testify/assert"
 )
diff --git a/routers/repo/issue.go b/routers/repo/issue.go
index 72e0357e6c..564a0eab09 100644
--- a/routers/repo/issue.go
+++ b/routers/repo/issue.go
@@ -27,7 +27,7 @@ import (
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/repo/pull.go b/routers/repo/pull.go
index cb4fa9547e..01a57f04e4 100644
--- a/routers/repo/pull.go
+++ b/routers/repo/pull.go
@@ -25,7 +25,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 8c63d73b38..53244f304c 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -21,7 +21,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/repo/setting.go b/routers/repo/setting.go
index 38c6ecf56e..3dc5a1e099 100644
--- a/routers/repo/setting.go
+++ b/routers/repo/setting.go
@@ -25,7 +25,7 @@ import (
 	"code.gitea.io/gitea/modules/validation"
 	"code.gitea.io/gitea/routers/utils"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"mvdan.cc/xurls/v2"
 )
 
diff --git a/routers/repo/webhook.go b/routers/repo/webhook.go
index 20a3a45c18..d523fd9e87 100644
--- a/routers/repo/webhook.go
+++ b/routers/repo/webhook.go
@@ -20,7 +20,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	api "code.gitea.io/gitea/modules/structs"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 6169aa563c..5774c65eca 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -38,16 +38,16 @@ import (
 	// to registers all internal adapters
 	_ "code.gitea.io/gitea/modules/session"
 
-	"github.com/go-macaron/binding"
-	"github.com/go-macaron/cache"
-	"github.com/go-macaron/captcha"
-	"github.com/go-macaron/csrf"
-	"github.com/go-macaron/i18n"
-	"github.com/go-macaron/session"
-	"github.com/go-macaron/toolbox"
+	"gitea.com/macaron/binding"
+	"gitea.com/macaron/cache"
+	"gitea.com/macaron/captcha"
+	"gitea.com/macaron/csrf"
+	"gitea.com/macaron/i18n"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/session"
+	"gitea.com/macaron/toolbox"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/tstranex/u2f"
-	macaron "gopkg.in/macaron.v1"
 )
 
 type routerLoggerOptions struct {
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 6850bbe11b..11d642b147 100644
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -22,7 +22,7 @@ import (
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/go-macaron/captcha"
+	"gitea.com/macaron/captcha"
 	"github.com/markbates/goth"
 	"github.com/tstranex/u2f"
 )
diff --git a/routers/user/auth_openid.go b/routers/user/auth_openid.go
index 48dbf02ffb..832766b16c 100644
--- a/routers/user/auth_openid.go
+++ b/routers/user/auth_openid.go
@@ -19,7 +19,7 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 
-	"github.com/go-macaron/captcha"
+	"gitea.com/macaron/captcha"
 )
 
 const (
diff --git a/routers/user/home.go b/routers/user/home.go
index 9ccd5bdb26..adf47d289c 100644
--- a/routers/user/home.go
+++ b/routers/user/home.go
@@ -18,9 +18,9 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/util"
 
-	"github.com/Unknwon/com"
 	"github.com/keybase/go-crypto/openpgp"
 	"github.com/keybase/go-crypto/openpgp/armor"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/routers/user/home_test.go b/routers/user/home_test.go
index 8a3d9b9f51..9d4136ac8c 100644
--- a/routers/user/home_test.go
+++ b/routers/user/home_test.go
@@ -9,9 +9,9 @@ import (
 	"testing"
 
 	"code.gitea.io/gitea/models"
+	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/test"
 
-	"code.gitea.io/gitea/modules/setting"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/routers/user/oauth.go b/routers/user/oauth.go
index 19add5e647..d4dcb857fa 100644
--- a/routers/user/oauth.go
+++ b/routers/user/oauth.go
@@ -18,8 +18,8 @@ import (
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/timeutil"
 
+	"gitea.com/macaron/binding"
 	"github.com/dgrijalva/jwt-go"
-	"github.com/go-macaron/binding"
 )
 
 const (
diff --git a/routers/user/setting/profile.go b/routers/user/setting/profile.go
index 64828e90ee..6db9fc7c6e 100644
--- a/routers/user/setting/profile.go
+++ b/routers/user/setting/profile.go
@@ -18,8 +18,8 @@ import (
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 
-	"github.com/Unknwon/com"
-	"github.com/Unknwon/i18n"
+	"github.com/unknwon/com"
+	"github.com/unknwon/i18n"
 )
 
 const (
diff --git a/vendor/gitea.com/macaron/binding/.drone.yml b/vendor/gitea.com/macaron/binding/.drone.yml
new file mode 100644
index 0000000000..9baf4f1cf7
--- /dev/null
+++ b/vendor/gitea.com/macaron/binding/.drone.yml
@@ -0,0 +1,24 @@
+kind: pipeline
+name: go1-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  environment:
+    GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: go1-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+    GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/binding/.gitignore b/vendor/gitea.com/macaron/binding/.gitignore
similarity index 100%
rename from vendor/github.com/go-macaron/binding/.gitignore
rename to vendor/gitea.com/macaron/binding/.gitignore
diff --git a/vendor/github.com/Unknwon/cae/LICENSE b/vendor/gitea.com/macaron/binding/LICENSE
similarity index 100%
rename from vendor/github.com/Unknwon/cae/LICENSE
rename to vendor/gitea.com/macaron/binding/LICENSE
diff --git a/vendor/github.com/go-macaron/binding/README.md b/vendor/gitea.com/macaron/binding/README.md
similarity index 82%
rename from vendor/github.com/go-macaron/binding/README.md
rename to vendor/gitea.com/macaron/binding/README.md
index a6748b57a1..aeaa571939 100644
--- a/vendor/github.com/go-macaron/binding/README.md
+++ b/vendor/gitea.com/macaron/binding/README.md
@@ -1,4 +1,4 @@
-# binding [![Build Status](https://travis-ci.org/go-macaron/binding.svg?branch=master)](https://travis-ci.org/go-macaron/binding) [![](http://gocover.io/_badge/github.com/go-macaron/binding)](http://gocover.io/github.com/go-macaron/binding)
+# binding [![Build Status](https://travis-ci.org/go-macaron/binding.svg?branch=master)](https://travis-ci.org/go-macaron/binding) [![Sourcegraph](https://sourcegraph.com/github.com/go-macaron/binding/-/badge.svg)](https://sourcegraph.com/github.com/go-macaron/binding?badge)
 
 Middleware binding provides request data binding and validation for [Macaron](https://github.com/go-macaron/macaron).
 
diff --git a/vendor/github.com/go-macaron/binding/binding.go b/vendor/gitea.com/macaron/binding/binding.go
similarity index 81%
rename from vendor/github.com/go-macaron/binding/binding.go
rename to vendor/gitea.com/macaron/binding/binding.go
index ace08d6cfe..633d836b64 100644
--- a/vendor/github.com/go-macaron/binding/binding.go
+++ b/vendor/gitea.com/macaron/binding/binding.go
@@ -22,17 +22,18 @@ import (
 	"io"
 	"mime/multipart"
 	"net/http"
+	"net/url"
 	"reflect"
 	"regexp"
 	"strconv"
 	"strings"
 	"unicode/utf8"
 
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
-const _VERSION = "0.3.2"
+const _VERSION = "0.6.0"
 
 func Version() string {
 	return _VERSION
@@ -145,7 +146,7 @@ func Form(formStruct interface{}, ifacePtr ...interface{}) macaron.Handler {
 		if parseErr != nil {
 			errors.Add([]string{}, ERR_DESERIALIZATION, parseErr.Error())
 		}
-		mapForm(formStruct, ctx.Req.Form, nil, errors)
+		errors = mapForm(formStruct, ctx.Req.Form, nil, errors)
 		validateAndMap(formStruct, ctx, errors, ifacePtr...)
 	}
 }
@@ -185,7 +186,7 @@ func MultipartForm(formStruct interface{}, ifacePtr ...interface{}) macaron.Hand
 				ctx.Req.MultipartForm = form
 			}
 		}
-		mapForm(formStruct, ctx.Req.MultipartForm.Value, ctx.Req.MultipartForm.File, errors)
+		errors = mapForm(formStruct, ctx.Req.MultipartForm.Value, ctx.Req.MultipartForm.File, errors)
 		validateAndMap(formStruct, ctx, errors, ifacePtr...)
 	}
 }
@@ -211,13 +212,35 @@ func Json(jsonStruct interface{}, ifacePtr ...interface{}) macaron.Handler {
 	}
 }
 
+// RawValidate is same as Validate but does not require a HTTP context,
+// and can be used independently just for validation.
+// This function does not support Validator interface.
+func RawValidate(obj interface{}) Errors {
+	var errs Errors
+	v := reflect.ValueOf(obj)
+	k := v.Kind()
+	if k == reflect.Interface || k == reflect.Ptr {
+		v = v.Elem()
+		k = v.Kind()
+	}
+	if k == reflect.Slice || k == reflect.Array {
+		for i := 0; i < v.Len(); i++ {
+			e := v.Index(i).Interface()
+			errs = validateStruct(errs, e)
+		}
+	} else {
+		errs = validateStruct(errs, obj)
+	}
+	return errs
+}
+
 // Validate is middleware to enforce required fields. If the struct
 // passed in implements Validator, then the user-defined Validate method
 // is executed, and its errors are mapped to the context. This middleware
 // performs no error handling: it merely detects errors and maps them.
 func Validate(obj interface{}) macaron.Handler {
 	return func(ctx *macaron.Context) {
-		var errors Errors
+		var errs Errors
 		v := reflect.ValueOf(obj)
 		k := v.Kind()
 		if k == reflect.Interface || k == reflect.Ptr {
@@ -227,18 +250,18 @@ func Validate(obj interface{}) macaron.Handler {
 		if k == reflect.Slice || k == reflect.Array {
 			for i := 0; i < v.Len(); i++ {
 				e := v.Index(i).Interface()
-				errors = validateStruct(errors, e)
+				errs = validateStruct(errs, e)
 				if validator, ok := e.(Validator); ok {
-					errors = validator.Validate(ctx, errors)
+					errs = validator.Validate(ctx, errs)
 				}
 			}
 		} else {
-			errors = validateStruct(errors, obj)
+			errs = validateStruct(errs, obj)
 			if validator, ok := obj.(Validator); ok {
-				errors = validator.Validate(ctx, errors)
+				errs = validator.Validate(ctx, errs)
 			}
 		}
-		ctx.Map(errors)
+		ctx.Map(errs)
 	}
 }
 
@@ -246,9 +269,42 @@ var (
 	AlphaDashPattern    = regexp.MustCompile("[^\\d\\w-_]")
 	AlphaDashDotPattern = regexp.MustCompile("[^\\d\\w-_\\.]")
 	EmailPattern        = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
-	URLPattern          = regexp.MustCompile(`(http|https):\/\/(?:\\S+(?::\\S*)?@)?[\w\-_]+(\.[\w\-_]+)*([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?`)
 )
 
+// Copied from github.com/asaskevich/govalidator.
+const _MAX_URL_RUNE_COUNT = 2083
+const _MIN_URL_RUNE_COUNT = 3
+
+var (
+	urlSchemaRx    = `((ftp|tcp|udp|wss?|https?):\/\/)`
+	urlUsernameRx  = `(\S+(:\S*)?@)`
+	urlIPRx        = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))`
+	ipRx           = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
+	urlSubdomainRx = `((www\.)|([a-zA-Z0-9]([-\.][-\._a-zA-Z0-9]+)*))`
+	urlPortRx      = `(:(\d{1,5}))`
+	urlPathRx      = `((\/|\?|#)[^\s]*)`
+	URLPattern     = regexp.MustCompile(`^` + urlSchemaRx + `?` + urlUsernameRx + `?` + `((` + urlIPRx + `|(\[` + ipRx + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + urlSubdomainRx + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + urlPortRx + `?` + urlPathRx + `?$`)
+)
+
+// IsURL check if the string is an URL.
+func isURL(str string) bool {
+	if str == "" || utf8.RuneCountInString(str) >= _MAX_URL_RUNE_COUNT || len(str) <= _MIN_URL_RUNE_COUNT || strings.HasPrefix(str, ".") {
+		return false
+	}
+	u, err := url.Parse(str)
+	if err != nil {
+		return false
+	}
+	if strings.HasPrefix(u.Host, ".") {
+		return false
+	}
+	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
+		return false
+	}
+	return URLPattern.MatchString(str)
+
+}
+
 type (
 	// Rule represents a validation rule.
 	Rule struct {
@@ -257,18 +313,34 @@ type (
 		// IsValid applies validation rule to condition.
 		IsValid func(Errors, string, interface{}) (bool, Errors)
 	}
-	// RuleMapper represents a validation rule mapper,
+
+	// ParamRule does same thing as Rule but passes rule itself to IsValid method.
+	ParamRule struct {
+		// IsMatch checks if rule matches.
+		IsMatch func(string) bool
+		// IsValid applies validation rule to condition.
+		IsValid func(Errors, string, string, interface{}) (bool, Errors)
+	}
+
+	// RuleMapper and ParamRuleMapper represent validation rule mappers,
 	// it allwos users to add custom validation rules.
-	RuleMapper []*Rule
+	RuleMapper      []*Rule
+	ParamRuleMapper []*ParamRule
 )
 
 var ruleMapper RuleMapper
+var paramRuleMapper ParamRuleMapper
 
 // AddRule adds new validation rule.
 func AddRule(r *Rule) {
 	ruleMapper = append(ruleMapper, r)
 }
 
+// AddParamRule adds new validation rule.
+func AddParamRule(r *ParamRule) {
+	paramRuleMapper = append(paramRuleMapper, r)
+}
+
 func in(fieldValue interface{}, arr string) bool {
 	val := fmt.Sprintf("%v", fieldValue)
 	vals := strings.Split(arr, ",")
@@ -356,6 +428,16 @@ VALIDATE_RULES:
 				break VALIDATE_RULES
 			}
 		case rule == "Required":
+			v := reflect.ValueOf(fieldValue)
+			if v.Kind() == reflect.Slice {
+				if v.Len() == 0 {
+					errors.Add([]string{field.Name}, ERR_REQUIRED, "Required")
+					break VALIDATE_RULES
+				}
+
+				continue
+			}
+
 			if reflect.DeepEqual(zero, fieldValue) {
 				errors.Add([]string{field.Name}, ERR_REQUIRED, "Required")
 				break VALIDATE_RULES
@@ -422,7 +504,7 @@ VALIDATE_RULES:
 			str := fmt.Sprintf("%v", fieldValue)
 			if len(str) == 0 {
 				continue
-			} else if !URLPattern.MatchString(str) {
+			} else if !isURL(str) {
 				errors.Add([]string{field.Name}, ERR_URL, "Url")
 				break VALIDATE_RULES
 			}
@@ -449,14 +531,14 @@ VALIDATE_RULES:
 		case strings.HasPrefix(rule, "Default("):
 			if reflect.DeepEqual(zero, fieldValue) {
 				if fieldVal.CanAddr() {
-					setWithProperType(field.Type.Kind(), rule[8:len(rule)-1], fieldVal, field.Tag.Get("form"), errors)
+					errors = setWithProperType(field.Type.Kind(), rule[8:len(rule)-1], fieldVal, field.Tag.Get("form"), errors)
 				} else {
 					errors.Add([]string{field.Name}, ERR_EXCLUDE, "Default")
 					break VALIDATE_RULES
 				}
 			}
 		default:
-			// Apply custom validation rules.
+			// Apply custom validation rules
 			var isValid bool
 			for i := range ruleMapper {
 				if ruleMapper[i].IsMatch(rule) {
@@ -466,6 +548,14 @@ VALIDATE_RULES:
 					}
 				}
 			}
+			for i := range paramRuleMapper {
+				if paramRuleMapper[i].IsMatch(rule) {
+					isValid, errors = paramRuleMapper[i].IsValid(errors, rule, field.Name, fieldValue)
+					if !isValid {
+						break VALIDATE_RULES
+					}
+				}
+			}
 		}
 	}
 	return errors
@@ -497,7 +587,7 @@ func SetNameMapper(nm NameMapper) {
 
 // Takes values from the form data and puts them into a struct
 func mapForm(formStruct reflect.Value, form map[string][]string,
-	formfile map[string][]*multipart.FileHeader, errors Errors) {
+	formfile map[string][]*multipart.FileHeader, errors Errors) Errors {
 
 	if formStruct.Kind() == reflect.Ptr {
 		formStruct = formStruct.Elem()
@@ -510,12 +600,12 @@ func mapForm(formStruct reflect.Value, form map[string][]string,
 
 		if typeField.Type.Kind() == reflect.Ptr && typeField.Anonymous {
 			structField.Set(reflect.New(typeField.Type.Elem()))
-			mapForm(structField.Elem(), form, formfile, errors)
+			errors = mapForm(structField.Elem(), form, formfile, errors)
 			if reflect.DeepEqual(structField.Elem().Interface(), reflect.Zero(structField.Elem().Type()).Interface()) {
 				structField.Set(reflect.Zero(structField.Type()))
 			}
 		} else if typeField.Type.Kind() == reflect.Struct {
-			mapForm(structField, form, formfile, errors)
+			errors = mapForm(structField, form, formfile, errors)
 		}
 
 		inputFieldName := parseFormName(typeField.Name, typeField.Tag.Get("form"))
@@ -530,11 +620,11 @@ func mapForm(formStruct reflect.Value, form map[string][]string,
 				sliceOf := structField.Type().Elem().Kind()
 				slice := reflect.MakeSlice(structField.Type(), numElems, numElems)
 				for i := 0; i < numElems; i++ {
-					setWithProperType(sliceOf, inputValue[i], slice.Index(i), inputFieldName, errors)
+					errors = setWithProperType(sliceOf, inputValue[i], slice.Index(i), inputFieldName, errors)
 				}
 				formStruct.Field(i).Set(slice)
 			} else {
-				setWithProperType(typeField.Type.Kind(), inputValue[0], structField, inputFieldName, errors)
+				errors = setWithProperType(typeField.Type.Kind(), inputValue[0], structField, inputFieldName, errors)
 			}
 			continue
 		}
@@ -555,13 +645,14 @@ func mapForm(formStruct reflect.Value, form map[string][]string,
 			structField.Set(reflect.ValueOf(inputFile[0]))
 		}
 	}
+	return errors
 }
 
 // This sets the value in a struct of an indeterminate type to the
 // matching value from the request (via Form middleware) in the
 // same type, so that not all deserialized values have to be strings.
 // Supported types are string, int, float, and bool.
-func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value, nameInTag string, errors Errors) {
+func setWithProperType(valueKind reflect.Kind, val string, structField reflect.Value, nameInTag string, errors Errors) Errors {
 	switch valueKind {
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		if val == "" {
@@ -586,7 +677,7 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
 	case reflect.Bool:
 		if val == "on" {
 			structField.SetBool(true)
-			return
+			break
 		}
 
 		if val == "" {
@@ -621,6 +712,7 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
 	case reflect.String:
 		structField.SetString(val)
 	}
+	return errors
 }
 
 // Don't pass in pointers to bind to. Can lead to bugs.
diff --git a/vendor/github.com/go-macaron/binding/errors.go b/vendor/gitea.com/macaron/binding/errors.go
similarity index 100%
rename from vendor/github.com/go-macaron/binding/errors.go
rename to vendor/gitea.com/macaron/binding/errors.go
diff --git a/vendor/gitea.com/macaron/binding/go.mod b/vendor/gitea.com/macaron/binding/go.mod
new file mode 100644
index 0000000000..8609495d49
--- /dev/null
+++ b/vendor/gitea.com/macaron/binding/go.mod
@@ -0,0 +1,9 @@
+module gitea.com/macaron/binding
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+)
diff --git a/vendor/gitea.com/macaron/binding/go.sum b/vendor/gitea.com/macaron/binding/go.sum
new file mode 100644
index 0000000000..56302b6a5f
--- /dev/null
+++ b/vendor/gitea.com/macaron/binding/go.sum
@@ -0,0 +1,30 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/gitea.com/macaron/cache/.drone.yml b/vendor/gitea.com/macaron/cache/.drone.yml
new file mode 100644
index 0000000000..9baf4f1cf7
--- /dev/null
+++ b/vendor/gitea.com/macaron/cache/.drone.yml
@@ -0,0 +1,24 @@
+kind: pipeline
+name: go1-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  environment:
+    GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: go1-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+    GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/gitea.com/macaron/cache/.gitignore b/vendor/gitea.com/macaron/cache/.gitignore
new file mode 100644
index 0000000000..5c84e85ffc
--- /dev/null
+++ b/vendor/gitea.com/macaron/cache/.gitignore
@@ -0,0 +1,5 @@
+nodb/cache
+ledis/tmp.db/
+nodb/tmp.db/
+/vendor
+/.idea
diff --git a/vendor/github.com/Unknwon/com/LICENSE b/vendor/gitea.com/macaron/cache/LICENSE
similarity index 100%
rename from vendor/github.com/Unknwon/com/LICENSE
rename to vendor/gitea.com/macaron/cache/LICENSE
diff --git a/vendor/github.com/go-macaron/cache/README.md b/vendor/gitea.com/macaron/cache/README.md
similarity index 50%
rename from vendor/github.com/go-macaron/cache/README.md
rename to vendor/gitea.com/macaron/cache/README.md
index d27aa93b67..e9eac96115 100644
--- a/vendor/github.com/go-macaron/cache/README.md
+++ b/vendor/gitea.com/macaron/cache/README.md
@@ -1,19 +1,19 @@
-# cache [![Build Status](https://travis-ci.org/go-macaron/cache.svg?branch=master)](https://travis-ci.org/go-macaron/cache) [![](http://gocover.io/_badge/github.com/go-macaron/cache)](http://gocover.io/github.com/go-macaron/cache)
+# cache
 
 Middleware cache provides cache management for [Macaron](https://github.com/go-macaron/macaron). It can use many cache adapters, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Ledis and Nodb.
 
 ### Installation
 
-	go get github.com/go-macaron/cache
+	go get gitea.com/macaron/cache
 
 ## Getting Help
 
-- [API Reference](https://gowalker.org/github.com/go-macaron/cache)
+- [API Reference](https://gowalker.org/gitea.com/macaron/cache)
 - [Documentation](http://go-macaron.com/docs/middlewares/cache)
 
 ## Credits
 
-This package is a modified version of [beego/cache](https://github.com/astaxie/beego/tree/master/cache).
+This package is a modified version of [go-macaron/cache](github.com/go-macaron/cache).
 
 ## License
 
diff --git a/vendor/github.com/go-macaron/cache/cache.go b/vendor/gitea.com/macaron/cache/cache.go
similarity index 99%
rename from vendor/github.com/go-macaron/cache/cache.go
rename to vendor/gitea.com/macaron/cache/cache.go
index 7742a3245b..0893bca6c0 100644
--- a/vendor/github.com/go-macaron/cache/cache.go
+++ b/vendor/gitea.com/macaron/cache/cache.go
@@ -19,7 +19,7 @@ package cache
 import (
 	"fmt"
 
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 const _VERSION = "0.3.0"
diff --git a/vendor/github.com/go-macaron/cache/file.go b/vendor/gitea.com/macaron/cache/file.go
similarity index 98%
rename from vendor/github.com/go-macaron/cache/file.go
rename to vendor/gitea.com/macaron/cache/file.go
index 8cbfaa10b5..3a51892b41 100644
--- a/vendor/github.com/go-macaron/cache/file.go
+++ b/vendor/gitea.com/macaron/cache/file.go
@@ -26,8 +26,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 // Item represents a cache item.
diff --git a/vendor/gitea.com/macaron/cache/go.mod b/vendor/gitea.com/macaron/cache/go.mod
new file mode 100644
index 0000000000..b00811dc2a
--- /dev/null
+++ b/vendor/gitea.com/macaron/cache/go.mod
@@ -0,0 +1,30 @@
+module gitea.com/macaron/cache
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668
+	github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
+	github.com/edsrzf/mmap-go v1.0.0 // indirect
+	github.com/go-redis/redis v6.15.2+incompatible
+	github.com/go-sql-driver/mysql v1.4.1
+	github.com/lib/pq v1.2.0
+	github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de // indirect
+	github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af
+	github.com/mattn/go-sqlite3 v1.11.0 // indirect
+	github.com/onsi/ginkgo v1.8.0 // indirect
+	github.com/onsi/gomega v1.5.0 // indirect
+	github.com/pelletier/go-toml v1.4.0 // indirect
+	github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
+	github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d // indirect
+	github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92
+	github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/syndtr/goleveldb v1.0.0 // indirect
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
+	golang.org/x/sys v0.0.0-20190730183949-1393eb018365 // indirect
+	google.golang.org/appengine v1.6.1 // indirect
+	gopkg.in/ini.v1 v1.44.2
+)
diff --git a/vendor/gitea.com/macaron/cache/go.sum b/vendor/gitea.com/macaron/cache/go.sum
new file mode 100644
index 0000000000..3f311ad14b
--- /dev/null
+++ b/vendor/gitea.com/macaron/cache/go.sum
@@ -0,0 +1,106 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
+github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af h1:UaWHNBdukWrSG3DRvHFR/hyfg681fceqQDYVTBncKfQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 h1:qvsJwGToa8rxb42cDRhkbKeX2H5N8BH+s2aUikGt8mI=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190730183949-1393eb018365 h1:SaXEMXhWzMJThc05vu6uh61Q245r4KaWMrsTedk0FDc=
+golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.44.2 h1:N6kNUPqiIyxP+s/aINPzRvNpcTVV30qLC0t6ZjZFlUU=
+gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/go-macaron/cache/memcache/memcache.go b/vendor/gitea.com/macaron/cache/memcache/memcache.go
similarity index 97%
rename from vendor/github.com/go-macaron/cache/memcache/memcache.go
rename to vendor/gitea.com/macaron/cache/memcache/memcache.go
index f8a99097f5..79f44bfccc 100644
--- a/vendor/github.com/go-macaron/cache/memcache/memcache.go
+++ b/vendor/gitea.com/macaron/cache/memcache/memcache.go
@@ -18,10 +18,10 @@ package cache
 import (
 	"strings"
 
-	"github.com/Unknwon/com"
 	"github.com/bradfitz/gomemcache/memcache"
+	"github.com/unknwon/com"
 
-	"github.com/go-macaron/cache"
+	"gitea.com/macaron/cache"
 )
 
 // MemcacheCacher represents a memcache cache adapter implementation.
diff --git a/vendor/github.com/go-macaron/cache/memcache/memcache.goconvey b/vendor/gitea.com/macaron/cache/memcache/memcache.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/cache/memcache/memcache.goconvey
rename to vendor/gitea.com/macaron/cache/memcache/memcache.goconvey
diff --git a/vendor/github.com/go-macaron/cache/memory.go b/vendor/gitea.com/macaron/cache/memory.go
similarity index 100%
rename from vendor/github.com/go-macaron/cache/memory.go
rename to vendor/gitea.com/macaron/cache/memory.go
diff --git a/vendor/github.com/go-macaron/cache/redis/redis.go b/vendor/gitea.com/macaron/cache/redis/redis.go
similarity index 93%
rename from vendor/github.com/go-macaron/cache/redis/redis.go
rename to vendor/gitea.com/macaron/cache/redis/redis.go
index 5b59fbd292..892ee28bdc 100644
--- a/vendor/github.com/go-macaron/cache/redis/redis.go
+++ b/vendor/gitea.com/macaron/cache/redis/redis.go
@@ -20,11 +20,11 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
+	"github.com/go-redis/redis"
+	"github.com/unknwon/com"
 	"gopkg.in/ini.v1"
-	"gopkg.in/redis.v2"
 
-	"github.com/go-macaron/cache"
+	"gitea.com/macaron/cache"
 )
 
 // RedisCacher represents a redis cache adapter implementation.
@@ -40,7 +40,7 @@ type RedisCacher struct {
 func (c *RedisCacher) Put(key string, val interface{}, expire int64) error {
 	key = c.prefix + key
 	if expire == 0 {
-		if err := c.c.Set(key, com.ToStr(val)).Err(); err != nil {
+		if err := c.c.Set(key, com.ToStr(val), 0).Err(); err != nil {
 			return err
 		}
 	} else {
@@ -48,7 +48,7 @@ func (c *RedisCacher) Put(key string, val interface{}, expire int64) error {
 		if err != nil {
 			return err
 		}
-		if err = c.c.SetEx(key, dur, com.ToStr(val)).Err(); err != nil {
+		if err = c.c.Set(key, com.ToStr(val), dur).Err(); err != nil {
 			return err
 		}
 	}
@@ -99,7 +99,7 @@ func (c *RedisCacher) Decr(key string) error {
 
 // IsExist returns true if cached value exists.
 func (c *RedisCacher) IsExist(key string) bool {
-	if c.c.Exists(c.prefix + key).Val() {
+	if c.c.Exists(c.prefix+key).Val() == 1 {
 		return true
 	}
 
@@ -148,7 +148,7 @@ func (c *RedisCacher) StartAndGC(opts cache.Options) error {
 		case "password":
 			opt.Password = v
 		case "db":
-			opt.DB = com.StrTo(v).MustInt64()
+			opt.DB = com.StrTo(v).MustInt()
 		case "pool_size":
 			opt.PoolSize = com.StrTo(v).MustInt()
 		case "idle_timeout":
diff --git a/vendor/github.com/go-macaron/cache/redis/redis.goconvey b/vendor/gitea.com/macaron/cache/redis/redis.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/cache/redis/redis.goconvey
rename to vendor/gitea.com/macaron/cache/redis/redis.goconvey
diff --git a/vendor/github.com/go-macaron/cache/utils.go b/vendor/gitea.com/macaron/cache/utils.go
similarity index 100%
rename from vendor/github.com/go-macaron/cache/utils.go
rename to vendor/gitea.com/macaron/cache/utils.go
diff --git a/vendor/gitea.com/macaron/captcha/.drone.yml b/vendor/gitea.com/macaron/captcha/.drone.yml
new file mode 100644
index 0000000000..1db7ea30e3
--- /dev/null
+++ b/vendor/gitea.com/macaron/captcha/.drone.yml
@@ -0,0 +1,24 @@
+kind: pipeline
+name: go1-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: go1-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/github.com/Unknwon/i18n/LICENSE b/vendor/gitea.com/macaron/captcha/LICENSE
similarity index 100%
rename from vendor/github.com/Unknwon/i18n/LICENSE
rename to vendor/gitea.com/macaron/captcha/LICENSE
diff --git a/vendor/github.com/go-macaron/captcha/README.md b/vendor/gitea.com/macaron/captcha/README.md
similarity index 52%
rename from vendor/github.com/go-macaron/captcha/README.md
rename to vendor/gitea.com/macaron/captcha/README.md
index 5eab6f3feb..f55b2e925e 100644
--- a/vendor/github.com/go-macaron/captcha/README.md
+++ b/vendor/gitea.com/macaron/captcha/README.md
@@ -1,14 +1,14 @@
-# captcha [![Build Status](https://travis-ci.org/go-macaron/captcha.svg?branch=master)](https://travis-ci.org/go-macaron/captcha)
+# captcha [![Build Status](https://drone.gitea.com/api/badges/macaron/captcha/status.svg)](https://drone.gitea.com/macaron/captcha)
 
-Middleware captcha provides captcha service for [Macaron](https://github.com/go-macaron/macaron).
+Middleware captcha provides captcha service for [Macaron](https://gitea.com/macaron/macaron).
 
 ### Installation
 
-	go get github.com/go-macaron/captcha
+	go get gitea.com/macaron/captcha
 
 ## Getting Help
 
-- [API Reference](https://gowalker.org/github.com/go-macaron/captcha)
+- [API Reference](https://gowalker.org/gitea.com/macaron/captcha)
 - [Documentation](http://go-macaron.com/docs/middlewares/captcha)
 
 ## License
diff --git a/vendor/github.com/go-macaron/captcha/captcha.go b/vendor/gitea.com/macaron/captcha/captcha.go
similarity index 98%
rename from vendor/github.com/go-macaron/captcha/captcha.go
rename to vendor/gitea.com/macaron/captcha/captcha.go
index 91e6386651..b6e51f2a26 100644
--- a/vendor/github.com/go-macaron/captcha/captcha.go
+++ b/vendor/gitea.com/macaron/captcha/captcha.go
@@ -23,9 +23,9 @@ import (
 	"path"
 	"strings"
 
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/cache"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/cache"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 const _VERSION = "0.1.0"
diff --git a/vendor/gitea.com/macaron/captcha/go.mod b/vendor/gitea.com/macaron/captcha/go.mod
new file mode 100644
index 0000000000..6980787b99
--- /dev/null
+++ b/vendor/gitea.com/macaron/captcha/go.mod
@@ -0,0 +1,10 @@
+module gitea.com/macaron/captcha
+
+go 1.11
+
+require (
+	gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+)
diff --git a/vendor/gitea.com/macaron/captcha/go.sum b/vendor/gitea.com/macaron/captcha/go.sum
new file mode 100644
index 0000000000..6c6f0e4b66
--- /dev/null
+++ b/vendor/gitea.com/macaron/captcha/go.sum
@@ -0,0 +1,78 @@
+gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 h1:mMsMEg90c5KXQgRWsH8D6GHXfZIW1RAe5S9VYIb12lM=
+gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76/go.mod h1:NFHb9Of+LUnU86bU20CiXXg6ZlgCJ4XytP14UsHOXFs=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.44.2 h1:N6kNUPqiIyxP+s/aINPzRvNpcTVV30qLC0t6ZjZFlUU=
+gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/go-macaron/captcha/image.go b/vendor/gitea.com/macaron/captcha/image.go
similarity index 100%
rename from vendor/github.com/go-macaron/captcha/image.go
rename to vendor/gitea.com/macaron/captcha/image.go
diff --git a/vendor/github.com/go-macaron/captcha/siprng.go b/vendor/gitea.com/macaron/captcha/siprng.go
similarity index 100%
rename from vendor/github.com/go-macaron/captcha/siprng.go
rename to vendor/gitea.com/macaron/captcha/siprng.go
diff --git a/vendor/gitea.com/macaron/cors/.drone.yml b/vendor/gitea.com/macaron/cors/.drone.yml
new file mode 100644
index 0000000000..39499f444a
--- /dev/null
+++ b/vendor/gitea.com/macaron/cors/.drone.yml
@@ -0,0 +1,9 @@
+kind: pipeline
+name: default
+
+steps:
+- name: test
+  image: golang:1.11
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
diff --git a/vendor/github.com/go-macaron/cors/.gitignore b/vendor/gitea.com/macaron/cors/.gitignore
similarity index 100%
rename from vendor/github.com/go-macaron/cors/.gitignore
rename to vendor/gitea.com/macaron/cors/.gitignore
diff --git a/vendor/github.com/go-macaron/cors/LICENSE b/vendor/gitea.com/macaron/cors/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/cors/LICENSE
rename to vendor/gitea.com/macaron/cors/LICENSE
diff --git a/vendor/gitea.com/macaron/cors/README.md b/vendor/gitea.com/macaron/cors/README.md
new file mode 100644
index 0000000000..5ef70e3579
--- /dev/null
+++ b/vendor/gitea.com/macaron/cors/README.md
@@ -0,0 +1,5 @@
+# cors
+
+[![Build Status](https://drone.gitea.com/api/badges/macaron/cors/status.svg)](https://drone.gitea.com/macaron/cors)
+
+Package cors is a middleware that handles CORS requests &amp; headers for Macaron.
diff --git a/vendor/github.com/go-macaron/cors/cors.go b/vendor/gitea.com/macaron/cors/cors.go
similarity index 62%
rename from vendor/github.com/go-macaron/cors/cors.go
rename to vendor/gitea.com/macaron/cors/cors.go
index b0cec3ddd8..ed00df1e7b 100644
--- a/vendor/github.com/go-macaron/cors/cors.go
+++ b/vendor/gitea.com/macaron/cors/cors.go
@@ -8,20 +8,42 @@ import (
 	"strconv"
 	"strings"
 
-	macaron "gopkg.in/macaron.v1"
+	macaron "gitea.com/macaron/macaron"
 )
 
-const _VERSION = "0.1.0"
+const version = "0.1.1"
 
+const anyDomain = "!*"
+
+// Version returns the version of this module
 func Version() string {
-	return _VERSION
+	return version
 }
 
-// Options represents a struct for specifying configuration options for the CORS middleware.
+/*
+Options to configure the CORS middleware read from the [cors] section of the ini configuration file.
+
+SCHEME may be http or https as accepted schemes or the '*' wildcard to accept any scheme.
+
+ALLOW_DOMAIN may be a comma separated list of domains that are allowed to run CORS requests
+Special values are the  a single '*' wildcard that will allow any domain to send requests without
+credentials and the special '!*' wildcard which will reply with requesting domain in the 'access-control-allow-origin'
+header and hence allow requess from any domain *with* credentials.
+
+ALLOW_SUBDOMAIN set to true accepts requests from any subdomain of ALLOW_DOMAIN.
+
+METHODS may be a comma separated list of HTTP-methods to be accepted.
+
+MAX_AGE_SECONDS may be the duration in secs for which the response is cached (default 600).
+ref: https://stackoverflow.com/questions/54300997/is-it-possible-to-cache-http-options-response?noredirect=1#comment95790277_54300997
+ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
+
+ALLOW_CREDENTIALS set to false rejects any request with credentials.
+*/
 type Options struct {
 	Section          string
 	Scheme           string
-	AllowDomain      string
+	AllowDomain      []string
 	AllowSubdomain   bool
 	Methods          []string
 	MaxAgeSeconds    int
@@ -43,7 +65,10 @@ func prepareOptions(options []Options) Options {
 		opt.Scheme = sec.Key("SCHEME").MustString("http")
 	}
 	if len(opt.AllowDomain) == 0 {
-		opt.AllowDomain = sec.Key("ALLOW_DOMAIN").MustString("*")
+		opt.AllowDomain = sec.Key("ALLOW_DOMAIN").Strings(",")
+		if len(opt.AllowDomain) == 0 {
+			opt.AllowDomain = []string{"*"}
+		}
 	}
 	if !opt.AllowSubdomain {
 		opt.AllowSubdomain = sec.Key("ALLOW_SUBDOMAIN").MustBool(false)
@@ -63,9 +88,6 @@ func prepareOptions(options []Options) Options {
 		}
 	}
 	if opt.MaxAgeSeconds <= 0 {
-		// cache options response for 600 secs
-		// ref: https://stackoverflow.com/questions/54300997/is-it-possible-to-cache-http-options-response?noredirect=1#comment95790277_54300997
-		// ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
 		opt.MaxAgeSeconds = sec.Key("MAX_AGE_SECONDS").MustInt(600)
 	}
 	if !opt.AllowCredentials {
@@ -75,9 +97,9 @@ func prepareOptions(options []Options) Options {
 	return opt
 }
 
+// CORS responds to preflight requests with adequat access-control-* respond headers
 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
 // https://fetch.spec.whatwg.org/#cors-protocol-and-credentials
-// For requests without credentials, the server may specify "*" as a wildcard, thereby allowing any origin to access the resource.
 func CORS(options ...Options) macaron.Handler {
 	opt := prepareOptions(options)
 	return func(ctx *macaron.Context, log *log.Logger) {
@@ -88,9 +110,9 @@ func CORS(options ...Options) macaron.Handler {
 			"access-control-allow-headers": ctx.Req.Header.Get("access-control-request-headers"),
 			"access-control-max-age":       strconv.Itoa(opt.MaxAgeSeconds),
 		}
-		if opt.AllowDomain == "*" {
+		if opt.AllowDomain[0] == "*" {
 			headers["access-control-allow-origin"] = "*"
-		} else if opt.AllowDomain != "" {
+		} else {
 			origin := ctx.Req.Header.Get("Origin")
 			if reqOptions && origin == "" {
 				respErrorf(ctx, log, http.StatusBadRequest, "missing origin header in CORS request")
@@ -103,10 +125,17 @@ func CORS(options ...Options) macaron.Handler {
 				return
 			}
 
-			ok := u.Hostname() == opt.AllowDomain ||
-				(opt.AllowSubdomain && strings.HasSuffix(u.Hostname(), "."+opt.AllowDomain))
+			ok := false
+			for _, d := range opt.AllowDomain {
+				if u.Hostname() == d || (opt.AllowSubdomain && strings.HasSuffix(u.Hostname(), "."+d)) || d == anyDomain {
+					ok = true
+					break
+				}
+			}
 			if ok {
-				u.Scheme = opt.Scheme
+				if opt.Scheme != "*" {
+					u.Scheme = opt.Scheme
+				}
 				headers["access-control-allow-origin"] = u.String()
 				headers["access-control-allow-credentials"] = strconv.FormatBool(opt.AllowCredentials)
 				headers["vary"] = "Origin"
diff --git a/vendor/gitea.com/macaron/cors/go.mod b/vendor/gitea.com/macaron/cors/go.mod
new file mode 100644
index 0000000000..418aab88de
--- /dev/null
+++ b/vendor/gitea.com/macaron/cors/go.mod
@@ -0,0 +1,5 @@
+module gitea.com/macaron/cors
+
+go 1.11
+
+require gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827
diff --git a/vendor/gitea.com/macaron/cors/go.sum b/vendor/gitea.com/macaron/cors/go.sum
new file mode 100644
index 0000000000..e3bcd933dc
--- /dev/null
+++ b/vendor/gitea.com/macaron/cors/go.sum
@@ -0,0 +1,31 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827 h1:/rT4MEFjhdViy2BFWKUwbC0JSNSziEbBCM7q4/B9qgo=
+gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjIkOq4BM8uPUb+VHuU02ZfAO6R4+wD//tiCiRw=
+github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
+github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/gitea.com/macaron/csrf/.drone.yml b/vendor/gitea.com/macaron/csrf/.drone.yml
new file mode 100644
index 0000000000..1db7ea30e3
--- /dev/null
+++ b/vendor/gitea.com/macaron/csrf/.drone.yml
@@ -0,0 +1,24 @@
+kind: pipeline
+name: go1-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: go1-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/binding/LICENSE b/vendor/gitea.com/macaron/csrf/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/binding/LICENSE
rename to vendor/gitea.com/macaron/csrf/LICENSE
diff --git a/vendor/gitea.com/macaron/csrf/README.md b/vendor/gitea.com/macaron/csrf/README.md
new file mode 100644
index 0000000000..3295bd5f9a
--- /dev/null
+++ b/vendor/gitea.com/macaron/csrf/README.md
@@ -0,0 +1,18 @@
+# csrf [![Build Status](https://drone.gitea.com/api/badges/macaron/csrf/status.svg)](https://drone.gitea.com/macaron/csrf)
+
+Middleware csrf generates and validates CSRF tokens for [Macaron](https://gitea.com/macaron/macaron).
+
+[API Reference](https://gowalker.org/gitea.com/macaron/csrf)
+
+### Installation
+
+	go get gitea.com/macaron/csrf
+	
+## Getting Help
+
+- [API Reference](https://gowalker.org/gitea.com/macaron/csrf)
+- [Documentation](http://go-macaron.com/docs/middlewares/csrf)
+
+## License
+
+This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/csrf/csrf.go b/vendor/gitea.com/macaron/csrf/csrf.go
similarity index 98%
rename from vendor/github.com/go-macaron/csrf/csrf.go
rename to vendor/gitea.com/macaron/csrf/csrf.go
index 00f3c3c9c0..66f5b40a8e 100644
--- a/vendor/github.com/go-macaron/csrf/csrf.go
+++ b/vendor/gitea.com/macaron/csrf/csrf.go
@@ -20,9 +20,9 @@ import (
 	"net/http"
 	"time"
 
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/session"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/session"
+	"github.com/unknwon/com"
 )
 
 const _VERSION = "0.1.1"
diff --git a/vendor/gitea.com/macaron/csrf/go.mod b/vendor/gitea.com/macaron/csrf/go.mod
new file mode 100644
index 0000000000..946cb6afff
--- /dev/null
+++ b/vendor/gitea.com/macaron/csrf/go.mod
@@ -0,0 +1,12 @@
+module gitea.com/macaron/csrf
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705
+	github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect
+	github.com/smartystreets/assertions v1.0.1 // indirect
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+)
diff --git a/vendor/gitea.com/macaron/csrf/go.sum b/vendor/gitea.com/macaron/csrf/go.sum
new file mode 100644
index 0000000000..7919c9f8c3
--- /dev/null
+++ b/vendor/gitea.com/macaron/csrf/go.sum
@@ -0,0 +1,83 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705 h1:mvkQGAlON1Z6Y8pqa/+FpYIskk54mazuECUfZK5oTg0=
+gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
+github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
+github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
+github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/go-macaron/csrf/xsrf.go b/vendor/gitea.com/macaron/csrf/xsrf.go
similarity index 100%
rename from vendor/github.com/go-macaron/csrf/xsrf.go
rename to vendor/gitea.com/macaron/csrf/xsrf.go
diff --git a/vendor/gitea.com/macaron/i18n/.drone.yml b/vendor/gitea.com/macaron/i18n/.drone.yml
new file mode 100644
index 0000000000..3f2a434892
--- /dev/null
+++ b/vendor/gitea.com/macaron/i18n/.drone.yml
@@ -0,0 +1,24 @@
+kind: pipeline
+name: golang-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: golang-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/cache/LICENSE b/vendor/gitea.com/macaron/i18n/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/cache/LICENSE
rename to vendor/gitea.com/macaron/i18n/LICENSE
diff --git a/vendor/gitea.com/macaron/i18n/README.md b/vendor/gitea.com/macaron/i18n/README.md
new file mode 100644
index 0000000000..bff89d9b6c
--- /dev/null
+++ b/vendor/gitea.com/macaron/i18n/README.md
@@ -0,0 +1,16 @@
+# i18n [![Build Status](https://drone.gitea.com/api/badges/macaron/i18n/status.svg)](https://drone.gitea.com/macaron/i18n) [![](http://gocover.io/_badge/github.com/go-macaron/i18n)](http://gocover.io/github.com/go-macaron/i18n)
+
+Middleware i18n provides app Internationalization and Localization for [Macaron](https://gitea.com/macaron/macaron).
+
+### Installation
+
+	go get gitea.com/macaron/i18n
+	
+## Getting Help
+
+- [API Reference](https://gowalker.org/gitea.com/macaron/i18n)
+- [Documentation](http://go-macaron.com/docs/middlewares/i18n)
+
+## License
+
+This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/gitea.com/macaron/i18n/go.mod b/vendor/gitea.com/macaron/i18n/go.mod
new file mode 100644
index 0000000000..03577c6e88
--- /dev/null
+++ b/vendor/gitea.com/macaron/i18n/go.mod
@@ -0,0 +1,11 @@
+module gitea.com/macaron/i18n
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
+	golang.org/x/text v0.3.2
+)
diff --git a/vendor/gitea.com/macaron/i18n/go.sum b/vendor/gitea.com/macaron/i18n/go.sum
new file mode 100644
index 0000000000..c96916d448
--- /dev/null
+++ b/vendor/gitea.com/macaron/i18n/go.sum
@@ -0,0 +1,35 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbRgofEOX4/3gMiraevQKJdIBhYE=
+github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag=
+gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/github.com/go-macaron/i18n/i18n.go b/vendor/gitea.com/macaron/i18n/i18n.go
similarity index 98%
rename from vendor/github.com/go-macaron/i18n/i18n.go
rename to vendor/gitea.com/macaron/i18n/i18n.go
index 4f386a0bbd..fd114a5bf7 100644
--- a/vendor/github.com/go-macaron/i18n/i18n.go
+++ b/vendor/gitea.com/macaron/i18n/i18n.go
@@ -20,10 +20,10 @@ import (
 	"path"
 	"strings"
 
-	"github.com/Unknwon/com"
-	"github.com/Unknwon/i18n"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
+	"github.com/unknwon/i18n"
 	"golang.org/x/text/language"
-	"gopkg.in/macaron.v1"
 )
 
 const _VERSION = "0.4.0"
diff --git a/vendor/gitea.com/macaron/inject/.drone.yml b/vendor/gitea.com/macaron/inject/.drone.yml
new file mode 100644
index 0000000000..4db3bab535
--- /dev/null
+++ b/vendor/gitea.com/macaron/inject/.drone.yml
@@ -0,0 +1,20 @@
+kind: pipeline
+name: go1-1-1
+
+steps:
+- name: test
+  image: golang:1.11
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
+
+---
+kind: pipeline
+name: go1-1-2
+
+steps:
+- name: test
+  image: golang:1.12
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
diff --git a/vendor/github.com/go-macaron/inject/LICENSE b/vendor/gitea.com/macaron/inject/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/inject/LICENSE
rename to vendor/gitea.com/macaron/inject/LICENSE
diff --git a/vendor/github.com/go-macaron/inject/README.md b/vendor/gitea.com/macaron/inject/README.md
similarity index 63%
rename from vendor/github.com/go-macaron/inject/README.md
rename to vendor/gitea.com/macaron/inject/README.md
index c65c76955d..5ed58bae52 100644
--- a/vendor/github.com/go-macaron/inject/README.md
+++ b/vendor/gitea.com/macaron/inject/README.md
@@ -1,4 +1,4 @@
-# inject [![Build Status](https://travis-ci.org/go-macaron/inject.svg?branch=master)](https://travis-ci.org/go-macaron/inject) [![](http://gocover.io/_badge/github.com/go-macaron/inject)](http://gocover.io/github.com/go-macaron/inject)
+# inject [![Build Status](https://drone.gitea.com/api/badges/macaron/inject/status.svg)](https://drone.gitea.com/macaron/inject) [![](http://gocover.io/_badge/gitea.com/macaron/inject)](http://gocover.io/gitea.com/macaron/inject)
 
 Package inject provides utilities for mapping and injecting dependencies in various ways.
 
diff --git a/vendor/gitea.com/macaron/inject/go.mod b/vendor/gitea.com/macaron/inject/go.mod
new file mode 100644
index 0000000000..7d885b7008
--- /dev/null
+++ b/vendor/gitea.com/macaron/inject/go.mod
@@ -0,0 +1,5 @@
+module gitea.com/macaron/inject
+
+go 1.11
+
+require github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
diff --git a/vendor/gitea.com/macaron/inject/go.sum b/vendor/gitea.com/macaron/inject/go.sum
new file mode 100644
index 0000000000..6a9ccb166c
--- /dev/null
+++ b/vendor/gitea.com/macaron/inject/go.sum
@@ -0,0 +1,13 @@
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
diff --git a/vendor/github.com/go-macaron/inject/inject.go b/vendor/gitea.com/macaron/inject/inject.go
similarity index 100%
rename from vendor/github.com/go-macaron/inject/inject.go
rename to vendor/gitea.com/macaron/inject/inject.go
diff --git a/vendor/gitea.com/macaron/macaron/.drone.yml b/vendor/gitea.com/macaron/macaron/.drone.yml
new file mode 100644
index 0000000000..06ecc018e3
--- /dev/null
+++ b/vendor/gitea.com/macaron/macaron/.drone.yml
@@ -0,0 +1,10 @@
+kind: pipeline
+name: default
+
+steps:
+- name: test
+  image: golang:1.12
+  commands:
+  - go get -u
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
diff --git a/vendor/gopkg.in/macaron.v1/.gitignore b/vendor/gitea.com/macaron/macaron/.gitignore
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/.gitignore
rename to vendor/gitea.com/macaron/macaron/.gitignore
diff --git a/vendor/gopkg.in/macaron.v1/LICENSE b/vendor/gitea.com/macaron/macaron/LICENSE
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/LICENSE
rename to vendor/gitea.com/macaron/macaron/LICENSE
diff --git a/vendor/gopkg.in/macaron.v1/README.md b/vendor/gitea.com/macaron/macaron/README.md
similarity index 96%
rename from vendor/gopkg.in/macaron.v1/README.md
rename to vendor/gitea.com/macaron/macaron/README.md
index d2613c886e..97b782ed87 100644
--- a/vendor/gopkg.in/macaron.v1/README.md
+++ b/vendor/gitea.com/macaron/macaron/README.md
@@ -11,14 +11,14 @@ The minimum requirement of Go is **1.6**.
 
 To install Macaron:
 
-	go get gopkg.in/macaron.v1
+	go get gitea.com/macaron/macaron
 
 The very basic usage of Macaron:
 
 ```go
 package main
 
-import "gopkg.in/macaron.v1"
+import "gitea.com/macaron/macaron"
 
 func main() {
 	m := macaron.Classic()
@@ -79,7 +79,7 @@ There are already many [middlewares](https://github.com/go-macaron) to simplify
 
 ## Getting Help
 
-- [API Reference](https://gowalker.org/gopkg.in/macaron.v1)
+- [API Reference](https://gowalker.org/gitea.com/macaron/macaron)
 - [Documentation](https://go-macaron.com)
 - [FAQs](https://go-macaron.com/docs/faqs)
 
diff --git a/vendor/gopkg.in/macaron.v1/context.go b/vendor/gitea.com/macaron/macaron/context.go
similarity index 98%
rename from vendor/gopkg.in/macaron.v1/context.go
rename to vendor/gitea.com/macaron/macaron/context.go
index 063f9e0148..a3f2c69e03 100644
--- a/vendor/gopkg.in/macaron.v1/context.go
+++ b/vendor/gitea.com/macaron/macaron/context.go
@@ -31,8 +31,8 @@ import (
 	"strings"
 	"time"
 
-	"github.com/Unknwon/com"
-	"github.com/go-macaron/inject"
+	"gitea.com/macaron/inject"
+	"github.com/unknwon/com"
 	"golang.org/x/crypto/pbkdf2"
 )
 
@@ -162,12 +162,12 @@ func (ctx *Context) renderHTML(status int, setName, tplName string, data ...inte
 	}
 }
 
-// HTML calls Render.HTML but allows less arguments.
+// HTML renders the HTML with default template set.
 func (ctx *Context) HTML(status int, name string, data ...interface{}) {
 	ctx.renderHTML(status, DEFAULT_TPL_SET_NAME, name, data...)
 }
 
-// HTML calls Render.HTMLSet but allows less arguments.
+// HTMLSet renders the HTML with given template set name.
 func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interface{}) {
 	ctx.renderHTML(status, setName, tplName, data...)
 }
diff --git a/vendor/gitea.com/macaron/macaron/go.mod b/vendor/gitea.com/macaron/macaron/go.mod
new file mode 100644
index 0000000000..e256ae8f63
--- /dev/null
+++ b/vendor/gitea.com/macaron/macaron/go.mod
@@ -0,0 +1,11 @@
+module gitea.com/macaron/macaron
+
+go 1.11
+
+require (
+	gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
+	gopkg.in/ini.v1 v1.44.0
+)
diff --git a/vendor/gitea.com/macaron/macaron/go.sum b/vendor/gitea.com/macaron/macaron/go.sum
new file mode 100644
index 0000000000..7dfc6ea74e
--- /dev/null
+++ b/vendor/gitea.com/macaron/macaron/go.sum
@@ -0,0 +1,27 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/gopkg.in/macaron.v1/logger.go b/vendor/gitea.com/macaron/macaron/logger.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/logger.go
rename to vendor/gitea.com/macaron/macaron/logger.go
diff --git a/vendor/gopkg.in/macaron.v1/macaron.go b/vendor/gitea.com/macaron/macaron/macaron.go
similarity index 99%
rename from vendor/gopkg.in/macaron.v1/macaron.go
rename to vendor/gitea.com/macaron/macaron/macaron.go
index 715076ac13..17b5783702 100644
--- a/vendor/gopkg.in/macaron.v1/macaron.go
+++ b/vendor/gitea.com/macaron/macaron/macaron.go
@@ -26,10 +26,10 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 	"gopkg.in/ini.v1"
 
-	"github.com/go-macaron/inject"
+	"gitea.com/macaron/inject"
 )
 
 const _VERSION = "1.3.2.1216"
diff --git a/vendor/gopkg.in/macaron.v1/macaronlogo.png b/vendor/gitea.com/macaron/macaron/macaronlogo.png
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/macaronlogo.png
rename to vendor/gitea.com/macaron/macaron/macaronlogo.png
diff --git a/vendor/gopkg.in/macaron.v1/recovery.go b/vendor/gitea.com/macaron/macaron/recovery.go
similarity index 99%
rename from vendor/gopkg.in/macaron.v1/recovery.go
rename to vendor/gitea.com/macaron/macaron/recovery.go
index ea3bdac045..49c3096d64 100644
--- a/vendor/gopkg.in/macaron.v1/recovery.go
+++ b/vendor/gitea.com/macaron/macaron/recovery.go
@@ -23,7 +23,7 @@ import (
 	"net/http"
 	"runtime"
 
-	"github.com/go-macaron/inject"
+	"gitea.com/macaron/inject"
 )
 
 const (
diff --git a/vendor/gopkg.in/macaron.v1/render.go b/vendor/gitea.com/macaron/macaron/render.go
similarity index 99%
rename from vendor/gopkg.in/macaron.v1/render.go
rename to vendor/gitea.com/macaron/macaron/render.go
index f45e431240..6f2e93f21b 100644
--- a/vendor/gopkg.in/macaron.v1/render.go
+++ b/vendor/gitea.com/macaron/macaron/render.go
@@ -31,7 +31,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 const (
diff --git a/vendor/gopkg.in/macaron.v1/response_writer.go b/vendor/gitea.com/macaron/macaron/response_writer.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/response_writer.go
rename to vendor/gitea.com/macaron/macaron/response_writer.go
diff --git a/vendor/gopkg.in/macaron.v1/return_handler.go b/vendor/gitea.com/macaron/macaron/return_handler.go
similarity index 98%
rename from vendor/gopkg.in/macaron.v1/return_handler.go
rename to vendor/gitea.com/macaron/macaron/return_handler.go
index db6eec3e9f..2e37c78a32 100644
--- a/vendor/gopkg.in/macaron.v1/return_handler.go
+++ b/vendor/gitea.com/macaron/macaron/return_handler.go
@@ -19,7 +19,7 @@ import (
 	"net/http"
 	"reflect"
 
-	"github.com/go-macaron/inject"
+	"gitea.com/macaron/inject"
 )
 
 // ReturnHandler is a service that Martini provides that is called
diff --git a/vendor/gopkg.in/macaron.v1/router.go b/vendor/gitea.com/macaron/macaron/router.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/router.go
rename to vendor/gitea.com/macaron/macaron/router.go
diff --git a/vendor/gopkg.in/macaron.v1/static.go b/vendor/gitea.com/macaron/macaron/static.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/static.go
rename to vendor/gitea.com/macaron/macaron/static.go
diff --git a/vendor/gopkg.in/macaron.v1/tree.go b/vendor/gitea.com/macaron/macaron/tree.go
similarity index 99%
rename from vendor/gopkg.in/macaron.v1/tree.go
rename to vendor/gitea.com/macaron/macaron/tree.go
index c351b9452b..0ab094dd68 100644
--- a/vendor/gopkg.in/macaron.v1/tree.go
+++ b/vendor/gitea.com/macaron/macaron/tree.go
@@ -18,7 +18,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 type patternType int8
diff --git a/vendor/gopkg.in/macaron.v1/util_go17.go b/vendor/gitea.com/macaron/macaron/util_go17.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/util_go17.go
rename to vendor/gitea.com/macaron/macaron/util_go17.go
diff --git a/vendor/gopkg.in/macaron.v1/util_go18.go b/vendor/gitea.com/macaron/macaron/util_go18.go
similarity index 100%
rename from vendor/gopkg.in/macaron.v1/util_go18.go
rename to vendor/gitea.com/macaron/macaron/util_go18.go
diff --git a/vendor/gitea.com/macaron/session/.drone.yml b/vendor/gitea.com/macaron/session/.drone.yml
new file mode 100644
index 0000000000..717ada4b8f
--- /dev/null
+++ b/vendor/gitea.com/macaron/session/.drone.yml
@@ -0,0 +1,11 @@
+kind: pipeline
+name: default
+
+steps:
+- name: test
+  image: golang:1.12
+  environment:
+      GOPROXY: https://goproxy.cn
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
\ No newline at end of file
diff --git a/vendor/gitea.com/macaron/session/.gitignore b/vendor/gitea.com/macaron/session/.gitignore
new file mode 100644
index 0000000000..834722925c
--- /dev/null
+++ b/vendor/gitea.com/macaron/session/.gitignore
@@ -0,0 +1,4 @@
+ledis/tmp.db
+nodb/tmp.db
+/vendor
+/.idea
diff --git a/vendor/github.com/go-macaron/captcha/LICENSE b/vendor/gitea.com/macaron/session/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/captcha/LICENSE
rename to vendor/gitea.com/macaron/session/LICENSE
diff --git a/vendor/gitea.com/macaron/session/README.md b/vendor/gitea.com/macaron/session/README.md
new file mode 100644
index 0000000000..ebbbff5453
--- /dev/null
+++ b/vendor/gitea.com/macaron/session/README.md
@@ -0,0 +1,22 @@
+# session
+
+Middleware session provides session management for [Macaron](https://gitea.com/macaron/macaron). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb.
+
+### Installation
+
+The minimum requirement of Go is 1.11 .
+
+	go get gitea.com/macaron/session
+
+## Getting Help
+
+- [API Reference](https://gowalker.org/gitea.com/macaron/session)
+- [Documentation](https://go-macaron.com/docs/middlewares/session)
+
+## Credits
+
+This package is a modified version of [go-macaron/session](github.com/go-macaron/session).
+
+## License
+
+This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/session/couchbase/couchbase.go b/vendor/gitea.com/macaron/session/couchbase/couchbase.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/couchbase/couchbase.go
rename to vendor/gitea.com/macaron/session/couchbase/couchbase.go
index 8001fd15f1..8f5a32f969 100644
--- a/vendor/github.com/go-macaron/session/couchbase/couchbase.go
+++ b/vendor/gitea.com/macaron/session/couchbase/couchbase.go
@@ -19,9 +19,8 @@ import (
 	"strings"
 	"sync"
 
+	"gitea.com/macaron/session"
 	"github.com/couchbaselabs/go-couchbase"
-
-	"github.com/go-macaron/session"
 )
 
 // CouchbaseSessionStore represents a couchbase session store implementation.
@@ -172,8 +171,8 @@ func (p *CouchbaseProvider) Exist(sid string) bool {
 	}
 }
 
-// Destory deletes a session by session ID.
-func (p *CouchbaseProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *CouchbaseProvider) Destroy(sid string) error {
 	p.b = p.getBucket()
 	defer p.b.Close()
 
diff --git a/vendor/github.com/go-macaron/session/file.go b/vendor/gitea.com/macaron/session/file.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/file.go
rename to vendor/gitea.com/macaron/session/file.go
index 64b47f2b00..3e575564ee 100644
--- a/vendor/github.com/go-macaron/session/file.go
+++ b/vendor/gitea.com/macaron/session/file.go
@@ -25,7 +25,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 // FileStore represents a file session store implementation.
@@ -170,8 +170,8 @@ func (p *FileProvider) Exist(sid string) bool {
 	return com.IsFile(p.filepath(sid))
 }
 
-// Destory deletes a session by session ID.
-func (p *FileProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *FileProvider) Destroy(sid string) error {
 	p.lock.Lock()
 	defer p.lock.Unlock()
 	return os.Remove(p.filepath(sid))
diff --git a/vendor/github.com/go-macaron/session/flash.go b/vendor/gitea.com/macaron/session/flash.go
similarity index 98%
rename from vendor/github.com/go-macaron/session/flash.go
rename to vendor/gitea.com/macaron/session/flash.go
index 99aae71e22..93c461d47a 100644
--- a/vendor/github.com/go-macaron/session/flash.go
+++ b/vendor/gitea.com/macaron/session/flash.go
@@ -17,7 +17,7 @@ package session
 import (
 	"net/url"
 
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 type Flash struct {
diff --git a/vendor/gitea.com/macaron/session/go.mod b/vendor/gitea.com/macaron/session/go.mod
new file mode 100644
index 0000000000..626199661d
--- /dev/null
+++ b/vendor/gitea.com/macaron/session/go.mod
@@ -0,0 +1,32 @@
+module gitea.com/macaron/session
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668
+	github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d // indirect
+	github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b // indirect
+	github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7
+	github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
+	github.com/edsrzf/mmap-go v1.0.0 // indirect
+	github.com/go-redis/redis v6.15.2+incompatible
+	github.com/go-sql-driver/mysql v1.4.1
+	github.com/lib/pq v1.2.0
+	github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de // indirect
+	github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af
+	github.com/mattn/go-sqlite3 v1.11.0 // indirect
+	github.com/pelletier/go-toml v1.4.0 // indirect
+	github.com/pkg/errors v0.8.1 // indirect
+	github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
+	github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d // indirect
+	github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92
+	github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/stretchr/testify v1.3.0 // indirect
+	github.com/syndtr/goleveldb v1.0.0 // indirect
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
+	google.golang.org/appengine v1.6.1 // indirect
+	gopkg.in/ini.v1 v1.44.0
+)
diff --git a/vendor/gitea.com/macaron/session/go.sum b/vendor/gitea.com/macaron/session/go.sum
new file mode 100644
index 0000000000..dc7dc6f34a
--- /dev/null
+++ b/vendor/gitea.com/macaron/session/go.sum
@@ -0,0 +1,116 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
+github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
+github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d h1:XMf4E1U+b9E3ElF0mjvfXZdflBRZz4gLp16nQ/QSHQM=
+github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b h1:bZ9rKU2/V8sY+NulSfxDOnXTWcs1rySqdF1sVepihvo=
+github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
+github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8=
+github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
+github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
+github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
+github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af h1:UaWHNBdukWrSG3DRvHFR/hyfg681fceqQDYVTBncKfQ=
+github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
+github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 h1:qvsJwGToa8rxb42cDRhkbKeX2H5N8BH+s2aUikGt8mI=
+github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs=
+github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c h1:+EXw7AwNOKzPFXMZ1yNjO40aWCh3PIquJB2fYlv9wcs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/go-macaron/session/memcache/memcache.go b/vendor/gitea.com/macaron/session/memcache/memcache.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/memcache/memcache.go
rename to vendor/gitea.com/macaron/session/memcache/memcache.go
index 496939398b..ff12097542 100644
--- a/vendor/github.com/go-macaron/session/memcache/memcache.go
+++ b/vendor/gitea.com/macaron/session/memcache/memcache.go
@@ -20,9 +20,8 @@ import (
 	"strings"
 	"sync"
 
+	"gitea.com/macaron/session"
 	"github.com/bradfitz/gomemcache/memcache"
-
-	"github.com/go-macaron/session"
 )
 
 // MemcacheStore represents a memcache session store implementation.
@@ -152,8 +151,8 @@ func (p *MemcacheProvider) Exist(sid string) bool {
 	return err == nil
 }
 
-// Destory deletes a session by session ID.
-func (p *MemcacheProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *MemcacheProvider) Destroy(sid string) error {
 	return p.c.Delete(sid)
 }
 
diff --git a/vendor/github.com/go-macaron/session/memcache/memcache.goconvey b/vendor/gitea.com/macaron/session/memcache/memcache.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/session/memcache/memcache.goconvey
rename to vendor/gitea.com/macaron/session/memcache/memcache.goconvey
diff --git a/vendor/github.com/go-macaron/session/memory.go b/vendor/gitea.com/macaron/session/memory.go
similarity index 92%
rename from vendor/github.com/go-macaron/session/memory.go
rename to vendor/gitea.com/macaron/session/memory.go
index 4ad929352e..fbb5b8013f 100644
--- a/vendor/github.com/go-macaron/session/memory.go
+++ b/vendor/gitea.com/macaron/session/memory.go
@@ -145,8 +145,8 @@ func (p *MemProvider) Exist(sid string) bool {
 	return ok
 }
 
-// Destory deletes a session by session ID.
-func (p *MemProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *MemProvider) Destroy(sid string) error {
 	p.lock.Lock()
 	defer p.lock.Unlock()
 
@@ -171,7 +171,7 @@ func (p *MemProvider) Regenerate(oldsid, sid string) (RawStore, error) {
 		return nil, err
 	}
 
-	if err = p.Destory(oldsid); err != nil {
+	if err = p.Destroy(oldsid); err != nil {
 		return nil, err
 	}
 
diff --git a/vendor/github.com/go-macaron/session/mysql/mysql.go b/vendor/gitea.com/macaron/session/mysql/mysql.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/mysql/mysql.go
rename to vendor/gitea.com/macaron/session/mysql/mysql.go
index 7bde37445e..da5079b24a 100644
--- a/vendor/github.com/go-macaron/session/mysql/mysql.go
+++ b/vendor/gitea.com/macaron/session/mysql/mysql.go
@@ -22,9 +22,8 @@ import (
 	"sync"
 	"time"
 
+	"gitea.com/macaron/session"
 	_ "github.com/go-sql-driver/mysql"
-
-	"github.com/go-macaron/session"
 )
 
 // MysqlStore represents a mysql session store implementation.
@@ -154,8 +153,8 @@ func (p *MysqlProvider) Exist(sid string) bool {
 	return err != sql.ErrNoRows
 }
 
-// Destory deletes a session by session ID.
-func (p *MysqlProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *MysqlProvider) Destroy(sid string) error {
 	_, err := p.c.Exec("DELETE FROM session WHERE `key`=?", sid)
 	return err
 }
diff --git a/vendor/github.com/go-macaron/session/mysql/mysql.goconvey b/vendor/gitea.com/macaron/session/mysql/mysql.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/session/mysql/mysql.goconvey
rename to vendor/gitea.com/macaron/session/mysql/mysql.goconvey
diff --git a/vendor/github.com/go-macaron/session/nodb/nodb.go b/vendor/gitea.com/macaron/session/nodb/nodb.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/nodb/nodb.go
rename to vendor/gitea.com/macaron/session/nodb/nodb.go
index 8b5a711693..db174e7ed1 100644
--- a/vendor/github.com/go-macaron/session/nodb/nodb.go
+++ b/vendor/gitea.com/macaron/session/nodb/nodb.go
@@ -18,10 +18,9 @@ import (
 	"fmt"
 	"sync"
 
+	"gitea.com/macaron/session"
 	"github.com/lunny/nodb"
 	"github.com/lunny/nodb/config"
-
-	"github.com/go-macaron/session"
 )
 
 // NodbStore represents a nodb session store implementation.
@@ -154,8 +153,8 @@ func (p *NodbProvider) Exist(sid string) bool {
 	return err == nil && count > 0
 }
 
-// Destory deletes a session by session ID.
-func (p *NodbProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *NodbProvider) Destroy(sid string) error {
 	_, err := p.c.Del([]byte(sid))
 	return err
 }
diff --git a/vendor/github.com/go-macaron/session/nodb/nodb.goconvey b/vendor/gitea.com/macaron/session/nodb/nodb.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/session/nodb/nodb.goconvey
rename to vendor/gitea.com/macaron/session/nodb/nodb.goconvey
diff --git a/vendor/github.com/go-macaron/session/postgres/postgres.go b/vendor/gitea.com/macaron/session/postgres/postgres.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/postgres/postgres.go
rename to vendor/gitea.com/macaron/session/postgres/postgres.go
index f1e034b501..c307241a3c 100644
--- a/vendor/github.com/go-macaron/session/postgres/postgres.go
+++ b/vendor/gitea.com/macaron/session/postgres/postgres.go
@@ -22,9 +22,8 @@ import (
 	"sync"
 	"time"
 
+	"gitea.com/macaron/session"
 	_ "github.com/lib/pq"
-
-	"github.com/go-macaron/session"
 )
 
 // PostgresStore represents a postgres session store implementation.
@@ -155,8 +154,8 @@ func (p *PostgresProvider) Exist(sid string) bool {
 	return err != sql.ErrNoRows
 }
 
-// Destory deletes a session by session ID.
-func (p *PostgresProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *PostgresProvider) Destroy(sid string) error {
 	_, err := p.c.Exec("DELETE FROM session WHERE key=$1", sid)
 	return err
 }
diff --git a/vendor/github.com/go-macaron/session/postgres/postgres.goconvey b/vendor/gitea.com/macaron/session/postgres/postgres.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/session/postgres/postgres.goconvey
rename to vendor/gitea.com/macaron/session/postgres/postgres.goconvey
diff --git a/vendor/github.com/go-macaron/session/redis/redis.go b/vendor/gitea.com/macaron/session/redis/redis.go
similarity index 91%
rename from vendor/github.com/go-macaron/session/redis/redis.go
rename to vendor/gitea.com/macaron/session/redis/redis.go
index 2d7fe98405..5f242d6b37 100644
--- a/vendor/github.com/go-macaron/session/redis/redis.go
+++ b/vendor/gitea.com/macaron/session/redis/redis.go
@@ -21,11 +21,10 @@ import (
 	"sync"
 	"time"
 
-	"github.com/Unknwon/com"
+	"gitea.com/macaron/session"
+	"github.com/go-redis/redis"
+	"github.com/unknwon/com"
 	"gopkg.in/ini.v1"
-	"gopkg.in/redis.v2"
-
-	"github.com/go-macaron/session"
 )
 
 // RedisStore represents a redis session store implementation.
@@ -91,7 +90,7 @@ func (s *RedisStore) Release() error {
 		return err
 	}
 
-	return s.c.SetEx(s.prefix+s.sid, s.duration, string(data)).Err()
+	return s.c.Set(s.prefix+s.sid, string(data), s.duration).Err()
 }
 
 // Flush deletes all session data.
@@ -135,7 +134,7 @@ func (p *RedisProvider) Init(maxlifetime int64, configs string) (err error) {
 		case "password":
 			opt.Password = v
 		case "db":
-			opt.DB = com.StrTo(v).MustInt64()
+			opt.DB = com.StrTo(v).MustInt()
 		case "pool_size":
 			opt.PoolSize = com.StrTo(v).MustInt()
 		case "idle_timeout":
@@ -158,7 +157,7 @@ func (p *RedisProvider) Init(maxlifetime int64, configs string) (err error) {
 func (p *RedisProvider) Read(sid string) (session.RawStore, error) {
 	psid := p.prefix + sid
 	if !p.Exist(sid) {
-		if err := p.c.SetEx(psid, p.duration, "").Err(); err != nil {
+		if err := p.c.Set(psid, "", p.duration).Err(); err != nil {
 			return nil, err
 		}
 	}
@@ -182,12 +181,12 @@ func (p *RedisProvider) Read(sid string) (session.RawStore, error) {
 
 // Exist returns true if session with given ID exists.
 func (p *RedisProvider) Exist(sid string) bool {
-	has, err := p.c.Exists(p.prefix + sid).Result()
-	return err == nil && has
+	v, err := p.c.Exists(p.prefix + sid).Result()
+	return err == nil && v == 1
 }
 
-// Destory deletes a session by session ID.
-func (p *RedisProvider) Destory(sid string) error {
+// Destroy deletes a session by session ID.
+func (p *RedisProvider) Destroy(sid string) error {
 	return p.c.Del(p.prefix + sid).Err()
 }
 
@@ -200,7 +199,7 @@ func (p *RedisProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err
 		return nil, fmt.Errorf("new sid '%s' already exists", sid)
 	} else if !p.Exist(oldsid) {
 		// Make a fake old session.
-		if err = p.c.SetEx(poldsid, p.duration, "").Err(); err != nil {
+		if err = p.c.Set(poldsid, "", p.duration).Err(); err != nil {
 			return nil, err
 		}
 	}
diff --git a/vendor/github.com/go-macaron/session/redis/redis.goconvey b/vendor/gitea.com/macaron/session/redis/redis.goconvey
similarity index 100%
rename from vendor/github.com/go-macaron/session/redis/redis.goconvey
rename to vendor/gitea.com/macaron/session/redis/redis.goconvey
diff --git a/vendor/github.com/go-macaron/session/session.go b/vendor/gitea.com/macaron/session/session.go
similarity index 97%
rename from vendor/github.com/go-macaron/session/session.go
rename to vendor/gitea.com/macaron/session/session.go
index 97fa56ede6..93f18342d0 100644
--- a/vendor/github.com/go-macaron/session/session.go
+++ b/vendor/gitea.com/macaron/session/session.go
@@ -24,7 +24,7 @@ import (
 	"net/url"
 	"time"
 
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 const _VERSION = "0.6.0"
@@ -54,8 +54,8 @@ type Store interface {
 	RawStore
 	// Read returns raw session store by session ID.
 	Read(string) (RawStore, error)
-	// Destory deletes a session.
-	Destory(*macaron.Context) error
+	// Destroy deletes a session.
+	Destroy(*macaron.Context) error
 	// RegenerateId regenerates a session store from old session ID to new one.
 	RegenerateId(*macaron.Context) (RawStore, error)
 	// Count counts and returns number of sessions.
@@ -209,8 +209,8 @@ type Provider interface {
 	Read(sid string) (RawStore, error)
 	// Exist returns true if session with given ID exists.
 	Exist(sid string) bool
-	// Destory deletes a session by session ID.
-	Destory(sid string) error
+	// Destroy deletes a session by session ID.
+	Destroy(sid string) error
 	// Regenerate regenerates a session store from old session ID to new one.
 	Regenerate(oldsid, sid string) (RawStore, error)
 	// Count counts and returns number of sessions.
@@ -318,8 +318,8 @@ func (m *Manager) Read(sid string) (RawStore, error) {
 	return m.provider.Read(sid)
 }
 
-// Destory deletes a session by given ID.
-func (m *Manager) Destory(ctx *macaron.Context) error {
+// Destroy deletes a session by given ID.
+func (m *Manager) Destroy(ctx *macaron.Context) error {
 	sid := ctx.GetCookie(m.opt.CookieName)
 	if len(sid) == 0 {
 		return nil
@@ -329,7 +329,7 @@ func (m *Manager) Destory(ctx *macaron.Context) error {
 		return err
 	}
 
-	if err := m.provider.Destory(sid); err != nil {
+	if err := m.provider.Destroy(sid); err != nil {
 		return err
 	}
 	cookie := &http.Cookie{
diff --git a/vendor/github.com/go-macaron/session/utils.go b/vendor/gitea.com/macaron/session/utils.go
similarity index 98%
rename from vendor/github.com/go-macaron/session/utils.go
rename to vendor/gitea.com/macaron/session/utils.go
index 90ca38064b..762b978cdf 100644
--- a/vendor/github.com/go-macaron/session/utils.go
+++ b/vendor/gitea.com/macaron/session/utils.go
@@ -21,7 +21,7 @@ import (
 	"encoding/gob"
 	"io"
 
-	"github.com/Unknwon/com"
+	"github.com/unknwon/com"
 )
 
 func init() {
diff --git a/vendor/gitea.com/macaron/toolbox/.drone.yml b/vendor/gitea.com/macaron/toolbox/.drone.yml
new file mode 100644
index 0000000000..39499f444a
--- /dev/null
+++ b/vendor/gitea.com/macaron/toolbox/.drone.yml
@@ -0,0 +1,9 @@
+kind: pipeline
+name: default
+
+steps:
+- name: test
+  image: golang:1.11
+  commands:
+  - go build -v
+  - go test -v -race -coverprofile=coverage.txt -covermode=atomic
diff --git a/vendor/github.com/go-macaron/toolbox/.gitignore b/vendor/gitea.com/macaron/toolbox/.gitignore
similarity index 100%
rename from vendor/github.com/go-macaron/toolbox/.gitignore
rename to vendor/gitea.com/macaron/toolbox/.gitignore
diff --git a/vendor/github.com/go-macaron/csrf/LICENSE b/vendor/gitea.com/macaron/toolbox/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/csrf/LICENSE
rename to vendor/gitea.com/macaron/toolbox/LICENSE
diff --git a/vendor/github.com/go-macaron/toolbox/README.md b/vendor/gitea.com/macaron/toolbox/README.md
similarity index 89%
rename from vendor/github.com/go-macaron/toolbox/README.md
rename to vendor/gitea.com/macaron/toolbox/README.md
index 72769a06ea..75055d5f07 100644
--- a/vendor/github.com/go-macaron/toolbox/README.md
+++ b/vendor/gitea.com/macaron/toolbox/README.md
@@ -1,21 +1,22 @@
 toolbox
 =======
 
-Middleware toolbox provides health chcek, pprof, profile and statistic services for [Macaron](https://github.com/go-macaron/macaron).
+Middleware toolbox provides health chcek, pprof, profile and statistic services for [Macaron](https://gitea.com/macaron/macaron).
 
-[API Reference](https://gowalker.org/github.com/go-macaron/toolbox)
+[![Build Status](https://drone.gitea.com/api/badges/macaron/toolbox/status.svg)](https://drone.gitea.com/macaron/toolbox) 
+[API Reference](https://gowalker.org/gitea.com/macaron/toolbox)
 
 ### Installation
 
-	go get github.com/go-macaron/toolbox
+	go get gitea.com/macaron/toolbox
 	
 ## Usage
 
 ```go
 // main.go
 import (
-	"gopkg.in/macaron.v1"
-	"github.com/go-macaron/toolbox"
+	"gitea.com/macaron/macaron"
+	"gitea.com/macaron/toolbox"
 )
 
 func main() {
@@ -73,7 +74,7 @@ import (
 	"os"
 	"time"
 	//...
-	"github.com/go-macaron/toolbox"
+	"gitea.com/macaron/toolbox"
 )
 
 func main() {
diff --git a/vendor/gitea.com/macaron/toolbox/go.mod b/vendor/gitea.com/macaron/toolbox/go.mod
new file mode 100644
index 0000000000..f54b8074ca
--- /dev/null
+++ b/vendor/gitea.com/macaron/toolbox/go.mod
@@ -0,0 +1,9 @@
+module gitea.com/macaron/toolbox
+
+go 1.11
+
+require (
+	gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+)
diff --git a/vendor/gitea.com/macaron/toolbox/go.sum b/vendor/gitea.com/macaron/toolbox/go.sum
new file mode 100644
index 0000000000..56302b6a5f
--- /dev/null
+++ b/vendor/gitea.com/macaron/toolbox/go.sum
@@ -0,0 +1,30 @@
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
+gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
+gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
+gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/github.com/go-macaron/toolbox/healthcheck.go b/vendor/gitea.com/macaron/toolbox/healthcheck.go
similarity index 100%
rename from vendor/github.com/go-macaron/toolbox/healthcheck.go
rename to vendor/gitea.com/macaron/toolbox/healthcheck.go
diff --git a/vendor/github.com/go-macaron/toolbox/profile.go b/vendor/gitea.com/macaron/toolbox/profile.go
similarity index 98%
rename from vendor/github.com/go-macaron/toolbox/profile.go
rename to vendor/gitea.com/macaron/toolbox/profile.go
index 1eb2cdfe53..359a87fde4 100644
--- a/vendor/github.com/go-macaron/toolbox/profile.go
+++ b/vendor/gitea.com/macaron/toolbox/profile.go
@@ -27,8 +27,8 @@ import (
 	"runtime/pprof"
 	"time"
 
-	"github.com/Unknwon/com"
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
+	"github.com/unknwon/com"
 )
 
 var (
diff --git a/vendor/github.com/go-macaron/toolbox/statistic.go b/vendor/gitea.com/macaron/toolbox/statistic.go
similarity index 100%
rename from vendor/github.com/go-macaron/toolbox/statistic.go
rename to vendor/gitea.com/macaron/toolbox/statistic.go
diff --git a/vendor/github.com/go-macaron/toolbox/toolbox.go b/vendor/gitea.com/macaron/toolbox/toolbox.go
similarity index 99%
rename from vendor/github.com/go-macaron/toolbox/toolbox.go
rename to vendor/gitea.com/macaron/toolbox/toolbox.go
index 8c7f03adff..42e565e45b 100644
--- a/vendor/github.com/go-macaron/toolbox/toolbox.go
+++ b/vendor/gitea.com/macaron/toolbox/toolbox.go
@@ -23,7 +23,7 @@ import (
 	"path"
 	"time"
 
-	"gopkg.in/macaron.v1"
+	"gitea.com/macaron/macaron"
 )
 
 const _VERSION = "0.1.4"
diff --git a/vendor/github.com/Unknwon/com/.travis.yml b/vendor/github.com/Unknwon/com/.travis.yml
deleted file mode 100644
index 882eb2d122..0000000000
--- a/vendor/github.com/Unknwon/com/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: go
-
-go:
-  - 1.2
-  - 1.3
-  - 1.4
-  - tip
-
-install: go get -v -t
-
-notifications:
-  email:
-    - u@gogs.io
\ No newline at end of file
diff --git a/vendor/github.com/bradfitz/gomemcache/memcache/memcache.go b/vendor/github.com/bradfitz/gomemcache/memcache/memcache.go
index 7b5442d735..25e88ca261 100644
--- a/vendor/github.com/bradfitz/gomemcache/memcache/memcache.go
+++ b/vendor/github.com/bradfitz/gomemcache/memcache/memcache.go
@@ -23,7 +23,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net"
 
 	"strconv"
@@ -33,7 +32,7 @@ import (
 )
 
 // Similar to:
-// http://code.google.com/appengine/docs/go/memcache/reference.html
+// https://godoc.org/google.golang.org/appengine/memcache
 
 var (
 	// ErrCacheMiss means that a Get failed because the item wasn't present.
@@ -56,7 +55,7 @@ var (
 	ErrNoStats = errors.New("memcache: no statistics available")
 
 	// ErrMalformedKey is returned when an invalid key is used.
-	// Keys must be at maximum 250 bytes long, ASCII, and not
+	// Keys must be at maximum 250 bytes long and not
 	// contain whitespace or control characters.
 	ErrMalformedKey = errors.New("malformed: key is too long or contains invalid characters")
 
@@ -64,14 +63,17 @@ var (
 	ErrNoServers = errors.New("memcache: no servers configured or available")
 )
 
-// DefaultTimeout is the default socket read/write timeout.
-const DefaultTimeout = 100 * time.Millisecond
-
 const (
-	buffered            = 8 // arbitrary buffered channel size, for readability
-	maxIdleConnsPerAddr = 2 // TODO(bradfitz): make this configurable?
+	// DefaultTimeout is the default socket read/write timeout.
+	DefaultTimeout = 100 * time.Millisecond
+
+	// DefaultMaxIdleConns is the default maximum number of idle connections
+	// kept for any single address.
+	DefaultMaxIdleConns = 2
 )
 
+const buffered = 8 // arbitrary buffered channel size, for readability
+
 // resumableError returns true if err is only a protocol-level cache error.
 // This is used to determine whether or not a server connection should
 // be re-used or not. If an error occurs, by default we don't reuse the
@@ -89,7 +91,7 @@ func legalKey(key string) bool {
 		return false
 	}
 	for i := 0; i < len(key); i++ {
-		if key[i] <= ' ' || key[i] > 0x7e {
+		if key[i] <= ' ' || key[i] == 0x7f {
 			return false
 		}
 	}
@@ -133,6 +135,14 @@ type Client struct {
 	// If zero, DefaultTimeout is used.
 	Timeout time.Duration
 
+	// MaxIdleConns specifies the maximum number of idle connections that will
+	// be maintained per address. If less than one, DefaultMaxIdleConns will be
+	// used.
+	//
+	// Consider your expected traffic rates and latency carefully. This should
+	// be set to a number higher than your peak parallel requests.
+	MaxIdleConns int
+
 	selector ServerSelector
 
 	lk       sync.Mutex
@@ -196,7 +206,7 @@ func (c *Client) putFreeConn(addr net.Addr, cn *conn) {
 		c.freeconn = make(map[string][]*conn)
 	}
 	freelist := c.freeconn[addr.String()]
-	if len(freelist) >= maxIdleConnsPerAddr {
+	if len(freelist) >= c.maxIdleConns() {
 		cn.nc.Close()
 		return
 	}
@@ -225,6 +235,13 @@ func (c *Client) netTimeout() time.Duration {
 	return DefaultTimeout
 }
 
+func (c *Client) maxIdleConns() int {
+	if c.MaxIdleConns > 0 {
+		return c.MaxIdleConns
+	}
+	return DefaultMaxIdleConns
+}
+
 // ConnectTimeoutError is the error type used when it takes
 // too long to connect to the desired host. This level of
 // detail can generally be ignored.
@@ -308,8 +325,9 @@ func (c *Client) Get(key string) (item *Item, err error) {
 
 // Touch updates the expiry for the given key. The seconds parameter is either
 // a Unix timestamp or, if seconds is less than 1 month, the number of seconds
-// into the future at which time the item will expire. ErrCacheMiss is returned if the
-// key is not in the cache. The key must be at most 250 bytes in length.
+// into the future at which time the item will expire. Zero means the item has
+// no expiration time. ErrCacheMiss is returned if the key is not in the cache.
+// The key must be at most 250 bytes in length.
 func (c *Client) Touch(key string, seconds int32) (err error) {
 	return c.withKeyAddr(key, func(addr net.Addr) error {
 		return c.touchFromAddr(addr, []string{key}, seconds)
@@ -463,11 +481,14 @@ func parseGetResponse(r *bufio.Reader, cb func(*Item)) error {
 		if err != nil {
 			return err
 		}
-		it.Value, err = ioutil.ReadAll(io.LimitReader(r, int64(size)+2))
+		it.Value = make([]byte, size+2)
+		_, err = io.ReadFull(r, it.Value)
 		if err != nil {
+			it.Value = nil
 			return err
 		}
 		if !bytes.HasSuffix(it.Value, crlf) {
+			it.Value = nil
 			return fmt.Errorf("memcache: corrupt get result read")
 		}
 		it.Value = it.Value[:size]
diff --git a/vendor/github.com/bradfitz/gomemcache/memcache/selector.go b/vendor/github.com/bradfitz/gomemcache/memcache/selector.go
index 10b04d349f..89ad81e0d8 100644
--- a/vendor/github.com/bradfitz/gomemcache/memcache/selector.go
+++ b/vendor/github.com/bradfitz/gomemcache/memcache/selector.go
@@ -41,6 +41,21 @@ type ServerList struct {
 	addrs []net.Addr
 }
 
+// staticAddr caches the Network() and String() values from any net.Addr.
+type staticAddr struct {
+	ntw, str string
+}
+
+func newStaticAddr(a net.Addr) net.Addr {
+	return &staticAddr{
+		ntw: a.Network(),
+		str: a.String(),
+	}
+}
+
+func (s *staticAddr) Network() string { return s.ntw }
+func (s *staticAddr) String() string  { return s.str }
+
 // SetServers changes a ServerList's set of servers at runtime and is
 // safe for concurrent use by multiple goroutines.
 //
@@ -58,13 +73,13 @@ func (ss *ServerList) SetServers(servers ...string) error {
 			if err != nil {
 				return err
 			}
-			naddr[i] = addr
+			naddr[i] = newStaticAddr(addr)
 		} else {
 			tcpaddr, err := net.ResolveTCPAddr("tcp", server)
 			if err != nil {
 				return err
 			}
-			naddr[i] = tcpaddr
+			naddr[i] = newStaticAddr(tcpaddr)
 		}
 	}
 
diff --git a/vendor/github.com/couchbase/gomemcached/client/mc.go b/vendor/github.com/couchbase/gomemcached/client/mc.go
index bd1433ba28..0f1d61e512 100644
--- a/vendor/github.com/couchbase/gomemcached/client/mc.go
+++ b/vendor/github.com/couchbase/gomemcached/client/mc.go
@@ -2,6 +2,7 @@
 package memcached
 
 import (
+	"crypto/tls"
 	"encoding/binary"
 	"fmt"
 	"github.com/couchbase/gomemcached"
@@ -26,11 +27,14 @@ type ClientIface interface {
 	AuthScramSha(user, pass string) (*gomemcached.MCResponse, error)
 	CASNext(vb uint16, k string, exp int, state *CASState) bool
 	CAS(vb uint16, k string, f CasFunc, initexp int) (*gomemcached.MCResponse, error)
+	CollectionsGetCID(scope string, collection string) (*gomemcached.MCResponse, error)
 	Close() error
 	Decr(vb uint16, key string, amt, def uint64, exp int) (uint64, error)
 	Del(vb uint16, key string) (*gomemcached.MCResponse, error)
 	EnableMutationToken() (*gomemcached.MCResponse, error)
 	Get(vb uint16, key string) (*gomemcached.MCResponse, error)
+	GetCollectionsManifest() (*gomemcached.MCResponse, error)
+	GetFromCollection(vb uint16, cid uint32, key string) (*gomemcached.MCResponse, error)
 	GetSubdoc(vb uint16, key string, subPaths []string) (*gomemcached.MCResponse, error)
 	GetAndTouch(vb uint16, key string, exp int) (*gomemcached.MCResponse, error)
 	GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MCResponse, subPaths []string) error
@@ -74,11 +78,19 @@ type Feature uint16
 
 const FeatureMutationToken = Feature(0x04)
 const FeatureXattr = Feature(0x06)
+const FeatureCollections = Feature(0x12)
 const FeatureDataType = Feature(0x0b)
 
+type memcachedConnection interface {
+	io.ReadWriteCloser
+
+	SetReadDeadline(time.Time) error
+	SetDeadline(time.Time) error
+}
+
 // The Client itself.
 type Client struct {
-	conn io.ReadWriteCloser
+	conn memcachedConnection
 	// use uint32 type so that it can be accessed through atomic APIs
 	healthy uint32
 	opaque  uint32
@@ -105,6 +117,15 @@ func Connect(prot, dest string) (rv *Client, err error) {
 	return Wrap(conn)
 }
 
+// Connect to a memcached server using TLS.
+func ConnectTLS(prot, dest string, config *tls.Config) (rv *Client, err error) {
+	conn, err := tls.Dial(prot, dest, config)
+	if err != nil {
+		return nil, err
+	}
+	return Wrap(conn)
+}
+
 func SetDefaultTimeouts(dial, read, write time.Duration) {
 	DefaultDialTimeout = dial
 	DefaultWriteTimeout = write
@@ -115,22 +136,25 @@ func SetDefaultDialTimeout(dial time.Duration) {
 }
 
 func (c *Client) SetKeepAliveOptions(interval time.Duration) {
-	c.conn.(*net.TCPConn).SetKeepAlive(true)
-	c.conn.(*net.TCPConn).SetKeepAlivePeriod(interval)
+	tcpConn, ok := c.conn.(*net.TCPConn)
+	if ok {
+		tcpConn.SetKeepAlive(true)
+		tcpConn.SetKeepAlivePeriod(interval)
+	}
 }
 
 func (c *Client) SetReadDeadline(t time.Time) {
-	c.conn.(*net.TCPConn).SetReadDeadline(t)
+	c.conn.SetReadDeadline(t)
 }
 
 func (c *Client) SetDeadline(t time.Time) {
-	c.conn.(*net.TCPConn).SetDeadline(t)
+	c.conn.SetDeadline(t)
 }
 
 // Wrap an existing transport.
-func Wrap(rwc io.ReadWriteCloser) (rv *Client, err error) {
+func Wrap(conn memcachedConnection) (rv *Client, err error) {
 	client := &Client{
-		conn:   rwc,
+		conn:   conn,
 		hdrBuf: make([]byte, gomemcached.HDR_LEN),
 		opaque: uint32(1),
 	}
@@ -278,6 +302,22 @@ func (c *Client) Get(vb uint16, key string) (*gomemcached.MCResponse, error) {
 	})
 }
 
+// Get the value for a key from a collection, identified by collection id.
+func (c *Client) GetFromCollection(vb uint16, cid uint32, key string) (*gomemcached.MCResponse, error) {
+	keyBytes := []byte(key)
+	encodedCid := make([]byte, binary.MaxVarintLen32)
+	lenEncodedCid := binary.PutUvarint(encodedCid, uint64(cid))
+	encodedKey := make([]byte, 0, lenEncodedCid+len(keyBytes))
+	encodedKey = append(encodedKey, encodedCid[0:lenEncodedCid]...)
+	encodedKey = append(encodedKey, keyBytes...)
+
+	return c.Send(&gomemcached.MCRequest{
+		Opcode:  gomemcached.GET,
+		VBucket: vb,
+		Key:     encodedKey,
+	})
+}
+
 // Get the xattrs, doc value for the input key
 func (c *Client) GetSubdoc(vb uint16, key string, subPaths []string) (*gomemcached.MCResponse, error) {
 
@@ -296,6 +336,33 @@ func (c *Client) GetSubdoc(vb uint16, key string, subPaths []string) (*gomemcach
 	return res, nil
 }
 
+// Retrieve the collections manifest.
+func (c *Client) GetCollectionsManifest() (*gomemcached.MCResponse, error) {
+
+	res, err := c.Send(&gomemcached.MCRequest{
+		Opcode: gomemcached.GET_COLLECTIONS_MANIFEST,
+	})
+
+	if err != nil && IfResStatusError(res) {
+		return res, err
+	}
+	return res, nil
+}
+
+// Retrieve the collections manifest.
+func (c *Client) CollectionsGetCID(scope string, collection string) (*gomemcached.MCResponse, error) {
+
+	res, err := c.Send(&gomemcached.MCRequest{
+		Opcode: gomemcached.COLLECTIONS_GET_CID,
+		Key:    []byte(scope + "." + collection),
+	})
+
+	if err != nil && IfResStatusError(res) {
+		return res, err
+	}
+	return res, nil
+}
+
 // Get the value for a key, and update expiry
 func (c *Client) GetAndTouch(vb uint16, key string, exp int) (*gomemcached.MCResponse, error) {
 	extraBuf := make([]byte, 4)
@@ -425,10 +492,9 @@ func (c *Client) AuthPlain(user, pass string) (*gomemcached.MCResponse, error) {
 
 // select bucket
 func (c *Client) SelectBucket(bucket string) (*gomemcached.MCResponse, error) {
-
 	return c.Send(&gomemcached.MCRequest{
 		Opcode: gomemcached.SELECT_BUCKET,
-		Key:    []byte(fmt.Sprintf("%s", bucket))})
+		Key:    []byte(bucket)})
 }
 
 func (c *Client) store(opcode gomemcached.CommandCode, vb uint16,
diff --git a/vendor/github.com/couchbase/gomemcached/client/upr_feed.go b/vendor/github.com/couchbase/gomemcached/client/upr_feed.go
index dc737e6cc0..95fa12577f 100644
--- a/vendor/github.com/couchbase/gomemcached/client/upr_feed.go
+++ b/vendor/github.com/couchbase/gomemcached/client/upr_feed.go
@@ -53,6 +53,16 @@ type UprEvent struct {
 	AckSize      uint32 // The number of bytes that can be Acked to DCP
 }
 
+type PriorityType string
+
+// high > medium > disabled > low
+const (
+	PriorityDisabled PriorityType = ""
+	PriorityLow      PriorityType = "low"
+	PriorityMed      PriorityType = "medium"
+	PriorityHigh     PriorityType = "high"
+)
+
 // UprStream is per stream data structure over an UPR Connection.
 type UprStream struct {
 	Vbucket   uint16 // Vbucket id
@@ -62,6 +72,27 @@ type UprStream struct {
 	connected bool
 }
 
+type FeedState int
+
+const (
+	FeedStateInitial = iota
+	FeedStateOpened  = iota
+	FeedStateClosed  = iota
+)
+
+func (fs FeedState) String() string {
+	switch fs {
+	case FeedStateInitial:
+		return "Initial"
+	case FeedStateOpened:
+		return "Opened"
+	case FeedStateClosed:
+		return "Closed"
+	default:
+		return "Unknown"
+	}
+}
+
 const (
 	CompressionTypeStartMarker = iota // also means invalid
 	CompressionTypeNone        = iota
@@ -80,6 +111,8 @@ type UprFeatures struct {
 	Xattribute          bool
 	CompressionType     int
 	IncludeDeletionTime bool
+	DcpPriority         PriorityType
+	EnableExpiry        bool
 }
 
 /**
@@ -179,7 +212,7 @@ func (negotiator *vbStreamNegotiator) handleStreamRequest(feed *UprFeed,
 
 	stream, err := negotiator.getStreamFromMap(vbno, opaque)
 	if err != nil {
-		err = fmt.Errorf("Stream not found for vb %d appOpaque %v: %#v", vbno, appOpaque, *pktPtr)
+		err = fmt.Errorf("Stream not found for vb %d: %#v", vbno, *pktPtr)
 		logging.Errorf(err.Error())
 		return nil, err
 	}
@@ -226,8 +259,6 @@ func (negotiator *vbStreamNegotiator) cleanUpVbStreams(vbno uint16) {
 type UprFeed struct {
 	// lock for feed.vbstreams
 	muVbstreams sync.RWMutex
-	// lock for feed.closed
-	muClosed    sync.RWMutex
 	C           <-chan *UprEvent            // Exported channel for receiving UPR events
 	negotiator  vbStreamNegotiator          // Used for pre-vbstreams, concurrent vb stream negotiation
 	vbstreams   map[uint16]*UprStream       // official live vb->stream mapping
@@ -240,12 +271,12 @@ type UprFeed struct {
 	stats       UprStats                    // Stats for upr client
 	transmitCh  chan *gomemcached.MCRequest // transmit command channel
 	transmitCl  chan bool                   //  closer channel for transmit go-routine
-	closed      bool                        // flag indicating whether the feed has been closed
-	// flag indicating whether client of upr feed will send ack to upr feed
 	// if flag is true, upr feed will use ack from client to determine whether/when to send ack to DCP
 	// if flag is false, upr feed will track how many bytes it has sent to client
 	// and use that to determine whether/when to send ack to DCP
 	ackByClient bool
+	feedState   FeedState
+	muFeedState sync.RWMutex
 }
 
 // Exported interface - to allow for mocking
@@ -263,6 +294,8 @@ type UprFeedIface interface {
 	UprOpenWithXATTR(name string, sequence uint32, bufSize uint32) error
 	UprOpenWithFeatures(name string, sequence uint32, bufSize uint32, features UprFeatures) (error, UprFeatures)
 	UprRequestStream(vbno, opaqueMSB uint16, flags uint32, vuuid, startSequence, endSequence, snapStart, snapEnd uint64) error
+	// Set DCP priority on an existing DCP connection. The command is sent asynchronously without waiting for a response
+	SetPriorityAsync(p PriorityType) error
 }
 
 type UprStats struct {
@@ -494,6 +527,31 @@ func (feed *UprFeed) UprOpenWithFeatures(name string, sequence uint32, bufSize u
 	return feed.uprOpen(name, sequence, bufSize, features)
 }
 
+func (feed *UprFeed) SetPriorityAsync(p PriorityType) error {
+	if !feed.isOpen() {
+		// do not send this command if upr feed is not yet open, otherwise it may interfere with
+		// feed start up process, which relies on synchronous message exchange with DCP.
+		return fmt.Errorf("Upr feed is not open. State=%v", feed.getState())
+	}
+
+	return feed.setPriority(p, false /*sync*/)
+}
+
+func (feed *UprFeed) setPriority(p PriorityType, sync bool) error {
+	rq := &gomemcached.MCRequest{
+		Opcode: gomemcached.UPR_CONTROL,
+		Key:    []byte("set_priority"),
+		Body:   []byte(p),
+		Opaque: getUprOpenCtrlOpaque(),
+	}
+	if sync {
+		return sendMcRequestSync(feed.conn, rq)
+	} else {
+		return feed.writeToTransmitCh(rq)
+
+	}
+}
+
 func (feed *UprFeed) uprOpen(name string, sequence uint32, bufSize uint32, features UprFeatures) (err error, activatedFeatures UprFeatures) {
 	mc := feed.conn
 
@@ -561,6 +619,31 @@ func (feed *UprFeed) uprOpen(name string, sequence uint32, bufSize uint32, featu
 	}
 	activatedFeatures.CompressionType = features.CompressionType
 
+	if features.DcpPriority != PriorityDisabled {
+		err = feed.setPriority(features.DcpPriority, true /*sync*/)
+		if err == nil {
+			activatedFeatures.DcpPriority = features.DcpPriority
+		} else {
+			return
+		}
+	}
+
+	if features.EnableExpiry {
+		rq := &gomemcached.MCRequest{
+			Opcode: gomemcached.UPR_CONTROL,
+			Key:    []byte("enable_expiry_opcode"),
+			Body:   []byte("true"),
+			Opaque: getUprOpenCtrlOpaque(),
+		}
+		err = sendMcRequestSync(feed.conn, rq)
+		if err != nil {
+			return
+		}
+		activatedFeatures.EnableExpiry = true
+	}
+
+	// everything is ok so far, set upr feed to open state
+	feed.setOpen()
 	return
 }
 
@@ -988,18 +1071,37 @@ func vbOpaque(opq32 uint32) uint16 {
 
 // Close this UprFeed.
 func (feed *UprFeed) Close() {
-	feed.muClosed.Lock()
-	defer feed.muClosed.Unlock()
-	if !feed.closed {
+	feed.muFeedState.Lock()
+	defer feed.muFeedState.Unlock()
+	if feed.feedState != FeedStateClosed {
 		close(feed.closer)
-		feed.closed = true
+		feed.feedState = FeedStateClosed
 		feed.negotiator.initialize()
 	}
 }
 
 // check if the UprFeed has been closed
 func (feed *UprFeed) Closed() bool {
-	feed.muClosed.RLock()
-	defer feed.muClosed.RUnlock()
-	return feed.closed
+	feed.muFeedState.RLock()
+	defer feed.muFeedState.RUnlock()
+	return feed.feedState == FeedStateClosed
+}
+
+// set upr feed to opened state after initialization is done
+func (feed *UprFeed) setOpen() {
+	feed.muFeedState.Lock()
+	defer feed.muFeedState.Unlock()
+	feed.feedState = FeedStateOpened
+}
+
+func (feed *UprFeed) isOpen() bool {
+	feed.muFeedState.RLock()
+	defer feed.muFeedState.RUnlock()
+	return feed.feedState == FeedStateOpened
+}
+
+func (feed *UprFeed) getState() FeedState {
+	feed.muFeedState.RLock()
+	defer feed.muFeedState.RUnlock()
+	return feed.feedState
 }
diff --git a/vendor/github.com/couchbase/gomemcached/mc_constants.go b/vendor/github.com/couchbase/gomemcached/mc_constants.go
index 1d5027d16c..32f4f51852 100644
--- a/vendor/github.com/couchbase/gomemcached/mc_constants.go
+++ b/vendor/github.com/couchbase/gomemcached/mc_constants.go
@@ -93,9 +93,12 @@ const (
 	OBSERVE_SEQNO = CommandCode(0x91) // Sequence Number based Observe
 	OBSERVE       = CommandCode(0x92)
 
-	GET_META            = CommandCode(0xA0) // Get meta. returns with expiry, flags, cas etc
-	SUBDOC_GET          = CommandCode(0xc5) // Get subdoc. Returns with xattrs
-	SUBDOC_MULTI_LOOKUP = CommandCode(0xd0) // Multi lookup. Doc xattrs and meta.
+	GET_META                 = CommandCode(0xA0) // Get meta. returns with expiry, flags, cas etc
+	GET_COLLECTIONS_MANIFEST = CommandCode(0xba) // Get entire collections manifest.
+	COLLECTIONS_GET_CID      = CommandCode(0xbb) // Get collection id.
+	SUBDOC_GET               = CommandCode(0xc5) // Get subdoc. Returns with xattrs
+	SUBDOC_MULTI_LOOKUP      = CommandCode(0xd0) // Multi lookup. Doc xattrs and meta.
+
 )
 
 // command codes that are counted toward DCP control buffer
@@ -113,29 +116,33 @@ type Status uint16
 
 // Matches with protocol_binary.h as source of truth
 const (
-	SUCCESS         = Status(0x00)
-	KEY_ENOENT      = Status(0x01)
-	KEY_EEXISTS     = Status(0x02)
-	E2BIG           = Status(0x03)
-	EINVAL          = Status(0x04)
-	NOT_STORED      = Status(0x05)
-	DELTA_BADVAL    = Status(0x06)
-	NOT_MY_VBUCKET  = Status(0x07)
-	NO_BUCKET       = Status(0x08)
-	LOCKED          = Status(0x09)
-	AUTH_STALE      = Status(0x1f)
-	AUTH_ERROR      = Status(0x20)
-	AUTH_CONTINUE   = Status(0x21)
-	ERANGE          = Status(0x22)
-	ROLLBACK        = Status(0x23)
-	EACCESS         = Status(0x24)
-	NOT_INITIALIZED = Status(0x25)
-	UNKNOWN_COMMAND = Status(0x81)
-	ENOMEM          = Status(0x82)
-	NOT_SUPPORTED   = Status(0x83)
-	EINTERNAL       = Status(0x84)
-	EBUSY           = Status(0x85)
-	TMPFAIL         = Status(0x86)
+	SUCCESS            = Status(0x00)
+	KEY_ENOENT         = Status(0x01)
+	KEY_EEXISTS        = Status(0x02)
+	E2BIG              = Status(0x03)
+	EINVAL             = Status(0x04)
+	NOT_STORED         = Status(0x05)
+	DELTA_BADVAL       = Status(0x06)
+	NOT_MY_VBUCKET     = Status(0x07)
+	NO_BUCKET          = Status(0x08)
+	LOCKED             = Status(0x09)
+	AUTH_STALE         = Status(0x1f)
+	AUTH_ERROR         = Status(0x20)
+	AUTH_CONTINUE      = Status(0x21)
+	ERANGE             = Status(0x22)
+	ROLLBACK           = Status(0x23)
+	EACCESS            = Status(0x24)
+	NOT_INITIALIZED    = Status(0x25)
+	UNKNOWN_COMMAND    = Status(0x81)
+	ENOMEM             = Status(0x82)
+	NOT_SUPPORTED      = Status(0x83)
+	EINTERNAL          = Status(0x84)
+	EBUSY              = Status(0x85)
+	TMPFAIL            = Status(0x86)
+	UNKNOWN_COLLECTION = Status(0x88)
+
+	SYNC_WRITE_IN_PROGRESS = Status(0xa2)
+	SYNC_WRITE_AMBIGUOUS   = Status(0xa3)
 
 	// SUBDOC
 	SUBDOC_PATH_NOT_FOUND             = Status(0xc0)
@@ -261,6 +268,8 @@ func init() {
 	CommandNames[UPR_CONTROL] = "UPR_CONTROL"
 	CommandNames[SUBDOC_GET] = "SUBDOC_GET"
 	CommandNames[SUBDOC_MULTI_LOOKUP] = "SUBDOC_MULTI_LOOKUP"
+	CommandNames[GET_COLLECTIONS_MANIFEST] = "GET_COLLECTIONS_MANIFEST"
+	CommandNames[COLLECTIONS_GET_CID] = "COLLECTIONS_GET_CID"
 
 	StatusNames = make(map[Status]string)
 	StatusNames[SUCCESS] = "SUCCESS"
@@ -285,6 +294,7 @@ func init() {
 	StatusNames[EINTERNAL] = "EINTERNAL"
 	StatusNames[EBUSY] = "EBUSY"
 	StatusNames[TMPFAIL] = "TMPFAIL"
+	StatusNames[UNKNOWN_COLLECTION] = "UNKNOWN_COLLECTION"
 	StatusNames[SUBDOC_PATH_NOT_FOUND] = "SUBDOC_PATH_NOT_FOUND"
 	StatusNames[SUBDOC_BAD_MULTI] = "SUBDOC_BAD_MULTI"
 
diff --git a/vendor/github.com/couchbase/goutils/logging/logger.go b/vendor/github.com/couchbase/goutils/logging/logger.go
index b9948f9b2e..ab854635bf 100644
--- a/vendor/github.com/couchbase/goutils/logging/logger.go
+++ b/vendor/github.com/couchbase/goutils/logging/logger.go
@@ -36,6 +36,7 @@ const (
 	TEXTFORMATTER = LogEntryFormatter(iota)
 	JSONFORMATTER
 	KVFORMATTER
+	UNIFORMFORMATTER
 )
 
 func (level Level) String() string {
@@ -476,6 +477,6 @@ func Stackf(level Level, fmt string, args ...interface{}) {
 }
 
 func init() {
-	logger = NewLogger(os.Stderr, INFO, TEXTFORMATTER)
+	logger := NewLogger(os.Stderr, INFO, TEXTFORMATTER)
 	SetLogger(logger)
 }
diff --git a/vendor/github.com/couchbase/goutils/logging/logger_golog.go b/vendor/github.com/couchbase/goutils/logging/logger_golog.go
index eec432a513..14fd3c391d 100644
--- a/vendor/github.com/couchbase/goutils/logging/logger_golog.go
+++ b/vendor/github.com/couchbase/goutils/logging/logger_golog.go
@@ -1,4 +1,4 @@
-//  Copyright (c) 2016 Couchbase, Inc.
+//  Copyright (c) 2016-2019 Couchbase, Inc.
 //  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
 //  except in compliance with the License. You may obtain a copy of the License at
 //    http://www.apache.org/licenses/LICENSE-2.0
@@ -31,7 +31,7 @@ const (
 	_RLEVEL = "_rlevel"
 )
 
-func NewLogger(out io.Writer, lvl Level, fmtLogging LogEntryFormatter) *goLogger {
+func NewLogger(out io.Writer, lvl Level, fmtLogging LogEntryFormatter, fmtArgs ...interface{}) *goLogger {
 	logger := &goLogger{
 		logger: log.New(out, "", 0),
 		level:  lvl,
@@ -40,6 +40,10 @@ func NewLogger(out io.Writer, lvl Level, fmtLogging LogEntryFormatter) *goLogger
 		logger.entryFormatter = &jsonFormatter{}
 	} else if fmtLogging == KVFORMATTER {
 		logger.entryFormatter = &keyvalueFormatter{}
+	} else if fmtLogging == UNIFORMFORMATTER {
+		logger.entryFormatter = &uniformFormatter{
+			callback: fmtArgs[0].(ComponentCallback),
+		}
 	} else {
 		logger.entryFormatter = &textFormatter{}
 	}
@@ -316,3 +320,46 @@ func (*jsonFormatter) format(newEntry *logEntry) string {
 	s := bytes.NewBuffer(append(serialized, '\n'))
 	return s.String()
 }
+
+type ComponentCallback func() string
+
+type uniformFormatter struct {
+	callback ComponentCallback
+}
+
+// ex. 2019-03-15T11:28:07.652-04:00 DEBU COMPONENT.subcomponent This is a message from test in uniform format
+
+var _LEVEL_UNIFORM = []string{
+	DEBUG:   "DEBU",
+	TRACE:   "TRAC",
+	REQUEST: "REQU",
+	INFO:    "INFO",
+	WARN:    "WARN",
+	ERROR:   "ERRO",
+	SEVERE:  "SEVE",
+	FATAL:   "FATA",
+	NONE:    "NONE",
+}
+
+func (level Level) UniformString() string {
+	return _LEVEL_UNIFORM[level]
+}
+
+func (uf *uniformFormatter) format(newEntry *logEntry) string {
+	b := &bytes.Buffer{}
+	appendValue(b, newEntry.Time)
+	component := uf.callback()
+	if newEntry.Rlevel != NONE {
+		// not really any accommodation for a composite level in the uniform standard; just output as abbr,abbr
+		fmt.Fprintf(b, "%s,%s %s ", newEntry.Level.UniformString(), newEntry.Rlevel.UniformString(), component)
+	} else {
+		fmt.Fprintf(b, "%s %s ", newEntry.Level.UniformString(), component)
+	}
+	appendValue(b, newEntry.Message)
+	for key, value := range newEntry.Data {
+		appendKeyValue(b, key, value)
+	}
+	b.WriteByte('\n')
+	s := bytes.NewBuffer(b.Bytes())
+	return s.String()
+}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/client.go b/vendor/github.com/couchbaselabs/go-couchbase/client.go
index 43c3382960..433b08ff02 100644
--- a/vendor/github.com/couchbaselabs/go-couchbase/client.go
+++ b/vendor/github.com/couchbaselabs/go-couchbase/client.go
@@ -255,6 +255,26 @@ func (b *Bucket) GetCount(refresh bool) (count int64, err error) {
 	return count, nil
 }
 
+// Get bucket document size through the bucket stats
+func (b *Bucket) GetSize(refresh bool) (size int64, err error) {
+	if refresh {
+		b.Refresh()
+	}
+
+	var sz int64
+	for _, gs := range b.GatherStats("") {
+		if len(gs.Stats) > 0 {
+			sz, err = strconv.ParseInt(gs.Stats["ep_value_size"], 10, 64)
+			if err != nil {
+				return 0, err
+			}
+			size += sz
+		}
+	}
+
+	return size, nil
+}
+
 func isAuthError(err error) bool {
 	estr := err.Error()
 	return strings.Contains(estr, "Auth failure")
@@ -980,6 +1000,78 @@ func (b *Bucket) Append(k string, data []byte) error {
 	return b.Write(k, 0, 0, data, Append|Raw)
 }
 
+func (b *Bucket) GetsMCFromCollection(collUid uint32, key string, reqDeadline time.Time) (*gomemcached.MCResponse, error) {
+	var err error
+	var response *gomemcached.MCResponse
+
+	if key == "" {
+		return nil, nil
+	}
+
+	if ClientOpCallback != nil {
+		defer func(t time.Time) { ClientOpCallback("GetsMCFromCollection", key, t, err) }(time.Now())
+	}
+
+	err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
+		var err1 error
+
+		mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+		_, err1 = mc.SelectBucket(b.Name)
+		if err1 != nil {
+			mc.SetDeadline(noDeadline)
+			return err1
+		}
+
+		mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+		response, err1 = mc.GetFromCollection(vb, collUid, key)
+		if err1 != nil {
+			mc.SetDeadline(noDeadline)
+			return err1
+		}
+
+		return nil
+	}, false)
+
+	return response, err
+}
+
+// Returns collectionUid, manifestUid, error.
+func (b *Bucket) GetCollectionCID(scope string, collection string, reqDeadline time.Time) (uint32, uint32, error) {
+	var err error
+	var response *gomemcached.MCResponse
+
+	if ClientOpCallback != nil {
+		defer func(t time.Time) { ClientOpCallback("GetCollectionCID", scope+"."+collection, t, err) }(time.Now())
+	}
+
+	var key = "DUMMY" // Contact any server.
+	var manifestUid uint32
+	var collUid uint32
+	err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
+		var err1 error
+
+		mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+		_, err1 = mc.SelectBucket(b.Name)
+		if err1 != nil {
+			mc.SetDeadline(noDeadline)
+			return err1
+		}
+
+		response, err1 = mc.CollectionsGetCID(scope, collection)
+		if err1 != nil {
+			mc.SetDeadline(noDeadline)
+			return err1
+		}
+
+		manifestUid = binary.BigEndian.Uint32(response.Extras[4:8])
+		collUid = binary.BigEndian.Uint32(response.Extras[8:12])
+
+		return nil
+	}, false)
+
+	return collUid, manifestUid, err
+}
+
 // Get a value straight from Memcached
 func (b *Bucket) GetsMC(key string, reqDeadline time.Time) (*gomemcached.MCResponse, error) {
 	var err error
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go b/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go
index babd3adb6a..23102abd84 100644
--- a/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go
+++ b/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go
@@ -1,6 +1,7 @@
 package couchbase
 
 import (
+	"crypto/tls"
 	"errors"
 	"sync/atomic"
 	"time"
@@ -36,7 +37,7 @@ var ConnPoolAvailWaitTime = time.Millisecond
 
 type connectionPool struct {
 	host        string
-	mkConn      func(host string, ah AuthHandler) (*memcached.Client, error)
+	mkConn      func(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error)
 	auth        AuthHandler
 	connections chan *memcached.Client
 	createsem   chan bool
@@ -44,9 +45,11 @@ type connectionPool struct {
 	poolSize    int
 	connCount   uint64
 	inUse       bool
+	tlsConfig   *tls.Config
+	bucket string
 }
 
-func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolOverflow int) *connectionPool {
+func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolOverflow int, tlsConfig *tls.Config, bucket string) *connectionPool {
 	connSize := poolSize
 	if closer {
 		connSize += poolOverflow
@@ -58,6 +61,8 @@ func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolO
 		mkConn:      defaultMkConn,
 		auth:        ah,
 		poolSize:    poolSize,
+		tlsConfig:   tlsConfig,
+		bucket:      bucket,
 	}
 	if closer {
 		rv.bailOut = make(chan bool, 1)
@@ -69,10 +74,19 @@ func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolO
 // ConnPoolTimeout is notified whenever connections are acquired from a pool.
 var ConnPoolCallback func(host string, source string, start time.Time, err error)
 
-func defaultMkConn(host string, ah AuthHandler) (*memcached.Client, error) {
+// Use regular in-the-clear connection if tlsConfig is nil.
+// Use secure connection (TLS) if tlsConfig is set.
+func defaultMkConn(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error) {
 	var features memcached.Features
 
-	conn, err := memcached.Connect("tcp", host)
+	var conn *memcached.Client
+	var err error
+	if tlsConfig == nil {
+		conn, err = memcached.Connect("tcp", host)
+	} else {
+		conn, err = memcached.ConnectTLS("tcp", host, tlsConfig)
+	}
+
 	if err != nil {
 		return nil, err
 	}
@@ -92,6 +106,10 @@ func defaultMkConn(host string, ah AuthHandler) (*memcached.Client, error) {
 		features = append(features, memcached.FeatureXattr)
 	}
 
+	if EnableCollections {
+		features = append(features, memcached.FeatureCollections)
+	}
+
 	if len(features) > 0 {
 		if DefaultTimeout > 0 {
 			conn.SetDeadline(getDeadline(noDeadline, DefaultTimeout))
@@ -122,6 +140,11 @@ func defaultMkConn(host string, ah AuthHandler) (*memcached.Client, error) {
 		return conn, nil
 	}
 	name, pass, bucket := ah.GetCredentials()
+	if bucket  == "" {
+		// Authenticator does not know specific bucket.
+		bucket = bucketName
+	}
+
 	if name != "default" {
 		_, err = conn.Auth(name, pass)
 		if err != nil {
@@ -221,7 +244,7 @@ func (cp *connectionPool) GetWithTimeout(d time.Duration) (rv *memcached.Client,
 			// Build a connection if we can't get a real one.
 			// This can potentially be an overflow connection, or
 			// a pooled connection.
-			rv, err := cp.mkConn(cp.host, cp.auth)
+			rv, err := cp.mkConn(cp.host, cp.auth, cp.tlsConfig, cp.bucket)
 			if err != nil {
 				// On error, release our create hold
 				<-cp.createsem
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/pools.go b/vendor/github.com/couchbaselabs/go-couchbase/pools.go
index 5f3ff8c495..0e2379398a 100644
--- a/vendor/github.com/couchbaselabs/go-couchbase/pools.go
+++ b/vendor/github.com/couchbaselabs/go-couchbase/pools.go
@@ -16,8 +16,10 @@ import (
 	"net/url"
 	"runtime"
 	"sort"
+	"strconv"
 	"strings"
 	"sync"
+	"time"
 	"unsafe"
 
 	"github.com/couchbase/goutils/logging"
@@ -28,8 +30,9 @@ import (
 
 // HTTPClient to use for REST and view operations.
 var MaxIdleConnsPerHost = 256
+var ClientTimeOut = 10 * time.Second
 var HTTPTransport = &http.Transport{MaxIdleConnsPerHost: MaxIdleConnsPerHost}
-var HTTPClient = &http.Client{Transport: HTTPTransport}
+var HTTPClient = &http.Client{Transport: HTTPTransport, Timeout: ClientTimeOut}
 
 // PoolSize is the size of each connection pool (per host).
 var PoolSize = 64
@@ -53,6 +56,9 @@ var EnableDataType = false
 // Enable Xattr
 var EnableXattr = false
 
+// Enable Collections
+var EnableCollections = false
+
 // TCP keepalive interval in seconds. Default 30 minutes
 var TCPKeepaliveInterval = 30 * 60
 
@@ -178,12 +184,12 @@ type Node struct {
 
 // A Pool of nodes and buckets.
 type Pool struct {
-	BucketMap map[string]Bucket
+	BucketMap map[string]*Bucket
 	Nodes     []Node
 
 	BucketURL map[string]string `json:"buckets"`
 
-	client Client
+	client *Client
 }
 
 // VBucketServerMap is the a mapping of vbuckets to nodes.
@@ -240,13 +246,14 @@ type Bucket struct {
 	commonSufix      string
 	ah               AuthHandler        // auth handler
 	ds               *DurablitySettings // Durablity Settings for this bucket
-	Scopes           Scopes
+	closed           bool
 }
 
 // PoolServices is all the bucket-independent services in a pool
 type PoolServices struct {
-	Rev      int            `json:"rev"`
-	NodesExt []NodeServices `json:"nodesExt"`
+	Rev          int             `json:"rev"`
+	NodesExt     []NodeServices  `json:"nodesExt"`
+	Capabilities json.RawMessage `json:"clusterCapabilities"`
 }
 
 // NodeServices is all the bucket-independent services running on
@@ -337,7 +344,7 @@ func (b *Bucket) GetName() string {
 	return ret
 }
 
-// Nodes returns teh current list of nodes servicing this bucket.
+// Nodes returns the current list of nodes servicing this bucket.
 func (b *Bucket) Nodes() []Node {
 	b.RLock()
 	defer b.RUnlock()
@@ -475,6 +482,14 @@ func (b *Bucket) GetRandomDoc() (*gomemcached.MCResponse, error) {
 		return nil, err
 	}
 
+	// We may need to select the bucket before GetRandomDoc()
+	// will work. This is sometimes done at startup (see defaultMkConn())
+	// but not always, depending on the auth type.
+	_, err = conn.SelectBucket(b.Name)
+	if err != nil {
+		return nil, err
+	}
+
 	// get a randomm document from the connection
 	doc, err := conn.GetRandomDoc()
 	// need to return the connection to the pool
@@ -533,9 +548,10 @@ func (b *Bucket) CommonAddressSuffix() string {
 // A Client is the starting point for all services across all buckets
 // in a Couchbase cluster.
 type Client struct {
-	BaseURL *url.URL
-	ah      AuthHandler
-	Info    Pools
+	BaseURL   *url.URL
+	ah        AuthHandler
+	Info      Pools
+	tlsConfig *tls.Config
 }
 
 func maybeAddAuth(req *http.Request, ah AuthHandler) error {
@@ -601,11 +617,11 @@ func doHTTPRequest(req *http.Request) (*http.Response, error) {
 	var err error
 	var res *http.Response
 
-	tr := &http.Transport{}
-
 	// we need a client that ignores certificate errors, since we self-sign
 	// our certs
 	if client == nil && req.URL.Scheme == "https" {
+		var tr *http.Transport
+
 		if skipVerify {
 			tr = &http.Transport{
 				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
@@ -931,6 +947,25 @@ func ConnectWithAuth(baseU string, ah AuthHandler) (c Client, err error) {
 	return c, c.parseURLResponse("/pools", &c.Info)
 }
 
+// Call this method with a TLS certificate file name to make communication
+// with the KV engine encrypted.
+//
+// This method should be called immediately after a Connect*() method.
+func (c *Client) InitTLS(certFile string) error {
+	serverCert, err := ioutil.ReadFile(certFile)
+	if err != nil {
+		return err
+	}
+	CA_Pool := x509.NewCertPool()
+	CA_Pool.AppendCertsFromPEM(serverCert)
+	c.tlsConfig = &tls.Config{RootCAs: CA_Pool}
+	return nil
+}
+
+func (c *Client) ClearTLS() {
+	c.tlsConfig = nil
+}
+
 // ConnectWithAuthCreds connects to a couchbase cluster with the give
 // authorization creds returned by cb_auth
 func ConnectWithAuthCreds(baseU, username, password string) (c Client, err error) {
@@ -941,7 +976,6 @@ func ConnectWithAuthCreds(baseU, username, password string) (c Client, err error
 
 	c.ah = newBucketAuth(username, password, "")
 	return c, c.parseURLResponse("/pools", &c.Info)
-
 }
 
 // Connect to a couchbase cluster.  An authentication handler will be
@@ -1038,44 +1072,153 @@ func (b *Bucket) NodeListChanged() bool {
 // /pooles/default/$BUCKET_NAME/collections API.
 // {"myScope2":{"myCollectionC":{}},"myScope1":{"myCollectionB":{},"myCollectionA":{}},"_default":{"_default":{}}}
 
-// A Scopes holds the set of scopes in a bucket.
+// Structures for parsing collections manifest.
 // The map key is the name of the scope.
-type Scopes map[string]Collections
+// Example data:
+// {"uid":"b","scopes":[
+//    {"name":"_default","uid":"0","collections":[
+//       {"name":"_default","uid":"0"}]},
+//    {"name":"myScope1","uid":"8","collections":[
+//       {"name":"myCollectionB","uid":"c"},
+//       {"name":"myCollectionA","uid":"b"}]},
+//    {"name":"myScope2","uid":"9","collections":[
+//       {"name":"myCollectionC","uid":"d"}]}]}
+type InputManifest struct {
+	Uid    string
+	Scopes []InputScope
+}
+type InputScope struct {
+	Name        string
+	Uid         string
+	Collections []InputCollection
+}
+type InputCollection struct {
+	Name string
+	Uid  string
+}
 
-// A Collections holds the set of collections in a scope.
-// The map key is the name of the collection.
-type Collections map[string]Collection
+// Structures for storing collections information.
+type Manifest struct {
+	Uid    uint64
+	Scopes map[string]*Scope // map by name
+}
+type Scope struct {
+	Name        string
+	Uid         uint64
+	Collections map[string]*Collection // map by name
+}
+type Collection struct {
+	Name string
+	Uid  uint64
+}
 
-// A Collection holds the information for a collection.
-// It is currently returned empty.
-type Collection struct{}
+var _EMPTY_MANIFEST *Manifest = &Manifest{Uid: 0, Scopes: map[string]*Scope{}}
 
-func getScopesAndCollections(pool *Pool, bucketName string) (Scopes, error) {
-	scopes := make(Scopes)
-	// This URL is a bit of a hack. The "default" is the name of the pool, and should
-	// be a parameter. But the name does not appear to be available anywhere,
-	// and in any case we never use a pool other than "default".
-	err := pool.client.parseURLResponse(fmt.Sprintf("/pools/default/buckets/%s/collections", bucketName), &scopes)
+func parseCollectionsManifest(res *gomemcached.MCResponse) (*Manifest, error) {
+	if !EnableCollections {
+		return _EMPTY_MANIFEST, nil
+	}
+
+	var im InputManifest
+	err := json.Unmarshal(res.Body, &im)
 	if err != nil {
 		return nil, err
 	}
-	return scopes, nil
+
+	uid, err := strconv.ParseUint(im.Uid, 16, 64)
+	if err != nil {
+		return nil, err
+	}
+	mani := &Manifest{Uid: uid, Scopes: make(map[string]*Scope, len(im.Scopes))}
+	for _, iscope := range im.Scopes {
+		scope_uid, err := strconv.ParseUint(iscope.Uid, 16, 64)
+		if err != nil {
+			return nil, err
+		}
+		scope := &Scope{Uid: scope_uid, Name: iscope.Name, Collections: make(map[string]*Collection, len(iscope.Collections))}
+		mani.Scopes[iscope.Name] = scope
+		for _, icoll := range iscope.Collections {
+			coll_uid, err := strconv.ParseUint(icoll.Uid, 16, 64)
+			if err != nil {
+				return nil, err
+			}
+			coll := &Collection{Uid: coll_uid, Name: icoll.Name}
+			scope.Collections[icoll.Name] = coll
+		}
+	}
+
+	return mani, nil
+}
+
+// This function assumes the bucket is locked.
+func (b *Bucket) GetCollectionsManifest() (*Manifest, error) {
+	// Collections not used?
+	if !EnableCollections {
+		return nil, fmt.Errorf("Collections not enabled.")
+	}
+
+	b.RLock()
+	pools := b.getConnPools(true /* already locked */)
+	pool := pools[0] // Any pool will do, so use the first one.
+	b.RUnlock()
+	client, err := pool.Get()
+	if err != nil {
+		return nil, fmt.Errorf("Unable to get connection to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+	}
+
+	// We need to select the bucket before GetCollectionsManifest()
+	// will work. This is sometimes done at startup (see defaultMkConn())
+	// but not always, depending on the auth type.
+	// Doing this is safe because we collect the the connections
+	// by bucket, so the bucket being selected will never change.
+	_, err = client.SelectBucket(b.Name)
+	if err != nil {
+		pool.Return(client)
+		return nil, fmt.Errorf("Unable to select bucket %s: %v. No collections access to bucket %s.", err, b.Name, b.Name)
+	}
+
+	res, err := client.GetCollectionsManifest()
+	if err != nil {
+		pool.Return(client)
+		return nil, fmt.Errorf("Unable to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+	}
+	mani, err := parseCollectionsManifest(res)
+	if err != nil {
+		pool.Return(client)
+		return nil, fmt.Errorf("Unable to parse collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+	}
+
+	pool.Return(client)
+	return mani, nil
+}
+
+func (b *Bucket) RefreshFully() error {
+	return b.refresh(false)
 }
 
 func (b *Bucket) Refresh() error {
+	return b.refresh(true)
+}
+
+func (b *Bucket) refresh(preserveConnections bool) error {
 	b.RLock()
 	pool := b.pool
 	uri := b.URI
-	name := b.Name
+	client := pool.client
 	b.RUnlock()
+	tlsConfig := client.tlsConfig
 
-	tmpb := &Bucket{}
-	err := pool.client.parseURLResponse(uri, tmpb)
-	if err != nil {
-		return err
+	var poolServices PoolServices
+	var err error
+	if tlsConfig != nil {
+		poolServices, err = client.GetPoolServices("default")
+		if err != nil {
+			return err
+		}
 	}
 
-	scopes, err := getScopesAndCollections(pool, name)
+	tmpb := &Bucket{}
+	err = pool.client.parseURLResponse(uri, tmpb)
 	if err != nil {
 		return err
 	}
@@ -1096,50 +1239,67 @@ func (b *Bucket) Refresh() error {
 	newcps := make([]*connectionPool, len(tmpb.VBSMJson.ServerList))
 	for i := range newcps {
 
-		pool := b.getConnPoolByHost(tmpb.VBSMJson.ServerList[i], true /* bucket already locked */)
-		if pool != nil && pool.inUse == false {
-			// if the hostname and index is unchanged then reuse this pool
-			newcps[i] = pool
-			pool.inUse = true
-			continue
+		if preserveConnections {
+			pool := b.getConnPoolByHost(tmpb.VBSMJson.ServerList[i], true /* bucket already locked */)
+			if pool != nil && pool.inUse == false {
+				// if the hostname and index is unchanged then reuse this pool
+				newcps[i] = pool
+				pool.inUse = true
+				continue
+			}
+		}
+
+		hostport := tmpb.VBSMJson.ServerList[i]
+		if tlsConfig != nil {
+			hostport, err = MapKVtoSSL(hostport, &poolServices)
+			if err != nil {
+				b.Unlock()
+				return err
+			}
 		}
 
 		if b.ah != nil {
-			newcps[i] = newConnectionPool(
-				tmpb.VBSMJson.ServerList[i],
-				b.ah, AsynchronousCloser, PoolSize, PoolOverflow)
+			newcps[i] = newConnectionPool(hostport,
+				b.ah, AsynchronousCloser, PoolSize, PoolOverflow, tlsConfig, b.Name)
 
 		} else {
-			newcps[i] = newConnectionPool(
-				tmpb.VBSMJson.ServerList[i],
+			newcps[i] = newConnectionPool(hostport,
 				b.authHandler(true /* bucket already locked */),
-				AsynchronousCloser, PoolSize, PoolOverflow)
+				AsynchronousCloser, PoolSize, PoolOverflow, tlsConfig, b.Name)
 		}
 	}
 	b.replaceConnPools2(newcps, true /* bucket already locked */)
 	tmpb.ah = b.ah
 	b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
 	b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
-	b.Scopes = scopes
 
 	b.Unlock()
 	return nil
 }
 
 func (p *Pool) refresh() (err error) {
-	p.BucketMap = make(map[string]Bucket)
+	p.BucketMap = make(map[string]*Bucket)
 
 	buckets := []Bucket{}
 	err = p.client.parseURLResponse(p.BucketURL["uri"], &buckets)
 	if err != nil {
 		return err
 	}
-	for _, b := range buckets {
+	for i, _ := range buckets {
+		b := new(Bucket)
+		*b = buckets[i]
 		b.pool = p
 		b.nodeList = unsafe.Pointer(&b.NodesJSON)
-		b.replaceConnPools(make([]*connectionPool, len(b.VBSMJson.ServerList)))
 
+		// MB-33185 this is merely defensive, just in case
+		// refresh() gets called on a perfectly node pool
+		ob, ok := p.BucketMap[b.Name]
+		if ok && ob.connPools != nil {
+			ob.Close()
+		}
+		b.replaceConnPools(make([]*connectionPool, len(b.VBSMJson.ServerList)))
 		p.BucketMap[b.Name] = b
+		runtime.SetFinalizer(b, bucketFinalizer)
 	}
 	return nil
 }
@@ -1148,9 +1308,11 @@ func (p *Pool) refresh() (err error) {
 // "default").
 func (c *Client) GetPool(name string) (p Pool, err error) {
 	var poolURI string
+
 	for _, p := range c.Info.Pools {
 		if p.Name == name {
 			poolURI = p.URI
+			break
 		}
 	}
 	if poolURI == "" {
@@ -1159,7 +1321,7 @@ func (c *Client) GetPool(name string) (p Pool, err error) {
 
 	err = c.parseURLResponse(poolURI, &p)
 
-	p.client = *c
+	p.client = c
 
 	err = p.refresh()
 	return
@@ -1184,6 +1346,19 @@ func (c *Client) GetPoolServices(name string) (ps PoolServices, err error) {
 	return
 }
 
+func (b *Bucket) GetPoolServices(name string) (*PoolServices, error) {
+	b.RLock()
+	pool := b.pool
+	b.RUnlock()
+
+	ps, err := pool.client.GetPoolServices(name)
+	if err != nil {
+		return nil, err
+	}
+
+	return &ps, nil
+}
+
 // Close marks this bucket as no longer needed, closing connections it
 // may have open.
 func (b *Bucket) Close() {
@@ -1201,7 +1376,12 @@ func (b *Bucket) Close() {
 
 func bucketFinalizer(b *Bucket) {
 	if b.connPools != nil {
-		logging.Warnf("Finalizing a bucket with active connections.")
+		if !b.closed {
+			logging.Warnf("Finalizing a bucket with active connections.")
+		}
+
+		// MB-33185 do not leak connection pools
+		b.Close()
 	}
 }
 
@@ -1211,12 +1391,11 @@ func (p *Pool) GetBucket(name string) (*Bucket, error) {
 	if !ok {
 		return nil, &BucketNotFoundError{bucket: name}
 	}
-	runtime.SetFinalizer(&rv, bucketFinalizer)
 	err := rv.Refresh()
 	if err != nil {
 		return nil, err
 	}
-	return &rv, nil
+	return rv, nil
 }
 
 // GetBucket gets a bucket from within this pool.
@@ -1225,13 +1404,12 @@ func (p *Pool) GetBucketWithAuth(bucket, username, password string) (*Bucket, er
 	if !ok {
 		return nil, &BucketNotFoundError{bucket: bucket}
 	}
-	runtime.SetFinalizer(&rv, bucketFinalizer)
 	rv.ah = newBucketAuth(username, password, bucket)
 	err := rv.Refresh()
 	if err != nil {
 		return nil, err
 	}
-	return &rv, nil
+	return rv, nil
 }
 
 // GetPool gets the pool to which this bucket belongs.
@@ -1244,7 +1422,21 @@ func (b *Bucket) GetPool() *Pool {
 
 // GetClient gets the client from which we got this pool.
 func (p *Pool) GetClient() *Client {
-	return &p.client
+	return p.client
+}
+
+// Release bucket connections when the pool is no longer in use
+func (p *Pool) Close() {
+	// fine to loop through the buckets unlocked
+	// locking happens at the bucket level
+	for b, _ := range p.BucketMap {
+
+		// MB-33208 defer closing connection pools until the bucket is no longer used
+		bucket := p.BucketMap[b]
+		bucket.Lock()
+		bucket.closed = true
+		bucket.Unlock()
+	}
 }
 
 // GetBucket is a convenience function for getting a named bucket from
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/port_map.go b/vendor/github.com/couchbaselabs/go-couchbase/port_map.go
new file mode 100644
index 0000000000..24c9f105db
--- /dev/null
+++ b/vendor/github.com/couchbaselabs/go-couchbase/port_map.go
@@ -0,0 +1,84 @@
+package couchbase
+
+/*
+
+The goal here is to map a hostname:port combination to another hostname:port
+combination. The original hostname:port gives the name and regular KV port
+of a couchbase server. We want to determine the corresponding SSL KV port.
+
+To do this, we have a pool services structure, as obtained from
+the /pools/default/nodeServices API.
+
+For a fully configured two-node system, the structure may look like this:
+{"rev":32,"nodesExt":[
+	{"services":{"mgmt":8091,"mgmtSSL":18091,"fts":8094,"ftsSSL":18094,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211},"hostname":"172.23.123.101"},
+	{"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211,"n1ql":8093,"n1qlSSL":18093},"thisNode":true,"hostname":"172.23.123.102"}]}
+
+In this case, note the "hostname" fields, and the "kv" and "kvSSL" fields.
+
+For a single-node system, perhaps brought up for testing, the structure may look like this:
+{"rev":66,"nodesExt":[
+	{"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"kv":11210,"kvSSL":11207,"capi":8092,"capiSSL":18092,"projector":9999,"n1ql":8093,"n1qlSSL":18093},"thisNode":true}],"clusterCapabilitiesVer":[1,0],"clusterCapabilities":{"n1ql":["enhancedPreparedStatements"]}}
+
+Here, note that there is only a single entry in the "nodeExt" array and that it does not have a "hostname" field.
+We will assume that either hostname fields are present, or there is only a single node.
+*/
+
+import (
+	"encoding/json"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+func ParsePoolServices(jsonInput string) (*PoolServices, error) {
+	ps := &PoolServices{}
+	err := json.Unmarshal([]byte(jsonInput), ps)
+	return ps, err
+}
+
+func MapKVtoSSL(hostport string, ps *PoolServices) (string, error) {
+	colonIndex := strings.LastIndex(hostport, ":")
+	if colonIndex < 0 {
+		return "", fmt.Errorf("Unable to find host/port separator in %s", hostport)
+	}
+	host := hostport[0:colonIndex]
+	port := hostport[colonIndex+1:]
+	portInt, err := strconv.Atoi(port)
+	if err != nil {
+		return "", fmt.Errorf("Unable to parse host/port combination %s: %v", hostport, err)
+	}
+
+	var ns *NodeServices
+	if len(ps.NodesExt) == 1 {
+		ns = &(ps.NodesExt[0])
+	} else {
+		for i := range ps.NodesExt {
+			hostname := ps.NodesExt[i].Hostname
+			if len(hostname) == 0 {
+				// in case of missing hostname, check for 127.0.0.1
+				hostname = "127.0.0.1"
+			}
+			if hostname == host {
+				ns = &(ps.NodesExt[i])
+				break
+			}
+		}
+	}
+
+	if ns == nil {
+		return "", fmt.Errorf("Unable to parse host/port combination %s: no matching node found among %d", hostport, len(ps.NodesExt))
+	}
+	kv, found := ns.Services["kv"]
+	if !found {
+		return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kv port listed", hostport)
+	}
+	kvSSL, found := ns.Services["kvSSL"]
+	if !found {
+		return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kvSSL port listed", hostport)
+	}
+	if portInt != kv {
+		return "", fmt.Errorf("Unable to map hostport combination %s: expected port %d but found %d", hostport, portInt, kv)
+	}
+	return fmt.Sprintf("%s:%d", host, kvSSL), nil
+}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/streaming.go b/vendor/github.com/couchbaselabs/go-couchbase/streaming.go
index 6467635371..6d8f7dfd53 100644
--- a/vendor/github.com/couchbaselabs/go-couchbase/streaming.go
+++ b/vendor/github.com/couchbaselabs/go-couchbase/streaming.go
@@ -88,6 +88,16 @@ func (b *Bucket) UpdateBucket() error {
 	var failures int
 	var returnErr error
 
+	var poolServices PoolServices
+	var err error
+	tlsConfig := b.pool.client.tlsConfig
+	if tlsConfig != nil {
+		poolServices, err = b.pool.client.GetPoolServices("default")
+		if err != nil {
+			return err
+		}
+	}
+
 	for {
 
 		if failures == MAX_RETRY_COUNT {
@@ -110,15 +120,6 @@ func (b *Bucket) UpdateBucket() error {
 			return err
 		}
 
-		b.RLock()
-		pool := b.pool
-		bucketName := b.Name
-		b.RUnlock()
-		scopes, err := getScopesAndCollections(pool, bucketName)
-		if err != nil {
-			return err
-		}
-
 		// Lock here to avoid having pool closed under us.
 		b.RLock()
 		err = maybeAddAuth(req, b.pool.client.ah)
@@ -176,16 +177,22 @@ func (b *Bucket) UpdateBucket() error {
 					continue
 				}
 				// else create a new pool
+				hostport := tmpb.VBSMJson.ServerList[i]
+				if tlsConfig != nil {
+					hostport, err = MapKVtoSSL(hostport, &poolServices)
+					if err != nil {
+						b.Unlock()
+						return err
+					}
+				}
 				if b.ah != nil {
-					newcps[i] = newConnectionPool(
-						tmpb.VBSMJson.ServerList[i],
-						b.ah, false, PoolSize, PoolOverflow)
+					newcps[i] = newConnectionPool(hostport,
+						b.ah, false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name)
 
 				} else {
-					newcps[i] = newConnectionPool(
-						tmpb.VBSMJson.ServerList[i],
+					newcps[i] = newConnectionPool(hostport,
 						b.authHandler(true /* bucket already locked */),
-						false, PoolSize, PoolOverflow)
+						false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name)
 				}
 			}
 
@@ -194,7 +201,6 @@ func (b *Bucket) UpdateBucket() error {
 			tmpb.ah = b.ah
 			b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
 			b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
-			b.Scopes = scopes
 			b.Unlock()
 
 			logging.Infof("Got new configuration for bucket %s", b.GetName())
diff --git a/vendor/github.com/edsrzf/mmap-go/mmap.go b/vendor/github.com/edsrzf/mmap-go/mmap.go
index 14fb22580a..29655bd222 100644
--- a/vendor/github.com/edsrzf/mmap-go/mmap.go
+++ b/vendor/github.com/edsrzf/mmap-go/mmap.go
@@ -81,25 +81,27 @@ func (m *MMap) header() *reflect.SliceHeader {
 	return (*reflect.SliceHeader)(unsafe.Pointer(m))
 }
 
+func (m *MMap) addrLen() (uintptr, uintptr) {
+	header := m.header()
+	return header.Data, uintptr(header.Len)
+}
+
 // Lock keeps the mapped region in physical memory, ensuring that it will not be
 // swapped out.
 func (m MMap) Lock() error {
-	dh := m.header()
-	return lock(dh.Data, uintptr(dh.Len))
+	return m.lock()
 }
 
 // Unlock reverses the effect of Lock, allowing the mapped region to potentially
 // be swapped out.
 // If m is already unlocked, aan error will result.
 func (m MMap) Unlock() error {
-	dh := m.header()
-	return unlock(dh.Data, uintptr(dh.Len))
+	return m.unlock()
 }
 
 // Flush synchronizes the mapping's contents to the file's contents on disk.
 func (m MMap) Flush() error {
-	dh := m.header()
-	return flush(dh.Data, uintptr(dh.Len))
+	return m.flush()
 }
 
 // Unmap deletes the memory mapped region, flushes any remaining changes, and sets
@@ -109,8 +111,7 @@ func (m MMap) Flush() error {
 // Unmap should only be called on the slice value that was originally returned from
 // a call to Map. Calling Unmap on a derived slice may cause errors.
 func (m *MMap) Unmap() error {
-	dh := m.header()
-	err := unmap(dh.Data, uintptr(dh.Len))
+	err := m.unmap()
 	*m = nil
 	return err
 }
diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_unix.go b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go
index 4af98420d5..25b13e51fd 100644
--- a/vendor/github.com/edsrzf/mmap-go/mmap_unix.go
+++ b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go
@@ -7,61 +7,45 @@
 package mmap
 
 import (
-	"syscall"
+	"golang.org/x/sys/unix"
 )
 
 func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) {
-	flags := syscall.MAP_SHARED
-	prot := syscall.PROT_READ
+	flags := unix.MAP_SHARED
+	prot := unix.PROT_READ
 	switch {
 	case inprot&COPY != 0:
-		prot |= syscall.PROT_WRITE
-		flags = syscall.MAP_PRIVATE
+		prot |= unix.PROT_WRITE
+		flags = unix.MAP_PRIVATE
 	case inprot&RDWR != 0:
-		prot |= syscall.PROT_WRITE
+		prot |= unix.PROT_WRITE
 	}
 	if inprot&EXEC != 0 {
-		prot |= syscall.PROT_EXEC
+		prot |= unix.PROT_EXEC
 	}
 	if inflags&ANON != 0 {
-		flags |= syscall.MAP_ANON
+		flags |= unix.MAP_ANON
 	}
 
-	b, err := syscall.Mmap(int(fd), off, len, prot, flags)
+	b, err := unix.Mmap(int(fd), off, len, prot, flags)
 	if err != nil {
 		return nil, err
 	}
 	return b, nil
 }
 
-func flush(addr, len uintptr) error {
-	_, _, errno := syscall.Syscall(_SYS_MSYNC, addr, len, _MS_SYNC)
-	if errno != 0 {
-		return syscall.Errno(errno)
-	}
-	return nil
+func (m MMap) flush() error {
+	return unix.Msync([]byte(m), unix.MS_SYNC)
 }
 
-func lock(addr, len uintptr) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_MLOCK, addr, len, 0)
-	if errno != 0 {
-		return syscall.Errno(errno)
-	}
-	return nil
+func (m MMap) lock() error {
+	return unix.Mlock([]byte(m))
 }
 
-func unlock(addr, len uintptr) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_MUNLOCK, addr, len, 0)
-	if errno != 0 {
-		return syscall.Errno(errno)
-	}
-	return nil
+func (m MMap) unlock() error {
+	return unix.Munlock([]byte(m))
 }
 
-func unmap(addr, len uintptr) error {
-	_, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, addr, len, 0)
-	if errno != 0 {
-		return syscall.Errno(errno)
-	}
-	return nil
+func (m MMap) unmap() error {
+	return unix.Munmap([]byte(m))
 }
diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_windows.go b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go
index c3d2d02d3f..7910da2577 100644
--- a/vendor/github.com/edsrzf/mmap-go/mmap_windows.go
+++ b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go
@@ -8,7 +8,8 @@ import (
 	"errors"
 	"os"
 	"sync"
-	"syscall"
+
+	"golang.org/x/sys/windows"
 )
 
 // mmap on Windows is a two-step process.
@@ -19,23 +20,29 @@ import (
 // not a struct, so it's convenient to manipulate.
 
 // We keep this map so that we can get back the original handle from the memory address.
+
+type addrinfo struct {
+	file    windows.Handle
+	mapview windows.Handle
+}
+
 var handleLock sync.Mutex
-var handleMap = map[uintptr]syscall.Handle{}
+var handleMap = map[uintptr]*addrinfo{}
 
 func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
-	flProtect := uint32(syscall.PAGE_READONLY)
-	dwDesiredAccess := uint32(syscall.FILE_MAP_READ)
+	flProtect := uint32(windows.PAGE_READONLY)
+	dwDesiredAccess := uint32(windows.FILE_MAP_READ)
 	switch {
 	case prot&COPY != 0:
-		flProtect = syscall.PAGE_WRITECOPY
-		dwDesiredAccess = syscall.FILE_MAP_COPY
+		flProtect = windows.PAGE_WRITECOPY
+		dwDesiredAccess = windows.FILE_MAP_COPY
 	case prot&RDWR != 0:
-		flProtect = syscall.PAGE_READWRITE
-		dwDesiredAccess = syscall.FILE_MAP_WRITE
+		flProtect = windows.PAGE_READWRITE
+		dwDesiredAccess = windows.FILE_MAP_WRITE
 	}
 	if prot&EXEC != 0 {
 		flProtect <<= 4
-		dwDesiredAccess |= syscall.FILE_MAP_EXECUTE
+		dwDesiredAccess |= windows.FILE_MAP_EXECUTE
 	}
 
 	// The maximum size is the area of the file, starting from 0,
@@ -45,7 +52,7 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
 	maxSizeHigh := uint32((off + int64(len)) >> 32)
 	maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF)
 	// TODO: Do we need to set some security attributes? It might help portability.
-	h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil)
+	h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil)
 	if h == 0 {
 		return nil, os.NewSyscallError("CreateFileMapping", errno)
 	}
@@ -54,12 +61,15 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
 	// is the length the user requested.
 	fileOffsetHigh := uint32(off >> 32)
 	fileOffsetLow := uint32(off & 0xFFFFFFFF)
-	addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len))
+	addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len))
 	if addr == 0 {
 		return nil, os.NewSyscallError("MapViewOfFile", errno)
 	}
 	handleLock.Lock()
-	handleMap[addr] = h
+	handleMap[addr] = &addrinfo{
+		file:    windows.Handle(hfile),
+		mapview: h,
+	}
 	handleLock.Unlock()
 
 	m := MMap{}
@@ -71,8 +81,9 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
 	return m, nil
 }
 
-func flush(addr, len uintptr) error {
-	errno := syscall.FlushViewOfFile(addr, len)
+func (m MMap) flush() error {
+	addr, len := m.addrLen()
+	errno := windows.FlushViewOfFile(addr, len)
 	if errno != nil {
 		return os.NewSyscallError("FlushViewOfFile", errno)
 	}
@@ -85,22 +96,29 @@ func flush(addr, len uintptr) error {
 		return errors.New("unknown base address")
 	}
 
-	errno = syscall.FlushFileBuffers(handle)
+	errno = windows.FlushFileBuffers(handle.file)
 	return os.NewSyscallError("FlushFileBuffers", errno)
 }
 
-func lock(addr, len uintptr) error {
-	errno := syscall.VirtualLock(addr, len)
+func (m MMap) lock() error {
+	addr, len := m.addrLen()
+	errno := windows.VirtualLock(addr, len)
 	return os.NewSyscallError("VirtualLock", errno)
 }
 
-func unlock(addr, len uintptr) error {
-	errno := syscall.VirtualUnlock(addr, len)
+func (m MMap) unlock() error {
+	addr, len := m.addrLen()
+	errno := windows.VirtualUnlock(addr, len)
 	return os.NewSyscallError("VirtualUnlock", errno)
 }
 
-func unmap(addr, len uintptr) error {
-	flush(addr, len)
+func (m MMap) unmap() error {
+	err := m.flush()
+	if err != nil {
+		return err
+	}
+
+	addr := m.header().Data
 	// Lock the UnmapViewOfFile along with the handleMap deletion.
 	// As soon as we unmap the view, the OS is free to give the
 	// same addr to another new map. We don't want another goroutine
@@ -108,7 +126,7 @@ func unmap(addr, len uintptr) error {
 	// we're trying to remove our old addr/handle pair.
 	handleLock.Lock()
 	defer handleLock.Unlock()
-	err := syscall.UnmapViewOfFile(addr)
+	err = windows.UnmapViewOfFile(addr)
 	if err != nil {
 		return err
 	}
@@ -120,6 +138,6 @@ func unmap(addr, len uintptr) error {
 	}
 	delete(handleMap, addr)
 
-	e := syscall.CloseHandle(syscall.Handle(handle))
+	e := windows.CloseHandle(windows.Handle(handle.mapview))
 	return os.NewSyscallError("CloseHandle", e)
 }
diff --git a/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go b/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go
deleted file mode 100644
index a64b003e2d..0000000000
--- a/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 Evan Shaw. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mmap
-
-const _SYS_MSYNC = 277
-const _MS_SYNC = 0x04
diff --git a/vendor/github.com/edsrzf/mmap-go/msync_unix.go b/vendor/github.com/edsrzf/mmap-go/msync_unix.go
deleted file mode 100644
index 91ee5f40f1..0000000000
--- a/vendor/github.com/edsrzf/mmap-go/msync_unix.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 Evan Shaw. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux openbsd solaris
-
-package mmap
-
-import (
-	"syscall"
-)
-
-const _SYS_MSYNC = syscall.SYS_MSYNC
-const _MS_SYNC = syscall.MS_SYNC
diff --git a/vendor/github.com/go-macaron/binding/.travis.yml b/vendor/github.com/go-macaron/binding/.travis.yml
deleted file mode 100644
index 2462c6e19d..0000000000
--- a/vendor/github.com/go-macaron/binding/.travis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-sudo: false
-language: go
-
-go:
-  - 1.3
-  - 1.4
-  - 1.5
-  - 1.6
-  - tip
-
-script: go test -v -cover -race
-
-notifications:
-  email:
-    - u@gogs.io
diff --git a/vendor/github.com/go-macaron/cache/.gitignore b/vendor/github.com/go-macaron/cache/.gitignore
deleted file mode 100644
index 69067d55d5..0000000000
--- a/vendor/github.com/go-macaron/cache/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-nodb/cache
-ledis/tmp.db/
-nodb/tmp.db/
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/cache/.travis.yml b/vendor/github.com/go-macaron/cache/.travis.yml
deleted file mode 100644
index 2774fb35d5..0000000000
--- a/vendor/github.com/go-macaron/cache/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-sudo: false
-language: go
-
-go:
-  - 1.3
-  - 1.4
-  - 1.5
-  - tip
-
-script: go test -v -cover -race
-
-notifications:
-  email:
-    - u@gogs.io
diff --git a/vendor/github.com/go-macaron/captcha/.travis.yml b/vendor/github.com/go-macaron/captcha/.travis.yml
deleted file mode 100644
index 81680f0f02..0000000000
--- a/vendor/github.com/go-macaron/captcha/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.6.x
-  - 1.7.x
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-
-script: go test -v -cover -race
diff --git a/vendor/github.com/go-macaron/cors/README.md b/vendor/github.com/go-macaron/cors/README.md
deleted file mode 100644
index be1cdca1a9..0000000000
--- a/vendor/github.com/go-macaron/cors/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# cors
-Package cors is a middleware that handles CORS requests &amp; headers for Macaron.
diff --git a/vendor/github.com/go-macaron/cors/go.mod b/vendor/github.com/go-macaron/cors/go.mod
deleted file mode 100644
index 6e03401924..0000000000
--- a/vendor/github.com/go-macaron/cors/go.mod
+++ /dev/null
@@ -1,11 +0,0 @@
-module github.com/go-macaron/cors
-
-go 1.12
-
-require (
-	github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 // indirect
-	github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 // indirect
-	golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect
-	gopkg.in/ini.v1 v1.42.0 // indirect
-	gopkg.in/macaron.v1 v1.3.2
-)
diff --git a/vendor/github.com/go-macaron/cors/go.sum b/vendor/github.com/go-macaron/cors/go.sum
deleted file mode 100644
index 782d98c540..0000000000
--- a/vendor/github.com/go-macaron/cors/go.sum
+++ /dev/null
@@ -1,19 +0,0 @@
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
-github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
-github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191 h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI=
-github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191/go.mod h1:VFI2o2q9kYsC4o7VP1HrEVosiZZTd+MVT3YZx4gqvJw=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE=
-github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w=
-github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
-golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
-golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
-gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/macaron.v1 v1.3.2 h1:AvWIaPmwBUA87/OWzePkoxeaw6YJWDfBt1pDFPBnLf8=
-gopkg.in/macaron.v1 v1.3.2/go.mod h1:PrsiawTWAGZs6wFbT5hlr7SQ2Ns9h7cUVtcUu4lQOVo=
diff --git a/vendor/github.com/go-macaron/csrf/.travis.yml b/vendor/github.com/go-macaron/csrf/.travis.yml
deleted file mode 100644
index 81680f0f02..0000000000
--- a/vendor/github.com/go-macaron/csrf/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.6.x
-  - 1.7.x
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-
-script: go test -v -cover -race
diff --git a/vendor/github.com/go-macaron/csrf/README.md b/vendor/github.com/go-macaron/csrf/README.md
deleted file mode 100644
index ff3e10a013..0000000000
--- a/vendor/github.com/go-macaron/csrf/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# csrf [![Build Status](https://travis-ci.org/go-macaron/csrf.svg?branch=master)](https://travis-ci.org/go-macaron/csrf) [![](http://gocover.io/_badge/github.com/go-macaron/csrf)](http://gocover.io/github.com/go-macaron/csrf)
-
-Middleware csrf generates and validates CSRF tokens for [Macaron](https://github.com/go-macaron/macaron).
-
-[API Reference](https://gowalker.org/github.com/go-macaron/csrf)
-
-### Installation
-
-	go get github.com/go-macaron/csrf
-	
-## Getting Help
-
-- [API Reference](https://gowalker.org/github.com/go-macaron/csrf)
-- [Documentation](http://go-macaron.com/docs/middlewares/csrf)
-
-## License
-
-This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/i18n/.travis.yml b/vendor/github.com/go-macaron/i18n/.travis.yml
deleted file mode 100644
index f331c2c84a..0000000000
--- a/vendor/github.com/go-macaron/i18n/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.6.x
-  - 1.7.x
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-  - 1.11.x
-
-script: go test -v -cover -race
diff --git a/vendor/github.com/go-macaron/i18n/README.md b/vendor/github.com/go-macaron/i18n/README.md
deleted file mode 100644
index 737c0b9950..0000000000
--- a/vendor/github.com/go-macaron/i18n/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# i18n [![Build Status](https://travis-ci.org/go-macaron/i18n.svg?branch=master)](https://travis-ci.org/go-macaron/i18n) [![](http://gocover.io/_badge/github.com/go-macaron/i18n)](http://gocover.io/github.com/go-macaron/i18n)
-
-Middleware i18n provides app Internationalization and Localization for [Macaron](https://github.com/go-macaron/macaron).
-
-### Installation
-
-	go get github.com/go-macaron/i18n
-	
-## Getting Help
-
-- [API Reference](https://gowalker.org/github.com/go-macaron/i18n)
-- [Documentation](http://go-macaron.com/docs/middlewares/i18n)
-
-## License
-
-This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/inject/.travis.yml b/vendor/github.com/go-macaron/inject/.travis.yml
deleted file mode 100644
index 2774fb35d5..0000000000
--- a/vendor/github.com/go-macaron/inject/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-sudo: false
-language: go
-
-go:
-  - 1.3
-  - 1.4
-  - 1.5
-  - tip
-
-script: go test -v -cover -race
-
-notifications:
-  email:
-    - u@gogs.io
diff --git a/vendor/github.com/go-macaron/session/.gitignore b/vendor/github.com/go-macaron/session/.gitignore
deleted file mode 100644
index 9297dbcd7c..0000000000
--- a/vendor/github.com/go-macaron/session/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-ledis/tmp.db
-nodb/tmp.db
\ No newline at end of file
diff --git a/vendor/github.com/go-macaron/session/.travis.yml b/vendor/github.com/go-macaron/session/.travis.yml
deleted file mode 100644
index bc978bae7f..0000000000
--- a/vendor/github.com/go-macaron/session/.travis.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-  - 1.11.x
-
-script: go test -v -cover -race
diff --git a/vendor/github.com/go-macaron/session/README.md b/vendor/github.com/go-macaron/session/README.md
deleted file mode 100644
index fe4f4ba1b3..0000000000
--- a/vendor/github.com/go-macaron/session/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# session [![Build Status](https://travis-ci.org/go-macaron/session.svg?branch=master)](https://travis-ci.org/go-macaron/session)
-
-Middleware session provides session management for [Macaron](https://github.com/go-macaron/macaron). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb.
-
-### Installation
-
-The minimum requirement of Go is 1.6 (*1.7 if using Redis, 1.8 if using MySQL*).
-
-	go get github.com/go-macaron/session
-	
-## Getting Help
-
-- [API Reference](https://gowalker.org/github.com/go-macaron/session)
-- [Documentation](https://go-macaron.com/docs/middlewares/session)
-
-## Credits
-
-This package is a modified version of [beego/session](https://github.com/astaxie/beego/tree/master/session).
-
-## License
-
-This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file
diff --git a/vendor/github.com/lib/pq/.travis.sh b/vendor/github.com/lib/pq/.travis.sh
index 21a526443d..ebf447030b 100644
--- a/vendor/github.com/lib/pq/.travis.sh
+++ b/vendor/github.com/lib/pq/.travis.sh
@@ -70,17 +70,4 @@ postgresql_uninstall() {
 	sudo rm -rf /var/lib/postgresql
 }
 
-megacheck_install() {
-	# Lock megacheck version at $MEGACHECK_VERSION to prevent spontaneous
-	# new error messages in old code.
-	go get -d honnef.co/go/tools/...
-	git -C $GOPATH/src/honnef.co/go/tools/ checkout $MEGACHECK_VERSION
-	go install honnef.co/go/tools/cmd/megacheck
-	megacheck --version
-}
-
-golint_install() {
-	go get golang.org/x/lint/golint
-}
-
 $1
diff --git a/vendor/github.com/lib/pq/.travis.yml b/vendor/github.com/lib/pq/.travis.yml
index f0305809f4..8396f5d9d4 100644
--- a/vendor/github.com/lib/pq/.travis.yml
+++ b/vendor/github.com/lib/pq/.travis.yml
@@ -1,9 +1,8 @@
 language: go
 
 go:
-  - 1.9.x
-  - 1.10.x
   - 1.11.x
+  - 1.12.x
   - master
 
 sudo: true
@@ -14,16 +13,11 @@ env:
     - PQGOSSLTESTS=1
     - PQSSLCERTTEST_PATH=$PWD/certs
     - PGHOST=127.0.0.1
-    - MEGACHECK_VERSION=2017.2.2
   matrix:
     - PGVERSION=10
     - PGVERSION=9.6
     - PGVERSION=9.5
     - PGVERSION=9.4
-    - PGVERSION=9.3
-    - PGVERSION=9.2
-    - PGVERSION=9.1
-    - PGVERSION=9.0
 
 before_install:
   - ./.travis.sh postgresql_uninstall
@@ -31,9 +25,9 @@ before_install:
   - ./.travis.sh postgresql_install
   - ./.travis.sh postgresql_configure
   - ./.travis.sh client_configure
-  - ./.travis.sh megacheck_install
-  - ./.travis.sh golint_install
   - go get golang.org/x/tools/cmd/goimports
+  - go get golang.org/x/lint/golint
+  - GO111MODULE=on go get honnef.co/go/tools/cmd/staticcheck@2019.2.1
 
 before_script:
   - createdb pqgotest
@@ -44,7 +38,7 @@ script:
   - >
     goimports -d -e $(find -name '*.go') | awk '{ print } END { exit NR == 0 ? 0 : 1 }'
   - go vet ./...
-  - megacheck -go 1.9 ./...
+  - staticcheck -go 1.11 ./...
   - golint ./...
   - PQTEST_BINARY_PARAMETERS=no  go test -race -v ./...
   - PQTEST_BINARY_PARAMETERS=yes go test -race -v ./...
diff --git a/vendor/github.com/lib/pq/buf.go b/vendor/github.com/lib/pq/buf.go
index 666b0012a7..4b0a0a8f7e 100644
--- a/vendor/github.com/lib/pq/buf.go
+++ b/vendor/github.com/lib/pq/buf.go
@@ -66,7 +66,7 @@ func (b *writeBuf) int16(n int) {
 }
 
 func (b *writeBuf) string(s string) {
-	b.buf = append(b.buf, (s + "\000")...)
+	b.buf = append(append(b.buf, s...), '\000')
 }
 
 func (b *writeBuf) byte(c byte) {
diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go
index 62551a1420..55152b1242 100644
--- a/vendor/github.com/lib/pq/conn.go
+++ b/vendor/github.com/lib/pq/conn.go
@@ -92,6 +92,7 @@ type Dialer interface {
 	DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
 }
 
+// DialerContext is the context-aware dialer interface.
 type DialerContext interface {
 	DialContext(ctx context.Context, network, address string) (net.Conn, error)
 }
@@ -301,6 +302,9 @@ func (c *Connector) open(ctx context.Context) (cn *conn, err error) {
 
 	err = cn.ssl(o)
 	if err != nil {
+		if cn.c != nil {
+			cn.c.Close()
+		}
 		return nil, err
 	}
 
@@ -546,7 +550,7 @@ func (cn *conn) Commit() (err error) {
 	// would get the same behaviour if you issued a COMMIT in a failed
 	// transaction, so it's also the least surprising thing to do here.
 	if cn.txnStatus == txnStatusInFailedTransaction {
-		if err := cn.Rollback(); err != nil {
+		if err := cn.rollback(); err != nil {
 			return err
 		}
 		return ErrInFailedTransaction
@@ -573,7 +577,10 @@ func (cn *conn) Rollback() (err error) {
 		return driver.ErrBadConn
 	}
 	defer cn.errRecover(&err)
+	return cn.rollback()
+}
 
+func (cn *conn) rollback() (err error) {
 	cn.checkIsInTransaction(true)
 	_, commandTag, err := cn.simpleExec("ROLLBACK")
 	if err != nil {
@@ -1500,6 +1507,39 @@ func QuoteIdentifier(name string) string {
 	return `"` + strings.Replace(name, `"`, `""`, -1) + `"`
 }
 
+// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal
+// to DDL and other statements that do not accept parameters) to be used as part
+// of an SQL statement.  For example:
+//
+//    exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z")
+//    err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))
+//
+// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be
+// replaced by two backslashes (i.e. "\\") and the C-style escape identifier
+// that PostgreSQL provides ('E') will be prepended to the string.
+func QuoteLiteral(literal string) string {
+	// This follows the PostgreSQL internal algorithm for handling quoted literals
+	// from libpq, which can be found in the "PQEscapeStringInternal" function,
+	// which is found in the libpq/fe-exec.c source file:
+	// https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c
+	//
+	// substitute any single-quotes (') with two single-quotes ('')
+	literal = strings.Replace(literal, `'`, `''`, -1)
+	// determine if the string has any backslashes (\) in it.
+	// if it does, replace any backslashes (\) with two backslashes (\\)
+	// then, we need to wrap the entire string with a PostgreSQL
+	// C-style escape. Per how "PQEscapeStringInternal" handles this case, we
+	// also add a space before the "E"
+	if strings.Contains(literal, `\`) {
+		literal = strings.Replace(literal, `\`, `\\`, -1)
+		literal = ` E'` + literal + `'`
+	} else {
+		// otherwise, we can just wrap the literal with a pair of single quotes
+		literal = `'` + literal + `'`
+	}
+	return literal
+}
+
 func md5s(s string) string {
 	h := md5.New()
 	h.Write([]byte(s))
diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go
index 3b0d365f29..a6902fae61 100644
--- a/vendor/github.com/lib/pq/encode.go
+++ b/vendor/github.com/lib/pq/encode.go
@@ -117,11 +117,10 @@ func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interfa
 		}
 		return i
 	case oid.T_float4, oid.T_float8:
-		bits := 64
-		if typ == oid.T_float4 {
-			bits = 32
-		}
-		f, err := strconv.ParseFloat(string(s), bits)
+		// We always use 64 bit parsing, regardless of whether the input text is for
+		// a float4 or float8, because clients expect float64s for all float datatypes
+		// and returning a 32-bit parsed float64 produces lossy results.
+		f, err := strconv.ParseFloat(string(s), 64)
 		if err != nil {
 			errorf("%s", err)
 		}
diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go
index 96aae29c65..3d66ba7c52 100644
--- a/vendor/github.com/lib/pq/error.go
+++ b/vendor/github.com/lib/pq/error.go
@@ -478,13 +478,13 @@ func errRecoverNoErrBadConn(err *error) {
 	}
 }
 
-func (c *conn) errRecover(err *error) {
+func (cn *conn) errRecover(err *error) {
 	e := recover()
 	switch v := e.(type) {
 	case nil:
 		// Do nothing
 	case runtime.Error:
-		c.bad = true
+		cn.bad = true
 		panic(v)
 	case *Error:
 		if v.Fatal() {
@@ -493,7 +493,7 @@ func (c *conn) errRecover(err *error) {
 			*err = v
 		}
 	case *net.OpError:
-		c.bad = true
+		cn.bad = true
 		*err = v
 	case error:
 		if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
@@ -503,13 +503,13 @@ func (c *conn) errRecover(err *error) {
 		}
 
 	default:
-		c.bad = true
+		cn.bad = true
 		panic(fmt.Sprintf("unknown error: %#v", e))
 	}
 
 	// Any time we return ErrBadConn, we need to remember it since *Tx doesn't
 	// mark the connection bad in database/sql.
 	if *err == driver.ErrBadConn {
-		c.bad = true
+		cn.bad = true
 	}
 }
diff --git a/vendor/github.com/lib/pq/scram/scram.go b/vendor/github.com/lib/pq/scram/scram.go
index 5d0358f8ff..484f378a76 100644
--- a/vendor/github.com/lib/pq/scram/scram.go
+++ b/vendor/github.com/lib/pq/scram/scram.go
@@ -22,7 +22,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Pacakage scram implements a SCRAM-{SHA-1,etc} client per RFC5802.
+// Package scram implements a SCRAM-{SHA-1,etc} client per RFC5802.
 //
 // http://tools.ietf.org/html/rfc5802
 //
diff --git a/vendor/github.com/mattn/go-sqlite3/.travis.yml b/vendor/github.com/mattn/go-sqlite3/.travis.yml
index 2ae08beb4d..eb0abbbbea 100644
--- a/vendor/github.com/mattn/go-sqlite3/.travis.yml
+++ b/vendor/github.com/mattn/go-sqlite3/.travis.yml
@@ -8,34 +8,24 @@ addons:
   apt:
     update: true
 
-env:
-  matrix:
-    - GOTAGS=
-    - GOTAGS=libsqlite3
-    - GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
-    - GOTAGS=sqlite_vacuum_full
-
 go:
   - 1.9.x
   - 1.10.x
   - 1.11.x
+  - master
 
 before_install:
   - |
-    if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then 
+    if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
       brew update
     fi
-  - |
-    go get github.com/smartystreets/goconvey
-    if [[ "${GOOS}" != "windows" ]]; then
-      go get github.com/mattn/goveralls
-      go get golang.org/x/tools/cmd/cover
-    fi
+  - go get github.com/smartystreets/goconvey
+  - go get github.com/mattn/goveralls
+  - go get golang.org/x/tools/cmd/cover
 
 script:
-  - GOOS=$(go env GOOS) GOARCH=$(go env GOARCH) go build -v -tags "${GOTAGS}" .
-  - |
-    if [[ "${GOOS}" != "windows" ]]; then
-      $HOME/gopath/bin/goveralls -repotoken 3qJVUE0iQwqnCbmNcDsjYu1nh4J4KIFXx
-      go test -race -v . -tags "${GOTAGS}"
-    fi
+  - $HOME/gopath/bin/goveralls -repotoken 3qJVUE0iQwqnCbmNcDsjYu1nh4J4KIFXx
+  - go test -race -v . -tags ""
+  - go test -race -v . -tags "libsqlite3"
+  - go test -race -v . -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
+  - go test -race -v . -tags "sqlite_vacuum_full"
\ No newline at end of file
diff --git a/vendor/github.com/mattn/go-sqlite3/README.md b/vendor/github.com/mattn/go-sqlite3/README.md
index 207f1cd1eb..8a87941e40 100644
--- a/vendor/github.com/mattn/go-sqlite3/README.md
+++ b/vendor/github.com/mattn/go-sqlite3/README.md
@@ -10,9 +10,7 @@ go-sqlite3
 
 sqlite3 driver conforming to the built-in database/sql interface
 
-Supported Golang version:
-- 1.9.x
-- 1.10.x
+Supported Golang version: See .travis.yml
 
 [This package follows the official Golang Release Policy.](https://golang.org/doc/devel/release.html#policy)
 
@@ -249,7 +247,7 @@ Required dependency
 brew install sqlite3
 ```
 
-For OSX there is an additional package install which is required if you whish to build the `icu` extension.
+For OSX there is an additional package install which is required if you wish to build the `icu` extension.
 
 This additional package can be installed with `homebrew`.
 
@@ -282,7 +280,7 @@ To compile this package on Windows OS you must have the `gcc` compiler installed
 3) Open a terminal for the TDM-GCC toolchain, can be found in the Windows Start menu.
 4) Navigate to your project folder and run the `go build ...` command for this package.
 
-For example the TDM-GCC Toolchain can be found [here](ttps://sourceforge.net/projects/tdm-gcc/).
+For example the TDM-GCC Toolchain can be found [here](https://sourceforge.net/projects/tdm-gcc/).
 
 ## Errors
 
@@ -458,15 +456,19 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
 
     Why is it racy if I use a `sql.Open("sqlite3", ":memory:")` database?
 
-    Each connection to :memory: opens a brand new in-memory sql database, so if
+    Each connection to `":memory:"` opens a brand new in-memory sql database, so if
     the stdlib's sql engine happens to open another connection and you've only
-    specified ":memory:", that connection will see a brand new database. A
-    workaround is to use "file::memory:?mode=memory&cache=shared". Every
-    connection to this string will point to the same in-memory database. 
+    specified `":memory:"`, that connection will see a brand new database. A
+    workaround is to use `"file::memory:?cache=shared"` (or `"file:foobar?mode=memory&cache=shared"`). Every
+    connection to this string will point to the same in-memory database.
+    
+    Note that if the last database connection in the pool closes, the in-memory database is deleted. Make sure the [max idle connection limit](https://golang.org/pkg/database/sql/#DB.SetMaxIdleConns) is > 0, and the [connection lifetime](https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime) is infinite.
     
     For more information see
     * [#204](https://github.com/mattn/go-sqlite3/issues/204)
     * [#511](https://github.com/mattn/go-sqlite3/issues/511)
+    * https://www.sqlite.org/sharedcache.html#shared_cache_and_in_memory_databases
+    * https://www.sqlite.org/inmemorydb.html#sharedmemdb
 
 - Reading from database with large amount of goroutines fails on OSX.
 
@@ -481,11 +483,11 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
 
     You need to implement the feature or call the sqlite3 cli.
 
-    More infomation see [#305](https://github.com/mattn/go-sqlite3/issues/305)
+    More information see [#305](https://github.com/mattn/go-sqlite3/issues/305)
 
 - Error: `database is locked`
 
-    When you get an database is locked. Please use the following options.
+    When you get a database is locked. Please use the following options.
 
     Add to DSN: `cache=shared`
 
@@ -497,7 +499,7 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
     Second please set the database connections of the SQL package to 1.
     
     ```go
-    db.SetMaxOpenConn(1)
+    db.SetMaxOpenConns(1)
     ```
 
     More information see [#209](https://github.com/mattn/go-sqlite3/issues/209)
diff --git a/vendor/github.com/mattn/go-sqlite3/callback.go b/vendor/github.com/mattn/go-sqlite3/callback.go
index 2c68973b85..e8c492b361 100644
--- a/vendor/github.com/mattn/go-sqlite3/callback.go
+++ b/vendor/github.com/mattn/go-sqlite3/callback.go
@@ -368,7 +368,7 @@ func callbackRet(typ reflect.Type) (callbackRetConverter, error) {
 func callbackError(ctx *C.sqlite3_context, err error) {
 	cstr := C.CString(err.Error())
 	defer C.free(unsafe.Pointer(cstr))
-	C.sqlite3_result_error(ctx, cstr, -1)
+	C.sqlite3_result_error(ctx, cstr, C.int(-1))
 }
 
 // Test support code. Tests are not allowed to import "C", so we can't
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
index 7763197505..140d096a88 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
@@ -1,7 +1,7 @@
 #ifndef USE_LIBSQLITE3
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.25.2.  By combining all the individual C code files into this
+** version 3.29.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
@@ -40,7 +40,7 @@
 ** SQLite was built with.
 */
 
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
 
 /*
 ** Include the configuration header output by 'configure' if we're using the
@@ -261,6 +261,9 @@ static const char * const sqlite3azCompileOpt[] = {
 #if SQLITE_ENABLE_FTS5
   "ENABLE_FTS5",
 #endif
+#if SQLITE_ENABLE_GEOPOLY
+  "ENABLE_GEOPOLY",
+#endif
 #if SQLITE_ENABLE_HIDDEN_COLUMNS
   "ENABLE_HIDDEN_COLUMNS",
 #endif
@@ -291,6 +294,9 @@ static const char * const sqlite3azCompileOpt[] = {
 #if SQLITE_ENABLE_MULTIPLEX
   "ENABLE_MULTIPLEX",
 #endif
+#if SQLITE_ENABLE_NORMALIZE
+  "ENABLE_NORMALIZE",
+#endif
 #if SQLITE_ENABLE_NULL_TRIM
   "ENABLE_NULL_TRIM",
 #endif
@@ -883,6 +889,11 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
 #pragma warning(disable : 4706)
 #endif /* defined(_MSC_VER) */
 
+#if defined(_MSC_VER) && !defined(_WIN64)
+#undef SQLITE_4_BYTE_ALIGNED_MALLOC
+#define SQLITE_4_BYTE_ALIGNED_MALLOC
+#endif /* defined(_MSC_VER) && !defined(_WIN64) */
+
 #endif /* SQLITE_MSVC_H */
 
 /************** End of msvc.h ************************************************/
@@ -1157,9 +1168,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.25.2"
-#define SQLITE_VERSION_NUMBER 3025002
-#define SQLITE_SOURCE_ID      "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
+#define SQLITE_VERSION        "3.29.0"
+#define SQLITE_VERSION_NUMBER 3029000
+#define SQLITE_SOURCE_ID      "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -1223,6 +1234,9 @@ SQLITE_API int sqlite3_libversion_number(void);
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
 SQLITE_API const char *sqlite3_compileoption_get(int N);
+#else
+# define sqlite3_compileoption_used(X) 0
+# define sqlite3_compileoption_get(X)  ((void*)0)
 #endif
 
 /*
@@ -1857,6 +1871,15 @@ struct sqlite3_io_methods {
 ** file space based on this hint in order to help writes to the database
 ** file run faster.
 **
+** <li>[[SQLITE_FCNTL_SIZE_LIMIT]]
+** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that
+** implements [sqlite3_deserialize()] to set an upper bound on the size
+** of the in-memory database.  The argument is a pointer to a [sqlite3_int64].
+** If the integer pointed to is negative, then it is filled in with the
+** current limit.  Otherwise the limit is set to the larger of the value
+** of the integer pointed to and the current database size.  The integer
+** pointed to is set to the new limit.
+**
 ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
 ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
 ** extends and truncates the database file in chunks of a size specified
@@ -2165,6 +2188,7 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
 #define SQLITE_FCNTL_LOCK_TIMEOUT           34
 #define SQLITE_FCNTL_DATA_VERSION           35
+#define SQLITE_FCNTL_SIZE_LIMIT             36
 
 /* deprecated names */
 #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -2317,8 +2341,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
 ** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
 ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
 ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable.   The file can be a
-** directory.
+** to test whether a file is at least readable.  The SQLITE_ACCESS_READ
+** flag is never actually used and is not implemented in the built-in
+** VFSes of SQLite.  The file is named by the second argument and can be a
+** directory. The xAccess method returns [SQLITE_OK] on success or some
+** non-zero error code if there is an I/O error or if the name of
+** the file given in the second argument is illegal.  If SQLITE_OK
+** is returned, then non-zero or zero is written into *pResOut to indicate
+** whether or not the file is accessible.  
 **
 ** ^SQLite will always allocate at least mxPathname+1 bytes for the
 ** output buffer xFullPathname.  The exact size of the output buffer
@@ -3006,6 +3036,17 @@ struct sqlite3_mem_methods {
 ** 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.
+**
+** [[SQLITE_CONFIG_MEMDB_MAXSIZE]]
+** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE
+** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter
+** [sqlite3_int64] parameter which is the default maximum size for an in-memory
+** database created using [sqlite3_deserialize()].  This default maximum
+** size can be adjusted up or down for individual databases using the
+** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control].  If this
+** configuration setting is never used, then the default maximum is determined
+** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option.  If that
+** compile-time option is not set, then the default maximum is 1073741824.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -3036,6 +3077,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
 #define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
 #define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+#define SQLITE_CONFIG_MEMDB_MAXSIZE       29  /* sqlite3_int64 */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -3051,6 +3093,7 @@ struct sqlite3_mem_methods {
 ** 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].
@@ -3073,6 +3116,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -3083,6 +3127,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -3093,9 +3138,10 @@ struct sqlite3_mem_methods {
 ** 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
+** <dd> ^This option is used to enable or disable the
+** [fts3_tokenizer()] function which is part of the
 ** [FTS3] full-text search engine extension.
 ** There should be two additional arguments.
 ** The first argument is an integer which is 0 to disable fts3_tokenizer() or
@@ -3106,6 +3152,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -3123,7 +3170,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -3132,6 +3179,7 @@ struct sqlite3_mem_methods {
 ** 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 
@@ -3145,7 +3193,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -3161,7 +3209,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -3173,7 +3221,7 @@ struct sqlite3_mem_methods {
 ** it is not disabled, 1 if it is.  
 ** </dd>
 **
-** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
+** [[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
@@ -3192,6 +3240,58 @@ struct sqlite3_mem_methods {
 ** 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> The [PRAGMA journal_mode=OFF] statement.
+** <li> Writes to the [sqlite_dbpage] virtual table.
+** <li> Direct writes to [shadow tables].
+** </ul>
+** </dd>
+**
+** [[SQLITE_DBCONFIG_WRITABLE_SCHEMA]] <dt>SQLITE_DBCONFIG_WRITABLE_SCHEMA</dt>
+** <dd>The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the
+** "writable_schema" flag. This has the same effect and is logically equivalent
+** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF].
+** The first argument to this setting is an integer which is 0 to disable 
+** the writable_schema, positive to enable writable_schema, 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 writable_schema
+** is enabled or disabled following this call.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
+** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
+** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
+** the legacy behavior of the [ALTER TABLE RENAME] command such it
+** behaves as it did prior to [version 3.24.0] (2018-06-04).  See the
+** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
+** additional information. This feature can also be turned on and off
+** using the [PRAGMA legacy_alter_table] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DML]]
+** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DML statement
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DDL]]
+** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DDL statements,
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
 ** </dd>
 ** </dl>
 */
@@ -3205,7 +3305,12 @@ struct sqlite3_mem_methods {
 #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_MAX                   1009 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
+#define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
+#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
+#define SQLITE_DBCONFIG_MAX                   1014 /* Largest DBCONFIG */
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -3362,7 +3467,7 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** 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
+** 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
@@ -4006,9 +4111,9 @@ SQLITE_API int sqlite3_set_authorizer(
 ** time is in units of nanoseconds, however the current implementation
 ** is only capable of millisecond resolution so the six least significant
 ** digits in the time are meaningless.  Future versions of SQLite
-** might provide greater resolution on the profiler callback.  The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
+** might provide greater resolution on the profiler callback.  Invoking
+** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+** profile callback.
 */
 SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
    void(*xTrace)(void*,const char*), void*);
@@ -4422,6 +4527,8 @@ SQLITE_API int sqlite3_open_v2(
 ** is not a database file pathname pointer that SQLite passed into the xOpen
 ** VFS method, then the behavior of this routine is undefined and probably
 ** undesirable.
+**
+** See the [URI filename] documentation for additional information.
 */
 SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
 SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
@@ -4643,9 +4750,24 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** 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 is a no-op. This flag used
+** to be required for any prepared statement that wanted to use the
+** [sqlite3_normalized_sql()] interface.  However, the
+** [sqlite3_normalized_sql()] interface is now available to all
+** prepared statements, regardless of whether or not they use this
+** flag.
+**
+** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
+** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
+** to return an error (error code SQLITE_ERROR) if the statement uses
+** any virtual tables.
 ** </dl>
 */
 #define SQLITE_PREPARE_PERSISTENT              0x01
+#define SQLITE_PREPARE_NORMALIZE               0x02
+#define SQLITE_PREPARE_NO_VTAB                 0x04
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
@@ -4803,6 +4925,11 @@ SQLITE_API int sqlite3_prepare16_v3(
 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
 ** string containing the SQL text of prepared statement P with
 ** [bound parameters] expanded.
+** ^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
@@ -4818,14 +4945,16 @@ SQLITE_API int sqlite3_prepare16_v3(
 ** 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()].
 */
 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
@@ -4863,6 +4992,18 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
 */
 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 
+/*
+** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the
+** prepared statement S is an EXPLAIN statement, or 2 if the
+** statement S is an EXPLAIN QUERY PLAN.
+** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
+** an ordinary statement or a NULL pointer.
+*/
+SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
+
 /*
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
 ** METHOD: sqlite3_stmt
@@ -5002,7 +5143,9 @@ typedef struct sqlite3_context sqlite3_context;
 ** ^The fifth argument to the BLOB and string binding interfaces
 ** is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
-** to dispose of the BLOB or string even if the call to bind API fails.
+** to dispose of the BLOB or string even if the call to the bind API fails,
+** except the destructor is not called if the third parameter is a NULL
+** pointer or the fourth parameter is negative.
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
 ** information is in static, unmanaged space and does not need to be freed.
@@ -5919,6 +6062,8 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** <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.
+** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
 ** </table></blockquote>
 **
 ** <b>Details:</b>
@@ -5980,6 +6125,11 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** than within an [xUpdate] method call for an UPDATE statement, then
 ** the return value is arbitrary and meaningless.
 **
+** ^The sqlite3_value_frombind(X) interface returns non-zero if the
+** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+** interfaces.  ^If X comes from an SQL literal value, or a table column,
+** and expression, then sqlite3_value_frombind(X) returns zero.
+**
 ** 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
@@ -6025,6 +6175,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*);
+SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
 
 /*
 ** CAPI3REF: Finding The Subtype Of SQL Values
@@ -6760,7 +6911,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 ** associated with database N of connection D.  ^The main database file
 ** has the name "main".  If there is no attached database N on the database
 ** connection D, or if database N is a temporary or in-memory database, then
-** a NULL pointer is returned.
+** this function will return either a NULL pointer or an empty string.
 **
 ** ^The filename returned by this function is the output of the
 ** xFullPathname method of the [VFS].  ^In other words, the filename
@@ -7315,6 +7466,9 @@ struct sqlite3_module {
   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*);
 };
 
 /*
@@ -8237,6 +8391,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
 #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
@@ -8247,7 +8402,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_SORTER_MMAP             24
 #define SQLITE_TESTCTRL_IMPOSTER                25
 #define SQLITE_TESTCTRL_PARSER_COVERAGE         26
-#define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_RESULT_INTREAL          27
+#define SQLITE_TESTCTRL_LAST                    27  /* Largest TESTCTRL */
 
 /*
 ** CAPI3REF: SQL Keyword Checking
@@ -9649,6 +9805,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
 ** 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,
@@ -10418,7 +10575,7 @@ struct sqlite3_rtree_query_info {
   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 */
@@ -10914,12 +11071,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
 ** 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 */
   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
 
 
 /*
@@ -10963,7 +11146,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
 ** sqlite3changeset_next() is called on the iterator or until the 
 ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
 ** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
 ** is an indirect change, or false (0) otherwise. See the documentation for
 ** [sqlite3session_indirect()] for a description of direct and indirect
 ** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
@@ -11574,7 +11757,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
   ),
   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 */
 );
 
 /*
@@ -11592,8 +11775,14 @@ SQLITE_API int sqlite3changeset_apply_v2(
 **   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
@@ -11824,7 +12013,7 @@ SQLITE_API int sqlite3rebaser_configure(
 ** 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 
+** is set to point to the new buffer containing the rebased changeset 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)
@@ -11987,6 +12176,12 @@ SQLITE_API int sqlite3changeset_start_strm(
   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),
@@ -12013,6 +12208,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
   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++.
@@ -12146,12 +12380,8 @@ struct Fts5PhraseIter {
 **
 **   Usually, output parameter *piPhrase is set to the phrase number, *piCol
 **   to the column in which it occurs and *piOff the token offset of the
-**   first token of the phrase. The exception is if the table was created
-**   with the offsets=0 option specified. In this case *piOff is always
-**   set to -1.
-**
-**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
-**   if an error occurs.
+**   first token of the phrase. Returns SQLITE_OK if successful, or an error
+**   code (i.e. SQLITE_NOMEM) if an error occurs.
 **
 **   This API can be quite slow if used with an FTS5 table created with the
 **   "detail=none" or "detail=column" option. 
@@ -12192,7 +12422,7 @@ struct Fts5PhraseIter {
 **   Save the pointer passed as the second argument as the extension functions 
 **   "auxiliary data". The pointer may then be retrieved by the current or any
 **   future invocation of the same fts5 extension function made as part of
-**   of the same MATCH query using the xGetAuxdata() API.
+**   the same MATCH query using the xGetAuxdata() API.
 **
 **   Each extension function is allocated a single auxiliary data slot for
 **   each FTS query (MATCH expression). If the extension function is invoked 
@@ -12207,7 +12437,7 @@ struct Fts5PhraseIter {
 **   The xDelete callback, if one is specified, is also invoked on the
 **   auxiliary data pointer after the FTS5 query has finished.
 **
-**   If an error (e.g. an OOM condition) occurs within this function, an
+**   If an error (e.g. an OOM condition) occurs within this function,
 **   the auxiliary data is set to NULL and an error code returned. If the
 **   xDelete parameter was not NULL, it is invoked on the auxiliary data
 **   pointer before returning.
@@ -12440,11 +12670,11 @@ struct Fts5ExtensionApi {
 **            the tokenizer substitutes "first" for "1st" and the query works
 **            as expected.
 **
-**       <li> By adding multiple synonyms for a single term to the FTS index.
-**            In this case, when tokenizing query text, the tokenizer may 
-**            provide multiple synonyms for a single term within the document.
-**            FTS5 then queries the index for each synonym individually. For
-**            example, faced with the query:
+**       <li> By querying the index for all synonyms of each query term
+**            separately. In this case, when tokenizing query text, the
+**            tokenizer may provide multiple synonyms for a single term 
+**            within the document. FTS5 then queries the index for each 
+**            synonym individually. For example, faced with the query:
 **
 **   <codeblock>
 **     ... MATCH 'first place'</codeblock>
@@ -12468,7 +12698,7 @@ struct Fts5ExtensionApi {
 **            "place".
 **
 **            This way, even if the tokenizer does not provide synonyms
-**            when tokenizing query text (it should not - to do would be
+**            when tokenizing query text (it should not - to do so would be
 **            inefficient), it doesn't matter if the user queries for 
 **            'first + place' or '1st + place', as there are entries in the
 **            FTS index corresponding to both forms of the first token.
@@ -13233,7 +13463,7 @@ struct Hash {
   unsigned int count;       /* Number of entries in this table */
   HashElem *first;          /* The first element of the array */
   struct _ht {              /* the hash table */
-    int count;                 /* Number of entries with this hash */
+    unsigned int count;        /* Number of entries with this hash */
     HashElem *chain;           /* Pointer to first entry with this hash */
   } *ht;
 };
@@ -13374,99 +13604,94 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #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  
-
-/* Flags that can be added to a token code when it is not
-** being stored in a u8: */
-#define TKFLG_DONTFOLD       0x100  /* Omit constant folding optimizations */
+#define TK_EXCLUDE                         88
+#define TK_GROUPS                          89
+#define TK_OTHERS                          90
+#define TK_TIES                            91
+#define TK_REINDEX                         92
+#define TK_RENAME                          93
+#define TK_CTIME_KW                        94
+#define TK_ANY                             95
+#define TK_BITAND                          96
+#define TK_BITOR                           97
+#define TK_LSHIFT                          98
+#define TK_RSHIFT                          99
+#define TK_PLUS                           100
+#define TK_MINUS                          101
+#define TK_STAR                           102
+#define TK_SLASH                          103
+#define TK_REM                            104
+#define TK_CONCAT                         105
+#define TK_COLLATE                        106
+#define TK_BITNOT                         107
+#define TK_ON                             108
+#define TK_INDEXED                        109
+#define TK_STRING                         110
+#define TK_JOIN_KW                        111
+#define TK_CONSTRAINT                     112
+#define TK_DEFAULT                        113
+#define TK_NULL                           114
+#define TK_PRIMARY                        115
+#define TK_UNIQUE                         116
+#define TK_CHECK                          117
+#define TK_REFERENCES                     118
+#define TK_AUTOINCR                       119
+#define TK_INSERT                         120
+#define TK_DELETE                         121
+#define TK_UPDATE                         122
+#define TK_SET                            123
+#define TK_DEFERRABLE                     124
+#define TK_FOREIGN                        125
+#define TK_DROP                           126
+#define TK_UNION                          127
+#define TK_ALL                            128
+#define TK_EXCEPT                         129
+#define TK_INTERSECT                      130
+#define TK_SELECT                         131
+#define TK_VALUES                         132
+#define TK_DISTINCT                       133
+#define TK_DOT                            134
+#define TK_FROM                           135
+#define TK_JOIN                           136
+#define TK_USING                          137
+#define TK_ORDER                          138
+#define TK_GROUP                          139
+#define TK_HAVING                         140
+#define TK_LIMIT                          141
+#define TK_WHERE                          142
+#define TK_INTO                           143
+#define TK_NOTHING                        144
+#define TK_FLOAT                          145
+#define TK_BLOB                           146
+#define TK_INTEGER                        147
+#define TK_VARIABLE                       148
+#define TK_CASE                           149
+#define TK_WHEN                           150
+#define TK_THEN                           151
+#define TK_ELSE                           152
+#define TK_INDEX                          153
+#define TK_ALTER                          154
+#define TK_ADD                            155
+#define TK_WINDOW                         156
+#define TK_OVER                           157
+#define TK_FILTER                         158
+#define TK_TRUEFALSE                      159
+#define TK_ISNOT                          160
+#define TK_FUNCTION                       161
+#define TK_COLUMN                         162
+#define TK_AGG_FUNCTION                   163
+#define TK_AGG_COLUMN                     164
+#define TK_UMINUS                         165
+#define TK_UPLUS                          166
+#define TK_TRUTH                          167
+#define TK_REGISTER                       168
+#define TK_VECTOR                         169
+#define TK_SELECT_COLUMN                  170
+#define TK_IF_NULL_ROW                    171
+#define TK_ASTERISK                       172
+#define TK_SPAN                           173
+#define TK_SPACE                          174
+#define TK_ILLEGAL                        175
 
 /************** End of parse.h ***********************************************/
 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -13772,12 +13997,13 @@ typedef INT16_TYPE LogEst;
 ** at run-time.
 */
 #ifndef SQLITE_BYTEORDER
-# if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
-     defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
-     defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
-     defined(__arm__)  || defined(_M_ARM64)
+# 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(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
 #   define SQLITE_BYTEORDER    1234
-# elif defined(sparc)    || defined(__ppc__)
+# elif defined(sparc)     || defined(__ppc__) || \
+       defined(__ARMEB__) || defined(__AARCH64EB__)
 #   define SQLITE_BYTEORDER    4321
 # else
 #   define SQLITE_BYTEORDER 0
@@ -14398,9 +14624,6 @@ struct BtreePayload {
 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*);
@@ -14412,6 +14635,7 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
 SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
 SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
 
 SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
 SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
@@ -14651,12 +14875,11 @@ typedef struct VdbeOpList VdbeOpList;
 #endif
 
 /*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that 
-** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
-** the macro again restores the address.
+** The following macro converts a label returned by sqlite3VdbeMakeLabel()
+** into an index into the Parse.aLabel[] array that contains the resolved
+** address of that label.
 */
-#define ADDR(X)  (-1-(X))
+#define ADDR(X)  (~(X))
 
 /*
 ** The makefile scans the vdbe.c source file and creates the "opcodes.h"
@@ -14758,25 +14981,25 @@ typedef struct VdbeOpList VdbeOpList;
 #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_MakeRecord     92 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+#define OP_Count          93 /* synopsis: r[P2]=count()                    */
+#define OP_ReadCookie     94
+#define OP_SetCookie      95
+#define OP_BitAnd         96 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr          97 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft      98 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight     99 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add           100 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract      101 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply      102 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide        103 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder     104 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat        105 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_ReopenIdx     106 /* synopsis: root=P2 iDb=P3                   */
+#define OP_BitNot        107 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
+#define OP_OpenRead      108 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenWrite     109 /* synopsis: root=P2 iDb=P3                   */
+#define OP_String8       110 /* same as TK_STRING, synopsis: r[P2]='P4'    */
 #define OP_OpenDup       111
 #define OP_OpenAutoindex 112 /* synopsis: nColumn=P2                       */
 #define OP_OpenEphemeral 113 /* synopsis: nColumn=P2                       */
@@ -14789,57 +15012,56 @@ typedef struct VdbeOpList VdbeOpList;
 #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
+#define OP_Delete        123
+#define OP_ResetCount    124
+#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData    126 /* synopsis: r[P2]=data                       */
+#define OP_RowData       127 /* synopsis: r[P2]=data                       */
+#define OP_Rowid         128 /* synopsis: r[P2]=rowid                      */
+#define OP_NullRow       129
+#define OP_SeekEnd       130
+#define OP_SorterInsert  131 /* synopsis: key=r[P2]                        */
+#define OP_IdxInsert     132 /* synopsis: key=r[P2]                        */
+#define OP_IdxDelete     133 /* synopsis: key=r[P2@P3]                     */
+#define OP_DeferredSeek  134 /* synopsis: Move P3 to P1.rowid if needed    */
+#define OP_IdxRowid      135 /* synopsis: r[P2]=rowid                      */
+#define OP_Destroy       136
+#define OP_Clear         137
+#define OP_ResetSorter   138
+#define OP_CreateBtree   139 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
+#define OP_SqlExec       140
+#define OP_ParseSchema   141
+#define OP_LoadAnalysis  142
+#define OP_DropTable     143
+#define OP_DropIndex     144
+#define OP_Real          145 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
+#define OP_DropTrigger   146
+#define OP_IntegrityCk   147
+#define OP_RowSetAdd     148 /* synopsis: rowset(P1)=r[P2]                 */
+#define OP_Param         149
+#define OP_FkCounter     150 /* synopsis: fkctr[P1]+=P2                    */
+#define OP_MemMax        151 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+#define OP_OffsetLimit   152 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggInverse    153 /* synopsis: accum=r[P3] inverse(r[P2@P5])    */
+#define OP_AggStep       154 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+#define OP_AggStep1      155 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+#define OP_AggValue      156 /* synopsis: r[P3]=value N=P2                 */
+#define OP_AggFinal      157 /* synopsis: accum=r[P1] N=P2                 */
+#define OP_Expire        158
+#define OP_TableLock     159 /* synopsis: iDb=P1 root=P2 write=P3          */
+#define OP_VBegin        160
+#define OP_VCreate       161
+#define OP_VDestroy      162
+#define OP_VOpen         163
+#define OP_VColumn       164 /* synopsis: r[P3]=vcolumn(P2)                */
+#define OP_VRename       165
+#define OP_Pagecount     166
+#define OP_MaxPgcnt      167
+#define OP_Trace         168
+#define OP_CursorHint    169
+#define OP_Noop          170
+#define OP_Explain       171
+#define OP_Abortable     172
 
 /* Properties such as "out2" or "jump" that are specified in
 ** comments following the "case" for each opcode in the vdbe.c
@@ -14863,17 +15085,17 @@ typedef struct VdbeOpList VdbeOpList;
 /*  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,\
+/*  88 */ 0x12, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
+/*  96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/* 104 */ 0x26, 0x26, 0x00, 0x12, 0x00, 0x00, 0x10, 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,}
+/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\
+/* 136 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 144 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
+/* 152 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
+/* 168 */ 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
@@ -14932,6 +15154,12 @@ SQLITE_PRIVATE   int sqlite3VdbeExplainParent(Parse*);
 # define ExplainQueryPlan(P)
 # define ExplainQueryPlanPop(P)
 # define ExplainQueryPlanParent(P) 0
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
+#endif
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
+SQLITE_PRIVATE   void sqlite3ExplainBreakpoint(const char*,const char*);
+#else
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
 #endif
 SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
 SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
@@ -14947,7 +15175,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
 SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
 SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
@@ -14968,6 +15196,10 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
 SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
 SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
+#endif
 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
@@ -15278,9 +15510,6 @@ SQLITE_PRIVATE   int sqlite3PagerWalSupported(Pager *pPager);
 SQLITE_PRIVATE   int sqlite3PagerWalCallback(Pager *pPager);
 SQLITE_PRIVATE   int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
 SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager, 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);
@@ -15288,8 +15517,10 @@ 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
@@ -15534,6 +15765,10 @@ SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
 /* 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 **********************************************/
@@ -16039,12 +16274,14 @@ struct LookasideSlot {
 ** 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
 /*
@@ -16088,10 +16325,13 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
 /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
 ** in the style of sqlite3_trace()
 */
-#define SQLITE_TRACE_LEGACY  0x80
+#define SQLITE_TRACE_LEGACY          0x40     /* Use the legacy xTrace */
+#define SQLITE_TRACE_XPROFILE        0x80     /* Use the legacy xProfile */
 #else
-#define SQLITE_TRACE_LEGACY  0
+#define SQLITE_TRACE_LEGACY          0
+#define SQLITE_TRACE_XPROFILE        0
 #endif /* SQLITE_OMIT_DEPRECATED */
+#define SQLITE_TRACE_NONLEGACY_MASK  0x0f     /* Normal flags */
 
 
 /*
@@ -16105,7 +16345,7 @@ struct sqlite3 {
   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 */
@@ -16150,14 +16390,17 @@ struct sqlite3 {
   void **aExtension;            /* Array of shared library handles */
   int (*xTrace)(u32,void*,void*,void*);     /* Trace function */
   void *pTraceArg;                          /* Argument to the trace function */
+#ifndef SQLITE_OMIT_DEPRECATED
   void (*xProfile)(void*,const char*,u64);  /* Profiling function */
   void *pProfileArg;                        /* Argument to profile function */
+#endif
   void *pCommitArg;                 /* Argument to xCommitCallback() */
   int (*xCommitCallback)(void*);    /* Invoked at every commit. */
   void *pRollbackArg;               /* Argument to xRollbackCallback() */
   void (*xRollbackCallback)(void*); /* Invoked at every commit. */
   void *pUpdateArg;
   void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
+  Parse *pParse;                /* Current parse */
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
   void *pPreUpdateArg;          /* First argument to xPreUpdateCallback */
   void (*xPreUpdateCallback)(   /* Registered using sqlite3_preupdate_hook() */
@@ -16271,14 +16514,20 @@ struct sqlite3 {
 #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 */
+#define SQLITE_DqsDDL         0x20000000  /* dbl-quoted strings allowed in DDL*/
+#define SQLITE_DqsDML         0x40000000  /* dbl-quoted strings allowed in DML*/
 
 /* 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 */
+#define SQLITE_ParserTrace    HI(0x0020)  /* PRAGMA parser_trace=ON */
 #endif
 
 /*
@@ -16287,7 +16536,8 @@ struct sqlite3 {
 #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 */
+#define DBFLAG_VacuumInto     0x0008  /* Currently running VACUUM INTO */
+#define DBFLAG_SchemaKnownOk  0x0010  /* Schema is known to be valid */
 
 /*
 ** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -16295,7 +16545,7 @@ struct sqlite3 {
 ** selectively disable various optimizations.
 */
 #define SQLITE_QueryFlattener 0x0001   /* Query flattening */
-                          /*  0x0002   available for reuse */
+#define SQLITE_WindowFunc     0x0002   /* Use xInverse for window functions */
 #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
 #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
 #define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
@@ -16412,8 +16662,8 @@ struct FuncDestructor {
                                     ** 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  0x10000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE  0x20000  /* Requires partition size as arg. */
+#define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
 
 /*
 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -16489,10 +16739,13 @@ struct FuncDestructor {
 #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,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
@@ -16727,6 +16980,7 @@ struct Table {
 #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
@@ -16962,7 +17216,7 @@ struct Index {
   u16 nKeyCol;             /* Number of columns forming the key */
   u16 nColumn;             /* Number of columns stored in the index */
   u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
-  unsigned idxType:2;      /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
+  unsigned idxType:2;      /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
   unsigned bUnordered:1;   /* Use this index for == or IN queries only */
   unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
   unsigned isResized:1;    /* True if resizeIndexObject() has been called */
@@ -16970,6 +17224,7 @@ struct 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 */
+  unsigned bAscKeyBug:1;   /* True if the bba7b69f9849b5bf bug applies */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   int nSample;             /* Number of elements in aSample[] */
   int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
@@ -16987,6 +17242,7 @@ struct Index {
 #define SQLITE_IDXTYPE_APPDEF      0   /* Created using CREATE INDEX */
 #define SQLITE_IDXTYPE_UNIQUE      1   /* Implements a UNIQUE constraint */
 #define SQLITE_IDXTYPE_PRIMARYKEY  2   /* Is the PRIMARY KEY for the table */
+#define SQLITE_IDXTYPE_IPK         3   /* INTEGER PRIMARY KEY index */
 
 /* Return true if index X is a PRIMARY KEY index */
 #define IsPrimaryKeyIndex(X)  ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
@@ -17013,6 +17269,12 @@ struct IndexSample {
   tRowcnt *anDLt;   /* Est. number of distinct keys less than this sample */
 };
 
+/*
+** 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.
@@ -17190,25 +17452,33 @@ struct Expr {
                          ** TK_SELECT_COLUMN: column of the result vector */
   i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
   i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
-  u8 op2;                /* TK_REGISTER: original value of Expr.op
+  u8 op2;                /* TK_REGISTER/TK_TRUTH: original value of Expr.op
                          ** 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 */
-#ifndef SQLITE_OMIT_WINDOWFUNC
-  Window *pWin;          /* Window definition for window functions */
-#endif
+  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 */
+    struct {               /* TK_IN, TK_SELECT, and TK_EXISTS */
+      int iAddr;             /* Subroutine entry address */
+      int regReturn;         /* Register used to hold return address */
+    } sub;
+  } y;
 };
 
 /*
 ** The following are the meanings of bits in the Expr.flags field.
+** Value restrictions:
+**
+**          EP_Agg == NC_HasAgg == SF_HasAgg
+**          EP_Win == NC_HasWin
 */
 #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
-#define EP_Agg       0x000002 /* Contains one or more aggregate functions */
+#define EP_Distinct  0x000002 /* Aggregate function with DISTINCT keyword */
 #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_Agg       0x000010 /* Contains one or more aggregate functions */
 #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
 #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
 #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
@@ -17216,10 +17486,10 @@ struct Expr {
 #define EP_Generic   0x000200 /* Ignore COLLATE or affinity on this tree */
 #define EP_IntValue  0x000400 /* Integer value contained in u.iValue */
 #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Skip      0x001000 /* COLLATE, AS, or UNLIKELY */
+#define EP_Skip      0x001000 /* Operator does not contribute to affinity */
 #define EP_Reduced   0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
 #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static    0x008000 /* Held in memory not obtained from malloc() */
+#define EP_Win       0x008000 /* Contains window functions */
 #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
 #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
 #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
@@ -17228,6 +17498,12 @@ struct Expr {
 #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 */
+#define EP_Subrtn   0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
+#define EP_Quoted   0x4000000 /* TK_ID was originally quoted */
+#define EP_Static   0x8000000 /* Held in memory not obtained from malloc() */
+#define EP_IsTrue  0x10000000 /* Always has boolean value of TRUE */
+#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
 
 /*
 ** The EP_Propagate mask is a set of properties that automatically propagate
@@ -17243,6 +17519,8 @@ struct Expr {
 #define ExprHasAllProperty(E,P)  (((E)->flags&(P))==(P))
 #define ExprSetProperty(E,P)     (E)->flags|=(P)
 #define ExprClearProperty(E,P)   (E)->flags&=~(P)
+#define ExprAlwaysTrue(E)   (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
+#define ExprAlwaysFalse(E)  (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
 
 /* The ExprSetVVAProperty() macro is used for Verification, Validation,
 ** and Accreditation only.  It works like ExprSetProperty() during VVA
@@ -17459,7 +17737,7 @@ struct NameContext {
   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 */
+  int ncFlags;         /* Zero or more NC_* flags defined below */
   Select *pWinSelect;  /* SELECT statement for any window functions */
 };
 
@@ -17467,8 +17745,9 @@ struct NameContext {
 ** Allowed values for the NameContext, ncFlags field.
 **
 ** Value constraints (all checked via assert()):
-**    NC_HasAgg    == SF_HasAgg
+**    NC_HasAgg    == SF_HasAgg    == EP_Agg
 **    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
+**    NC_HasWin    == EP_Win
 **
 */
 #define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
@@ -17484,6 +17763,8 @@ struct NameContext {
 #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 */
+#define NC_HasWin    0x8000  /* One or more window functions seen */
+#define NC_IsDDL    0x10000  /* Resolving names in a CREATE statement */
 
 /*
 ** An instance of the following object describes a single ON CONFLICT
@@ -17771,16 +18052,17 @@ struct Parse {
   u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
   u8 okConstFactor;    /* OK to factor out constants */
   u8 disableLookaside; /* Number of times lookaside has been disabled */
+  u8 disableVtab;      /* Disable all virtual tables for this parse */
   int nRangeReg;       /* Size of the temporary register block */
   int iRangeReg;       /* First register in temporary register block */
   int nErr;            /* Number of errors seen */
   int nTab;            /* Number of previously allocated VDBE cursors */
   int nMem;            /* Number of memory cells used so far */
-  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
   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 nLabel;          /* Number of labels used */
+  int nLabel;          /* The *negative* of the number of labels used */
+  int nLabelAlloc;     /* Number of slots in aLabel */
   int *aLabel;         /* Space to hold the labels */
   ExprList *pConstExpr;/* Constant expressions */
   Token constraintName;/* Name of the constraint currently being parsed */
@@ -17797,6 +18079,7 @@ struct Parse {
   AutoincInfo *pAinc;  /* Information about AUTOINCREMENT counters */
   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
   Table *pTriggerTab;  /* Table triggers are being coded for */
+  Parse *pParentParse; /* Parent parser if this parser is nested */
   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 */
@@ -17840,7 +18123,9 @@ struct Parse {
   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 */
+  Index *pNewIndex;         /* An index being constructed by CREATE INDEX.
+                            ** Also used to hold redundant UNIQUE constraints
+                            ** during a RENAME COLUMN */
   Trigger *pNewTrigger;     /* Trigger under construct by a CREATE TRIGGER */
   const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -17913,6 +18198,7 @@ struct AuthContext {
 */
 #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 */
@@ -18067,6 +18353,7 @@ typedef struct {
   int iDb;            /* 0 for main database.  1 for TEMP, 2.. for ATTACHed */
   int rc;             /* Result code stored here */
   u32 mInitFlags;     /* Flags controlling error messages */
+  u32 nInitRow;       /* Number of rows processed */
 } InitData;
 
 /*
@@ -18127,10 +18414,14 @@ struct Sqlite3Config {
   void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx);  /* Callback */
   void *pVdbeBranchArg;                                     /* 1st argument */
 #endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+  sqlite3_int64 mxMemdbSize;        /* Default max memdb size */
+#endif
 #ifndef SQLITE_UNTESTABLE
   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 */
 };
@@ -18229,7 +18520,7 @@ struct TreeView {
 #endif /* SQLITE_DEBUG */
 
 /*
-** This object is used in varioius ways, all related to window functions
+** This object is used in various 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.
@@ -18244,15 +18535,18 @@ struct TreeView {
 **       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.
+** to be accessible in two different ways.  Use case (3) are separate objects.
 */
 struct Window {
   char *zName;            /* Name of window (may be NULL) */
+  char *zBase;            /* Name of base window for chaining (may be NULL) */
   ExprList *pPartition;   /* PARTITION BY clause */
   ExprList *pOrderBy;     /* ORDER BY clause */
-  u8 eType;               /* TK_RANGE or TK_ROWS */
+  u8 eFrmType;            /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
   u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
   u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
+  u8 bImplicitFrame;      /* True if frame was implicitly specified */
+  u8 eExclude;            /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
   Expr *pStart;           /* Expression for "<expr> PRECEDING" */
   Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
   Window *pNextWin;       /* Next window function belonging to this SELECT */
@@ -18263,17 +18557,19 @@ struct Window {
   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 */
+  int regPart;            /* Array of registers for PARTITION BY values */
   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 */
+  int regOne;             /* Register containing constant value 1 */
+  int regStartRowid;
+  int regEndRowid;
 };
 
 #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 Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
 SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
 SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*);
 SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
@@ -18284,6 +18580,8 @@ 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);
+SQLITE_PRIVATE void sqlite3WindowChain(Parse*, Window*, Window*);
+SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
 #else
 # define sqlite3WindowDelete(a,b)
 # define sqlite3WindowFunctions()
@@ -18384,6 +18682,7 @@ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
 */
 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
 
@@ -18472,8 +18771,12 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
 #endif
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
+# define EXP754 (((u64)0x7ff)<<52)
+# define MAN754 ((((u64)1)<<52)-1)
+# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
 SQLITE_PRIVATE   int sqlite3IsNaN(double);
 #else
+# define IsNaN(X)         0
 # define sqlite3IsNaN(X)  0
 #endif
 
@@ -18500,6 +18803,7 @@ SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
 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
@@ -18511,7 +18815,9 @@ SQLITE_PRIVATE   void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
 
 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
+SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
 SQLITE_PRIVATE void sqlite3Dequote(char*);
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
 SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
 SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
 SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
@@ -18529,10 +18835,12 @@ SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
 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 *sqlite3ExprAnd(Parse*,Expr*, Expr*);
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
 SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
 SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
 SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
 SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
@@ -18540,6 +18848,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
 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 sqlite3IndexHasDuplicateRootPage(Index*);
 SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
 SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
 SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -18573,6 +18882,11 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
 SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
 SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
                     sqlite3_vfs**,char**,char **);
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE   int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
+#else
+# define sqlite3CodecQueryParameters(A,B,C) 0
+#endif
 SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
 
 #ifdef SQLITE_UNTESTABLE
@@ -18625,8 +18939,8 @@ SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upser
 SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
 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*);
+SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
+SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
 SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
                                       Token*, Select*, Expr*, IdList*);
 SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@@ -18693,8 +19007,8 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_ite
 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
+SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
+SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
 SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
 SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
@@ -18737,6 +19051,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
 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*,Upsert*);
 #ifdef SQLITE_ENABLE_NULL_TRIM
@@ -18757,6 +19072,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*);
 SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
@@ -18833,6 +19149,7 @@ SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
 SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
 SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
 SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64);
 SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
 SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
 SQLITE_PRIVATE int sqlite3Atoi(const char*);
@@ -18914,6 +19231,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Toke
 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);
@@ -18933,6 +19251,9 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
                         void(*)(void*));
 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
+#ifndef SQLITE_UNTESTABLE
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
+#endif
 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
@@ -18962,14 +19283,15 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
 SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -19117,6 +19439,9 @@ 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 char *sqlite3Normalize(Vdbe*, const char*);
+#endif
 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
@@ -19211,7 +19536,7 @@ SQLITE_PRIVATE   void sqlite3EndBenignMalloc(void);
 #define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
 #define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
 #define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
 
 SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
 SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
@@ -19491,8 +19816,15 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 ** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
 ** that compile-time option is omitted.
 */
-#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
+#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
 # define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+#else
+# if !SQLITE_ALLOW_COVERING_INDEX_SCAN 
+#   error "Compile-time disabling of covering index scan using the\
+ -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
+ Contact SQLite developers if this is a problem for you, and\
+ delete this #error macro to continue with your build."
+# endif
 #endif
 
 /* The minimum PMA size is set to this value multiplied by the database
@@ -19527,6 +19859,13 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 #endif
 
 
+/* The default maximum size of an in-memory database created using
+** sqlite3_deserialize()
+*/
+#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE
+# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824
+#endif
+
 /*
 ** The following singleton contains the global configuration for
 ** the SQLite library.
@@ -19574,12 +19913,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    0,                         /* xVdbeBranch */
    0,                         /* pVbeBranchArg */
 #endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+   SQLITE_MEMDB_DEFAULT_MAXSIZE,   /* mxMemdbSize */
+#endif
 #ifndef SQLITE_UNTESTABLE
    0,                         /* xTestCallback */
 #endif
    0,                         /* bLocaltimeFault */
+   0,                         /* bInternalFunctions */
    0x7ffffffe,                /* iOnceResetThreshold */
-   SQLITE_DEFAULT_SORTERREF_SIZE   /* szSorterRef */
+   SQLITE_DEFAULT_SORTERREF_SIZE,   /* szSorterRef */
 };
 
 /*
@@ -19908,12 +20251,12 @@ struct sqlite3_value {
 #define MEM_Int       0x0004   /* Value is an integer */
 #define MEM_Real      0x0008   /* Value is a real number */
 #define MEM_Blob      0x0010   /* Value is a BLOB */
-#define MEM_AffMask   0x001f   /* Mask of affinity bits */
-/* Available          0x0020   */
-/* Available          0x0040   */
+#define MEM_IntReal   0x0020   /* MEM_Int that stringifies like MEM_Real */
+#define MEM_AffMask   0x003f   /* Mask of affinity bits */
+#define MEM_FromBind  0x0040   /* Value originates from sqlite3_bind() */
 #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 */
+#define MEM_TypeMask  0xc1bf   /* Mask of type bits */
 
 
 /* Whenever Mem contains a valid string or blob representation, one of
@@ -19945,6 +20288,12 @@ struct sqlite3_value {
 #define MemSetTypeFlag(p, f) \
    ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
 
+/*
+** True if Mem X is a NULL-nochng type.
+*/
+#define MemNullNochng(X) \
+  ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0)
+
 /*
 ** Return true if a memory cell is not marked as invalid.  This macro
 ** is for use inside assert() statements only.
@@ -19998,6 +20347,9 @@ struct sqlite3_context {
 */
 typedef unsigned bft;  /* Bit Field Type */
 
+/* The ScanStatus object holds a single value for the
+** sqlite3_stmt_scanstatus() interface.
+*/
 typedef struct ScanStatus ScanStatus;
 struct ScanStatus {
   int addrExplain;                /* OP_Explain for loop */
@@ -20008,6 +20360,19 @@ struct ScanStatus {
   char *zName;                    /* Name of table or index */
 };
 
+/* The DblquoteStr object holds the text of a double-quoted
+** string for a prepared statement.  A linked list of these objects
+** is constructed during statement parsing and is held on Vdbe.pDblStr.
+** When computing a normalized SQL statement for an SQL statement, that
+** list is consulted for each double-quoted identifier to see if the
+** identifier should really be a string literal.
+*/
+typedef struct DblquoteStr DblquoteStr;
+struct DblquoteStr {
+  DblquoteStr *pNextStr;   /* Next string literal in the list */
+  char z[8];               /* Dequoted value for the string */
+};
+
 /*
 ** An instance of the virtual machine.  This structure contains the complete
 ** state of the virtual machine.
@@ -20027,28 +20392,29 @@ struct Vdbe {
   int pc;                 /* The program counter */
   int rc;                 /* Value to return */
   int nChange;            /* Number of db changes made since last reset */
-  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
+  int iStatement;         /* Statement number (or 0 if has no opened stmt) */
   i64 iCurrentTime;       /* Value of julianday('now') for this statement */
   i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
+  Mem *aMem;              /* The memory locations */
+  Mem **apArg;            /* Arguments to currently executing user function */
+  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
+  Mem *aVar;              /* Values for the OP_Variable opcode. */
 
   /* When allocating a new Vdbe object, all of the fields below should be
   ** initialized to zero or NULL */
 
   Op *aOp;                /* Space to hold the virtual machine's program */
-  Mem *aMem;              /* The memory locations */
-  Mem **apArg;            /* Arguments to currently executing user function */
+  int nOp;                /* Number of instructions in the program */
+  int nOpAlloc;           /* Slots allocated for aOp[] */
   Mem *aColName;          /* Column names to return */
   Mem *pResultSet;        /* Pointer to an array of results */
   char *zErrMsg;          /* Error message written here */
-  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
-  Mem *aVar;              /* Values for the OP_Variable opcode. */
   VList *pVList;          /* Name of variables */
 #ifndef SQLITE_OMIT_TRACE
   i64 startTime;          /* Time when query started - used for profiling */
 #endif
-  int nOp;                /* Number of instructions in the program */
 #ifdef SQLITE_DEBUG
   int rcApp;              /* errcode set by sqlite3_result_error_code() */
   u32 nWrite;             /* Number of write operations that have occurred */
@@ -20069,6 +20435,10 @@ struct Vdbe {
   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 */
+  DblquoteStr *pDblStr;   /* List of double-quoted string literals */
+#endif
   void *pFree;            /* Free this when deleting the vdbe */
   VdbeFrame *pFrame;      /* Parent frame */
   VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
@@ -20131,7 +20501,9 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
+#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*);
@@ -20170,7 +20542,9 @@ 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);
@@ -21002,7 +21376,7 @@ static int parseDateOrTime(
     return 0;
   }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
     return setDateTimeToCurrent(context, p);
-  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
+  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
     setRawDateNumber(p, r);
     return 0;
   }
@@ -21336,7 +21710,7 @@ static int parseModifier(
       ** date is already on the appropriate weekday, this is a no-op.
       */
       if( sqlite3_strnicmp(z, "weekday ", 8)==0
-               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
+               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
                && (n=(int)r)==r && n>=0 && r<7 ){
         sqlite3_int64 Z;
         computeYMD_HMS(p);
@@ -21395,7 +21769,7 @@ static int parseModifier(
       double rRounder;
       int i;
       for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
-      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
+      if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
         rc = 1;
         break;
       }
@@ -26869,6 +27243,9 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
       db->u1.isInterrupted = 1;
     }
     db->lookaside.bDisable++;
+    if( db->pParse ){
+      db->pParse->rc = SQLITE_NOMEM_BKPT;
+    }
   }
 }
 
@@ -27025,6 +27402,12 @@ static const et_info fmtinfo[] = {
   {  'r', 10, 1, etORDINAL,    0,  0 },
 };
 
+/* Floating point constants used for rounding */
+static const double arRound[] = {
+  5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
+  5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
+};
+
 /*
 ** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
 ** conversions will work.
@@ -27062,7 +27445,8 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
 static void setStrAccumError(StrAccum *p, u8 eError){
   assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
   p->accError = eError;
-  p->nAlloc = 0;
+  if( p->mxAlloc ) sqlite3_str_reset(p);
+  if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
 }
 
 /*
@@ -27081,6 +27465,28 @@ static char *getTextArg(PrintfArguments *p){
   return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
 }
 
+/*
+** Allocate memory for a temporary buffer needed for printf rendering.
+**
+** If the requested size of the temp buffer is larger than the size
+** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
+** Do the size check before the memory allocation to prevent rogue
+** SQL from requesting large allocations using the precision or width
+** field of the printf() function.
+*/
+static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
+  char *z;
+  if( pAccum->accError ) return 0;
+  if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
+    setStrAccumError(pAccum, SQLITE_TOOBIG);
+    return 0;
+  }
+  z = sqlite3DbMallocRaw(pAccum->db, n);
+  if( z==0 ){
+    setStrAccumError(pAccum, SQLITE_NOMEM);
+  }
+  return z;
+}
 
 /*
 ** On machines with a small stack size, you can redefine the
@@ -27163,6 +27569,9 @@ SQLITE_API void sqlite3_str_vappendf(
     flag_leftjustify = flag_prefix = cThousand =
      flag_alternateform = flag_altform2 = flag_zeropad = 0;
     done = 0;
+    width = 0;
+    flag_long = 0;
+    precision = -1;
     do{
       switch( c ){
         case '-':   flag_leftjustify = 1;     break;
@@ -27173,80 +27582,93 @@ SQLITE_API void sqlite3_str_vappendf(
         case '0':   flag_zeropad = 1;         break;
         case ',':   cThousand = ',';          break;
         default:    done = 1;                 break;
+        case 'l': {
+          flag_long = 1;
+          c = *++fmt;
+          if( c=='l' ){
+            c = *++fmt;
+            flag_long = 2;
+          }
+          done = 1;
+          break;
+        }
+        case '1': case '2': case '3': case '4': case '5':
+        case '6': case '7': case '8': case '9': {
+          unsigned wx = c - '0';
+          while( (c = *++fmt)>='0' && c<='9' ){
+            wx = wx*10 + c - '0';
+          }
+          testcase( wx>0x7fffffff );
+          width = wx & 0x7fffffff;
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+          if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+            width = SQLITE_PRINTF_PRECISION_LIMIT;
+          }
+#endif
+          if( c!='.' && c!='l' ){
+            done = 1;
+          }else{
+            fmt--;
+          }
+          break;
+        }
+        case '*': {
+          if( bArgList ){
+            width = (int)getIntArg(pArgList);
+          }else{
+            width = va_arg(ap,int);
+          }
+          if( width<0 ){
+            flag_leftjustify = 1;
+            width = width >= -2147483647 ? -width : 0;
+          }
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+          if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+            width = SQLITE_PRINTF_PRECISION_LIMIT;
+          }
+#endif
+          if( (c = fmt[1])!='.' && c!='l' ){
+            c = *++fmt;
+            done = 1;
+          }
+          break;
+        }
+        case '.': {
+          c = *++fmt;
+          if( c=='*' ){
+            if( bArgList ){
+              precision = (int)getIntArg(pArgList);
+            }else{
+              precision = va_arg(ap,int);
+            }
+            if( precision<0 ){
+              precision = precision >= -2147483647 ? -precision : -1;
+            }
+            c = *++fmt;
+          }else{
+            unsigned px = 0;
+            while( c>='0' && c<='9' ){
+              px = px*10 + c - '0';
+              c = *++fmt;
+            }
+            testcase( px>0x7fffffff );
+            precision = px & 0x7fffffff;
+          }
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+          if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
+            precision = SQLITE_PRINTF_PRECISION_LIMIT;
+          }
+#endif
+          if( c=='l' ){
+            --fmt;
+          }else{
+            done = 1;
+          }
+          break;
+        }
       }
     }while( !done && (c=(*++fmt))!=0 );
-    /* Get the field width */
-    if( c=='*' ){
-      if( bArgList ){
-        width = (int)getIntArg(pArgList);
-      }else{
-        width = va_arg(ap,int);
-      }
-      if( width<0 ){
-        flag_leftjustify = 1;
-        width = width >= -2147483647 ? -width : 0;
-      }
-      c = *++fmt;
-    }else{
-      unsigned wx = 0;
-      while( c>='0' && c<='9' ){
-        wx = wx*10 + c - '0';
-        c = *++fmt;
-      }
-      testcase( wx>0x7fffffff );
-      width = wx & 0x7fffffff;
-    }
-    assert( width>=0 );
-#ifdef SQLITE_PRINTF_PRECISION_LIMIT
-    if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
-      width = SQLITE_PRINTF_PRECISION_LIMIT;
-    }
-#endif
 
-    /* Get the precision */
-    if( c=='.' ){
-      c = *++fmt;
-      if( c=='*' ){
-        if( bArgList ){
-          precision = (int)getIntArg(pArgList);
-        }else{
-          precision = va_arg(ap,int);
-        }
-        c = *++fmt;
-        if( precision<0 ){
-          precision = precision >= -2147483647 ? -precision : -1;
-        }
-      }else{
-        unsigned px = 0;
-        while( c>='0' && c<='9' ){
-          px = px*10 + c - '0';
-          c = *++fmt;
-        }
-        testcase( px>0x7fffffff );
-        precision = px & 0x7fffffff;
-      }
-    }else{
-      precision = -1;
-    }
-    assert( precision>=(-1) );
-#ifdef SQLITE_PRINTF_PRECISION_LIMIT
-    if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
-      precision = SQLITE_PRINTF_PRECISION_LIMIT;
-    }
-#endif
-
-
-    /* Get the conversion type modifier */
-    if( c=='l' ){
-      flag_long = 1;
-      c = *++fmt;
-      if( c=='l' ){
-        flag_long = 2;
-        c = *++fmt;
-      }
-    }else{
-      flag_long = 0;
-    }
     /* Fetch the info entry for the field */
     infop = &fmtinfo[0];
     xtype = etINVALID;
@@ -27331,12 +27753,11 @@ SQLITE_API void sqlite3_str_vappendf(
           nOut = etBUFSIZE;
           zOut = buf;
         }else{
-          u64 n = (u64)precision + 10 + precision/3;
-          zOut = zExtra = sqlite3Malloc( n );
-          if( zOut==0 ){
-            setStrAccumError(pAccum, SQLITE_NOMEM);
-            return;
-          }
+          u64 n;
+          n = (u64)precision + 10;
+          if( cThousand ) n += precision/3;
+          zOut = zExtra = printfTempBuf(pAccum, n);
+          if( zOut==0 ) return;
           nOut = (int)n;
         }
         bufpt = &zOut[nOut-1];
@@ -27405,8 +27826,18 @@ SQLITE_API void sqlite3_str_vappendf(
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
         testcase( precision>0xfff );
-        for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-        if( xtype==etFLOAT ) realvalue += rounder;
+        idx = precision & 0xfff;
+        rounder = arRound[idx%10];
+        while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
+        if( xtype==etFLOAT ){
+          double rx = (double)realvalue;
+          sqlite3_uint64 u;
+          int ex;
+          memcpy(&u, &rx, sizeof(u));
+          ex = -1023 + (int)((u>>52)&0x7ff);
+          if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
+          realvalue += rounder;
+        }
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
         if( sqlite3IsNaN((double)realvalue) ){
@@ -27455,12 +27886,12 @@ SQLITE_API void sqlite3_str_vappendf(
         }else{
           e2 = exp;
         }
-        if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
-          bufpt = zExtra 
-              = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
-          if( bufpt==0 ){
-            setStrAccumError(pAccum, SQLITE_NOMEM);
-            return;
+        {
+          i64 szBufNeeded;           /* Size of a temporary buffer needed */
+          szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
+          if( szBufNeeded > etBUFSIZE ){
+            bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
+            if( bufpt==0 ) return;
           }
         }
         zOut = bufpt;
@@ -27684,11 +28115,8 @@ SQLITE_API void sqlite3_str_vappendf(
         needQuote = !isnull && xtype==etSQLESCAPE2;
         n += i + 3;
         if( n>etBUFSIZE ){
-          bufpt = zExtra = sqlite3Malloc( n );
-          if( bufpt==0 ){
-            setStrAccumError(pAccum, SQLITE_NOMEM);
-            return;
-          }
+          bufpt = zExtra = printfTempBuf(pAccum, n);
+          if( bufpt==0 ) return;
         }else{
           bufpt = buf;
         }
@@ -27778,9 +28206,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
     return 0;
   }
   if( p->mxAlloc==0 ){
-    N = p->nAlloc - p->nChar - 1;
     setStrAccumError(p, SQLITE_TOOBIG);
-    return N;
+    return p->nAlloc - p->nChar - 1;
   }else{
     char *zOld = isMalloced(p) ? p->zText : 0;
     i64 szNew = p->nChar;
@@ -27852,7 +28279,7 @@ 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 );
-  assert( p->accError==0 || p->nAlloc==0 );
+  assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 );
   if( p->nChar+N >= p->nAlloc ){
     enlargeAndAppend(p,z,N);
   }else if( N ){
@@ -28297,6 +28724,43 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
   }
 }
 
+/*
+** 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, " tab=%Q nCol=%d ptr=%p",
+           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
+    }
+    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.
@@ -28351,39 +28815,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
     }
 #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);
-        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<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 ){
@@ -28478,24 +28912,62 @@ SQLITE_PRIVATE void sqlite3TreeViewBound(
 ** Generate a human-readable explanation for a Window object
 */
 SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+  int nElement = 0;
+  if( pWin->pFilter ){
+    sqlite3TreeViewItem(pView, "FILTER", 1);
+    sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
+    sqlite3TreeViewPop(pView);
+  }
   pView = sqlite3TreeViewPush(pView, more);
   if( pWin->zName ){
-    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
+    sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
   }else{
-    sqlite3TreeViewLine(pView, "OVER");
+    sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
+  }
+  if( pWin->zBase )    nElement++;
+  if( pWin->pOrderBy ) nElement++;
+  if( pWin->eFrmType ) nElement++;
+  if( pWin->eExclude ) nElement++;
+  if( pWin->zBase ){
+    sqlite3TreeViewPush(pView, (--nElement)>0);
+    sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
+    sqlite3TreeViewPop(pView);
   }
   if( pWin->pPartition ){
-    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
+    sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
   }
   if( pWin->pOrderBy ){
-    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
+    sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
   }
-  if( pWin->eType ){
-    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
+  if( pWin->eFrmType ){
+    char zBuf[30];
+    const char *zFrmType = "ROWS";
+    if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
+    if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
+    sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
+        pWin->bImplicitFrame ? " (implied)" : "");
+    sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
     sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
     sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
     sqlite3TreeViewPop(pView);
   }
+  if( pWin->eExclude ){
+    char zBuf[30];
+    const char *zExclude;
+    switch( pWin->eExclude ){
+      case TK_NO:      zExclude = "NO OTHERS";   break;
+      case TK_CURRENT: zExclude = "CURRENT ROW"; break;
+      case TK_GROUP:   zExclude = "GROUP";       break;
+      case TK_TIES:    zExclude = "TIES";        break;
+      default:
+        sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
+        zExclude = zBuf;
+        break;
+    }
+    sqlite3TreeViewPush(pView, 0);
+    sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
+    sqlite3TreeViewPop(pView);
+  }
   sqlite3TreeViewPop(pView);
 }
 #endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -28645,7 +29117,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
       };
       assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
       assert( pExpr->pRight );
-      assert( pExpr->pRight->op==TK_TRUEFALSE );
+      assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE );
       x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
       zUniOp = azOp[x];
       break;
@@ -28673,7 +29145,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
       }else{
         pFarg = pExpr->x.pList;
 #ifndef SQLITE_OMIT_WINDOWFUNC
-        pWin = pExpr->pWin;
+        pWin = pExpr->y.pWin;
 #else
         pWin = 0;
 #endif 
@@ -29475,11 +29947,11 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read(
 ** encoding, or if *pMem does not contain a string value.
 */
 SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
-  int len;                    /* Maximum length of output string in bytes */
-  unsigned char *zOut;                  /* Output buffer */
-  unsigned char *zIn;                   /* Input iterator */
-  unsigned char *zTerm;                 /* End of input */
-  unsigned char *z;                     /* Output iterator */
+  sqlite3_int64 len;          /* Maximum length of output string in bytes */
+  unsigned char *zOut;        /* Output buffer */
+  unsigned char *zIn;         /* Input iterator */
+  unsigned char *zTerm;       /* End of input */
+  unsigned char *z;           /* Output iterator */
   unsigned int c;
 
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -29528,14 +30000,14 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
     ** nul-terminator.
     */
     pMem->n &= ~1;
-    len = pMem->n * 2 + 1;
+    len = 2 * (sqlite3_int64)pMem->n + 1;
   }else{
     /* When converting from UTF-8 to UTF-16 the maximum growth is caused
     ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
     ** character. Two bytes are required in the output buffer for the
     ** nul-terminator.
     */
-    len = pMem->n * 2 + 2;
+    len = 2 * (sqlite3_int64)pMem->n + 2;
   }
 
   /* Set zIn to point at the start of the input buffer and zTerm to point 1
@@ -29827,9 +30299,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
 */
 /* #include "sqliteInt.h" */
 /* #include <stdarg.h> */
-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
-# include <math.h>
-#endif
+#include <math.h>
 
 /*
 ** Routine needed to support the testcase() macro.
@@ -29842,15 +30312,23 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){
 #endif
 
 /*
-** Give a callback to the test harness that can be used to simulate faults
-** in places where it is difficult or expensive to do so purely by means
-** of inputs.
+** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
+** or to bypass normal error detection during testing in order to let 
+** execute proceed futher downstream.
 **
-** The intent of the integer argument is to let the fault simulator know
-** which of multiple sqlite3FaultSim() calls has been hit.
+** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0).  The
+** sqlite3FaultSim() function only returns non-zero during testing.
 **
-** Return whatever integer value the test callback returns, or return
-** SQLITE_OK if no test callback is installed.
+** During testing, if the test harness has set a fault-sim callback using
+** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then
+** each call to sqlite3FaultSim() is relayed to that application-supplied
+** callback and the integer return value form the application-supplied
+** callback is returned by sqlite3FaultSim().
+**
+** The integer argument to sqlite3FaultSim() is a code to identify which
+** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim()
+** should have a unique code.  To prevent legacy testing applications from
+** breaking, the codes should not be changed or reused.
 */
 #ifndef SQLITE_UNTESTABLE
 SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
@@ -29862,47 +30340,11 @@ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
 #ifndef SQLITE_OMIT_FLOATING_POINT
 /*
 ** Return true if the floating point value is Not a Number (NaN).
-**
-** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-** Otherwise, we have our own implementation that works on most systems.
 */
 SQLITE_PRIVATE int sqlite3IsNaN(double x){
-  int rc;   /* The value return */
-#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
-  /*
-  ** Systems that support the isnan() library function should probably
-  ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
-  ** found that many systems do not have a working isnan() function so
-  ** this implementation is provided as an alternative.
-  **
-  ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
-  ** On the other hand, the use of -ffast-math comes with the following
-  ** warning:
-  **
-  **      This option [-ffast-math] should never be turned on by any
-  **      -O option since it can result in incorrect output for programs
-  **      which depend on an exact implementation of IEEE or ISO 
-  **      rules/specifications for math functions.
-  **
-  ** Under MSVC, this NaN test may fail if compiled with a floating-
-  ** point precision mode other than /fp:precise.  From the MSDN 
-  ** documentation:
-  **
-  **      The compiler [with /fp:precise] will properly handle comparisons 
-  **      involving NaN. For example, x != x evaluates to true if x is NaN 
-  **      ...
-  */
-#ifdef __FAST_MATH__
-# error SQLite will not work correctly with the -ffast-math option of GCC.
-#endif
-  volatile double y = x;
-  volatile double z = y;
-  rc = (y!=z);
-#else  /* if HAVE_ISNAN */
-  rc = isnan(x);
-#endif /* HAVE_ISNAN */
-  testcase( rc );
-  return rc;
+  u64 y;
+  memcpy(&y,&x,sizeof(y));
+  return IsNaN(y);
 }
 #endif /* SQLITE_OMIT_FLOATING_POINT */
 
@@ -30035,6 +30477,19 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
   }
 }
 
+/*
+** If database connection db is currently parsing SQL, then transfer
+** error code errCode to that parser if the parser has not already
+** encountered some other kind of error.
+*/
+SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){
+  Parse *pParse;
+  if( db==0 || (pParse = db->pParse)==0 ) return errCode;
+  pParse->rc = errCode;
+  pParse->nErr++;
+  return errCode;
+}
+
 /*
 ** Convert an SQL-style quoted string into a normal string by removing
 ** the quote characters.  The conversion is done in-place.  If the
@@ -30048,7 +30503,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
 ** dequoted string, exclusive of the zero terminator, if dequoting does
 ** occur.
 **
-** 2002-Feb-14: This routine is extended to remove MS-Access style
+** 2002-02-14: This routine is extended to remove MS-Access style
 ** brackets from around identifiers.  For example:  "[a-b-c]" becomes
 ** "a-b-c".
 */
@@ -30074,6 +30529,11 @@ SQLITE_PRIVATE void sqlite3Dequote(char *z){
   }
   z[j] = 0;
 }
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
+  assert( sqlite3Isquote(p->u.zToken[0]) );
+  p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
+  sqlite3Dequote(p->u.zToken);
+}
 
 /*
 ** Generate a Token object from a string
@@ -30106,12 +30566,18 @@ SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
 }
 SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
   unsigned char *a, *b;
-  int c;
+  int c, x;
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   for(;;){
-    c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
-    if( c || *a==0 ) break;
+    c = *a;
+    x = *b;
+    if( c==x ){
+      if( c==0 ) break;
+    }else{
+      c = (int)UpperToLower[c] - (int)UpperToLower[x];
+      if( c ) break;
+    }
     a++;
     b++;
   }
@@ -30139,15 +30605,15 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
 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
+    1.0e+001L,
+    1.0e+002L,
+    1.0e+004L,
+    1.0e+008L,
+    1.0e+016L,
+    1.0e+032L,
+    1.0e+064L,
+    1.0e+128L,
+    1.0e+256L
   };
   LONGDOUBLE_TYPE r = 1.0;
   int i;
@@ -30177,8 +30643,15 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
 ** uses the encoding enc.  The string is not necessarily zero-terminated.
 **
 ** Return TRUE if the result is a valid real number (or integer) and FALSE
-** if the string is empty or contains extraneous text.  Valid numbers
-** are in one of these formats:
+** if the string is empty or contains extraneous text.  More specifically
+** return
+**      1          =>  The input string is a pure integer
+**      2 or more  =>  The input has a decimal point or eNNN clause
+**      0 or less  =>  The input string is not a valid number
+**     -1          =>  Not a valid number, but has a valid prefix which 
+**                     includes a decimal point and/or an eNNN clause
+**
+** Valid numbers are in one of these formats:
 **
 **    [+-]digits[E[+-]digits]
 **    [+-]digits.[digits][E[+-]digits]
@@ -30203,8 +30676,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   int e = 0;       /* exponent */
   int eValid = 1;  /* True exponent is either not used or is well-formed */
   double result;
-  int nDigits = 0;
-  int nonNum = 0;  /* True if input contains UTF16 with high byte non-zero */
+  int nDigit = 0;  /* Number of digits processed */
+  int eType = 1;   /* 1: pure integer,  2+: fractional  -1 or less: bad UTF16 */
 
   assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
   *pResult = 0.0;   /* Default return value, in case of an error */
@@ -30215,8 +30688,10 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
     int i;
     incr = 2;
     assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+    testcase( enc==SQLITE_UTF16LE );
+    testcase( enc==SQLITE_UTF16BE );
     for(i=3-enc; i<length && z[i]==0; i+=2){}
-    nonNum = i<length;
+    if( i<length ) eType = -100;
     zEnd = &z[i^1];
     z += (enc&1);
   }
@@ -30234,27 +30709,30 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   }
 
   /* copy max significant digits to significand */
-  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
+  while( z<zEnd && sqlite3Isdigit(*z) ){
     s = s*10 + (*z - '0');
-    z+=incr; nDigits++;
+    z+=incr; nDigit++;
+    if( s>=((LARGEST_INT64-9)/10) ){
+      /* skip non-significant significand digits
+      ** (increase exponent by d to shift decimal left) */
+      while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; }
+    }
   }
-
-  /* skip non-significant significand digits
-  ** (increase exponent by d to shift decimal left) */
-  while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
   if( z>=zEnd ) goto do_atof_calc;
 
   /* if decimal point is present */
   if( *z=='.' ){
     z+=incr;
+    eType++;
     /* copy digits from after decimal to significand
     ** (decrease exponent by d to shift decimal right) */
     while( z<zEnd && sqlite3Isdigit(*z) ){
       if( s<((LARGEST_INT64-9)/10) ){
         s = s*10 + (*z - '0');
         d--;
+        nDigit++;
       }
-      z+=incr; nDigits++;
+      z+=incr;
     }
   }
   if( z>=zEnd ) goto do_atof_calc;
@@ -30263,6 +30741,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
   if( *z=='e' || *z=='E' ){
     z+=incr;
     eValid = 0;
+    eType++;
 
     /* This branch is needed to avoid a (harmless) buffer overread.  The 
     ** special comment alerts the mutation tester that the correct answer
@@ -30361,7 +30840,13 @@ do_atof_calc:
   *pResult = result;
 
   /* return true if number and no extra non-whitespace chracters after */
-  return z==zEnd && nDigits>0 && eValid && nonNum==0;
+  if( z==zEnd && nDigit>0 && eValid && eType>0 ){
+    return eType;
+  }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
+    return -1;
+  }else{
+    return 0;
+  }
 #else
   return !sqlite3Atoi64(z, pResult, length, enc);
 #endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -30404,6 +30889,7 @@ static int compare2pow63(const char *zNum, int incr){
 **
 ** Returns:
 **
+**    -1    Not even a prefix of the input text looks like an integer
 **     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
@@ -30463,9 +30949,9 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
     *pNum = (i64)u;
   }
   rc = 0;
-  if( (i==0 && zStart==zNum)     /* No digits */
-   || nonNum                     /* UTF16 with high-order bytes non-zero */
-  ){
+  if( i==0 && zStart==zNum ){    /* No digits */
+    rc = -1;
+  }else if( nonNum ){            /* UTF16 with high-order bytes non-zero */
     rc = 1;
   }else if( &zNum[i]<zEnd ){     /* Extra bytes at the end */
     int jj = i;
@@ -30696,23 +31182,12 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
 SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
   u32 a,b,s;
 
-  a = *p;
-  /* a: p0 (unmasked) */
-  if (!(a&0x80))
-  {
-    *v = a;
+  if( ((signed char*)p)[0]>=0 ){
+    *v = *p;
     return 1;
   }
-
-  p++;
-  b = *p;
-  /* b: p1 (unmasked) */
-  if (!(b&0x80))
-  {
-    a &= 0x7f;
-    a = a<<7;
-    a |= b;
-    *v = a;
+  if( ((signed char*)p)[1]>=0 ){
+    *v = ((u32)(p[0]&0x7f)<<7) | p[1];
     return 2;
   }
 
@@ -30720,8 +31195,9 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
   assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
   assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
 
-  p++;
-  a = a<<14;
+  a = ((u32)p[0])<<14;
+  b = p[1];
+  p += 2;
   a |= *p;
   /* a: p0<<14 | p2 (unmasked) */
   if (!(a&0x80))
@@ -31381,7 +31857,7 @@ SQLITE_PRIVATE VList *sqlite3VListAdd(
   assert( pIn==0 || pIn[0]>=3 );  /* Verify ok to add new elements */
   if( pIn==0 || pIn[1]+nInt > pIn[0] ){
     /* Enlarge the allocation */
-    int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
+    sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt;
     VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
     if( pOut==0 ) return pIn;
     if( pIn==0 ) pOut[1] = 2;
@@ -31587,7 +32063,7 @@ static HashElem *findElementWithHash(
   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 count;            /* Number of elements left to test */
   unsigned int h;                /* The computed hash */
   static HashElem nullElement = { 0, 0, 0, 0 };
 
@@ -31635,8 +32111,8 @@ static void removeElementGivenHash(
     if( pEntry->chain==elem ){
       pEntry->chain = elem->next;
     }
+    assert( pEntry->count>0 );
     pEntry->count--;
-    assert( pEntry->count>=0 );
   }
   sqlite3_free( elem );
   pH->count--;
@@ -31811,25 +32287,25 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
     /*  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"),
+    /*  92 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+    /*  93 */ "Count"            OpHelp("r[P2]=count()"),
+    /*  94 */ "ReadCookie"       OpHelp(""),
+    /*  95 */ "SetCookie"        OpHelp(""),
+    /*  96 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
+    /*  97 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
+    /*  98 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
+    /*  99 */ "ShiftRight"       OpHelp("r[P3]=r[P2]>>r[P1]"),
+    /* 100 */ "Add"              OpHelp("r[P3]=r[P1]+r[P2]"),
+    /* 101 */ "Subtract"         OpHelp("r[P3]=r[P2]-r[P1]"),
+    /* 102 */ "Multiply"         OpHelp("r[P3]=r[P1]*r[P2]"),
+    /* 103 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
+    /* 104 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
+    /* 105 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
+    /* 106 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+    /* 107 */ "BitNot"           OpHelp("r[P2]= ~r[P1]"),
+    /* 108 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+    /* 109 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+    /* 110 */ "String8"          OpHelp("r[P2]='P4'"),
     /* 111 */ "OpenDup"          OpHelp(""),
     /* 112 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
     /* 113 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
@@ -31842,57 +32318,56 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
     /* 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(""),
+    /* 123 */ "Delete"           OpHelp(""),
+    /* 124 */ "ResetCount"       OpHelp(""),
+    /* 125 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+    /* 126 */ "SorterData"       OpHelp("r[P2]=data"),
+    /* 127 */ "RowData"          OpHelp("r[P2]=data"),
+    /* 128 */ "Rowid"            OpHelp("r[P2]=rowid"),
+    /* 129 */ "NullRow"          OpHelp(""),
+    /* 130 */ "SeekEnd"          OpHelp(""),
+    /* 131 */ "SorterInsert"     OpHelp("key=r[P2]"),
+    /* 132 */ "IdxInsert"        OpHelp("key=r[P2]"),
+    /* 133 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+    /* 134 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
+    /* 135 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+    /* 136 */ "Destroy"          OpHelp(""),
+    /* 137 */ "Clear"            OpHelp(""),
+    /* 138 */ "ResetSorter"      OpHelp(""),
+    /* 139 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
+    /* 140 */ "SqlExec"          OpHelp(""),
+    /* 141 */ "ParseSchema"      OpHelp(""),
+    /* 142 */ "LoadAnalysis"     OpHelp(""),
+    /* 143 */ "DropTable"        OpHelp(""),
+    /* 144 */ "DropIndex"        OpHelp(""),
+    /* 145 */ "Real"             OpHelp("r[P2]=P4"),
+    /* 146 */ "DropTrigger"      OpHelp(""),
+    /* 147 */ "IntegrityCk"      OpHelp(""),
+    /* 148 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+    /* 149 */ "Param"            OpHelp(""),
+    /* 150 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+    /* 151 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+    /* 152 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+    /* 153 */ "AggInverse"       OpHelp("accum=r[P3] inverse(r[P2@P5])"),
+    /* 154 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+    /* 155 */ "AggStep1"         OpHelp("accum=r[P3] step(r[P2@P5])"),
+    /* 156 */ "AggValue"         OpHelp("r[P3]=value N=P2"),
+    /* 157 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+    /* 158 */ "Expire"           OpHelp(""),
+    /* 159 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+    /* 160 */ "VBegin"           OpHelp(""),
+    /* 161 */ "VCreate"          OpHelp(""),
+    /* 162 */ "VDestroy"         OpHelp(""),
+    /* 163 */ "VOpen"            OpHelp(""),
+    /* 164 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+    /* 165 */ "VRename"          OpHelp(""),
+    /* 166 */ "Pagecount"        OpHelp(""),
+    /* 167 */ "MaxPgcnt"         OpHelp(""),
+    /* 168 */ "Trace"            OpHelp(""),
+    /* 169 */ "CursorHint"       OpHelp(""),
+    /* 170 */ "Noop"             OpHelp(""),
+    /* 171 */ "Explain"          OpHelp(""),
+    /* 172 */ "Abortable"        OpHelp(""),
   };
   return azName[i];
 }
@@ -32038,12 +32513,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 #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
 
 /*
@@ -33219,8 +33692,7 @@ struct unixFileId {
 
 /*
 ** 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
@@ -33266,13 +33738,16 @@ struct unixInodeInfo {
 
 /*
 ** A lists of all unixInodeInfo objects.
+**
+** Must hold unixBigLock in order to read or write this variable.
 */
 static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
 
 #ifdef SQLITE_DEBUG
 /*
-** True if the inode mutex is held, or not.  Used only within assert()
-** to help verify correct mutex usage.
+** 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 );
@@ -33400,8 +33875,8 @@ static void closePendingFds(unixFile *pFile){
 /*
 ** 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;
@@ -33436,8 +33911,7 @@ static void releaseInodeInfo(unixFile *pFile){
 ** 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.
 */
@@ -33498,6 +33972,7 @@ static int findInodeInfo(
 #else
   fileId.ino = (u64)statbuf.st_ino;
 #endif
+  assert( unixMutexHeld() );
   pInode = inodeList;
   while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
     pInode = pInode->pNext;
@@ -33517,6 +33992,7 @@ static int findInodeInfo(
       }
     }
     pInode->nRef = 1;
+    assert( unixMutexHeld() );
     pInode->pNext = inodeList;
     pInode->pPrev = 0;
     if( inodeList ) inodeList->pPrev = pInode;
@@ -36314,18 +36790,18 @@ static int unixGetpagesize(void){
 **
 ** 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 */
@@ -36347,16 +36823,16 @@ struct unixShmNode {
 ** 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 */
@@ -36386,7 +36862,8 @@ static int unixShmSystemLock(
 
   /* 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 );
@@ -36394,13 +36871,13 @@ static int unixShmSystemLock(
   /* 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;
   }
 
@@ -36472,18 +36949,18 @@ static void unixShmPurge(unixFile *pFd){
     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]);
       }
     }
     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);
@@ -36525,7 +37002,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
   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 ){
@@ -36533,7 +37010,12 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
       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);
       }
     }
@@ -36639,12 +37121,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
     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;
       }
@@ -36652,11 +37134,11 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
 
     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;
         }
@@ -36667,7 +37149,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
       ** 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;
@@ -36687,13 +37169,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
   ** 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 */
@@ -36745,7 +37227,7 @@ static int unixShmMap(
 
   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;
@@ -36753,8 +37235,8 @@ static int unixShmMap(
   }
   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;
@@ -36766,12 +37248,12 @@ static int unixShmMap(
 
     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;
       }
@@ -36799,7 +37281,7 @@ static int unixShmMap(
           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;
@@ -36822,22 +37304,22 @@ static int unixShmMap(
       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);
           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++){
@@ -36854,7 +37336,7 @@ shmpage_out:
     *pp = 0;
   }
   if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
-  sqlite3_mutex_leave(pShmNode->mutex);
+  sqlite3_mutex_leave(pShmNode->pShmMutex);
   return rc;
 }
 
@@ -36888,12 +37370,12 @@ static int unixShmLock(
        || 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 */
 
@@ -36966,7 +37448,7 @@ static int unixShmLock(
       }
     }
   }
-  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;
@@ -37016,14 +37498,14 @@ static int unixShmUnmap(
 
   /* 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;
 
   /* 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 */
@@ -37032,7 +37514,7 @@ static int unixShmUnmap(
   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);
@@ -40450,8 +40932,7 @@ struct winFile {
   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
 };
@@ -43072,6 +43553,26 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
   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 );
@@ -44500,9 +45001,9 @@ shmpage_out:
 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();
@@ -44514,7 +45015,6 @@ static int winUnmapfile(winFile *pFile){
     }
     pFile->pMapRegion = 0;
     pFile->mmapSize = 0;
-    pFile->mmapSizeActual = 0;
   }
   if( pFile->hMap!=NULL ){
     if( !osCloseHandle(pFile->hMap) ){
@@ -44625,7 +45125,6 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
     }
     pFd->pMapRegion = pNew;
     pFd->mmapSize = nMap;
-    pFd->mmapSizeActual = nMap;
   }
 
   OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
@@ -45427,7 +45926,6 @@ static int winOpen(
   pFile->hMap = NULL;
   pFile->pMapRegion = 0;
   pFile->mmapSize = 0;
-  pFile->mmapSizeActual = 0;
   pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
 #endif
 
@@ -46320,7 +46818,8 @@ typedef struct MemFile MemFile;
 struct MemFile {
   sqlite3_file base;              /* IO methods */
   sqlite3_int64 sz;               /* Size of the file */
-  sqlite3_int64 szMax;            /* Space allocated to aData */
+  sqlite3_int64 szAlloc;          /* Space allocated to aData */
+  sqlite3_int64 szMax;            /* Maximum allowed size of the file */
   unsigned char *aData;           /* content of the file */
   int nMmap;                      /* Number of memory mapped pages */
   unsigned mFlags;                /* Flags */
@@ -46446,10 +46945,15 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
   if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
     return SQLITE_FULL;
   }
+  if( newSz>p->szMax ){
+    return SQLITE_FULL;
+  }
+  newSz *= 2;
+  if( newSz>p->szMax ) newSz = p->szMax;
   pNew = sqlite3_realloc64(p->aData, newSz);
   if( pNew==0 ) return SQLITE_NOMEM;
   p->aData = pNew;
-  p->szMax = newSz;
+  p->szAlloc = newSz;
   return SQLITE_OK;
 }
 
@@ -46463,10 +46967,11 @@ static int memdbWrite(
   sqlite_int64 iOfst
 ){
   MemFile *p = (MemFile *)pFile;
+  if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY;
   if( iOfst+iAmt>p->sz ){
     int rc;
-    if( iOfst+iAmt>p->szMax
-     && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
+    if( iOfst+iAmt>p->szAlloc
+     && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
     ){
       return rc;
     }
@@ -46512,6 +47017,11 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
 */
 static int memdbLock(sqlite3_file *pFile, int eLock){
   MemFile *p = (MemFile *)pFile;
+  if( eLock>SQLITE_LOCK_SHARED 
+   && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0
+  ){
+    return SQLITE_READONLY;
+  }
   p->eLock = eLock;
   return SQLITE_OK;
 }
@@ -46536,6 +47046,19 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
     *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
     rc = SQLITE_OK;
   }
+  if( op==SQLITE_FCNTL_SIZE_LIMIT ){
+    sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
+    if( iLimit<p->sz ){
+      if( iLimit<0 ){
+        iLimit = p->szMax;
+      }else{
+        iLimit = p->sz;
+      }
+    }
+    p->szMax = iLimit;
+    *(sqlite3_int64*)pArg = iLimit;
+    rc = SQLITE_OK;
+  }
   return rc;
 }
 
@@ -46566,8 +47089,12 @@ static int memdbFetch(
   void **pp
 ){
   MemFile *p = (MemFile *)pFile;
-  p->nMmap++;
-  *pp = (void*)(p->aData + iOfst);
+  if( iOfst+iAmt>p->sz ){
+    *pp = 0;
+  }else{
+    p->nMmap++;
+    *pp = (void*)(p->aData + iOfst);
+  }
   return SQLITE_OK;
 }
 
@@ -46597,6 +47124,7 @@ static int memdbOpen(
   assert( pOutFlags!=0 );  /* True because flags==SQLITE_OPEN_MAIN_DB */
   *pOutFlags = flags | SQLITE_OPEN_MEMORY;
   p->base.pMethods = &memdb_io_methods;
+  p->szMax = sqlite3GlobalConfig.mxMemdbSize;
   return SQLITE_OK;
 }
 
@@ -46846,7 +47374,11 @@ SQLITE_API int sqlite3_deserialize(
   }else{
     p->aData = pData;
     p->sz = szDb;
+    p->szAlloc = szBuf;
     p->szMax = szBuf;
+    if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){
+      p->szMax = sqlite3GlobalConfig.mxMemdbSize;
+    }
     p->mFlags = mFlags;
     rc = SQLITE_OK;
   }
@@ -47324,7 +47856,7 @@ bitvec_end:
 **   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
@@ -47535,9 +48067,10 @@ static int numberOfCachePages(PCache *p){
     ** suggested cache size is set to N. */
     return p->szCache;
   }else{
-    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
-    ** the number of cache pages is adjusted to use approximately abs(N*1024)
-    ** bytes of memory. */
+    /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
+    ** number of cache pages is adjusted to be a number of pages that would
+    ** use approximately abs(N*1024) bytes of memory based on the current
+    ** page size. */
     return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
   }
 }
@@ -48148,6 +48681,15 @@ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
   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
@@ -48258,20 +48800,32 @@ typedef struct PGroup PGroup;
 ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
 ** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
 ** in memory.
+**
+** Note: Variables isBulkLocal and isAnchor were once type "u8". That works,
+** but causes a 2-byte gap in the structure for most architectures (since 
+** pointers must be either 4 or 8-byte aligned). As this structure is located
+** in memory directly after the associated page data, if the database is
+** corrupt, code at the b-tree layer may overread the page buffer and 
+** read part of this structure before the corruption is detected. This
+** can cause a valgrind error if the unitialized gap is accessed. Using u16
+** ensures there is no such gap, and therefore no bytes of unitialized memory
+** in the structure.
 */
 struct PgHdr1 {
   sqlite3_pcache_page page;      /* Base class. Must be first. pBuf & pExtra */
   unsigned int iKey;             /* Key value (page number) */
-  u8 isBulkLocal;                /* This page from bulk local storage */
-  u8 isAnchor;                   /* This is the PGroup.lru element */
+  u16 isBulkLocal;               /* This page from bulk local storage */
+  u16 isAnchor;                  /* This is the PGroup.lru element */
   PgHdr1 *pNext;                 /* Next in hash table chain */
   PCache1 *pCache;               /* Cache that currently owns this page */
   PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
   PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
+                                 /* NB: pLruPrev is only valid if pLruNext!=0 */
 };
 
 /*
-** 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)
@@ -48332,6 +48886,7 @@ struct PCache1 {
   unsigned int nMax;                  /* Configured "cache_size" value */
   unsigned int n90pct;                /* nMax*9/10 */
   unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
+  unsigned int nPurgeableDummy;       /* pnPurgeable points here when not used*/
 
   /* Hash table of all pages. The following variables may only be accessed
   ** when the accessor is holding the PGroup mutex.
@@ -48466,6 +49021,7 @@ static int pcache1InitBulk(PCache1 *pCache){
       pX->isBulkLocal = 1;
       pX->isAnchor = 0;
       pX->pNext = pCache->pFree;
+      pX->pLruPrev = 0;           /* Initializing this saves a valgrind error */
       pCache->pFree = pX;
       zBulk += pCache->szAlloc;
     }while( --nBulk );
@@ -48641,6 +49197,7 @@ static void pcache1FreePage(PgHdr1 *p){
 ** exists, this function falls back to sqlite3Malloc().
 */
 SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
+  assert( sz<=65536+8 ); /* These allocations are never very large */
   return pcache1Alloc(sz);
 }
 
@@ -48735,7 +49292,8 @@ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
   pPage->pLruPrev->pLruNext = pPage->pLruNext;
   pPage->pLruNext->pLruPrev = pPage->pLruPrev;
   pPage->pLruNext = 0;
-  pPage->pLruPrev = 0;
+  /* pPage->pLruPrev = 0;
+  ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */
   assert( pPage->isAnchor==0 );
   assert( pPage->pCache->pGroup->lru.isAnchor==1 );
   pPage->pCache->nRecyclable--;
@@ -48928,6 +49486,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
     }else{
       pGroup = &pcache1.grp;
     }
+    pcache1EnterMutex(pGroup);
     if( pGroup->lru.isAnchor==0 ){
       pGroup->lru.isAnchor = 1;
       pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
@@ -48937,7 +49496,6 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
     pCache->szExtra = szExtra;
     pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
     pCache->bPurgeable = (bPurgeable ? 1 : 0);
-    pcache1EnterMutex(pGroup);
     pcache1ResizeHash(pCache);
     if( bPurgeable ){
       pCache->nMin = 10;
@@ -48945,8 +49503,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
       pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
       pCache->pnPurgeable = &pGroup->nPurgeable;
     }else{
-      static unsigned int dummyCurrentPage;
-      pCache->pnPurgeable = &dummyCurrentPage;
+      pCache->pnPurgeable = &pCache->nPurgeableDummy;
     }
     pcache1LeaveMutex(pGroup);
     if( pCache->nHash==0 ){
@@ -49073,8 +49630,9 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
     pPage->iKey = iKey;
     pPage->pNext = pCache->apHash[h];
     pPage->pCache = pCache;
-    pPage->pLruPrev = 0;
     pPage->pLruNext = 0;
+    /* pPage->pLruPrev = 0;
+    ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */
     *(void **)pPage->page.pExtra = 0;
     pCache->apHash[h] = pPage;
     if( iKey>pCache->iMaxKey ){
@@ -49234,7 +49792,7 @@ static void pcache1Unpin(
   /* It is an error to call this function if the page is already 
   ** part of the PGroup LRU list.
   */
-  assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+  assert( pPage->pLruNext==0 );
   assert( PAGE_IS_PINNED(pPage) );
 
   if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
@@ -50911,19 +51469,33 @@ static const unsigned char aJournalMagic[] = {
 */
 #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;
+#ifdef SQLITE_HAS_CODEC
+  if( pPager->xCodec!=0 ) return 0;
+#endif
+#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
@@ -53861,8 +54433,14 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
       rc = sqlite3OsFileSize(pPager->fd, &nByte);
     }
     if( rc==SQLITE_OK ){
-      pNew = (char *)sqlite3PageMalloc(pageSize);
-      if( !pNew ) rc = SQLITE_NOMEM_BKPT;
+      /* 8 bytes of zeroed overrun space is sufficient so that the b-tree
+      * cell header parser will never run off the end of the allocation */
+      pNew = (char *)sqlite3PageMalloc(pageSize+8);
+      if( !pNew ){
+        rc = SQLITE_NOMEM_BKPT;
+      }else{
+        memset(pNew+pageSize, 0, 8);
+      }
     }
 
     if( rc==SQLITE_OK ){
@@ -53914,7 +54492,10 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
     pPager->mxPgno = mxPage;
   }
   assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
-  assert( pPager->mxPgno>=pPager->dbSize );  /* OP_MaxPgcnt enforces this */
+  /* assert( pPager->mxPgno>=pPager->dbSize ); */
+  /* OP_MaxPgcnt ensures that the parameter passed to this function is not
+  ** less than the total number of valid pages in the database. But this
+  ** may be less than Pager.dbSize, and so the assert() above is not valid */
   return pPager->mxPgno;
 }
 
@@ -57107,7 +57688,11 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
   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;
@@ -57236,8 +57821,12 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
   */
   pPg->flags &= ~PGHDR_NEED_SYNC;
   pPgOld = sqlite3PagerLookup(pPager, pgno);
-  assert( !pPgOld || pPgOld->nRef==1 );
+  assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB );
   if( pPgOld ){
+    if( pPgOld->nRef>1 ){
+      sqlite3PagerUnrefNotNull(pPgOld);
+      return SQLITE_CORRUPT_BKPT;
+    }
     pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
     if( pPager->tempFile ){
       /* Do not discard pages from an in-memory database since we might
@@ -57765,7 +58354,7 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pS
 */
 SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
   assert( pPager->pWal );
-  return sqlite3WalSnapshotUnlock(pPager->pWal);
+  sqlite3WalSnapshotUnlock(pPager->pWal);
 }
 
 #endif /* SQLITE_ENABLE_SNAPSHOT */
@@ -58366,7 +58955,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
 
   /* Enlarge the pWal->apWiData[] array if required */
   if( pWal->nWiData<=iPage ){
-    int nByte = sizeof(u32*)*(iPage+1);
+    sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
     volatile u32 **apNew;
     apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
     if( !apNew ){
@@ -58470,6 +59059,7 @@ static void walChecksumBytes(
 
   assert( nByte>=8 );
   assert( (nByte&0x00000007)==0 );
+  assert( nByte<=65536 );
 
   if( nativeCksum ){
     do {
@@ -58777,6 +59367,7 @@ static void walCleanupHash(Wal *pWal){
   int iLimit = 0;                 /* Zero values greater than this */
   int nByte;                      /* Number of bytes to zero in aPgno[] */
   int i;                          /* Used to iterate through aHash[] */
+  int rc;                         /* Return code form walHashGet() */
 
   assert( pWal->writeLock );
   testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
@@ -58787,11 +59378,12 @@ static void walCleanupHash(Wal *pWal){
 
   /* Obtain pointers to the hash-table and page-number array containing 
   ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
-  ** that the page said hash-table and array reside on is already mapped.
+  ** that the page said hash-table and array reside on is already mapped.(1)
   */
   assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
   assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
-  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+  rc = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+  if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */
 
   /* Zero all hash-table entries that correspond to frame numbers greater
   ** than pWal->hdr.mxFrame.
@@ -59405,7 +59997,7 @@ 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 */
-  int nByte;                      /* Number of bytes to allocate */
+  sqlite3_int64 nByte;            /* Number of bytes to allocate */
   int i;                          /* Iterator variable */
   ht_slot *aTmp;                  /* Temp space used by merge-sort */
   int rc = SQLITE_OK;             /* Return Code */
@@ -60696,9 +61288,9 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
     }
     nCollide = HASHTABLE_NSLOT;
     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 ){
+      u32 iH = sLoc.aHash[iKey];
+      u32 iFrame = iH + sLoc.iZero;
+      if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
         assert( iFrame>iRead || CORRUPT_DB );
         iRead = iFrame;
       }
@@ -61941,7 +62533,7 @@ struct MemPage {
   u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
   u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
   u16 cellOffset;      /* Index in aData of first cell pointer */
-  u16 nFree;           /* Number of free bytes on the page */
+  int nFree;           /* Number of free bytes on the page. -1 for unknown */
   u16 nCell;           /* Number of cells on this page, local and ovfl */
   u16 maskPage;        /* Mask for page offset */
   u16 aiOvfl[4];       /* Insert the i-th overflow cell before the aiOvfl-th
@@ -62149,9 +62741,16 @@ struct CellInfo {
 ** found at self->pBt->mutex. 
 **
 ** skipNext meaning:
-**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
-**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
-**    eState==FAULT:                   Cursor fault with skipNext as error code.
+** The meaning of skipNext depends on the value of eState:
+**
+**   eState            Meaning of skipNext
+**   VALID             skipNext is meaningless and is ignored
+**   INVALID           skipNext is meaningless and is ignored
+**   SKIPNEXT          sqlite3BtreeNext() is a no-op if skipNext>0 and
+**                     sqlite3BtreePrevious() is no-op if skipNext<0.
+**   REQUIRESEEK       restoreCursorPosition() restores the cursor to
+**                     eState=SKIPNEXT if skipNext!=0
+**   FAULT             skipNext holds the cursor fault error code.
 */
 struct BtCursor {
   u8 eState;                /* One of the CURSOR_XXX constants (see below) */
@@ -63315,13 +63914,19 @@ static int saveCursorKey(BtCursor *pCur){
     /* Only the rowid is required for a table btree */
     pCur->nKey = sqlite3BtreeIntegerKey(pCur);
   }else{
-    /* For an index btree, save the complete key content */
+    /* For an index btree, save the complete key content. It is possible
+    ** that the current key is corrupt. In that case, it is possible that
+    ** the sqlite3VdbeRecordUnpack() function may overread the buffer by
+    ** up to the size of 1 varint plus 1 8-byte value when the cursor 
+    ** position is restored. Hence the 17 bytes of padding allocated 
+    ** below. */
     void *pKey;
     pCur->nKey = sqlite3BtreePayloadSize(pCur);
-    pKey = sqlite3Malloc( pCur->nKey );
+    pKey = sqlite3Malloc( pCur->nKey + 9 + 8 );
     if( pKey ){
       rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
       if( rc==SQLITE_OK ){
+        memset(((u8*)pKey)+pCur->nKey, 0, 9+8);
         pCur->pKey = pKey;
       }else{
         sqlite3_free(pKey);
@@ -63453,11 +64058,12 @@ static int btreeMoveto(
   UnpackedRecord *pIdxKey;   /* Unpacked index key */
 
   if( pKey ){
+    KeyInfo *pKeyInfo = pCur->pKeyInfo;
     assert( nKey==(i64)(int)nKey );
-    pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo);
+    pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
     if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
-    sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
-    if( pIdxKey->nField==0 ){
+    sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey);
+    if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){
       rc = SQLITE_CORRUPT_BKPT;
       goto moveto_done;
     }
@@ -63481,19 +64087,23 @@ moveto_done:
 */
 static int btreeRestoreCursorPosition(BtCursor *pCur){
   int rc;
-  int skipNext;
+  int skipNext = 0;
   assert( cursorOwnsBtShared(pCur) );
   assert( pCur->eState>=CURSOR_REQUIRESEEK );
   if( pCur->eState==CURSOR_FAULT ){
     return pCur->skipNext;
   }
   pCur->eState = CURSOR_INVALID;
-  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
+  if( sqlite3FaultSim(410) ){
+    rc = SQLITE_IOERR;
+  }else{
+    rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
+  }
   if( rc==SQLITE_OK ){
     sqlite3_free(pCur->pKey);
     pCur->pKey = 0;
     assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
-    pCur->skipNext |= skipNext;
+    if( skipNext ) pCur->skipNext = skipNext;
     if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
       pCur->eState = CURSOR_SKIPNEXT;
     }
@@ -63563,7 +64173,6 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
   if( pCur->eState!=CURSOR_VALID ){
     *pDifferentRow = 1;
   }else{
-    assert( pCur->skipNext==0 );
     *pDifferentRow = 0;
   }
   return SQLITE_OK;
@@ -63647,6 +64256,13 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
     *pRC = rc;
     return;
   }
+  if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){
+    /* The first byte of the extra data is the MemPage.isInit byte.
+    ** If that byte is set, it means this page is also being used
+    ** as a btree page. */
+    *pRC = SQLITE_CORRUPT_BKPT;
+    goto ptrmap_exit;
+  }
   offset = PTRMAP_PTROFFSET(iPtrmap, key);
   if( offset<0 ){
     *pRC = SQLITE_CORRUPT_BKPT;
@@ -63709,7 +64325,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
 #else /* if defined SQLITE_OMIT_AUTOVACUUM */
   #define ptrmapPut(w,x,y,z,rc)
   #define ptrmapGet(w,x,y,z) SQLITE_OK
-  #define ptrmapPutOvflPtr(x, y, rc)
+  #define ptrmapPutOvflPtr(x, y, z, rc)
 #endif
 
 /*
@@ -64002,17 +64618,24 @@ static u16 cellSize(MemPage *pPage, int iCell){
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
-** If the cell pCell, part of page pPage contains a pointer
-** to an overflow page, insert an entry into the pointer-map
-** for the overflow page.
+** The cell pCell is currently part of page pSrc but will ultimately be part
+** of pPage.  (pSrc and pPager are often the same.)  If pCell contains a
+** pointer to an overflow page, insert an entry into the pointer-map for
+** the overflow page that will be valid after pCell has been moved to pPage.
 */
-static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
+static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
   CellInfo info;
   if( *pRC ) return;
   assert( pCell!=0 );
   pPage->xParseCell(pPage, pCell, &info);
   if( info.nLocal<info.nPayload ){
-    Pgno ovfl = get4byte(&pCell[info.nSize-4]);
+    Pgno ovfl;
+    if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
+      testcase( pSrc!=pPage );
+      *pRC = SQLITE_CORRUPT_BKPT;
+      return;
+    }
+    ovfl = get4byte(&pCell[info.nSize-4]);
     ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
   }
 }
@@ -64056,7 +64679,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
   hdr = pPage->hdrOffset;
   cellOffset = pPage->cellOffset;
   nCell = pPage->nCell;
-  assert( nCell==get2byte(&data[hdr+3]) );
+  assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB );
   iCellFirst = cellOffset + 2*nCell;
   usableSize = pPage->pBt->usableSize;
 
@@ -64067,19 +64690,10 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
   ** reconstruct the entire page.  */
   if( (int)data[hdr+7]<=nMaxFrag ){
     int iFree = get2byte(&data[hdr+1]);
+    if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
     if( iFree ){
       int iFree2 = get2byte(&data[iFree]);
-
-      /* pageFindSlot() has already verified that free blocks are sorted
-      ** in order of offset within the page, and that no block extends
-      ** past the end of the page. Provided the two free slots do not 
-      ** overlap, this guarantees that the memmove() calls below will not
-      ** overwrite the usableSize byte buffer, even if the database page
-      ** is corrupt.  */
-      assert( iFree2==0 || iFree2>iFree );
-      assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
-      assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
-
+      if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
       if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
         u8 *pEnd = &data[cellOffset + nCell*2];
         u8 *pAddr;
@@ -64090,12 +64704,15 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
           return SQLITE_CORRUPT_PAGE(pPage);
         }
         if( iFree2 ){
-          assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
+          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
           sz2 = get2byte(&data[iFree2+2]);
-          assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+          if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
           memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
           sz += sz2;
+        }else if( iFree+sz>usableSize ){
+          return SQLITE_CORRUPT_PAGE(pPage);
         }
+
         cbrk = top+sz;
         assert( cbrk+(iFree-top) <= usableSize );
         memmove(&data[cbrk], &data[top], iFree-top);
@@ -64146,6 +64763,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
   data[hdr+7] = 0;
 
  defragment_out:
+  assert( pPage->nFree>=0 );
   if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
     return SQLITE_CORRUPT_PAGE(pPage);
   }
@@ -64173,16 +64791,16 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
 ** causes the fragmentation count to exceed 60.
 */
 static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
-  const int hdr = pPg->hdrOffset;
-  u8 * const aData = pPg->aData;
-  int iAddr = hdr + 1;
-  int pc = get2byte(&aData[iAddr]);
-  int x;
-  int usableSize = pPg->pBt->usableSize;
-  int size;            /* Size of the free slot */
+  const int hdr = pPg->hdrOffset;            /* Offset to page header */
+  u8 * const aData = pPg->aData;             /* Page data */
+  int iAddr = hdr + 1;                       /* Address of ptr to pc */
+  int pc = get2byte(&aData[iAddr]);          /* Address of a free slot */
+  int x;                                     /* Excess size of the slot */
+  int maxPC = pPg->pBt->usableSize - nByte;  /* Max address for a usable slot */
+  int size;                                  /* Size of the free slot */
 
   assert( pc>0 );
-  while( pc<=usableSize-4 ){
+  while( pc<=maxPC ){
     /* 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. */
@@ -64190,10 +64808,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
     if( (x = size - nByte)>=0 ){
       testcase( x==4 );
       testcase( x==3 );
-      if( size+pc > usableSize ){
-        *pRc = SQLITE_CORRUPT_PAGE(pPg);
-        return 0;
-      }else if( x<4 ){
+      if( x<4 ){
         /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
         ** number of bytes in fragments may not exceed 60. */
         if( aData[hdr+7]>57 ) return 0;
@@ -64202,21 +64817,31 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
         ** fragmented bytes within the page. */
         memcpy(&aData[iAddr], &aData[pc], 2);
         aData[hdr+7] += (u8)x;
+      }else if( x+pc > maxPC ){
+        /* This slot extends off the end of the usable part of the page */
+        *pRc = SQLITE_CORRUPT_PAGE(pPg);
+        return 0;
       }else{
         /* The slot remains on the free-list. Reduce its size to account
-         ** for the portion used by the new allocation. */
+        ** for the portion used by the new allocation. */
         put2byte(&aData[pc+2], x);
       }
       return &aData[pc + x];
     }
     iAddr = pc;
     pc = get2byte(&aData[pc]);
-    if( pc<iAddr+size ) break;
+    if( pc<=iAddr+size ){
+      if( pc ){
+        /* The next slot in the chain is not past the end of the current slot */
+        *pRc = SQLITE_CORRUPT_PAGE(pPg);
+      }
+      return 0;
+    }
   }
-  if( pc ){
+  if( pc>maxPC+nByte-4 ){
+    /* The free slot chain extends off the end of the page */
     *pRc = SQLITE_CORRUPT_PAGE(pPg);
   }
-
   return 0;
 }
 
@@ -64257,7 +64882,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   ** However, that integer is too large to be stored in a 2-byte unsigned
   ** integer, so a value of 0 is used in its place. */
   top = get2byte(&data[hdr+5]);
-  assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
+  assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
   if( gap>top ){
     if( top==0 && pPage->pBt->usableSize==65536 ){
       top = 65536;
@@ -64266,9 +64891,9 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
     }
   }
 
-  /* If there is enough space between gap and top for one more cell pointer
-  ** array entry offset, and if the freelist is not empty, then search the
-  ** freelist looking for a free slot big enough to satisfy the request.
+  /* If there is enough space between gap and top for one more cell pointer,
+  ** and if the freelist is not empty, then search the
+  ** freelist looking for a slot big enough to satisfy the request.
   */
   testcase( gap+2==top );
   testcase( gap+1==top );
@@ -64290,6 +64915,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   testcase( gap+2+nByte==top );
   if( gap+2+nByte>top ){
     assert( pPage->nCell>0 || CORRUPT_DB );
+    assert( pPage->nFree>=0 );
     rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
     if( rc ) return rc;
     top = get2byteNotZero(&data[hdr+5]);
@@ -64298,7 +64924,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
 
 
   /* Allocate memory from the gap in between the cell pointer array
-  ** and the cell content area.  The btreeInitPage() call has already
+  ** and the cell content area.  The btreeComputeFreeSpace() call has already
   ** validated the freelist.  Given that the freelist is valid, there
   ** is no way that the allocation can extend off the end of the page.
   ** The assert() below verifies the previous sentence.
@@ -64317,7 +64943,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
 **
 ** Adjacent freeblocks are coalesced.
 **
-** Note that even though the freeblock list was checked by btreeInitPage(),
+** Even though the freeblock list was checked by btreeComputeFreeSpace(),
 ** that routine will not detect overlap between cells or freeblocks.  Nor
 ** does it detect cells or freeblocks that encrouch into the reserved bytes
 ** at the end of the page.  So do additional corruption checks inside this
@@ -64479,21 +65105,14 @@ static int decodeFlags(MemPage *pPage, int flagByte){
 }
 
 /*
-** Initialize the auxiliary information for a disk block.
-**
-** Return SQLITE_OK on success.  If we see that the page does
-** not contain a well-formed database page, then return 
-** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
-** guarantee that the page is well-formed.  It only shows that
-** we failed to detect any corruption.
+** Compute the amount of freespace on the page.  In other words, fill
+** in the pPage->nFree field.
 */
-static int btreeInitPage(MemPage *pPage){
+static int btreeComputeFreeSpace(MemPage *pPage){
   int pc;            /* Address of a freeblock within pPage->aData[] */
   u8 hdr;            /* Offset to beginning of page header */
   u8 *data;          /* Equal to pPage->aData */
-  BtShared *pBt;        /* The main btree structure */
   int usableSize;    /* Amount of usable space on each page */
-  u16 cellOffset;    /* Offset from start of page to first cell pointer */
   int nFree;         /* Number of unused bytes on the page */
   int top;           /* First byte of the cell content area */
   int iCellFirst;    /* First allowable cell or freeblock offset */
@@ -64505,71 +65124,18 @@ static int btreeInitPage(MemPage *pPage){
   assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
   assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
   assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
-  assert( pPage->isInit==0 );
+  assert( pPage->isInit==1 );
+  assert( pPage->nFree<0 );
 
-  pBt = pPage->pBt;
+  usableSize = pPage->pBt->usableSize;
   hdr = pPage->hdrOffset;
   data = pPage->aData;
-  /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
-  ** the b-tree page type. */
-  if( decodeFlags(pPage, data[hdr]) ){
-    return SQLITE_CORRUPT_PAGE(pPage);
-  }
-  assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
-  pPage->maskPage = (u16)(pBt->pageSize - 1);
-  pPage->nOverflow = 0;
-  usableSize = pBt->usableSize;
-  pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
-  pPage->aDataEnd = &data[usableSize];
-  pPage->aCellIdx = &data[cellOffset];
-  pPage->aDataOfst = &data[pPage->childPtrSize];
   /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
   ** the start of the cell content area. A zero value for this integer is
   ** interpreted as 65536. */
   top = get2byteNotZero(&data[hdr+5]);
-  /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
-  ** number of cells on the page. */
-  pPage->nCell = get2byte(&data[hdr+3]);
-  if( pPage->nCell>MX_CELL(pBt) ){
-    /* To many cells for a single page.  The page must be corrupt */
-    return SQLITE_CORRUPT_PAGE(pPage);
-  }
-  testcase( pPage->nCell==MX_CELL(pBt) );
-  /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
-  ** possible for a root page of a table that contains no rows) then the
-  ** offset to the cell content area will equal the page size minus the
-  ** bytes of reserved space. */
-  assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
-
-  /* A malformed database page might cause us to read past the end
-  ** of page when parsing a cell.  
-  **
-  ** The following block of code checks early to see if a cell extends
-  ** past the end of a page boundary and causes SQLITE_CORRUPT to be 
-  ** returned if it does.
-  */
-  iCellFirst = cellOffset + 2*pPage->nCell;
+  iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell;
   iCellLast = usableSize - 4;
-  if( pBt->db->flags & SQLITE_CellSizeCk ){
-    int i;            /* Index into the cell pointer array */
-    int sz;           /* Size of a cell */
-
-    if( !pPage->leaf ) iCellLast--;
-    for(i=0; i<pPage->nCell; i++){
-      pc = get2byteAligned(&data[cellOffset+i*2]);
-      testcase( pc==iCellFirst );
-      testcase( pc==iCellLast );
-      if( pc<iCellFirst || pc>iCellLast ){
-        return SQLITE_CORRUPT_PAGE(pPage);
-      }
-      sz = pPage->xCellSize(pPage, &data[pc]);
-      testcase( pc+sz==usableSize );
-      if( pc+sz>usableSize ){
-        return SQLITE_CORRUPT_PAGE(pPage);
-      }
-    }
-    if( !pPage->leaf ) iCellLast++;
-  }  
 
   /* Compute the total free space on the page
   ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
@@ -64613,11 +65179,104 @@ static int btreeInitPage(MemPage *pPage){
   ** serves to verify that the offset to the start of the cell-content
   ** area, according to the page header, lies within the page.
   */
-  if( nFree>usableSize ){
+  if( nFree>usableSize || nFree<iCellFirst ){
     return SQLITE_CORRUPT_PAGE(pPage);
   }
   pPage->nFree = (u16)(nFree - iCellFirst);
+  return SQLITE_OK;
+}
+
+/*
+** Do additional sanity check after btreeInitPage() if
+** PRAGMA cell_size_check=ON 
+*/
+static SQLITE_NOINLINE int btreeCellSizeCheck(MemPage *pPage){
+  int iCellFirst;    /* First allowable cell or freeblock offset */
+  int iCellLast;     /* Last possible cell or freeblock offset */
+  int i;             /* Index into the cell pointer array */
+  int sz;            /* Size of a cell */
+  int pc;            /* Address of a freeblock within pPage->aData[] */
+  u8 *data;          /* Equal to pPage->aData */
+  int usableSize;    /* Maximum usable space on the page */
+  int cellOffset;    /* Start of cell content area */
+
+  iCellFirst = pPage->cellOffset + 2*pPage->nCell;
+  usableSize = pPage->pBt->usableSize;
+  iCellLast = usableSize - 4;
+  data = pPage->aData;
+  cellOffset = pPage->cellOffset;
+  if( !pPage->leaf ) iCellLast--;
+  for(i=0; i<pPage->nCell; i++){
+    pc = get2byteAligned(&data[cellOffset+i*2]);
+    testcase( pc==iCellFirst );
+    testcase( pc==iCellLast );
+    if( pc<iCellFirst || pc>iCellLast ){
+      return SQLITE_CORRUPT_PAGE(pPage);
+    }
+    sz = pPage->xCellSize(pPage, &data[pc]);
+    testcase( pc+sz==usableSize );
+    if( pc+sz>usableSize ){
+      return SQLITE_CORRUPT_PAGE(pPage);
+    }
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Initialize the auxiliary information for a disk block.
+**
+** Return SQLITE_OK on success.  If we see that the page does
+** not contain a well-formed database page, then return 
+** SQLITE_CORRUPT.  Note that a return of SQLITE_OK does not
+** guarantee that the page is well-formed.  It only shows that
+** we failed to detect any corruption.
+*/
+static int btreeInitPage(MemPage *pPage){
+  u8 *data;          /* Equal to pPage->aData */
+  BtShared *pBt;        /* The main btree structure */
+
+  assert( pPage->pBt!=0 );
+  assert( pPage->pBt->db!=0 );
+  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
+  assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
+  assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
+  assert( pPage->isInit==0 );
+
+  pBt = pPage->pBt;
+  data = pPage->aData + pPage->hdrOffset;
+  /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+  ** the b-tree page type. */
+  if( decodeFlags(pPage, data[0]) ){
+    return SQLITE_CORRUPT_PAGE(pPage);
+  }
+  assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
+  pPage->maskPage = (u16)(pBt->pageSize - 1);
+  pPage->nOverflow = 0;
+  pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
+  pPage->aCellIdx = data + pPage->childPtrSize + 8;
+  pPage->aDataEnd = pPage->aData + pBt->usableSize;
+  pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
+  /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+  ** number of cells on the page. */
+  pPage->nCell = get2byte(&data[3]);
+  if( pPage->nCell>MX_CELL(pBt) ){
+    /* To many cells for a single page.  The page must be corrupt */
+    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
+  ** possible for a root page of a table that contains no rows) then the
+  ** offset to the cell content area will equal the page size minus the
+  ** bytes of reserved space. */
+  assert( pPage->nCell>0
+       || get2byteNotZero(&data[5])==(int)pBt->usableSize
+       || CORRUPT_DB );
+  pPage->nFree = -1;  /* Indicate that this value is yet uncomputed */
   pPage->isInit = 1;
+  if( pBt->db->flags & SQLITE_CellSizeCk ){
+    return btreeCellSizeCheck(pPage);
+  }
   return SQLITE_OK;
 }
 
@@ -64760,19 +65419,18 @@ static int getAndInitPage(
 
   if( pgno>btreePagecount(pBt) ){
     rc = SQLITE_CORRUPT_BKPT;
-    goto getAndInitPage_error;
+    goto getAndInitPage_error1;
   }
   rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
   if( rc ){
-    goto getAndInitPage_error;
+    goto getAndInitPage_error1;
   }
   *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
   if( (*ppPage)->isInit==0 ){
     btreePageFromDbPage(pDbPage, pgno, pBt);
     rc = btreeInitPage(*ppPage);
     if( rc!=SQLITE_OK ){
-      releasePage(*ppPage);
-      goto getAndInitPage_error;
+      goto getAndInitPage_error2;
     }
   }
   assert( (*ppPage)->pgno==pgno );
@@ -64782,12 +65440,13 @@ static int getAndInitPage(
   ** compatible with the root page. */
   if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
     rc = SQLITE_CORRUPT_PGNO(pgno);
-    releasePage(*ppPage);
-    goto getAndInitPage_error;
+    goto getAndInitPage_error2;
   }
   return SQLITE_OK;
 
-getAndInitPage_error:
+getAndInitPage_error2:
+  releasePage(*ppPage);
+getAndInitPage_error1:
   if( pCur ){
     pCur->iPage--;
     pCur->pPage = pCur->apPage[pCur->iPage];
@@ -65647,9 +66306,9 @@ static int newDatabase(BtShared*);
 static int lockBtree(BtShared *pBt){
   int rc;              /* Result code from subfunctions */
   MemPage *pPage1;     /* Page 1 of the database file */
-  int nPage;           /* Number of pages in the database */
-  int nPageFile = 0;   /* Number of pages in the database file */
-  int nPageHeader;     /* Number of pages in the database according to hdr */
+  u32 nPage;           /* Number of pages in the database */
+  u32 nPageFile = 0;   /* Number of pages in the database file */
+  u32 nPageHeader;     /* Number of pages in the database according to hdr */
 
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( pBt->pPage1==0 );
@@ -65662,7 +66321,7 @@ static int lockBtree(BtShared *pBt){
   ** a valid database file. 
   */
   nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
-  sqlite3PagerPagecount(pBt->pPager, &nPageFile);
+  sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
   if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
     nPage = nPageFile;
   }
@@ -65743,6 +66402,7 @@ static int lockBtree(BtShared *pBt){
     ){
       goto page1_init_failed;
     }
+    pBt->btsFlags |= BTS_PAGESIZE_FIXED;
     assert( (pageSize & 7)==0 );
     /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
     ** integer at offset 20 is the number of bytes of space at the end of
@@ -65767,7 +66427,7 @@ static int lockBtree(BtShared *pBt){
                                    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;
     }
@@ -66133,7 +66793,7 @@ static int setChildPtrmaps(MemPage *pPage){
   for(i=0; i<nCell; i++){
     u8 *pCell = findCell(pPage, i);
 
-    ptrmapPutOvflPtr(pPage, pCell, &rc);
+    ptrmapPutOvflPtr(pPage, pPage, pCell, &rc);
 
     if( !pPage->leaf ){
       Pgno childPgno = get4byte(pCell);
@@ -66241,6 +66901,7 @@ static int relocatePage(
       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", 
@@ -66746,6 +67407,18 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
   return rc;
 }
 
+/*
+** Set the pBt->nPage field correctly, according to the current
+** state of the database.  Assume pBt->pPage1 is valid.
+*/
+static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
+  int nPage = get4byte(&pPage1->aData[28]);
+  testcase( nPage==0 );
+  if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
+  testcase( pBt->nPage!=nPage );
+  pBt->nPage = nPage;
+}
+
 /*
 ** Rollback the transaction in progress.
 **
@@ -66791,11 +67464,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
     ** call btreeGetPage() on page 1 again to make
     ** sure pPage1->aData is set correctly. */
     if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
-      int nPage = get4byte(28+(u8*)pPage1->aData);
-      testcase( nPage==0 );
-      if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
-      testcase( pBt->nPage!=nPage );
-      pBt->nPage = nPage;
+      btreeSetNPage(pBt, pPage1);
       releasePageOne(pPage1);
     }
     assert( countValidCursors(pBt, 1)==0 );
@@ -66875,12 +67544,11 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
         pBt->nPage = 0;
       }
       rc = newDatabase(pBt);
-      pBt->nPage = get4byte(28 + pBt->pPage1->aData);
+      btreeSetNPage(pBt, pBt->pPage1);
 
-      /* The database size was written into the offset 28 of the header
-      ** when the transaction started, so we know that the value at offset
-      ** 28 is nonzero. */
-      assert( pBt->nPage>0 );
+      /* pBt->nPage might be zero if the database was corrupt when 
+      ** the transaction was started. Otherwise, it must be at least 1.  */
+      assert( CORRUPT_DB || pBt->nPage>0 );
     }
     sqlite3BtreeLeave(p);
   }
@@ -67058,6 +67726,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
     sqlite3_free(pCur->aOverflow);
     sqlite3_free(pCur->pKey);
     sqlite3BtreeLeave(pBtree);
+    pCur->pBtree = 0;
   }
   return SQLITE_OK;
 }
@@ -67156,6 +67825,25 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
   return pCur->info.nPayload;
 }
 
+/*
+** Return an upper bound on the size of any record for the table
+** that the cursor is pointing into.
+**
+** This is an optimization.  Everything will still work if this
+** routine always returns 2147483647 (which is the largest record
+** that SQLite can handle) or more.  But returning a smaller value might
+** prevent large memory allocations when trying to interpret a
+** corrupt datrabase.
+**
+** The current implementation merely returns the size of the underlying
+** database file.
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){
+  assert( cursorHoldsMutex(pCur) );
+  assert( pCur->eState==CURSOR_VALID );
+  return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage;
+}
+
 /*
 ** Given the page number of an overflow page in the database (parameter
 ** ovfl), this function finds the page number of the next page in the 
@@ -67412,9 +68100,6 @@ static int accessPayload(
         /* 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;
@@ -67425,7 +68110,7 @@ static int accessPayload(
         **
         **   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 
@@ -67436,11 +68121,10 @@ static int accessPayload(
         */
         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) */
@@ -67850,23 +68534,6 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
   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.
@@ -67889,6 +68556,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
     assert( pCur->ix==pCur->pPage->nCell-1 );
     assert( pCur->pPage->leaf );
 #endif
+    *pRes = 0;
     return SQLITE_OK;
   }
 
@@ -67974,7 +68642,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
       ** try to get there using sqlite3BtreeNext() rather than a full
       ** binary search.  This is an optimization only.  The correct answer
       ** is still obtained without this case, only a little more slowely */
-      if( pCur->info.nKey+1==intKey && !pCur->skipNext ){
+      if( pCur->info.nKey+1==intKey ){
         *pRes = 0;
         rc = sqlite3BtreeNext(pCur, 0);
         if( rc==SQLITE_OK ){
@@ -68110,29 +68778,31 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
           ** case this happens.  */
           void *pCellKey;
           u8 * const pCellBody = pCell - pPage->childPtrSize;
+          const int nOverrun = 18;  /* Size of the overrun padding */
           pPage->xParseCell(pPage, pCellBody, &pCur->info);
           nCell = (int)pCur->info.nKey;
           testcase( nCell<0 );   /* True if key size is 2^32 or more */
           testcase( nCell==0 );  /* Invalid key size:  0x80 0x80 0x00 */
           testcase( nCell==1 );  /* Invalid key size:  0x80 0x80 0x01 */
           testcase( nCell==2 );  /* Minimum legal index key size */
-          if( nCell<2 ){
+          if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
             rc = SQLITE_CORRUPT_PAGE(pPage);
             goto moveto_finish;
           }
-          pCellKey = sqlite3Malloc( nCell+18 );
+          pCellKey = sqlite3Malloc( nCell+nOverrun );
           if( pCellKey==0 ){
             rc = SQLITE_NOMEM_BKPT;
             goto moveto_finish;
           }
           pCur->ix = (u16)idx;
           rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
+          memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
           pCur->curFlags &= ~BTCF_ValidOvfl;
           if( rc ){
             sqlite3_free(pCellKey);
             goto moveto_finish;
           }
-          c = xRecordCompare(nCell, pCellKey, pIdxKey);
+          c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
           sqlite3_free(pCellKey);
         }
         assert( 
@@ -68248,7 +68918,6 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
   MemPage *pPage;
 
   assert( cursorOwnsBtShared(pCur) );
-  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
   if( pCur->eState!=CURSOR_VALID ){
     assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
     rc = restoreCursorPosition(pCur);
@@ -68258,14 +68927,9 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
     if( CURSOR_INVALID==pCur->eState ){
       return SQLITE_DONE;
     }
-    if( pCur->skipNext ){
-      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+    if( pCur->eState==CURSOR_SKIPNEXT ){
       pCur->eState = CURSOR_VALID;
-      if( pCur->skipNext>0 ){
-        pCur->skipNext = 0;
-        return SQLITE_OK;
-      }
-      pCur->skipNext = 0;
+      if( pCur->skipNext>0 ) return SQLITE_OK;
     }
   }
 
@@ -68320,7 +68984,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
   UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
   assert( cursorOwnsBtShared(pCur) );
   assert( flags==0 || flags==1 );
-  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
   pCur->info.nSize = 0;
   pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
   if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
@@ -68361,7 +69024,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
   MemPage *pPage;
 
   assert( cursorOwnsBtShared(pCur) );
-  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
   assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
   assert( pCur->info.nSize==0 );
   if( pCur->eState!=CURSOR_VALID ){
@@ -68372,14 +69034,9 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
     if( CURSOR_INVALID==pCur->eState ){
       return SQLITE_DONE;
     }
-    if( pCur->skipNext ){
-      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+    if( CURSOR_SKIPNEXT==pCur->eState ){
       pCur->eState = CURSOR_VALID;
-      if( pCur->skipNext<0 ){
-        pCur->skipNext = 0;
-        return SQLITE_OK;
-      }
-      pCur->skipNext = 0;
+      if( pCur->skipNext<0 ) return SQLITE_OK;
     }
   }
 
@@ -68414,7 +69071,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
 SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
   assert( cursorOwnsBtShared(pCur) );
   assert( flags==0 || flags==1 );
-  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
   UNUSED_PARAMETER( flags );  /* Used in COMDB2 but not native SQLite */
   pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
   pCur->info.nSize = 0;
@@ -68750,7 +69406,7 @@ static int allocateBtreePage(
     TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
   }
 
-  assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+  assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) );
 
 end_allocate_page:
   releasePage(pTrunk);
@@ -68778,13 +69434,15 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
   MemPage *pPage1 = pBt->pPage1;      /* Local reference to page 1 */
   MemPage *pPage;                     /* Page being freed. May be NULL. */
   int rc;                             /* Return Code */
-  int nFree;                          /* Initial number of pages on free-list */
+  u32 nFree;                          /* Initial number of pages on free-list */
 
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( CORRUPT_DB || iPage>1 );
   assert( !pMemPage || pMemPage->pgno==iPage );
 
-  if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
+  if( iPage<2 || iPage>pBt->nPage ){
+    return SQLITE_CORRUPT_BKPT;
+  }
   if( pMemPage ){
     pPage = pMemPage;
     sqlite3PagerRef(pPage->pDbPage);
@@ -69195,6 +69853,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
   assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+  assert( pPage->nFree>=0 );
   data = pPage->aData;
   ptr = &pPage->aCellIdx[2*idx];
   pc = get2byte(ptr);
@@ -69265,6 +69924,7 @@ static void insertCell(
   ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
   ** the term after the || in the following assert(). */
   assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
+  assert( pPage->nFree>=0 );
   if( pPage->nOverflow || sz+2>pPage->nFree ){
     if( pTemp ){
       memcpy(pTemp, pCell, sz);
@@ -69305,9 +69965,16 @@ static void insertCell(
     assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
     assert( idx+sz <= (int)pPage->pBt->usableSize );
     pPage->nFree -= (u16)(2 + sz);
-    memcpy(&data[idx], pCell, sz);
     if( iChild ){
+      /* In a corrupt database where an entry in the cell index section of
+      ** a btree page has a value of 3 or less, the pCell value might point
+      ** as many as 4 bytes in front of the start of the aData buffer for
+      ** the source page.  Make sure this does not cause problems by not
+      ** reading the first 4 bytes */
+      memcpy(&data[idx+4], pCell+4, sz-4);
       put4byte(&data[idx], iChild);
+    }else{
+      memcpy(&data[idx], pCell, sz);
     }
     pIns = pPage->aCellIdx + i*2;
     memmove(pIns+2, pIns, 2*(pPage->nCell - i));
@@ -69315,21 +69982,100 @@ static void insertCell(
     pPage->nCell++;
     /* increment the cell count */
     if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++;
-    assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell );
+    assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB );
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pPage->pBt->autoVacuum ){
       /* The cell may contain a pointer to an overflow page. If so, write
       ** the entry for the overflow page into the pointer map.
       */
-      ptrmapPutOvflPtr(pPage, pCell, pRC);
+      ptrmapPutOvflPtr(pPage, pPage, pCell, pRC);
     }
 #endif
   }
 }
 
+/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation.  NN is the number of neighbors on either side
+** of the page that participate in the balancing operation.  NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course).  Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+**
+** (Later:) The description above makes it seem as if these values are
+** tunable - as if you could change them and recompile and it would all work.
+** But that is unlikely.  NB has been 3 since the inception of SQLite and
+** we have never tested any other value.
+*/
+#define NN 1             /* Number of neighbors on either side of pPage */
+#define NB 3             /* (NN*2+1): Total pages involved in the balance */
+
 /*
 ** A CellArray object contains a cache of pointers and sizes for a
 ** consecutive sequence of cells that might be held on multiple pages.
+**
+** The cells in this array are the divider cell or cells from the pParent
+** page plus up to three child pages.  There are a total of nCell cells.
+**
+** pRef is a pointer to one of the pages that contributes cells.  This is
+** used to access information such as MemPage.intKey and MemPage.pBt->pageSize
+** which should be common to all pages that contribute cells to this array.
+**
+** apCell[] and szCell[] hold, respectively, pointers to the start of each
+** cell and the size of each cell.  Some of the apCell[] pointers might refer
+** to overflow cells.  In other words, some apCel[] pointers might not point
+** to content area of the pages.
+**
+** A szCell[] of zero means the size of that cell has not yet been computed.
+**
+** The cells come from as many as four different pages:
+**
+**             -----------
+**             | Parent  |
+**             -----------
+**            /     |     \
+**           /      |      \
+**  ---------   ---------   ---------
+**  |Child-1|   |Child-2|   |Child-3|
+**  ---------   ---------   ---------
+**
+** The order of cells is in the array is for an index btree is:
+**
+**       1.  All cells from Child-1 in order
+**       2.  The first divider cell from Parent
+**       3.  All cells from Child-2 in order
+**       4.  The second divider cell from Parent
+**       5.  All cells from Child-3 in order
+**
+** For a table-btree (with rowids) the items 2 and 4 are empty because
+** content exists only in leaves and there are no divider cells.
+**
+** For an index btree, the apEnd[] array holds pointer to the end of page
+** for Child-1, the Parent, Child-2, the Parent (again), and Child-3,
+** respectively. The ixNx[] array holds the number of cells contained in
+** each of these 5 stages, and all stages to the left.  Hence:
+**
+**    ixNx[0] = Number of cells in Child-1.
+**    ixNx[1] = Number of cells in Child-1 plus 1 for first divider.
+**    ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider.
+**    ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells
+**    ixNx[4] = Total number of cells.
+**
+** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2]
+** are used and they point to the leaf pages only, and the ixNx value are:
+**
+**    ixNx[0] = Number of cells in Child-1.
+**    ixNx[1] = Number of cells in Child-1 and Child-2.
+**    ixNx[2] = Total number of cells.
+**
+** Sometimes when deleting, a child page can have zero cells.  In those
+** cases, ixNx[] entries with higher indexes, and the corresponding apEnd[]
+** entries, shift down.  The end result is that each ixNx[] entry should
+** be larger than the previous
 */
 typedef struct CellArray CellArray;
 struct CellArray {
@@ -69337,6 +70083,8 @@ struct CellArray {
   MemPage *pRef;          /* Reference page */
   u8 **apCell;            /* All cells begin balanced */
   u16 *szCell;            /* Local size of all cells in apCell[] */
+  u8 *apEnd[NB*2];        /* MemPage.aDataEnd values */
+  int ixNx[NB*2];         /* Index of at which we move to the next apEnd[] */
 };
 
 /*
@@ -69387,36 +70135,59 @@ static u16 cachedCellSize(CellArray *p, int N){
 ** responsibility of the caller to set it correctly.
 */
 static int rebuildPage(
-  MemPage *pPg,                   /* Edit this page */
+  CellArray *pCArray,             /* Content to be added to page pPg */
+  int iFirst,                     /* First cell in pCArray to use */
   int nCell,                      /* Final number of cells on page */
-  u8 **apCell,                    /* Array of cells */
-  u16 *szCell                     /* Array of cell sizes */
+  MemPage *pPg                    /* The page to be reconstructed */
 ){
   const int hdr = pPg->hdrOffset;          /* Offset of header on pPg */
   u8 * const aData = pPg->aData;           /* Pointer to data for pPg */
   const int usableSize = pPg->pBt->usableSize;
   u8 * const pEnd = &aData[usableSize];
-  int i;
+  int i = iFirst;                 /* Which cell to copy from pCArray*/
+  u32 j;                          /* Start of cell content area */
+  int iEnd = i+nCell;             /* Loop terminator */
   u8 *pCellptr = pPg->aCellIdx;
   u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
   u8 *pData;
+  int k;                          /* Current slot in pCArray->apEnd[] */
+  u8 *pSrcEnd;                    /* Current pCArray->apEnd[k] value */
 
-  i = get2byte(&aData[hdr+5]);
-  memcpy(&pTmp[i], &aData[i], usableSize - i);
+  assert( i<iEnd );
+  j = get2byte(&aData[hdr+5]);
+  if( NEVER(j>(u32)usableSize) ){ j = 0; }
+  memcpy(&pTmp[j], &aData[j], usableSize - j);
+
+  for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
+  pSrcEnd = pCArray->apEnd[k];
 
   pData = pEnd;
-  for(i=0; i<nCell; i++){
-    u8 *pCell = apCell[i];
+  while( 1/*exit by break*/ ){
+    u8 *pCell = pCArray->apCell[i];
+    u16 sz = pCArray->szCell[i];
+    assert( sz>0 );
     if( SQLITE_WITHIN(pCell,aData,pEnd) ){
+      if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT;
       pCell = &pTmp[pCell - aData];
+    }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd
+           && (uptr)(pCell)<(uptr)pSrcEnd
+    ){
+      return SQLITE_CORRUPT_BKPT;
     }
-    pData -= szCell[i];
+
+    pData -= sz;
     put2byte(pCellptr, (pData - aData));
     pCellptr += 2;
     if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
-    memcpy(pData, pCell, szCell[i]);
-    assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
-    testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
+    memcpy(pData, pCell, sz);
+    assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
+    testcase( sz!=pPg->xCellSize(pPg,pCell) );
+    i++;
+    if( i>=iEnd ) break;
+    if( pCArray->ixNx[k]<=i ){
+      k++;
+      pSrcEnd = pCArray->apEnd[k];
+    }
   }
 
   /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
@@ -69431,12 +70202,11 @@ static int rebuildPage(
 }
 
 /*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
-** contains the size in bytes of each such cell. This function attempts to 
-** add the cells stored in the array to page pPg. If it cannot (because 
-** the page needs to be defragmented before the cells will fit), non-zero
-** is returned. Otherwise, if the cells are added successfully, zero is
-** returned.
+** The pCArray objects contains pointers to b-tree cells and the cell sizes.
+** This function attempts to add the cells stored in the array to page pPg.
+** If it cannot (because the page needs to be defragmented before the cells
+** will fit), non-zero is returned. Otherwise, if the cells are added
+** successfully, zero is returned.
 **
 ** Argument pCellptr points to the first entry in the cell-pointer array
 ** (part of page pPg) to populate. After cell apCell[0] is written to the
@@ -69458,18 +70228,23 @@ static int rebuildPage(
 static int pageInsertArray(
   MemPage *pPg,                   /* Page to add cells to */
   u8 *pBegin,                     /* End of cell-pointer array */
-  u8 **ppData,                    /* IN/OUT: Page content -area pointer */
+  u8 **ppData,                    /* IN/OUT: Page content-area pointer */
   u8 *pCellptr,                   /* Pointer to cell-pointer area */
   int iFirst,                     /* Index of first cell to add */
   int nCell,                      /* Number of cells to add to pPg */
   CellArray *pCArray              /* Array of cells */
 ){
-  int i;
-  u8 *aData = pPg->aData;
-  u8 *pData = *ppData;
-  int iEnd = iFirst + nCell;
+  int i = iFirst;                 /* Loop counter - cell index to insert */
+  u8 *aData = pPg->aData;         /* Complete page */
+  u8 *pData = *ppData;            /* Content area.  A subset of aData[] */
+  int iEnd = iFirst + nCell;      /* End of loop. One past last cell to ins */
+  int k;                          /* Current slot in pCArray->apEnd[] */
+  u8 *pEnd;                       /* Maximum extent of cell data */
   assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
-  for(i=iFirst; i<iEnd; i++){
+  if( iEnd<=iFirst ) return 0;
+  for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
+  pEnd = pCArray->apEnd[k];
+  while( 1 /*Exit by break*/ ){
     int sz, rc;
     u8 *pSlot;
     sz = cachedCellSize(pCArray, i);
@@ -69484,20 +70259,33 @@ static int pageInsertArray(
     assert( (pSlot+sz)<=pCArray->apCell[i]
          || pSlot>=(pCArray->apCell[i]+sz)
          || CORRUPT_DB );
+    if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd
+     && (uptr)(pCArray->apCell[i])<(uptr)pEnd
+    ){
+      assert( CORRUPT_DB );
+      (void)SQLITE_CORRUPT_BKPT;
+      return 1;
+    }
     memmove(pSlot, pCArray->apCell[i], sz);
     put2byte(pCellptr, (pSlot - aData));
     pCellptr += 2;
+    i++;
+    if( i>=iEnd ) break;
+    if( pCArray->ixNx[k]<=i ){
+      k++;
+      pEnd = pCArray->apEnd[k];
+    }
   }
   *ppData = pData;
   return 0;
 }
 
 /*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell 
-** contains the size in bytes of each such cell. This function adds the
-** space associated with each cell in the array that is currently stored 
-** within the body of pPg to the pPg free-list. The cell-pointers and other
-** fields of the page are not updated.
+** The pCArray object contains pointers to b-tree cells and their sizes.
+**
+** This function adds the space associated with each cell in the array
+** that is currently stored within the body of pPg to the pPg free-list.
+** The cell-pointers and other fields of the page are not updated.
 **
 ** This function returns the total number of cells added to the free-list.
 */
@@ -69547,9 +70335,9 @@ static int pageFreeArray(
 }
 
 /*
-** apCell[] and szCell[] contains pointers to and sizes of all cells in the
-** pages being balanced.  The current page, pPg, has pPg->nCell cells starting
-** with apCell[iOld].  After balancing, this page should hold nNew cells
+** pCArray contains pointers to and sizes of all cells in the page being
+** balanced.  The current page, pPg, has pPg->nCell cells starting with
+** pCArray->apCell[iOld].  After balancing, this page should hold nNew cells
 ** starting at apCell[iNew].
 **
 ** This routine makes the necessary adjustments to pPg so that it contains
@@ -69581,13 +70369,17 @@ static int editPage(
 #endif
 
   /* Remove cells from the start and end of the page */
+  assert( nCell>=0 );
   if( iOld<iNew ){
     int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
+    if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
     memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
     nCell -= nShift;
   }
   if( iNewEnd < iOldEnd ){
-    nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+    int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+    assert( nCell>=nTail );
+    nCell -= nTail;
   }
 
   pData = &aData[get2byteNotZero(&aData[hdr+5])];
@@ -69597,6 +70389,7 @@ static int editPage(
   if( iNew<iOld ){
     int nAdd = MIN(nNew,iOld-iNew);
     assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
+    assert( nAdd>=0 );
     pCellptr = pPg->aCellIdx;
     memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
     if( pageInsertArray(
@@ -69611,7 +70404,9 @@ static int editPage(
     int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
     if( iCell>=0 && iCell<nNew ){
       pCellptr = &pPg->aCellIdx[iCell * 2];
-      memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+      if( nCell>iCell ){
+        memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+      }
       nCell++;
       if( pageInsertArray(
             pPg, pBegin, &pData, pCellptr,
@@ -69621,6 +70416,7 @@ static int editPage(
   }
 
   /* Append cells to the end of the page */
+  assert( nCell>=0 );
   pCellptr = &pPg->aCellIdx[nCell*2];
   if( pageInsertArray(
         pPg, pBegin, &pData, pCellptr,
@@ -69649,24 +70445,9 @@ static int editPage(
  editpage_fail:
   /* Unable to edit this page. Rebuild it from scratch instead. */
   populateCellCache(pCArray, iNew, nNew);
-  return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
+  return rebuildPage(pCArray, iNew, nNew, pPg);
 }
 
-/*
-** The following parameters determine how many adjacent pages get involved
-** in a balancing operation.  NN is the number of neighbors on either side
-** of the page that participate in the balancing operation.  NB is the
-** total number of pages that participate, including the target page and
-** NN neighbors on either side.
-**
-** The minimum value of NN is 1 (of course).  Increasing NN above 1
-** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
-** in exchange for a larger degradation in INSERT and UPDATE performance.
-** The value of NN appears to give the best results overall.
-*/
-#define NN 1             /* Number of neighbors on either side of pPage */
-#define NB (NN*2+1)      /* Total pages involved in the balance */
-
 
 #ifndef SQLITE_OMIT_QUICKBALANCE
 /*
@@ -69701,9 +70482,10 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   assert( sqlite3PagerIswriteable(pParent->pDbPage) );
   assert( pPage->nOverflow==1 );
-
-  /* This error condition is now caught prior to reaching this function */
-  if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
+  
+  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;  /* dbfuzz001.test */
+  assert( pPage->nFree>=0 );
+  assert( pParent->nFree>=0 );
 
   /* Allocate a new page. This page will become the right-sibling of 
   ** pPage. Make the parent page writable, so that the new divider cell
@@ -69717,12 +70499,22 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
     u8 *pCell = pPage->apOvfl[0];
     u16 szCell = pPage->xCellSize(pPage, pCell);
     u8 *pStop;
+    CellArray b;
 
     assert( sqlite3PagerIswriteable(pNew->pDbPage) );
-    assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
+    assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
     zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
-    rc = rebuildPage(pNew, 1, &pCell, &szCell);
-    if( NEVER(rc) ) return rc;
+    b.nCell = 1;
+    b.pRef = pPage;
+    b.apCell = &pCell;
+    b.szCell = &szCell;
+    b.apEnd[0] = pPage->aDataEnd;
+    b.ixNx[0] = 2;
+    rc = rebuildPage(&b, 0, 1, pNew);
+    if( NEVER(rc) ){
+      releasePage(pNew);
+      return rc;
+    }
     pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
 
     /* If this is an auto-vacuum database, update the pointer map
@@ -69737,7 +70529,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
     if( ISAUTOVACUUM ){
       ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
       if( szCell>pNew->minLocal ){
-        ptrmapPutOvflPtr(pNew, pCell, &rc);
+        ptrmapPutOvflPtr(pNew, pNew, pCell, &rc);
       }
     }
   
@@ -69863,6 +70655,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
     */
     pTo->isInit = 0;
     rc = btreeInitPage(pTo);
+    if( rc==SQLITE_OK ) rc = btreeComputeFreeSpace(pTo);
     if( rc!=SQLITE_OK ){
       *pRC = rc;
       return;
@@ -69960,10 +70753,6 @@ static int balance_nonroot(
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( sqlite3PagerIswriteable(pParent->pDbPage) );
 
-#if 0
-  TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#endif
-
   /* At this point pParent may have at most one overflow cell. And if
   ** this overflow cell is present, it must be the cell with 
   ** index iParentIdx. This scenario comes about when this function
@@ -69975,6 +70764,7 @@ static int balance_nonroot(
   if( !aOvflSpace ){
     return SQLITE_NOMEM_BKPT;
   }
+  assert( pParent->nFree>=0 );
 
   /* Find the sibling pages to balance. Also locate the cells in pParent 
   ** that divide the siblings. An attempt is made to find NN siblings on 
@@ -70014,7 +70804,13 @@ static int balance_nonroot(
       memset(apOld, 0, (i+1)*sizeof(MemPage*));
       goto balance_cleanup;
     }
-    nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
+    if( apOld[i]->nFree<0 ){
+      rc = btreeComputeFreeSpace(apOld[i]);
+      if( rc ){
+        memset(apOld, 0, (i)*sizeof(MemPage*));
+        goto balance_cleanup;
+      }
+    }
     if( (i--)==0 ) break;
 
     if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
@@ -70058,6 +70854,7 @@ static int balance_nonroot(
 
   /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
   ** alignment */
+  nMaxCells = nOld*(MX_CELL(pBt) + ArraySize(pParent->apOvfl));
   nMaxCells = (nMaxCells + 3)&~3;
 
   /*
@@ -70068,7 +70865,7 @@ static int balance_nonroot(
      + nMaxCells*sizeof(u16)                       /* b.szCell */
      + pBt->pageSize;                              /* aSpace1 */
 
-  assert( szScratch<=6*(int)pBt->pageSize );
+  assert( szScratch<=7*(int)pBt->pageSize );
   b.apCell = sqlite3StackAllocRaw(0, szScratch );
   if( b.apCell==0 ){
     rc = SQLITE_NOMEM_BKPT;
@@ -70104,6 +70901,7 @@ static int balance_nonroot(
     u16 maskPage = pOld->maskPage;
     u8 *piCell = aData + pOld->cellOffset;
     u8 *piEnd;
+    VVA_ONLY( int nCellAtStart = b.nCell; )
 
     /* Verify that all sibling pages are of the same "type" (table-leaf,
     ** table-interior, index-leaf, or index-interior).
@@ -70132,6 +70930,10 @@ static int balance_nonroot(
     */
     memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
     if( pOld->nOverflow>0 ){
+      if( limit<pOld->aiOvfl[0] ){
+        rc = SQLITE_CORRUPT_BKPT;
+        goto balance_cleanup;
+      }
       limit = pOld->aiOvfl[0];
       for(j=0; j<limit; j++){
         b.apCell[b.nCell] = aData + (maskPage & get2byteAligned(piCell));
@@ -70151,6 +70953,7 @@ static int balance_nonroot(
       piCell += 2;
       b.nCell++;
     }
+    assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) );
 
     cntOld[i] = b.nCell;
     if( i<nOld-1 && !leafData){
@@ -70204,8 +71007,19 @@ static int balance_nonroot(
   ** 
   */
   usableSpace = pBt->usableSize - 12 + leafCorrection;
-  for(i=0; i<nOld; i++){
+  for(i=k=0; i<nOld; i++, k++){
     MemPage *p = apOld[i];
+    b.apEnd[k] = p->aDataEnd;
+    b.ixNx[k] = cntOld[i];
+    if( k && b.ixNx[k]==b.ixNx[k-1] ){
+      k--;  /* Omit b.ixNx[] entry for child pages with no cells */
+    }
+    if( !leafData ){
+      k++;
+      b.apEnd[k] = pParent->aDataEnd;
+      b.ixNx[k] = cntOld[i]+1;
+    }
+    assert( p->nFree>=0 );
     szNew[i] = usableSpace - p->nFree;
     for(j=0; j<p->nOverflow; j++){
       szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
@@ -70429,19 +71243,20 @@ static int balance_nonroot(
   ** populated, not here.
   */
   if( ISAUTOVACUUM ){
-    MemPage *pNew = apNew[0];
-    u8 *aOld = pNew->aData;
+    MemPage *pOld;
+    MemPage *pNew = pOld = apNew[0];
     int cntOldNext = pNew->nCell + pNew->nOverflow;
-    int usableSize = pBt->usableSize;
     int iNew = 0;
     int iOld = 0;
 
     for(i=0; i<b.nCell; i++){
       u8 *pCell = b.apCell[i];
-      if( i==cntOldNext ){
-        MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
+      while( i==cntOldNext ){
+        iOld++;
+        assert( iOld<nNew || iOld<nOld );
+        assert( iOld>=0 && iOld<NB );
+        pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
         cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
-        aOld = pOld->aData;
       }
       if( i==cntNew[iNew] ){
         pNew = apNew[++iNew];
@@ -70456,13 +71271,13 @@ static int balance_nonroot(
       ** overflow cell), we can skip updating the pointer map entries.  */
       if( iOld>=nNew
        || pNew->pgno!=aPgno[iOld]
-       || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
+       || !SQLITE_WITHIN(pCell,pOld->aData,pOld->aDataEnd)
       ){
         if( !leafCorrection ){
           ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
         }
         if( cachedCellSize(&b,i)>pNew->minLocal ){
-          ptrmapPutOvflPtr(pNew, pCell, &rc);
+          ptrmapPutOvflPtr(pNew, pOld, pCell, &rc);
         }
         if( rc ) goto balance_cleanup;
       }
@@ -70607,7 +71422,8 @@ static int balance_nonroot(
     rc = defragmentPage(apNew[0], -1);
     testcase( rc!=SQLITE_OK );
     assert( apNew[0]->nFree == 
-        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+        (get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset
+          - apNew[0]->nCell*2)
       || rc!=SQLITE_OK
     );
     copyNodeContent(apNew[0], pParent, &rc);
@@ -70706,7 +71522,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
   }
   assert( sqlite3PagerIswriteable(pChild->pDbPage) );
   assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
-  assert( pChild->nCell==pRoot->nCell );
+  assert( pChild->nCell==pRoot->nCell || CORRUPT_DB );
 
   TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
 
@@ -70748,6 +71564,7 @@ static int balance(BtCursor *pCur){
     int iPage = pCur->iPage;
     MemPage *pPage = pCur->pPage;
 
+    if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
     if( iPage==0 ){
       if( pPage->nOverflow ){
         /* The root page of the b-tree is overfull. In this case call the
@@ -70776,6 +71593,9 @@ static int balance(BtCursor *pCur){
       int const iIdx = pCur->aiIdx[iPage-1];
 
       rc = sqlite3PagerWrite(pParent->pDbPage);
+      if( rc==SQLITE_OK && pParent->nFree<0 ){
+        rc = btreeComputeFreeSpace(pParent);
+      }
       if( rc==SQLITE_OK ){
 #ifndef SQLITE_OMIT_QUICKBALANCE
         if( pPage->intKeyLeaf
@@ -70886,7 +71706,11 @@ static int btreeOverwriteContent(
     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);
+      /* In a corrupt database, it is possible for the source and destination
+      ** buffers to overlap.  This is harmless since the database is already
+      ** corrupt but it does cause valgrind and ASAN warnings.  So use
+      ** memmove(). */
+      memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt);
     }
   }
   return SQLITE_OK;
@@ -71118,6 +71942,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
   pPage = pCur->pPage;
   assert( pPage->intKey || pX->nKey>=0 );
   assert( pPage->leaf || !pPage->intKey );
+  if( pPage->nFree<0 ){
+    rc = btreeComputeFreeSpace(pPage);
+    if( rc ) return rc;
+  }
 
   TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
           pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
@@ -71260,14 +72088,18 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
   assert( pCur->curFlags & BTCF_WriteFlag );
   assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
   assert( !hasReadConflicts(p, pCur->pgnoRoot) );
-  assert( pCur->ix<pCur->pPage->nCell );
-  assert( pCur->eState==CURSOR_VALID );
   assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
+  if( pCur->eState==CURSOR_REQUIRESEEK ){
+    rc = btreeRestoreCursorPosition(pCur);
+    if( rc ) return rc;
+  }
+  assert( pCur->eState==CURSOR_VALID );
 
   iCellDepth = pCur->iPage;
   iCellIdx = pCur->ix;
   pPage = pCur->pPage;
   pCell = findCell(pPage, iCellIdx);
+  if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT;
 
   /* If the bPreserve flag is set to true, then the cursor position must
   ** be preserved following this delete operation. If the current delete
@@ -71281,6 +72113,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
   if( bPreserve ){
     if( !pPage->leaf 
      || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+     || pPage->nCell==1  /* See dbfuzz001.test for a test case */
     ){
       /* A b-tree rebalance will be required after deleting this entry.
       ** Save the cursor key.  */
@@ -71337,6 +72170,10 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
     Pgno n;
     unsigned char *pTmp;
 
+    if( pLeaf->nFree<0 ){
+      rc = btreeComputeFreeSpace(pLeaf);
+      if( rc ) return rc;
+    }
     if( iCellDepth<pCur->iPage-1 ){
       n = pCur->apPage[iCellDepth+1]->pgno;
     }else{
@@ -71695,6 +72532,9 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
   assert( sqlite3BtreeHoldsMutex(p) );
   assert( p->inTrans==TRANS_WRITE );
   assert( iTable>=2 );
+  if( iTable>btreePagecount(pBt) ){
+    return SQLITE_CORRUPT_BKPT;
+  }
 
   rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
   if( rc ) return rc;
@@ -72043,10 +72883,10 @@ static void checkList(
   IntegrityCk *pCheck,  /* Integrity checking context */
   int isFreeList,       /* True for a freelist.  False for overflow page list */
   int iPage,            /* Page number for first page in the list */
-  int N                 /* Expected number of pages in the list */
+  u32 N                 /* Expected number of pages in the list */
 ){
   int i;
-  int expected = N;
+  u32 expected = N;
   int nErrAtStart = pCheck->nErr;
   while( iPage!=0 && pCheck->mxErr ){
     DbPage *pOvflPage;
@@ -72059,18 +72899,18 @@ static void checkList(
     }
     pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
     if( isFreeList ){
-      int n = get4byte(&pOvflData[4]);
+      u32 n = (u32)get4byte(&pOvflData[4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pCheck->pBt->autoVacuum ){
         checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
       }
 #endif
-      if( n>(int)pCheck->pBt->usableSize/4-2 ){
+      if( n>pCheck->pBt->usableSize/4-2 ){
         checkAppendMsg(pCheck,
            "freelist leaf count too big on page %d", iPage);
         N--;
       }else{
-        for(i=0; i<n; i++){
+        for(i=0; i<(int)n; i++){
           Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
           if( pCheck->pBt->autoVacuum ){
@@ -72228,6 +73068,11 @@ static int checkTreePage(
                    "btreeInitPage() returns error code %d", rc);
     goto end_of_check;
   }
+  if( (rc = btreeComputeFreeSpace(pPage))!=0 ){
+    assert( rc==SQLITE_CORRUPT );
+    checkAppendMsg(pCheck, "free space corruption", rc);
+    goto end_of_check;
+  }
   data = pPage->aData;
   hdr = pPage->hdrOffset;
 
@@ -72300,7 +73145,7 @@ static int checkTreePage(
 
     /* Check the content overflow list */
     if( info.nPayload>info.nLocal ){
-      int nPage;       /* Number of pages on the overflow chain */
+      u32 nPage;       /* Number of pages on the overflow chain */
       Pgno pgnoOvfl;   /* First page of the overflow chain */
       assert( pc + info.nSize - 4 <= usableSize );
       nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
@@ -72360,9 +73205,9 @@ static int checkTreePage(
     i = get2byte(&data[hdr+1]);
     while( i>0 ){
       int size, j;
-      assert( (u32)i<=usableSize-4 );     /* Enforced by btreeInitPage() */
+      assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */
       size = get2byte(&data[i+2]);
-      assert( (u32)(i+size)<=usableSize );  /* Enforced by btreeInitPage() */
+      assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */
       btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
       /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
       ** big-endian integer which is the offset in the b-tree page of the next
@@ -72371,8 +73216,8 @@ static int checkTreePage(
       j = get2byte(&data[i]);
       /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
       ** increasing offset. */
-      assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
-      assert( (u32)j<=usableSize-4 );   /* Enforced by btreeInitPage() */
+      assert( j==0 || j>i+size );     /* Enforced by btreeComputeFreeSpace() */
+      assert( (u32)j<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */
       i = j;
     }
     /* Analyze the min-heap looking for overlap between cells and/or 
@@ -72447,7 +73292,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   Pgno i;
   IntegrityCk sCheck;
   BtShared *pBt = p->pBt;
-  int savedDbFlags = pBt->db->flags;
+  u64 savedDbFlags = pBt->db->flags;
   char zErr[100];
   VVA_ONLY( int nRef );
 
@@ -72514,7 +73359,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   }
 #endif
   testcase( pBt->db->flags & SQLITE_CellSizeCk );
-  pBt->db->flags &= ~SQLITE_CellSizeCk;
+  pBt->db->flags &= ~(u64)SQLITE_CellSizeCk;
   for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
     i64 notUsed;
     if( aRoot[i]==0 ) continue;
@@ -73130,7 +73975,7 @@ static int backupOnePage(
   if( nSrcReserve!=nDestReserve ){
     u32 newPgsz = nSrcPgsz;
     rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
-    if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
+    if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
   }
 #endif
 
@@ -73677,6 +74522,11 @@ copy_finished:
 /* #include "sqliteInt.h" */
 /* #include "vdbeInt.h" */
 
+/* True if X is a power of two.  0 is considered a power of two here.
+** In other words, return true if X has at most one bit set.
+*/
+#define ISPOWEROF2(X)  (((X)&((X)-1))==0)
+
 #ifdef SQLITE_DEBUG
 /*
 ** Check invariants on a Mem object.
@@ -73696,8 +74546,8 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
   ** That saves a few cycles in inner loops. */
   assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
 
-  /* Cannot be both MEM_Int and MEM_Real at the same time */
-  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+  /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
+  assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
 
   if( p->flags & MEM_Null ){
     /* Cannot be both MEM_Null and some other type */
@@ -73716,7 +74566,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
               ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
 
       /* No other bits set */
-      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
+      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
                            |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
     }else{
       /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
@@ -73751,9 +74601,31 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
 }
 #endif
 
+/*
+** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
+** into a buffer.
+*/
+static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
+  StrAccum acc;
+  assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
+  sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
+  if( p->flags & MEM_Int ){
+    sqlite3_str_appendf(&acc, "%lld", p->u.i);
+  }else if( p->flags & MEM_IntReal ){
+    sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
+  }else{
+    sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
+  }
+  assert( acc.zText==zBuf && acc.mxAlloc<=0 );
+  zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
+}
+
 #ifdef SQLITE_DEBUG
 /*
-** Check that string value of pMem agrees with its integer or real value.
+** Validity checks on pMem.  pMem holds a string.
+**
+** (1) Check that string value of pMem agrees with its integer or real value.
+** (2) Check that the string is correctly zero terminated
 **
 ** 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.
@@ -73771,17 +74643,24 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
 **
 ** This routine is for use inside of assert() statements only.
 */
-SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
+SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(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);
+  if( p->flags & MEM_Term ){
+    /* Insure that the string is properly zero-terminated.  Pay particular
+    ** attention to the case where p->n is odd */
+    if( p->szMalloc>0 && p->z==p->zMalloc ){
+      assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
+      assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
+    }
+    assert( p->z[p->n]==0 );
+    assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
+    assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
   }
+  if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
+  vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
   z = p->z;
   i = j = 0;
   incr = 1;
@@ -73837,8 +74716,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
 }
 
 /*
-** Make sure pMem->z points to a writable allocation of at least 
-** min(n,32) bytes.
+** Make sure pMem->z points to a writable allocation of at least n bytes.
 **
 ** If the bPreserve argument is true, then copy of the content of
 ** pMem->z into the new allocation.  pMem must be either a string or
@@ -73857,7 +74735,6 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
 
   assert( pMem->szMalloc==0
        || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
-  if( n<32 ) n = 32;
   if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
     pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
     bPreserve = 0;
@@ -73895,34 +74772,40 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
 **
 ** Any prior string or blob content in the pMem object may be discarded.
 ** The pMem->xDel destructor is called, if it exists.  Though MEM_Str
-** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
-** values are preserved.
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
+** and MEM_Null values are preserved.
 **
 ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
 ** if unable to complete the resizing.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
-  assert( szNew>0 );
+  assert( CORRUPT_DB || szNew>0 );
   assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
   if( pMem->szMalloc<szNew ){
     return sqlite3VdbeMemGrow(pMem, szNew, 0);
   }
   assert( (pMem->flags & MEM_Dyn)==0 );
   pMem->z = pMem->zMalloc;
-  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
+  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
   return SQLITE_OK;
 }
 
 /*
 ** It is already known that pMem contains an unterminated string.
 ** Add the zero terminator.
+**
+** Three bytes of zero are added.  In this way, there is guaranteed
+** to be a double-zero byte at an even byte boundary in order to
+** terminate a UTF16 string, even if the initial size of the buffer
+** is an odd number of bytes.
 */
 static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
-  if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+  if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
     return SQLITE_NOMEM_BKPT;
   }
   pMem->z[pMem->n] = 0;
   pMem->z[pMem->n+1] = 0;
+  pMem->z[pMem->n+2] = 0;
   pMem->flags |= MEM_Term;
   return SQLITE_OK;
 }
@@ -73959,13 +74842,15 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
 SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
   int nByte;
   assert( pMem->flags & MEM_Zero );
-  assert( pMem->flags&MEM_Blob );
+  assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
+  testcase( sqlite3_value_nochange(pMem) );
   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. */
   nByte = pMem->n + pMem->u.nZero;
   if( nByte<=0 ){
+    if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
     nByte = 1;
   }
   if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
@@ -73994,12 +74879,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
 }
 
 /*
-** Add MEM_Str to the set of representations for the given Mem.  Numbers
-** are converted using sqlite3_snprintf().  Converting a BLOB to a string
-** is a no-op.
+** Add MEM_Str to the set of representations for the given Mem.  This
+** routine is only called if pMem is a number of some kind, not a NULL
+** or a BLOB.
 **
-** Existing representations MEM_Int and MEM_Real are invalidated if
-** bForce is true but are retained if bForce is false.
+** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
+** if bForce is true but are retained if bForce is false.
 **
 ** A MEM_Null value will never be passed to this function. This function is
 ** used for converting values to text for returning to the user (i.e. via
@@ -74008,13 +74893,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
 ** user and the latter is an internal programming error.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
-  int fg = pMem->flags;
   const int nByte = 32;
 
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-  assert( !(fg&MEM_Zero) );
-  assert( !(fg&(MEM_Str|MEM_Blob)) );
-  assert( fg&(MEM_Int|MEM_Real) );
+  assert( !(pMem->flags&MEM_Zero) );
+  assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
+  assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
   assert( !sqlite3VdbeMemIsRowSet(pMem) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
@@ -74024,22 +74908,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
     return SQLITE_NOMEM_BKPT;
   }
 
-  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
-  ** string representation of the value. Then, if the required encoding
-  ** is UTF-16le or UTF-16be do a translation.
-  ** 
-  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
-  */
-  if( fg & MEM_Int ){
-    sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
-  }else{
-    assert( fg & MEM_Real );
-    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
-  }
-  pMem->n = sqlite3Strlen30(pMem->z);
+  vdbeMemRenderNum(nByte, pMem->z, pMem);
+  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);
+  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
   sqlite3VdbeChangeEncoding(pMem, enc);
   return SQLITE_OK;
 }
@@ -74213,7 +75087,8 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   flags = pMem->flags;
-  if( flags & MEM_Int ){
+  if( flags & (MEM_Int|MEM_IntReal) ){
+    testcase( flags & MEM_IntReal );
     return pMem->u.i;
   }else if( flags & MEM_Real ){
     return doubleToInt64(pMem->u.r);
@@ -74242,7 +75117,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   if( pMem->flags & MEM_Real ){
     return pMem->u.r;
-  }else if( pMem->flags & MEM_Int ){
+  }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+    testcase( pMem->flags & MEM_IntReal );
     return (double)pMem->u.i;
   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
     return memRealValue(pMem);
@@ -74257,7 +75133,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
 ** 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;
+  testcase( pMem->flags & MEM_IntReal );
+  if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
   if( pMem->flags & MEM_Null ) return ifNull;
   return sqlite3VdbeRealValue(pMem)!=0.0;
 }
@@ -74320,17 +75197,21 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
 /* 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.
 **
+** This function assumes that i was obtained by assignment from r1.
+**
 ** 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){
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
   double r2 = (double)i;
-  return memcmp(&r1, &r2, sizeof(r1))==0;
+  return r1==0.0
+      || (memcmp(&r1, &r2, sizeof(r1))==0
+          && i >= -2251799813685248LL && i < 2251799813685248LL);
 }
 
 /*
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
+** Convert pMem so that it has type MEM_Real or MEM_Int.
 ** Invalidate any prior representations.
 **
 ** Every effort is made to force the conversion, even if the input
@@ -74338,25 +75219,26 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
 ** as much of the string as we can and ignore the rest.
 */
 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
-  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
+  testcase( pMem->flags & MEM_Int );
+  testcase( pMem->flags & MEM_Real );
+  testcase( pMem->flags & MEM_IntReal );
+  testcase( pMem->flags & MEM_Null );
+  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
     int rc;
+    sqlite3_int64 ix;
     assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-    rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
-    if( rc==0 ){
+    rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+    if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
+     || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
+    ){
+      pMem->u.i = ix;
       MemSetTypeFlag(pMem, MEM_Int);
     }else{
-      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);
-      }
+      MemSetTypeFlag(pMem, MEM_Real);
     }
   }
-  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
+  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
   pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
   return SQLITE_OK;
 }
@@ -74399,7 +75281,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
       pMem->flags |= (pMem->flags&MEM_Blob)>>3;
       sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
       assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
-      pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+      pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
       break;
     }
   }
@@ -74583,7 +75465,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
       ** 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_Int|MEM_IntReal))==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 );
@@ -74705,7 +75587,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
     assert( enc!=0 );
     if( enc==SQLITE_UTF8 ){
       nByte = 0x7fffffff & (int)strlen(z);
-      if( nByte>iLimit ) nByte = iLimit+1;
     }else{
       for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
     }
@@ -74717,29 +75598,30 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
   ** management (one of MEM_Dyn or MEM_Static).
   */
   if( xDel==SQLITE_TRANSIENT ){
-    int nAlloc = nByte;
+    u32 nAlloc = nByte;
     if( flags&MEM_Term ){
       nAlloc += (enc==SQLITE_UTF8?1:2);
     }
     if( nByte>iLimit ){
-      return SQLITE_TOOBIG;
+      return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
     }
     testcase( nAlloc==0 );
     testcase( nAlloc==31 );
     testcase( nAlloc==32 );
-    if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
+    if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
       return SQLITE_NOMEM_BKPT;
     }
     memcpy(pMem->z, z, nAlloc);
-  }else if( xDel==SQLITE_DYNAMIC ){
-    sqlite3VdbeMemRelease(pMem);
-    pMem->zMalloc = pMem->z = (char *)z;
-    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
   }else{
     sqlite3VdbeMemRelease(pMem);
     pMem->z = (char *)z;
-    pMem->xDel = xDel;
-    flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+    if( xDel==SQLITE_DYNAMIC ){
+      pMem->zMalloc = pMem->z;
+      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+    }else{
+      pMem->xDel = xDel;
+      flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+    }
   }
 
   pMem->n = nByte;
@@ -74782,6 +75664,9 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
 ){
   int rc;
   pMem->flags = MEM_Null;
+  if( sqlite3BtreeMaxRecordSize(pCur)<offset+amt ){
+    return SQLITE_CORRUPT_BKPT;
+  }
   if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
     rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
     if( rc==SQLITE_OK ){
@@ -74855,7 +75740,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
   assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
               || pVal->db->mallocFailed );
   if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
-    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+    assert( sqlite3VdbeMemValidStrRep(pVal) );
     return pVal->z;
   }else{
     return 0;
@@ -74878,7 +75763,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
   assert( !sqlite3VdbeMemIsRowSet(pVal) );
   if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
-    assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+    assert( sqlite3VdbeMemValidStrRep(pVal) );
     return pVal->z;
   }
   if( pVal->flags&MEM_Null ){
@@ -75143,7 +76028,12 @@ static int valueFromExpr(
     }else{
       sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
     }
-    if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
+    assert( (pVal->flags & MEM_IntReal)==0 );
+    if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
+      testcase( pVal->flags & MEM_Int );
+      testcase( pVal->flags & MEM_Real );
+      pVal->flags &= ~MEM_Str;
+    }
     if( enc!=SQLITE_UTF8 ){
       rc = sqlite3VdbeChangeEncoding(pVal, enc);
     }
@@ -75166,7 +76056,7 @@ static int valueFromExpr(
   }else if( op==TK_NULL ){
     pVal = valueNew(db, pCtx);
     if( pVal==0 ) goto no_mem;
-    sqlite3VdbeMemNumerify(pVal);
+    sqlite3VdbeMemSetNull(pVal);
   }
 #ifndef SQLITE_OMIT_BLOB_LITERAL
   else if( op==TK_BLOB ){
@@ -75188,9 +76078,11 @@ static int valueFromExpr(
   }
 #endif
   else if( op==TK_TRUEFALSE ){
-     pVal = valueNew(db, pCtx);
-     pVal->flags = MEM_Int;
-     pVal->u.i = pExpr->u.zToken[4]==0;
+    pVal = valueNew(db, pCtx);
+    if( pVal ){
+      pVal->flags = MEM_Int;
+      pVal->u.i = pExpr->u.zToken[4]==0;
+    }
   }
 
   *ppVal = pVal;
@@ -75583,7 +76475,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
   pParse->pVdbe = p;
   assert( pParse->aLabel==0 );
   assert( pParse->nLabel==0 );
-  assert( pParse->nOpAlloc==0 );
+  assert( p->nOpAlloc==0 );
   assert( pParse->szOpAlloc==0 );
   sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
   return p;
@@ -75613,6 +76505,43 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag
   p->zSql = sqlite3DbStrNDup(p->db, z, n);
 }
 
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Add a new element to the Vdbe->pDblStr list.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){
+  if( p ){
+    int n = sqlite3Strlen30(z);
+    DblquoteStr *pStr = sqlite3DbMallocRawNN(db,
+                            sizeof(*pStr)+n+1-sizeof(pStr->z));
+    if( pStr ){
+      pStr->pNextStr = p->pDblStr;
+      p->pDblStr = pStr;
+      memcpy(pStr->z, z, n+1);
+    }
+  }
+}
+#endif
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** zId of length nId is a double-quoted identifier.  Check to see if
+** that identifier is really used as a string literal.
+*/
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(
+  Vdbe *pVdbe,            /* The prepared statement */
+  const char *zId         /* The double-quoted identifier, already dequoted */
+){
+  DblquoteStr *pStr;
+  assert( zId!=0 );
+  if( pVdbe->pDblStr==0 ) return 0;
+  for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){
+    if( strcmp(zId, pStr->z)==0 ) return 1;
+  }
+  return 0;
+}
+#endif
+
 /*
 ** Swap all content between two VDBE structures.
 */
@@ -75632,6 +76561,11 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
   zTmp = pA->zSql;
   pA->zSql = pB->zSql;
   pB->zSql = zTmp;
+#if 0
+  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));
@@ -75644,7 +76578,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
 ** to 1024/sizeof(Op).
 **
 ** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain 
+** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain 
 ** unchanged (this is so that any opcodes already allocated can be 
 ** correctly deallocated along with the rest of the Vdbe).
 */
@@ -75660,9 +76594,11 @@ static int growOpArray(Vdbe *v, int nOp){
   ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
   ** size of the op array or add 1KB of space, whichever is smaller. */
 #ifdef SQLITE_TEST_REALLOC_STRESS
-  int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
+  sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc
+                        : (sqlite3_int64)v->nOpAlloc+nOp);
 #else
-  int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
+  sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc
+                        : (sqlite3_int64)(1024/sizeof(Op)));
   UNUSED_PARAMETER(nOp);
 #endif
 
@@ -75673,11 +76609,11 @@ static int growOpArray(Vdbe *v, int nOp){
   }
 
   assert( nOp<=(1024/sizeof(Op)) );
-  assert( nNew>=(p->nOpAlloc+nOp) );
+  assert( nNew>=(v->nOpAlloc+nOp) );
   pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
   if( pNew ){
     p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
-    p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+    v->nOpAlloc = p->szOpAlloc/sizeof(Op);
     v->aOp = pNew;
   }
   return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
@@ -75711,9 +76647,9 @@ static void test_addop_breakpoint(void){
 ** operand.
 */
 static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
-  assert( p->pParse->nOpAlloc<=p->nOp );
+  assert( p->nOpAlloc<=p->nOp );
   if( growOpArray(p, 1) ) return 1;
-  assert( p->pParse->nOpAlloc>p->nOp );
+  assert( p->nOpAlloc>p->nOp );
   return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
 }
 SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
@@ -75723,7 +76659,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
   i = p->nOp;
   assert( p->magic==VDBE_MAGIC_INIT );
   assert( op>=0 && op<0xff );
-  if( p->pParse->nOpAlloc<=i ){
+  if( p->nOpAlloc<=i ){
     return growOp3(p, op, p1, p2, p3);
   }
   p->nOp++;
@@ -75855,13 +76791,29 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
 }
 
 /*
-** Add a new OP_Explain opcode.
+** Set a debugger breakpoint on the following routine in order to
+** monitor the EXPLAIN QUERY PLAN code generation.
+*/
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
+  (void)z1;
+  (void)z2;
+}
+#endif
+
+/*
+** Add a new OP_ 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 ){
+#ifndef SQLITE_DEBUG
+  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
+  ** But omit them (for performance) during production builds */
+  if( pParse->explain==2 )
+#endif
+  {
     char *zMsg;
     Vdbe *v;
     va_list ap;
@@ -75873,7 +76825,10 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
     iThis = v->nOp;
     sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
                       zMsg, P4_DYNAMIC);
-    if( bPush) pParse->addrExplain = iThis;
+    sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z);
+    if( bPush){
+      pParse->addrExplain = iThis;
+    }
   }
 }
 
@@ -75881,6 +76836,7 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
 ** Pop the EXPLAIN QUERY PLAN stack one level.
 */
 SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
+  sqlite3ExplainBreakpoint("POP", 0);
   pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
 }
 #endif /* SQLITE_OMIT_EXPLAIN */
@@ -75945,21 +76901,22 @@ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
 ** The VDBE knows that a P2 value is a label because labels are
 ** always negative and P2 values are suppose to be non-negative.
 ** Hence, a negative P2 value is a label that has yet to be resolved.
+** (Later:) This is only true for opcodes that have the OPFLG_JUMP
+** property.
 **
-** Zero is returned if a malloc() fails.
+** Variable usage notes:
+**
+**     Parse.aLabel[x]     Stores the address that the x-th label resolves
+**                         into.  For testing (SQLITE_DEBUG), unresolved
+**                         labels stores -1, but that is not required.
+**     Parse.nLabelAlloc   Number of slots allocated to Parse.aLabel[]
+**     Parse.nLabel        The *negative* of the number of labels that have
+**                         been issued.  The negative is stored because
+**                         that gives a performance improvement over storing
+**                         the equivalent positive value.
 */
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
-  Parse *p = v->pParse;
-  int i = p->nLabel++;
-  assert( v->magic==VDBE_MAGIC_INIT );
-  if( (i & (i-1))==0 ){
-    p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, 
-                                       (i*2+1)*sizeof(p->aLabel[0]));
-  }
-  if( p->aLabel ){
-    p->aLabel[i] = -1;
-  }
-  return ADDR(i);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){
+  return --pParse->nLabel;
 }
 
 /*
@@ -75967,18 +76924,35 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
 ** be inserted.  The parameter "x" must have been obtained from
 ** a prior call to sqlite3VdbeMakeLabel().
 */
+static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
+  int nNewSize = 10 - p->nLabel;
+  p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
+                     nNewSize*sizeof(p->aLabel[0]));
+  if( p->aLabel==0 ){
+    p->nLabelAlloc = 0;
+  }else{
+#ifdef SQLITE_DEBUG
+    int i;
+    for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1;
+#endif
+    p->nLabelAlloc = nNewSize;
+    p->aLabel[j] = v->nOp;
+  }
+}
 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
   Parse *p = v->pParse;
   int j = ADDR(x);
   assert( v->magic==VDBE_MAGIC_INIT );
-  assert( j<p->nLabel );
+  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);
-    }
+  if( p->db->flags & SQLITE_VdbeAddopTrace ){
+    printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
+  }
 #endif
+  if( p->nLabelAlloc + p->nLabel < 0 ){
+    resizeResolveLabel(p,v,j);
+  }else{
     assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
     p->aLabel[j] = v->nOp;
   }
@@ -76094,6 +77068,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   int hasAbort = 0;
   int hasFkCounter = 0;
   int hasCreateTable = 0;
+  int hasCreateIndex = 0;
   int hasInitCoroutine = 0;
   Op *pOp;
   VdbeOpIter sIter;
@@ -76103,13 +77078,23 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   while( (pOp = opIterNext(&sIter))!=0 ){
     int opcode = pOp->opcode;
     if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
+     || opcode==OP_VDestroy
+     || (opcode==OP_Function0 && pOp->p4.pFunc->funcFlags&SQLITE_FUNC_INTERNAL)
      || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
-      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
+      && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
     ){
       hasAbort = 1;
       break;
     }
     if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
+    if( mayAbort ){
+      /* hasCreateIndex may also be set for some DELETE statements that use
+      ** OP_Clear. So this routine may end up returning true in the case 
+      ** where a "DELETE FROM tbl" has a statement-journal but does not
+      ** require one. This is not so bad - it is an inefficiency, not a bug. */
+      if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
+      if( opcode==OP_Clear ) hasCreateIndex = 1;
+    }
     if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
 #ifndef SQLITE_OMIT_FOREIGN_KEY
     if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
@@ -76125,7 +77110,8 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   ** true for this case to prevent the assert() in the callers frame
   ** from failing.  */
   return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
-              || (hasCreateTable && hasInitCoroutine) );
+        || (hasCreateTable && hasInitCoroutine) || hasCreateIndex
+  );
 }
 #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
 
@@ -76253,7 +77239,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
             ** 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 );
+            assert( ADDR(pOp->p2)<-pParse->nLabel );
             pOp->p2 = aLabel[ADDR(pOp->p2)];
           }
           break;
@@ -76292,7 +77278,7 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
 */
 #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
 SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
-  assert( p->nOp + N <= p->pParse->nOpAlloc );
+  assert( p->nOp + N <= p->nOpAlloc );
 }
 #endif
 
@@ -76364,7 +77350,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
   VdbeOp *pOut, *pFirst;
   assert( nOp>0 );
   assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
+  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
     return 0;
   }
   pFirst = pOut = &p->aOp[p->nOp];
@@ -76410,7 +77396,7 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(
   LogEst nEst,                    /* Estimated number of output rows */
   const char *zName               /* Name of table or index being scanned */
 ){
-  int nByte = (p->nScan+1) * sizeof(ScanStatus);
+  sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
   ScanStatus *aNew;
   aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
   if( aNew ){
@@ -76997,7 +77983,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
       Mem *pMem = pOp->p4.pMem;
       if( pMem->flags & MEM_Str ){
         zP4 = pMem->z;
-      }else if( pMem->flags & MEM_Int ){
+      }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
         sqlite3_str_appendf(&x, "%lld", pMem->u.i);
       }else if( pMem->flags & MEM_Real ){
         sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
@@ -77531,9 +78517,9 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
 ** of a ReusableSpace object by the allocSpace() routine below.
 */
 struct ReusableSpace {
-  u8 *pSpace;          /* Available memory */
-  int nFree;           /* Bytes of available memory */
-  int nNeeded;         /* Total bytes that could not be allocated */
+  u8 *pSpace;            /* Available memory */
+  sqlite3_int64 nFree;   /* Bytes of available memory */
+  sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */
 };
 
 /* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
@@ -77553,7 +78539,7 @@ struct ReusableSpace {
 static void *allocSpace(
   struct ReusableSpace *p,  /* Bulk memory available for allocation */
   void *pBuf,               /* Pointer to a prior allocation */
-  int nByte                 /* Bytes of memory needed */
+  sqlite3_int64 nByte       /* Bytes of memory needed */
 ){
   assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
   if( pBuf==0 ){
@@ -77686,19 +78672,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
   ** the leftover memory at the end of the opcode array.  This can significantly
   ** reduce the amount of memory held by a prepared statement.
   */
-  do {
-    x.nNeeded = 0;
-    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
-    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
-    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
-    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+  x.nNeeded = 0;
+  p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem));
+  p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
+  p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
+  p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+  p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
 #endif
-    if( x.nNeeded==0 ) break;
+  if( x.nNeeded ){
     x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
     x.nFree = x.nNeeded;
-  }while( !db->mallocFailed );
+    if( !db->mallocFailed ){
+      p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
+      p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
+      p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
+      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+#endif
+    }
+  }
 
   p->pVList = pParse->pVList;
   pParse->pVList =  0;
@@ -78351,7 +79345,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
     }
 
     /* Check for immediate foreign key violations. */
-    if( p->rc==SQLITE_OK ){
+    if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
       sqlite3VdbeCheckFk(p, 0);
     }
   
@@ -78390,7 +79384,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
         }else{
           db->nDeferredCons = 0;
           db->nDeferredImmCons = 0;
-          db->flags &= ~SQLITE_DeferFKs;
+          db->flags &= ~(u64)SQLITE_DeferFKs;
           sqlite3CommitInternalChanges(db);
         }
       }else{
@@ -78703,6 +79697,16 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
   vdbeFreeOpArray(db, p->aOp, p->nOp);
   sqlite3DbFree(db, p->aColName);
   sqlite3DbFree(db, p->zSql);
+#ifdef SQLITE_ENABLE_NORMALIZE
+  sqlite3DbFree(db, p->zNormSql);
+  {
+    DblquoteStr *pThis, *pNext;
+    for(pThis=p->pDblStr; pThis; pThis=pNext){
+      pNext = pThis->pNextStr;
+      sqlite3DbFree(db, pThis);
+    }
+  }
+#endif
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   {
     int i;
@@ -78867,6 +79871,8 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
 
 /*
 ** Return the serial-type for the value stored in pMem.
+**
+** This routine might convert a large MEM_IntReal value into MEM_Real.
 */
 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
   int flags = pMem->flags;
@@ -78877,11 +79883,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
     *pLen = 0;
     return 0;
   }
-  if( flags&MEM_Int ){
+  if( flags&(MEM_Int|MEM_IntReal) ){
     /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
 #   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
     i64 i = pMem->u.i;
     u64 u;
+    testcase( flags & MEM_Int );
+    testcase( flags & MEM_IntReal );
     if( i<0 ){
       u = ~i;
     }else{
@@ -78901,6 +79909,15 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
     if( u<=2147483647 ){ *pLen = 4; return 4; }
     if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
     *pLen = 8;
+    if( flags&MEM_IntReal ){
+      /* If the value is IntReal and is going to take up 8 bytes to store
+      ** as an integer, then we might as well make it an 8-byte floating
+      ** point value */
+      pMem->u.r = (double)pMem->u.i;
+      pMem->flags &= ~MEM_IntReal;
+      pMem->flags |= MEM_Real;
+      return 7;
+    }
     return 6;
   }
   if( flags&MEM_Real ){
@@ -79074,7 +80091,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
 ** routine so that in most cases the overhead of moving the stack pointer
 ** is avoided.
 */ 
-static u32 SQLITE_NOINLINE serialGet(
+static u32 serialGet(
   const unsigned char *buf,     /* Buffer to deserialize from */
   u32 serial_type,              /* Serial type to deserialize */
   Mem *pMem                     /* Memory cell to write value into */
@@ -79106,7 +80123,7 @@ static u32 SQLITE_NOINLINE serialGet(
     assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
     swapMixedEndianFloat(x);
     memcpy(&pMem->u.r, &x, sizeof(x));
-    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
+    pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
   }
   return 8;
 }
@@ -79242,7 +80259,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
   UnpackedRecord *p      /* Populate this structure before returning. */
 ){
   const unsigned char *aKey = (const unsigned char *)pKey;
-  int d; 
+  u32 d; 
   u32 idx;                        /* Offset in aKey[] to read from */
   u16 u;                          /* Unsigned loop counter */
   u32 szHdr;
@@ -79253,7 +80270,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
   idx = getVarint32(aKey, szHdr);
   d = szHdr;
   u = 0;
-  while( idx<szHdr && d<=nKey ){
+  while( idx<szHdr && d<=(u32)nKey ){
     u32 serial_type;
 
     idx += getVarint32(&aKey[idx], serial_type);
@@ -79266,6 +80283,13 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
     pMem++;
     if( (++u)>=p->nField ) break;
   }
+  if( d>(u32)nKey && u ){
+    assert( CORRUPT_DB );
+    /* In a corrupt record entry, the last pMem might have been set up using 
+    ** uninitialized memory. Overwrite its value with NULL, to prevent
+    ** warnings from MSAN. */
+    sqlite3VdbeMemSetNull(pMem-1);
+  }
   assert( u<=pKeyInfo->nKeyField + 1 );
   p->nField = u;
 }
@@ -79331,8 +80355,8 @@ static int vdbeRecordCompareDebug(
     ** Use that approximation to avoid the more expensive call to
     ** sqlite3VdbeSerialTypeLen() in the common case.
     */
-    if( d1+serial_type1+2>(u32)nKey1
-     && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 
+    if( d1+(u64)serial_type1+2>(u64)nKey1
+     && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 
     ){
       break;
     }
@@ -79343,7 +80367,8 @@ static int vdbeRecordCompareDebug(
 
     /* Do the comparison
     */
-    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
+    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
+                           pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
     if( rc!=0 ){
       assert( mem1.szMalloc==0 );  /* See comment below */
       if( pKeyInfo->aSortOrder[i] ){
@@ -79548,8 +80573,13 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
 
   /* At least one of the two values is a number
   */
-  if( combined_flags&(MEM_Int|MEM_Real) ){
-    if( (f1 & f2 & MEM_Int)!=0 ){
+  if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
+    testcase( combined_flags & MEM_Int );
+    testcase( combined_flags & MEM_Real );
+    testcase( combined_flags & MEM_IntReal );
+    if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
+      testcase( f1 & f2 & MEM_Int );
+      testcase( f1 & f2 & MEM_IntReal );
       if( pMem1->u.i < pMem2->u.i ) return -1;
       if( pMem1->u.i > pMem2->u.i ) return +1;
       return 0;
@@ -79559,15 +80589,23 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
       if( pMem1->u.r > pMem2->u.r ) return +1;
       return 0;
     }
-    if( (f1&MEM_Int)!=0 ){
+    if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
+      testcase( f1 & MEM_Int );
+      testcase( f1 & MEM_IntReal );
       if( (f2&MEM_Real)!=0 ){
         return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
+      }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+        if( pMem1->u.i < pMem2->u.i ) return -1;
+        if( pMem1->u.i > pMem2->u.i ) return +1;
+        return 0;
       }else{
         return -1;
       }
     }
     if( (f1&MEM_Real)!=0 ){
-      if( (f2&MEM_Int)!=0 ){
+      if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+        testcase( f2 & MEM_Int );
+        testcase( f2 & MEM_IntReal );
         return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
       }else{
         return -1;
@@ -79699,12 +80737,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
   }else{
     idx1 = getVarint32(aKey1, szHdr1);
     d1 = szHdr1;
-    if( d1>(unsigned)nKey1 ){ 
-      pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
-      return 0;  /* Corruption */
-    }
     i = 0;
   }
+  if( d1>(unsigned)nKey1 ){ 
+    pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+    return 0;  /* Corruption */
+  }
 
   VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
   assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField 
@@ -79716,7 +80754,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
     u32 serial_type;
 
     /* RHS is an integer */
-    if( pRhs->flags & MEM_Int ){
+    if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
+      testcase( pRhs->flags & MEM_Int );
+      testcase( pRhs->flags & MEM_IntReal );
       serial_type = aKey1[idx1];
       testcase( serial_type==12 );
       if( serial_type>=10 ){
@@ -79774,10 +80814,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
         mem1.n = (serial_type - 12) / 2;
         testcase( (d1+mem1.n)==(unsigned)nKey1 );
         testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
-        if( (d1+mem1.n) > (unsigned)nKey1 ){
+        if( (d1+mem1.n) > (unsigned)nKey1
+         || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i
+        ){
           pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
           return 0;                /* Corruption */
-        }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
+        }else if( pKeyInfo->aColl[i] ){
           mem1.enc = pKeyInfo->enc;
           mem1.db = pKeyInfo->db;
           mem1.flags = MEM_Str;
@@ -80059,7 +81101,9 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
     testcase( flags & MEM_Real );
     testcase( flags & MEM_Null );
     testcase( flags & MEM_Blob );
-    if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
+    if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
+     && p->pKeyInfo->aColl[0]==0
+    ){
       assert( flags & MEM_Str );
       return vdbeRecordCompareString;
     }
@@ -80104,7 +81148,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
   (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;
   }
 
@@ -80475,14 +81521,16 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
   sqlite3_int64 iNow;
   sqlite3_int64 iElapse;
   assert( p->startTime>0 );
-  assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
+  assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 );
   assert( db->init.busy==0 );
   assert( p->zSql!=0 );
   sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
   iElapse = (iNow - p->startTime)*1000000;
+#ifndef SQLITE_OMIT_DEPRECATED
   if( db->xProfile ){
     db->xProfile(db->pProfileArg, p->zSql, iElapse);
   }
+#endif
   if( db->mTrace & SQLITE_TRACE_PROFILE ){
     db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
   }
@@ -80645,39 +81693,86 @@ SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
 */
 SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
   static const u8 aType[] = {
-     SQLITE_BLOB,     /* 0x00 */
-     SQLITE_NULL,     /* 0x01 */
-     SQLITE_TEXT,     /* 0x02 */
-     SQLITE_NULL,     /* 0x03 */
-     SQLITE_INTEGER,  /* 0x04 */
-     SQLITE_NULL,     /* 0x05 */
-     SQLITE_INTEGER,  /* 0x06 */
-     SQLITE_NULL,     /* 0x07 */
-     SQLITE_FLOAT,    /* 0x08 */
-     SQLITE_NULL,     /* 0x09 */
-     SQLITE_FLOAT,    /* 0x0a */
-     SQLITE_NULL,     /* 0x0b */
-     SQLITE_INTEGER,  /* 0x0c */
-     SQLITE_NULL,     /* 0x0d */
-     SQLITE_INTEGER,  /* 0x0e */
-     SQLITE_NULL,     /* 0x0f */
-     SQLITE_BLOB,     /* 0x10 */
-     SQLITE_NULL,     /* 0x11 */
-     SQLITE_TEXT,     /* 0x12 */
-     SQLITE_NULL,     /* 0x13 */
-     SQLITE_INTEGER,  /* 0x14 */
-     SQLITE_NULL,     /* 0x15 */
-     SQLITE_INTEGER,  /* 0x16 */
-     SQLITE_NULL,     /* 0x17 */
-     SQLITE_FLOAT,    /* 0x18 */
-     SQLITE_NULL,     /* 0x19 */
-     SQLITE_FLOAT,    /* 0x1a */
-     SQLITE_NULL,     /* 0x1b */
-     SQLITE_INTEGER,  /* 0x1c */
-     SQLITE_NULL,     /* 0x1d */
-     SQLITE_INTEGER,  /* 0x1e */
-     SQLITE_NULL,     /* 0x1f */
+     SQLITE_BLOB,     /* 0x00 (not possible) */
+     SQLITE_NULL,     /* 0x01 NULL */
+     SQLITE_TEXT,     /* 0x02 TEXT */
+     SQLITE_NULL,     /* 0x03 (not possible) */
+     SQLITE_INTEGER,  /* 0x04 INTEGER */
+     SQLITE_NULL,     /* 0x05 (not possible) */
+     SQLITE_INTEGER,  /* 0x06 INTEGER + TEXT */
+     SQLITE_NULL,     /* 0x07 (not possible) */
+     SQLITE_FLOAT,    /* 0x08 FLOAT */
+     SQLITE_NULL,     /* 0x09 (not possible) */
+     SQLITE_FLOAT,    /* 0x0a FLOAT + TEXT */
+     SQLITE_NULL,     /* 0x0b (not possible) */
+     SQLITE_INTEGER,  /* 0x0c (not possible) */
+     SQLITE_NULL,     /* 0x0d (not possible) */
+     SQLITE_INTEGER,  /* 0x0e (not possible) */
+     SQLITE_NULL,     /* 0x0f (not possible) */
+     SQLITE_BLOB,     /* 0x10 BLOB */
+     SQLITE_NULL,     /* 0x11 (not possible) */
+     SQLITE_TEXT,     /* 0x12 (not possible) */
+     SQLITE_NULL,     /* 0x13 (not possible) */
+     SQLITE_INTEGER,  /* 0x14 INTEGER + BLOB */
+     SQLITE_NULL,     /* 0x15 (not possible) */
+     SQLITE_INTEGER,  /* 0x16 (not possible) */
+     SQLITE_NULL,     /* 0x17 (not possible) */
+     SQLITE_FLOAT,    /* 0x18 FLOAT + BLOB */
+     SQLITE_NULL,     /* 0x19 (not possible) */
+     SQLITE_FLOAT,    /* 0x1a (not possible) */
+     SQLITE_NULL,     /* 0x1b (not possible) */
+     SQLITE_INTEGER,  /* 0x1c (not possible) */
+     SQLITE_NULL,     /* 0x1d (not possible) */
+     SQLITE_INTEGER,  /* 0x1e (not possible) */
+     SQLITE_NULL,     /* 0x1f (not possible) */
+     SQLITE_FLOAT,    /* 0x20 INTREAL */
+     SQLITE_NULL,     /* 0x21 (not possible) */
+     SQLITE_TEXT,     /* 0x22 INTREAL + TEXT */
+     SQLITE_NULL,     /* 0x23 (not possible) */
+     SQLITE_FLOAT,    /* 0x24 (not possible) */
+     SQLITE_NULL,     /* 0x25 (not possible) */
+     SQLITE_FLOAT,    /* 0x26 (not possible) */
+     SQLITE_NULL,     /* 0x27 (not possible) */
+     SQLITE_FLOAT,    /* 0x28 (not possible) */
+     SQLITE_NULL,     /* 0x29 (not possible) */
+     SQLITE_FLOAT,    /* 0x2a (not possible) */
+     SQLITE_NULL,     /* 0x2b (not possible) */
+     SQLITE_FLOAT,    /* 0x2c (not possible) */
+     SQLITE_NULL,     /* 0x2d (not possible) */
+     SQLITE_FLOAT,    /* 0x2e (not possible) */
+     SQLITE_NULL,     /* 0x2f (not possible) */
+     SQLITE_BLOB,     /* 0x30 (not possible) */
+     SQLITE_NULL,     /* 0x31 (not possible) */
+     SQLITE_TEXT,     /* 0x32 (not possible) */
+     SQLITE_NULL,     /* 0x33 (not possible) */
+     SQLITE_FLOAT,    /* 0x34 (not possible) */
+     SQLITE_NULL,     /* 0x35 (not possible) */
+     SQLITE_FLOAT,    /* 0x36 (not possible) */
+     SQLITE_NULL,     /* 0x37 (not possible) */
+     SQLITE_FLOAT,    /* 0x38 (not possible) */
+     SQLITE_NULL,     /* 0x39 (not possible) */
+     SQLITE_FLOAT,    /* 0x3a (not possible) */
+     SQLITE_NULL,     /* 0x3b (not possible) */
+     SQLITE_FLOAT,    /* 0x3c (not possible) */
+     SQLITE_NULL,     /* 0x3d (not possible) */
+     SQLITE_FLOAT,    /* 0x3e (not possible) */
+     SQLITE_NULL,     /* 0x3f (not possible) */
   };
+#ifdef SQLITE_DEBUG
+  {
+    int eType = SQLITE_BLOB;
+    if( pVal->flags & MEM_Null ){
+      eType = SQLITE_NULL;
+    }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
+      eType = SQLITE_FLOAT;
+    }else if( pVal->flags & MEM_Int ){
+      eType = SQLITE_INTEGER;
+    }else if( pVal->flags & MEM_Str ){
+      eType = SQLITE_TEXT;
+    }
+    assert( eType == aType[pVal->flags&MEM_AffMask] );
+  }
+#endif
   return aType[pVal->flags&MEM_AffMask];
 }
 
@@ -80686,6 +81781,11 @@ SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
   return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
 }
 
+/* Return true if a parameter value originated from an sqlite3_bind() */
+SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){
+  return (pVal->flags&MEM_FromBind)!=0;
+}
+
 /* Make a copy of an sqlite3_value object
 */
 SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
@@ -80922,6 +82022,21 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
   sqlite3OomFault(pCtx->pOut->db);
 }
 
+#ifndef SQLITE_UNTESTABLE
+/* Force the INT64 value currently stored as the result to be
+** a MEM_IntReal value.  See the SQLITE_TESTCTRL_RESULT_INTREAL
+** test-control.
+*/
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){ 
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  if( pCtx->pOut->flags & MEM_Int ){
+    pCtx->pOut->flags &= ~MEM_Int;
+    pCtx->pOut->flags |= MEM_IntReal;
+  }
+}
+#endif
+
+
 /*
 ** This function is called after a transaction has been committed. It 
 ** invokes callbacks registered with sqlite3_wal_hook() as required.
@@ -80996,7 +82111,7 @@ static int sqlite3Step(Vdbe *p){
     return SQLITE_NOMEM_BKPT;
   }
 
-  if( p->pc<=0 && p->expired ){
+  if( p->pc<0 && p->expired ){
     p->rc = SQLITE_SCHEMA;
     rc = SQLITE_ERROR;
     goto end_of_step;
@@ -81015,7 +82130,7 @@ static int sqlite3Step(Vdbe *p){
     );
 
 #ifndef SQLITE_OMIT_TRACE
-    if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
+    if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
         && !db->init.busy && p->zSql ){
       sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
     }else{
@@ -81042,16 +82157,18 @@ static int sqlite3Step(Vdbe *p){
     db->nVdbeExec--;
   }
 
+  if( rc!=SQLITE_ROW ){
 #ifndef SQLITE_OMIT_TRACE
-  /* If the statement completed successfully, invoke the profile callback */
-  if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
+    /* If the statement completed successfully, invoke the profile callback */
+    checkProfileCallback(db, p);
 #endif
 
-  if( rc==SQLITE_DONE && db->autoCommit ){
-    assert( p->rc==SQLITE_OK );
-    p->rc = doWalCallbacks(db);
-    if( p->rc!=SQLITE_OK ){
-      rc = SQLITE_ERROR;
+    if( rc==SQLITE_DONE && db->autoCommit ){
+      assert( p->rc==SQLITE_OK );
+      p->rc = doWalCallbacks(db);
+      if( p->rc!=SQLITE_OK ){
+        rc = SQLITE_ERROR;
+      }
     }
   }
 
@@ -81071,9 +82188,9 @@ end_of_step:
        || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
   );
   assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
-  if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 
-   && rc!=SQLITE_ROW 
-   && rc!=SQLITE_DONE 
+  if( rc!=SQLITE_ROW 
+   && rc!=SQLITE_DONE
+   && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
   ){
     /* If this statement was prepared using saved SQL and an 
     ** error has occurred, then return the error code in p->rc to the
@@ -81529,10 +82646,10 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
 ** or a constant) then useTypes 2, 3, and 4 return NULL.
 */
 static const void *columnName(
-  sqlite3_stmt *pStmt,
-  int N,
-  const void *(*xFunc)(Mem*),
-  int useType
+  sqlite3_stmt *pStmt,     /* The statement */
+  int N,                   /* Which column to get the name for */
+  int useUtf16,            /* True to return the name as UTF16 */
+  int useType              /* What type of name */
 ){
   const void *ret;
   Vdbe *p;
@@ -81553,8 +82670,15 @@ static const void *columnName(
     N += useType*n;
     sqlite3_mutex_enter(db->mutex);
     assert( db->mallocFailed==0 );
-    ret = xFunc(&p->aColName[N]);
-     /* A malloc may have failed inside of the xFunc() call. If this
+#ifndef SQLITE_OMIT_UTF16
+    if( useUtf16 ){
+      ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
+    }else
+#endif
+    {
+      ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]);
+    }
+    /* A malloc may have failed inside of the _text() call. If this
     ** is the case, clear the mallocFailed flag and return NULL.
     */
     if( db->mallocFailed ){
@@ -81571,13 +82695,11 @@ static const void *columnName(
 ** statement pStmt.
 */
 SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
+  return columnName(pStmt, N, 0, COLNAME_NAME);
 }
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
+  return columnName(pStmt, N, 1, COLNAME_NAME);
 }
 #endif
 
@@ -81596,13 +82718,11 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
 ** of the result set of SQL statement pStmt.
 */
 SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
+  return columnName(pStmt, N, 0, COLNAME_DECLTYPE);
 }
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
+  return columnName(pStmt, N, 1, COLNAME_DECLTYPE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 #endif /* SQLITE_OMIT_DECLTYPE */
@@ -81614,13 +82734,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
 ** anything else which is not an unambiguous reference to a database column.
 */
 SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
+  return columnName(pStmt, N, 0, COLNAME_DATABASE);
 }
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
+  return columnName(pStmt, N, 1, COLNAME_DATABASE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -81630,13 +82748,11 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N
 ** anything else which is not an unambiguous reference to a database column.
 */
 SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
+  return columnName(pStmt, N, 0, COLNAME_TABLE);
 }
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
+  return columnName(pStmt, N, 1, COLNAME_TABLE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 
@@ -81646,13 +82762,11 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
 ** anything else which is not an unambiguous reference to a database column.
 */
 SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
+  return columnName(pStmt, N, 0, COLNAME_COLUMN);
 }
 #ifndef SQLITE_OMIT_UTF16
 SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
-  return columnName(
-      pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
+  return columnName(pStmt, N, 1, COLNAME_COLUMN);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 #endif /* SQLITE_ENABLE_COLUMN_METADATA */
@@ -81695,7 +82809,7 @@ static int vdbeUnbind(Vdbe *p, int i){
   pVar = &p->aVar[i];
   sqlite3VdbeMemRelease(pVar);
   pVar->flags = MEM_Null;
-  sqlite3Error(p->db, SQLITE_OK);
+  p->db->errCode = SQLITE_OK;
 
   /* If the bit corresponding to this variable in Vdbe.expmask is set, then 
   ** binding a new value to this variable invalidates the current query plan.
@@ -82020,6 +83134,14 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
   return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
 }
 
+/*
+** Return 1 if the statement is an EXPLAIN and return 2 if the
+** statement is an EXPLAIN QUERY PLAN
+*/
+SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
+  return pStmt ? ((Vdbe*)pStmt)->explain : 0;
+}
+
 /*
 ** Return true if the prepared statement is in need of being reset.
 */
@@ -82115,6 +83237,22 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
 #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;
+  if( p==0 ) return 0;
+  if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){
+    sqlite3_mutex_enter(p->db->mutex);
+    p->zNormSql = sqlite3Normalize(p, p->zSql);
+    sqlite3_mutex_leave(p->db->mutex);
+  }
+  return p->zNormSql;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
 /*
 ** Allocate and populate an UnpackedRecord structure based on the serialized
@@ -82185,7 +83323,9 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
   }else if( iIdx>=p->pUnpacked->nField ){
     *ppValue = (sqlite3_value *)columnNullValue();
   }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
-    if( pMem->flags & MEM_Int ){
+    if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+      testcase( pMem->flags & MEM_Int );
+      testcase( pMem->flags & MEM_IntReal );
       sqlite3VdbeMemRealify(pMem);
     }
   }
@@ -82504,7 +83644,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
       pVar = &p->aVar[idx-1];
       if( pVar->flags & MEM_Null ){
         sqlite3_str_append(&out, "NULL", 4);
-      }else if( pVar->flags & MEM_Int ){
+      }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
         sqlite3_str_appendf(&out, "%lld", pVar->u.i);
       }else if( pVar->flags & MEM_Real ){
         sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
@@ -82693,12 +83833,20 @@ SQLITE_API int sqlite3_found_count = 0;
 ** feature is used for test suite validation only and does not appear an
 ** production builds.
 **
-** 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. 
+** M is the type of branch.  I is the direction taken for this instance of
+** the branch.
+**
+**   M: 2 - two-way branch (I=0: fall-thru   1: jump                )
+**      3 - two-way + NULL (I=0: fall-thru   1: jump      2: NULL   )
+**      4 - OP_Jump        (I=0: jump p1     1: jump p2   2: jump p3)
+**
+** In other words, if M is 2, then I is either 0 (for fall-through) or
+** 1 (for when the branch is taken).  If M is 3, the I is 0 for an
+** ordinary fall-through, I is 1 if the branch was taken, and I is 2 
+** if the result of comparison is NULL.  For M=3, I=2 the jump may or
+** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5.
+** When M is 4, that means that an OP_Jump is being run.  I is 0, 1, or 2
+** depending on if the operands are less than, equal, or greater than.
 **
 ** iSrcLine is the source code line (from the __LINE__ macro) that
 ** generated the VDBE instruction combined with flag bits.  The source
@@ -82709,9 +83857,9 @@ SQLITE_API int sqlite3_found_count = 0;
 ** 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
+** Bit 0x08 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.
+** should be treated as equivalent
 **
 ** Since only a line number is retained, not the filename, this macro
 ** only works for amalgamation builds.  But that is ok, since these macros
@@ -82735,6 +83883,18 @@ SQLITE_API int sqlite3_found_count = 0;
     mNever = iSrcLine >> 24;
     assert( (I & mNever)==0 );
     if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
+    /* Invoke the branch coverage callback with three arguments:
+    **    iSrcLine - the line number of the VdbeCoverage() macro, with
+    **               flags removed.
+    **    I        - Mask of bits 0x07 indicating which cases are are
+    **               fulfilled by this instance of the jump.  0x01 means
+    **               fall-thru, 0x02 means taken, 0x04 means NULL.  Any
+    **               impossible cases (ex: if the comparison is never NULL)
+    **               are filled in automatically so that the coverage
+    **               measurement logic does not flag those impossible cases
+    **               as missed coverage.
+    **    M        - Type of jump.  Same as M argument above
+    */
     I |= mNever;
     if( M==2 ) I |= 0x04;
     if( M==4 ){
@@ -82746,14 +83906,6 @@ SQLITE_API int sqlite3_found_count = 0;
   }
 #endif
 
-/*
-** Convert the given register into a string if it isn't one
-** already. Return non-zero if a malloc() fails.
-*/
-#define Stringify(P, enc) \
-   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
-     { goto no_mem; }
-
 /*
 ** An ephemeral string value (signified by the MEM_Ephem flag) contains
 ** a pointer to a dynamically allocated string where some other entity
@@ -82811,6 +83963,11 @@ static VdbeCursor *allocateCursor(
 
   assert( iCur>=0 && iCur<p->nCursor );
   if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
+    /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
+    ** is clear. Otherwise, if this is an ephemeral cursor created by 
+    ** OP_OpenDup, the cursor will not be closed and will still be part
+    ** of a BtShared.pCursor list.  */
+    if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
     sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
     p->apCsr[iCur] = 0;
   }
@@ -82830,6 +83987,21 @@ static VdbeCursor *allocateCursor(
   return pCx;
 }
 
+/*
+** The string in pRec is known to look like an integer and to have a
+** floating point value of rValue.  Return true and set *piValue to the
+** integer value if the string is in range to be an integer.  Otherwise,
+** return false.
+*/
+static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
+  i64 iValue = (double)rValue;
+  if( sqlite3RealSameAsInt(rValue,iValue) ){
+    *piValue = iValue;
+    return 1;
+  }
+  return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
+}
+
 /*
 ** Try to convert a value into a numeric representation if we can
 ** do so without loss of information.  In other words, if the string
@@ -82847,12 +84019,12 @@ static VdbeCursor *allocateCursor(
 */
 static void applyNumericAffinity(Mem *pRec, int bTryForInt){
   double rValue;
-  i64 iValue;
   u8 enc = pRec->enc;
-  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
-  if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
-  if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
-    pRec->u.i = iValue;
+  int rc;
+  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
+  rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc);
+  if( rc<=0 ) return;
+  if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){
     pRec->flags |= MEM_Int;
   }else{
     pRec->u.r = rValue;
@@ -82906,11 +84078,14 @@ static void applyAffinity(
     ** there is already a string rep, but it is pointless to waste those
     ** CPU cycles. */
     if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
-      if( (pRec->flags&(MEM_Real|MEM_Int)) ){
+      if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
+        testcase( pRec->flags & MEM_Int );
+        testcase( pRec->flags & MEM_Real );
+        testcase( pRec->flags & MEM_IntReal );
         sqlite3VdbeMemStringify(pRec, enc, 1);
       }
     }
-    pRec->flags &= ~(MEM_Real|MEM_Int);
+    pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
   }
 }
 
@@ -82949,12 +84124,21 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
 ** accordingly.
 */
 static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
-  assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
+  int rc;
+  sqlite3_int64 ix;
+  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
   assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
-  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)==0 ){
+  ExpandBlob(pMem);
+  rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+  if( rc<=0 ){
+    if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
+      pMem->u.i = ix;
+      return MEM_Int;
+    }else{
+      return MEM_Real;
+    }
+  }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
+    pMem->u.i = ix;
     return MEM_Int;
   }
   return MEM_Real;
@@ -82968,10 +84152,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
 ** But it does set pMem->u.r and pMem->u.i appropriately.
 */
 static u16 numericType(Mem *pMem){
-  if( pMem->flags & (MEM_Int|MEM_Real) ){
-    return pMem->flags & (MEM_Int|MEM_Real);
+  if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
+    testcase( pMem->flags & MEM_Int );
+    testcase( pMem->flags & MEM_Real );
+    testcase( pMem->flags & MEM_IntReal );
+    return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
   }
   if( pMem->flags & (MEM_Str|MEM_Blob) ){
+    testcase( pMem->flags & MEM_Str );
+    testcase( pMem->flags & MEM_Blob );
     return computeNumericType(pMem);
   }
   return 0;
@@ -83067,6 +84256,8 @@ static void memTracePrint(Mem *p){
     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_IntReal))!=0 ){
+    printf(" ir:%lld", p->u.i);
   }else if( p->flags & MEM_Int ){
     printf(" i:%lld", p->u.i);
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -83276,6 +84467,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
 
   assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
   sqlite3VdbeEnter(p);
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+  if( db->xProgress ){
+    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+    assert( 0 < db->nProgressOps );
+    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
+  }else{
+    nProgressLimit = 0xffffffff;
+  }
+#endif
   if( p->rc==SQLITE_NOMEM ){
     /* This happens if a malloc() inside a call to sqlite3_column_text() or
     ** sqlite3_column_text16() failed.  */
@@ -83289,15 +84489,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
   db->busyHandler.nBusy = 0;
   if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
   sqlite3VdbeIOTraceSql(p);
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-  if( db->xProgress ){
-    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
-    assert( 0 < db->nProgressOps );
-    nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
-  }else{
-    nProgressLimit = 0xffffffff;
-  }
-#endif
 #ifdef SQLITE_DEBUG
   sqlite3BeginBenignMalloc();
   if( p->pc==0
@@ -83473,10 +84664,11 @@ check_for_interrupt:
   ** If the progress callback returns non-zero, exit the virtual machine with
   ** a return code SQLITE_ABORT.
   */
-  if( nVmStep>=nProgressLimit && db->xProgress!=0 ){
+  while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
     assert( db->nProgressOps!=0 );
-    nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+    nProgressLimit += db->nProgressOps;
     if( db->xProgress(db->pProgressArg) ){
+      nProgressLimit = 0xffffffff;
       rc = SQLITE_INTERRUPT;
       goto abort_due_to_error;
     }
@@ -83755,6 +84947,7 @@ case OP_String8: {         /* same as TK_STRING, out2 */
   if( encoding!=SQLITE_UTF8 ){
     rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
     assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
+    if( rc ) goto too_big;
     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
     assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
     assert( VdbeMemDynamic(pOut)==0 );
@@ -83767,7 +84960,6 @@ case OP_String8: {         /* same as TK_STRING, out2 */
     pOp->p4.z = pOut->z;
     pOp->p1 = pOut->n;
   }
-  testcase( rc==SQLITE_TOOBIG );
 #endif
   if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
@@ -83889,7 +85081,10 @@ case OP_Variable: {            /* out2 */
     goto too_big;
   }
   pOut = &aMem[pOp->p2];
-  sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+  if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+  memcpy(pOut, pVar, MEMCELLSIZE);
+  pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
+  pOut->flags |= MEM_Static|MEM_FromBind;
   UPDATE_MAX_BLOBSIZE(pOut);
   break;
 }
@@ -84022,18 +85217,6 @@ case OP_ResultRow: {
   assert( pOp->p1>0 );
   assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
 
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-  /* Run the progress counter just before returning.
-  */
-  if( db->xProgress!=0
-   && nVmStep>=nProgressLimit 
-   && db->xProgress(db->pProgressArg)!=0
-  ){
-    rc = SQLITE_INTERRUPT;
-    goto abort_due_to_error;
-  }
-#endif
-
   /* If this statement has violated immediate foreign key constraints, do
   ** not return the number of rows modified. And do not RELEASE the statement
   ** transaction. It needs to be rolled back.  */
@@ -84105,33 +85288,57 @@ case OP_ResultRow: {
 ** to avoid a memcpy().
 */
 case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
-  i64 nByte;
+  i64 nByte;          /* Total size of the output string or blob */
+  u16 flags1;         /* Initial flags for P1 */
+  u16 flags2;         /* Initial flags for P2 */
 
   pIn1 = &aMem[pOp->p1];
   pIn2 = &aMem[pOp->p2];
   pOut = &aMem[pOp->p3];
+  testcase( pIn1==pIn2 );
+  testcase( pOut==pIn2 );
   assert( pIn1!=pOut );
-  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
+  flags1 = pIn1->flags;
+  testcase( flags1 & MEM_Null );
+  testcase( pIn2->flags & MEM_Null );
+  if( (flags1 | pIn2->flags) & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
     break;
   }
-  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
-  Stringify(pIn1, encoding);
-  Stringify(pIn2, encoding);
+  if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
+    if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
+    flags1 = pIn1->flags & ~MEM_Str;
+  }else if( (flags1 & MEM_Zero)!=0 ){
+    if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
+    flags1 = pIn1->flags & ~MEM_Str;
+  }
+  flags2 = pIn2->flags;
+  if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
+    if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
+    flags2 = pIn2->flags & ~MEM_Str;
+  }else if( (flags2 & MEM_Zero)!=0 ){
+    if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
+    flags2 = pIn2->flags & ~MEM_Str;
+  }
   nByte = pIn1->n + pIn2->n;
   if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
-  if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+  if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
     goto no_mem;
   }
   MemSetTypeFlag(pOut, MEM_Str);
   if( pOut!=pIn2 ){
     memcpy(pOut->z, pIn2->z, pIn2->n);
+    assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
+    pIn2->flags = flags2;
   }
   memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
+  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+  pIn1->flags = flags1;
   pOut->z[nByte]=0;
   pOut->z[nByte+1] = 0;
+  pOut->z[nByte+2] = 0;
   pOut->flags |= MEM_Term;
   pOut->n = (int)nByte;
   pOut->enc = encoding;
@@ -84182,7 +85389,6 @@ case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
 case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
 case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
 case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
-  char bIntint;   /* Started out as two integer operands */
   u16 flags;      /* Combined MEM_* flags from both inputs */
   u16 type1;      /* Numeric type of left operand */
   u16 type2;      /* Numeric type of right operand */
@@ -84200,7 +85406,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
   if( (type1 & type2 & MEM_Int)!=0 ){
     iA = pIn1->u.i;
     iB = pIn2->u.i;
-    bIntint = 1;
     switch( pOp->opcode ){
       case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
       case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
@@ -84223,7 +85428,6 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
   }else if( (flags & MEM_Null)!=0 ){
     goto arithmetic_result_is_null;
   }else{
-    bIntint = 0;
 fp_math:
     rA = sqlite3VdbeRealValue(pIn1);
     rB = sqlite3VdbeRealValue(pIn2);
@@ -84238,8 +85442,8 @@ fp_math:
         break;
       }
       default: {
-        iA = (i64)rA;
-        iB = (i64)rB;
+        iA = sqlite3VdbeIntValue(pIn1);
+        iB = sqlite3VdbeIntValue(pIn2);
         if( iA==0 ) goto arithmetic_result_is_null;
         if( iA==-1 ) iA = 1;
         rB = (double)(iB % iA);
@@ -84255,9 +85459,6 @@ fp_math:
     }
     pOut->u.r = rB;
     MemSetTypeFlag(pOut, MEM_Real);
-    if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
-      sqlite3VdbeIntegerAffinity(pOut);
-    }
 #endif
   }
   break;
@@ -84399,8 +85600,8 @@ case OP_MustBeInt: {            /* jump, in1 */
   pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_Int)==0 ){
     applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
-    VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
     if( (pIn1->flags & MEM_Int)==0 ){
+      VdbeBranchTaken(1, 2);
       if( pOp->p2==0 ){
         rc = SQLITE_MISMATCH;
         goto abort_due_to_error;
@@ -84409,6 +85610,7 @@ case OP_MustBeInt: {            /* jump, in1 */
       }
     }
   }
+  VdbeBranchTaken(0, 2);
   MemSetTypeFlag(pIn1, MEM_Int);
   break;
 }
@@ -84425,7 +85627,9 @@ case OP_MustBeInt: {            /* jump, in1 */
 */
 case OP_RealAffinity: {                  /* in1 */
   pIn1 = &aMem[pOp->p1];
-  if( pIn1->flags & MEM_Int ){
+  if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
+    testcase( pIn1->flags & MEM_Int );
+    testcase( pIn1->flags & MEM_IntReal );
     sqlite3VdbeMemRealify(pIn1);
   }
   break;
@@ -84583,15 +85787,15 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       ** OP_Eq or OP_Ne) then take the jump or not depending on whether
       ** or not both operands are null.
       */
-      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
       assert( (flags1 & MEM_Cleared)==0 );
-      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
+      testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
       if( (flags1&flags3&MEM_Null)!=0
        && (flags3&MEM_Cleared)==0
       ){
         res = 0;  /* Operands are equal */
       }else{
-        res = 1;  /* Operands are not equal */
+        res = ((flags3 & MEM_Null) ? -1 : +1);  /* Operands are not equal */
       }
     }else{
       /* SQLITE_NULLEQ is clear and at least one operand is NULL,
@@ -84617,7 +85821,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
     affinity = pOp->p5 & SQLITE_AFF_MASK;
     if( affinity>=SQLITE_AFF_NUMERIC ){
       if( (flags1 | flags3)&MEM_Str ){
-        if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+        if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
           applyNumericAffinity(pIn1,0);
           assert( flags3==pIn3->flags );
           /* testcase( flags3!=pIn3->flags );
@@ -84627,7 +85831,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
           ** in case our analysis is incorrect, so it is left in. */
           flags3 = pIn3->flags;
         }
-        if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+        if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
           applyNumericAffinity(pIn3,0);
         }
       }
@@ -84640,17 +85844,19 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
         goto compare_op;
       }
     }else if( affinity==SQLITE_AFF_TEXT ){
-      if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
+      if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
         testcase( pIn1->flags & MEM_Int );
         testcase( pIn1->flags & MEM_Real );
+        testcase( pIn1->flags & MEM_IntReal );
         sqlite3VdbeMemStringify(pIn1, encoding, 1);
         testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
         flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
         assert( pIn1!=pIn3 );
       }
-      if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
+      if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
         testcase( pIn3->flags & MEM_Int );
         testcase( pIn3->flags & MEM_Real );
+        testcase( pIn3->flags & MEM_IntReal );
         sqlite3VdbeMemStringify(pIn3, encoding, 1);
         testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
         flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
@@ -84709,7 +85915,7 @@ compare_op:
     pOut->u.i = res2;
     REGISTER_TRACE(pOp->p2, pOut);
   }else{
-    VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+    VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
     if( res2 ){
       goto jump_to_p2;
     }
@@ -85259,15 +86465,15 @@ case OP_Column: {
       zEndHdr = zData + aOffset[0];
       testcase( zHdr>=zEndHdr );
       do{
-        if( (t = zHdr[0])<0x80 ){
+        if( (pC->aType[i] = t = zHdr[0])<0x80 ){
           zHdr++;
           offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
         }else{
           zHdr += sqlite3GetVarint32(zHdr, &t);
+          pC->aType[i] = t;
           offset64 += sqlite3VdbeSerialTypeLen(t);
         }
-        pC->aType[i++] = t;
-        aOffset[i] = (u32)(offset64 & 0xffffffff);
+        aOffset[++i] = (u32)(offset64 & 0xffffffff);
       }while( i<=p2 && zHdr<zEndHdr );
 
       /* The record is corrupt if any of the following are true:
@@ -85406,12 +86612,21 @@ case OP_Affinity: {
   assert( pOp->p2>0 );
   assert( zAffinity[pOp->p2]==0 );
   pIn1 = &aMem[pOp->p1];
-  do{
+  while( 1 /*edit-by-break*/ ){
     assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
     assert( memIsValid(pIn1) );
-    applyAffinity(pIn1, *(zAffinity++), encoding);
+    applyAffinity(pIn1, zAffinity[0], encoding);
+    if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
+      /* When applying REAL affinity, if the result is still MEM_Int, 
+      ** indicate that REAL is actually desired */
+      pIn1->flags |= MEM_IntReal;
+      pIn1->flags &= ~MEM_Int;
+    }
+    REGISTER_TRACE((int)(pIn1-aMem), pIn1);
+    zAffinity++;
+    if( zAffinity[0]==0 ) break;
     pIn1++;
-  }while( zAffinity[0] );
+  }
   break;
 }
 
@@ -85432,7 +86647,6 @@ case OP_Affinity: {
 ** If P4 is NULL then all index fields have the affinity BLOB.
 */
 case OP_MakeRecord: {
-  u8 *zNewRecord;        /* A buffer to hold the data for the new record */
   Mem *pRec;             /* The new record */
   u64 nData;             /* Number of bytes of data space */
   int nHdr;              /* Number of bytes of header space */
@@ -85445,9 +86659,9 @@ case OP_MakeRecord: {
   int nField;            /* Number of fields in the record */
   char *zAffinity;       /* The affinity string for the record */
   int file_format;       /* File format to use for encoding */
-  int i;                 /* Space used in zNewRecord[] header */
-  int j;                 /* Space used in zNewRecord[] content */
   u32 len;               /* Length of a field */
+  u8 *zHdr;              /* Where to write next byte of the header */
+  u8 *zPayload;          /* Where to write next byte of the payload */
 
   /* Assuming the record contains N fields, the record format looks
   ** like this:
@@ -85486,7 +86700,14 @@ case OP_MakeRecord: {
   if( zAffinity ){
     pRec = pData0;
     do{
-      applyAffinity(pRec++, *(zAffinity++), encoding);
+      applyAffinity(pRec, zAffinity[0], encoding);
+      if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){
+        pRec->flags |= MEM_IntReal;
+        pRec->flags &= ~(MEM_Int);
+      }
+      REGISTER_TRACE((int)(pRec-aMem), pRec);
+      zAffinity++;
+      pRec++;
       assert( zAffinity[0]==0 || pRec<=pLast );
     }while( zAffinity[0] );
   }
@@ -85554,46 +86775,54 @@ case OP_MakeRecord: {
     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
   ** 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;
-
-  /* Write the record */
-  i = putVarint32(zNewRecord, nHdr);
-  j = nHdr;
-  assert( pData0<=pLast );
-  pRec = pData0;
-  do{
-    serial_type = pRec->uTemp;
-    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
-    ** additional varints, one per column. */
-    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
-    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
-    ** immediately follow the header. */
-    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
-  }while( (++pRec)<=pLast );
-  assert( i==nHdr );
-  assert( j==nByte );
-
-  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
   pOut->n = (int)nByte;
   pOut->flags = MEM_Blob;
   if( nZero ){
     pOut->u.nZero = nZero;
     pOut->flags |= MEM_Zero;
   }
-  REGISTER_TRACE(pOp->p3, pOut);
   UPDATE_MAX_BLOBSIZE(pOut);
+  zHdr = (u8 *)pOut->z;
+  zPayload = zHdr + nHdr;
+
+  /* Write the record */
+  zHdr += putVarint32(zHdr, nHdr);
+  assert( pData0<=pLast );
+  pRec = pData0;
+  do{
+    serial_type = pRec->uTemp;
+    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
+    ** additional varints, one per column. */
+    zHdr += putVarint32(zHdr, serial_type);            /* serial type */
+    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
+    ** immediately follow the header. */
+    zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
+  }while( (++pRec)<=pLast );
+  assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
+  assert( nByte==(int)(zPayload - (u8*)pOut->z) );
+
+  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
+  REGISTER_TRACE(pOp->p3, pOut);
   break;
 }
 
@@ -85623,8 +86852,9 @@ case OP_Count: {         /* out2 */
 /* Opcode: Savepoint P1 * * P4 *
 **
 ** Open, release or rollback the savepoint named by parameter P4, depending
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
+** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
+** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
+** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
 */
 case OP_Savepoint: {
   int p1;                         /* Value of P1 operand */
@@ -85692,6 +86922,7 @@ case OP_Savepoint: {
       }
     }
   }else{
+    assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
     iSavepoint = 0;
 
     /* Find the named savepoint. If there is no such savepoint, then an
@@ -85745,6 +86976,7 @@ case OP_Savepoint: {
             if( rc!=SQLITE_OK ) goto abort_due_to_error;
           }
         }else{
+          assert( p1==SAVEPOINT_RELEASE );
           isSchemaChange = 0;
         }
         for(ii=0; ii<db->nDb; ii++){
@@ -85781,6 +87013,7 @@ case OP_Savepoint: {
           db->nSavepoint--;
         }
       }else{
+        assert( p1==SAVEPOINT_ROLLBACK );
         db->nDeferredCons = pSavepoint->nDeferredCons;
         db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
       }
@@ -86261,7 +87494,9 @@ case OP_OpenDup: {
   pCx->isEphemeral = 1;
   pCx->pKeyInfo = pOrig->pKeyInfo;
   pCx->isTable = pOrig->isTable;
-  rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
+  pCx->pgnoRoot = pOrig->pgnoRoot;
+  pCx->isOrdered = pOrig->isOrdered;
+  rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                           pCx->pKeyInfo, pCx->uc.pCursor);
   /* The sqlite3BtreeCursor() routine can only fail for the first cursor
   ** opened for a database.  Since there is already an open cursor when this
@@ -86279,6 +87514,9 @@ case OP_OpenDup: {
 ** the main database is read-only.  The ephemeral
 ** table is deleted automatically when the cursor is closed.
 **
+** If the cursor P1 is already opened on an ephemeral table, the table
+** is cleared (all content is erased).
+**
 ** P2 is the number of columns in the ephemeral table.
 ** The cursor points to a BTree table if P4==0 and to a BTree index
 ** if P4 is not 0.  If P4 is not NULL, it points to a KeyInfo structure
@@ -86310,41 +87548,55 @@ case OP_OpenEphemeral: {
       SQLITE_OPEN_TRANSIENT_DB;
   assert( pOp->p1>=0 );
   assert( pOp->p2>=0 );
-  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
-  if( pCx==0 ) goto no_mem;
-  pCx->nullRow = 1;
-  pCx->isEphemeral = 1;
-  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
-                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
-  if( rc==SQLITE_OK ){
-    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
-  }
-  if( rc==SQLITE_OK ){
-    /* If a transient index is required, create it by calling
-    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
-    ** opening it. If a transient table is required, just use the
-    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
-    */
-    if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
-      int pgno;
-      assert( pOp->p4type==P4_KEYINFO );
-      rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); 
-      if( rc==SQLITE_OK ){
-        assert( pgno==MASTER_ROOT+1 );
-        assert( pKeyInfo->db==db );
-        assert( pKeyInfo->enc==ENC(db) );
-        rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
-                                pKeyInfo, pCx->uc.pCursor);
-      }
-      pCx->isTable = 0;
-    }else{
-      rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
-                              0, pCx->uc.pCursor);
-      pCx->isTable = 1;
+  pCx = p->apCsr[pOp->p1];
+  if( pCx ){
+    /* If the ephermeral table is already open, erase all existing content
+    ** so that the table is empty again, rather than creating a new table. */
+    assert( pCx->isEphemeral );
+    pCx->seqCount = 0;
+    pCx->cacheStatus = CACHE_STALE;
+    if( pCx->pBtx ){
+      rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
     }
+  }else{
+    pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
+    if( pCx==0 ) goto no_mem;
+    pCx->isEphemeral = 1;
+    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, 0);
+    }
+    if( rc==SQLITE_OK ){
+      /* If a transient index is required, create it by calling
+      ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
+      ** opening it. If a transient table is required, just use the
+      ** automatically created table with root-page 1 (an BLOB_INTKEY table).
+      */
+      if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+        assert( pOp->p4type==P4_KEYINFO );
+        rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
+                                     BTREE_BLOBKEY | pOp->p5); 
+        if( rc==SQLITE_OK ){
+          assert( pCx->pgnoRoot==MASTER_ROOT+1 );
+          assert( pKeyInfo->db==db );
+          assert( pKeyInfo->enc==ENC(db) );
+          rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
+                                  pKeyInfo, pCx->uc.pCursor);
+        }
+        pCx->isTable = 0;
+      }else{
+        pCx->pgnoRoot = MASTER_ROOT;
+        rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
+                                0, pCx->uc.pCursor);
+        pCx->isTable = 1;
+      }
+    }
+    pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
   }
   if( rc ) goto abort_due_to_error;
-  pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+  pCx->nullRow = 1;
   break;
 }
 
@@ -86573,6 +87825,8 @@ case OP_SeekGT: {       /* jump, in3, group */
   pC->seekOp = pOp->opcode;
 #endif
 
+  pC->deferredMoveto = 0;
+  pC->cacheStatus = CACHE_STALE;
   if( pC->isTable ){
     /* The BTREE_SEEK_EQ flag is only set on index cursors */
     assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
@@ -86582,20 +87836,24 @@ case OP_SeekGT: {       /* jump, in3, group */
     ** blob, or NULL.  But it needs to be an integer before we can do
     ** the seek, so convert it. */
     pIn3 = &aMem[pOp->p3];
-    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
       applyNumericAffinity(pIn3, 0);
     }
     iKey = sqlite3VdbeIntValue(pIn3);
 
     /* If the P3 value could not be converted into an integer without
     ** loss of information, then special processing is required... */
-    if( (pIn3->flags & MEM_Int)==0 ){
+    if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
       if( (pIn3->flags & MEM_Real)==0 ){
-        /* If the P3 value cannot be converted into any kind of a number,
-        ** then the seek is not possible, so jump to P2 */
-        VdbeBranchTaken(1,2); goto jump_to_p2;
-        break;
-      }
+        if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
+          VdbeBranchTaken(1,2); goto jump_to_p2;
+          break;
+        }else{
+          rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+          if( rc!=SQLITE_OK ) goto abort_due_to_error;
+          goto seek_not_found;
+        }
+      }else
 
       /* If the approximation iKey is larger than the actual real search
       ** term, substitute >= for > and < for <=. e.g. if the search term
@@ -86619,7 +87877,7 @@ case OP_SeekGT: {       /* jump, in3, group */
         assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
         if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
       }
-    } 
+    }
     rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
     pC->movetoTarget = iKey;  /* Used by OP_Delete */
     if( rc!=SQLITE_OK ){
@@ -86673,8 +87931,6 @@ case OP_SeekGT: {       /* jump, in3, group */
       goto seek_not_found;
     }
   }
-  pC->deferredMoveto = 0;
-  pC->cacheStatus = CACHE_STALE;
 #ifdef SQLITE_TEST
   sqlite3_search_count++;
 #endif
@@ -86974,7 +88230,9 @@ case OP_SeekRowid: {        /* jump, in3 */
   u64 iKey;
 
   pIn3 = &aMem[pOp->p3];
-  if( (pIn3->flags & MEM_Int)==0 ){
+  testcase( pIn3->flags & MEM_Int );
+  testcase( pIn3->flags & MEM_IntReal );
+  if( (pIn3->flags & (MEM_Int|MEM_IntReal))==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
@@ -86994,7 +88252,7 @@ case OP_NotExists:          /* jump, in3 */
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
 #ifdef SQLITE_DEBUG
-  pC->seekOp = OP_SeekRowid;
+  if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
 #endif
   assert( pC->isTable );
   assert( pC->eCurType==CURTYPE_BTREE );
@@ -87212,14 +88470,7 @@ case OP_NewRowid: {           /* out2 */
 ** This instruction only works on tables.  The equivalent instruction
 ** for indices is OP_IdxInsert.
 */
-/* Opcode: InsertInt P1 P2 P3 P4 P5
-** Synopsis: intkey=P3 data=r[P2]
-**
-** This works exactly like OP_Insert except that the key is the
-** integer value P3, not the value of the integer stored in register P3.
-*/
-case OP_Insert: 
-case OP_InsertInt: {
+case OP_Insert: {
   Mem *pData;       /* MEM cell holding data for the record to be inserted */
   Mem *pKey;        /* MEM cell holding key  for the record */
   VdbeCursor *pC;   /* Cursor to table into which insert is written */
@@ -87240,16 +88491,11 @@ case OP_InsertInt: {
   REGISTER_TRACE(pOp->p2, pData);
   sqlite3VdbeIncrWriteCounter(p, pC);
 
-  if( pOp->opcode==OP_Insert ){
-    pKey = &aMem[pOp->p3];
-    assert( pKey->flags & MEM_Int );
-    assert( memIsValid(pKey) );
-    REGISTER_TRACE(pOp->p3, pKey);
-    x.nKey = pKey->u.i;
-  }else{
-    assert( pOp->opcode==OP_InsertInt );
-    x.nKey = pOp->p3;
-  }
+  pKey = &aMem[pOp->p3];
+  assert( pKey->flags & MEM_Int );
+  assert( memIsValid(pKey) );
+  REGISTER_TRACE(pOp->p3, pKey);
+  x.nKey = pKey->u.i;
 
   if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
     assert( pC->iDb>=0 );
@@ -87361,7 +88607,7 @@ case OP_Delete: {
     ** OP_Delete will have also set the pC->movetoTarget field to the rowid of
     ** the row that is being deleted */
     i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
-    assert( pC->movetoTarget==iKey );
+    assert( CORRUPT_DB || pC->movetoTarget==iKey );
   }
 #endif
 
@@ -87769,7 +89015,7 @@ case OP_Sort: {        /* jump */
   p->aCounter[SQLITE_STMTSTATUS_SORT]++;
   /* Fall through into OP_Rewind */
 }
-/* Opcode: Rewind P1 P2 * * P5
+/* Opcode: Rewind P1 P2 * * *
 **
 ** 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.
@@ -87777,10 +89023,6 @@ case OP_Sort: {        /* jump */
 ** 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.
@@ -87791,6 +89033,7 @@ case OP_Rewind: {        /* jump */
   int res;
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+  assert( pOp->p5==0 );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
@@ -87805,9 +89048,6 @@ case OP_Rewind: {        /* jump */
     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;
   }
@@ -87902,7 +89142,7 @@ case OP_Next:          /* jump */
   assert( pOp->opcode!=OP_Next
        || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
        || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
-       || pC->seekOp==OP_NullRow);
+       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
   assert( pOp->opcode!=OP_Prev
        || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
        || pC->seekOp==OP_Last 
@@ -88420,7 +89660,7 @@ case OP_ParseSchema: {
   {
     zMaster = MASTER_NAME;
     initData.db = db;
-    initData.iDb = pOp->p1;
+    initData.iDb = iDb;
     initData.pzErrMsg = &p->zErrMsg;
     initData.mInitFlags = 0;
     zSql = sqlite3MPrintf(db,
@@ -88432,9 +89672,16 @@ case OP_ParseSchema: {
       assert( db->init.busy==0 );
       db->init.busy = 1;
       initData.rc = SQLITE_OK;
+      initData.nInitRow = 0;
       assert( !db->mallocFailed );
       rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
       if( rc==SQLITE_OK ) rc = initData.rc;
+      if( rc==SQLITE_OK && initData.nInitRow==0 ){
+        /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
+        ** at least one SQL statement. Any less than that indicates that
+        ** the sqlite_master table is corrupt. */
+        rc = SQLITE_CORRUPT_BKPT;
+      }
       sqlite3DbFreeNN(db, zSql);
       db->init.busy = 0;
     }
@@ -88797,10 +90044,20 @@ case OP_Program: {        /* jump */
   p->nOp = pProgram->nOp;
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   p->anExec = 0;
+#endif
+#ifdef SQLITE_DEBUG
+  /* Verify that second and subsequent executions of the same trigger do not
+  ** try to reuse register values from the first use. */
+  {
+    int i;
+    for(i=0; i<p->nMem; i++){
+      aMem[i].pScopyFrom = 0;  /* Prevent false-positive AboutToChange() errs */
+      aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
+    }
+  }
 #endif
   pOp = &aOp[-1];
-
-  break;
+  goto check_for_interrupt;
 }
 
 /* Opcode: Param P1 P2 * * *
@@ -89172,6 +90429,7 @@ case OP_AggFinal: {
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
 #ifndef SQLITE_OMIT_WINDOWFUNC
   if( pOp->p3 ){
+    memAboutToChange(p, &aMem[pOp->p3]);
     rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
     pMem = &aMem[pOp->p3];
   }else
@@ -89336,14 +90594,19 @@ case OP_JournalMode: {    /* out2 */
 #endif /* SQLITE_OMIT_PRAGMA */
 
 #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum P1 * * * *
+/* Opcode: Vacuum P1 P2 * * *
 **
 ** Vacuum the entire database P1.  P1 is 0 for "main", and 2 or more
 ** for an attached database.  The "temp" database may not be vacuumed.
+**
+** If P2 is not zero, then it is a register holding a string which is
+** the file into which the result of vacuum should be written.  When
+** P2 is zero, the vacuum overwrites the original database.
 */
 case OP_Vacuum: {
   assert( p->readOnly==0 );
-  rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
+  rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1,
+                        pOp->p2 ? &aMem[pOp->p2] : 0);
   if( rc ) goto abort_due_to_error;
   break;
 }
@@ -89495,6 +90758,7 @@ case OP_VDestroy: {
   db->nVDestroy++;
   rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
   db->nVDestroy--;
+  assert( p->errorAction==OE_Abort && p->usesStmtJournal );
   if( rc ) goto abort_due_to_error;
   break;
 }
@@ -89617,10 +90881,11 @@ case OP_VFilter: {   /* jump */
 **
 ** 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 and 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;
@@ -89642,7 +90907,8 @@ case OP_VColumn: {
   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;
@@ -89736,7 +91002,7 @@ case OP_VRename: {
   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;
+  if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter;
   sqlite3VtabImportErrmsg(p, pVtab);
   p->expired = 0;
   if( rc ) goto abort_due_to_error;
@@ -90201,7 +91467,16 @@ abort_due_to_error:
   ** release the mutexes on btrees that were acquired at the
   ** top. */
 vdbe_return:
-  testcase( nVmStep>0 );
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+  while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
+    nProgressLimit += db->nProgressOps;
+    if( db->xProgress(db->pProgressArg) ){
+      nProgressLimit = 0xffffffff;
+      rc = SQLITE_INTERRUPT;
+      goto abort_due_to_error;
+    }
+  }
+#endif
   p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
   sqlite3VdbeLeave(p);
   assert( rc!=SQLITE_OK || nExtraDelete==0 
@@ -91288,7 +92563,7 @@ static int vdbePmaReadBlob(
     /* Extend the p->aAlloc[] allocation if required. */
     if( p->nAlloc<nByte ){
       u8 *aNew;
-      int nNew = MAX(128, p->nAlloc*2);
+      sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc);
       while( nByte>nNew ) nNew = nNew*2;
       aNew = sqlite3Realloc(p->aAlloc, nNew);
       if( !aNew ) return SQLITE_NOMEM_BKPT;
@@ -92579,15 +93854,19 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
 
     if( nMin>pSorter->nMemory ){
       u8 *aNew;
-      int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
-      int nNew = pSorter->nMemory * 2;
+      sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory;
+      int iListOff = -1;
+      if( pSorter->list.pList ){
+        iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
+      }
       while( nNew < nMin ) nNew = nNew*2;
       if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
       if( nNew < nMin ) nNew = nMin;
-
       aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
       if( !aNew ) return SQLITE_NOMEM_BKPT;
-      pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
+      if( iListOff>=0 ){
+        pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
+      }
       pSorter->list.aMemory = aNew;
       pSorter->nMemory = nNew;
     }
@@ -93963,6 +95242,22 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
 /* #include <string.h> */
 
 
+#if !defined(SQLITE_OMIT_WINDOWFUNC)
+/*
+** Walk all expressions linked into the list of Window objects passed
+** as the second argument.
+*/
+static int walkWindowList(Walker *pWalker, Window *pList){
+  Window *pWin;
+  for(pWin=pList; pWin; pWin=pWin->pNextWin){
+    if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
+    if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
+    if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+  }
+  return WRC_Continue;
+}
+#endif
+
 /*
 ** Walk an expression tree.  Invoke the callback once for each node
 ** of the expression, while descending.  (In other words, the callback
@@ -94001,11 +95296,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
         if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
       }
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
-        Window *pWin = pExpr->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;
+      if( ExprHasProperty(pExpr, EP_WinFunc) ){
+        if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
       }
 #endif
     }
@@ -94045,6 +95337,16 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
   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 !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
+  {
+    Parse *pParse = pWalker->pParse;
+    if( pParse && IN_RENAME_OBJECT ){
+      int rc = walkWindowList(pWalker, p->pWinDefn);
+      assert( rc==WRC_Continue );
+      return rc;
+    }
+  }
+#endif
   return WRC_Continue;
 }
 
@@ -94196,7 +95498,6 @@ static void resolveAlias(
     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,
@@ -94265,6 +95566,23 @@ SQLITE_PRIVATE int sqlite3MatchSpanName(
   return 1;
 }
 
+/*
+** Return TRUE if the double-quoted string  mis-feature should be supported.
+*/
+static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
+  if( db->init.busy ) return 1;  /* Always support for legacy schemas */
+  if( pTopNC->ncFlags & NC_IsDDL ){
+    /* Currently parsing a DDL statement */
+    if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
+      return 1;
+    }
+    return (db->flags & SQLITE_DqsDDL)!=0;
+  }else{
+    /* Currently parsing a DML statement */
+    return (db->flags & SQLITE_DqsDML)!=0;
+  }
+}
+
 /*
 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
 ** that name in the set of source tables in pSrcList and make the pExpr 
@@ -94275,7 +95593,7 @@ SQLITE_PRIVATE int sqlite3MatchSpanName(
 **                         (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.
@@ -94319,7 +95637,6 @@ static int lookupName(
 
   /* 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
@@ -94381,7 +95698,7 @@ static int lookupName(
             continue;
           }
           if( IN_RENAME_OBJECT && pItem->zAlias ){
-            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
           }
         }
         if( 0==(cntTab++) ){
@@ -94407,13 +95724,13 @@ static int lookupName(
       }
       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 ) */
 
@@ -94470,7 +95787,7 @@ static int lookupName(
             testcase( iCol==(-1) );
             if( IN_RENAME_OBJECT ){
               pExpr->iColumn = iCol;
-              pExpr->pTab = pTab;
+              pExpr->y.pTab = pTab;
               eNewExprOp = TK_COLUMN;
             }else{
               pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
@@ -94492,7 +95809,7 @@ static int lookupName(
               testcase( iCol==32 );
               pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
             }
-            pExpr->pTab = pTab;
+            pExpr->y.pTab = pTab;
             pExpr->iColumn = (i16)iCol;
             eNewExprOp = TK_TRIGGER;
 #endif /* SQLITE_OMIT_TRIGGER */
@@ -94553,6 +95870,10 @@ static int lookupName(
             sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
             return WRC_Abort;
           }
+          if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
+            sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
+            return WRC_Abort;
+          }
           if( sqlite3ExprVectorSize(pOrig)!=1 ){
             sqlite3ErrorMsg(pParse, "row value misused");
             return WRC_Abort;
@@ -94590,9 +95911,30 @@ static int lookupName(
   */
   if( cnt==0 && zTab==0 ){
     assert( pExpr->op==TK_ID );
-    if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+    if( ExprHasProperty(pExpr,EP_DblQuoted)
+     && areDoubleQuotedStringsEnabled(db, pTopNC)
+    ){
+      /* If a double-quoted identifier does not match any known column name,
+      ** then treat it as a string.
+      **
+      ** This hack was added in the early days of SQLite in a misguided attempt
+      ** to be compatible with MySQL 3.x, which used double-quotes for strings.
+      ** I now sorely regret putting in this hack. The effect of this hack is
+      ** that misspelled identifier names are silently converted into strings
+      ** rather than causing an error, to the frustration of countless
+      ** programmers. To all those frustrated programmers, my apologies.
+      **
+      ** Someday, I hope to get rid of this hack. Unfortunately there is
+      ** a huge amount of legacy SQL that uses it. So for now, we just
+      ** issue a warning.
+      */
+      sqlite3_log(SQLITE_WARNING,
+        "double-quoted string literal: \"%w\"", zCol);
+#ifdef SQLITE_ENABLE_NORMALIZE
+      sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
+#endif
       pExpr->op = TK_STRING;
-      pExpr->pTab = 0;
+      pExpr->y.pTab = 0;
       return WRC_Prune;
     }
     if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -94670,9 +96012,9 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
   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;
@@ -94762,7 +96104,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       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;
@@ -94806,9 +96148,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
         zColumn = pRight->u.zToken;
         if( IN_RENAME_OBJECT ){
           sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
-        }
-        if( IN_RENAME_OBJECT ){
-          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
+          sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
         }
       }
       return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
@@ -94826,6 +96166,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       const char *zId;            /* The function name. */
       FuncDef *pDef;              /* Information about the function */
       u8 enc = ENC(pParse->db);   /* The database encoding */
+      int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
 
       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
       zId = pExpr->u.zToken;
@@ -94841,7 +96182,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       }else{
         is_agg = pDef->xFinalize!=0;
         if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
-          ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+          ExprSetProperty(pExpr, EP_Unlikely);
           if( n==2 ){
             pExpr->iTable = exprProbability(pList->a[1].pExpr);
             if( pExpr->iTable<0 ){
@@ -94890,6 +96231,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           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( 0==IN_RENAME_OBJECT ){
@@ -94898,18 +96248,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           || (pDef->xValue==0 && pDef->xInverse==0)
           || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
         );
-        if( pDef && pDef->xValue==0 && pExpr->pWin ){
+        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->pWin)
-           || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==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->pWin ){
+          if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
             zType = "window";
           }else{
             zType = "aggregate";
@@ -94938,8 +96288,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           pNC->nErr++;
         }
         if( is_agg ){
+          /* Window functions may not be arguments of aggregate functions.
+          ** Or arguments of other window functions. But aggregate functions
+          ** may be arguments for window functions.  */
 #ifndef SQLITE_OMIT_WINDOWFUNC
-          pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
+          pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
 #else
           pNC->ncFlags &= ~NC_AllowAgg;
 #endif
@@ -94948,19 +96301,21 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       sqlite3WalkExprList(pWalker, pList);
       if( is_agg ){
 #ifndef SQLITE_OMIT_WINDOWFUNC
-        if( pExpr->pWin ){
+        if( pExpr->y.pWin ){
           Select *pSel = pNC->pWinSelect;
-          sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
-          sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
-          sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
-          sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
-          if( 0==pSel->pWin 
-           || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) 
-          ){
-            pExpr->pWin->pNextWin = pSel->pWin;
-            pSel->pWin = pExpr->pWin;
+          if( IN_RENAME_OBJECT==0 ){
+            sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
           }
-          pNC->ncFlags |= NC_AllowWin;
+          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
+          sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
+          sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+          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_HasWin;
         }else
 #endif /* SQLITE_OMIT_WINDOWFUNC */
         {
@@ -94978,8 +96333,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
             pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
 
           }
-          pNC->ncFlags |= NC_AllowAgg;
         }
+        pNC->ncFlags |= savedAllowFlags;
       }
       /* FIX ME:  Compute pExpr->affinity based on the expected return
       ** type of the function 
@@ -95010,11 +96365,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
     }
     case TK_IS:
     case TK_ISNOT: {
-      Expr *pRight;
+      Expr *pRight = sqlite3ExprSkipCollate(pExpr->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 ){
+      if( pRight->op==TK_ID ){
         int rc = resolveExprStep(pWalker, pRight);
         if( rc==WRC_Abort ) return WRC_Abort;
         if( pRight->op==TK_TRUEFALSE ){
@@ -95230,32 +96585,53 @@ static int resolveCompoundOrderBy(
       }else{
         iCol = resolveAsName(pParse, pEList, pE);
         if( iCol==0 ){
-          pDup = sqlite3ExprDup(db, pE, 0);
+          /* Now test if expression pE matches one of the values returned
+          ** by pSelect. In the usual case this is done by duplicating the 
+          ** expression, resolving any symbols in it, and then comparing
+          ** it against each expression returned by the SELECT statement.
+          ** Once the comparisons are finished, the duplicate expression
+          ** is deleted.
+          **
+          ** Or, if this is running as part of an ALTER TABLE operation,
+          ** resolve the symbols in the actual expression, not a duplicate.
+          ** And, if one of the comparisons is successful, leave the expression
+          ** as is instead of transforming it to an integer as in the usual
+          ** case. This allows the code in alter.c to modify column
+          ** refererences within the ORDER BY expression as required.  */
+          if( IN_RENAME_OBJECT ){
+            pDup = pE;
+          }else{
+            pDup = sqlite3ExprDup(db, pE, 0);
+          }
           if( !db->mallocFailed ){
             assert(pDup);
             iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
           }
-          sqlite3ExprDelete(db, pDup);
+          if( !IN_RENAME_OBJECT ){
+            sqlite3ExprDelete(db, pDup);
+          }
         }
       }
       if( iCol>0 ){
         /* Convert the ORDER BY term into an integer column number iCol,
         ** taking care to preserve the COLLATE clause if it exists */
-        Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
-        if( pNew==0 ) return 1;
-        pNew->flags |= EP_IntValue;
-        pNew->u.iValue = iCol;
-        if( pItem->pExpr==pE ){
-          pItem->pExpr = pNew;
-        }else{
-          Expr *pParent = pItem->pExpr;
-          assert( pParent->op==TK_COLLATE );
-          while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
-          assert( pParent->pLeft==pE );
-          pParent->pLeft = pNew;
+        if( !IN_RENAME_OBJECT ){
+          Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+          if( pNew==0 ) return 1;
+          pNew->flags |= EP_IntValue;
+          pNew->u.iValue = iCol;
+          if( pItem->pExpr==pE ){
+            pItem->pExpr = pNew;
+          }else{
+            Expr *pParent = pItem->pExpr;
+            assert( pParent->op==TK_COLLATE );
+            while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
+            assert( pParent->pLeft==pE );
+            pParent->pLeft = pNew;
+          }
+          sqlite3ExprDelete(db, pE);
+          pItem->u.x.iOrderByCol = (u16)iCol;
         }
-        sqlite3ExprDelete(db, pE);
-        pItem->u.x.iOrderByCol = (u16)iCol;
         pItem->done = 1;
       }else{
         moreToDo = 1;
@@ -95314,6 +96690,38 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
   return 0;
 }
 
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Walker callback for resolveRemoveWindows().
+*/
+static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
+  if( ExprHasProperty(pExpr, EP_WinFunc) ){
+    Window **pp;
+    for(pp=&pWalker->u.pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
+      if( *pp==pExpr->y.pWin ){
+        *pp = (*pp)->pNextWin;
+        break;
+      }    
+    }
+  }
+  return WRC_Continue;
+}
+
+/*
+** Remove any Window objects owned by the expression pExpr from the
+** Select.pWin list of Select object pSelect.
+*/
+static void resolveRemoveWindows(Select *pSelect, Expr *pExpr){
+  Walker sWalker;
+  memset(&sWalker, 0, sizeof(Walker));
+  sWalker.xExprCallback = resolveRemoveWindowsCb;
+  sWalker.u.pSelect = pSelect;
+  sqlite3WalkExpr(&sWalker, pExpr);
+}
+#else
+# define resolveRemoveWindows(x,y)
+#endif
+
 /*
 ** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
 ** The Name context of the SELECT statement is pNC.  zType is either
@@ -95380,19 +96788,10 @@ static int resolveOrderGroupBy(
     }
     for(j=0; j<pSelect->pEList->nExpr; j++){
       if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
-#ifndef SQLITE_OMIT_WINDOWFUNC
-        if( pE->pWin ){
-          /* 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->pWin ){
-              *pp = (*pp)->pNextWin;
-            }    
-          }
-        }
-#endif
+        /* Since this expresion is being changed into a reference
+        ** to an identical expression in the result set, remove all Window
+        ** objects belonging to the expression from the Select.pWin list. */
+        resolveRemoveWindows(pSelect, pE);
         pItem->u.x.iOrderByCol = j+1;
       }
     }
@@ -95472,7 +96871,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     */
     for(i=0; i<p->pSrc->nSrc; i++){
       struct SrcList_item *pItem = &p->pSrc->a[i];
-      if( pItem->pSelect ){
+      if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
         NameContext *pNC;         /* Used to iterate name contexts */
         int nRef = 0;             /* Refcount for pOuterNC and outer contexts */
         const char *zSavedContext = pParse->zAuthContext;
@@ -95604,6 +97003,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
       }
     }
 
+#ifndef SQLITE_OMIT_WINDOWFUNC
+    if( IN_RENAME_OBJECT ){
+      Window *pWin;
+      for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
+        if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
+         || sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
+        ){
+          return WRC_Abort;
+        }
+      }
+    }
+#endif
+
     /* If this is part of a compound SELECT, check that it has the right
     ** number of expressions in the select list. */
     if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
@@ -95679,12 +97091,12 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
   NameContext *pNC,       /* Namespace to resolve expressions in. */
   Expr *pExpr             /* The expression to be analyzed. */
 ){
-  u16 savedHasAgg;
+  int savedHasAgg;
   Walker w;
 
   if( pExpr==0 ) return SQLITE_OK;
-  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
-  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
+  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
   w.pParse = pNC->pParse;
   w.xExprCallback = resolveExprStep;
   w.xSelectCallback = resolveSelectStep;
@@ -95700,9 +97112,11 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
 #if SQLITE_MAX_EXPR_DEPTH>0
   w.pParse->nHeight -= pExpr->nHeight;
 #endif
-  if( pNC->ncFlags & NC_HasAgg ){
-    ExprSetProperty(pExpr, EP_Agg);
-  }
+  assert( EP_Agg==NC_HasAgg );
+  assert( EP_Win==NC_HasWin );
+  testcase( pNC->ncFlags & NC_HasAgg );
+  testcase( pNC->ncFlags & NC_HasWin );
+  ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
   pNC->ncFlags |= savedHasAgg;
   return pNC->nErr>0 || w.pParse->nErr>0;
 }
@@ -95754,38 +97168,47 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
 }
 
 /*
-** Resolve names in expressions that can only reference a single table:
+** Resolve names in expressions that can only reference a single table
+** or which cannot reference any tables at all.  Examples:
 **
-**    *   CHECK constraints
-**    *   WHERE clauses on partial indices
+**    (1)   CHECK constraints
+**    (2)   WHERE clauses on partial indices
+**    (3)   Expressions in indexes on expressions
+**    (4)   Expression arguments to VACUUM INTO.
 **
-** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
-** is set to -1 and the Expr.iColumn value is set to the column number.
+** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
+** nodes of the expression is set to -1 and the Expr.iColumn value is
+** set to the column number.  In case (4), TK_COLUMN nodes cause an error.
 **
 ** Any errors cause an error message to be set in pParse.
 */
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(
   Parse *pParse,      /* Parsing context */
-  Table *pTab,        /* The table being referenced */
-  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+  Table *pTab,        /* The table being referenced, or NULL */
+  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
   Expr *pExpr,        /* Expression to resolve.  May be NULL. */
   ExprList *pList     /* Expression list to resolve.  May be NULL. */
 ){
   SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
   NameContext sNC;                /* Name context for pParse->pNewTable */
+  int rc;
 
-  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
+  assert( type==0 || pTab!=0 );
+  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
   memset(&sNC, 0, sizeof(sNC));
   memset(&sSrc, 0, sizeof(sSrc));
-  sSrc.nSrc = 1;
-  sSrc.a[0].zName = pTab->zName;
-  sSrc.a[0].pTab = pTab;
-  sSrc.a[0].iCursor = -1;
+  if( pTab ){
+    sSrc.nSrc = 1;
+    sSrc.a[0].zName = pTab->zName;
+    sSrc.a[0].pTab = pTab;
+    sSrc.a[0].iCursor = -1;
+  }
   sNC.pParse = pParse;
   sNC.pSrcList = &sSrc;
-  sNC.ncFlags = type;
-  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
-  if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
+  sNC.ncFlags = type | NC_IsDDL;
+  if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
+  if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
+  return rc;
 }
 
 /************** End of resolve.c *********************************************/
@@ -95836,8 +97259,12 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
 */
 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
   int op;
-  pExpr = sqlite3ExprSkipCollate(pExpr);
   if( pExpr->flags & EP_Generic ) return 0;
+  while( ExprHasProperty(pExpr, EP_Skip) ){
+    assert( pExpr->op==TK_COLLATE );
+    pExpr = pExpr->pLeft;
+    assert( pExpr!=0 );
+  }
   op = pExpr->op;
   if( op==TK_SELECT ){
     assert( pExpr->flags&EP_xIsSelect );
@@ -95850,8 +97277,8 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
     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 );
@@ -95898,7 +97325,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
 ** or likelihood() function at the root of an expression.
 */
 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
-  while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
+  while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
     if( ExprHasProperty(pExpr, EP_Unlikely) ){
       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
       assert( pExpr->x.pList->nExpr>0 );
@@ -95933,15 +97360,15 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
   while( p ){
     int op = p->op;
     if( p->flags & EP_Generic ) break;
-    if( (op==TK_AGG_COLUMN || op==TK_COLUMN
-          || op==TK_REGISTER || op==TK_TRIGGER)
-     && p->pTab!=0
+    if( op==TK_REGISTER ) op = p->op2;
+    if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
+     && 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;
@@ -95950,7 +97377,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
       p = p->pLeft;
       continue;
     }
-    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+    if( op==TK_COLLATE ){
       pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
       break;
     }
@@ -96257,6 +97684,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
   }else{
     if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
     pRet = sqlite3ExprDup(pParse->db, pVector, 0);
+    sqlite3RenameTokenRemap(pParse, pRet, pVector);
   }
   return pRet;
 }
@@ -96273,7 +97701,7 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
   int reg = 0;
 #ifndef SQLITE_OMIT_SUBQUERY
   if( pExpr->op==TK_SELECT ){
-    reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+    reg = sqlite3CodeSubselect(pParse, pExpr);
   }
 #endif
   return reg;
@@ -96345,7 +97773,7 @@ static void codeVectorCompare(
   int regLeft = 0;
   int regRight = 0;
   u8 opx = op;
-  int addrDone = sqlite3VdbeMakeLabel(v);
+  int addrDone = sqlite3VdbeMakeLabel(pParse);
 
   if( nLeft!=sqlite3ExprVectorSize(pRight) ){
     sqlite3ErrorMsg(pParse, "row value misused");
@@ -96564,7 +97992,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
     pNew->iAgg = -1;
     if( pToken ){
       if( nExtra==0 ){
-        pNew->flags |= EP_IntValue|EP_Leaf;
+        pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
         pNew->u.iValue = iValue;
       }else{
         pNew->u.zToken = (char*)&pNew[1];
@@ -96572,8 +98000,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
         if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
         pNew->u.zToken[pToken->n] = 0;
         if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
-          if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
-          sqlite3Dequote(pNew->u.zToken);
+          sqlite3DequoteExpr(pNew);
         }
       }
     }
@@ -96642,20 +98069,16 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
   Expr *pRight            /* Right operand */
 ){
   Expr *p;
-  if( op==TK_AND && pParse->nErr==0 ){
-    /* Take advantage of short-circuit false optimization for AND */
-    p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
-  }else{
-    p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
-    if( p ){
-      memset(p, 0, sizeof(Expr));
-      p->op = op & TKFLG_MASK;
-      p->iAgg = -1;
-    }
+  p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
+  if( p ){
+    memset(p, 0, sizeof(Expr));
+    p->op = op & 0xff;
+    p->iAgg = -1;
     sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
-  }
-  if( p ) {
     sqlite3ExprCheckHeight(pParse, p->nHeight);
+  }else{
+    sqlite3ExprDelete(pParse->db, pLeft);
+    sqlite3ExprDelete(pParse->db, pRight);
   }
   return p;
 }
@@ -96676,33 +98099,6 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pS
 }
 
 
-/*
-** If the expression is always either TRUE or FALSE (respectively),
-** then return 1.  If one cannot determine the truth value of the
-** expression at compile-time return 0.
-**
-** This is an optimization.  If is OK to return 0 here even if
-** the expression really is always false or false (a false negative).
-** But it is a bug to return 1 if the expression might have different
-** boolean values in different circumstances (a false positive.)
-**
-** Note that if the expression is part of conditional for a
-** LEFT JOIN, then we cannot determine at compile-time whether or not
-** is it true or false, so always return 0.
-*/
-static int exprAlwaysTrue(Expr *p){
-  int v = 0;
-  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
-  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
-  return v!=0;
-}
-static int exprAlwaysFalse(Expr *p){
-  int v = 0;
-  if( ExprHasProperty(p, EP_FromJoin) ) return 0;
-  if( !sqlite3ExprIsInteger(p, &v) ) return 0;
-  return v==0;
-}
-
 /*
 ** Join two expressions using an AND operator.  If either expression is
 ** NULL, then just return the other expression.
@@ -96711,19 +98107,18 @@ static int exprAlwaysFalse(Expr *p){
 ** of returning an AND expression, just return a constant expression with
 ** a value of false.
 */
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
-  if( pLeft==0 ){
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
+  sqlite3 *db = pParse->db;
+  if( pLeft==0  ){
     return pRight;
   }else if( pRight==0 ){
     return pLeft;
-  }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
-    sqlite3ExprDelete(db, pLeft);
-    sqlite3ExprDelete(db, pRight);
+  }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
+    sqlite3ExprUnmapAndDelete(pParse, pLeft);
+    sqlite3ExprUnmapAndDelete(pParse, pRight);
     return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
   }else{
-    Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
-    sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
-    return pNew;
+    return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
   }
 }
 
@@ -96844,6 +98239,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
   assert( p!=0 );
   /* Sanity check: Assert that the IntValue is non-negative if it exists */
   assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
+
+  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 );
@@ -96862,8 +98261,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
     }else{
       sqlite3ExprListDelete(db, p->x.pList);
     }
-    if( !ExprHasProperty(p, EP_Reduced) ){
-      sqlite3WindowDelete(db, p->pWin);
+    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);
@@ -96875,6 +98275,18 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
   if( p ) sqlite3ExprDeleteNN(db, p);
 }
 
+/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
+** expression.
+*/
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
+  if( p ){
+    if( IN_RENAME_OBJECT ){
+      sqlite3RenameExprUnmap(pParse, p);
+    }
+    sqlite3ExprDeleteNN(pParse->db, p);
+  }
+}
+
 /*
 ** Return the number of bytes allocated for the expression structure 
 ** passed as the first argument. This is always one of EXPR_FULLSIZE,
@@ -96886,6 +98298,16 @@ static int exprStructSize(Expr *p){
   return EXPR_FULLSIZE;
 }
 
+/*
+** Copy the complete content of an Expr node, taking care not to read
+** past the end of the structure for a reduced-size version of the source
+** Expr.
+*/
+static void exprNodeCopy(Expr *pDest, Expr *pSrc){
+  memset(pDest, 0, sizeof(Expr));
+  memcpy(pDest, pSrc, exprStructSize(pSrc));
+}
+
 /*
 ** The dupedExpr*Size() routines each return the number of bytes required
 ** to store a copy of an expression or expression tree.  They differ in
@@ -96927,7 +98349,7 @@ static int dupedExprStructSize(Expr *p, int flags){
   assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
   if( 0==flags || p->op==TK_SELECT_COLUMN 
 #ifndef SQLITE_OMIT_WINDOWFUNC
-   || p->pWin 
+   || ExprHasProperty(p, EP_WinFunc)
 #endif
   ){
     nSize = EXPR_FULLSIZE;
@@ -96954,7 +98376,7 @@ static int dupedExprStructSize(Expr *p, int flags){
 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);
 }
@@ -97057,22 +98479,24 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
     }
 
     /* Fill in pNew->pLeft and pNew->pRight. */
-    zAlloc += dupedExprNodeSize(p, dupFlags);
-    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 ?
                       exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
         pNew->pRight = p->pRight ?
                        exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
       }
-    }else{
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
-        pNew->pWin = 0;
-      }else{
-        pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
+      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;
+      }
+    }else{
       if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
         if( pNew->op==TK_SELECT_COLUMN ){
           pNew->pLeft = p->pLeft;
@@ -97084,9 +98508,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
         pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
       }
     }
-    if( pzBuffer ){
-      *pzBuffer = zAlloc;
-    }
   }
   return pNew;
 }
@@ -97100,7 +98521,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
 static With *withDup(sqlite3 *db, With *p){
   With *pRet = 0;
   if( p ){
-    int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
+    sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
     pRet = sqlite3DbMallocZero(db, nByte);
     if( pRet ){
       int i;
@@ -97118,6 +98539,36 @@ static With *withDup(sqlite3 *db, With *p){
 # define withDup(x,y) 0
 #endif
 
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** The gatherSelectWindows() procedure and its helper routine
+** gatherSelectWindowsCallback() are used to scan all the expressions
+** an a newly duplicated SELECT statement and gather all of the Window
+** objects found there, assembling them onto the linked list at Select->pWin.
+*/
+static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
+  if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
+    assert( ExprHasProperty(pExpr, EP_WinFunc) );
+    pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
+    pWalker->u.pSelect->pWin = pExpr->y.pWin;
+  }
+  return WRC_Continue;
+}
+static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
+  return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
+}
+static void gatherSelectWindows(Select *p){
+  Walker w;
+  w.xExprCallback = gatherSelectWindowsCallback;
+  w.xSelectCallback = gatherSelectWindowsSelectCallback;
+  w.xSelectCallback2 = 0;
+  w.pParse = 0;
+  w.u.pSelect = p;
+  sqlite3WalkSelect(&w, p);
+}
+#endif
+
+
 /*
 ** The following group of routines make deep copies of expressions,
 ** expression lists, ID lists, and select statements.  The copies can
@@ -97285,6 +98736,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
 #ifndef SQLITE_OMIT_WINDOWFUNC
     pNew->pWin = 0;
     pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
+    if( p->pWin ) gatherSelectWindows(pNew);
 #endif
     pNew->selId = p->selId;
     *pp = pNew;
@@ -97334,7 +98786,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
   }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
     ExprList *pNew;
     pNew = sqlite3DbRealloc(db, pList, 
-             sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0]));
+         sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0]));
     if( pNew==0 ){
       goto no_mem;
     }
@@ -97417,7 +98869,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
   }
 
 vector_append_error:
-  sqlite3ExprDelete(db, pExpr);
+  sqlite3ExprUnmapAndDelete(pParse, pExpr);
   sqlite3IdListDelete(db, pColumns);
   return pList;
 }
@@ -97560,10 +99012,12 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
 */
 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
+  if( !ExprHasProperty(pExpr, EP_Quoted)
+   && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
+       || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
   ){
     pExpr->op = TK_TRUEFALSE;
+    ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
     return 1;
   }
   return 0;
@@ -97574,12 +99028,40 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
 ** and 0 if it is FALSE.
 */
 SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
+  pExpr = sqlite3ExprSkipCollate((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;
 }
 
+/*
+** If pExpr is an AND or OR expression, try to simplify it by eliminating
+** terms that are always true or false.  Return the simplified expression.
+** Or return the original expression if no simplification is possible.
+**
+** Examples:
+**
+**     (x<10) AND true                =>   (x<10)
+**     (x<10) AND false               =>   false
+**     (x<10) AND (y=22 OR false)     =>   (x<10) AND (y=22)
+**     (x<10) AND (y=22 OR true)      =>   (x<10)
+**     (y=22) OR true                 =>   true
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
+  assert( pExpr!=0 );
+  if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
+    Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
+    Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
+    if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
+      pExpr = pExpr->op==TK_AND ? pRight : pLeft;
+    }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
+      pExpr = pExpr->op==TK_AND ? pLeft : pRight;
+    }
+  }
+  return pExpr;
+}
+
 
 /*
 ** These routines are Walker callbacks used to check expressions to
@@ -97824,7 +99306,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
 */
 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
   int rc = 0;
-  if( p==0 ) return 0;  /* Can only happen following on OOM */
+  if( NEVER(p==0) ) return 0;  /* Used to only happen following on OOM */
 
   /* If an expression is an integer literal that fits in a signed 32-bit
   ** integer, then the EP_IntValue flag will have already been set */
@@ -97870,7 +99352,9 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
 */
 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
   u8 op;
-  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
+  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
+    p = p->pLeft;
+  }
   op = p->op;
   if( op==TK_REGISTER ) op = p->op2;
   switch( op ){
@@ -97881,8 +99365,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
       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;
   }
@@ -98106,7 +99590,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
   Expr *pX,                  /* The right-hand side (RHS) of the IN operator */
   u32 inFlags,               /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
   int *prRhsHasNull,         /* Register holding NULL status.  See notes */
-  int *aiMap                 /* Mapping from Index fields to RHS fields */
+  int *aiMap,                /* Mapping from Index fields to RHS fields */
+  int *piTab                 /* OUT: index to use */
 ){
   Select *p;                            /* SELECT to the right of IN operator */
   int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
@@ -98201,6 +99686,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
           Bitmask colUsed;      /* Columns of the index used */
           Bitmask mCol;         /* Mask for the current column */
           if( pIdx->nColumn<nExpr ) continue;
+          if( pIdx->pPartIdxWhere!=0 ) continue;
           /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
           ** BITMASK(nExpr) without overflowing */
           testcase( pIdx->nColumn==BMS-2 );
@@ -98291,16 +99777,15 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
     eType = IN_INDEX_EPH;
     if( inFlags & IN_INDEX_LOOP ){
       pParse->nQueryLoop = 0;
-      if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
-        eType = IN_INDEX_ROWID;
-      }
     }else if( prRhsHasNull ){
       *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
     }
-    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
+    assert( pX->op==TK_IN );
+    sqlite3CodeRhsOfIN(pParse, pX, iTab);
+    if( rMayHaveNull ){
+      sqlite3SetHasNullFlag(v, iTab, rMayHaveNull);
+    }
     pParse->nQueryLoop = savedNQueryLoop;
-  }else{
-    pX->iTable = iTab;
   }
 
   if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
@@ -98308,6 +99793,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
     n = sqlite3ExprVectorSize(pX->pLeft);
     for(i=0; i<n; i++) aiMap[i] = i;
   }
+  *piTab = iTab;
   return eType;
 }
 #endif
@@ -98381,48 +99867,230 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
   }
 }
 
+#ifndef SQLITE_OMIT_SUBQUERY
 /*
-** Generate code for scalar subqueries used as a subquery expression, EXISTS,
-** or IN operators.  Examples:
+** Generate code that will construct an ephemeral table containing all terms
+** in the RHS of an IN operator.  The IN operator can be in either of two
+** forms:
 **
-**     (SELECT a FROM b)          -- subquery
-**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
 **     x IN (4,5,11)              -- IN operator with list on right-hand side
 **     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
 **
-** The pExpr parameter describes the expression that contains the IN
-** operator or subquery.
+** The pExpr parameter is the IN operator.  The cursor number for the
+** constructed ephermeral table is returned.  The first time the ephemeral
+** table is computed, the cursor number is also stored in pExpr->iTable,
+** however the cursor number returned might not be the same, as it might
+** have been duplicated using OP_OpenDup.
 **
-** If parameter isRowid is non-zero, then expression pExpr is guaranteed
-** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
-** to some integer key column of a table B-Tree. In this case, use an
-** intkey B-Tree to store the set of IN(...) values instead of the usual
-** (slower) variable length keys B-Tree.
+** If the LHS expression ("x" in the examples) is a column value, or
+** the SELECT statement returns a column value, then the affinity of that
+** column is used to build the index keys. If both 'x' and the
+** SELECT... statement are columns, then numeric affinity is used
+** if either column has NUMERIC or INTEGER affinity. If neither
+** 'x' nor the SELECT... statement are columns, then numeric affinity
+** is used.
+*/
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
+  Parse *pParse,          /* Parsing context */
+  Expr *pExpr,            /* The IN operator */
+  int iTab                /* Use this cursor number */
+){
+  int addrOnce = 0;           /* Address of the OP_Once instruction at top */
+  int addr;                   /* Address of OP_OpenEphemeral instruction */
+  Expr *pLeft;                /* the LHS of the IN operator */
+  KeyInfo *pKeyInfo = 0;      /* Key information */
+  int nVal;                   /* Size of vector pLeft */
+  Vdbe *v;                    /* The prepared statement under construction */
+
+  v = pParse->pVdbe;
+  assert( v!=0 );
+
+  /* The evaluation of the IN must be repeated every time it
+  ** is encountered if any of the following is true:
+  **
+  **    *  The right-hand side is a correlated subquery
+  **    *  The right-hand side is an expression list containing variables
+  **    *  We are inside a trigger
+  **
+  ** If all of the above are false, then we can compute the RHS just once
+  ** and reuse it many names.
+  */
+  if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
+    /* Reuse of the RHS is allowed */
+    /* If this routine has already been coded, but the previous code
+    ** might not have been invoked yet, so invoke it now as a subroutine. 
+    */
+    if( ExprHasProperty(pExpr, EP_Subrtn) ){
+      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+        ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
+              pExpr->x.pSelect->selId));
+      }
+      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+                        pExpr->y.sub.iAddr);
+      sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
+      sqlite3VdbeJumpHere(v, addrOnce);
+      return;
+    }
+
+    /* Begin coding the subroutine */
+    ExprSetProperty(pExpr, EP_Subrtn);
+    pExpr->y.sub.regReturn = ++pParse->nMem;
+    pExpr->y.sub.iAddr =
+      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+    VdbeComment((v, "return address"));
+
+    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+  }
+
+  /* Check to see if this is a vector IN operator */
+  pLeft = pExpr->pLeft;
+  nVal = sqlite3ExprVectorSize(pLeft);
+
+  /* Construct the ephemeral table that will contain the content of
+  ** RHS of the IN operator.
+  */
+  pExpr->iTable = iTab;
+  addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+    VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
+  }else{
+    VdbeComment((v, "RHS of IN operator"));
+  }
+#endif
+  pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
+
+  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+    /* Case 1:     expr IN (SELECT ...)
+    **
+    ** Generate code to write the results of the select into the temporary
+    ** table allocated and opened above.
+    */
+    Select *pSelect = pExpr->x.pSelect;
+    ExprList *pEList = pSelect->pEList;
+
+    ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
+        addrOnce?"":"CORRELATED ", pSelect->selId
+    ));
+    /* If the LHS and RHS of the IN operator do not match, that
+    ** error will have been caught long before we reach this point. */
+    if( ALWAYS(pEList->nExpr==nVal) ){
+      SelectDest dest;
+      int i;
+      sqlite3SelectDestInit(&dest, SRT_Set, iTab);
+      dest.zAffSdst = exprINAffinity(pParse, pExpr);
+      pSelect->iLimit = 0;
+      testcase( pSelect->selFlags & SF_Distinct );
+      testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+      if( sqlite3Select(pParse, pSelect, &dest) ){
+        sqlite3DbFree(pParse->db, dest.zAffSdst);
+        sqlite3KeyInfoUnref(pKeyInfo);
+        return;
+      }
+      sqlite3DbFree(pParse->db, dest.zAffSdst);
+      assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+      assert( pEList!=0 );
+      assert( pEList->nExpr>0 );
+      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+      for(i=0; i<nVal; i++){
+        Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
+        pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
+            pParse, p, pEList->a[i].pExpr
+        );
+      }
+    }
+  }else if( ALWAYS(pExpr->x.pList!=0) ){
+    /* Case 2:     expr IN (exprlist)
+    **
+    ** For each expression, build an index key from the evaluation and
+    ** store it in the temporary table. If <expr> is a column, then use
+    ** that columns affinity when building index keys. If <expr> is not
+    ** a column, use numeric affinity.
+    */
+    char affinity;            /* Affinity of the LHS of the IN */
+    int i;
+    ExprList *pList = pExpr->x.pList;
+    struct ExprList_item *pItem;
+    int r1, r2, r3;
+    affinity = sqlite3ExprAffinity(pLeft);
+    if( !affinity ){
+      affinity = SQLITE_AFF_BLOB;
+    }
+    if( pKeyInfo ){
+      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+    }
+
+    /* Loop through each expression in <exprlist>. */
+    r1 = sqlite3GetTempReg(pParse);
+    r2 = sqlite3GetTempReg(pParse);
+    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
+      Expr *pE2 = pItem->pExpr;
+
+      /* If the expression is not constant then we will need to
+      ** disable the test that was generated above that makes sure
+      ** this code only executes once.  Because for a non-constant
+      ** expression we need to rerun this code each time.
+      */
+      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
+        sqlite3VdbeChangeToNoop(v, addrOnce);
+        ExprClearProperty(pExpr, EP_Subrtn);
+        addrOnce = 0;
+      }
+
+      /* Evaluate the expression and insert it into the temp table */
+      r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
+      sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
+    }
+    sqlite3ReleaseTempReg(pParse, r1);
+    sqlite3ReleaseTempReg(pParse, r2);
+  }
+  if( pKeyInfo ){
+    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
+  }
+  if( addrOnce ){
+    sqlite3VdbeJumpHere(v, addrOnce);
+    /* Subroutine return */
+    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
+  }
+}
+#endif /* SQLITE_OMIT_SUBQUERY */
+
+/*
+** Generate code for scalar subqueries used as a subquery expression
+** or EXISTS operator:
 **
-** If rMayHaveNull is non-zero, that means that the operation is an IN
-** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
-** All this routine does is initialize the register given by rMayHaveNull
-** to NULL.  Calling routines will take care of changing this register
-** value to non-NULL if the RHS is NULL-free.
+**     (SELECT a FROM b)          -- subquery
+**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
 **
-** For a SELECT or EXISTS operator, return the register that holds the
-** result.  For a multi-column SELECT, the result is stored in a contiguous
-** array of registers and the return value is the register of the left-most
-** result column.  Return 0 for IN operators or if an error occurs.
+** The pExpr parameter is the SELECT or EXISTS operator to be coded.
+**
+** The register that holds the result.  For a multi-column SELECT, 
+** the result is stored in a contiguous array of registers and the
+** return value is the register of the left-most result column.
+** Return 0 if an error occurs.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3CodeSubselect(
-  Parse *pParse,          /* Parsing context */
-  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
-  int rHasNullFlag,       /* Register that records whether NULLs exist in RHS */
-  int isRowid             /* If true, LHS of IN operator is a rowid */
-){
-  int jmpIfDynamic = -1;                      /* One-time test address */
-  int rReg = 0;                           /* Register storing resulting */
-  Vdbe *v = sqlite3GetVdbe(pParse);
-  if( NEVER(v==0) ) return 0;
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+  int addrOnce = 0;           /* Address of OP_Once at top of subroutine */
+  int rReg = 0;               /* Register storing resulting */
+  Select *pSel;               /* SELECT statement to encode */
+  SelectDest dest;            /* How to deal with SELECT result */
+  int nReg;                   /* Registers to allocate */
+  Expr *pLimit;               /* New limit expression */
 
-  /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+  Vdbe *v = pParse->pVdbe;
+  assert( v!=0 );
+  testcase( pExpr->op==TK_EXISTS );
+  testcase( pExpr->op==TK_SELECT );
+  assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
+  assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+  pSel = pExpr->x.pSelect;
+
+  /* The evaluation of the EXISTS/SELECT must be repeated every time it
   ** is encountered if any of the following is true:
   **
   **    *  The right-hand side is a correlated subquery
@@ -98433,208 +100101,70 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
   ** save the results, and reuse the same result on subsequent invocations.
   */
   if( !ExprHasProperty(pExpr, EP_VarSelect) ){
-    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
-  }
-
-  switch( pExpr->op ){
-    case TK_IN: {
-      int addr;                   /* Address of OP_OpenEphemeral instruction */
-      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
-      KeyInfo *pKeyInfo = 0;      /* Key information */
-      int nVal;                   /* Size of vector pLeft */
-      
-      nVal = sqlite3ExprVectorSize(pLeft);
-      assert( !isRowid || nVal==1 );
-
-      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
-      ** expression it is handled the same way.  An ephemeral table is 
-      ** filled with index keys representing the results from the 
-      ** SELECT or the <exprlist>.
-      **
-      ** If the 'x' expression is a column value, or the SELECT...
-      ** statement returns a column value, then the affinity of that
-      ** column is used to build the index keys. If both 'x' and the
-      ** SELECT... statement are columns, then numeric affinity is used
-      ** if either column has NUMERIC or INTEGER affinity. If neither
-      ** 'x' nor the SELECT... statement are columns, then numeric affinity
-      ** is used.
-      */
-      pExpr->iTable = pParse->nTab++;
-      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
-          pExpr->iTable, (isRowid?0:nVal));
-      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
-
-      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
-        /* Case 1:     expr IN (SELECT ...)
-        **
-        ** Generate code to write the results of the select into the temporary
-        ** table allocated and opened above.
-        */
-        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. */
-        if( ALWAYS(pEList->nExpr==nVal) ){
-          SelectDest dest;
-          int i;
-          sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
-          dest.zAffSdst = exprINAffinity(pParse, pExpr);
-          pSelect->iLimit = 0;
-          testcase( pSelect->selFlags & SF_Distinct );
-          testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
-          if( sqlite3Select(pParse, pSelect, &dest) ){
-            sqlite3DbFree(pParse->db, dest.zAffSdst);
-            sqlite3KeyInfoUnref(pKeyInfo);
-            return 0;
-          }
-          sqlite3DbFree(pParse->db, dest.zAffSdst);
-          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
-          assert( pEList!=0 );
-          assert( pEList->nExpr>0 );
-          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
-          for(i=0; i<nVal; i++){
-            Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
-            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
-                pParse, p, pEList->a[i].pExpr
-            );
-          }
-        }
-      }else if( ALWAYS(pExpr->x.pList!=0) ){
-        /* Case 2:     expr IN (exprlist)
-        **
-        ** For each expression, build an index key from the evaluation and
-        ** store it in the temporary table. If <expr> is a column, then use
-        ** that columns affinity when building index keys. If <expr> is not
-        ** a column, use numeric affinity.
-        */
-        char affinity;            /* Affinity of the LHS of the IN */
-        int i;
-        ExprList *pList = pExpr->x.pList;
-        struct ExprList_item *pItem;
-        int r1, r2, r3;
-        affinity = sqlite3ExprAffinity(pLeft);
-        if( !affinity ){
-          affinity = SQLITE_AFF_BLOB;
-        }
-        if( pKeyInfo ){
-          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
-          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-        }
-
-        /* Loop through each expression in <exprlist>. */
-        r1 = sqlite3GetTempReg(pParse);
-        r2 = sqlite3GetTempReg(pParse);
-        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;
-
-          /* If the expression is not constant then we will need to
-          ** disable the test that was generated above that makes sure
-          ** this code only executes once.  Because for a non-constant
-          ** expression we need to rerun this code each time.
-          */
-          if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
-            sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
-            jmpIfDynamic = -1;
-          }
-
-          /* Evaluate the expression and insert it into the temp table */
-          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
-            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
-          }else{
-            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
-            if( isRowid ){
-              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
-                                sqlite3VdbeCurrentAddr(v)+2);
-              VdbeCoverage(v);
-              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
-            }else{
-              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
-              sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
-            }
-          }
-        }
-        sqlite3ReleaseTempReg(pParse, r1);
-        sqlite3ReleaseTempReg(pParse, r2);
-      }
-      if( pKeyInfo ){
-        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
-      }
-      break;
+    /* If this routine has already been coded, then invoke it as a
+    ** subroutine. */
+    if( ExprHasProperty(pExpr, EP_Subrtn) ){
+      ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
+      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+                        pExpr->y.sub.iAddr);
+      return pExpr->iTable;
     }
 
-    case TK_EXISTS:
-    case TK_SELECT:
-    default: {
-      /* Case 3:    (SELECT ... FROM ...)
-      **     or:    EXISTS(SELECT ... FROM ...)
-      **
-      ** For a SELECT, generate code to put the values for all columns of
-      ** the first row into an array of registers and return the index of
-      ** the first register.
-      **
-      ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
-      ** into a register and return that register number.
-      **
-      ** In both cases, the query is augmented with "LIMIT 1".  Any 
-      ** preexisting limit is discarded in place of the new LIMIT 1.
-      */
-      Select *pSel;                         /* SELECT statement to encode */
-      SelectDest dest;                      /* How to deal with SELECT result */
-      int nReg;                             /* Registers to allocate */
-      Expr *pLimit;                         /* New limit expression */
+    /* Begin coding the subroutine */
+    ExprSetProperty(pExpr, EP_Subrtn);
+    pExpr->y.sub.regReturn = ++pParse->nMem;
+    pExpr->y.sub.iAddr =
+      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+    VdbeComment((v, "return address"));
 
-      testcase( pExpr->op==TK_EXISTS );
-      testcase( pExpr->op==TK_SELECT );
-      assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
-      assert( ExprHasProperty(pExpr, EP_xIsSelect) );
-
-      pSel = pExpr->x.pSelect;
-      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;
-      if( pExpr->op==TK_SELECT ){
-        dest.eDest = SRT_Mem;
-        dest.iSdst = dest.iSDParm;
-        dest.nSdst = nReg;
-        sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
-        VdbeComment((v, "Init subquery result"));
-      }else{
-        dest.eDest = SRT_Exists;
-        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
-        VdbeComment((v, "Init EXISTS result"));
-      }
-      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;
-      if( sqlite3Select(pParse, pSel, &dest) ){
-        return 0;
-      }
-      rReg = dest.iSDParm;
-      ExprSetVVAProperty(pExpr, EP_NoReduce);
-      break;
-    }
+    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
   }
-
-  if( rHasNullFlag ){
-    sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
+  
+  /* For a SELECT, generate code to put the values for all columns of
+  ** the first row into an array of registers and return the index of
+  ** the first register.
+  **
+  ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
+  ** into a register and return that register number.
+  **
+  ** In both cases, the query is augmented with "LIMIT 1".  Any 
+  ** preexisting limit is discarded in place of the new LIMIT 1.
+  */
+  ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d",
+        addrOnce?"":"CORRELATED ", pSel->selId));
+  nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+  sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+  pParse->nMem += nReg;
+  if( pExpr->op==TK_SELECT ){
+    dest.eDest = SRT_Mem;
+    dest.iSdst = dest.iSDParm;
+    dest.nSdst = nReg;
+    sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
+    VdbeComment((v, "Init subquery result"));
+  }else{
+    dest.eDest = SRT_Exists;
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
+    VdbeComment((v, "Init EXISTS result"));
   }
+  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;
+  if( sqlite3Select(pParse, pSel, &dest) ){
+    return 0;
+  }
+  pExpr->iTable = rReg = dest.iSDParm;
+  ExprSetVVAProperty(pExpr, EP_NoReduce);
+  if( addrOnce ){
+    sqlite3VdbeJumpHere(v, addrOnce);
 
-  if( jmpIfDynamic>=0 ){
-    sqlite3VdbeJumpHere(v, jmpIfDynamic);
+    /* Subroutine return */
+    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
   }
 
   return rReg;
@@ -98711,6 +100241,7 @@ static void sqlite3ExprCodeIN(
   int addrTruthOp;      /* Address of opcode that determines the IN is true */
   int destNotNull;      /* Jump here if a comparison is not true in step 6 */
   int addrTop;          /* Top of the step-6 loop */ 
+  int iTab = 0;         /* Index to use */
 
   pLeft = pExpr->pLeft;
   if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
@@ -98722,7 +100253,7 @@ static void sqlite3ExprCodeIN(
   if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
 
   /* Attempt to compute the RHS. After this step, if anything other than
-  ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable 
+  ** IN_INDEX_NOOP is returned, the table opened with cursor iTab
   ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
   ** the RHS has not yet been coded.  */
   v = pParse->pVdbe;
@@ -98730,7 +100261,8 @@ static void sqlite3ExprCodeIN(
   VdbeNoopComment((v, "begin IN expr"));
   eType = sqlite3FindInIndex(pParse, pExpr,
                              IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
-                             destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);
+                             destIfFalse==destIfNull ? 0 : &rRhsHasNull,
+                             aiMap, &iTab);
 
   assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
        || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC 
@@ -98776,7 +100308,7 @@ static void sqlite3ExprCodeIN(
   if( eType==IN_INDEX_NOOP ){
     ExprList *pList = pExpr->x.pList;
     CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-    int labelOk = sqlite3VdbeMakeLabel(v);
+    int labelOk = sqlite3VdbeMakeLabel(pParse);
     int r2, regToFree;
     int regCkNull = 0;
     int ii;
@@ -98820,7 +100352,7 @@ static void sqlite3ExprCodeIN(
   if( destIfNull==destIfFalse ){
     destStep2 = destIfFalse;
   }else{
-    destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
+    destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
   }
   for(i=0; i<nVector; i++){
     Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
@@ -98838,19 +100370,19 @@ static void sqlite3ExprCodeIN(
     /* In this case, the RHS is the ROWID of table b-tree and so we also
     ** know that the RHS is non-NULL.  Hence, we combine steps 3 and 4
     ** into a single opcode. */
-    sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
+    sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
     VdbeCoverage(v);
     addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto);  /* Return True */
   }else{
     sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
     if( destIfFalse==destIfNull ){
       /* Combine Step 3 and Step 5 into a single opcode */
-      sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
+      sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
                            rLhs, nVector); VdbeCoverage(v);
       goto sqlite3ExprCodeIN_finished;
     }
     /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
-    addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
+    addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
                                       rLhs, nVector); VdbeCoverage(v);
   }
 
@@ -98875,10 +100407,10 @@ static void sqlite3ExprCodeIN(
   ** of the RHS.
   */
   if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
-  addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+  addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
   VdbeCoverage(v);
   if( nVector>1 ){
-    destNotNull = sqlite3VdbeMakeLabel(v);
+    destNotNull = sqlite3VdbeMakeLabel(pParse);
   }else{
     /* For nVector==1, combine steps 6 and 7 by immediately returning
     ** FALSE if the first comparison is not NULL */
@@ -98890,7 +100422,7 @@ static void sqlite3ExprCodeIN(
     int r3 = sqlite3GetTempReg(pParse);
     p = sqlite3VectorFieldSubexpr(pLeft, i);
     pColl = sqlite3ExprCollSeq(pParse, p);
-    sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
+    sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
     sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
                       (void*)pColl, P4_COLLSEQ);
     VdbeCoverage(v);
@@ -98899,7 +100431,7 @@ static void sqlite3ExprCodeIN(
   sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
   if( nVector>1 ){
     sqlite3VdbeResolveLabel(v, destNotNull);
-    sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
+    sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
     VdbeCoverage(v);
 
     /* Step 7:  If we reach this point, we know that the result must
@@ -99070,7 +100602,8 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
 ** register iReg.  The caller must ensure that iReg already contains
 ** the correct value for the expression.
 */
-static void exprToRegister(Expr *p, int iReg){
+static void exprToRegister(Expr *pExpr, int iReg){
+  Expr *p = sqlite3ExprSkipCollate(pExpr);
   p->op2 = p->op;
   p->op = TK_REGISTER;
   p->iTable = iReg;
@@ -99098,7 +100631,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
 #if SQLITE_OMIT_SUBQUERY
       iResult = 0;
 #else
-      iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
+      iResult = sqlite3CodeSubselect(pParse, p);
 #endif
     }else{
       int i;
@@ -99170,7 +100703,7 @@ expr_code_doover:
         ** constant.
         */
         int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
-        int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+        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' );
@@ -99194,7 +100727,7 @@ expr_code_doover:
           iTab = pParse->iSelfTab - 1;
         }
       }
-      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+      return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
                                pExpr->iColumn, iTab, target,
                                pExpr->op2);
     }
@@ -99408,8 +100941,8 @@ expr_code_doover:
       CollSeq *pColl = 0;    /* A collating sequence */
 
 #ifndef SQLITE_OMIT_WINDOWFUNC
-      if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
-        return pExpr->pWin->regResult;
+      if( ExprHasProperty(pExpr, EP_WinFunc) ){
+        return pExpr->y.pWin->regResult;
       }
 #endif
 
@@ -99443,7 +100976,7 @@ expr_code_doover:
       ** arguments past the first non-NULL argument.
       */
       if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
-        int endCoalesce = sqlite3VdbeMakeLabel(v);
+        int endCoalesce = sqlite3VdbeMakeLabel(pParse);
         assert( nFarg>=2 );
         sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
         for(i=1; i<nFarg; i++){
@@ -99572,14 +101105,14 @@ expr_code_doover:
       if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
         sqlite3SubselectError(pParse, nCol, 1);
       }else{
-        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+        return sqlite3CodeSubselect(pParse, pExpr);
       }
       break;
     }
     case TK_SELECT_COLUMN: {
       int n;
       if( pExpr->pLeft->iTable==0 ){
-        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
+        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
       }
       assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
       if( pExpr->iTable
@@ -99591,8 +101124,8 @@ expr_code_doover:
       return pExpr->pLeft->iTable + pExpr->iColumn;
     }
     case TK_IN: {
-      int destIfFalse = sqlite3VdbeMakeLabel(v);
-      int destIfNull = sqlite3VdbeMakeLabel(v);
+      int destIfFalse = sqlite3VdbeMakeLabel(pParse);
+      int destIfNull = sqlite3VdbeMakeLabel(pParse);
       sqlite3VdbeAddOp2(v, OP_Null, 0, target);
       sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
       sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
@@ -99652,7 +101185,7 @@ expr_code_doover:
       **   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 );
@@ -99663,7 +101196,7 @@ expr_code_doover:
       sqlite3VdbeAddOp2(v, OP_Param, p1, target);
       VdbeComment((v, "r[%d]=%s.%s", target,
         (pExpr->iTable ? "new" : "old"),
-        (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
+        (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
       ));
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -99732,9 +101265,9 @@ expr_code_doover:
       pEList = pExpr->x.pList;
       aListelem = pEList->a;
       nExpr = pEList->nExpr;
-      endLabel = sqlite3VdbeMakeLabel(v);
+      endLabel = sqlite3VdbeMakeLabel(pParse);
       if( (pX = pExpr->pLeft)!=0 ){
-        tempX = *pX;
+        exprNodeCopy(&tempX, pX);
         testcase( pX->op==TK_COLUMN );
         exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
         testcase( regFree1==0 );
@@ -99755,7 +101288,7 @@ expr_code_doover:
         }else{
           pTest = aListelem[i].pExpr;
         }
-        nextCase = sqlite3VdbeMakeLabel(v);
+        nextCase = sqlite3VdbeMakeLabel(pParse);
         testcase( pTest->op==TK_COLUMN );
         sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
         testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
@@ -100055,13 +101588,12 @@ static void exprCodeBetween(
   Expr exprX;       /* The  x  subexpression */
   int regFree1 = 0; /* Temporary use register */
 
-
   memset(&compLeft, 0, sizeof(Expr));
   memset(&compRight, 0, sizeof(Expr));
   memset(&exprAnd, 0, sizeof(Expr));
 
   assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
-  exprX = *pExpr->pLeft;
+  exprNodeCopy(&exprX, pExpr->pLeft);
   exprAnd.op = TK_AND;
   exprAnd.pLeft = &compLeft;
   exprAnd.pRight = &compRight;
@@ -100123,18 +101655,23 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
   if( NEVER(pExpr==0) ) return;  /* No way this can happen */
   op = pExpr->op;
   switch( op ){
-    case TK_AND: {
-      int d2 = sqlite3VdbeMakeLabel(v);
-      testcase( jumpIfNull==0 );
-      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
-      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
-      sqlite3VdbeResolveLabel(v, d2);
-      break;
-    }
+    case TK_AND:
     case TK_OR: {
-      testcase( jumpIfNull==0 );
-      sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
-      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+      Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+      if( pAlt!=pExpr ){
+        sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
+      }else if( op==TK_AND ){
+        int d2 = sqlite3VdbeMakeLabel(pParse);
+        testcase( jumpIfNull==0 );
+        sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
+                           jumpIfNull^SQLITE_JUMPIFNULL);
+        sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+        sqlite3VdbeResolveLabel(v, d2);
+      }else{
+        testcase( jumpIfNull==0 );
+        sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+        sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+      }
       break;
     }
     case TK_NOT: {
@@ -100210,7 +101747,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case TK_IN: {
-      int destIfFalse = sqlite3VdbeMakeLabel(v);
+      int destIfFalse = sqlite3VdbeMakeLabel(pParse);
       int destIfNull = jumpIfNull ? dest : destIfFalse;
       sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
       sqlite3VdbeGoto(v, dest);
@@ -100220,9 +101757,9 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
 #endif
     default: {
     default_expr:
-      if( exprAlwaysTrue(pExpr) ){
+      if( ExprAlwaysTrue(pExpr) ){
         sqlite3VdbeGoto(v, dest);
-      }else if( exprAlwaysFalse(pExpr) ){
+      }else if( ExprAlwaysFalse(pExpr) ){
         /* No-op */
       }else{
         r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -100290,18 +101827,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
   assert( pExpr->op!=TK_GE || op==OP_Lt );
 
   switch( pExpr->op ){
-    case TK_AND: {
-      testcase( jumpIfNull==0 );
-      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
-      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
-      break;
-    }
+    case TK_AND:
     case TK_OR: {
-      int d2 = sqlite3VdbeMakeLabel(v);
-      testcase( jumpIfNull==0 );
-      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
-      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
-      sqlite3VdbeResolveLabel(v, d2);
+      Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+      if( pAlt!=pExpr ){
+        sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
+      }else if( pExpr->op==TK_AND ){
+        testcase( jumpIfNull==0 );
+        sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+        sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+      }else{
+        int d2 = sqlite3VdbeMakeLabel(pParse);
+        testcase( jumpIfNull==0 );
+        sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
+                          jumpIfNull^SQLITE_JUMPIFNULL);
+        sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+        sqlite3VdbeResolveLabel(v, d2);
+      }
       break;
     }
     case TK_NOT: {
@@ -100381,7 +101923,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
       if( jumpIfNull ){
         sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
       }else{
-        int destIfNull = sqlite3VdbeMakeLabel(v);
+        int destIfNull = sqlite3VdbeMakeLabel(pParse);
         sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
         sqlite3VdbeResolveLabel(v, destIfNull);
       }
@@ -100390,9 +101932,9 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
 #endif
     default: {
     default_expr: 
-      if( exprAlwaysFalse(pExpr) ){
+      if( ExprAlwaysFalse(pExpr) ){
         sqlite3VdbeGoto(v, dest);
-      }else if( exprAlwaysTrue(pExpr) ){
+      }else if( ExprAlwaysTrue(pExpr) ){
         /* no-op */
       }else{
         r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
@@ -100502,7 +102044,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
     }
     return 2;
   }
-  if( pA->op!=pB->op ){
+  if( pA->op!=pB->op || pA->op==TK_RAISE ){
     if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
       return 1;
     }
@@ -100514,40 +102056,44 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
   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_NULL ){
+      return 0;
     }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 ){
+    }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
       return 2;
     }
   }
   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
-  if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+  if( (combinedFlags & EP_TokenOnly)==0 ){
     if( combinedFlags & EP_xIsSelect ) 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;
-    assert( (combinedFlags & EP_Reduced)==0 );
-    if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
+    if( pA->op!=TK_STRING
+     && pA->op!=TK_TRUEFALSE
+     && (combinedFlags & EP_Reduced)==0
+    ){
       if( pA->iColumn!=pB->iColumn ) return 2;
+      if( pA->op2!=pB->op2 ) return 2;
       if( pA->iTable!=pB->iTable 
        && (pA->iTable!=iTab || NEVER(pB->iTable>=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( (pA->pWin==0)==(pB->pWin==0) );
-
-    if( pA->pWin!=0 ){
-      if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
-    }
-#endif
   }
   return 0;
 }
@@ -100592,6 +102138,76 @@ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
              iTab);
 }
 
+/*
+** Return non-zero if Expr p can only be true if pNN is not NULL.
+*/
+static int exprImpliesNotNull(
+  Parse *pParse,      /* Parsing context */
+  Expr *p,            /* The expression to be checked */
+  Expr *pNN,          /* The expression that is NOT NULL */
+  int iTab,           /* Table being evaluated */
+  int seenNot         /* True if p is an operand of NOT */
+){
+  assert( p );
+  assert( pNN );
+  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1;
+  switch( p->op ){
+    case TK_IN: {
+      if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
+      assert( ExprHasProperty(p,EP_xIsSelect)
+           || (p->x.pList!=0 && p->x.pList->nExpr>0) );
+      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+    }
+    case TK_BETWEEN: {
+      ExprList *pList = p->x.pList;
+      assert( pList!=0 );
+      assert( pList->nExpr==2 );
+      if( seenNot ) return 0;
+      if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
+       || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
+      ){
+        return 1;
+      }
+      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+    }
+    case TK_EQ:
+    case TK_NE:
+    case TK_LT:
+    case TK_LE:
+    case TK_GT:
+    case TK_GE:
+    case TK_PLUS:
+    case TK_MINUS:
+    case TK_STAR:
+    case TK_REM:
+    case TK_BITAND:
+    case TK_BITOR:
+    case TK_SLASH:
+    case TK_LSHIFT:
+    case TK_RSHIFT: 
+    case TK_CONCAT: {
+      if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
+      /* Fall thru into the next case */
+    }
+    case TK_SPAN:
+    case TK_COLLATE:
+    case TK_BITNOT:
+    case TK_UPLUS:
+    case TK_UMINUS: {
+      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+    }
+    case TK_TRUTH: {
+      if( seenNot ) return 0;
+      if( p->op2!=TK_IS ) return 0;
+      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+    }
+    case TK_NOT: {
+      return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
+    }
+  }
+  return 0;
+}
+
 /*
 ** Return true if we can prove the pE2 will always be true if pE1 is
 ** true.  Return false if we cannot complete the proof or if pE2 might
@@ -100627,10 +102243,10 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i
   ){
     return 1;
   }
-  if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
-    Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
-    testcase( pX!=pE1->pLeft );
-    if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
+  if( pE2->op==TK_NOTNULL
+   && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
+  ){
+    return 1;
   }
   return 0;
 }
@@ -100652,6 +102268,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
     case TK_ISNOT:
     case TK_NOT:
     case TK_ISNULL:
+    case TK_NOTNULL:
     case TK_IS:
     case TK_OR:
     case TK_CASE:
@@ -100660,6 +102277,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
       testcase( pExpr->op==TK_ISNOT );
       testcase( pExpr->op==TK_NOT );
       testcase( pExpr->op==TK_ISNULL );
+      testcase( pExpr->op==TK_NOTNULL );
       testcase( pExpr->op==TK_IS );
       testcase( pExpr->op==TK_OR );
       testcase( pExpr->op==TK_CASE );
@@ -100688,8 +102306,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
       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;
       }
@@ -100722,6 +102340,17 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
 */
 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
   Walker w;
+  p = sqlite3ExprSkipCollate(p);
+  while( p ){
+    if( p->op==TK_NOTNULL ){
+      p = p->pLeft;
+    }else if( p->op==TK_AND ){
+      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
+      p = p->pRight;
+    }else{
+      break;
+    }
+  }
   w.xExprCallback = impliesNotNullRow;
   w.xSelectCallback = 0;
   w.xSelectCallback2 = 0;
@@ -100920,7 +102549,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
              && (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;
@@ -101033,6 +102662,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
   w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
   w.walkerDepth = 0;
   w.u.pNC = pNC;
+  w.pParse = 0;
   assert( pNC->pSrcList!=0 );
   sqlite3WalkExpr(&w, pExpr);
 }
@@ -101164,9 +102794,16 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
 **
 ** 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);
+static int isAlterableTable(Parse *pParse, Table *pTab){
+  if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) 
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+   || ( (pTab->tabFlags & TF_Shadow) 
+     && (pParse->db->flags & SQLITE_Defensive)
+     && pParse->db->nVdbeExec==0
+   )
+#endif
+  ){
+    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
     return 1;
   }
   return 0;
@@ -101183,7 +102820,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
   sqlite3NestedParse(pParse, 
       "SELECT 1 "
       "FROM \"%w\".%s "
-      "WHERE name NOT LIKE 'sqlite_%%'"
+      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
       " AND sql NOT LIKE 'create virtual%%'"
       " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
       zDb, MASTER_NAME, 
@@ -101194,7 +102831,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
     sqlite3NestedParse(pParse, 
         "SELECT 1 "
         "FROM temp.%s "
-        "WHERE name NOT LIKE 'sqlite_%%'"
+        "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
         " AND sql NOT LIKE 'create virtual%%'"
         " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
         MASTER_NAME, zDb 
@@ -101262,7 +102899,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
   /* Make sure it is not a system table being altered, or a reserved name
   ** that the table is being renamed to.
   */
-  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
     goto exit_rename_table;
   }
   if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
@@ -101295,15 +102932,15 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
   }
 #endif
 
-  /* Begin a transaction for database iDb. 
-  ** Then modify the schema cookie (since the ALTER TABLE modifies the
-  ** schema). Open a statement transaction if the table is a virtual
-  ** table.
-  */
+  /* Begin a transaction for database iDb. Then modify the schema cookie
+  ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(),
+  ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the 
+  ** nested SQL may raise an exception.  */
   v = sqlite3GetVdbe(pParse);
   if( v==0 ){
     goto exit_rename_table;
   }
+  sqlite3MayAbort(pParse);
 
   /* figure out how many UTF-8 characters are in zName */
   zTabName = pTab->zName;
@@ -101315,7 +102952,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
       "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_%%'"
+      "AND   name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
       , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
   );
 
@@ -101326,7 +102963,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
           "tbl_name = %Q, "
           "name = CASE "
             "WHEN type='table' THEN %Q "
-            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
+            "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
+            "     AND type='index' THEN "
              "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
             "ELSE name END "
       "WHERE tbl_name=%Q COLLATE nocase AND "
@@ -101372,7 +103010,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
     int i = ++pParse->nMem;
     sqlite3VdbeLoadString(v, i, zName);
     sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
-    sqlite3MayAbort(pParse);
   }
 #endif
 
@@ -101560,7 +103197,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
     sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
     goto exit_begin_add_column;
   }
-  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
     goto exit_begin_add_column;
   }
 
@@ -101662,7 +103299,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
   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!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
   if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
 
   /* Which schema holds the table to be altered */  
@@ -101693,6 +103330,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
   ** uses the sqlite_rename_column() SQL function to compute the new
   ** CREATE statement text for the sqlite_master table.
   */
+  sqlite3MayAbort(pParse);
   zNew = sqlite3NameFromToken(db, pNew);
   if( !zNew ) goto exit_rename_column;
   assert( pNew->n>0 );
@@ -101700,7 +103338,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
   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)"
+      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
+      " AND (type != 'index' OR tbl_name = %Q)"
       " AND sql NOT LIKE 'create virtual%%'",
       zDb, MASTER_NAME, 
       zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
@@ -101803,10 +103442,16 @@ static void renameTokenCheckAll(Parse *pParse, void *pPtr){
 #endif
 
 /*
-** Add a new RenameToken object mapping parse tree element pPtr into
-** token *pToken to the Parse object currently under construction.
+** Remember that the parser tree element pPtr was created using
+** the token pToken.
 **
-** Return a copy of pPtr.
+** 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;
@@ -101848,6 +103493,29 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
   return WRC_Continue;
 }
 
+/*
+** Walker callback used by sqlite3RenameExprUnmap().
+*/
+static int renameUnmapSelectCb(Walker *pWalker, Select *p){
+  Parse *pParse = pWalker->pParse;
+  int i;
+  if( ALWAYS(p->pEList) ){
+    ExprList *pList = p->pEList;
+    for(i=0; i<pList->nExpr; i++){
+      if( pList->a[i].zName ){
+        sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName);
+      }
+    }
+  }
+  if( ALWAYS(p->pSrc) ){  /* Every Select as a SrcList, even if it is empty */
+    SrcList *pSrc = p->pSrc;
+    for(i=0; i<pSrc->nSrc; i++){
+      sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
+    }
+  }
+  return WRC_Continue;
+}
+
 /*
 ** Remove all nodes that are part of expression pExpr from the rename list.
 */
@@ -101856,6 +103524,7 @@ SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
   memset(&sWalker, 0, sizeof(Walker));
   sWalker.pParse = pParse;
   sWalker.xExprCallback = renameUnmapExprCb;
+  sWalker.xSelectCallback = renameUnmapSelectCb;
   sqlite3WalkExpr(&sWalker, pExpr);
 }
 
@@ -101910,14 +103579,31 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
   }
 }
 
+/*
+** Iterate through the Select objects that are part of WITH clauses attached
+** to select statement pSelect.
+*/
+static void renameWalkWith(Walker *pWalker, Select *pSelect){
+  if( pSelect->pWith ){
+    int i;
+    for(i=0; i<pSelect->pWith->nCte; i++){
+      Select *p = pSelect->pWith->a[i].pSelect;
+      NameContext sNC;
+      memset(&sNC, 0, sizeof(sNC));
+      sNC.pParse = pWalker->pParse;
+      sqlite3SelectPrep(sNC.pParse, p, &sNC);
+      sqlite3WalkSelect(pWalker, p);
+    }
+  }
+}
+
 /*
 ** 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);
+  renameWalkWith(pWalker, p);
   return WRC_Continue;
 }
 
@@ -101939,7 +103625,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }else if( pExpr->op==TK_COLUMN 
    && pExpr->iColumn==p->iCol 
-   && p->pTab==pExpr->pTab
+   && p->pTab==pExpr->y.pTab
   ){
     renameTokenFind(pWalker->pParse, p, (void*)pExpr);
   }
@@ -102067,7 +103753,6 @@ static int renameParseSql(
   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 
@@ -102197,9 +103882,14 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
       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( pNew->pWhen ){
+  if( rc==SQLITE_OK && pNew->pWhen ){
     rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
   }
 
@@ -102245,6 +103935,7 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
           }
           sNC.ncFlags = 0;
         }
+        sNC.pSrcList = 0;
       }
     }
   }
@@ -102282,11 +103973,15 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
 */
 static void renameParseCleanup(Parse *pParse){
   sqlite3 *db = pParse->db;
+  Index *pIdx;
   if( pParse->pVdbe ){
     sqlite3VdbeFinalize(pParse->pVdbe);
   }
   sqlite3DeleteTable(db, pParse->pNewTable);
-  if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
+  while( (pIdx = pParse->pNewIndex)!=0 ){
+    pParse->pNewIndex = pIdx->pNext;
+    sqlite3FreeIndex(db, pIdx);
+  }
   sqlite3DeleteTrigger(db, pParse->pNewTrigger);
   sqlite3DbFree(db, pParse->zErrMsg);
   renameTokenFree(db, pParse->pRename);
@@ -102313,15 +104008,8 @@ static void renameParseCleanup(Parse *pParse){
 ** into zNew.  The name should be quoted if bQuote is true.
 **
 ** This function is used internally by the ALTER TABLE RENAME COLUMN command.
-** Though accessible to application code, it is not intended for use by
-** applications.  The existance of this function, and the way it works,
-** is subject to change without notice.
-**
-** If any of the parameters are out-of-bounds, then simply return NULL.
-** An out-of-bounds parameter can only occur when the application calls
-** this function directly.  The parameters will always be well-formed when
-** this routine is invoked by the bytecode for a legitimate ALTER TABLE
-** statement.
+** 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,
@@ -102404,6 +104092,9 @@ static void renameColumnFunc(
         for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
           sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
         }
+        for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
+          sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
+        }
       }
 
       for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
@@ -102477,8 +104168,8 @@ renameColumnFunc_done:
 */
 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
   RenameCtx *p = pWalker->u.pRename;
-  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
-    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+  if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
+    renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
   }
   return WRC_Continue;
 }
@@ -102490,12 +104181,17 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
   int i;
   RenameCtx *p = pWalker->u.pRename;
   SrcList *pSrc = pSelect->pSrc;
+  if( pSrc==0 ){
+    assert( pWalker->pParse->db->mallocFailed );
+    return WRC_Abort;
+  }
   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);
     }
   }
+  renameWalkWith(pWalker, pSelect);
 
   return WRC_Continue;
 }
@@ -102575,7 +104271,7 @@ static void renameTableFunc(
         }else{
           /* Modify any FK definitions to point to the new table. */
 #ifndef SQLITE_OMIT_FOREIGN_KEY
-          if( db->flags & SQLITE_ForeignKeys ){
+          if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
             FKey *pFKey;
             for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
               if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
@@ -102729,9 +104425,9 @@ static void renameTableTest(
 */
 SQLITE_PRIVATE void sqlite3AlterFunctions(void){
   static FuncDef aAlterTableFuncs[] = {
-    FUNCTION(sqlite_rename_column,  9, 0, 0, renameColumnFunc),
-    FUNCTION(sqlite_rename_table,  7, 0, 0, renameTableFunc),
-    FUNCTION(sqlite_rename_test,  5, 0, 0, renameTableTest),
+    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));
 }
@@ -103897,7 +105593,7 @@ static void analyzeOneTable(
     addrNextRow = sqlite3VdbeCurrentAddr(v);
 
     if( nColTest>0 ){
-      int endDistinctTest = sqlite3VdbeMakeLabel(v);
+      int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
       int *aGotoChng;               /* Array of jump instruction addresses */
       aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
       if( aGotoChng==0 ) continue;
@@ -104780,7 +106476,7 @@ static void attachFunc(
     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
     **
@@ -104835,8 +106531,8 @@ static void attachFunc(
     assert( pVfs );
     flags |= SQLITE_OPEN_MAIN_DB;
     rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
-    sqlite3_free( zPath );
     db->nDb++;
+    pNew->zDbSName = sqlite3DbStrDup(db, zName);
   }
   db->noSharedCache = 0;
   if( rc==SQLITE_CONSTRAINT ){
@@ -104864,7 +106560,6 @@ static void attachFunc(
     sqlite3BtreeLeave(pNew->pBt);
   }
   pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
-  if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
   if( rc==SQLITE_OK && pNew->zDbSName==0 ){
     rc = SQLITE_NOMEM_BKPT;
   }
@@ -104892,15 +106587,19 @@ static void attachFunc(
         break;
 
       case SQLITE_NULL:
-        /* No key specified.  Use the key from the main database */
-        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
-        if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
-          rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+        /* No key specified.  Use the key from URI filename, or if none,
+        ** use the key from the main database. */
+        if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
+          sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+          if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+            rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+          }
         }
         break;
     }
   }
 #endif
+  sqlite3_free( zPath );
 
   /* 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 
@@ -104911,12 +106610,14 @@ static void attachFunc(
     sqlite3BtreeEnterAll(db);
     db->init.iDb = 0;
     db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
-    rc = sqlite3Init(db, &zErrDyn);
+    if( !REOPEN_AS_MEMDB(db) ){
+      rc = sqlite3Init(db, &zErrDyn);
+    }
     sqlite3BtreeLeaveAll(db);
     assert( zErrDyn==0 || rc!=SQLITE_OK );
   }
 #ifdef SQLITE_USER_AUTHENTICATION
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){
     u8 newAuth = 0;
     rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth);
     if( newAuth<db->auth.authLevel ){
@@ -105460,6 +107161,7 @@ SQLITE_PRIVATE void sqlite3AuthRead(
   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 ){
@@ -105516,6 +107218,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
   /* Don't do any authorization checks if the database is initialising
   ** or if the parser is being invoked from within sqlite3_declare_vtab.
   */
+  assert( !IN_RENAME_OBJECT || db->xAuth==0 );
   if( db->init.busy || IN_SPECIAL_PARSE ){
     return SQLITE_OK;
   }
@@ -105810,7 +107513,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
   if( v && pParse->nErr==0 && !db->mallocFailed ){
     /* A minimum of one cursor is required if autoincrement is used
     *  See ticket [a696379c1f08866] */
-    if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+    assert( pParse->pAinc==0 || pParse->nTab>0 );
     sqlite3VdbeMakeReady(v, pParse);
     pParse->rc = SQLITE_DONE;
   }else{
@@ -105843,7 +107546,12 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   zSql = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
   if( zSql==0 ){
-    return;   /* A malloc must have failed */
+    /* This can result either from an OOM or because the formatted string
+    ** exceeds SQLITE_LIMIT_LENGTH.  In the latter case, we need to set
+    ** an error */
+    if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG;
+    pParse->nErr++;
+    return;
   }
   pParse->nested++;
   memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
@@ -105937,12 +107645,11 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
 
   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(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. */
+    /* 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. */
+    if( pParse->disableVtab==0 ){
       Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
       if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
         pMod = sqlite3PragmaVtabRegister(db, zName);
@@ -105952,13 +107659,18 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
       }
     }
 #endif
-    if( (flags & LOCATE_NOERR)==0 ){
-      if( zDbase ){
-        sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
-      }else{
-        sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
-      }
-      pParse->checkSchema = 1;
+    if( flags & LOCATE_NOERR ) return 0;
+    pParse->checkSchema = 1;
+  }else if( IsVirtual(p) && pParse->disableVtab ){
+    p = 0;
+  }
+
+  if( p==0 ){
+    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
+    if( zDbase ){
+      sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
+    }else{
+      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
     }
   }
 
@@ -106129,17 +107841,22 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
 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|DBFLAG_SchemaKnownOk);
   sqlite3VtabUnlockList(db);
   sqlite3BtreeLeaveAll(db);
-  sqlite3CollapseDatabaseArray(db);
+  if( db->nSchemaLock==0 ){
+    sqlite3CollapseDatabaseArray(db);
+  }
 }
 
 /*
@@ -106187,10 +107904,14 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
 
 #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. */
+  ** prior to doing any free() operations. Since schema Tables do not use
+  ** lookaside, this number should not change. 
+  **
+  ** If malloc has already failed, it may be that it failed while allocating
+  ** a Table object that was going to be marked ephemeral. So do not check
+  ** that no lookaside memory is used in this case either. */
   int nLookaside = 0;
-  if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
+  if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
     nLookaside = sqlite3LookasideUsed(db, 0);
   }
 #endif
@@ -106374,6 +108095,20 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
   return iDb;
 }
 
+/*
+** 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
@@ -106383,7 +108118,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
 */
 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;
@@ -106884,7 +108619,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(
 ** accept it.  This routine does the necessary conversion.  It converts
 ** the expression given in its argument from a TK_STRING into a TK_ID
 ** if the expression is just a TK_STRING with an optional COLLATE clause.
-** If the epxression is anything other than TK_STRING, the expression is
+** If the expression is anything other than TK_STRING, the expression is
 ** unchanged.
 */
 static void sqlite3StringToId(Expr *p){
@@ -106960,7 +108695,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
    && sortOrder!=SQLITE_SO_DESC
   ){
     if( IN_RENAME_OBJECT && pList ){
-      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
+      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
+      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
     }
     pTab->iPKey = iCol;
     pTab->keyConf = (u8)onError;
@@ -107280,10 +109016,51 @@ static void estimateIndexWidth(Index *pIdx){
   pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
 }
 
-/* Return true if value x is found any of the first nCol entries of aiCol[]
+/* Return true if column number x is any of the first nCol entries of aiCol[].
+** This is used to determine if the column number x appears in any of the
+** first nCol entries of an index.
 */
 static int hasColumn(const i16 *aiCol, int nCol, int x){
-  while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+  while( nCol-- > 0 ){
+    assert( aiCol[0]>=0 );
+    if( x==*(aiCol++) ){
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/*
+** Return true if any of the first nKey entries of index pIdx exactly
+** match the iCol-th entry of pPk.  pPk is always a WITHOUT ROWID
+** PRIMARY KEY index.  pIdx is an index on the same table.  pIdx may
+** or may not be the same index as pPk.
+**
+** The first nKey entries of pIdx are guaranteed to be ordinary columns,
+** not a rowid or expression.
+**
+** This routine differs from hasColumn() in that both the column and the
+** collating sequence must match for this routine, but for hasColumn() only
+** the column name must match.
+*/
+static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
+  int i, j;
+  assert( nKey<=pIdx->nColumn );
+  assert( iCol<MAX(pPk->nColumn,pPk->nKeyCol) );
+  assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
+  assert( pPk->pTable->tabFlags & TF_WithoutRowid );
+  assert( pPk->pTable==pIdx->pTable );
+  testcase( pPk==pIdx );
+  j = pPk->aiColumn[iCol];
+  assert( j!=XN_ROWID && j!=XN_EXPR );
+  for(i=0; i<nKey; i++){
+    assert( pIdx->aiColumn[i]>=0 || j>=0 );
+    if( pIdx->aiColumn[i]==j 
+     && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
+    ){
+      return 1;
+    }
+  }
   return 0;
 }
 
@@ -107372,15 +109149,19 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     pList = sqlite3ExprListAppend(pParse, 0, 
                   sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
     if( pList==0 ) return;
+    if( IN_RENAME_OBJECT ){
+      sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
+    }
     pList->a[0].sortOrder = pParse->iPkSortOrder;
     assert( pParse->pNewTable==pTab );
+    pTab->iPKey = -1;
     sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
                        SQLITE_IDXTYPE_PRIMARYKEY);
     if( db->mallocFailed || pParse->nErr ) return;
     pPk = sqlite3PrimaryKeyIndex(pTab);
-    pTab->iPKey = -1;
   }else{
     pPk = sqlite3PrimaryKeyIndex(pTab);
+    assert( pPk!=0 );
 
     /*
     ** Remove all redundant columns from the PRIMARY KEY.  For example, change
@@ -107388,9 +109169,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     ** code assumes the PRIMARY KEY contains no repeated columns.
     */
     for(i=j=1; i<pPk->nKeyCol; i++){
-      if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
+      if( isDupColumn(pPk, j, pPk, i) ){
         pPk->nColumn--;
       }else{
+        testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
         pPk->aiColumn[j++] = pPk->aiColumn[i];
       }
     }
@@ -107420,7 +109202,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     int n;
     if( IsPrimaryKeyIndex(pIdx) ) continue;
     for(i=n=0; i<nPk; i++){
-      if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+      if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+        testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
+        n++;
+      }
     }
     if( n==0 ){
       /* This index is a superset of the primary key */
@@ -107429,9 +109214,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     }
     if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
     for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
-      if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+      if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+        testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
         pIdx->aiColumn[j] = pPk->aiColumn[i];
         pIdx->azColl[j] = pPk->azColl[i];
+        if( pPk->aSortOrder[i] ){
+          /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
+          pIdx->bAscKeyBug = 1;
+        }
         j++;
       }
     }
@@ -107459,6 +109249,36 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
   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.
@@ -107498,6 +109318,10 @@ SQLITE_PRIVATE void sqlite3EndTable(
   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
@@ -107516,6 +109340,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
     if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
   }
 
+  assert( (p->tabFlags & TF_HasPrimaryKey)==0
+       || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 );
+  assert( (p->tabFlags & TF_HasPrimaryKey)!=0
+       || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) );
+
   /* Special processing for WITHOUT ROWID Tables */
   if( tabOpts & TF_WithoutRowid ){
     if( (p->tabFlags & TF_Autoincrement) ){
@@ -108005,7 +109834,7 @@ SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iT
 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
@@ -108164,6 +109993,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
   */
   if( IsVirtual(pTab) ){
     sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
+    sqlite3MayAbort(pParse);
   }
   sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
   sqlite3ChangeCookie(pParse, iDb);
@@ -108510,10 +110340,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
     sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
     sqlite3VdbeJumpHere(v, j2);
   }else{
+    /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
+    ** abort. The exception is if one of the indexed expressions contains a
+    ** user function that throws an exception when it is evaluated. But the
+    ** overhead of adding a statement journal to a CREATE INDEX statement is
+    ** very small (since most of the pages written do not contain content that
+    ** needs to be restored if the statement aborts), so we call 
+    ** sqlite3MayAbort() for all CREATE INDEX statements.  */
+    sqlite3MayAbort(pParse);
     addr2 = sqlite3VdbeCurrentAddr(v);
   }
   sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
-  sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+  if( !pIndex->bAscKeyBug ){
+    /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
+    ** faster by avoiding unnecessary seeks.  But the optimization does
+    ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
+    ** with DESC primary keys, since those indexes have there keys in
+    ** a different order from the main table.
+    ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
+    */
+    sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+  }
   sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
   sqlite3ReleaseTempReg(pParse, regRecord);
@@ -108668,13 +110515,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
   assert( pParse->nErr==0 );
   if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
        && db->init.busy==0
+       && pTblName!=0
 #if SQLITE_USER_AUTHENTICATION
        && sqlite3UserAuthTable(pTab->zName)==0
 #endif
 #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;
@@ -108778,6 +110625,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
     sqlite3ExprListSetSortOrder(pList, sortOrder);
   }else{
     sqlite3ExprListCheckLength(pParse, pList, "index");
+    if( pParse->nErr ) goto exit_create_index;
   }
 
   /* Figure out how many bytes of space are required to store explicitly
@@ -108796,6 +110644,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
   */
   nName = sqlite3Strlen30(zName);
   nExtraCol = pPk ? pPk->nKeyCol : 1;
+  assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ );
   pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
                                       nName + nExtra + 1, &zExtra);
   if( db->mallocFailed ){
@@ -108903,9 +110752,10 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
     for(j=0; j<pPk->nKeyCol; j++){
       int x = pPk->aiColumn[j];
       assert( x>=0 );
-      if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+      if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
         pIndex->nColumn--; 
       }else{
+        testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
         pIndex->aiColumn[i] = x;
         pIndex->azColl[i] = pPk->azColl[j];
         pIndex->aSortOrder[i] = pPk->aSortOrder[j];
@@ -108992,6 +110842,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
           }
         }
         if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
+        if( IN_RENAME_OBJECT ){
+          pIndex->pNext = pParse->pNewIndex;
+          pParse->pNewIndex = pIndex;
+          pIndex = 0;
+        }
         goto exit_create_index;
       }
     }
@@ -109007,6 +110862,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
       Index *p;
       assert( !IN_SPECIAL_PARSE );
       assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+      if( pTblName!=0 ){
+        pIndex->tnum = db->init.newTnum;
+        if( sqlite3IndexHasDuplicateRootPage(pIndex) ){
+          sqlite3ErrorMsg(pParse, "invalid rootpage");
+          pParse->rc = SQLITE_CORRUPT_BKPT;
+          goto exit_create_index;
+        }
+      }
       p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
           pIndex->zName, pIndex);
       if( p ){
@@ -109015,9 +110878,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
         goto exit_create_index;
       }
       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
@@ -109269,9 +111129,9 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate(
   int *pIdx         /* Write the index of a new slot here */
 ){
   char *z;
-  int n = *pnEntry;
+  sqlite3_int64 n = *pIdx = *pnEntry;
   if( (n & (n-1))==0 ){
-    int sz = (n==0) ? 1 : 2*n;
+    sqlite3_int64 sz = (n==0) ? 1 : 2*n;
     void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
     if( pNew==0 ){
       *pIdx = -1;
@@ -109281,7 +111141,6 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate(
   }
   z = (char*)pArray;
   memset(&z[n * szEntry], 0, szEntry);
-  *pIdx = n;
   ++*pnEntry;
   return pArray;
 }
@@ -109343,6 +111202,18 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
   return -1;
 }
 
+/*
+** Maximum size of a SrcList object.
+** The SrcList object is used to represent the FROM clause of a
+** SELECT statement, and the query planner cannot deal with more
+** than 64 tables in a join.  So any value larger than 64 here
+** is sufficient for most uses.  Smaller values, like say 10, are
+** appropriate for small and memory-limited applications.
+*/
+#ifndef SQLITE_MAX_SRCLIST
+# define SQLITE_MAX_SRCLIST 200
+#endif
+
 /*
 ** Expand the space allocated for the given SrcList object by
 ** creating nExtra new slots beginning at iStart.  iStart is zero based.
@@ -109359,11 +111230,12 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
 ** the iStart value would be 0.  The result then would
 ** be: nil, nil, nil, A, B.
 **
-** If a memory allocation fails the SrcList is unchanged.  The
-** db->mallocFailed flag will be set to true.
+** If a memory allocation fails or the SrcList becomes too large, leave
+** the original SrcList unchanged, return NULL, and leave an error message
+** in pParse.
 */
 SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
-  sqlite3 *db,       /* Database connection to notify of OOM errors */
+  Parse *pParse,     /* Parsing context into which errors are reported */
   SrcList *pSrc,     /* The SrcList to be enlarged */
   int nExtra,        /* Number of new slots to add to pSrc->a[] */
   int iStart         /* Index in pSrc->a[] of first new slot */
@@ -109379,17 +111251,23 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
   /* Allocate additional space if needed */
   if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
     SrcList *pNew;
-    int nAlloc = pSrc->nSrc*2+nExtra;
-    int nGot;
+    sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra;
+    sqlite3 *db = pParse->db;
+
+    if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){
+      sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d",
+                      SQLITE_MAX_SRCLIST);
+      return 0;
+    }
+    if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST;
     pNew = sqlite3DbRealloc(db, pSrc,
                sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
     if( pNew==0 ){
       assert( db->mallocFailed );
-      return pSrc;
+      return 0;
     }
     pSrc = pNew;
-    nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
-    pSrc->nAlloc = nGot;
+    pSrc->nAlloc = nAlloc;
   }
 
   /* Move existing slots that come after the newly inserted slots
@@ -109414,7 +111292,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
 ** Append a new table name to the given SrcList.  Create a new SrcList if
 ** need be.  A new entry is created in the SrcList even if pTable is NULL.
 **
-** A SrcList is returned, or NULL if there is an OOM error.  The returned
+** A SrcList is returned, or NULL if there is an OOM error or if the
+** SrcList grows to large.  The returned
 ** SrcList might be the same as the SrcList that was input or it might be
 ** a new one.  If an OOM error does occurs, then the prior value of pList
 ** that is input to this routine is automatically freed.
@@ -109445,27 +111324,32 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
 ** before being added to the SrcList.
 */
 SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
-  sqlite3 *db,        /* Connection to notify of malloc failures */
+  Parse *pParse,      /* Parsing context, in which errors are reported */
   SrcList *pList,     /* Append to this SrcList. NULL creates a new SrcList */
   Token *pTable,      /* Table to append */
   Token *pDatabase    /* Database of the table */
 ){
   struct SrcList_item *pItem;
+  sqlite3 *db;
   assert( pDatabase==0 || pTable!=0 );  /* Cannot have C without B */
-  assert( db!=0 );
+  assert( pParse!=0 );
+  assert( pParse->db!=0 );
+  db = pParse->db;
   if( pList==0 ){
-    pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
+    pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );
     if( pList==0 ) return 0;
     pList->nAlloc = 1;
     pList->nSrc = 1;
     memset(&pList->a[0], 0, sizeof(pList->a[0]));
     pList->a[0].iCursor = -1;
   }else{
-    pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
-  }
-  if( db->mallocFailed ){
-    sqlite3SrcListDelete(db, pList);
-    return 0;
+    SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc);
+    if( pNew==0 ){
+      sqlite3SrcListDelete(db, pList);
+      return 0;
+    }else{
+      pList = pNew;
+    }
   }
   pItem = &pList->a[pList->nSrc-1];
   if( pDatabase && pDatabase->z==0 ){
@@ -109554,7 +111438,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
     );
     goto append_from_error;
   }
-  p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
+  p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
   if( p==0 ){
     goto append_from_error;
   }
@@ -109874,7 +111758,8 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
   StrAccum errMsg;
   Table *pTab = pIdx->pTable;
 
-  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 
+                      pParse->db->aLimit[SQLITE_LIMIT_LENGTH]);
   if( pIdx->aColExpr ){
     sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
   }else{
@@ -109943,13 +111828,15 @@ static int collationMatch(const char *zColl, Index *pIndex){
 */
 #ifndef SQLITE_OMIT_REINDEX
 static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
-  Index *pIndex;              /* An index associated with pTab */
+  if( !IsVirtual(pTab) ){
+    Index *pIndex;              /* An index associated with pTab */
 
-  for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
-    if( zColl==0 || collationMatch(zColl, pIndex) ){
-      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
-      sqlite3BeginWriteOperation(pParse, 0, iDb);
-      sqlite3RefillIndex(pParse, pIndex, -1);
+    for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
+      if( zColl==0 || collationMatch(zColl, pIndex) ){
+        int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+        sqlite3BeginWriteOperation(pParse, 0, iDb);
+        sqlite3RefillIndex(pParse, pIndex, -1);
+      }
     }
   }
 }
@@ -110121,7 +112008,7 @@ SQLITE_PRIVATE With *sqlite3WithAdd(
   }
 
   if( pWith ){
-    int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
+    sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
     pNew = sqlite3DbRealloc(db, pWith, nByte);
   }else{
     pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
@@ -110448,7 +112335,7 @@ static int matchQuality(
 ** Search a FuncDefHash for a function with the given name.  Return
 ** a pointer to the matching FuncDef if found, or 0 if there is no match.
 */
-static FuncDef *functionSearch(
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(
   int h,               /* Hash of the name */
   const char *zFunc    /* Name of function */
 ){
@@ -110473,9 +112360,9 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
     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);
+    pOther = sqlite3FunctionSearch(h, zName);
     if( pOther ){
       assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
       aDef[i].pNext = pOther->pNext;
@@ -110552,8 +112439,8 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
   */ 
   if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
     bestScore = 0;
-    h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
-    p = functionSearch(h, zName);
+    h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
+    p = sqlite3FunctionSearch(h, zName);
     while( p ){
       int score = matchQuality(p, nArg, enc);
       if( score>bestScore ){
@@ -110700,32 +112587,49 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
   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
 ** 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);
@@ -110756,7 +112660,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
   sqlite3 *db = pParse->db;
   int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
   pWhere = sqlite3ExprDup(db, pWhere, 0);
-  pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+  pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
   if( pFrom ){
     assert( pFrom->nSrc==1 );
     pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
@@ -111156,7 +113060,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
     /* If this DELETE cannot use the ONEPASS strategy, this is the 
     ** end of the WHERE loop */
     if( eOnePass!=ONEPASS_OFF ){
-      addrBypass = sqlite3VdbeMakeLabel(v);
+      addrBypass = sqlite3VdbeMakeLabel(pParse);
     }else{
       sqlite3WhereEnd(pWInfo);
     }
@@ -111345,7 +113249,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
   /* Seek cursor iCur to the row to delete. If this row no longer exists 
   ** (this can happen if a trigger program has already deleted it), do
   ** not attempt to delete it or fire any DELETE triggers.  */
-  iLabel = sqlite3VdbeMakeLabel(v);
+  iLabel = sqlite3VdbeMakeLabel(pParse);
   opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
   if( eMode==ONEPASS_OFF ){
     sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
@@ -111551,7 +113455,7 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
 
   if( piPartIdxLabel ){
     if( pIdx->pPartIdxWhere ){
-      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+      *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
       pParse->iSelfTab = iDataCur + 1;
       sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                             SQLITE_JUMPIFNULL);
@@ -111622,6 +113526,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
 /* #include "sqliteInt.h" */
 /* #include <stdlib.h> */
 /* #include <assert.h> */
+/* #include <math.h> */
 /* #include "vdbeInt.h" */
 
 /*
@@ -111807,6 +113712,7 @@ static void instrFunc(
   int typeHaystack, typeNeedle;
   int N = 1;
   int isText;
+  unsigned char firstChar;
 
   UNUSED_PARAMETER(argc);
   typeHaystack = sqlite3_value_type(argv[0]);
@@ -111825,7 +113731,10 @@ static void instrFunc(
       isText = 1;
     }
     if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
-    while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+    firstChar = zNeedle[0];
+    while( nNeedle<=nHaystack
+       && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
+    ){
       N++;
       do{
         nHaystack--;
@@ -111988,10 +113897,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   ** handle the rounding directly,
   ** otherwise use printf.
   */
-  if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
-    r = (double)((sqlite_int64)(r+0.5));
-  }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
-    r = -(double)((sqlite_int64)((-r)+0.5));
+  if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
+    /* The value has no fractional part so there is nothing to round */
+  }else if( n==0 ){  
+    r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
   }else{
     zBuf = sqlite3_mprintf("%.*f",n,r);
     if( zBuf==0 ){
@@ -112116,11 +114025,11 @@ static void randomBlob(
   int argc,
   sqlite3_value **argv
 ){
-  int n;
+  sqlite3_int64 n;
   unsigned char *p;
   assert( argc==1 );
   UNUSED_PARAMETER(argc);
-  n = sqlite3_value_int(argv[0]);
+  n = sqlite3_value_int64(argv[0]);
   if( n<1 ){
     n = 1;
   }
@@ -112445,8 +114354,6 @@ static void likeFunc(
     return;
   }
 #endif
-  zB = sqlite3_value_text(argv[0]);
-  zA = sqlite3_value_text(argv[1]);
 
   /* Limit the length of the LIKE or GLOB pattern to avoid problems
   ** of deep recursion and N*N behavior in patternCompare().
@@ -112458,8 +114365,6 @@ static void likeFunc(
     sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
     return;
   }
-  assert( zB==sqlite3_value_text(argv[0]) );  /* Encoding did not change */
-
   if( argc==3 ){
     /* The escape character string must consist of a single UTF-8 character.
     ** Otherwise, return an error.
@@ -112475,6 +114380,8 @@ static void likeFunc(
   }else{
     escape = pInfo->matchSet;
   }
+  zB = sqlite3_value_text(argv[0]);
+  zA = sqlite3_value_text(argv[1]);
   if( zA && zB ){
 #ifdef SQLITE_TEST
     sqlite3_like_count++;
@@ -113400,35 +115307,24 @@ SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
 }
 
 /*
-** Set the LIKEOPT flag on the 2-argument function with the given name.
-*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
-  FuncDef *pDef;
-  pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
-  if( ALWAYS(pDef) ){
-    pDef->funcFlags |= flagVal;
-  }
-}
-
-/*
-** Register the built-in LIKE and GLOB functions.  The caseSensitive
+** Re-register the built-in LIKE functions.  The caseSensitive
 ** parameter determines whether or not the LIKE operator is case
-** sensitive.  GLOB is always case sensitive.
+** sensitive.
 */
 SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
   struct compareInfo *pInfo;
+  int flags;
   if( caseSensitive ){
     pInfo = (struct compareInfo*)&likeInfoAlt;
+    flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
   }else{
     pInfo = (struct compareInfo*)&likeInfoNorm;
+    flags = SQLITE_FUNC_LIKE;
   }
   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, 0, 0);
-  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
-  setLikeOptFlag(db, "like", 
-      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+  sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
+  sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
 }
 
 /*
@@ -113956,7 +115852,7 @@ static void fkLookupParent(
   int i;                                    /* Iterator variable */
   Vdbe *v = sqlite3GetVdbe(pParse);         /* Vdbe to add code to */
   int iCur = pParse->nTab - 1;              /* Cursor number to use */
-  int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */
+  int iOk = sqlite3VdbeMakeLabel(pParse);   /* jump here if parent key found */
 
   sqlite3VdbeVerifyAbortable(v,
     (!pFKey->isDeferred
@@ -114129,7 +116025,7 @@ static Expr *exprTableColumn(
 ){
   Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
   if( pExpr ){
-    pExpr->pTab = pTab;
+    pExpr->y.pTab = pTab;
     pExpr->iTable = iCursor;
     pExpr->iColumn = iCol;
   }
@@ -114218,7 +116114,7 @@ static void fkScanChildren(
     zCol = pFKey->pFrom->aCol[iCol].zName;
     pRight = sqlite3Expr(db, TK_ID, zCol);
     pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
-    pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+    pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
   }
 
   /* If the child table is the same as the parent table, then add terms
@@ -114229,8 +116125,11 @@ static void fkScanChildren(
   **     NOT( $current_a==a AND $current_b==b AND ... )
   **
   ** The first form is used for rowid tables.  The second form is used
-  ** for WITHOUT ROWID tables.  In the second form, the primary key is
-  ** (a,b,...)
+  ** for WITHOUT ROWID tables. In the second form, the *parent* key is
+  ** (a,b,...). Either the parent or primary key could be used to 
+  ** uniquely identify the current row, but the parent key is more convenient
+  ** as the required values have already been loaded into registers
+  ** by the caller.
   */
   if( pTab==pFKey->pFrom && nIncr>0 ){
     Expr *pNe;                    /* Expression (pLeft != pRight) */
@@ -114242,19 +116141,18 @@ static void fkScanChildren(
       pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
     }else{
       Expr *pEq, *pAll = 0;
-      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
       assert( pIdx!=0 );
-      for(i=0; i<pPk->nKeyCol; i++){
+      for(i=0; i<pIdx->nKeyCol; i++){
         i16 iCol = pIdx->aiColumn[i];
         assert( iCol>=0 );
         pLeft = exprTableRegister(pParse, pTab, regData, iCol);
-        pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
-        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
-        pAll = sqlite3ExprAnd(db, pAll, pEq);
+        pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
+        pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
+        pAll = sqlite3ExprAnd(pParse, pAll, pEq);
       }
       pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
     }
-    pWhere = sqlite3ExprAnd(db, pWhere, pNe);
+    pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
   }
 
   /* Resolve the references in the WHERE clause. */
@@ -114354,7 +116252,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
         if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
       }
       if( !p ) return;
-      iSkip = sqlite3VdbeMakeLabel(v);
+      iSkip = sqlite3VdbeMakeLabel(pParse);
       sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
     }
 
@@ -114639,7 +116537,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
 
     /* Create a SrcList structure containing the child table.  We need the
     ** child table as a SrcList for sqlite3WhereBegin() */
-    pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+    pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
     if( pSrc ){
       struct SrcList_item *pItem = pSrc->a;
       pItem->pTab = pFKey->pFrom;
@@ -114860,7 +116758,7 @@ static Trigger *fkActionTrigger(
             sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
           sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
       );
-      pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+      pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
 
       /* For ON UPDATE, construct the next term of the WHEN clause.
       ** The final WHEN clause will be like this:
@@ -114876,7 +116774,7 @@ static Trigger *fkActionTrigger(
               sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
               sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
             );
-        pWhen = sqlite3ExprAnd(db, pWhen, pEq);
+        pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
       }
   
       if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
@@ -114916,7 +116814,7 @@ static Trigger *fkActionTrigger(
       }
       pSelect = sqlite3SelectNew(pParse, 
           sqlite3ExprListAppend(pParse, 0, pRaise),
-          sqlite3SrcListAppend(db, 0, &tFrom, 0),
+          sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
           pWhere,
           0, 0, 0, 0, 0
       );
@@ -115205,7 +117103,8 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
     }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);
@@ -115377,6 +117276,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
     aOp[7].p2 = memId+2;
     aOp[7].p1 = memId;
     aOp[10].p2 = memId;
+    if( pParse->nTab==0 ) pParse->nTab = 1;
   }
 }
 
@@ -115871,7 +117771,7 @@ SQLITE_PRIVATE void sqlite3Insert(
     int nIdx;
     nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
                                       &iDataCur, &iIdxCur);
-    aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
+    aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
     if( aRegIdx==0 ){
       goto insert_cleanup;
     }
@@ -115880,9 +117780,15 @@ SQLITE_PRIVATE void sqlite3Insert(
       aRegIdx[i] = ++pParse->nMem;
       pParse->nMem += pIdx->nColumn;
     }
+    aRegIdx[i] = ++pParse->nMem;  /* Register to store the table record */
   }
 #ifndef SQLITE_OMIT_UPSERT
   if( pUpsert ){
+    if( IsVirtual(pTab) ){
+      sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
+              pTab->zName);
+      goto insert_cleanup;
+    }
     pTabList->a[0].iCursor = iDataCur;
     pUpsert->pUpsertSrc = pTabList;
     pUpsert->regData = regData;
@@ -115923,7 +117829,7 @@ SQLITE_PRIVATE void sqlite3Insert(
 
   /* Run the BEFORE and INSTEAD OF triggers, if there are any
   */
-  endOfLoop = sqlite3VdbeMakeLabel(v);
+  endOfLoop = sqlite3VdbeMakeLabel(pParse);
   if( tmask & TRIGGER_BEFORE ){
     int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
 
@@ -116005,16 +117911,12 @@ SQLITE_PRIVATE void sqlite3Insert(
       }else if( pSelect ){
         sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
       }else{
-        VdbeOp *pOp;
-        sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
-        pOp = sqlite3VdbeGetOp(v, -1);
-        assert( pOp!=0 );
-        if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+        Expr *pIpk = pList->a[ipkColumn].pExpr;
+        if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){
+          sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
           appendFlag = 1;
-          pOp->opcode = OP_NewRowid;
-          pOp->p1 = iDataCur;
-          pOp->p2 = regRowid;
-          pOp->p3 = regAutoinc;
+        }else{
+          sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
         }
       }
       /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
@@ -116185,14 +118087,15 @@ insert_cleanup:
 #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){
@@ -116214,12 +118117,21 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
 ** 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;
@@ -116234,7 +118146,7 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
   testcase( w.eCode==CKCNSTRNT_COLUMN );
   testcase( w.eCode==CKCNSTRNT_ROWID );
   testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
-  return !w.eCode;
+  return w.eCode!=0;
 }
 
 /*
@@ -116272,6 +118184,14 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
 ** the same as the order of indices on the linked list of indices
 ** at pTab->pIndex.
 **
+** (2019-05-07) The generated code also creates a new record for the
+** main table, if pTab is a rowid table, and stores that record in the
+** register identified by aRegIdx[nIdx] - in other words in the first
+** entry of aRegIdx[] past the last index.  It is important that the
+** record be generated during constraint checks to avoid affinity changes
+** to the register content that occur after constraint checks but before
+** the new record is inserted.
+**
 ** The caller must have already opened writeable cursors on the main
 ** table and all applicable indices (that is to say, all indices for which
 ** aRegIdx[] is not zero).  iDataCur is the cursor for the main table when
@@ -116399,7 +118319,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
     }
     assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
         || onError==OE_Ignore || onError==OE_Replace );
+    addr1 = 0;
     switch( onError ){
+      case OE_Replace: {
+        assert( onError==OE_Replace );
+        addr1 = sqlite3VdbeMakeLabel(pParse);
+        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+          VdbeCoverage(v);
+        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+          VdbeCoverage(v);
+        onError = OE_Abort;
+        /* Fall through into the OE_Abort case to generate code that runs
+        ** if both the input and the default value are NULL */
+      }
       case OE_Abort:
         sqlite3MayAbort(pParse);
         /* Fall through */
@@ -116412,19 +118345,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
         sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
         sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
         VdbeCoverage(v);
-        break;
-      }
-      case OE_Ignore: {
-        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
-        VdbeCoverage(v);
+        if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
         break;
       }
       default: {
-        assert( onError==OE_Replace );
-        addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
-           VdbeCoverage(v);
-        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
-        sqlite3VdbeJumpHere(v, addr1);
+        assert( onError==OE_Ignore );
+        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
+        VdbeCoverage(v);
         break;
       }
     }
@@ -116440,8 +118367,14 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
     for(i=0; i<pCheck->nExpr; i++){
       int allOk;
       Expr *pExpr = pCheck->a[i].pExpr;
-      if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
-      allOk = sqlite3VdbeMakeLabel(v);
+      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(pParse);
       sqlite3VdbeVerifyAbortable(v, onError);
       sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
       if( onError==OE_Ignore ){
@@ -116449,7 +118382,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
       }else{
         char *zName = pCheck->a[i].zName;
         if( zName==0 ) zName = pTab->zName;
-        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
+        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
         sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
                               onError, zName, P4_TRANSIENT,
                               P5_ConstraintCheck);
@@ -116508,7 +118441,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
   ** exist in the table.
   */
   if( pkChng && pPk==0 ){
-    int addrRowidOk = sqlite3VdbeMakeLabel(v);
+    int addrRowidOk = sqlite3VdbeMakeLabel(pParse);
 
     /* Figure out what action to take in case of a rowid collision */
     onError = pTab->keyConf;
@@ -116658,7 +118591,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
       VdbeComment((v, "Skip upsert subroutine"));
       sqlite3VdbeJumpHere(v, upsertJump);
     }else{
-      addrUniqueOk = sqlite3VdbeMakeLabel(v);
+      addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
     }
     if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
       sqlite3TableAffinity(v, pTab, regNewData+1);
@@ -116702,7 +118635,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
     sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
     VdbeComment((v, "for %s", pIdx->zName));
 #ifdef SQLITE_ENABLE_NULL_TRIM
-    if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
+    if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
+      sqlite3SetMakeRecordP5(v, pIdx->pTable);
+    }
 #endif
 
     /* In an UPDATE operation, if this index is the PRIMARY KEY index 
@@ -116741,7 +118676,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
     **   (3) There are no secondary indexes on the table
     **   (4) No delete triggers need to be fired if there is a conflict
     **   (5) No FK constraint counters need to be updated if a conflict occurs.
-    */ 
+    **
+    ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
+    ** must be explicitly deleted in order to ensure any pre-update hook
+    ** is invoked.  */ 
+#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
     if( (ix==0 && pIdx->pNext==0)                   /* Condition 3 */
      && pPk==pIdx                                   /* Condition 2 */
      && onError==OE_Replace                         /* Condition 1 */
@@ -116753,6 +118692,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
       sqlite3VdbeResolveLabel(v, addrUniqueOk);
       continue;
     }
+#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */
 
     /* Check to see if the new index entry will be unique */
     sqlite3VdbeVerifyAbortable(v, onError);
@@ -116866,11 +118806,21 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
 
   /* If the IPK constraint is a REPLACE, run it last */
   if( ipkTop ){
-    sqlite3VdbeGoto(v, ipkTop+1);
+    sqlite3VdbeGoto(v, ipkTop);
     VdbeComment((v, "Do IPK REPLACE"));
     sqlite3VdbeJumpHere(v, ipkBottom);
   }
 
+  /* Generate the table record */
+  if( HasRowid(pTab) ){
+    int regRec = aRegIdx[ix];
+    sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
+    sqlite3SetMakeRecordP5(v, pTab);
+    if( !bAffinityDone ){
+      sqlite3TableAffinity(v, pTab, 0);
+    }
+  }
+
   *pbMayReplace = seenReplace;
   VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
 }
@@ -116920,10 +118870,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   Vdbe *v;            /* Prepared statements under construction */
   Index *pIdx;        /* An index being inserted or updated */
   u8 pik_flags;       /* flag values passed to the btree insert */
-  int regData;        /* Content registers (after the rowid) */
-  int regRec;         /* Register holding assembled record for the table */
   int i;              /* Loop counter */
-  u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
 
   assert( update_flags==0
        || update_flags==OPFLAG_ISUPDATE
@@ -116935,7 +118882,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   assert( pTab->pSelect==0 );  /* This table is not a VIEW */
   for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
     if( aRegIdx[i]==0 ) continue;
-    bAffinityDone = 1;
     if( pIdx->pPartIdxWhere ){
       sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
       VdbeCoverage(v);
@@ -116947,10 +118893,13 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
       pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
       if( update_flags==0 ){
-        sqlite3VdbeAddOp4(v, OP_InsertInt, 
-            iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE
+        int r = sqlite3GetTempReg(pParse);
+        sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
+        sqlite3VdbeAddOp4(v, OP_Insert, 
+            iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE
         );
         sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
+        sqlite3ReleaseTempReg(pParse, r);
       }
 #endif
     }
@@ -116960,13 +118909,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
     sqlite3VdbeChangeP5(v, pik_flags);
   }
   if( !HasRowid(pTab) ) return;
-  regData = regNewData + 1;
-  regRec = sqlite3GetTempReg(pParse);
-  sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
-  sqlite3SetMakeRecordP5(v, pTab);
-  if( !bAffinityDone ){
-    sqlite3TableAffinity(v, pTab, 0);
-  }
   if( pParse->nested ){
     pik_flags = 0;
   }else{
@@ -116979,7 +118921,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   if( useSeekResult ){
     pik_flags |= OPFLAG_USESEEKRESULT;
   }
-  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
+  sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
   if( !pParse->nested ){
     sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
   }
@@ -117236,7 +119178,8 @@ static int xferOptimization(
   if( pSrc==0 ){
     return 0;   /* FROM clause does not contain a real table */
   }
-  if( pSrc==pDest ){
+  if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){
+    testcase( pSrc!=pDest ); /* Possible due to bad sqlite_master.rootpage */
     return 0;   /* tab1 and tab2 may not be the same table */
   }
   if( HasRowid(pDest)!=HasRowid(pSrc) ){
@@ -117297,6 +119240,13 @@ static int xferOptimization(
     if( pSrcIdx==0 ){
       return 0;    /* pDestIdx has no corresponding index in pSrc */
     }
+    if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema
+         && sqlite3FaultSim(411)==SQLITE_OK ){
+      /* The sqlite3FaultSim() call allows this corruption test to be
+      ** bypassed during testing, in order to exercise other corruption tests
+      ** further downstream. */
+      return 0;   /* Corrupt schema - two indexes on the same btree */
+    }
   }
 #ifndef SQLITE_OMIT_CHECK
   if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
@@ -117374,7 +119324,7 @@ static int xferOptimization(
       sqlite3RowidConstraint(pParse, onError, pDest);
       sqlite3VdbeJumpHere(v, addr2);
       autoIncStep(pParse, regAutoinc, regRowid);
-    }else if( pDest->pIndex==0 ){
+    }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){
       addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
     }else{
       addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
@@ -117437,7 +119387,7 @@ static int xferOptimization(
         sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
       }
     }
-    if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
+    if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
       idxInsFlags |= OPFLAG_NCHANGE;
     }
     sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
@@ -117512,7 +119462,7 @@ SQLITE_API int sqlite3_exec(
   sqlite3_mutex_enter(db->mutex);
   sqlite3Error(db, SQLITE_OK);
   while( rc==SQLITE_OK && zSql[0] ){
-    int nCol;
+    int nCol = 0;
     char **azVals = 0;
 
     pStmt = 0;
@@ -117526,9 +119476,7 @@ SQLITE_API int sqlite3_exec(
       zSql = zLeftover;
       continue;
     }
-
     callbackIsInit = 0;
-    nCol = sqlite3_column_count(pStmt);
 
     while( 1 ){
       int i;
@@ -117539,6 +119487,7 @@ SQLITE_API int sqlite3_exec(
           (SQLITE_DONE==rc && !callbackIsInit
                            && db->flags&SQLITE_NullCallback)) ){
         if( !callbackIsInit ){
+          nCol = sqlite3_column_count(pStmt);
           azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
           if( azCols==0 ){
             goto exec_out;
@@ -117941,12 +119890,18 @@ struct sqlite3_api_routines {
   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*);
+  /* Version 3.28.0 and later */
+  int (*stmt_isexplain)(sqlite3_stmt*);
+  int (*value_frombind)(sqlite3_value*);
 };
 
 /*
@@ -118234,6 +120189,11 @@ typedef int (*sqlite3_loadext_entry)(
 #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
+/* Version 3.28.0 and later */
+#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
+#define sqlite3_value_frombind         sqlite3_api->frombind
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -118322,6 +120282,7 @@ typedef int (*sqlite3_loadext_entry)(
 # 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
@@ -118689,7 +120650,16 @@ static const sqlite3_api_routines sqlite3Apis = {
   sqlite3_str_length,
   sqlite3_str_value,
   /* Version 3.25.0 and later */
-  sqlite3_create_window_function
+  sqlite3_create_window_function,
+  /* Version 3.26.0 and later */
+#ifdef SQLITE_ENABLE_NORMALIZE
+  sqlite3_normalized_sql,
+#else
+  0,
+#endif
+  /* Version 3.28.0 and later */
+  sqlite3_stmt_isexplain,
+  sqlite3_value_frombind
 };
 
 /*
@@ -118881,7 +120851,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
   if( onoff ){
     db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
   }else{
-    db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
+    db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
   }
   sqlite3_mutex_leave(db->mutex);
   return SQLITE_OK;
@@ -119137,12 +121107,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
 #define PragTyp_WAL_AUTOCHECKPOINT            38
 #define PragTyp_WAL_CHECKPOINT                39
 #define PragTyp_ACTIVATE_EXTENSIONS           40
-#define PragTyp_HEXKEY                        41
-#define PragTyp_KEY                           42
-#define PragTyp_REKEY                         43
-#define PragTyp_LOCK_STATUS                   44
-#define PragTyp_PARSER_TRACE                  45
-#define PragTyp_STATS                         46
+#define PragTyp_KEY                           41
+#define PragTyp_LOCK_STATUS                   42
+#define PragTyp_STATS                         43
 
 /* Property flags associated with various pragma. */
 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -119159,58 +121126,57 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
 ** 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",       
   /*  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 */
@@ -119220,7 +121186,7 @@ typedef struct PragmaName {
   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)
@@ -119256,7 +121222,7 @@ static const PragmaName aPragmaName[] = {
  {/* 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",
@@ -119272,11 +121238,13 @@ static const PragmaName aPragmaName[] = {
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
+#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
  {/* zName:     */ "case_sensitive_like",
   /* ePragTyp:  */ PragTyp_CASE_SENSITIVE_LIKE,
   /* ePragFlg:  */ PragFlg_NoColumns,
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
+#endif
  {/* zName:     */ "cell_size_check",
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119293,7 +121261,7 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
@@ -119328,14 +121296,14 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
  {/* 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)
@@ -119365,14 +121333,14 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
  {/* 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)
@@ -119408,21 +121376,21 @@ static const PragmaName aPragmaName[] = {
  {/* zName:     */ "function_list",
   /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
   /* ePragFlg:  */ PragFlg_Result0,
-  /* ColNames:  */ 29, 2,
+  /* ColNames:  */ 41, 2,
   /* iArg:      */ 0 },
 #endif
 #endif
 #if defined(SQLITE_HAS_CODEC)
  {/* zName:     */ "hexkey",
-  /* ePragTyp:  */ PragTyp_HEXKEY,
+  /* ePragTyp:  */ PragTyp_KEY,
   /* ePragFlg:  */ 0,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ 0 },
+  /* iArg:      */ 2 },
  {/* zName:     */ "hexrekey",
-  /* ePragTyp:  */ PragTyp_HEXKEY,
+  /* ePragTyp:  */ PragTyp_KEY,
   /* ePragFlg:  */ 0,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ 0 },
+  /* iArg:      */ 3 },
 #endif
 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 #if !defined(SQLITE_OMIT_CHECK)
@@ -119444,12 +121412,12 @@ static const PragmaName aPragmaName[] = {
  {/* 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,
@@ -119506,7 +121474,7 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
@@ -119532,7 +121500,7 @@ static const PragmaName aPragmaName[] = {
  {/* zName:     */ "module_list",
   /* ePragTyp:  */ PragTyp_MODULE_LIST,
   /* ePragFlg:  */ PragFlg_Result0,
-  /* ColNames:  */ 31, 1,
+  /* ColNames:  */ 9, 1,
   /* iArg:      */ 0 },
 #endif
 #endif
@@ -119554,18 +121522,20 @@ static const PragmaName aPragmaName[] = {
   /* ColNames:  */ 0, 0,
   /* iArg:      */ 0 },
 #endif
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
  {/* zName:     */ "parser_trace",
-  /* ePragTyp:  */ PragTyp_PARSER_TRACE,
-  /* ePragFlg:  */ 0,
+  /* ePragTyp:  */ PragTyp_FLAG,
+  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ 0 },
+  /* iArg:      */ SQLITE_ParserTrace },
+#endif
 #endif
 #if defined(SQLITE_INTROSPECTION_PRAGMAS)
  {/* 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)
@@ -119596,10 +121566,10 @@ static const PragmaName aPragmaName[] = {
 #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",
@@ -119652,7 +121622,7 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
@@ -119666,8 +121636,13 @@ static const PragmaName aPragmaName[] = {
  {/* 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",
@@ -119680,6 +121655,18 @@ static const PragmaName aPragmaName[] = {
   /* ePragFlg:  */ PragFlg_NoColumns1,
   /* 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,
@@ -119731,7 +121718,7 @@ static const PragmaName aPragmaName[] = {
  {/* 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)
@@ -119739,10 +121726,10 @@ static const PragmaName aPragmaName[] = {
   /* ePragTyp:  */ PragTyp_FLAG,
   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
   /* ColNames:  */ 0, 0,
-  /* iArg:      */ SQLITE_WriteSchema },
+  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
 #endif
 };
-/* Number of pragmas: 61 on by default, 78 total. */
+/* Number of pragmas: 62 on by default, 81 total. */
 
 /************** End of pragma.h **********************************************/
 /************** Continuing where we left off in pragma.c *********************/
@@ -120361,6 +122348,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
         ** then do a query */
         eMode = PAGER_JOURNALMODE_QUERY;
       }
+      if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
+        /* Do not allow journal-mode "OFF" in defensive since the database
+        ** can become corrupted using ordinary SQL when the journal is off */
+        eMode = PAGER_JOURNALMODE_QUERY;
+      }
     }
     if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
       /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
@@ -120533,7 +122525,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       if( sqlite3GetBoolean(zRight, size!=0) ){
         db->flags |= SQLITE_CacheSpill;
       }else{
-        db->flags &= ~SQLITE_CacheSpill;
+        db->flags &= ~(u64)SQLITE_CacheSpill;
       }
       setAllPagerFlags(db);
     }
@@ -120754,7 +122746,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       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.  */
@@ -120803,15 +122795,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
     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;
         }
@@ -120823,13 +122817,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
           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);
       }
     }
   }
@@ -120867,6 +122862,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
     Table *pTab;
     pIdx = sqlite3FindIndex(db, zRight, zDb);
     if( pIdx ){
+      int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
       int i;
       int mx;
       if( pPragma->iArg ){
@@ -120879,7 +122875,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
         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];
@@ -120903,8 +122899,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
     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",
@@ -120951,6 +122948,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
     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);
       }
     }
@@ -120992,9 +122990,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
     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++){
@@ -121039,9 +123038,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
     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;
@@ -121050,21 +123049,23 @@ SQLITE_PRIVATE void sqlite3Pragma(
         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{
@@ -121084,7 +123085,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
           x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
           assert( x==0 );
         }
-        addrOk = sqlite3VdbeMakeLabel(v);
+        addrOk = sqlite3VdbeMakeLabel(pParse);
 
         /* Generate code to read the child key values into registers
         ** regRow..regRow+n. If any of the child key values are NULL, this 
@@ -121129,19 +123130,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
 #endif /* !defined(SQLITE_OMIT_TRIGGER) */
 #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
 
-#ifndef NDEBUG
-  case PragTyp_PARSER_TRACE: {
-    if( zRight ){
-      if( sqlite3GetBoolean(zRight, 0) ){
-        sqlite3ParserTrace(stdout, "parser: ");
-      }else{
-        sqlite3ParserTrace(0, 0);
-      }
-    }
-  }
-  break;
-#endif
-
+#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
   /* Reinstall the LIKE and GLOB functions.  The variant of LIKE
   ** used will be case sensitive or not depending on the RHS.
   */
@@ -121151,6 +123140,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
     }
   }
   break;
+#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
 
 #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
 # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
@@ -121304,8 +123294,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
         if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
           ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
           if( db->mallocFailed==0 ){
-            int addrCkFault = sqlite3VdbeMakeLabel(v);
-            int addrCkOk = sqlite3VdbeMakeLabel(v);
+            int addrCkFault = sqlite3VdbeMakeLabel(pParse);
+            int addrCkOk = sqlite3VdbeMakeLabel(pParse);
             char *zErr;
             int k;
             pParse->iSelfTab = iDataCur + 1;
@@ -121328,7 +123318,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
           /* 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);
+            int ckUniq = sqlite3VdbeMakeLabel(pParse);
             if( pPk==pIdx ) continue;
             r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
                                          pPrior, r1);
@@ -121349,7 +123339,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
             ** 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 uniqOk = sqlite3VdbeMakeLabel(pParse);
               int jmp6;
               int kk;
               for(kk=0; kk<pIdx->nKeyCol; kk++){
@@ -121833,27 +123823,41 @@ SQLITE_PRIVATE void sqlite3Pragma(
 #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));
-    break;
-  }
-  case PragTyp_REKEY: {
-    if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
-    break;
-  }
-  case PragTyp_HEXKEY: {
     if( zRight ){
-      u8 iByte;
-      int i;
-      char zKey[40];
-      for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
-        iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
-        if( (i&1)!=0 ) zKey[i/2] = iByte;
-      }
-      if( (zLeft[3] & 0xf)==0xb ){
-        sqlite3_key_v2(db, zDb, zKey, i/2);
+      char zBuf[40];
+      const char *zKey = zRight;
+      int n;
+      if( pPragma->iArg==2 || pPragma->iArg==3 ){
+        u8 iByte;
+        int i;
+        for(i=0, iByte=0; i<sizeof(zBuf)*2 && sqlite3Isxdigit(zRight[i]); i++){
+          iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+          if( (i&1)!=0 ) zBuf[i/2] = iByte;
+        }
+        zKey = zBuf;
+        n = i/2;
       }else{
-        sqlite3_rekey_v2(db, zDb, zKey, i/2);
+        n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
+      }
+      if( (pPragma->iArg & 1)==0 ){
+        rc = sqlite3_key_v2(db, zDb, zKey, n);
+      }else{
+        rc = sqlite3_rekey_v2(db, zDb, zKey, n);
+      }
+      if( rc==SQLITE_OK && n!=0 ){
+        sqlite3VdbeSetNumCols(v, 1);
+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
+        returnSingleText(v, "ok");
       }
     }
     break;
@@ -122180,7 +124184,8 @@ static const sqlite3_module pragmaVtabModule = {
   0,                           /* xRename - rename the table */
   0,                           /* xSavepoint */
   0,                           /* xRelease */
-  0                            /* xRollbackTo */
+  0,                           /* xRollbackTo */
+  0                            /* xShadowName */
 };
 
 /*
@@ -122250,6 +124255,19 @@ static void corruptSchema(
   }
 }
 
+/*
+** Check to see if any sibling index (another index on the same table)
+** of pIndex has the same root page number, and if it does, return true.
+** This would indicate a corrupt schema.
+*/
+SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){
+  Index *p;
+  for(p=pIndex->pTable->pIndex; p; p=p->pNext){
+    if( p->tnum==pIndex->tnum && p!=pIndex ) return 1;
+  }
+  return 0;
+}
+
 /*
 ** This is the callback routine for the code that initializes the
 ** database.  See sqlite3Init() below for additional information.
@@ -122271,6 +124289,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
   UNUSED_PARAMETER2(NotUsed, argc);
   assert( sqlite3_mutex_held(db->mutex) );
   DbClearProperty(db, iDb, DB_Empty);
+  pData->nInitRow++;
   if( db->mallocFailed ){
     corruptSchema(pData, argv[0], 0);
     return 1;
@@ -122324,15 +124343,12 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
     */
     Index *pIndex;
     pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
-    if( pIndex==0 ){
-      /* This can occur if there exists an index on a TEMP table which
-      ** has the same name as another index on a permanent index.  Since
-      ** the permanent table is hidden by the TEMP table, we can also
-      ** safely ignore the index on the permanent table.
-      */
-      /* Do Nothing */;
-    }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
-      corruptSchema(pData, argv[0], "invalid rootpage");
+    if( pIndex==0
+     || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
+     || pIndex->tnum<2
+     || sqlite3IndexHasDuplicateRootPage(pIndex)
+    ){
+      corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
     }
   }
   return 0;
@@ -122382,6 +124398,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
   initData.rc = SQLITE_OK;
   initData.pzErrMsg = pzErrMsg;
   initData.mInitFlags = mFlags;
+  initData.nInitRow = 0;
   sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
   if( initData.rc ){
     rc = initData.rc;
@@ -122499,7 +124516,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
   ** indices that the user might have created.
   */
   if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
-    db->flags &= ~SQLITE_LegacyFileFmt;
+    db->flags &= ~(u64)SQLITE_LegacyFileFmt;
   }
 
   /* Read the schema information out of the schema tables
@@ -122533,8 +124550,8 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
     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
@@ -122751,6 +124768,7 @@ static int sqlite3Prepare(
     sParse.disableLookaside++;
     db->lookaside.bDisable++;
   }
+  sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
 
   /* Check to verify that it is possible to get a read lock on all
   ** database schemas.  The inability to get a read lock indicates that
@@ -122915,6 +124933,7 @@ static int sqlite3LockAndPrepare(
   return rc;
 }
 
+
 /*
 ** Rerun the compilation of a statement after a schema change.
 **
@@ -123479,7 +125498,7 @@ static void addWhereTerm(
     ExprSetVVAProperty(pEq, EP_NoReduce);
     pEq->iRightJoinTable = (i16)pE2->iTable;
   }
-  *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
+  *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
 }
 
 /*
@@ -123613,7 +125632,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
     */
     if( pRight->pOn ){
       if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
-      p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
+      p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
       pRight->pOn = 0;
     }
 
@@ -123755,7 +125774,7 @@ static void pushOntoSorter(
   }
   assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
   iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
-  pSort->labelDone = sqlite3VdbeMakeLabel(v);
+  pSort->labelDone = sqlite3VdbeMakeLabel(pParse);
   sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
                           SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
   if( bSeq ){
@@ -123794,7 +125813,7 @@ static void pushOntoSorter(
                                            pKI->nAllField-pKI->nKeyField-1);
     addrJmp = sqlite3VdbeCurrentAddr(v);
     sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
-    pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+    pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse);
     pSort->regReturn = ++pParse->nMem;
     sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
     sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
@@ -123927,7 +125946,7 @@ static void selectExprDefer(
     struct ExprList_item *pItem = &pEList->a[i];
     if( pItem->u.x.iOrderByCol==0 ){
       Expr *pExpr = pItem->pExpr;
-      Table *pTab = pExpr->pTab;
+      Table *pTab = pExpr->y.pTab;
       if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
        && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
       ){
@@ -123950,12 +125969,12 @@ static void selectExprDefer(
               Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
               if( pNew ){
                 pNew->iTable = pExpr->iTable;
-                pNew->pTab = pExpr->pTab;
+                pNew->y.pTab = pExpr->y.pTab;
                 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
                 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
               }
             }
-            pSort->aDefer[nDefer].pTab = pExpr->pTab;
+            pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
             pSort->aDefer[nDefer].iCsr = pExpr->iTable;
             pSort->aDefer[nDefer].nKey = nKey;
             nDefer++;
@@ -124541,7 +126560,7 @@ static void generateSortTail(
 ){
   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 addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */
   int addr;                       /* Top of output loop. Jump for Next. */
   int addrOnce = 0;
   int iTab;
@@ -124581,7 +126600,12 @@ static void generateSortTail(
     regRow = pDest->iSdst;
   }else{
     regRowid = sqlite3GetTempReg(pParse);
-    regRow = sqlite3GetTempRange(pParse, nColumn);
+    if( eDest==SRT_EphemTab || eDest==SRT_Table ){
+      regRow = sqlite3GetTempReg(pParse);
+      nColumn = 0;
+    }else{
+      regRow = sqlite3GetTempRange(pParse, nColumn);
+    }
   }
   nKey = pOrderBy->nExpr - pSort->nOBSat;
   if( pSort->sortFlags & SORTFLAG_UseSorter ){
@@ -124661,6 +126685,7 @@ static void generateSortTail(
   switch( eDest ){
     case SRT_Table:
     case SRT_EphemTab: {
+      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow);
       sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
       sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -124804,7 +126829,7 @@ static const char *columnTypeImpl(
         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
@@ -124989,7 +127014,7 @@ static void generateColumnNames(
 
     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;
@@ -124997,7 +127022,7 @@ static void generateColumnNames(
     }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) );
@@ -125088,7 +127113,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
       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";
@@ -125201,22 +127226,19 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
 SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
   Table *pTab;
   sqlite3 *db = pParse->db;
-  int savedFlags;
+  u64 savedFlags;
 
   savedFlags = db->flags;
-  db->flags &= ~SQLITE_FullColNames;
+  db->flags &= ~(u64)SQLITE_FullColNames;
   db->flags |= SQLITE_ShortColNames;
   sqlite3SelectPrep(pParse, pSelect, 0);
+  db->flags = savedFlags;
   if( pParse->nErr ) return 0;
   while( pSelect->pPrior ) pSelect = pSelect->pPrior;
-  db->flags = savedFlags;
   pTab = sqlite3DbMallocZero(db, sizeof(Table) );
   if( pTab==0 ){
     return 0;
   }
-  /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
-  ** is disabled */
-  assert( db->lookaside.bDisable );
   pTab->nTabRef = 1;
   pTab->zName = 0;
   pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -125442,11 +127464,18 @@ static void generateWithRecursiveQuery(
   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;
 
   /* Process the LIMIT and OFFSET clauses, if they exist */
-  addrBreak = sqlite3VdbeMakeLabel(v);
+  addrBreak = sqlite3VdbeMakeLabel(pParse);
   p->nSelectRow = 320;  /* 4 billion rows */
   computeLimitRegisters(pParse, p, addrBreak);
   pLimit = p->pLimit;
@@ -125516,7 +127545,7 @@ static void generateWithRecursiveQuery(
   sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
 
   /* Output the single row in Current */
-  addrCont = sqlite3VdbeMakeLabel(v);
+  addrCont = sqlite3VdbeMakeLabel(pParse);
   codeOffset(v, regOffset, addrCont);
   selectInnerLoop(pParse, p, iCurrent,
       0, 0, pDest, addrCont, addrBreak);
@@ -125651,6 +127680,7 @@ static int multiSelect(
   */
   assert( p && p->pPrior );  /* Calling function guarantees this much */
   assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
+  assert( p->selFlags & SF_Compound );
   db = pParse->db;
   pPrior = p->pPrior;
   dest = *pDest;
@@ -125824,8 +127854,8 @@ static int multiSelect(
         if( dest.eDest!=priorOp ){
           int iCont, iBreak, iStart;
           assert( p->pEList );
-          iBreak = sqlite3VdbeMakeLabel(v);
-          iCont = sqlite3VdbeMakeLabel(v);
+          iBreak = sqlite3VdbeMakeLabel(pParse);
+          iCont = sqlite3VdbeMakeLabel(pParse);
           computeLimitRegisters(pParse, p, iBreak);
           sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
           iStart = sqlite3VdbeCurrentAddr(v);
@@ -125893,8 +127923,8 @@ static int multiSelect(
         ** tables.
         */
         assert( p->pEList );
-        iBreak = sqlite3VdbeMakeLabel(v);
-        iCont = sqlite3VdbeMakeLabel(v);
+        iBreak = sqlite3VdbeMakeLabel(pParse);
+        iCont = sqlite3VdbeMakeLabel(pParse);
         computeLimitRegisters(pParse, p, iBreak);
         sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
         r1 = sqlite3GetTempReg(pParse);
@@ -126024,7 +128054,7 @@ static int generateOutputSubroutine(
   int addr;
 
   addr = sqlite3VdbeCurrentAddr(v);
-  iContinue = sqlite3VdbeMakeLabel(v);
+  iContinue = sqlite3VdbeMakeLabel(pParse);
 
   /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
   */
@@ -126261,8 +128291,8 @@ static int multiSelectOrderBy(
   db = pParse->db;
   v = pParse->pVdbe;
   assert( v!=0 );       /* Already thrown the error if VDBE alloc failed */
-  labelEnd = sqlite3VdbeMakeLabel(v);
-  labelCmpr = sqlite3VdbeMakeLabel(v);
+  labelEnd = sqlite3VdbeMakeLabel(pParse);
+  labelCmpr = sqlite3VdbeMakeLabel(pParse);
 
 
   /* Patch up the ORDER BY clause
@@ -126578,6 +128608,7 @@ static Expr *substExpr(
           ifNullRow.iTable = pSubst->iNewTable;
           pCopy = &ifNullRow;
         }
+        testcase( ExprHasProperty(pCopy, EP_Subquery) );
         pNew = sqlite3ExprDup(db, pCopy, 0);
         if( pNew && pSubst->isLeftJoin ){
           ExprSetProperty(pNew, EP_CanBeNull);
@@ -127070,11 +129101,9 @@ static int flattenSubquery(
       jointype = pSubitem->fg.jointype;
     }else{
       assert( pParent!=p );  /* 2nd and subsequent times through the loop */
-      pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
-      if( pSrc==0 ){
-        assert( db->mallocFailed );
-        break;
-      }
+      pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
+      if( pSrc==0 ) break;
+      pParent->pSrc = pSrc;
     }
 
     /* The subquery uses a single slot of the FROM clause of the outer
@@ -127093,10 +129122,9 @@ static int flattenSubquery(
     ** for the two elements in the FROM clause of the subquery.
     */
     if( nSubSrc>1 ){
-      pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
-      if( db->mallocFailed ){
-        break;
-      }
+      pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
+      if( pSrc==0 ) break;
+      pParent->pSrc = pSrc;
     }
 
     /* Transfer the FROM clause terms from the subquery into the
@@ -127142,11 +129170,12 @@ static int flattenSubquery(
       pParent->pOrderBy = pOrderBy;
       pSub->pOrderBy = 0;
     }
-    pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+    pWhere = pSub->pWhere;
+    pSub->pWhere = 0;
     if( isLeftJoin>0 ){
       setJoinExpr(pWhere, iNewParent);
     }
-    pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+    pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
     if( db->mallocFailed==0 ){
       SubstContext x;
       x.pParse = pParse;
@@ -127157,10 +129186,10 @@ static int flattenSubquery(
       substSelect(&x, pParent, 0);
     }
   
-    /* The flattened query is distinct if either the inner or the
-    ** outer query is distinct. 
-    */
-    pParent->selFlags |= pSub->selFlags & SF_Distinct;
+    /* The flattened query is a compound if either the inner or the
+    ** outer query is a compound. */
+    pParent->selFlags |= pSub->selFlags & SF_Compound;
+    assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */
   
     /*
     ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
@@ -127191,7 +129220,7 @@ static int flattenSubquery(
 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
 
 /*
-** A structure to keep track of all of the column values that fixed to
+** 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;
@@ -127203,13 +129232,28 @@ struct WhereConst {
 };
 
 /*
-** Add a new entry to the pConst object
+** Add a new entry to the pConst object.  Except, do not add duplicate
+** pColumn entires.
 */
 static void constInsert(
-  WhereConst *pConst,
-  Expr *pColumn,
-  Expr *pValue
+  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,
@@ -127466,9 +129510,9 @@ static int pushDownWhereTerms(
       x.pEList = pSubq->pEList;
       pNew = substExpr(&x, pNew);
       if( pSubq->selFlags & SF_Aggregate ){
-        pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
+        pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
       }else{
-        pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+        pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
       }
       pSubq = pSubq->pPrior;
     }
@@ -127894,7 +129938,7 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr
   pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
   pTab->tabFlags |= TF_Ephemeral;
 
-  return SQLITE_OK;
+  return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
 }
 
 /*
@@ -127940,6 +129984,10 @@ static int selectExpander(Walker *pWalker, Select *p){
   if( (selFlags & SF_Expanded)!=0 ){
     return WRC_Prune;
   }
+  if( pWalker->eCode ){
+    /* Renumber selId because it has been copied from a view */
+    p->selId = ++pParse->nSelect;
+  }
   pTabList = p->pSrc;
   pEList = p->pEList;
   sqlite3WithPush(pParse, p->pWith, 0);
@@ -127989,12 +130037,15 @@ static int selectExpander(Walker *pWalker, Select *p){
 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
       if( IsVirtual(pTab) || pTab->pSelect ){
         i16 nCol;
+        u8 eCodeOrig = pWalker->eCode;
         if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
         assert( pFrom->pSelect==0 );
         pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
         nCol = pTab->nCol;
         pTab->nCol = -1;
+        pWalker->eCode = 1;  /* Turn on Select.selId renumbering */
         sqlite3WalkSelect(pWalker, pFrom->pSelect);
+        pWalker->eCode = eCodeOrig;
         pTab->nCol = nCol;
       }
 #endif
@@ -128244,6 +130295,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
   }
   w.xSelectCallback = selectExpander;
   w.xSelectCallback2 = selectPopWith;
+  w.eCode = 0;
   sqlite3WalkSelect(&w, pSelect);
 }
 
@@ -128403,7 +130455,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
 **
 ** 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
+** registers if register regAcc contains 0. The caller will take care
 ** of setting and clearing regAcc.
 */
 static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
@@ -128430,7 +130482,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
       regAgg = 0;
     }
     if( pF->iDistinct>=0 ){
-      addrNext = sqlite3VdbeMakeLabel(v);
+      addrNext = sqlite3VdbeMakeLabel(pParse);
       testcase( nArg==0 );  /* Error condition */
       testcase( nArg>1 );   /* Also an error */
       codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
@@ -128515,7 +130567,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
       if( pNew ){
         Expr *pWhere = pS->pWhere;
         SWAP(Expr, *pNew, *pExpr);
-        pNew = sqlite3ExprAnd(db, pWhere, pNew);
+        pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
         pS->pWhere = pNew;
         pWalker->eCode = 1;
       }
@@ -128566,13 +130618,22 @@ static struct SrcList_item *isSelfJoinView(
 ){
   struct SrcList_item *pItem;
   for(pItem = pTabList->a; pItem<pThis; pItem++){
+    Select *pS1;
     if( pItem->pSelect==0 ) continue;
     if( pItem->fg.viaCoroutine ) continue;
     if( pItem->zName==0 ) continue;
-    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
+    assert( pItem->pTab!=0 );
+    assert( pThis->pTab!=0 );
+    if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
     if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
-    if( sqlite3ExprCompare(0, 
-          pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) 
+    pS1 = pItem->pSelect;
+    if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
+      /* The query flattener left two different CTE tables with identical
+      ** names in the same FROM clause. */
+      continue;
+    }
+    if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
+     || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) 
     ){
       /* The view was modified by some other optimization such as
       ** pushDownWhereTerms() */
@@ -128598,7 +130659,8 @@ static struct SrcList_item *isSelfJoinView(
 **   *  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(*)
+**   *  The outer query is a simple count(*) with no WHERE clause or other
+**      extraneous syntax.
 **
 ** Return TRUE if the optimization is undertaken.
 */
@@ -128609,6 +130671,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
   sqlite3 *db;
   if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate */
   if( p->pEList->nExpr!=1 ) return 0;               /* Single result column */
+  if( p->pWhere ) return 0;
+  if( p->pGroupBy ) return 0;
   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;  /* Is count() */
@@ -128835,6 +130899,7 @@ SQLITE_PRIVATE int sqlite3Select(
     }
 
     if( flattenSubquery(pParse, p, i, isAgg) ){
+      if( pParse->nErr ) goto select_end;
       /* This subquery can be absorbed into its parent. */
       i = -1;
     }
@@ -128930,22 +130995,12 @@ SQLITE_PRIVATE int sqlite3Select(
     pSub = pItem->pSelect;
     if( pSub==0 ) continue;
 
-    /* Sometimes the code for a subquery will be generated more than
-    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
-    ** for example.  In that case, do not regenerate the code to manifest
-    ** a view or the co-routine to implement a view.  The first instance
-    ** is sufficient, though the subroutine to manifest the view does need
-    ** to be invoked again. */
-    if( pItem->addrFillSub ){
-      if( pItem->fg.viaCoroutine==0 ){
-        /* The subroutine that manifests the view might be a one-time routine,
-        ** or it might need to be rerun on each iteration because it
-        ** encodes a correlated subquery. */
-        testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
-        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
-      }
-      continue;
-    }
+    /* The code for a subquery should only be generated once, though it is
+    ** technically harmless for it to be generated multiple times. The
+    ** following assert() will detect if something changes to cause
+    ** the same subquery to be coded multiple times, as a signal to the
+    ** developers to try to optimize the situation. */
+    assert( pItem->addrFillSub==0 );
 
     /* Increment Parse.nHeight by the height of the largest expression
     ** tree referred to by this, the parent select. The child select
@@ -129133,7 +131188,7 @@ SQLITE_PRIVATE int sqlite3Select(
 
   /* Set the limiter.
   */
-  iEnd = sqlite3VdbeMakeLabel(v);
+  iEnd = sqlite3VdbeMakeLabel(pParse);
   if( (p->selFlags & SF_FixedLimit)==0 ){
     p->nSelectRow = 320;  /* 4 billion rows */
   }
@@ -129200,9 +131255,9 @@ SQLITE_PRIVATE int sqlite3Select(
     assert( p->pEList==pEList );
 #ifndef SQLITE_OMIT_WINDOWFUNC
     if( pWin ){
-      int addrGosub = sqlite3VdbeMakeLabel(v);
-      int iCont = sqlite3VdbeMakeLabel(v);
-      int iBreak = sqlite3VdbeMakeLabel(v);
+      int addrGosub = sqlite3VdbeMakeLabel(pParse);
+      int iCont = sqlite3VdbeMakeLabel(pParse);
+      int iBreak = sqlite3VdbeMakeLabel(pParse);
       int regGosub = ++pParse->nMem;
 
       sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
@@ -129277,7 +131332,7 @@ SQLITE_PRIVATE int sqlite3Select(
     }
  
     /* Create a label to jump to when we want to abort the query */
-    addrEnd = sqlite3VdbeMakeLabel(v);
+    addrEnd = sqlite3VdbeMakeLabel(pParse);
 
     /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
     ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
@@ -129366,9 +131421,9 @@ SQLITE_PRIVATE int sqlite3Select(
       iUseFlag = ++pParse->nMem;
       iAbortFlag = ++pParse->nMem;
       regOutputRow = ++pParse->nMem;
-      addrOutputRow = sqlite3VdbeMakeLabel(v);
+      addrOutputRow = sqlite3VdbeMakeLabel(pParse);
       regReset = ++pParse->nMem;
-      addrReset = sqlite3VdbeMakeLabel(v);
+      addrReset = sqlite3VdbeMakeLabel(pParse);
       iAMem = pParse->nMem + 1;
       pParse->nMem += pGroupBy->nExpr;
       iBMem = pParse->nMem + 1;
@@ -130655,7 +132710,7 @@ static SrcList *targetSrcList(
   int iDb;             /* Index of the database to use */
   SrcList *pSrc;       /* SrcList to be returned */
 
-  pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+  pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
   if( pSrc ){
     assert( pSrc->nSrc>0 );
     pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
@@ -130840,6 +132895,7 @@ static TriggerPrg *codeRowTrigger(
   pSubParse->zAuthContext = pTrigger->zName;
   pSubParse->eTriggerOp = pTrigger->op;
   pSubParse->nQueryLoop = pParse->nQueryLoop;
+  pSubParse->disableVtab = pParse->disableVtab;
 
   v = sqlite3GetVdbe(pSubParse);
   if( v ){
@@ -130867,7 +132923,7 @@ static TriggerPrg *codeRowTrigger(
       if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
        && db->mallocFailed==0 
       ){
-        iEndTrigger = sqlite3VdbeMakeLabel(v);
+        iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
         sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
       }
       sqlite3ExprDelete(db, pWhen);
@@ -131191,6 +133247,57 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
 #endif
 }
 
+/*
+** 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.
 **
@@ -131216,11 +133323,12 @@ SQLITE_PRIVATE void sqlite3Update(
   Index *pIdx;           /* For looping over indices */
   Index *pPk;            /* The PRIMARY KEY index for WITHOUT ROWID tables */
   int nIdx;              /* Number of indices that need updating */
+  int nAllIdx;           /* Total number of indexes */
   int iBaseCur;          /* Base cursor number */
   int iDataCur;          /* Cursor for the canonical data btree */
   int iIdxCur;           /* Cursor for the first index */
   sqlite3 *db;           /* The database structure */
-  int *aRegIdx = 0;      /* First register in array assigned to each index */
+  int *aRegIdx = 0;      /* Registers for to each index and the main table */
   int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                          ** an expression for the i-th column of the table.
                          ** aXRef[i]==-1 if the i-th column is not changed. */
@@ -131334,10 +133442,10 @@ SQLITE_PRIVATE void sqlite3Update(
   /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].  
   ** Initialize aXRef[] and aToOpen[] to their default values.
   */
-  aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+  aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
   if( aXRef==0 ) goto update_cleanup;
   aRegIdx = aXRef+pTab->nCol;
-  aToOpen = (u8*)(aRegIdx+nIdx);
+  aToOpen = (u8*)(aRegIdx+nIdx+1);
   memset(aToOpen, 1, nIdx+1);
   aToOpen[nIdx+1] = 0;
   for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
@@ -131414,33 +133522,32 @@ SQLITE_PRIVATE void sqlite3Update(
   /* 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++){
+  if( onError==OE_Replace ) bReplace = 1;
+  for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
     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)
-           || (onError==OE_Default && pIdx->onError==OE_Replace) 
-          ){
+          if( onError==OE_Default && pIdx->onError==OE_Replace ){
             bReplace = 1;
           }
           break;
         }
       }
     }
-    if( reg==0 ) aToOpen[j+1] = 0;
-    aRegIdx[j] = reg;
+    if( reg==0 ) aToOpen[nAllIdx+1] = 0;
+    aRegIdx[nAllIdx] = reg;
   }
+  aRegIdx[nAllIdx] = ++pParse->nMem;  /* Register storing the table record */
   if( bReplace ){
     /* If REPLACE conflict resolution might be invoked, open cursors on all 
     ** indexes in case they are needed to delete records.  */
@@ -131455,7 +133562,13 @@ SQLITE_PRIVATE void sqlite3Update(
 
   /* Allocate required registers. */
   if( !IsVirtual(pTab) ){
-    regRowSet = ++pParse->nMem;
+    /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
+    ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
+    ** reallocated.  aRegIdx[nAllIdx] is the register in which the main
+    ** table record is written.  regRowSet holds the RowSet for the
+    ** two-pass update algorithm. */
+    assert( aRegIdx[nAllIdx]==pParse->nMem );
+    regRowSet = aRegIdx[nAllIdx];
     regOldRowid = regNewRowid = ++pParse->nMem;
     if( chngPk || pTrigger || hasFK ){
       regOld = pParse->nMem + 1;
@@ -131503,7 +133616,7 @@ SQLITE_PRIVATE void sqlite3Update(
 #endif
 
   /* Jump to labelBreak to abandon further processing of this UPDATE */
-  labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
+  labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);
 
   /* Not an UPSERT.  Normal processing.  Begin by
   ** initialize the count of updated rows */
@@ -131585,6 +133698,8 @@ SQLITE_PRIVATE void sqlite3Update(
     ** leave it in register regOldRowid.  */
     sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
     if( eOnePass==ONEPASS_OFF ){
+      /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
+      aRegIdx[nAllIdx] = ++pParse->nMem;
       sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
     }
   }else{
@@ -131638,13 +133753,13 @@ SQLITE_PRIVATE void sqlite3Update(
         VdbeCoverage(v);
       }
       if( eOnePass!=ONEPASS_SINGLE ){
-        labelContinue = sqlite3VdbeMakeLabel(v);
+        labelContinue = sqlite3VdbeMakeLabel(pParse);
       }
       sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
       VdbeCoverageIf(v, pPk==0);
       VdbeCoverageIf(v, pPk!=0);
     }else if( pPk ){
-      labelContinue = sqlite3VdbeMakeLabel(v);
+      labelContinue = sqlite3VdbeMakeLabel(pParse);
       sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
       addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
       sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
@@ -131975,7 +134090,7 @@ static void updateVirtualTable(
       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) ){
@@ -132412,16 +134527,17 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
 ** transient would cause the database file to appear to be deleted
 ** following reboot.
 */
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
+SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
   Vdbe *v = sqlite3GetVdbe(pParse);
   int iDb = 0;
-  if( v==0 ) return;
+  if( v==0 ) goto build_vacuum_end;
+  if( pParse->nErr ) goto build_vacuum_end;
   if( pNm ){
 #ifndef SQLITE_BUG_COMPATIBLE_20160819
     /* Default behavior:  Report an error if the argument to VACUUM is
     ** not recognized */
     iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
-    if( iDb<0 ) return;
+    if( iDb<0 ) goto build_vacuum_end;
 #else
     /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
     ** to VACUUM are silently ignored.  This is a back-out of a bug fix that
@@ -132433,37 +134549,63 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
 #endif
   }
   if( iDb!=1 ){
-    sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
+    int iIntoReg = 0;
+    if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
+      iIntoReg = ++pParse->nMem;
+      sqlite3ExprCode(pParse, pInto, iIntoReg);
+    }
+    sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
     sqlite3VdbeUsesBtree(v, iDb);
   }
+build_vacuum_end:
+  sqlite3ExprDelete(pParse->db, pInto);
   return;
 }
 
 /*
 ** This routine implements the OP_Vacuum opcode of the VDBE.
 */
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
+  char **pzErrMsg,        /* Write error message here */
+  sqlite3 *db,            /* Database connection */
+  int iDb,                /* Which attached DB to vacuum */
+  sqlite3_value *pOut     /* Write results here, if not NULL. VACUUM INTO */
+){
   int rc = SQLITE_OK;     /* Return code from service routines */
   Btree *pMain;           /* The database being vacuumed */
   Btree *pTemp;           /* The temporary database we vacuum into */
-  u16 saved_mDbFlags;     /* Saved value of db->mDbFlags */
-  u32 saved_flags;        /* Saved value of db->flags */
+  u32 saved_mDbFlags;     /* Saved value of db->mDbFlags */
+  u64 saved_flags;        /* Saved value of db->flags */
   int saved_nChange;      /* Saved value of db->nChange */
   int saved_nTotalChange; /* Saved value of db->nTotalChange */
+  u32 saved_openFlags;    /* Saved value of db->openFlags */
   u8 saved_mTrace;        /* Saved trace settings */
   Db *pDb = 0;            /* Database to detach at end of vacuum */
   int isMemDb;            /* True if vacuuming a :memory: database */
   int nRes;               /* Bytes of reserved space at the end of each page */
   int nDb;                /* Number of attached databases */
   const char *zDbMain;    /* Schema name of database to vacuum */
+  const char *zOut;       /* Name of output file */
 
   if( !db->autoCommit ){
     sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
-    return SQLITE_ERROR;
+    return SQLITE_ERROR; /* IMP: R-12218-18073 */
   }
   if( db->nVdbeActive>1 ){
     sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
-    return SQLITE_ERROR;
+    return SQLITE_ERROR; /* IMP: R-15610-35227 */
+  }
+  saved_openFlags = db->openFlags;
+  if( pOut ){
+    if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){
+      sqlite3SetString(pzErrMsg, db, "non-text filename");
+      return SQLITE_ERROR;
+    }
+    zOut = (const char*)sqlite3_value_text(pOut);
+    db->openFlags &= ~SQLITE_OPEN_READONLY;
+    db->openFlags |= SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
+  }else{
+    zOut = "";
   }
 
   /* Save the current value of the database flags so that it can be 
@@ -132476,7 +134618,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
   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 &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
+                   | SQLITE_Defensive | SQLITE_CountRows);
   db->mTrace = 0;
 
   zDbMain = db->aDb[iDb].zDbSName;
@@ -132498,19 +134641,23 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
   ** to write the journal header file.
   */
   nDb = db->nDb;
-  rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
+  rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
+  db->openFlags = saved_openFlags;
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
   assert( (db->nDb-1)==nDb );
   pDb = &db->aDb[nDb];
   assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
   pTemp = pDb->pBt;
-
-  /* The call to execSql() to attach the temp database has left the file
-  ** locked (as there was more than one active statement when the transaction
-  ** to read the schema was concluded. Unlock it here so that this doesn't
-  ** cause problems for the call to BtreeSetPageSize() below.  */
-  sqlite3BtreeCommit(pTemp);
-
+  if( pOut ){
+    sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
+    i64 sz = 0;
+    if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
+      rc = SQLITE_ERROR;
+      sqlite3SetString(pzErrMsg, db, "output file already exists");
+      goto end_of_vacuum;
+    }
+    db->mDbFlags |= DBFLAG_VacuumInto;
+  }
   nRes = sqlite3BtreeGetOptimalReserve(pMain);
 
   /* A VACUUM cannot change the pagesize of an encrypted database. */
@@ -132534,7 +134681,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
   */
   rc = execSql(db, pzErrMsg, "BEGIN");
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
-  rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
+  rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Do not attempt to change the page size for a WAL database */
@@ -132629,7 +134776,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
     };
 
     assert( 1==sqlite3BtreeIsInTrans(pTemp) );
-    assert( 1==sqlite3BtreeIsInTrans(pMain) );
+    assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );
 
     /* Copy Btree meta values */
     for(i=0; i<ArraySize(aCopy); i+=2){
@@ -132640,17 +134787,23 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
       if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
     }
 
-    rc = sqlite3BtreeCopyFile(pMain, pTemp);
+    if( pOut==0 ){
+      rc = sqlite3BtreeCopyFile(pMain, pTemp);
+    }
     if( rc!=SQLITE_OK ) goto end_of_vacuum;
     rc = sqlite3BtreeCommit(pTemp);
     if( rc!=SQLITE_OK ) goto end_of_vacuum;
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
+    if( pOut==0 ){
+      sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
+    }
 #endif
   }
 
   assert( rc==SQLITE_OK );
-  rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
+  if( pOut==0 ){
+    rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
+  }
 
 end_of_vacuum:
   /* Restore the original value of db->flags */
@@ -132992,9 +135145,13 @@ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
 ** string will be freed automatically when the table is
 ** deleted.
 */
-static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
-  int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
+static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
+  sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg);
   char **azModuleArg;
+  sqlite3 *db = pParse->db;
+  if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
+    sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
+  }
   azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
   if( azModuleArg==0 ){
     sqlite3DbFree(db, zArg);
@@ -133018,7 +135175,6 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
   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 */
 
@@ -133028,13 +135184,11 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
   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));
-  addModuleArgument(db, pTable, 0);
-  addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
+  addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName));
+  addModuleArgument(pParse, pTable, 0);
+  addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName));
   assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
        || (pParse->sNameToken.z==pName1->z && pName2->z==0)
   );
@@ -133049,6 +135203,8 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
   ** 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);
   }
@@ -133065,7 +135221,7 @@ static void addArgumentToVtab(Parse *pParse){
     const char *z = (const char*)pParse->sArg.z;
     int n = pParse->sArg.n;
     sqlite3 *db = pParse->db;
-    addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
+    addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
   }
 }
 
@@ -133354,7 +135510,8 @@ static int growVTrans(sqlite3 *db){
   /* Grow the sqlite3.aVTrans array if required */
   if( (db->nVTrans%ARRAY_INCR)==0 ){
     VTable **aVTrans;
-    int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
+    sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)*
+                                 ((sqlite3_int64)db->nVTrans + ARRAY_INCR);
     aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
     if( !aVTrans ){
       return SQLITE_NOMEM_BKPT;
@@ -133527,6 +135684,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
     p = vtabDisconnectAll(db, pTab);
     xDestroy = p->pMod->pModule->xDestroy;
     assert( xDestroy!=0 );  /* Checked before the virtual table is created */
+    pTab->nTabRef++;
     rc = xDestroy(p->pVtab);
     /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
     if( rc==SQLITE_OK ){
@@ -133535,6 +135693,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
       pTab->pVTable = 0;
       sqlite3VtabUnlock(p);
     }
+    sqlite3DeleteTable(db, pTab);
   }
 
   return rc;
@@ -133692,6 +135851,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
       const sqlite3_module *pMod = pVTab->pMod->pModule;
       if( pVTab->pVtab && pMod->iVersion>=2 ){
         int (*xMethod)(sqlite3_vtab *, int);
+        sqlite3VtabLock(pVTab);
         switch( op ){
           case SAVEPOINT_BEGIN:
             xMethod = pMod->xSavepoint;
@@ -133707,6 +135867,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
         if( xMethod && pVTab->iSavepoint>iSavepoint ){
           rc = xMethod(pVTab->pVtab, iSavepoint);
         }
+        sqlite3VtabUnlock(pVTab);
       }
     }
   }
@@ -133743,7 +135904,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
   /* 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;
@@ -133848,9 +136009,9 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
   pTab->pSchema = db->aDb[0].pSchema;
   assert( pTab->nModuleArg==0 );
   pTab->iPKey = -1;
-  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
-  addModuleArgument(db, pTab, 0);
-  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+  addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
+  addModuleArgument(pParse, pTab, 0);
+  addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
   rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
   if( rc ){
     sqlite3ErrorMsg(pParse, "%s", zErr);
@@ -133975,6 +136136,8 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
 ** planner logic in "where.c".  These definitions are broken out into
 ** a separate source file for easier editing.
 */
+#ifndef SQLITE_WHEREINT_H
+#define SQLITE_WHEREINT_H
 
 /*
 ** Trace output macros
@@ -134363,12 +136526,33 @@ struct WhereLoopBuilder {
   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 */
 #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
@@ -134447,8 +136631,11 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
 # define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
 #endif
 SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+  Parse *pParse,       /* Parsing context */
+  Vdbe *v,             /* Prepared statement under construction */
   WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
   int iLevel,          /* Which level of pWInfo->a[] should be coded */
+  WhereLevel *pLevel,  /* The current level pointer */
   Bitmask notReady     /* Which tables are currently available */
 );
 
@@ -134522,6 +136709,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
 #define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
 #define WHERE_IN_EARLYOUT  0x00040000  /* Perhaps quit IN loops early */
 
+#endif /* !defined(SQLITE_WHEREINT_H) */
+
 /************** End of whereInt.h ********************************************/
 /************** Continuing where we left off in wherecode.c ******************/
 
@@ -134718,6 +136907,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
     }
 #endif
     zMsg = sqlite3StrAccumFinish(&str);
+    sqlite3ExplainBreakpoint("",zMsg);
     ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
                             pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
   }
@@ -134930,7 +137120,7 @@ static Expr *removeUnindexableInClauseTerms(
     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 );
@@ -135043,16 +137233,17 @@ static int codeEqualityTerm(
       if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
     }
 
+    iTab = 0;
     if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
-      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
+      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
     }else{
       sqlite3 *db = pParse->db;
       pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
 
       if( !db->mallocFailed ){
         aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
-        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
-        pTerm->pExpr->iTable = pX->iTable;
+        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
+        pTerm->pExpr->iTable = iTab;
       }
       sqlite3ExprDelete(db, pX);
       pX = pTerm->pExpr;
@@ -135062,7 +137253,6 @@ static int codeEqualityTerm(
       testcase( bRev );
       bRev = !bRev;
     }
-    iTab = pX->iTable;
     sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
     VdbeCoverageIf(v, bRev);
     VdbeCoverageIf(v, !bRev);
@@ -135070,7 +137260,7 @@ static int codeEqualityTerm(
 
     pLoop->wsFlags |= WHERE_IN_ABLE;
     if( pLevel->u.in.nIn==0 ){
-      pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+      pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
     }
 
     i = pLevel->u.in.nIn;
@@ -135086,7 +137276,6 @@ static int codeEqualityTerm(
         if( pLoop->aLTerm[i]->pExpr==pX ){
           int iOut = iReg + i - iEq;
           if( eType==IN_INDEX_ROWID ){
-            testcase( nEq>1 );  /* Happens with a UNIQUE index on ROWID */
             pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
           }else{
             int iCol = aiMap ? aiMap[iMap++] : 0;
@@ -135504,7 +137693,7 @@ static void codeCursorHint(
     }
 
     /* If we survive all prior tests, that means this term is worth hinting */
-    pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
+    pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
   }
   if( pExpr!=0 ){
     sWalker.xExprCallback = codeCursorHintFixExpr;
@@ -135581,7 +137770,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
 #ifndef SQLITE_OMIT_SUBQUERY
     if( (p->flags & EP_xIsSelect) ){
       Vdbe *v = pParse->pVdbe;
-      int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
+      int iSelect;
+      assert( p->op==TK_SELECT );
+      iSelect = sqlite3CodeSubselect(pParse, p);
       sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
     }else
 #endif
@@ -135622,7 +137813,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
     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;
@@ -135662,27 +137853,54 @@ static void whereIndexExprTrans(
   }
 }
 
+/*
+** The pTruth expression is always true because it is the WHERE clause
+** a partial index that is driving a query loop.  Look through all of the
+** WHERE clause terms on the query, and if any of those terms must be
+** true because pTruth is true, then mark those WHERE clause terms as
+** coded.
+*/
+static void whereApplyPartialIndexConstraints(
+  Expr *pTruth,
+  int iTabCur,
+  WhereClause *pWC
+){
+  int i;
+  WhereTerm *pTerm;
+  while( pTruth->op==TK_AND ){
+    whereApplyPartialIndexConstraints(pTruth->pLeft, iTabCur, pWC);
+    pTruth = pTruth->pRight;
+  }
+  for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+    Expr *pExpr;
+    if( pTerm->wtFlags & TERM_CODED ) continue;
+    pExpr = pTerm->pExpr;
+    if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
+      pTerm->wtFlags |= TERM_CODED;
+    }
+  }
+}
+
 /*
 ** Generate code for the start of the iLevel-th loop in the WHERE clause
 ** implementation described by pWInfo.
 */
 SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+  Parse *pParse,       /* Parsing context */
+  Vdbe *v,             /* Prepared statement under construction */
   WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
   int iLevel,          /* Which level of pWInfo->a[] should be coded */
+  WhereLevel *pLevel,  /* The current level pointer */
   Bitmask notReady     /* Which tables are currently available */
 ){
   int j, k;            /* Loop counters */
   int iCur;            /* The VDBE cursor for the table */
   int addrNxt;         /* Where to jump to continue with the next IN case */
-  int omitTable;       /* True if we use the index only */
   int bRev;            /* True if we need to scan in reverse order */
-  WhereLevel *pLevel;  /* The where level to be coded */
   WhereLoop *pLoop;    /* The WhereLoop object being coded */
   WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
   WhereTerm *pTerm;               /* A WHERE clause term */
-  Parse *pParse;                  /* Parsing context */
   sqlite3 *db;                    /* Database connection */
-  Vdbe *v;                        /* The prepared stmt under constructions */
   struct SrcList_item *pTabItem;  /* FROM clause term being coded */
   int addrBrk;                    /* Jump here to break out of the loop */
   int addrHalt;                   /* addrBrk for the outermost loop */
@@ -135692,18 +137910,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
   Index *pIdx = 0;          /* Index used by loop (if any) */
   int iLoop;                /* Iteration of constraint generator loop */
 
-  pParse = pWInfo->pParse;
-  v = pParse->pVdbe;
   pWC = &pWInfo->sWC;
   db = pParse->db;
-  pLevel = &pWInfo->a[iLevel];
   pLoop = pLevel->pWLoop;
   pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
   iCur = pTabItem->iCursor;
   pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
   bRev = (pWInfo->revMask>>iLevel)&1;
-  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
-           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
   VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
 
   /* Create labels for the "break" and "continue" instructions
@@ -135716,8 +137929,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
   ** there are no IN operators in the constraints, the "addrNxt" label
   ** is the same as "addrBrk".
   */
-  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
-  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
+  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
+  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
 
   /* If this is the right table of a LEFT OUTER JOIN, allocate and
   ** initialize a memory cell that records if this table matches any
@@ -135844,7 +138057,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     pTerm = pLoop->aLTerm[0];
     assert( pTerm!=0 );
     assert( pTerm->pExpr!=0 );
-    assert( omitTable==0 );
     testcase( pTerm->wtFlags & TERM_VIRTUAL );
     iReleaseReg = ++pParse->nMem;
     iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
@@ -135853,6 +138065,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
     VdbeCoverage(v);
     pLevel->op = OP_Noop;
+    if( (pTerm->prereqAll & pLevel->notReady)==0 ){
+      pTerm->wtFlags |= TERM_CODED;
+    }
   }else if( (pLoop->wsFlags & WHERE_IPK)!=0
          && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
   ){
@@ -135863,7 +138078,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     int memEndValue = 0;
     WhereTerm *pStart, *pEnd;
 
-    assert( omitTable==0 );
     j = 0;
     pStart = pEnd = 0;
     if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
@@ -136027,6 +138241,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     char *zEndAff = 0;           /* Affinity for end of range constraint */
     u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
     u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
+    int omitTable;               /* True if we use the index only */
+
 
     pIdx = pLoop->u.btree.pIndex;
     iIdxCur = pLevel->iIdxCur;
@@ -136228,6 +138444,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     }
 
     /* Seek the table cursor, if required */
+    omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
+           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
     if( omitTable ){
       /* pIdx is a covering index.  No need to access the main table. */
     }else if( HasRowid(pIdx->pTable) ){
@@ -136262,11 +138480,24 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     ** 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
+    **
+    ** Also, do not do this when processing one index an a multi-index
+    ** OR clause, since the transformation will become invalid once we
+    ** move forward to the next index.
+    ** https://sqlite.org/src/info/4e8e4857d32d401f
     */
-    if( pLevel->iLeftJoin==0 ){
+    if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
       whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
     }
 
+    /* If a partial index is driving the loop, try to eliminate WHERE clause
+    ** terms from the query that must be true due to the WHERE clause of
+    ** the partial index
+    */
+    if( pIdx->pPartIdxWhere ){
+      whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
+    }
+
     /* Record the instruction used to terminate the loop. */
     if( pLoop->wsFlags & WHERE_ONEROW ){
       pLevel->op = OP_Noop;
@@ -136338,7 +138569,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
     int regRowset = 0;                        /* Register for RowSet object */
     int regRowid = 0;                         /* Register holding rowid */
-    int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
+    int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
     int iRetInit;                             /* Address of regReturn init */
     int untestedTerms = 0;             /* Some terms not completely tested */
     int ii;                            /* Loop counter */
@@ -136427,10 +138658,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
         if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
         testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
         pExpr = sqlite3ExprDup(db, pExpr, 0);
-        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
+        pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
       }
       if( pAndExpr ){
-        pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr);
+        /* The extra 0x10000 bit on the opcode is masked off and does not
+        ** become part of the new Expr.op.  However, it does make the
+        ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
+        ** prevents sqlite3PExpr() from implementing AND short-circuit 
+        ** optimization, which we do not want here. */
+        pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
       }
     }
 
@@ -136454,6 +138690,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
           pOrExpr = pAndExpr;
         }
         /* Loop through table entries that match term pOrTerm. */
+        ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
         WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
         pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                       wctrlFlags, iCovCur);
@@ -136557,6 +138794,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
 
           /* Finish the loop through table entries that match term pOrTerm. */
           sqlite3WhereEnd(pSubWInfo);
+          ExplainQueryPlanPop(pParse);
         }
       }
     }
@@ -136571,7 +138809,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
     sqlite3VdbeGoto(v, pLevel->addrBrk);
     sqlite3VdbeResolveLabel(v, iLoopBody);
 
-    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
+    if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
     if( !untestedTerms ) disableTerm(pLevel, pTerm);
   }else
 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -136658,8 +138896,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
         u32 x = pLevel->iLikeRepCntr;
         if( x>0 ){
           skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
+          VdbeCoverageIf(v, (x&1)==1);
+          VdbeCoverageIf(v, (x&1)==0);
         }
-        VdbeCoverage(v);
 #endif
       }
 #ifdef WHERETRACE_ENABLED /* 0xffff */
@@ -137003,27 +139242,33 @@ static int isLikeOrGlob(
           zNew[iTo++] = zNew[iFrom];
         }
         zNew[iTo] = 0;
+        assert( 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.
+        /* If the LHS is not an ordinary column with TEXT affinity, then the
+        ** pattern prefix boundaries (both the start and end boundaries) must
+        ** not look like a number.  Otherwise the pattern might be treated as
+        ** a number, which will invalidate the LIKE optimization.
         **
-        ** 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.
+        ** Getting this right has been a persistent source of bugs in the
+        ** LIKE optimization.  See, for example:
+        **    2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
+        **    2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
+        **    2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
+        **    2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
         */
-        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 */
         ){
-          if( pLeft->op!=TK_COLUMN 
-           || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
-           || IsVirtual(pLeft->pTab)  /* Value might be numeric */
-          ){
+          int isNum;
+          double rDummy;
+          isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+          if( isNum<=0 ){
+            zNew[iTo-1]++;
+            isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+            zNew[iTo-1]--;
+          }
+          if( isNum>0 ){
             sqlite3ExprDelete(db, pPrefix);
             sqlite3ValueFree(pVal);
             return 0;
@@ -137123,7 +139368,7 @@ static int isAuxiliaryVtabOperator(
     **       MATCH(expression,vtab_column)
     */
     pCol = pList->a[1].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    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;
@@ -137145,12 +139390,12 @@ static int isAuxiliaryVtabOperator(
     ** with function names in an arbitrary case.
     */
     pCol = pList->a[0].pExpr;
-    if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+    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->pTab)->pVtab;
+      pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
       assert( pVtab!=0 );
       assert( pVtab->pModule!=0 );
       pMod = (sqlite3_module *)pVtab->pModule;
@@ -137168,10 +139413,10 @@ static int isAuxiliaryVtabOperator(
     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);
     }
@@ -137518,6 +139763,7 @@ static void exprAnalyzeOrTerm(
     ** and column is found but leave okToChngToIN false if not found.
     */
     for(j=0; j<2 && !okToChngToIN; j++){
+      Expr *pLeft = 0;
       pOrTerm = pOrWc->a;
       for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
         assert( pOrTerm->eOperator & WO_EQ );
@@ -137541,6 +139787,7 @@ static void exprAnalyzeOrTerm(
         }
         iColumn = pOrTerm->u.leftColumn;
         iCursor = pOrTerm->leftCursor;
+        pLeft = pOrTerm->pExpr->pLeft;
         break;
       }
       if( i<0 ){
@@ -137560,7 +139807,9 @@ static void exprAnalyzeOrTerm(
         assert( pOrTerm->eOperator & WO_EQ );
         if( pOrTerm->leftCursor!=iCursor ){
           pOrTerm->wtFlags &= ~TERM_OR_OK;
-        }else if( pOrTerm->u.leftColumn!=iColumn ){
+        }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR 
+               && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
+        )){
           okToChngToIN = 0;
         }else{
           int affLeft, affRight;
@@ -138123,6 +140372,7 @@ static void exprAnalyze(
   if( pExpr->op==TK_NOTNULL
    && pExpr->pLeft->op==TK_COLUMN
    && pExpr->pLeft->iColumn>=0
+   && !ExprHasProperty(pExpr, EP_FromJoin)
    && OptimizationEnabled(db, SQLITE_Stat34)
   ){
     Expr *pNewExpr;
@@ -138256,6 +140506,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
   }else if( p->x.pList ){
     mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
   }
+#ifndef SQLITE_OMIT_WINDOWFUNC
+  if( p->op==TK_FUNCTION && p->y.pWin ){
+    mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
+    mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
+  }
+#endif
   return mask;
 }
 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
@@ -138314,6 +140570,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
   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",
@@ -138324,9 +140581,10 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
     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);
   }
 }
@@ -138645,6 +140903,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
   return 0;
 }
 
+/*
+** This is whereScanInit() for the case of an index on an expression.
+** It is factored out into a separate tail-recursion subroutine so that
+** the normal whereScanInit() routine, which is a high-runner, does not
+** need to push registers onto the stack as part of its prologue.
+*/
+static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){
+  pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr);
+  return whereScanNext(pScan);
+}
+
 /*
 ** Initialize a WHERE clause scanner object.  Return a pointer to the
 ** first match.  Return NULL if there are no matches.
@@ -138677,12 +140946,19 @@ static WhereTerm *whereScanInit(
   pScan->pIdxExpr = 0;
   pScan->idxaff = 0;
   pScan->zCollName = 0;
+  pScan->opMask = opMask;
+  pScan->k = 0;
+  pScan->aiCur[0] = iCur;
+  pScan->nEquiv = 1;
+  pScan->iEquiv = 1;
   if( pIdx ){
     int j = iColumn;
     iColumn = pIdx->aiColumn[j];
     if( iColumn==XN_EXPR ){
       pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
       pScan->zCollName = pIdx->azColl[j];
+      pScan->aiColumn[0] = XN_EXPR;
+      return whereScanInitIndexExpr(pScan);
     }else if( iColumn==pIdx->pTable->iPKey ){
       iColumn = XN_ROWID;
     }else if( iColumn>=0 ){
@@ -138692,12 +140968,7 @@ static WhereTerm *whereScanInit(
   }else if( iColumn==XN_EXPR ){
     return 0;
   }
-  pScan->opMask = opMask;
-  pScan->k = 0;
-  pScan->aiCur[0] = iCur;
   pScan->aiColumn[0] = iColumn;
-  pScan->nEquiv = 1;
-  pScan->iEquiv = 1;
   return whereScanNext(pScan);
 }
 
@@ -138884,17 +141155,17 @@ static LogEst estLog(LogEst N){
 ** opcodes into OP_Copy when the table is being accessed via co-routine 
 ** instead of via table lookup.
 **
-** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
-** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
-** then each OP_Rowid is transformed into an instruction to increment the
-** value stored in its output register.
+** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
+** cursor iTabCur are transformed into OP_Sequence opcode for the
+** iAutoidxCur cursor, in order to generate unique rowids for the
+** automatic index being generated.
 */
 static void translateColumnToCopy(
   Parse *pParse,      /* Parsing context */
   int iStart,         /* Translate from this opcode to the end */
   int iTabCur,        /* OP_Column/OP_Rowid references to this table */
   int iRegister,      /* The first column is in this register */
-  int bIncrRowid      /* If non-zero, transform OP_rowid to OP_AddImm(1) */
+  int iAutoidxCur     /* If non-zero, cursor of autoindex being generated */
 ){
   Vdbe *v = pParse->pVdbe;
   VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
@@ -138908,11 +141179,9 @@ static void translateColumnToCopy(
       pOp->p2 = pOp->p3;
       pOp->p3 = 0;
     }else if( pOp->opcode==OP_Rowid ){
-      if( bIncrRowid ){
-        /* Increment the value stored in the P2 operand of the OP_Rowid. */
-        pOp->opcode = OP_AddImm;
-        pOp->p1 = pOp->p2;
-        pOp->p2 = 1;
+      if( iAutoidxCur ){
+        pOp->opcode = OP_Sequence;
+        pOp->p1 = iAutoidxCur;
       }else{
         pOp->opcode = OP_Null;
         pOp->p1 = 0;
@@ -139059,7 +141328,7 @@ static void constructAutomaticIndex(
      && (pTerm->wtFlags & TERM_VIRTUAL)==0
      && !ExprHasProperty(pExpr, EP_FromJoin)
      && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
-      pPartial = sqlite3ExprAnd(pParse->db, pPartial,
+      pPartial = sqlite3ExprAnd(pParse, pPartial,
                                 sqlite3ExprDup(pParse->db, pExpr, 0));
     }
     if( termCanDriveIndex(pTerm, pSrc, notReady) ){
@@ -139172,7 +141441,7 @@ static void constructAutomaticIndex(
     addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
   }
   if( pPartial ){
-    iContinue = sqlite3VdbeMakeLabel(v);
+    iContinue = sqlite3VdbeMakeLabel(pParse);
     sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
     pLoop->wsFlags |= WHERE_PARTIALIDX;
   }
@@ -139186,8 +141455,9 @@ static void constructAutomaticIndex(
   if( pTabItem->fg.viaCoroutine ){
     sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
     testcase( pParse->db->mallocFailed );
+    assert( pLevel->iIdxCur>0 );
     translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
-                          pTabItem->regResult, 1);
+                          pTabItem->regResult, pLevel->iIdxCur);
     sqlite3VdbeGoto(v, addrTop);
     pTabItem->fg.viaCoroutine = 0;
   }else{
@@ -139367,9 +141637,11 @@ static sqlite3_index_info *allocateIndexInfo(
 ** 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
@@ -139383,7 +141655,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   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 ){
@@ -139394,19 +141666,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   }
   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) */
 
@@ -140461,6 +142721,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
   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.
   */
@@ -140547,7 +142815,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
   rc = whereLoopXfer(db, p, pTemplate);
   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
     Index *pIndex = p->u.btree.pIndex;
-    if( pIndex && pIndex->tnum==0 ){
+    if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){
       p->u.btree.pIndex = 0;
     }
   }
@@ -140714,8 +142982,8 @@ static int whereRangeVectorLen(
 ** terms only. If it is modified, this value is restored before this 
 ** function returns.
 **
-** If pProbe->tnum==0, that means pIndex is a fake index used for the
-** INTEGER PRIMARY KEY.
+** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is 
+** a fake index used for the INTEGER PRIMARY KEY.
 */
 static int whereLoopAddBtreeIndex(
   WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
@@ -141215,6 +143483,7 @@ static int whereLoopAddBtree(
     sPk.onError = OE_Replace;
     sPk.pTable = pTab;
     sPk.szIdxRow = pTab->szTabRow;
+    sPk.idxType = SQLITE_IDXTYPE_IPK;
     aiRowEstPk[0] = pTab->nRowLogEst;
     aiRowEstPk[1] = 0;
     pFirst = pSrc->pTab->pIndex;
@@ -141305,7 +143574,7 @@ static int whereLoopAddBtree(
     b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
     /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
     assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
-    if( pProbe->tnum<=0 ){
+    if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
       /* Integer primary key index */
       pNew->wsFlags = WHERE_IPK;
 
@@ -141471,7 +143740,17 @@ static int whereLoopAddVirtualOne(
 
   /* 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 );
@@ -141648,11 +143927,11 @@ static int whereLoopAddVirtual(
   rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
 
   /* If the call to xBestIndex() with all terms enabled produced a plan
-  ** that does not require any source tables (IOW: a plan with mBest==0),
-  ** then there is no point in making any further calls to xBestIndex() 
-  ** since they will all return the same result (if the xBestIndex()
-  ** implementation is sane). */
-  if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
+  ** that does not require any source tables (IOW: a plan with mBest==0)
+  ** and does not use an IN(...) operator, then there is no point in making 
+  ** any further calls to xBestIndex() since they will all return the same
+  ** result (if the xBestIndex() implementation is sane). */
+  if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
     int seenZero = 0;             /* True if a plan with no prereqs seen */
     int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
     Bitmask mPrev = 0;
@@ -141867,9 +144146,11 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
   /* 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
@@ -141895,7 +144176,15 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
       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);
@@ -142961,7 +145250,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   pWInfo->pResultSet = pResultSet;
   pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
   pWInfo->nLevel = nTabList;
-  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
+  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
   pWInfo->wctrlFlags = wctrlFlags;
   pWInfo->iLimit = iAuxArg;
   pWInfo->savedNQueryLoop = pParse->nQueryLoop;
@@ -143235,9 +145524,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
     int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
     int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
+    assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
     if( bOnerow || (
         0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
-     && 0==(wsFlags & WHERE_VIRTUALTABLE)
+     && !IsVirtual(pTabList->a[0].pTab)
      && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
     )){
       pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
@@ -143392,7 +145682,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
         pParse, pTabList, pLevel, wctrlFlags
     );
     pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
-    notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+    notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
     pWInfo->iContinue = pLevel->addrCont;
     if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
       sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
@@ -143577,6 +145867,29 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
       continue;
     }
 
+#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
+    /* Close all of the cursors that were opened by sqlite3WhereBegin.
+    ** Except, do not close cursors that will be reused by the OR optimization
+    ** (WHERE_OR_SUBCLAUSE).  And do not close the OP_OpenWrite cursors
+    ** created for the ONEPASS optimization.
+    */
+    if( (pTab->tabFlags & TF_Ephemeral)==0
+     && pTab->pSelect==0
+     && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+    ){
+      int ws = pLoop->wsFlags;
+      if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
+        sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
+      }
+      if( (ws & WHERE_INDEXED)!=0
+       && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 
+       && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+      ){
+        sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
+      }
+    }
+#endif
+
     /* If this scan uses an index, make VDBE code substitutions to read data
     ** from the index instead of from the table where possible.  In some cases
     ** this optimization prevents the table from ever being read, which can
@@ -143851,6 +146164,96 @@ static void dense_rankValueFunc(sqlite3_context *pCtx){
   }
 }
 
+/*
+** Implementation of built-in window function nth_value(). This
+** implementation is used in "slow mode" only - when the EXCLUDE clause
+** is not set to the default value "NO OTHERS".
+*/
+struct NthValueCtx {
+  i64 nStep;
+  sqlite3_value *pValue;
+};
+static void nth_valueStepFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct NthValueCtx *p;
+  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  if( p ){
+    i64 iVal;
+    switch( sqlite3_value_numeric_type(apArg[1]) ){
+      case SQLITE_INTEGER:
+        iVal = sqlite3_value_int64(apArg[1]);
+        break;
+      case SQLITE_FLOAT: {
+        double fVal = sqlite3_value_double(apArg[1]);
+        if( ((i64)fVal)!=fVal ) goto error_out;
+        iVal = (i64)fVal;
+        break;
+      }
+      default:
+        goto error_out;
+    }
+    if( iVal<=0 ) goto error_out;
+
+    p->nStep++;
+    if( iVal==p->nStep ){
+      p->pValue = sqlite3_value_dup(apArg[0]);
+      if( !p->pValue ){
+        sqlite3_result_error_nomem(pCtx);
+      }
+    }
+  }
+  UNUSED_PARAMETER(nArg);
+  UNUSED_PARAMETER(apArg);
+  return;
+
+ error_out:
+  sqlite3_result_error(
+      pCtx, "second argument to nth_value must be a positive integer", -1
+  );
+}
+static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
+  struct NthValueCtx *p;
+  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
+  if( p && p->pValue ){
+    sqlite3_result_value(pCtx, p->pValue);
+    sqlite3_value_free(p->pValue);
+    p->pValue = 0;
+  }
+}
+#define nth_valueInvFunc noopStepFunc
+#define nth_valueValueFunc noopValueFunc
+
+static void first_valueStepFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct NthValueCtx *p;
+  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  if( p && p->pValue==0 ){
+    p->pValue = sqlite3_value_dup(apArg[0]);
+    if( !p->pValue ){
+      sqlite3_result_error_nomem(pCtx);
+    }
+  }
+  UNUSED_PARAMETER(nArg);
+  UNUSED_PARAMETER(apArg);
+}
+static void first_valueFinalizeFunc(sqlite3_context *pCtx){
+  struct NthValueCtx *p;
+  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  if( p && p->pValue ){
+    sqlite3_result_value(pCtx, p->pValue);
+    sqlite3_value_free(p->pValue);
+    p->pValue = 0;
+  }
+}
+#define first_valueInvFunc noopStepFunc
+#define first_valueValueFunc noopValueFunc
+
 /*
 ** Implementation of built-in window function rank(). Assumes that
 ** the window frame has been set to:
@@ -143886,7 +146289,7 @@ static void rankValueFunc(sqlite3_context *pCtx){
 ** Implementation of built-in window function percent_rank(). Assumes that
 ** the window frame has been set to:
 **
-**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
+**   GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
 */
 static void percent_rankStepFunc(
   sqlite3_context *pCtx, 
@@ -143894,38 +146297,44 @@ static void percent_rankStepFunc(
   sqlite3_value **apArg
 ){
   struct CallCount *p;
-  UNUSED_PARAMETER(nArg); assert( nArg==1 );
-
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  UNUSED_PARAMETER(apArg);
   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;
-    }
+    p->nTotal++;
   }
 }
+static void percent_rankInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct CallCount *p;
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  UNUSED_PARAMETER(apArg);
+  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  p->nStep++;
+}
 static void percent_rankValueFunc(sqlite3_context *pCtx){
   struct CallCount *p;
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
+    p->nValue = p->nStep;
     if( p->nTotal>1 ){
-      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
+      double r = (double)p->nValue / (double)(p->nTotal-1);
       sqlite3_result_double(pCtx, r);
     }else{
       sqlite3_result_double(pCtx, 0.0);
     }
-    p->nValue = 0;
   }
 }
+#define percent_rankFinalizeFunc percent_rankValueFunc
 
 /*
 ** Implementation of built-in window function cume_dist(). Assumes that
 ** the window frame has been set to:
 **
-**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
+**   GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
 */
 static void cume_distStepFunc(
   sqlite3_context *pCtx, 
@@ -143933,24 +146342,33 @@ static void cume_distStepFunc(
   sqlite3_value **apArg
 ){
   struct CallCount *p;
-  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
-
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  UNUSED_PARAMETER(apArg);
   p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   if( p ){
-    if( p->nTotal==0 ){
-      p->nTotal = sqlite3_value_int64(apArg[0]);
-    }
-    p->nStep++;
+    p->nTotal++;
   }
 }
+static void cume_distInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct CallCount *p;
+  UNUSED_PARAMETER(nArg); assert( nArg==0 );
+  UNUSED_PARAMETER(apArg);
+  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  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 ){
+  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
+  if( p ){
     double r = (double)(p->nStep) / (double)(p->nTotal);
     sqlite3_result_double(pCtx, r);
   }
 }
+#define cume_distFinalizeFunc cume_distValueFunc
 
 /*
 ** Context object for ntile() window function.
@@ -143965,7 +146383,7 @@ struct NtileCtx {
 ** Implementation of ntile(). This assumes that the window frame has
 ** been coerced to:
 **
-**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
+**   ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
 */
 static void ntileStepFunc(
   sqlite3_context *pCtx, 
@@ -143973,32 +146391,42 @@ static void ntileStepFunc(
   sqlite3_value **apArg
 ){
   struct NtileCtx *p;
-  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
+  assert( nArg==1 ); 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++;
+    p->nTotal++;
   }
 }
+static void ntileInvFunc(
+  sqlite3_context *pCtx, 
+  int nArg,
+  sqlite3_value **apArg
+){
+  struct NtileCtx *p;
+  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
+  UNUSED_PARAMETER(apArg);
+  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  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);
+      sqlite3_result_int64(pCtx, p->iRow+1);
     }else{
       i64 nLarge = p->nTotal - p->nParam*nSize;
       i64 iSmall = nLarge*(nSize+1);
-      i64 iRow = p->iRow-1;
+      i64 iRow = p->iRow;
 
       assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
 
@@ -144010,6 +146438,7 @@ static void ntileValueFunc(sqlite3_context *pCtx){
     }
   }
 }
+#define ntileFinalizeFunc ntileValueFunc
 
 /*
 ** Context object for last_value() window function.
@@ -144059,7 +146488,7 @@ static void last_valueInvFunc(
 }
 static void last_valueValueFunc(sqlite3_context *pCtx){
   struct LastValueCtx *p;
-  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0);
   if( p && p->pVal ){
     sqlite3_result_value(pCtx, p->pVal);
   }
@@ -144149,12 +146578,12 @@ SQLITE_PRIVATE void sqlite3WindowFunctions(void){
     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(percent_rank, 0, 0),
+    WINDOWFUNCALL(cume_dist, 0, 0),
+    WINDOWFUNCALL(ntile, 1, 0),
     WINDOWFUNCALL(last_value, 1, 0),
-    WINDOWFUNCNOOP(nth_value, 2, 0),
-    WINDOWFUNCNOOP(first_value, 1, 0),
+    WINDOWFUNCALL(nth_value, 2, 0),
+    WINDOWFUNCALL(first_value, 1, 0),
     WINDOWFUNCNOOP(lead, 1, 0),
     WINDOWFUNCNOOP(lead, 2, 0),
     WINDOWFUNCNOOP(lead, 3, 0),
@@ -144165,6 +146594,17 @@ SQLITE_PRIVATE void sqlite3WindowFunctions(void){
   sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
 }
 
+static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
+  Window *p;
+  for(p=pList; p; p=p->pNextWin){
+    if( sqlite3StrICmp(p->zName, zName)==0 ) break;
+  }
+  if( p==0 ){
+    sqlite3ErrorMsg(pParse, "no such window: %s", zName);
+  }
+  return p;
+}
+
 /*
 ** This function is called immediately after resolving the function name
 ** for a window function within a SELECT statement. Argument pList is a
@@ -144188,48 +146628,66 @@ SQLITE_PRIVATE void sqlite3WindowUpdate(
   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;
-    }
+  if( pWin->zName && pWin->eFrmType==0 ){
+    Window *p = windowFind(pParse, pList, pWin->zName);
+    if( p==0 ) 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;
+    pWin->eFrmType = p->eFrmType;
+    pWin->eExclude = p->eExclude;
+  }else{
+    sqlite3WindowChain(pParse, pWin, pList);
   }
+  if( (pWin->eFrmType==TK_RANGE)
+   && (pWin->pStart || pWin->pEnd) 
+   && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
+  ){
+    sqlite3ErrorMsg(pParse, 
+      "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
+    );
+  }else
   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;
+    }else{
+      struct WindowUpdate {
+        const char *zFunc;
+        int eFrmType;
+        int eStart;
+        int eEnd;
+      } aUp[] = {
+        { row_numberName,   TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
+        { dense_rankName,   TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
+        { rankName,         TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
+        { percent_rankName, TK_GROUPS, TK_CURRENT,   TK_UNBOUNDED }, 
+        { cume_distName,    TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, 
+        { ntileName,        TK_ROWS,   TK_CURRENT,   TK_UNBOUNDED }, 
+        { leadName,         TK_ROWS,   TK_UNBOUNDED, TK_UNBOUNDED }, 
+        { lagName,          TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
+      };
+      int i;
+      for(i=0; i<ArraySize(aUp); i++){
+        if( pFunc->zName==aUp[i].zFunc ){
+          sqlite3ExprDelete(db, pWin->pStart);
+          sqlite3ExprDelete(db, pWin->pEnd);
+          pWin->pEnd = pWin->pStart = 0;
+          pWin->eFrmType = aUp[i].eFrmType;
+          pWin->eStart = aUp[i].eStart;
+          pWin->eEnd = aUp[i].eEnd;
+          pWin->eExclude = 0;
+          if( pWin->eStart==TK_FOLLOWING ){
+            pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
+          }
+          break;
+        }
+      }
     }
   }
   pWin->pFunc = pFunc;
@@ -144244,6 +146702,7 @@ struct WindowRewrite {
   Window *pWin;
   SrcList *pSrc;
   ExprList *pSub;
+  Table *pTab;
   Select *pSubSelect;             /* Current sub-select, if any */
 };
 
@@ -144277,12 +146736,12 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
   switch( pExpr->op ){
 
     case TK_FUNCTION:
-      if( pExpr->pWin==0 ){
+      if( !ExprHasProperty(pExpr, EP_WinFunc) ){
         break;
       }else{
         Window *pWin;
         for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
-          if( pExpr->pWin==pWin ){
+          if( pExpr->y.pWin==pWin ){
             assert( pWin->pOwner==pExpr );
             return WRC_Prune;
           }
@@ -144304,6 +146763,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
         pExpr->op = TK_COLUMN;
         pExpr->iColumn = p->pSub->nExpr-1;
         pExpr->iTable = p->pWin->iEphCsr;
+        pExpr->y.pTab = p->pTab;
       }
 
       break;
@@ -144347,6 +146807,7 @@ static void selectWindowRewriteEList(
   Window *pWin,
   SrcList *pSrc,
   ExprList *pEList,               /* Rewrite expressions in this list */
+  Table *pTab,
   ExprList **ppSub                /* IN/OUT: Sub-select expression-list */
 ){
   Walker sWalker;
@@ -144358,6 +146819,7 @@ static void selectWindowRewriteEList(
   sRewrite.pSub = *ppSub;
   sRewrite.pWin = pWin;
   sRewrite.pSrc = pSrc;
+  sRewrite.pTab = pTab;
 
   sWalker.pParse = pParse;
   sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -144376,13 +146838,18 @@ static void selectWindowRewriteEList(
 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 */
+  ExprList *pAppend,      /* List of values to append. Might be NULL */
+  int bIntToNull
 ){
   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);
+      if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
+        pDup->op = TK_NULL;
+        pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
+      }
       pList = sqlite3ExprListAppend(pParse, pList, pDup);
       if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
     }
@@ -144399,7 +146866,7 @@ static ExprList *exprListAppendList(
 */
 SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
   int rc = SQLITE_OK;
-  if( p->pWin ){
+  if( p->pWin && p->pPrior==0 ){
     Vdbe *v = sqlite3GetVdbe(pParse);
     sqlite3 *db = pParse->db;
     Select *pSub = 0;             /* The subquery */
@@ -144412,17 +146879,24 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
     ExprList *pSublist = 0;       /* Expression list for sub-query */
     Window *pMWin = p->pWin;      /* Master window object */
     Window *pWin;                 /* Window object iterator */
+    Table *pTab;
+
+    pTab = sqlite3DbMallocZero(db, sizeof(Table));
+    if( pTab==0 ){
+      return SQLITE_NOMEM;
+    }
 
     p->pSrc = 0;
     p->pWhere = 0;
     p->pGroupBy = 0;
     p->pHaving = 0;
+    p->selFlags &= ~SF_Aggregate;
 
     /* 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);
+    pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
     if( pSort && p->pOrderBy ){
       if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
         sqlite3ExprListDelete(db, p->pOrderBy);
@@ -144434,16 +146908,17 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
     ** The OpenEphemeral instruction is coded later, after it is known how
     ** many columns the table will have.  */
     pMWin->iEphCsr = pParse->nTab++;
+    pParse->nTab += 3;
 
-    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
-    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
+    selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &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);
+    pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
+    pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
 
     /* Append the arguments passed to each window function to the
     ** sub-select expression list. Also allocate two registers for each
@@ -144451,7 +146926,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
     ** results.  */
     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
       pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
-      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
+      pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
       if( pWin->pFilter ){
         Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
         pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
@@ -144476,24 +146951,30 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
     pSub = sqlite3SelectNew(
         pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
     );
-    p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
-    assert( p->pSrc || db->mallocFailed );
+    p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
     if( p->pSrc ){
+      Table *pTab2;
       p->pSrc->a[0].pSelect = pSub;
       sqlite3SrcListAssignCursors(pParse, p->pSrc);
-      if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+      pSub->selFlags |= SF_Expanded;
+      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
+      if( pTab2==0 ){
         rc = SQLITE_NOMEM;
       }else{
-        pSub->selFlags |= SF_Expanded;
-        p->selFlags &= ~SF_Aggregate;
-        sqlite3SelectPrep(pParse, pSub, 0);
+        memcpy(pTab, pTab2, sizeof(Table));
+        pTab->tabFlags |= TF_Ephemeral;
+        p->pSrc->a[0].pTab = pTab;
+        pTab = pTab2;
       }
-
       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
+      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
+      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
+      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
     }else{
       sqlite3SelectDelete(db, pSub);
     }
     if( db->mallocFailed ) rc = SQLITE_NOMEM;
+    sqlite3DbFree(db, pTab);
   }
 
   return rc;
@@ -144510,6 +146991,7 @@ SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){
     sqlite3ExprDelete(db, p->pEnd);
     sqlite3ExprDelete(db, p->pStart);
     sqlite3DbFree(db, p->zName);
+    sqlite3DbFree(db, p->zBase);
     sqlite3DbFree(db, p);
   }
 }
@@ -144534,6 +147016,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
 */
 static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
   if( 0==sqlite3ExprIsConstant(pExpr) ){
+    if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
     sqlite3ExprDelete(pParse->db, pExpr);
     pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
   }
@@ -144545,16 +147028,18 @@ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
 */
 SQLITE_PRIVATE Window *sqlite3WindowAlloc(
   Parse *pParse,    /* Parsing context */
-  int eType,        /* Frame type. TK_RANGE or TK_ROWS */
+  int eType,        /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
   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 */
+  Expr *pEnd,       /* End window size if TK_FOLLOWING or PRECEDING */
+  u8 eExclude       /* EXCLUDE clause */
 ){
   Window *pWin = 0;
+  int bImplicitFrame = 0;
 
   /* Parser assures the following: */
-  assert( eType==TK_RANGE || eType==TK_ROWS );
+  assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
   assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
            || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
   assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
@@ -144562,13 +147047,9 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(
   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;
+  if( eType==0 ){
+    bImplicitFrame = 1;
+    eType = TK_RANGE;
   }
 
   /* Additionally, the
@@ -144588,15 +147069,20 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(
   if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
    || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
   ){
-    sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
+    sqlite3ErrorMsg(pParse, "unsupported frame specification");
     goto windowAllocErr;
   }
 
   pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
   if( pWin==0 ) goto windowAllocErr;
-  pWin->eType = eType;
+  pWin->eFrmType = eType;
   pWin->eStart = eStart;
   pWin->eEnd = eEnd;
+  if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){
+    eExclude = TK_NO;
+  }
+  pWin->eExclude = eExclude;
+  pWin->bImplicitFrame = bImplicitFrame;
   pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
   pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
   return pWin;
@@ -144607,16 +147093,81 @@ windowAllocErr:
   return 0;
 }
 
+/*
+** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
+** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
+** equivalent nul-terminated string.
+*/
+SQLITE_PRIVATE Window *sqlite3WindowAssemble(
+  Parse *pParse, 
+  Window *pWin, 
+  ExprList *pPartition, 
+  ExprList *pOrderBy, 
+  Token *pBase
+){
+  if( pWin ){
+    pWin->pPartition = pPartition;
+    pWin->pOrderBy = pOrderBy;
+    if( pBase ){
+      pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
+    }
+  }else{
+    sqlite3ExprListDelete(pParse->db, pPartition);
+    sqlite3ExprListDelete(pParse->db, pOrderBy);
+  }
+  return pWin;
+}
+
+/*
+** Window *pWin has just been created from a WINDOW clause. Tokne pBase
+** is the base window. Earlier windows from the same WINDOW clause are
+** stored in the linked list starting at pWin->pNextWin. This function
+** either updates *pWin according to the base specification, or else
+** leaves an error in pParse.
+*/
+SQLITE_PRIVATE void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
+  if( pWin->zBase ){
+    sqlite3 *db = pParse->db;
+    Window *pExist = windowFind(pParse, pList, pWin->zBase);
+    if( pExist ){
+      const char *zErr = 0;
+      /* Check for errors */
+      if( pWin->pPartition ){
+        zErr = "PARTITION clause";
+      }else if( pExist->pOrderBy && pWin->pOrderBy ){
+        zErr = "ORDER BY clause";
+      }else if( pExist->bImplicitFrame==0 ){
+        zErr = "frame specification";
+      }
+      if( zErr ){
+        sqlite3ErrorMsg(pParse, 
+            "cannot override %s of window: %s", zErr, pWin->zBase
+        );
+      }else{
+        pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
+        if( pExist->pOrderBy ){
+          assert( pWin->pOrderBy==0 );
+          pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
+        }
+        sqlite3DbFree(db, pWin->zBase);
+        pWin->zBase = 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->pWin = pWin;
+      p->y.pWin = pWin;
+      ExprSetProperty(p, EP_WinFunc);
       pWin->pOwner = p;
       if( p->flags & EP_Distinct ){
         sqlite3ErrorMsg(pParse,
@@ -144633,9 +147184,10 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
 ** 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->eFrmType!=p2->eFrmType ) return 1;
   if( p1->eStart!=p2->eStart ) return 1;
   if( p1->eEnd!=p2->eEnd ) return 1;
+  if( p1->eExclude!=p2->eExclude ) 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;
@@ -144652,12 +147204,27 @@ SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
 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 ){
+
+  /* Allocate registers to use for PARTITION BY values, if any. Initialize
+  ** said registers to NULL.  */
+  if( pMWin->pPartition ){
+    int nExpr = pMWin->pPartition->nExpr;
     pMWin->regPart = pParse->nMem+1;
-    pParse->nMem += nPart;
-    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
+    pParse->nMem += nExpr;
+    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
+  }
+
+  pMWin->regOne = ++pParse->nMem;
+  sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
+
+  if( pMWin->eExclude ){
+    pMWin->regStartRowid = ++pParse->nMem;
+    pMWin->regEndRowid = ++pParse->nMem;
+    pMWin->csrApp = pParse->nTab++;
+    sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
+    sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
+    return;
   }
 
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
@@ -144686,20 +147253,24 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
     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);
     }
   }
 }
 
+#define WINDOW_STARTING_INT  0
+#define WINDOW_ENDING_INT    1
+#define WINDOW_NTH_VALUE_INT 2
+#define WINDOW_STARTING_NUM  3
+#define WINDOW_ENDING_NUM    4
+
 /*
 ** 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
@@ -144707,25 +147278,43 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
 ** 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 void windowCheckValue(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"
+    "second argument to nth_value must be a positive integer",
+    "frame starting offset must be a non-negative number",
+    "frame ending offset must be a non-negative number",
   };
-  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
+  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
   Vdbe *v = sqlite3GetVdbe(pParse);
   int regZero = sqlite3GetTempReg(pParse);
-  assert( eCond==0 || eCond==1 || eCond==2 );
+  assert( eCond>=0 && eCond<ArraySize(azErr) );
   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);
+  if( eCond>=WINDOW_STARTING_NUM ){
+    int regString = sqlite3GetTempReg(pParse);
+    sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+    sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
+    sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
+    VdbeCoverage(v);
+    assert( eCond==3 || eCond==4 );
+    VdbeCoverageIf(v, eCond==3);
+    VdbeCoverageIf(v, eCond==4);
+  }else{
+    sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
+    VdbeCoverage(v);
+    assert( eCond==0 || eCond==1 || eCond==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==0); /* NULL case captured by */
+  VdbeCoverageNeverNullIf(v, eCond==1); /*   the OP_MustBeInt */
   VdbeCoverageNeverNullIf(v, eCond==2);
+  VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
+  VdbeCoverageNeverNullIf(v, eCond==4); /*   the OP_Ge */
+  sqlite3MayAbort(pParse);
   sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
   sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
   sqlite3ReleaseTempReg(pParse, regZero);
@@ -144764,37 +147353,28 @@ static void windowAggStep(
   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 */
+  int reg                         /* Array of registers */
 ){
   Vdbe *v = sqlite3GetVdbe(pParse);
   Window *pWin;
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-    int flags = pWin->pFunc->funcFlags;
+    FuncDef *pFunc = pWin->pFunc;
     int regArg;
     int nArg = windowArgCount(pWin);
+    int i;
 
-    if( csr>=0 ){
-      int i;
-      for(i=0; i<nArg; i++){
+    for(i=0; i<nArg; i++){
+      if( i!=1 || pFunc->zName!=nth_valueName ){
         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
+      }else{
+        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, 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;
     }
+    regArg = reg;
 
-    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
-      && pWin->eStart!=TK_UNBOUNDED 
+    if( pMWin->regStartRowid==0
+     && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
+     && (pWin->eStart!=TK_UNBOUNDED)
     ){
       int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
       VdbeCoverage(v);
@@ -144811,34 +147391,24 @@ static void windowAggStep(
       }
       sqlite3VdbeJumpHere(v, addrIsNull);
     }else if( pWin->regApp ){
-      assert( pWin->pFunc->zName==nth_valueName
-           || pWin->pFunc->zName==first_valueName
+      assert( pFunc->zName==nth_valueName
+           || 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{
+    }else if( pFunc->xSFunc!=noopStepFunc ){
       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;
-        }
+        regTmp = sqlite3GetTempReg(pParse);
+        sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
         addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
         VdbeCoverage(v);
-        if( csr>0 ){
-          sqlite3ReleaseTempReg(pParse, regTmp);
-        }
+        sqlite3ReleaseTempReg(pParse, regTmp);
       }
-      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+      if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
         CollSeq *pColl;
         assert( nArg>0 );
         pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
@@ -144846,45 +147416,96 @@ static void windowAggStep(
       }
       sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
                         bInverse, regArg, pWin->regAccum);
-      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+      sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
       sqlite3VdbeChangeP5(v, (u8)nArg);
       if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
     }
   }
 }
 
+typedef struct WindowCodeArg WindowCodeArg;
+typedef struct WindowCsrAndReg WindowCsrAndReg;
+struct WindowCsrAndReg {
+  int csr;
+  int reg;
+};
+
+struct WindowCodeArg {
+  Parse *pParse;
+  Window *pMWin;
+  Vdbe *pVdbe;
+  int regGosub;
+  int addrGosub;
+  int regArg;
+  int eDelete;
+
+  WindowCsrAndReg start;
+  WindowCsrAndReg current;
+  WindowCsrAndReg end;
+};
+
 /*
-** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
-** (bFinal==1) for each window function in the linked list starting at
+** Values that may be passed as the second argument to windowCodeOp().
+*/
+#define WINDOW_RETURN_ROW 1
+#define WINDOW_AGGINVERSE 2
+#define WINDOW_AGGSTEP    3
+
+/*
+** Generate VM code to read the window frames peer values from cursor csr into
+** an array of registers starting at reg.
+*/
+static void windowReadPeerValues(
+  WindowCodeArg *p,
+  int csr,
+  int reg
+){
+  Window *pMWin = p->pMWin;
+  ExprList *pOrderBy = pMWin->pOrderBy;
+  if( pOrderBy ){
+    Vdbe *v = sqlite3GetVdbe(p->pParse);
+    ExprList *pPart = pMWin->pPartition;
+    int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
+    int i;
+    for(i=0; i<pOrderBy->nExpr; i++){
+      sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
+    }
+  }
+}
+
+/*
+** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
+** (bFin==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){
+static void windowAggFinal(WindowCodeArg *p, int bFin){
+  Parse *pParse = p->pParse;
+  Window *pMWin = p->pMWin;
   Vdbe *v = sqlite3GetVdbe(pParse);
   Window *pWin;
 
   for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
-     && pWin->eStart!=TK_UNBOUNDED 
+    if( pMWin->regStartRowid==0
+     && (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 ){
+      assert( pMWin->regStartRowid==0 );
     }else{
-      if( bFinal ){
-        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
+      int nArg = windowArgCount(pWin);
+      if( bFin ){
+        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
         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);
+        sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
         sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
       }
     }
@@ -144892,66 +147513,97 @@ static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
 }
 
 /*
-** 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.
+** Generate code to calculate the current values of all window functions in the
+** p->pMWin list by doing a full scan of the current window frame. Store the
+** results in the Window.regResult registers, ready to return the upper
+** layer.
 */
-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;
+static void windowFullScan(WindowCodeArg *p){
+  Window *pWin;
+  Parse *pParse = p->pParse;
+  Window *pMWin = p->pMWin;
+  Vdbe *v = p->pVdbe;
 
-  int reg = pParse->nMem+1;
-  int regRecord = reg+nSub;
-  int regRowid = regRecord+1;
+  int regCRowid = 0;              /* Current rowid value */
+  int regCPeer = 0;               /* Current peer values */
+  int regRowid = 0;               /* AggStep rowid value */
+  int regPeer = 0;                /* AggStep peer values */
 
-  *pRegSize = regRowid;
-  pParse->nMem += nSub + 2;
+  int nPeer;
+  int lblNext;
+  int lblBrk;
+  int addrNext;
+  int csr = pMWin->csrApp;
 
-  /* 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);
+  nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+
+  lblNext = sqlite3VdbeMakeLabel(pParse);
+  lblBrk = sqlite3VdbeMakeLabel(pParse);
+
+  regCRowid = sqlite3GetTempReg(pParse);
+  regRowid = sqlite3GetTempReg(pParse);
+  if( nPeer ){
+    regCPeer = sqlite3GetTempRange(pParse, nPeer);
+    regPeer = sqlite3GetTempRange(pParse, nPeer);
   }
-  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 ){
+  sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
+  windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
+
+  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+  }
+
+  sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
+  VdbeCoverage(v);
+  addrNext = sqlite3VdbeCurrentAddr(v);
+  sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
+  sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
+  VdbeCoverageNeverNull(v);
+
+  if( pMWin->eExclude==TK_CURRENT ){
+    sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
+    VdbeCoverageNeverNull(v);
+  }else if( pMWin->eExclude!=TK_NO ){
     int addr;
-    ExprList *pPart = pMWin->pPartition;
-    int nPart = pPart->nExpr;
-    int regNewPart = reg + pMWin->nBufferCol;
-    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+    int addrEq = 0;
+    KeyInfo *pKeyInfo = 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"));
+    if( pMWin->pOrderBy ){
+      pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
+    }
+    if( pMWin->eExclude==TK_TIES ){
+      addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
+      VdbeCoverageNeverNull(v);
+    }
+    if( pKeyInfo ){
+      windowReadPeerValues(p, csr, regPeer);
+      sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
+      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+      addr = sqlite3VdbeCurrentAddr(v)+1;
+      sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
+      VdbeCoverageEqNe(v);
+    }else{
+      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
+    }
+    if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
   }
 
-  /* Buffer the current row in the ephemeral table. */
-  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
-  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
+  windowAggStep(pParse, pMWin, csr, 0, p->regArg);
 
-  /* End of the input loop */
-  sqlite3WhereEnd(pWInfo);
+  sqlite3VdbeResolveLabel(v, lblNext);
+  sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
+  VdbeCoverage(v);
+  sqlite3VdbeJumpHere(v, addrNext-1);
+  sqlite3VdbeJumpHere(v, addrNext+1);
+  sqlite3ReleaseTempReg(pParse, regRowid);
+  sqlite3ReleaseTempReg(pParse, regCRowid);
+  if( nPeer ){
+    sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
+    sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
+  }
 
-  /* Invoke "flush_partition" to deal with the final (or only) partition */
-  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
-  VdbeComment((v, "call flush_partition"));
+  windowAggFinal(p, 1);
 }
 
 /*
@@ -144967,110 +147619,74 @@ static void windowPartitionCache(
 **   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);
+static void windowReturnOneRow(WindowCodeArg *p){
+  Window *pMWin = p->pMWin;
+  Vdbe *v = p->pVdbe;
 
-      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( pMWin->regStartRowid ){
+    windowFullScan(p);
+  }else{
+    Parse *pParse = p->pParse;
+    Window *pWin;
 
-      if( nArg<3 ){
+    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(pParse);
+        int tmpReg = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
-      }else{
-        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
+  
+        if( pFunc->zName==nth_valueName ){
+          sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg);
+          windowCheckValue(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);
       }
-      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);
+      else if( pFunc->zName==leadName || pFunc->zName==lagName ){
+        int nArg = pWin->pOwner->x.pList->nExpr;
+        int csr = pWin->csrApp;
+        int lbl = sqlite3VdbeMakeLabel(pParse);
+        int tmpReg = sqlite3GetTempReg(pParse);
+        int iEph = pMWin->iEphCsr;
+  
+        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);
       }
-
-      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 */
+  sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
 }
 
 /*
@@ -145088,17 +147704,17 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
     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( pMWin->regStartRowid==0 ){
+      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);
+      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;
@@ -145106,672 +147722,248 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
   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)
-**     }
-**
+/* 
+** Return true if the current frame should be cached in the ephemeral table,
+** even if there are no xInverse() calls required.
 */
-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);
+static int windowCacheFrame(Window *pMWin){
+  Window *pWin;
+  if( pMWin->regStartRowid ) return 1;
+  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+    FuncDef *pFunc = pWin->pFunc;
+    if( (pFunc->zName==nth_valueName)
+     || (pFunc->zName==first_valueName)
+     || (pFunc->zName==leadName)
+     || (pFunc->zName==lagName)
+    ){
+      return 1;
     }
   }
-
-  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);
+  return 0;
 }
 
 /*
-** 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.
+** regOld and regNew are each the first register in an array of size
+** pOrderBy->nExpr. This function generates code to compare the two
+** arrays of registers using the collation sequences and other comparison
+** parameters specified by pOrderBy. 
 **
-** 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
+** If the two arrays are not equal, the contents of regNew is copied to 
+** regOld and control falls through. Otherwise, if the contents of the arrays
+** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
 */
-static void windowCodeCacheStep(
-  Parse *pParse, 
-  Select *p,
-  WhereInfo *pWInfo,
-  int regGosub, 
-  int addrGosub
+static void windowIfNewPeer(
+  Parse *pParse,
+  ExprList *pOrderBy,
+  int regNew,                     /* First in array of new values */
+  int regOld,                     /* First in array of old values */
+  int addr                        /* Jump here */
 ){
-  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( pOrderBy ){
+    int nVal = pOrderBy->nExpr;
+    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
+    sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
+    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+    sqlite3VdbeAddOp3(v, OP_Jump, 
+      sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
     );
-    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+    VdbeCoverageEqNe(v);
+    sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
+  }else{
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
   }
-
-  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);
 }
 
+/*
+** This function is called as part of generating VM programs for RANGE
+** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
+** the ORDER BY term in the window, it generates code equivalent to:
+**
+**   if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
+**
+** A special type of arithmetic is used such that if csr.peerVal is not
+** a numeric type (real or integer), then the result of the addition is
+** a copy of csr1.peerVal.
+*/
+static void windowCodeRangeTest(
+  WindowCodeArg *p, 
+  int op,                          /* OP_Ge or OP_Gt */
+  int csr1, 
+  int regVal, 
+  int csr2,
+  int lbl
+){
+  Parse *pParse = p->pParse;
+  Vdbe *v = sqlite3GetVdbe(pParse);
+  int reg1 = sqlite3GetTempReg(pParse);
+  int reg2 = sqlite3GetTempReg(pParse);
+  int arith = OP_Add;
+  int addrGe;
+
+  int regString = ++pParse->nMem;
+
+  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
+  assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
+  if( p->pMWin->pOrderBy->a[0].sortOrder ){
+    switch( op ){
+      case OP_Ge: op = OP_Le; break;
+      case OP_Gt: op = OP_Lt; break;
+      default: assert( op==OP_Le ); op = OP_Ge; break;
+    }
+    arith = OP_Subtract;
+  }
+
+  windowReadPeerValues(p, csr1, reg1);
+  windowReadPeerValues(p, csr2, reg2);
+
+  /* Check if the peer value for csr1 value is a text or blob by comparing
+  ** it to the smallest possible string - ''. If it is, jump over the
+  ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
+  sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+  addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
+  VdbeCoverage(v);
+  sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
+  sqlite3VdbeJumpHere(v, addrGe);
+  sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
+  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+  assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
+  testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
+  testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
+  testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
+  testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
+
+  sqlite3ReleaseTempReg(pParse, reg1);
+  sqlite3ReleaseTempReg(pParse, reg2);
+}
 
 /*
-** 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".
+** Helper function for sqlite3WindowCodeStep(). Each call to this function
+** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE 
+** operation. Refer to the header comment for sqlite3WindowCodeStep() for
+** details.
 */
-static void windowCodeDefaultStep(
-  Parse *pParse, 
-  Select *p,
-  WhereInfo *pWInfo,
-  int regGosub, 
-  int addrGosub
+static int windowCodeOp(
+ WindowCodeArg *p,                /* Context object */
+ int op,                          /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
+ int regCountdown,                /* Register for OP_IfPos countdown */
+ int jumpOnEof                    /* Jump here if stepped cursor reaches EOF */
 ){
-  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;
+  int csr, reg;
+  Parse *pParse = p->pParse;
+  Window *pMWin = p->pMWin;
+  int ret = 0;
+  Vdbe *v = p->pVdbe;
+  int addrIf = 0; 
+  int addrContinue = 0;
+  int addrGoto = 0;
+  int bPeer = (pMWin->eFrmType!=TK_ROWS);
 
-  assert( pMWin->eType==TK_RANGE 
-      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
-  );
+  int lblDone = sqlite3VdbeMakeLabel(pParse);
+  int addrNextRange = 0;
 
-  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;
+  /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
+  ** starts with UNBOUNDED PRECEDING. */
+  if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
+    assert( regCountdown==0 && jumpOnEof==0 );
+    return 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);
+  if( regCountdown>0 ){
+    if( pMWin->eFrmType==TK_RANGE ){
+      addrNextRange = sqlite3VdbeCurrentAddr(v);
+      assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
+      if( op==WINDOW_AGGINVERSE ){
+        if( pMWin->eStart==TK_FOLLOWING ){
+          windowCodeRangeTest(
+              p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
+          );
+        }else{
+          windowCodeRangeTest(
+              p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
+          );
+        }
       }else{
-        addrJump = 0;
+        windowCodeRangeTest(
+            p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
+        );
       }
-      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
-      if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
+    }else{
+      addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
+      VdbeCoverage(v);
     }
-
-    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);
+  if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
+    windowAggFinal(p, 0);
+  }
+  addrContinue = sqlite3VdbeCurrentAddr(v);
+  switch( op ){
+    case WINDOW_RETURN_ROW:
+      csr = p->current.csr;
+      reg = p->current.reg;
+      windowReturnOneRow(p);
+      break;
 
-  /* Buffer the current row in the ephemeral table. */
-  if( pMWin->nBufferCol>0 ){
-    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
+    case WINDOW_AGGINVERSE:
+      csr = p->start.csr;
+      reg = p->start.reg;
+      if( pMWin->regStartRowid ){
+        assert( pMWin->regEndRowid );
+        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
+      }else{
+        windowAggStep(pParse, pMWin, csr, 1, p->regArg);
+      }
+      break;
+
+    default:
+      assert( op==WINDOW_AGGSTEP );
+      csr = p->end.csr;
+      reg = p->end.reg;
+      if( pMWin->regStartRowid ){
+        assert( pMWin->regEndRowid );
+        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
+      }else{
+        windowAggStep(pParse, pMWin, csr, 0, p->regArg);
+      }
+      break;
+  }
+
+  if( op==p->eDelete ){
+    sqlite3VdbeAddOp1(v, OP_Delete, csr);
+    sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+  }
+
+  if( jumpOnEof ){
+    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
+    VdbeCoverage(v);
+    ret = sqlite3VdbeAddOp0(v, OP_Goto);
   }else{
-    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
-    sqlite3VdbeAppendP4(v, (void*)"", 0);
+    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
+    VdbeCoverage(v);
+    if( bPeer ){
+      addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+    }
   }
-  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
-  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
 
-  /* End the database scan loop. */
-  sqlite3WhereEnd(pWInfo);
+  if( bPeer ){
+    int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+    int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
+    windowReadPeerValues(p, csr, regTmp);
+    windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
+    sqlite3ReleaseTempRange(pParse, regTmp, nReg);
+  }
 
-  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);
+  if( addrNextRange ){
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
+  }
+  sqlite3VdbeResolveLabel(v, lblDone);
+  if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
+  if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
+  return ret;
 }
 
+
 /*
 ** Allocate and return a duplicate of the Window object indicated by the
 ** third argument. Set the Window.pOwner field of the new object to
@@ -145779,16 +147971,18 @@ static void windowCodeDefaultStep(
 */
 SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
   Window *pNew = 0;
-  if( p ){
+  if( ALWAYS(p) ){
     pNew = sqlite3DbMallocZero(db, sizeof(Window));
     if( pNew ){
       pNew->zName = sqlite3DbStrDup(db, p->zName);
       pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+      pNew->pFunc = p->pFunc;
       pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
       pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
-      pNew->eType = p->eType;
+      pNew->eFrmType = p->eFrmType;
       pNew->eEnd = p->eEnd;
       pNew->eStart = p->eStart;
+      pNew->eExclude = p->eExclude;
       pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
       pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
       pNew->pOwner = pOwner;
@@ -145815,12 +148009,360 @@ SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
   return pRet;
 }
 
+/*
+** Return true if it can be determined at compile time that expression 
+** pExpr evaluates to a value that, when cast to an integer, is greater 
+** than zero. False otherwise.
+**
+** If an OOM error occurs, this function sets the Parse.db.mallocFailed 
+** flag and returns zero.
+*/
+static int windowExprGtZero(Parse *pParse, Expr *pExpr){
+  int ret = 0;
+  sqlite3 *db = pParse->db;
+  sqlite3_value *pVal = 0;
+  sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
+  if( pVal && sqlite3_value_int(pVal)>0 ){
+    ret = 1;
+  }
+  sqlite3ValueFree(pVal);
+  return ret;
+}
+
 /*
 ** 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. 
+** code to populate the Window.regResult register for each window function 
+** and invoke the sub-routine at instruction addrGosub once for each row.
+** sqlite3WhereEnd() is always called before returning. 
+**
+** This function handles several different types of window frames, which
+** require slightly different processing. The following pseudo code is
+** used to implement window frames of the form:
+**
+**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
+**
+** Other window frame types use variants of the following:
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**       if( new partition ){
+**         Gosub flush
+**       }
+**       Insert new row into eph table.
+**       
+**       if( first row of partition ){
+**         // Rewind three cursors, all open on the eph table.
+**         Rewind(csrEnd);
+**         Rewind(csrStart);
+**         Rewind(csrCurrent);
+**       
+**         regEnd = <expr2>          // FOLLOWING expression
+**         regStart = <expr1>        // PRECEDING expression
+**       }else{
+**         // First time this branch is taken, the eph table contains two 
+**         // rows. The first row in the partition, which all three cursors
+**         // currently point to, and the following row.
+**         AGGSTEP
+**         if( (regEnd--)<=0 ){
+**           RETURN_ROW
+**           if( (regStart--)<=0 ){
+**             AGGINVERSE
+**           }
+**         }
+**       }
+**     }
+**     flush:
+**       AGGSTEP
+**       while( 1 ){
+**         RETURN ROW
+**         if( csrCurrent is EOF ) break;
+**         if( (regStart--)<=0 ){
+**           AggInverse(csrStart)
+**           Next(csrStart)
+**         }
+**       }
+**
+** The pseudo-code above uses the following shorthand:
+**
+**   AGGSTEP:    invoke the aggregate xStep() function for each window function
+**               with arguments read from the current row of cursor csrEnd, then
+**               step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
+**
+**   RETURN_ROW: return a row to the caller based on the contents of the 
+**               current row of csrCurrent and the current state of all 
+**               aggregates. Then step cursor csrCurrent forward one row.
+**
+**   AGGINVERSE: invoke the aggregate xInverse() function for each window 
+**               functions with arguments read from the current row of cursor
+**               csrStart. Then step csrStart forward one row.
+**
+** There are two other ROWS window frames that are handled significantly
+** differently from the above - "BETWEEN <expr> PRECEDING AND <expr> PRECEDING"
+** and "BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING". These are special 
+** cases because they change the order in which the three cursors (csrStart,
+** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
+** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
+** three.
+**
+**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**       if( new partition ){
+**         Gosub flush
+**       }
+**       Insert new row into eph table.
+**       if( first row of partition ){
+**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**         regEnd = <expr2>
+**         regStart = <expr1>
+**       }else{
+**         if( (regEnd--)<=0 ){
+**           AGGSTEP
+**         }
+**         RETURN_ROW
+**         if( (regStart--)<=0 ){
+**           AGGINVERSE
+**         }
+**       }
+**     }
+**     flush:
+**       if( (regEnd--)<=0 ){
+**         AGGSTEP
+**       }
+**       RETURN_ROW
+**
+**
+**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**     if( new partition ){
+**       Gosub flush
+**     }
+**     Insert new row into eph table.
+**     if( first row of partition ){
+**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**       regEnd = <expr2>
+**       regStart = regEnd - <expr1>
+**     }else{
+**       AGGSTEP
+**       if( (regEnd--)<=0 ){
+**         RETURN_ROW
+**       }
+**       if( (regStart--)<=0 ){
+**         AGGINVERSE
+**       }
+**     }
+**   }
+**   flush:
+**     AGGSTEP
+**     while( 1 ){
+**       if( (regEnd--)<=0 ){
+**         RETURN_ROW
+**         if( eof ) break;
+**       }
+**       if( (regStart--)<=0 ){
+**         AGGINVERSE
+**         if( eof ) break
+**       }
+**     }
+**     while( !eof csrCurrent ){
+**       RETURN_ROW
+**     }
+**
+** For the most part, the patterns above are adapted to support UNBOUNDED by
+** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
+** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
+** This is optimized of course - branches that will never be taken and
+** conditions that are always true are omitted from the VM code. The only
+** exceptional case is:
+**
+**   ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**     if( new partition ){
+**       Gosub flush
+**     }
+**     Insert new row into eph table.
+**     if( first row of partition ){
+**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**       regStart = <expr1>
+**     }else{
+**       AGGSTEP
+**     }
+**   }
+**   flush:
+**     AGGSTEP
+**     while( 1 ){
+**       if( (regStart--)<=0 ){
+**         AGGINVERSE
+**         if( eof ) break
+**       }
+**       RETURN_ROW
+**     }
+**     while( !eof csrCurrent ){
+**       RETURN_ROW
+**     }
+**
+** Also requiring special handling are the cases:
+**
+**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
+**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
+**
+** when (expr1 < expr2). This is detected at runtime, not by this function.
+** To handle this case, the pseudo-code programs depicted above are modified
+** slightly to be:
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**     if( new partition ){
+**       Gosub flush
+**     }
+**     Insert new row into eph table.
+**     if( first row of partition ){
+**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**       regEnd = <expr2>
+**       regStart = <expr1>
+**       if( regEnd < regStart ){
+**         RETURN_ROW
+**         delete eph table contents
+**         continue
+**       }
+**     ...
+**
+** The new "continue" statement in the above jumps to the next iteration
+** of the outer loop - the one started by sqlite3WhereBegin().
+**
+** The various GROUPS cases are implemented using the same patterns as
+** ROWS. The VM code is modified slightly so that:
+**
+**   1. The else branch in the main loop is only taken if the row just
+**      added to the ephemeral table is the start of a new group. In
+**      other words, it becomes:
+**
+**         ... loop started by sqlite3WhereBegin() ...
+**         if( new partition ){
+**           Gosub flush
+**         }
+**         Insert new row into eph table.
+**         if( first row of partition ){
+**           Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**           regEnd = <expr2>
+**           regStart = <expr1>
+**         }else if( new group ){
+**           ... 
+**         }
+**       }
+**
+**   2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or 
+**      AGGINVERSE step processes the current row of the relevant cursor and
+**      all subsequent rows belonging to the same group.
+**
+** RANGE window frames are a little different again. As for GROUPS, the 
+** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
+** deal in groups instead of rows. As for ROWS and GROUPS, there are three
+** basic cases:
+**
+**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**       if( new partition ){
+**         Gosub flush
+**       }
+**       Insert new row into eph table.
+**       if( first row of partition ){
+**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**         regEnd = <expr2>
+**         regStart = <expr1>
+**       }else{
+**         AGGSTEP
+**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
+**           RETURN_ROW
+**           while( csrStart.key + regStart) < csrCurrent.key ){
+**             AGGINVERSE
+**           }
+**         }
+**       }
+**     }
+**     flush:
+**       AGGSTEP
+**       while( 1 ){
+**         RETURN ROW
+**         if( csrCurrent is EOF ) break;
+**           while( csrStart.key + regStart) < csrCurrent.key ){
+**             AGGINVERSE
+**           }
+**         }
+**       }
+**
+** In the above notation, "csr.key" means the current value of the ORDER BY 
+** expression (there is only ever 1 for a RANGE that uses an <expr> FOLLOWING
+** or <expr PRECEDING) read from cursor csr.
+**
+**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**       if( new partition ){
+**         Gosub flush
+**       }
+**       Insert new row into eph table.
+**       if( first row of partition ){
+**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**         regEnd = <expr2>
+**         regStart = <expr1>
+**       }else{
+**         if( (csrEnd.key + regEnd) <= csrCurrent.key ){
+**           AGGSTEP
+**         }
+**         while( (csrStart.key + regStart) < csrCurrent.key ){
+**           AGGINVERSE
+**         }
+**         RETURN_ROW
+**       }
+**     }
+**     flush:
+**       while( (csrEnd.key + regEnd) <= csrCurrent.key ){
+**         AGGSTEP
+**       }
+**       while( (csrStart.key + regStart) < csrCurrent.key ){
+**         AGGINVERSE
+**       }
+**       RETURN_ROW
+**
+**   RANGE BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
+**
+**     ... loop started by sqlite3WhereBegin() ...
+**       if( new partition ){
+**         Gosub flush
+**       }
+**       Insert new row into eph table.
+**       if( first row of partition ){
+**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+**         regEnd = <expr2>
+**         regStart = <expr1>
+**       }else{
+**         AGGSTEP
+**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
+**           while( (csrCurrent.key + regStart) > csrStart.key ){
+**             AGGINVERSE
+**           }
+**           RETURN_ROW
+**         }
+**       }
+**     }
+**     flush:
+**       AGGSTEP
+**       while( 1 ){
+**         while( (csrCurrent.key + regStart) > csrStart.key ){
+**           AGGINVERSE
+**           if( eof ) break "while( 1 )" loop.
+**         }
+**         RETURN_ROW
+**       }
+**       while( !eof csrCurrent ){
+**         RETURN_ROW
+**       }
+**
+** The text above leaves out many details. Refer to the code and comments
+** below for a more complete picture.
 */
 SQLITE_PRIVATE void sqlite3WindowCodeStep(
   Parse *pParse,                  /* Parse context */
@@ -145830,75 +148372,321 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
   int addrGosub                   /* OP_Gosub here to return each row */
 ){
   Window *pMWin = p->pWin;
+  ExprList *pOrderBy = pMWin->pOrderBy;
+  Vdbe *v = sqlite3GetVdbe(pParse);
+  int csrWrite;                   /* Cursor used to write to eph. table */
+  int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
+  int nInput = p->pSrc->a[0].pTab->nCol;    /* Number of cols returned by sub */
+  int iInput;                               /* To iterate through sub cols */
+  int addrNe;                     /* Address of OP_Ne */
+  int addrGosubFlush = 0;         /* Address of OP_Gosub to flush: */
+  int addrInteger = 0;            /* Address of OP_Integer */
+  int addrEmpty;                  /* Address of OP_Rewind in flush: */
+  int regStart = 0;               /* Value of <expr> PRECEDING */
+  int regEnd = 0;                 /* Value of <expr> FOLLOWING */
+  int regNew;                     /* Array of registers holding new input row */
+  int regRecord;                  /* regNew array in record form */
+  int regRowid;                   /* Rowid for regRecord in eph table */
+  int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
+  int regPeer = 0;                /* Peer values for current row */
+  int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
+  WindowCodeArg s;                /* Context object for sub-routines */
+  int lblWhereEnd;                /* Label just before sqlite3WhereEnd() code */
 
-  /* 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() */
+  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 
+  );
+  assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
+       || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
+       || pMWin->eExclude==TK_NO
+  );
 
-    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;
+  lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
+
+  /* Fill in the context object */
+  memset(&s, 0, sizeof(WindowCodeArg));
+  s.pParse = pParse;
+  s.pMWin = pMWin;
+  s.pVdbe = v;
+  s.regGosub = regGosub;
+  s.addrGosub = addrGosub;
+  s.current.csr = pMWin->iEphCsr;
+  csrWrite = s.current.csr+1;
+  s.start.csr = s.current.csr+2;
+  s.end.csr = s.current.csr+3;
+
+  /* Figure out when rows may be deleted from the ephemeral table. There
+  ** are four options - they may never be deleted (eDelete==0), they may 
+  ** be deleted as soon as they are no longer part of the window frame
+  ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row 
+  ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
+  ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
+  switch( pMWin->eStart ){
+    case TK_FOLLOWING:
+      if( pMWin->eFrmType!=TK_RANGE
+       && windowExprGtZero(pParse, pMWin->pStart)
+      ){
+        s.eDelete = WINDOW_RETURN_ROW;
+      }
+      break;
+    case TK_UNBOUNDED:
+      if( windowCacheFrame(pMWin)==0 ){
+        if( pMWin->eEnd==TK_PRECEDING ){
+          if( pMWin->eFrmType!=TK_RANGE
+           && windowExprGtZero(pParse, pMWin->pEnd)
+          ){
+            s.eDelete = WINDOW_AGGSTEP;
+          }
+        }else{
+          s.eDelete = WINDOW_RETURN_ROW;
         }
       }
-    }
+      break;
+    default:
+      s.eDelete = WINDOW_AGGINVERSE;
+      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);
+  /* Allocate registers for the array of values from the sub-query, the
+  ** samve values in record form, and the rowid used to insert said record
+  ** into the ephemeral table.  */
+  regNew = pParse->nMem+1;
+  pParse->nMem += nInput;
+  regRecord = ++pParse->nMem;
+  regRowid = ++pParse->nMem;
+
+  /* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
+  ** clause, allocate registers to store the results of evaluating each
+  ** <expr>.  */
+  if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
+    regStart = ++pParse->nMem;
+  }
+  if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
+    regEnd = ++pParse->nMem;
+  }
+
+  /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
+  ** registers to store copies of the ORDER BY expressions (peer values) 
+  ** for the main loop, and for each cursor (start, current and end). */
+  if( pMWin->eFrmType!=TK_ROWS ){
+    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
+    regNewPeer = regNew + pMWin->nBufferCol;
+    if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
+    regPeer = pParse->nMem+1;       pParse->nMem += nPeer;
+    s.start.reg = pParse->nMem+1;   pParse->nMem += nPeer;
+    s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
+    s.end.reg = pParse->nMem+1;     pParse->nMem += nPeer;
+  }
+
+  /* Load the column values for the row returned by the sub-select
+  ** into an array of registers starting at regNew. Assemble them into
+  ** a record in register regRecord. */
+  for(iInput=0; iInput<nInput; iInput++){
+    sqlite3VdbeAddOp3(v, OP_Column, csrInput, iInput, regNew+iInput);
+  }
+  sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, nInput, regRecord);
+
+  /* An input row has just been read into an array of registers starting
+  ** at regNew. If the window has a PARTITION clause, this block generates 
+  ** VM code to check if the input row is the start of a new partition.
+  ** If so, it does an OP_Gosub to an address to be filled in later. The
+  ** address of the OP_Gosub is stored in local variable addrGosubFlush. */
+  if( pMWin->pPartition ){
+    int addr;
+    ExprList *pPart = pMWin->pPartition;
+    int nPart = pPart->nExpr;
+    int regNewPart = regNew + pMWin->nBufferCol;
+    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+
+    regFlushPart = ++pParse->nMem;
+    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);
+    addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
+    VdbeComment((v, "call flush_partition"));
+    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
+  }
+
+  /* Insert the new row into the ephemeral table */
+  sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
+  sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
+  addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
+  VdbeCoverageNeverNull(v);
+
+  /* This block is run for the first row of each partition */
+  s.regArg = windowInitAccum(pParse, pMWin);
+
+  if( regStart ){
+    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
+    windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+  }
+  if( regEnd ){
+    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
+    windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+  }
+
+  if( pMWin->eStart==pMWin->eEnd && regStart ){
+    int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
+    int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
+    VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
+    VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
+    windowAggFinal(&s, 0);
+    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+    VdbeCoverageNeverTaken(v);
+    windowReturnOneRow(&s);
+    sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+    sqlite3VdbeJumpHere(v, addrGe);
+  }
+  if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
+    assert( pMWin->eEnd==TK_FOLLOWING );
+    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
+  }
+
+  if( pMWin->eStart!=TK_UNBOUNDED ){
+    sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
+    VdbeCoverageNeverTaken(v);
+  }
+  sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+  VdbeCoverageNeverTaken(v);
+  sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
+  VdbeCoverageNeverTaken(v);
+  if( regPeer && pOrderBy ){
+    sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
+    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
+    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
+    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
+  }
+
+  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+
+  sqlite3VdbeJumpHere(v, addrNe);
+
+  /* Beginning of the block executed for the second and subsequent rows. */
+  if( regPeer ){
+    windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
+  }
+  if( pMWin->eStart==TK_FOLLOWING ){
+    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+    if( pMWin->eEnd!=TK_UNBOUNDED ){
+      if( pMWin->eFrmType==TK_RANGE ){
+        int lbl = sqlite3VdbeMakeLabel(pParse);
+        int addrNext = sqlite3VdbeCurrentAddr(v);
+        windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+        sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
+        sqlite3VdbeResolveLabel(v, lbl);
+      }else{
+        windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
+        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+      }
     }
+  }else
+  if( pMWin->eEnd==TK_PRECEDING ){
+    int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
+    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+    if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+    if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+  }else{
+    int addr = 0;
+    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+    if( pMWin->eEnd!=TK_UNBOUNDED ){
+      if( pMWin->eFrmType==TK_RANGE ){
+        int lbl = 0;
+        addr = sqlite3VdbeCurrentAddr(v);
+        if( regEnd ){
+          lbl = sqlite3VdbeMakeLabel(pParse);
+          windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+        }
+        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+        if( regEnd ){
+          sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
+          sqlite3VdbeResolveLabel(v, lbl);
+        }
+      }else{
+        if( regEnd ){
+          addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
+          VdbeCoverage(v);
+        }
+        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+        if( regEnd ) sqlite3VdbeJumpHere(v, addr);
+      }
+    }
+  }
+
+  /* End of the main input loop */
+  sqlite3VdbeResolveLabel(v, lblWhereEnd);
+  sqlite3WhereEnd(pWInfo);
+
+  /* Fall through */
+  if( pMWin->pPartition ){
+    addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
+    sqlite3VdbeJumpHere(v, addrGosubFlush);
+  }
+
+  addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
+  VdbeCoverage(v);
+  if( pMWin->eEnd==TK_PRECEDING ){
+    int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
+    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+    if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+  }else if( pMWin->eStart==TK_FOLLOWING ){
+    int addrStart;
+    int addrBreak1;
+    int addrBreak2;
+    int addrBreak3;
+    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+    if( pMWin->eFrmType==TK_RANGE ){
+      addrStart = sqlite3VdbeCurrentAddr(v);
+      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+    }else
+    if( pMWin->eEnd==TK_UNBOUNDED ){
+      addrStart = sqlite3VdbeCurrentAddr(v);
+      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
+      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
+    }else{
+      assert( pMWin->eEnd==TK_FOLLOWING );
+      addrStart = sqlite3VdbeCurrentAddr(v);
+      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
+      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+    }
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+    sqlite3VdbeJumpHere(v, addrBreak2);
+    addrStart = sqlite3VdbeCurrentAddr(v);
+    addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+    sqlite3VdbeJumpHere(v, addrBreak1);
+    sqlite3VdbeJumpHere(v, addrBreak3);
+  }else{
+    int addrBreak;
+    int addrStart;
+    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+    addrStart = sqlite3VdbeCurrentAddr(v);
+    addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+    windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+    sqlite3VdbeJumpHere(v, addrBreak);
+  }
+  sqlite3VdbeJumpHere(v, addrEmpty);
+
+  sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+  if( pMWin->pPartition ){
+    if( pMWin->regStartRowid ){
+      sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+      sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
+    }
+    sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
+    sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
   }
 }
 
@@ -145931,6 +148719,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
 ** input grammar file:
 */
 /* #include <stdio.h> */
+/* #include <assert.h> */
 /************ Begin %include sections from the grammar ************************/
 
 /* #include "sqliteInt.h" */
@@ -146032,19 +148821,15 @@ static void disableLookaside(Parse *pParse){
       p->pLeft = p->pRight = 0;
       p->x.pList = 0;
       p->pAggInfo = 0;
-      p->pTab = 0;
+      p->y.pTab = 0;
       p->op2 = 0;
       p->iTable = 0;
       p->iColumn = 0;
-#ifndef SQLITE_OMIT_WINDOWFUNC
-      p->pWin = 0;
-#endif
       p->u.zToken = (char*)&p[1];
       memcpy(p->u.zToken, t.z, t.n);
       p->u.zToken[t.n] = 0;
       if( sqlite3Isquote(p->u.zToken[0]) ){
-        if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
-        sqlite3Dequote(p->u.zToken);
+        sqlite3DequoteExpr(p);
       }
 #if SQLITE_MAX_EXPR_DEPTH>0
       p->nHeight = 1;
@@ -146090,6 +148875,10 @@ static void disableLookaside(Parse *pParse){
     sqlite3ExprListSetName(pParse, p, pIdToken, 1);
     return p;
   }
+
+#if TK_SPAN>255
+# error too many tokens in the grammar
+#endif
 /**************** End of %include directives **********************************/
 /* These constants specify the various numeric values for terminal symbols
 ** in a format understandable to "makeheaders".  This section is blank unless
@@ -146153,27 +148942,28 @@ static void disableLookaside(Parse *pParse){
 #endif
 /************* Begin control #defines *****************************************/
 #define YYCODETYPE unsigned short int
-#define YYNOCODE 277
+#define YYNOCODE 302
 #define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 91
+#define YYWILDCARD 95
 #define sqlite3ParserTOKENTYPE Token
 typedef union {
   int yyinit;
   sqlite3ParserTOKENTYPE yy0;
-  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;
+  TriggerStep* yy11;
+  IdList* yy76;
+  ExprList* yy94;
+  Upsert* yy95;
+  int yy100;
+  Expr* yy102;
+  struct {int value; int mask;} yy199;
+  u8 yy218;
+  With* yy243;
+  struct TrigEvent yy298;
+  Window* yy379;
+  struct FrameBound yy389;
+  Select* yy391;
+  SrcList* yy407;
+  const char* yy528;
 } YYMINORTYPE;
 #ifndef YYSTACKDEPTH
 #define YYSTACKDEPTH 100
@@ -146189,17 +148979,17 @@ typedef union {
 #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
 #define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
 #define YYFALLBACK 1
-#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
+#define YYNSTATE             540
+#define YYNRULE              376
+#define YYNTOKEN             176
+#define YY_MAX_SHIFT         539
+#define YY_MIN_SHIFTREDUCE   783
+#define YY_MAX_SHIFTREDUCE   1158
+#define YY_ERROR_ACTION      1159
+#define YY_ACCEPT_ACTION     1160
+#define YY_NO_ACTION         1161
+#define YY_MIN_REDUCE        1162
+#define YY_MAX_REDUCE        1537
 /************* End control #defines *******************************************/
 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
 
@@ -146266,568 +149056,601 @@ typedef union {
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2009)
+#define YY_ACTTAB_COUNT (2142)
 static const YYACTIONTYPE yy_action[] = {
- /*     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,
+ /*     0 */   112,  109,  209,  112,  109,  209, 1160,    1,    1,  539,
+ /*    10 */     2, 1164,  490, 1193, 1293,  534,  289, 1196,  134,  383,
+ /*    20 */  1485, 1428, 1164, 1229, 1208, 1242, 1195,  289,  491,  134,
+ /*    30 */   373,  915, 1229,  443,   16,   16, 1242,   70,   70,  916,
+ /*    40 */   242, 1292,  296,  119,  120,  110, 1136, 1136,  981,  984,
+ /*    50 */   974,  974,  117,  117,  118,  118,  118,  118,  264,  264,
+ /*    60 */   190,  264,  264,  264,  264,  112,  109,  209,  362,  264,
+ /*    70 */   264,  531,  376,  497,  531, 1134,  531, 1501,  239,  206,
+ /*    80 */   338,    9,  531,  242,  219, 1203,  118,  118,  118,  118,
+ /*    90 */   111,  439,  112,  109,  209,  219,  116,  116,  116,  116,
+ /*   100 */   115,  115,  114,  114,  114,  113,  414,  115,  115,  114,
+ /*   110 */   114,  114,  113,  414,  418,   12,  383,  400, 1134,  114,
+ /*   120 */   114,  114,  113,  414, 1115,  418, 1134, 1392,  116,  116,
+ /*   130 */   116,  116,  115,  115,  114,  114,  114,  113,  414,  961,
+ /*   140 */   119,  120,  110, 1136, 1136,  981,  984,  974,  974,  117,
+ /*   150 */   117,  118,  118,  118,  118,  952,  534,  414,  941,  951,
+ /*   160 */  1481,  539,    2, 1164, 1505,  534,  160,  175,  289, 1134,
+ /*   170 */   134,  434,  312,  297, 1115, 1116, 1117, 1242,   70,   70,
+ /*   180 */  1089,  338, 1089,  118,  118,  118,  118,   42,   42,  448,
+ /*   190 */   951,  951,  953,  116,  116,  116,  116,  115,  115,  114,
+ /*   200 */   114,  114,  113,  414, 1115,  311,  264,  264,   82,  441,
+ /*   210 */   264,  264,  190,  383,  284,   12,  288,  525,  407,  531,
+ /*   220 */    96,  159,  458,  531,  371,  116,  116,  116,  116,  115,
+ /*   230 */   115,  114,  114,  114,  113,  414,  219,  119,  120,  110,
+ /*   240 */  1136, 1136,  981,  984,  974,  974,  117,  117,  118,  118,
+ /*   250 */   118,  118,  511, 1477, 1115, 1116, 1117,  113,  414,  534,
+ /*   260 */   528,  528,  528,  121,  534, 1427,  418,  116,  116,  116,
+ /*   270 */   116,  115,  115,  114,  114,  114,  113,  414, 1464,  351,
+ /*   280 */   270,   42,   42,  383,  187, 1115,   70,   70,  533,  433,
+ /*   290 */   116,  116,  116,  116,  115,  115,  114,  114,  114,  113,
+ /*   300 */   414,  534, 1339,  405,  159,  411,  410,  119,  120,  110,
+ /*   310 */  1136, 1136,  981,  984,  974,  974,  117,  117,  118,  118,
+ /*   320 */   118,  118,  285,   42,   42,  349,  411,  410,  514,  479,
+ /*   330 */  1458,   79, 1084,    6, 1140, 1115, 1116, 1117,  480, 1142,
+ /*   340 */   501, 1115, 1084,  123,  238, 1084,  136, 1141, 1234, 1234,
+ /*   350 */  1143,  383, 1143, 1115,  167,  426,   80,  447,  512, 1451,
+ /*   360 */   116,  116,  116,  116,  115,  115,  114,  114,  114,  113,
+ /*   370 */   414, 1143, 1466, 1143,  350,  119,  120,  110, 1136, 1136,
+ /*   380 */   981,  984,  974,  974,  117,  117,  118,  118,  118,  118,
+ /*   390 */   402, 1115, 1116, 1117,  500,  534,  250,  267,  336,  474,
+ /*   400 */   331,  473,  236, 1115, 1116, 1117,  231, 1115,  329,  471,
+ /*   410 */   468,  467,  509, 1458, 1464,  505,    6,   70,   70,  466,
+ /*   420 */   181,  380,  379,  534,  971,  971,  982,  985,  116,  116,
+ /*   430 */   116,  116,  115,  115,  114,  114,  114,  113,  414, 1115,
+ /*   440 */   412,  412,  412,  496, 1115,   69,   69,  235,  383,  288,
+ /*   450 */   525,  273,  326,  516,  337,  458, 1084, 1115, 1116, 1117,
+ /*   460 */  1232, 1232,  492,  160,  508,  441, 1084, 1067, 1531, 1084,
+ /*   470 */   207, 1531,  119,  120,  110, 1136, 1136,  981,  984,  974,
+ /*   480 */   974,  117,  117,  118,  118,  118,  118,  881,  534, 1115,
+ /*   490 */  1116, 1117,  975,  534, 1115, 1116, 1117,  534,  421,  534,
+ /*   500 */   141,  534,  176,  356,  517, 1119,   32,  511,  482,  388,
+ /*   510 */    70,   70,  818,  288,  525,   70,   70,  441,  499,   50,
+ /*   520 */    50,   70,   70,   70,   70,  116,  116,  116,  116,  115,
+ /*   530 */   115,  114,  114,  114,  113,  414,  274,  264,  264, 1115,
+ /*   540 */  1065,  264,  264, 1115,  355,  383,  409,  961, 1439,  822,
+ /*   550 */   531,  516,  190,  419,  531,  483, 1119,  516,  337,  516,
+ /*   560 */   518, 1115,  818,  952,  382,  458,  515,  951,  481,  119,
+ /*   570 */   120,  110, 1136, 1136,  981,  984,  974,  974,  117,  117,
+ /*   580 */   118,  118,  118,  118, 1338,  278, 1045,  278,  275, 1115,
+ /*   590 */  1116, 1117,  259, 1115, 1116, 1117,  534,    5,  951,  951,
+ /*   600 */   953, 1046,  231,    3,  143,  471,  468,  467, 1391,  463,
+ /*   610 */  1115, 1115, 1116, 1117, 1452,  466, 1047,  836,   70,   70,
+ /*   620 */   480,  534,  116,  116,  116,  116,  115,  115,  114,  114,
+ /*   630 */   114,  113,  414,   95, 1115,  287,  235,  856,  902,  420,
+ /*   640 */  1115,  534,  383,   13,   13,  381,  815,  857,  472,  112,
+ /*   650 */   109,  209, 1115,  337,  413,  309,  837,  394, 1436,  534,
+ /*   660 */  1115, 1116, 1117,   54,   54,  291,  119,  120,  110, 1136,
+ /*   670 */  1136,  981,  984,  974,  974,  117,  117,  118,  118,  118,
+ /*   680 */   118,   13,   13, 1084, 1115, 1116, 1117,  901,  264,  264,
+ /*   690 */  1115, 1116, 1117, 1084,  292,  399, 1084,  800,  388,  140,
+ /*   700 */   295,  531, 1115, 1116, 1117,  403,  447,  532,  534,  870,
+ /*   710 */   870,  534, 1240,  534,  329,  534, 1185,  389,  534,  116,
+ /*   720 */   116,  116,  116,  115,  115,  114,  114,  114,  113,  414,
+ /*   730 */    13,   13, 1024,   13,   13,   13,   13,   13,   13,  383,
+ /*   740 */    13,   13,  424, 1100,  401,  264,  264,  277,  160,  184,
+ /*   750 */  1182,  185, 1533,  369,  513,  484,  432,  487,  531,  424,
+ /*   760 */   423, 1397,  941,  119,  120,  110, 1136, 1136,  981,  984,
+ /*   770 */   974,  974,  117,  117,  118,  118,  118,  118, 1397, 1399,
+ /*   780 */   425,  519,  392,  264,  264, 1029, 1029,  455,  264,  264,
+ /*   790 */   264,  264, 1004,  304,  261, 1278,  531,  900,  288,  525,
+ /*   800 */   310,  531,  493,  531, 1067, 1532,  458,  387, 1532,  311,
+ /*   810 */   429,  299,  534,  107,  264,  264,  116,  116,  116,  116,
+ /*   820 */   115,  115,  114,  114,  114,  113,  414,  531,  424, 1384,
+ /*   830 */   507,  258,  258, 1246,   55,   55,  383, 1277,  265,  265,
+ /*   840 */   962,  324,  434,  312,  531,  531,  506, 1397, 1026, 1241,
+ /*   850 */   298,  531, 1026,  445,  301, 1095,  303,  534,  368, 1156,
+ /*   860 */   119,  120,  110, 1136, 1136,  981,  984,  974,  974,  117,
+ /*   870 */   117,  118,  118,  118,  118, 1045,  534, 1065,  534,   15,
+ /*   880 */    15, 1084,  208, 1324,  453,  452,  534, 1324,  534,  449,
+ /*   890 */  1046, 1084,  494,  458, 1084,  234,  233,  232,   44,   44,
+ /*   900 */    56,   56,  319, 1095,  322, 1047,  534,  900,   57,   57,
+ /*   910 */    58,   58,  534,  116,  116,  116,  116,  115,  115,  114,
+ /*   920 */   114,  114,  113,  414,  534,  514,  522,  534,   59,   59,
+ /*   930 */   302, 1157,  534,  383,   60,   60, 1237,  946,  788,  789,
+ /*   940 */   790, 1459, 1456,  446,    6,    6,   61,   61, 1212,   45,
+ /*   950 */    45,  534,  396,  383,   46,   46,  397,  119,  120,  110,
+ /*   960 */  1136, 1136,  981,  984,  974,  974,  117,  117,  118,  118,
+ /*   970 */   118,  118,  428,   48,   48,  534,  392,  119,  120,  110,
+ /*   980 */  1136, 1136,  981,  984,  974,  974,  117,  117,  118,  118,
+ /*   990 */   118,  118, 1324,  368, 1066,  447,  825,   49,   49,  534,
+ /*  1000 */   458,  357,  534,  353,  534,  138,  534,  337, 1478,  478,
+ /*  1010 */   116,  116,  116,  116,  115,  115,  114,  114,  114,  113,
+ /*  1020 */   414,   62,   62,  392,   63,   63,   64,   64,   14,   14,
+ /*  1030 */   116,  116,  116,  116,  115,  115,  114,  114,  114,  113,
+ /*  1040 */   414,  534,  810,  317,  271,  534, 1457,  825,  534,    6,
+ /*  1050 */   534, 1324,  534,  142,  534, 1442,  534,  212,  534, 1324,
+ /*  1060 */   534,  398,  305,   65,   65,  534, 1157,  125,  125,  476,
+ /*  1070 */    66,   66,   51,   51,   67,   67,   68,   68,   52,   52,
+ /*  1080 */   147,  147,  148,  148,  534,   98,  534,   75,   75,  276,
+ /*  1090 */   534,  272,  534,  810,  534,  876,  534,  527,  389,  534,
+ /*  1100 */   875,  534, 1151,  202,  534,  383,   53,   53,   71,   71,
+ /*  1110 */   288,  525,  126,  126,   72,   72,  127,  127,  128,  128,
+ /*  1120 */   454,  124,  124,  146,  146,  383,  145,  145,  408,  119,
+ /*  1130 */   120,  110, 1136, 1136,  981,  984,  974,  974,  117,  117,
+ /*  1140 */   118,  118,  118,  118,  534,  900,  534,   95,  534,  119,
+ /*  1150 */   120,  110, 1136, 1136,  981,  984,  974,  974,  117,  117,
+ /*  1160 */   118,  118,  118,  118,  390,  161,  132,  132,  131,  131,
+ /*  1170 */   129,  129,  534,  915,  534, 1455,  534, 1454,    6, 1416,
+ /*  1180 */     6,  916,  116,  116,  116,  116,  115,  115,  114,  114,
+ /*  1190 */   114,  113,  414, 1415,  130,  130,   74,   74,   76,   76,
+ /*  1200 */   534,   30,  116,  116,  116,  116,  115,  115,  114,  114,
+ /*  1210 */   114,  113,  414,  534,  263,  206,  534, 1133, 1504,   93,
+ /*  1220 */   876,  845,   73,   73,  102,  875,  100,  139,   17,   38,
+ /*  1230 */   208, 1062,   31,  450,  370,   43,   43,  101,   47,   47,
+ /*  1240 */   827,  216,  436,  308,  943,  440,   95,  241,  241,  442,
+ /*  1250 */   313,  464,  241,   95,  237,  900,  327,  383,  266,   95,
+ /*  1260 */   835,  834,  193,  335,  938,  314, 1011,  435,  842,  843,
+ /*  1270 */   955, 1007,  909,  334,  237,  241,  873,  383, 1023,  107,
+ /*  1280 */  1023,  119,  120,  110, 1136, 1136,  981,  984,  974,  974,
+ /*  1290 */   117,  117,  118,  118,  118,  118, 1022,  808, 1022, 1274,
+ /*  1300 */   137,  119,  108,  110, 1136, 1136,  981,  984,  974,  974,
+ /*  1310 */   117,  117,  118,  118,  118,  118,  874, 1011,  318,  107,
+ /*  1320 */   321,  955,  323,  325, 1225, 1211,  197, 1210, 1209,  330,
+ /*  1330 */   339, 1265,  340,  283,  116,  116,  116,  116,  115,  115,
+ /*  1340 */   114,  114,  114,  113,  414, 1286, 1323, 1261, 1471, 1272,
+ /*  1350 */   520,  218,  521, 1329,  116,  116,  116,  116,  115,  115,
+ /*  1360 */   114,  114,  114,  113,  414, 1192, 1184, 1173, 1172, 1174,
+ /*  1370 */  1494, 1488,  459,  256,  383, 1258,  342,  199,  367,  344,
+ /*  1380 */   211,  195,  307,  444,   11,  346,  469,  333, 1308, 1316,
+ /*  1390 */   375,  427,  203,  360,  383, 1388,  188, 1387,  189,  120,
+ /*  1400 */   110, 1136, 1136,  981,  984,  974,  974,  117,  117,  118,
+ /*  1410 */   118,  118,  118, 1208, 1151,  300,  348, 1491,  245, 1148,
+ /*  1420 */   110, 1136, 1136,  981,  984,  974,  974,  117,  117,  118,
+ /*  1430 */   118,  118,  118,  198, 1435, 1433,  524,   78,  391,  163,
+ /*  1440 */    82, 1393,  438,  173,   81,  105,  526, 1313,    4,   35,
+ /*  1450 */   157,  116,  116,  116,  116,  115,  115,  114,  114,  114,
+ /*  1460 */   113,  414,  529,  165,   93,  430, 1305,  168,  169,  431,
+ /*  1470 */   462,  116,  116,  116,  116,  115,  115,  114,  114,  114,
+ /*  1480 */   113,  414,  170,  171,  221,  415,  372,  437, 1319,  177,
+ /*  1490 */   374,   36,  451,  225, 1382,   87,  457,  523,  257, 1404,
+ /*  1500 */   316,  105,  526,  227,    4,  182,  460,  160,  320,  228,
+ /*  1510 */   377, 1175,  475,  229, 1228,  404, 1227, 1226,  529,  827,
+ /*  1520 */   961, 1219,  378, 1200, 1199,  406,  103,  103, 1218,  332,
+ /*  1530 */     8,  281, 1198,  104, 1503,  415,  536,  535,  486,  282,
+ /*  1540 */   951,  415,  489,  495,   92,  244, 1269,  341,  243,  122,
+ /*  1550 */  1270,  343,  514,  523, 1268, 1462,   10,  288,  525,  345,
+ /*  1560 */  1461,  354,   99,  352,  503,   94, 1267,  347, 1251,  502,
+ /*  1570 */   498,  951,  951,  953,  954,   27,  961, 1250,  194,  358,
+ /*  1580 */   251,  359,  103,  103, 1181,   34,  537, 1110,  252,  104,
+ /*  1590 */   254,  415,  536,  535,  255, 1368,  951, 1420,  286,  538,
+ /*  1600 */  1170, 1165, 1421,  135, 1419, 1418,  149,  150,  279,  784,
+ /*  1610 */   416,  196,  151,  290,  210,  200,   77,  385,  269,  386,
+ /*  1620 */   133,  162,  935, 1021,  201, 1019,  153,  951,  951,  953,
+ /*  1630 */   954,   27, 1480, 1104,  417,  164,  217,  268,  859,  166,
+ /*  1640 */   306, 1035,  366,  366,  365,  253,  363,  220,  172,  797,
+ /*  1650 */   939,  155,  105,  526,  393,    4,  395,  174,  156,   83,
+ /*  1660 */  1038,   84,  213,   85,  294,  222,   86,  223, 1034,  529,
+ /*  1670 */   144,   18,  293,  224,  315,  456,  241, 1027, 1145,  178,
+ /*  1680 */   226,  179,   37,  799,  334,  461,  230,  465,  470,  838,
+ /*  1690 */   180,   88,  415,   19,  280,  328,   20,   89,   90,  158,
+ /*  1700 */   191,  477,  215, 1097,  523,  204,  192,  987,   91, 1070,
+ /*  1710 */   152,   39,  485,  154, 1071,  503,   40,  488,  205,  260,
+ /*  1720 */   504,  262,  105,  526,  214,    4,  908,  961,  183,  240,
+ /*  1730 */   903,  107, 1086,  103,  103,   21,   22, 1088,   23,  529,
+ /*  1740 */   104,   24,  415,  536,  535, 1090, 1093,  951, 1094,   25,
+ /*  1750 */  1074,   33,    7,   26,  510, 1002,  247,  186,  384,   95,
+ /*  1760 */   988,  986,  415,  288,  525,  990, 1044,  246, 1043,  991,
+ /*  1770 */    28,   41,  530,  956,  523,  809,  106,   29,  951,  951,
+ /*  1780 */   953,  954,   27,  869,  361,  503,  422,  248,  364, 1105,
+ /*  1790 */   502,  249, 1161, 1496, 1495, 1161, 1161,  961, 1161, 1161,
+ /*  1800 */  1161, 1161, 1161,  103,  103, 1161, 1161, 1161, 1161, 1161,
+ /*  1810 */   104, 1161,  415,  536,  535, 1104,  417,  951, 1161,  268,
+ /*  1820 */  1161, 1161, 1161, 1161,  366,  366,  365,  253,  363, 1161,
+ /*  1830 */  1161,  797, 1161, 1161, 1161, 1161,  105,  526, 1161,    4,
+ /*  1840 */  1161, 1161, 1161, 1161,  213, 1161,  294, 1161,  951,  951,
+ /*  1850 */   953,  954,   27,  529,  293, 1161, 1161, 1161, 1161, 1161,
+ /*  1860 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /*  1870 */  1161, 1161, 1161, 1161, 1161, 1161,  415, 1161, 1161, 1161,
+ /*  1880 */  1161, 1161, 1161, 1161,  215, 1161, 1161, 1161,  523, 1161,
+ /*  1890 */  1161, 1161,  152, 1161, 1161,  154,  105,  526, 1161,    4,
+ /*  1900 */  1161, 1161, 1161, 1161, 1161, 1161,  214, 1161, 1161, 1161,
+ /*  1910 */  1161,  961, 1161,  529, 1161, 1161, 1161,  103,  103,  880,
+ /*  1920 */  1161, 1161, 1161, 1161,  104, 1161,  415,  536,  535, 1161,
+ /*  1930 */  1161,  951, 1161, 1161, 1161, 1161,  415, 1161, 1161, 1161,
+ /*  1940 */   384, 1161, 1161, 1161, 1161,  288,  525, 1161,  523, 1161,
+ /*  1950 */  1161, 1161, 1161, 1161, 1161, 1161,   97,  526, 1161,    4,
+ /*  1960 */  1161, 1161,  951,  951,  953,  954,   27, 1161,  422, 1161,
+ /*  1970 */  1161,  961, 1161,  529, 1161, 1161, 1161,  103,  103, 1161,
+ /*  1980 */  1161, 1161, 1161, 1161,  104, 1161,  415,  536,  535, 1161,
+ /*  1990 */  1161,  951,  268, 1161, 1161, 1161,  415,  366,  366,  365,
+ /*  2000 */   253,  363, 1161, 1161,  797, 1161, 1161, 1161,  523, 1161,
+ /*  2010 */  1161, 1161, 1161, 1161, 1161, 1161, 1161,  213, 1161,  294,
+ /*  2020 */  1161, 1161,  951,  951,  953,  954,   27,  293, 1161, 1161,
+ /*  2030 */  1161,  961, 1161, 1161, 1161, 1161, 1161,  103,  103, 1161,
+ /*  2040 */  1161, 1161, 1161, 1161,  104, 1161,  415,  536,  535, 1161,
+ /*  2050 */  1161,  951, 1161, 1161, 1161, 1161, 1161,  215, 1161, 1161,
+ /*  2060 */  1161, 1161, 1161, 1161, 1161,  152, 1161, 1161,  154, 1161,
+ /*  2070 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,  214,
+ /*  2080 */  1161, 1161,  951,  951,  953,  954,   27, 1161, 1161, 1161,
+ /*  2090 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /*  2100 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /*  2110 */  1161, 1161, 1161,  384, 1161, 1161, 1161, 1161,  288,  525,
+ /*  2120 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /*  2130 */  1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /*  2140 */  1161,  422,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     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,
+ /*     0 */   260,  261,  262,  260,  261,  262,  176,  177,  178,  179,
+ /*    10 */   180,  181,  184,  206,  209,  184,  186,  206,  188,   19,
+ /*    20 */   179,  281,  181,  213,  214,  195,  206,  186,  195,  188,
+ /*    30 */   195,   31,  222,  184,  206,  207,  195,  206,  207,   39,
+ /*    40 */    24,  209,  184,   43,   44,   45,   46,   47,   48,   49,
+ /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,  228,  229,
+ /*    60 */   184,  228,  229,  228,  229,  260,  261,  262,  192,  228,
+ /*    70 */   229,  241,  196,  242,  241,   59,  241,  205,  245,  246,
+ /*    80 */   184,   22,  241,   24,  254,  213,   54,   55,   56,   57,
+ /*    90 */    58,  256,  260,  261,  262,  254,   96,   97,   98,   99,
+ /*   100 */   100,  101,  102,  103,  104,  105,  106,  100,  101,  102,
+ /*   110 */   103,  104,  105,  106,  284,  203,   19,  221,   59,  102,
+ /*   120 */   103,  104,  105,  106,   59,  284,  110,  269,   96,   97,
+ /*   130 */    98,   99,  100,  101,  102,  103,  104,  105,  106,   94,
+ /*   140 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   150 */    53,   54,   55,   56,   57,  110,  184,  106,   73,  114,
+ /*   160 */   178,  179,  180,  181,  219,  184,   81,   22,  186,  110,
+ /*   170 */   188,  121,  122,  195,  109,  110,  111,  195,  206,  207,
+ /*   180 */    83,  184,   85,   54,   55,   56,   57,  206,  207,  277,
+ /*   190 */   145,  146,  147,   96,   97,   98,   99,  100,  101,  102,
+ /*   200 */   103,  104,  105,  106,   59,  120,  228,  229,  143,  184,
+ /*   210 */   228,  229,  184,   19,  242,  203,  131,  132,  221,  241,
+ /*   220 */    26,  184,  184,  241,  196,   96,   97,   98,   99,  100,
+ /*   230 */   101,  102,  103,  104,  105,  106,  254,   43,   44,   45,
+ /*   240 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+ /*   250 */    56,   57,  184,  184,  109,  110,  111,  105,  106,  184,
+ /*   260 */   200,  201,  202,   69,  184,  227,  284,   96,   97,   98,
+ /*   270 */    99,  100,  101,  102,  103,  104,  105,  106,  297,  298,
+ /*   280 */   255,  206,  207,   19,  272,   59,  206,  207,  184,  277,
+ /*   290 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  105,
+ /*   300 */   106,  184,  259,   19,  184,  100,  101,   43,   44,   45,
+ /*   310 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+ /*   320 */    56,   57,  242,  206,  207,  184,  100,  101,  138,  292,
+ /*   330 */   293,   67,   76,  296,  108,  109,  110,  111,  295,  113,
+ /*   340 */    84,   59,   86,   22,   26,   89,  156,  121,  224,  225,
+ /*   350 */   145,   19,  147,   59,   72,  256,   24,  184,  290,  291,
+ /*   360 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  105,
+ /*   370 */   106,  145,  297,  147,  299,   43,   44,   45,   46,   47,
+ /*   380 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
+ /*   390 */   106,  109,  110,  111,  138,  184,  112,  113,  114,  115,
+ /*   400 */   116,  117,  118,  109,  110,  111,  112,   59,  124,  115,
+ /*   410 */   116,  117,  292,  293,  297,  298,  296,  206,  207,  125,
+ /*   420 */    72,  100,  101,  184,   46,   47,   48,   49,   96,   97,
+ /*   430 */    98,   99,  100,  101,  102,  103,  104,  105,  106,   59,
+ /*   440 */   200,  201,  202,  184,   59,  206,  207,   46,   19,  131,
+ /*   450 */   132,  278,   23,  242,  184,  184,   76,  109,  110,  111,
+ /*   460 */   224,  225,  251,   81,   84,  184,   86,   22,   23,   89,
+ /*   470 */   184,   26,   43,   44,   45,   46,   47,   48,   49,   50,
+ /*   480 */    51,   52,   53,   54,   55,   56,   57,  102,  184,  109,
+ /*   490 */   110,  111,  114,  184,  109,  110,  111,  184,  227,  184,
+ /*   500 */   230,  184,   22,  264,  195,   59,   22,  184,  195,  108,
+ /*   510 */   206,  207,   59,  131,  132,  206,  207,  184,  138,  206,
+ /*   520 */   207,  206,  207,  206,  207,   96,   97,   98,   99,  100,
+ /*   530 */   101,  102,  103,  104,  105,  106,  255,  228,  229,   59,
+ /*   540 */    95,  228,  229,   59,  184,   19,  242,   94,  184,   23,
+ /*   550 */   241,  242,  184,  282,  241,  242,  110,  242,  184,  242,
+ /*   560 */   251,   59,  109,  110,  196,  184,  251,  114,  251,   43,
+ /*   570 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+ /*   580 */    54,   55,   56,   57,  259,  217,   12,  219,  255,  109,
+ /*   590 */   110,  111,  203,  109,  110,  111,  184,   22,  145,  146,
+ /*   600 */   147,   27,  112,   22,  230,  115,  116,  117,  227,   19,
+ /*   610 */    59,  109,  110,  111,  291,  125,   42,   35,  206,  207,
+ /*   620 */   295,  184,   96,   97,   98,   99,  100,  101,  102,  103,
+ /*   630 */   104,  105,  106,   26,   59,  233,   46,   63,  136,  184,
+ /*   640 */    59,  184,   19,  206,  207,  243,   23,   73,   66,  260,
+ /*   650 */   261,  262,   59,  184,  242,  195,   74,  220,  184,  184,
+ /*   660 */   109,  110,  111,  206,  207,  184,   43,   44,   45,   46,
+ /*   670 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
+ /*   680 */    57,  206,  207,   76,  109,  110,  111,  136,  228,  229,
+ /*   690 */   109,  110,  111,   86,  184,  220,   89,   21,  108,  230,
+ /*   700 */   184,  241,  109,  110,  111,  123,  184,  127,  184,  129,
+ /*   710 */   130,  184,  195,  184,  124,  184,  198,  199,  184,   96,
+ /*   720 */    97,   98,   99,  100,  101,  102,  103,  104,  105,  106,
+ /*   730 */   206,  207,   11,  206,  207,  206,  207,  206,  207,   19,
+ /*   740 */   206,  207,  184,   23,  220,  228,  229,  220,   81,  220,
+ /*   750 */   195,  220,  287,  288,  220,  195,   80,  195,  241,  201,
+ /*   760 */   202,  184,   73,   43,   44,   45,   46,   47,   48,   49,
+ /*   770 */    50,   51,   52,   53,   54,   55,   56,   57,  201,  202,
+ /*   780 */   113,  195,  184,  228,  229,  120,  121,  122,  228,  229,
+ /*   790 */   228,  229,  116,   16,   23,  184,  241,   26,  131,  132,
+ /*   800 */   278,  241,   19,  241,   22,   23,  184,  189,   26,  120,
+ /*   810 */   121,  122,  184,   26,  228,  229,   96,   97,   98,   99,
+ /*   820 */   100,  101,  102,  103,  104,  105,  106,  241,  270,  153,
+ /*   830 */    66,  228,  229,  229,  206,  207,   19,  184,  228,  229,
+ /*   840 */    23,   16,  121,  122,  241,  241,   82,  270,   29,  227,
+ /*   850 */   252,  241,   33,   19,   77,   91,   79,  184,   22,   23,
+ /*   860 */    43,   44,   45,   46,   47,   48,   49,   50,   51,   52,
+ /*   870 */    53,   54,   55,   56,   57,   12,  184,   95,  184,  206,
+ /*   880 */   207,   76,  111,  184,   65,  267,  184,  184,  184,  271,
+ /*   890 */    27,   86,  109,  184,   89,  120,  121,  122,  206,  207,
+ /*   900 */   206,  207,   77,  139,   79,   42,  184,  136,  206,  207,
+ /*   910 */   206,  207,  184,   96,   97,   98,   99,  100,  101,  102,
+ /*   920 */   103,  104,  105,  106,  184,  138,   63,  184,  206,  207,
+ /*   930 */   153,   95,  184,   19,  206,  207,  227,   23,    7,    8,
+ /*   940 */     9,  293,  293,  109,  296,  296,  206,  207,  215,  206,
+ /*   950 */   207,  184,  253,   19,  206,  207,  253,   43,   44,   45,
+ /*   960 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+ /*   970 */    56,   57,  184,  206,  207,  184,  184,   43,   44,   45,
+ /*   980 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+ /*   990 */    56,   57,  184,   22,   23,  184,   59,  206,  207,  184,
+ /*  1000 */   184,  238,  184,  240,  184,   22,  184,  184,  157,  158,
+ /*  1010 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  105,
+ /*  1020 */   106,  206,  207,  184,  206,  207,  206,  207,  206,  207,
+ /*  1030 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  105,
+ /*  1040 */   106,  184,   59,  227,  252,  184,  293,  110,  184,  296,
+ /*  1050 */   184,  184,  184,  230,  184,  184,  184,   15,  184,  184,
+ /*  1060 */   184,  253,  184,  206,  207,  184,   95,  206,  207,  102,
+ /*  1070 */   206,  207,  206,  207,  206,  207,  206,  207,  206,  207,
+ /*  1080 */   206,  207,  206,  207,  184,  151,  184,  206,  207,  278,
+ /*  1090 */   184,  252,  184,  110,  184,  128,  184,  198,  199,  184,
+ /*  1100 */   133,  184,   60,   26,  184,   19,  206,  207,  206,  207,
+ /*  1110 */   131,  132,  206,  207,  206,  207,  206,  207,  206,  207,
+ /*  1120 */   253,  206,  207,  206,  207,   19,  206,  207,  253,   43,
+ /*  1130 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+ /*  1140 */    54,   55,   56,   57,  184,   26,  184,   26,  184,   43,
+ /*  1150 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
+ /*  1160 */    54,   55,   56,   57,  285,  286,  206,  207,  206,  207,
+ /*  1170 */   206,  207,  184,   31,  184,  293,  184,  293,  296,  184,
+ /*  1180 */   296,   39,   96,   97,   98,   99,  100,  101,  102,  103,
+ /*  1190 */   104,  105,  106,  184,  206,  207,  206,  207,  206,  207,
+ /*  1200 */   184,   22,   96,   97,   98,   99,  100,  101,  102,  103,
+ /*  1210 */   104,  105,  106,  184,  245,  246,  184,   26,   23,  142,
+ /*  1220 */   128,   26,  206,  207,  150,  133,  152,   22,   22,   24,
+ /*  1230 */   111,   23,   53,  184,   26,  206,  207,  151,  206,  207,
+ /*  1240 */   119,   24,  122,   23,   23,   23,   26,   26,   26,   23,
+ /*  1250 */    23,   23,   26,   26,   26,  136,   23,   19,   22,   26,
+ /*  1260 */   113,  114,   24,  114,  144,  184,   59,   61,    7,    8,
+ /*  1270 */    59,   23,   23,  124,   26,   26,   23,   19,  145,   26,
+ /*  1280 */   147,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+ /*  1290 */    52,   53,   54,   55,   56,   57,  145,   23,  147,  184,
+ /*  1300 */    26,   43,   44,   45,   46,   47,   48,   49,   50,   51,
+ /*  1310 */    52,   53,   54,   55,   56,   57,   23,  110,  184,   26,
+ /*  1320 */   184,  110,  184,  184,  184,  215,  135,  215,  184,  184,
+ /*  1330 */   184,  247,  184,  244,   96,   97,   98,   99,  100,  101,
+ /*  1340 */   102,  103,  104,  105,  106,  184,  184,  184,  301,  184,
+ /*  1350 */   184,  134,  225,  184,   96,   97,   98,   99,  100,  101,
+ /*  1360 */   102,  103,  104,  105,  106,  184,  184,  184,  184,  184,
+ /*  1370 */   134,  184,  274,  273,   19,  244,  244,  204,  182,  244,
+ /*  1380 */   283,  231,  279,  279,  232,  244,  210,  209,  235,  235,
+ /*  1390 */   235,  248,  218,  234,   19,  209,  238,  209,  238,   44,
+ /*  1400 */    45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
+ /*  1410 */    55,   56,   57,  214,   60,  248,  248,  187,  134,   38,
+ /*  1420 */    45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
+ /*  1430 */    55,   56,   57,  232,  191,  191,  266,  280,  191,  283,
+ /*  1440 */   143,  269,  108,   22,  280,   19,   20,  258,   22,  257,
+ /*  1450 */    43,   96,   97,   98,   99,  100,  101,  102,  103,  104,
+ /*  1460 */   105,  106,   36,  223,  142,   18,  235,  226,  226,  191,
+ /*  1470 */    18,   96,   97,   98,   99,  100,  101,  102,  103,  104,
+ /*  1480 */   105,  106,  226,  226,  190,   59,  235,  235,  223,  223,
+ /*  1490 */   258,  257,  191,  190,  235,  150,   62,   71,  191,  276,
+ /*  1500 */   275,   19,   20,  190,   22,   22,  211,   81,  191,  190,
+ /*  1510 */   211,  191,  108,  190,  208,   64,  208,  208,   36,  119,
+ /*  1520 */    94,  216,  211,  208,  210,  106,  100,  101,  216,  208,
+ /*  1530 */    48,  268,  208,  107,  208,  109,  110,  111,  211,  268,
+ /*  1540 */   114,   59,  211,  137,  108,   88,  250,  249,  191,  141,
+ /*  1550 */   250,  249,  138,   71,  250,  300,   22,  131,  132,  249,
+ /*  1560 */   300,  191,  150,  238,   82,  140,  250,  249,  239,   87,
+ /*  1570 */   139,  145,  146,  147,  148,  149,   94,  239,  237,  236,
+ /*  1580 */    25,  235,  100,  101,  194,   26,  193,   13,  185,  107,
+ /*  1590 */   185,  109,  110,  111,    6,  263,  114,  203,  265,  183,
+ /*  1600 */   183,  183,  203,  212,  203,  203,  197,  197,  212,    4,
+ /*  1610 */     3,   22,  197,  155,   15,  204,  203,  289,   93,  289,
+ /*  1620 */    16,  286,  132,   23,  204,   23,  123,  145,  146,  147,
+ /*  1630 */   148,  149,    0,    1,    2,  143,   24,    5,   20,  135,
+ /*  1640 */    16,    1,   10,   11,   12,   13,   14,  137,  135,   17,
+ /*  1650 */   144,  123,   19,   20,   61,   22,   37,  143,  123,   53,
+ /*  1660 */   109,   53,   30,   53,   32,   34,   53,  134,    1,   36,
+ /*  1670 */     5,   22,   40,  108,  153,   41,   26,   68,   75,   68,
+ /*  1680 */   134,  108,   24,   20,  124,   19,  118,   67,   67,   28,
+ /*  1690 */    22,   22,   59,   22,   67,   23,   22,   22,  142,   37,
+ /*  1700 */    23,   22,   70,   23,   71,  157,   23,   23,   26,   23,
+ /*  1710 */    78,   22,   24,   81,   23,   82,   22,   24,  134,   23,
+ /*  1720 */    87,   23,   19,   20,   92,   22,  109,   94,   22,   34,
+ /*  1730 */   136,   26,   85,  100,  101,   34,   34,   83,   34,   36,
+ /*  1740 */   107,   34,  109,  110,  111,   75,   90,  114,   75,   34,
+ /*  1750 */    23,   22,   44,   34,   24,   23,   22,   26,  126,   26,
+ /*  1760 */    23,   23,   59,  131,  132,   23,   23,   26,   23,   11,
+ /*  1770 */    22,   22,   26,   23,   71,   23,   22,   22,  145,  146,
+ /*  1780 */   147,  148,  149,  128,   23,   82,  154,  134,   15,    1,
+ /*  1790 */    87,  134,  302,  134,  134,  302,  302,   94,  302,  302,
+ /*  1800 */   302,  302,  302,  100,  101,  302,  302,  302,  302,  302,
+ /*  1810 */   107,  302,  109,  110,  111,    1,    2,  114,  302,    5,
+ /*  1820 */   302,  302,  302,  302,   10,   11,   12,   13,   14,  302,
+ /*  1830 */   302,   17,  302,  302,  302,  302,   19,   20,  302,   22,
+ /*  1840 */   302,  302,  302,  302,   30,  302,   32,  302,  145,  146,
+ /*  1850 */   147,  148,  149,   36,   40,  302,  302,  302,  302,  302,
+ /*  1860 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  1870 */   302,  302,  302,  302,  302,  302,   59,  302,  302,  302,
+ /*  1880 */   302,  302,  302,  302,   70,  302,  302,  302,   71,  302,
+ /*  1890 */   302,  302,   78,  302,  302,   81,   19,   20,  302,   22,
+ /*  1900 */   302,  302,  302,  302,  302,  302,   92,  302,  302,  302,
+ /*  1910 */   302,   94,  302,   36,  302,  302,  302,  100,  101,  102,
+ /*  1920 */   302,  302,  302,  302,  107,  302,  109,  110,  111,  302,
+ /*  1930 */   302,  114,  302,  302,  302,  302,   59,  302,  302,  302,
+ /*  1940 */   126,  302,  302,  302,  302,  131,  132,  302,   71,  302,
+ /*  1950 */   302,  302,  302,  302,  302,  302,   19,   20,  302,   22,
+ /*  1960 */   302,  302,  145,  146,  147,  148,  149,  302,  154,  302,
+ /*  1970 */   302,   94,  302,   36,  302,  302,  302,  100,  101,  302,
+ /*  1980 */   302,  302,  302,  302,  107,  302,  109,  110,  111,  302,
+ /*  1990 */   302,  114,    5,  302,  302,  302,   59,   10,   11,   12,
+ /*  2000 */    13,   14,  302,  302,   17,  302,  302,  302,   71,  302,
+ /*  2010 */   302,  302,  302,  302,  302,  302,  302,   30,  302,   32,
+ /*  2020 */   302,  302,  145,  146,  147,  148,  149,   40,  302,  302,
+ /*  2030 */   302,   94,  302,  302,  302,  302,  302,  100,  101,  302,
+ /*  2040 */   302,  302,  302,  302,  107,  302,  109,  110,  111,  302,
+ /*  2050 */   302,  114,  302,  302,  302,  302,  302,   70,  302,  302,
+ /*  2060 */   302,  302,  302,  302,  302,   78,  302,  302,   81,  302,
+ /*  2070 */   302,  302,  302,  302,  302,  302,  302,  302,  302,   92,
+ /*  2080 */   302,  302,  145,  146,  147,  148,  149,  302,  302,  302,
+ /*  2090 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2100 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2110 */   302,  302,  302,  126,  302,  302,  302,  302,  131,  132,
+ /*  2120 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2130 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2140 */   302,  154,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2150 */   302,  302,  302,  302,  302,  302,  302,  302,  302,  302,
+ /*  2160 */   302,  302,  302,  302,  302,  302,  302,  302,  302,
 };
-#define YY_SHIFT_COUNT    (520)
+#define YY_SHIFT_COUNT    (539)
 #define YY_SHIFT_MIN      (0)
-#define YY_SHIFT_MAX      (1858)
+#define YY_SHIFT_MAX      (1987)
 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,
+ /*     0 */  1814, 1632, 1987, 1426, 1426,  382, 1482, 1633, 1703, 1877,
+ /*    10 */  1877, 1877,   85,    0,    0,  264, 1106, 1877, 1877, 1877,
+ /*    20 */  1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /*    30 */   226,  226,  380,  380,  294,  667,  382,  382,  382,  382,
+ /*    40 */   382,  382,   97,  194,  332,  429,  526,  623,  720,  817,
+ /*    50 */   914,  934, 1086, 1238, 1106, 1106, 1106, 1106, 1106, 1106,
+ /*    60 */  1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106,
+ /*    70 */  1106, 1106, 1258, 1106, 1355, 1375, 1375, 1817, 1877, 1877,
+ /*    80 */  1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /*    90 */  1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /*   100 */  1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /*   110 */  1937, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /*   120 */  1877, 1877, 1877, 1877,   32,  129,  129,  129,  129,  129,
+ /*   130 */   171,    7,   17,  593,  676,  590,  593,  205,  205,  593,
+ /*   140 */   318,  318,  318,  318,   50,  152,   51, 2142, 2142,  284,
+ /*   150 */   284,  284,   65,  145,  282,  145,  145,  574,  574,  256,
+ /*   160 */   348,  445,  782,  593,  593,  593,  593,  593,  593,  593,
+ /*   170 */   593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+ /*   180 */   593,  593,  593,  593,  607,  607,  593,  721,  805,  805,
+ /*   190 */   446,  851,  851,  446,  190,  979, 2142, 2142, 2142,  453,
+ /*   200 */    45,   45,  480,  490,  484,  385,  575,  502,  551,  581,
+ /*   210 */   593,  593,  593,  593,  593,  593,  593,  593,  593,  689,
+ /*   220 */   593,  593,  593,  593,  593,  593,  593,  593,  593,  593,
+ /*   230 */   593,  593,  582,  582,  582,  593,  593,  593,  593,  771,
+ /*   240 */   593,  593,  593,   59,  764,  593,  593,  863,  593,  593,
+ /*   250 */   593,  593,  593,  593,  593,  593,  665,  819,  580,   16,
+ /*   260 */    16,   16,   16, 1119,  580,  580,  967,  321,  931, 1042,
+ /*   270 */  1077,  783,  783,  834, 1077, 1077,  834, 1121, 1195,  401,
+ /*   280 */  1142, 1142, 1142,  783,  787,  787, 1074, 1191, 1092, 1205,
+ /*   290 */  1354, 1284, 1284, 1381, 1381, 1284, 1297, 1334, 1421, 1407,
+ /*   300 */  1322, 1447, 1447, 1447, 1447, 1284, 1452, 1322, 1322, 1334,
+ /*   310 */  1421, 1407, 1407, 1322, 1284, 1452, 1345, 1434, 1284, 1452,
+ /*   320 */  1483, 1284, 1452, 1284, 1452, 1483, 1404, 1404, 1404, 1451,
+ /*   330 */  1483, 1404, 1400, 1404, 1451, 1404, 1404, 1483, 1419, 1419,
+ /*   340 */  1483, 1406, 1436, 1406, 1436, 1406, 1436, 1406, 1436, 1284,
+ /*   350 */  1457, 1457, 1408, 1414, 1534, 1284, 1412, 1408, 1425, 1431,
+ /*   360 */  1322, 1555, 1559, 1574, 1574, 1588, 1588, 1588, 2142, 2142,
+ /*   370 */  2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ /*   380 */  2142, 2142, 2142,  378,  777,  836,  971,  825,  775,  983,
+ /*   390 */  1208, 1179, 1217, 1120, 1220, 1206, 1221, 1222, 1226, 1227,
+ /*   400 */  1228, 1233,  937, 1147, 1261, 1149, 1207, 1248, 1249, 1253,
+ /*   410 */  1133, 1151, 1274, 1293, 1211, 1236, 1605, 1607, 1589, 1458,
+ /*   420 */  1599, 1525, 1604, 1600, 1602, 1490, 1492, 1503, 1612, 1504,
+ /*   430 */  1618, 1510, 1624, 1640, 1513, 1506, 1528, 1593, 1619, 1514,
+ /*   440 */  1606, 1608, 1610, 1613, 1535, 1551, 1631, 1533, 1667, 1665,
+ /*   450 */  1649, 1565, 1521, 1609, 1650, 1611, 1603, 1634, 1546, 1573,
+ /*   460 */  1658, 1663, 1666, 1560, 1568, 1668, 1620, 1669, 1671, 1672,
+ /*   470 */  1674, 1621, 1661, 1675, 1627, 1662, 1677, 1556, 1679, 1680,
+ /*   480 */  1548, 1683, 1684, 1682, 1686, 1689, 1688, 1691, 1694, 1693,
+ /*   490 */  1584, 1696, 1698, 1617, 1695, 1706, 1594, 1705, 1701, 1702,
+ /*   500 */  1704, 1707, 1647, 1670, 1654, 1708, 1673, 1656, 1715, 1727,
+ /*   510 */  1729, 1730, 1731, 1733, 1719, 1732, 1705, 1737, 1738, 1742,
+ /*   520 */  1743, 1741, 1745, 1734, 1758, 1748, 1749, 1750, 1752, 1754,
+ /*   530 */  1755, 1746, 1655, 1653, 1657, 1659, 1660, 1761, 1773, 1788,
 };
-#define YY_REDUCE_COUNT (369)
-#define YY_REDUCE_MIN   (-237)
-#define YY_REDUCE_MAX   (1424)
+#define YY_REDUCE_COUNT (382)
+#define YY_REDUCE_MIN   (-260)
+#define YY_REDUCE_MAX   (1420)
 static const short yy_reduce_ofst[] = {
- /*     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,
+ /*     0 */  -170,  -18, -159,  309,  313, -167,  -19,   75,  117,  211,
+ /*    10 */   315,  317, -165, -195, -168, -260,  389,  437,  475,  524,
+ /*    20 */   527, -169,  529,  531,  -28,   80,  534,  239,  304,  412,
+ /*    30 */   558,  577,   37,  120,  368,  -22,  460,  517,  555,  560,
+ /*    40 */   562,  586, -257, -257, -257, -257, -257, -257, -257, -257,
+ /*    50 */  -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /*    60 */  -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /*    70 */  -257, -257, -257, -257, -257, -257, -257, -172,  457,  628,
+ /*    80 */   673,  692,  694,  702,  704,  722,  728,  740,  743,  748,
+ /*    90 */   767,  791,  815,  818,  820,  822,  857,  861,  864,  866,
+ /*   100 */   868,  870,  872,  874,  876,  881,  900,  902,  906,  908,
+ /*   110 */   910,  912,  915,  917,  920,  960,  962,  964,  988,  990,
+ /*   120 */   992, 1016, 1029, 1032, -257, -257, -257, -257, -257, -257,
+ /*   130 */  -257, -257, -257,  271,  618, -190,   68,   60,  240, -124,
+ /*   140 */   603,  610,  603,  610,   12, -257, -257, -257, -257, -128,
+ /*   150 */  -128, -128, -142,   25,  270,  281,  333,  124,  236,  648,
+ /*   160 */   374,  465,  465,   28,  598,  792,  839,  469,   38,  381,
+ /*   170 */   622,  709,  173,  699,  522,  703,  808,  811,  867,  816,
+ /*   180 */  -104,  823,   -3,  875,  649,  753,  323,  -88,  882,  884,
+ /*   190 */   518,   43,  325,  899,  763,  604,  879,  969,  402, -193,
+ /*   200 */  -189, -180, -151,  -55,   69,  104,  141,  259,  286,  360,
+ /*   210 */   364,  455,  474,  481,  510,  516,  611,  653,  788,   99,
+ /*   220 */   871,  878,  995, 1009, 1049, 1081, 1115, 1134, 1136, 1138,
+ /*   230 */  1139, 1140,  733, 1110, 1112, 1144, 1145, 1146, 1148, 1084,
+ /*   240 */  1161, 1162, 1163, 1089, 1047, 1165, 1166, 1127, 1169,  104,
+ /*   250 */  1181, 1182, 1183, 1184, 1185, 1187, 1098, 1100, 1150, 1131,
+ /*   260 */  1132, 1135, 1141, 1084, 1150, 1150, 1152, 1173, 1196, 1097,
+ /*   270 */  1153, 1143, 1167, 1103, 1154, 1155, 1104, 1176, 1174, 1199,
+ /*   280 */  1178, 1186, 1188, 1168, 1158, 1160, 1170, 1159, 1201, 1230,
+ /*   290 */  1156, 1243, 1244, 1157, 1164, 1247, 1172, 1189, 1192, 1240,
+ /*   300 */  1231, 1241, 1242, 1256, 1257, 1278, 1294, 1251, 1252, 1232,
+ /*   310 */  1234, 1265, 1266, 1259, 1301, 1303, 1223, 1225, 1307, 1313,
+ /*   320 */  1295, 1317, 1319, 1320, 1323, 1299, 1306, 1308, 1309, 1305,
+ /*   330 */  1311, 1315, 1314, 1321, 1312, 1324, 1326, 1327, 1263, 1271,
+ /*   340 */  1331, 1296, 1298, 1300, 1302, 1304, 1310, 1316, 1318, 1357,
+ /*   350 */  1255, 1260, 1329, 1325, 1332, 1370, 1333, 1338, 1341, 1343,
+ /*   360 */  1346, 1390, 1393, 1403, 1405, 1416, 1417, 1418, 1328, 1330,
+ /*   370 */  1335, 1409, 1394, 1399, 1401, 1402, 1410, 1391, 1396, 1411,
+ /*   380 */  1420, 1413, 1415,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     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,
+ /*     0 */  1537, 1537, 1537, 1377, 1159, 1266, 1159, 1159, 1159, 1377,
+ /*    10 */  1377, 1377, 1159, 1296, 1296, 1430, 1190, 1159, 1159, 1159,
+ /*    20 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1376, 1159, 1159,
+ /*    30 */  1159, 1159, 1460, 1460, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*    40 */  1159, 1159, 1159, 1302, 1159, 1159, 1159, 1159, 1159, 1378,
+ /*    50 */  1379, 1159, 1159, 1159, 1429, 1431, 1394, 1312, 1311, 1310,
+ /*    60 */  1309, 1412, 1283, 1307, 1300, 1304, 1372, 1373, 1371, 1375,
+ /*    70 */  1379, 1378, 1159, 1303, 1343, 1357, 1342, 1159, 1159, 1159,
+ /*    80 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*    90 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   100 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   110 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   120 */  1159, 1159, 1159, 1159, 1351, 1356, 1362, 1355, 1352, 1345,
+ /*   130 */  1344, 1346, 1347, 1159, 1180, 1230, 1159, 1159, 1159, 1159,
+ /*   140 */  1448, 1447, 1159, 1159, 1190, 1348, 1349, 1359, 1358, 1437,
+ /*   150 */  1493, 1492, 1395, 1159, 1159, 1159, 1159, 1159, 1159, 1460,
+ /*   160 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   170 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   180 */  1159, 1159, 1159, 1159, 1460, 1460, 1159, 1190, 1460, 1460,
+ /*   190 */  1186, 1337, 1336, 1186, 1290, 1159, 1443, 1266, 1257, 1159,
+ /*   200 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   210 */  1159, 1159, 1159, 1434, 1432, 1159, 1159, 1159, 1159, 1159,
+ /*   220 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   230 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   240 */  1159, 1159, 1159, 1262, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   250 */  1159, 1159, 1159, 1159, 1159, 1487, 1159, 1407, 1244, 1262,
+ /*   260 */  1262, 1262, 1262, 1264, 1245, 1243, 1256, 1191, 1166, 1529,
+ /*   270 */  1306, 1285, 1285, 1526, 1306, 1306, 1526, 1205, 1507, 1202,
+ /*   280 */  1296, 1296, 1296, 1285, 1290, 1290, 1374, 1263, 1256, 1159,
+ /*   290 */  1529, 1271, 1271, 1528, 1528, 1271, 1395, 1315, 1321, 1233,
+ /*   300 */  1306, 1239, 1239, 1239, 1239, 1271, 1177, 1306, 1306, 1315,
+ /*   310 */  1321, 1233, 1233, 1306, 1271, 1177, 1411, 1523, 1271, 1177,
+ /*   320 */  1385, 1271, 1177, 1271, 1177, 1385, 1231, 1231, 1231, 1220,
+ /*   330 */  1385, 1231, 1205, 1231, 1220, 1231, 1231, 1385, 1389, 1389,
+ /*   340 */  1385, 1289, 1284, 1289, 1284, 1289, 1284, 1289, 1284, 1271,
+ /*   350 */  1470, 1470, 1301, 1290, 1380, 1271, 1159, 1301, 1299, 1297,
+ /*   360 */  1306, 1183, 1223, 1490, 1490, 1486, 1486, 1486, 1534, 1534,
+ /*   370 */  1443, 1502, 1190, 1190, 1190, 1190, 1502, 1207, 1207, 1191,
+ /*   380 */  1191, 1190, 1502, 1159, 1159, 1159, 1159, 1159, 1159, 1497,
+ /*   390 */  1159, 1396, 1275, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   400 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   410 */  1159, 1159, 1159, 1159, 1159, 1326, 1159, 1162, 1440, 1159,
+ /*   420 */  1159, 1438, 1159, 1159, 1159, 1159, 1159, 1159, 1276, 1159,
+ /*   430 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   440 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1525, 1159, 1159,
+ /*   450 */  1159, 1159, 1159, 1159, 1410, 1409, 1159, 1159, 1273, 1159,
+ /*   460 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   470 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   480 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   490 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1298, 1159, 1159,
+ /*   500 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   510 */  1159, 1159, 1475, 1291, 1159, 1159, 1516, 1159, 1159, 1159,
+ /*   520 */  1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /*   530 */  1159, 1511, 1247, 1328, 1159, 1327, 1331, 1159, 1171, 1159,
 };
 /********** End of lemon-generated parsing tables *****************************/
 
@@ -146935,6 +149758,10 @@ static const YYCODETYPE yyFallback[] = {
    59,  /*  PRECEDING => ID */
    59,  /*      RANGE => ID */
    59,  /*  UNBOUNDED => ID */
+   59,  /*    EXCLUDE => ID */
+   59,  /*     GROUPS => ID */
+   59,  /*     OTHERS => ID */
+   59,  /*       TIES => ID */
    59,  /*    REINDEX => ID */
    59,  /*     RENAME => ID */
    59,  /*   CTIME_KW => ID */
@@ -147113,195 +149940,220 @@ static const char *const yyTokenName[] = {
   /*   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",
+  /*   88 */ "EXCLUDE",
+  /*   89 */ "GROUPS",
+  /*   90 */ "OTHERS",
+  /*   91 */ "TIES",
+  /*   92 */ "REINDEX",
+  /*   93 */ "RENAME",
+  /*   94 */ "CTIME_KW",
+  /*   95 */ "ANY",
+  /*   96 */ "BITAND",
+  /*   97 */ "BITOR",
+  /*   98 */ "LSHIFT",
+  /*   99 */ "RSHIFT",
+  /*  100 */ "PLUS",
+  /*  101 */ "MINUS",
+  /*  102 */ "STAR",
+  /*  103 */ "SLASH",
+  /*  104 */ "REM",
+  /*  105 */ "CONCAT",
+  /*  106 */ "COLLATE",
+  /*  107 */ "BITNOT",
+  /*  108 */ "ON",
+  /*  109 */ "INDEXED",
+  /*  110 */ "STRING",
+  /*  111 */ "JOIN_KW",
+  /*  112 */ "CONSTRAINT",
+  /*  113 */ "DEFAULT",
+  /*  114 */ "NULL",
+  /*  115 */ "PRIMARY",
+  /*  116 */ "UNIQUE",
+  /*  117 */ "CHECK",
+  /*  118 */ "REFERENCES",
+  /*  119 */ "AUTOINCR",
+  /*  120 */ "INSERT",
+  /*  121 */ "DELETE",
+  /*  122 */ "UPDATE",
+  /*  123 */ "SET",
+  /*  124 */ "DEFERRABLE",
+  /*  125 */ "FOREIGN",
+  /*  126 */ "DROP",
+  /*  127 */ "UNION",
+  /*  128 */ "ALL",
+  /*  129 */ "EXCEPT",
+  /*  130 */ "INTERSECT",
+  /*  131 */ "SELECT",
+  /*  132 */ "VALUES",
+  /*  133 */ "DISTINCT",
+  /*  134 */ "DOT",
+  /*  135 */ "FROM",
+  /*  136 */ "JOIN",
+  /*  137 */ "USING",
+  /*  138 */ "ORDER",
+  /*  139 */ "GROUP",
+  /*  140 */ "HAVING",
+  /*  141 */ "LIMIT",
+  /*  142 */ "WHERE",
+  /*  143 */ "INTO",
+  /*  144 */ "NOTHING",
+  /*  145 */ "FLOAT",
+  /*  146 */ "BLOB",
+  /*  147 */ "INTEGER",
+  /*  148 */ "VARIABLE",
+  /*  149 */ "CASE",
+  /*  150 */ "WHEN",
+  /*  151 */ "THEN",
+  /*  152 */ "ELSE",
+  /*  153 */ "INDEX",
+  /*  154 */ "ALTER",
+  /*  155 */ "ADD",
+  /*  156 */ "WINDOW",
+  /*  157 */ "OVER",
+  /*  158 */ "FILTER",
+  /*  159 */ "TRUEFALSE",
+  /*  160 */ "ISNOT",
+  /*  161 */ "FUNCTION",
+  /*  162 */ "COLUMN",
+  /*  163 */ "AGG_FUNCTION",
+  /*  164 */ "AGG_COLUMN",
+  /*  165 */ "UMINUS",
+  /*  166 */ "UPLUS",
+  /*  167 */ "TRUTH",
+  /*  168 */ "REGISTER",
+  /*  169 */ "VECTOR",
+  /*  170 */ "SELECT_COLUMN",
+  /*  171 */ "IF_NULL_ROW",
+  /*  172 */ "ASTERISK",
+  /*  173 */ "SPAN",
+  /*  174 */ "SPACE",
+  /*  175 */ "ILLEGAL",
+  /*  176 */ "input",
+  /*  177 */ "cmdlist",
+  /*  178 */ "ecmd",
+  /*  179 */ "cmdx",
+  /*  180 */ "explain",
+  /*  181 */ "cmd",
+  /*  182 */ "transtype",
+  /*  183 */ "trans_opt",
+  /*  184 */ "nm",
+  /*  185 */ "savepoint_opt",
+  /*  186 */ "create_table",
+  /*  187 */ "create_table_args",
+  /*  188 */ "createkw",
+  /*  189 */ "temp",
+  /*  190 */ "ifnotexists",
+  /*  191 */ "dbnm",
+  /*  192 */ "columnlist",
+  /*  193 */ "conslist_opt",
+  /*  194 */ "table_options",
+  /*  195 */ "select",
+  /*  196 */ "columnname",
+  /*  197 */ "carglist",
+  /*  198 */ "typetoken",
+  /*  199 */ "typename",
+  /*  200 */ "signed",
+  /*  201 */ "plus_num",
+  /*  202 */ "minus_num",
+  /*  203 */ "scanpt",
+  /*  204 */ "scantok",
+  /*  205 */ "ccons",
+  /*  206 */ "term",
+  /*  207 */ "expr",
+  /*  208 */ "onconf",
+  /*  209 */ "sortorder",
+  /*  210 */ "autoinc",
+  /*  211 */ "eidlist_opt",
+  /*  212 */ "refargs",
+  /*  213 */ "defer_subclause",
+  /*  214 */ "refarg",
+  /*  215 */ "refact",
+  /*  216 */ "init_deferred_pred_opt",
+  /*  217 */ "conslist",
+  /*  218 */ "tconscomma",
+  /*  219 */ "tcons",
+  /*  220 */ "sortlist",
+  /*  221 */ "eidlist",
+  /*  222 */ "defer_subclause_opt",
+  /*  223 */ "orconf",
+  /*  224 */ "resolvetype",
+  /*  225 */ "raisetype",
+  /*  226 */ "ifexists",
+  /*  227 */ "fullname",
+  /*  228 */ "selectnowith",
+  /*  229 */ "oneselect",
+  /*  230 */ "wqlist",
+  /*  231 */ "multiselect_op",
+  /*  232 */ "distinct",
+  /*  233 */ "selcollist",
+  /*  234 */ "from",
+  /*  235 */ "where_opt",
+  /*  236 */ "groupby_opt",
+  /*  237 */ "having_opt",
+  /*  238 */ "orderby_opt",
+  /*  239 */ "limit_opt",
+  /*  240 */ "window_clause",
+  /*  241 */ "values",
+  /*  242 */ "nexprlist",
+  /*  243 */ "sclp",
+  /*  244 */ "as",
+  /*  245 */ "seltablist",
+  /*  246 */ "stl_prefix",
+  /*  247 */ "joinop",
+  /*  248 */ "indexed_opt",
+  /*  249 */ "on_opt",
+  /*  250 */ "using_opt",
+  /*  251 */ "exprlist",
+  /*  252 */ "xfullname",
+  /*  253 */ "idlist",
+  /*  254 */ "with",
+  /*  255 */ "setlist",
+  /*  256 */ "insert_cmd",
+  /*  257 */ "idlist_opt",
+  /*  258 */ "upsert",
+  /*  259 */ "over_clause",
+  /*  260 */ "likeop",
+  /*  261 */ "between_op",
+  /*  262 */ "in_op",
+  /*  263 */ "paren_exprlist",
+  /*  264 */ "case_operand",
+  /*  265 */ "case_exprlist",
+  /*  266 */ "case_else",
+  /*  267 */ "uniqueflag",
+  /*  268 */ "collate",
+  /*  269 */ "vinto",
+  /*  270 */ "nmnum",
+  /*  271 */ "trigger_decl",
+  /*  272 */ "trigger_cmd_list",
+  /*  273 */ "trigger_time",
+  /*  274 */ "trigger_event",
+  /*  275 */ "foreach_clause",
+  /*  276 */ "when_clause",
+  /*  277 */ "trigger_cmd",
+  /*  278 */ "trnm",
+  /*  279 */ "tridxby",
+  /*  280 */ "database_kw_opt",
+  /*  281 */ "key_opt",
+  /*  282 */ "add_column_fullname",
+  /*  283 */ "kwcolumn_opt",
+  /*  284 */ "create_vtab",
+  /*  285 */ "vtabarglist",
+  /*  286 */ "vtabarg",
+  /*  287 */ "vtabargtoken",
+  /*  288 */ "lp",
+  /*  289 */ "anylist",
+  /*  290 */ "windowdefn_list",
+  /*  291 */ "windowdefn",
+  /*  292 */ "window",
+  /*  293 */ "frame_opt",
+  /*  294 */ "part_opt",
+  /*  295 */ "filter_opt",
+  /*  296 */ "range_or_rows",
+  /*  297 */ "frame_bound",
+  /*  298 */ "frame_bound_s",
+  /*  299 */ "frame_bound_e",
+  /*  300 */ "frame_exclude_opt",
+  /*  301 */ "frame_exclude",
 };
 #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
 
@@ -147338,344 +150190,353 @@ static const char *const yyRuleName[] = {
  /*  26 */ "typetoken ::= typename LP signed COMMA signed RP",
  /*  27 */ "typename ::= typename ID|STRING",
  /*  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 ::=",
+ /*  29 */ "scantok ::=",
+ /*  30 */ "ccons ::= CONSTRAINT nm",
+ /*  31 */ "ccons ::= DEFAULT scantok term",
+ /*  32 */ "ccons ::= DEFAULT LP expr RP",
+ /*  33 */ "ccons ::= DEFAULT PLUS scantok term",
+ /*  34 */ "ccons ::= DEFAULT MINUS scantok term",
+ /*  35 */ "ccons ::= DEFAULT scantok ID|INDEXED",
+ /*  36 */ "ccons ::= NOT NULL onconf",
+ /*  37 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /*  38 */ "ccons ::= UNIQUE onconf",
+ /*  39 */ "ccons ::= CHECK LP expr RP",
+ /*  40 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /*  41 */ "ccons ::= defer_subclause",
+ /*  42 */ "ccons ::= COLLATE ID|STRING",
+ /*  43 */ "autoinc ::=",
+ /*  44 */ "autoinc ::= AUTOINCR",
+ /*  45 */ "refargs ::=",
+ /*  46 */ "refargs ::= refargs refarg",
+ /*  47 */ "refarg ::= MATCH nm",
+ /*  48 */ "refarg ::= ON INSERT refact",
+ /*  49 */ "refarg ::= ON DELETE refact",
+ /*  50 */ "refarg ::= ON UPDATE refact",
+ /*  51 */ "refact ::= SET NULL",
+ /*  52 */ "refact ::= SET DEFAULT",
+ /*  53 */ "refact ::= CASCADE",
+ /*  54 */ "refact ::= RESTRICT",
+ /*  55 */ "refact ::= NO ACTION",
+ /*  56 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /*  57 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /*  58 */ "init_deferred_pred_opt ::=",
+ /*  59 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /*  60 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /*  61 */ "conslist_opt ::=",
+ /*  62 */ "tconscomma ::= COMMA",
+ /*  63 */ "tcons ::= CONSTRAINT nm",
+ /*  64 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /*  65 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /*  66 */ "tcons ::= CHECK LP expr RP onconf",
+ /*  67 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /*  68 */ "defer_subclause_opt ::=",
+ /*  69 */ "onconf ::=",
+ /*  70 */ "onconf ::= ON CONFLICT resolvetype",
+ /*  71 */ "orconf ::=",
+ /*  72 */ "orconf ::= OR resolvetype",
+ /*  73 */ "resolvetype ::= IGNORE",
+ /*  74 */ "resolvetype ::= REPLACE",
+ /*  75 */ "cmd ::= DROP TABLE ifexists fullname",
+ /*  76 */ "ifexists ::= IF EXISTS",
+ /*  77 */ "ifexists ::=",
+ /*  78 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /*  79 */ "cmd ::= DROP VIEW ifexists fullname",
+ /*  80 */ "cmd ::= select",
+ /*  81 */ "select ::= WITH wqlist selectnowith",
+ /*  82 */ "select ::= WITH RECURSIVE wqlist selectnowith",
+ /*  83 */ "select ::= selectnowith",
+ /*  84 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /*  85 */ "multiselect_op ::= UNION",
+ /*  86 */ "multiselect_op ::= UNION ALL",
+ /*  87 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /*  88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /*  89 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
+ /*  90 */ "values ::= VALUES LP nexprlist RP",
+ /*  91 */ "values ::= values COMMA LP nexprlist RP",
+ /*  92 */ "distinct ::= DISTINCT",
+ /*  93 */ "distinct ::= ALL",
+ /*  94 */ "distinct ::=",
+ /*  95 */ "sclp ::=",
+ /*  96 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /*  97 */ "selcollist ::= sclp scanpt STAR",
+ /*  98 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /*  99 */ "as ::= AS nm",
+ /* 100 */ "as ::=",
+ /* 101 */ "from ::=",
+ /* 102 */ "from ::= FROM seltablist",
+ /* 103 */ "stl_prefix ::= seltablist joinop",
+ /* 104 */ "stl_prefix ::=",
+ /* 105 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 106 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 107 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 108 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 109 */ "dbnm ::=",
+ /* 110 */ "dbnm ::= DOT nm",
+ /* 111 */ "fullname ::= nm",
+ /* 112 */ "fullname ::= nm DOT nm",
+ /* 113 */ "xfullname ::= nm",
+ /* 114 */ "xfullname ::= nm DOT nm",
+ /* 115 */ "xfullname ::= nm DOT nm AS nm",
+ /* 116 */ "xfullname ::= nm AS nm",
+ /* 117 */ "joinop ::= COMMA|JOIN",
+ /* 118 */ "joinop ::= JOIN_KW JOIN",
+ /* 119 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 120 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 121 */ "on_opt ::= ON expr",
+ /* 122 */ "on_opt ::=",
+ /* 123 */ "indexed_opt ::=",
+ /* 124 */ "indexed_opt ::= INDEXED BY nm",
+ /* 125 */ "indexed_opt ::= NOT INDEXED",
+ /* 126 */ "using_opt ::= USING LP idlist RP",
+ /* 127 */ "using_opt ::=",
+ /* 128 */ "orderby_opt ::=",
+ /* 129 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 130 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 131 */ "sortlist ::= expr sortorder",
+ /* 132 */ "sortorder ::= ASC",
+ /* 133 */ "sortorder ::= DESC",
+ /* 134 */ "sortorder ::=",
+ /* 135 */ "groupby_opt ::=",
+ /* 136 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 137 */ "having_opt ::=",
+ /* 138 */ "having_opt ::= HAVING expr",
+ /* 139 */ "limit_opt ::=",
+ /* 140 */ "limit_opt ::= LIMIT expr",
+ /* 141 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 142 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 143 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
+ /* 144 */ "where_opt ::=",
+ /* 145 */ "where_opt ::= WHERE expr",
+ /* 146 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
+ /* 147 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 148 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 149 */ "setlist ::= nm EQ expr",
+ /* 150 */ "setlist ::= LP idlist RP EQ expr",
+ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 152 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
+ /* 153 */ "upsert ::=",
+ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
+ /* 155 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
+ /* 156 */ "upsert ::= ON CONFLICT DO NOTHING",
+ /* 157 */ "insert_cmd ::= INSERT orconf",
+ /* 158 */ "insert_cmd ::= REPLACE",
+ /* 159 */ "idlist_opt ::=",
+ /* 160 */ "idlist_opt ::= LP idlist RP",
+ /* 161 */ "idlist ::= idlist COMMA nm",
+ /* 162 */ "idlist ::= nm",
+ /* 163 */ "expr ::= LP expr RP",
+ /* 164 */ "expr ::= ID|INDEXED",
+ /* 165 */ "expr ::= JOIN_KW",
+ /* 166 */ "expr ::= nm DOT nm",
+ /* 167 */ "expr ::= nm DOT nm DOT nm",
+ /* 168 */ "term ::= NULL|FLOAT|BLOB",
+ /* 169 */ "term ::= STRING",
+ /* 170 */ "term ::= INTEGER",
+ /* 171 */ "expr ::= VARIABLE",
+ /* 172 */ "expr ::= expr COLLATE ID|STRING",
+ /* 173 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 174 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 175 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 176 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
+ /* 177 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
+ /* 178 */ "term ::= CTIME_KW",
+ /* 179 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 180 */ "expr ::= expr AND expr",
+ /* 181 */ "expr ::= expr OR expr",
+ /* 182 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 183 */ "expr ::= expr EQ|NE expr",
+ /* 184 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 185 */ "expr ::= expr PLUS|MINUS expr",
+ /* 186 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 187 */ "expr ::= expr CONCAT expr",
+ /* 188 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 189 */ "expr ::= expr likeop expr",
+ /* 190 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 191 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 192 */ "expr ::= expr NOT NULL",
+ /* 193 */ "expr ::= expr IS expr",
+ /* 194 */ "expr ::= expr IS NOT expr",
+ /* 195 */ "expr ::= NOT expr",
+ /* 196 */ "expr ::= BITNOT expr",
+ /* 197 */ "expr ::= PLUS|MINUS expr",
+ /* 198 */ "between_op ::= BETWEEN",
+ /* 199 */ "between_op ::= NOT BETWEEN",
+ /* 200 */ "expr ::= expr between_op expr AND expr",
+ /* 201 */ "in_op ::= IN",
+ /* 202 */ "in_op ::= NOT IN",
+ /* 203 */ "expr ::= expr in_op LP exprlist RP",
+ /* 204 */ "expr ::= LP select RP",
+ /* 205 */ "expr ::= expr in_op LP select RP",
+ /* 206 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 207 */ "expr ::= EXISTS LP select RP",
+ /* 208 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 209 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 210 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 211 */ "case_else ::= ELSE expr",
+ /* 212 */ "case_else ::=",
+ /* 213 */ "case_operand ::= expr",
+ /* 214 */ "case_operand ::=",
+ /* 215 */ "exprlist ::=",
+ /* 216 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 217 */ "nexprlist ::= expr",
+ /* 218 */ "paren_exprlist ::=",
+ /* 219 */ "paren_exprlist ::= LP exprlist RP",
+ /* 220 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 221 */ "uniqueflag ::= UNIQUE",
+ /* 222 */ "uniqueflag ::=",
+ /* 223 */ "eidlist_opt ::=",
+ /* 224 */ "eidlist_opt ::= LP eidlist RP",
+ /* 225 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 226 */ "eidlist ::= nm collate sortorder",
+ /* 227 */ "collate ::=",
+ /* 228 */ "collate ::= COLLATE ID|STRING",
+ /* 229 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 230 */ "cmd ::= VACUUM vinto",
+ /* 231 */ "cmd ::= VACUUM nm vinto",
+ /* 232 */ "vinto ::= INTO expr",
+ /* 233 */ "vinto ::=",
+ /* 234 */ "cmd ::= PRAGMA nm dbnm",
+ /* 235 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 236 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 237 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 238 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 239 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 240 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 241 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 242 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 243 */ "trigger_time ::= BEFORE|AFTER",
+ /* 244 */ "trigger_time ::= INSTEAD OF",
+ /* 245 */ "trigger_time ::=",
+ /* 246 */ "trigger_event ::= DELETE|INSERT",
+ /* 247 */ "trigger_event ::= UPDATE",
+ /* 248 */ "trigger_event ::= UPDATE OF idlist",
+ /* 249 */ "when_clause ::=",
+ /* 250 */ "when_clause ::= WHEN expr",
+ /* 251 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 252 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 253 */ "trnm ::= nm DOT nm",
+ /* 254 */ "tridxby ::= INDEXED BY nm",
+ /* 255 */ "tridxby ::= NOT INDEXED",
+ /* 256 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 257 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 258 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 259 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 260 */ "expr ::= RAISE LP IGNORE RP",
+ /* 261 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 262 */ "raisetype ::= ROLLBACK",
+ /* 263 */ "raisetype ::= ABORT",
+ /* 264 */ "raisetype ::= FAIL",
+ /* 265 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 266 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 267 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 268 */ "key_opt ::=",
+ /* 269 */ "key_opt ::= KEY expr",
+ /* 270 */ "cmd ::= REINDEX",
+ /* 271 */ "cmd ::= REINDEX nm dbnm",
+ /* 272 */ "cmd ::= ANALYZE",
+ /* 273 */ "cmd ::= ANALYZE nm dbnm",
+ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 275 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 276 */ "add_column_fullname ::= fullname",
+ /* 277 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 278 */ "cmd ::= create_vtab",
+ /* 279 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 280 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 281 */ "vtabarg ::=",
+ /* 282 */ "vtabargtoken ::= ANY",
+ /* 283 */ "vtabargtoken ::= lp anylist RP",
+ /* 284 */ "lp ::= LP",
+ /* 285 */ "with ::= WITH wqlist",
+ /* 286 */ "with ::= WITH RECURSIVE wqlist",
+ /* 287 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 288 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 289 */ "windowdefn_list ::= windowdefn",
+ /* 290 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 291 */ "windowdefn ::= nm AS LP window RP",
+ /* 292 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 293 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 294 */ "window ::= ORDER BY sortlist frame_opt",
+ /* 295 */ "window ::= nm ORDER BY sortlist frame_opt",
+ /* 296 */ "window ::= frame_opt",
+ /* 297 */ "window ::= nm frame_opt",
+ /* 298 */ "frame_opt ::=",
+ /* 299 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+ /* 300 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+ /* 301 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+ /* 302 */ "frame_bound_s ::= frame_bound",
+ /* 303 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 304 */ "frame_bound_e ::= frame_bound",
+ /* 305 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 306 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+ /* 307 */ "frame_bound ::= CURRENT ROW",
+ /* 308 */ "frame_exclude_opt ::=",
+ /* 309 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+ /* 310 */ "frame_exclude ::= NO OTHERS",
+ /* 311 */ "frame_exclude ::= CURRENT ROW",
+ /* 312 */ "frame_exclude ::= GROUP|TIES",
+ /* 313 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 314 */ "over_clause ::= filter_opt OVER LP window RP",
+ /* 315 */ "over_clause ::= filter_opt OVER nm",
+ /* 316 */ "filter_opt ::=",
+ /* 317 */ "filter_opt ::= FILTER LP WHERE expr RP",
+ /* 318 */ "input ::= cmdlist",
+ /* 319 */ "cmdlist ::= cmdlist ecmd",
+ /* 320 */ "cmdlist ::= ecmd",
+ /* 321 */ "ecmd ::= SEMI",
+ /* 322 */ "ecmd ::= cmdx SEMI",
+ /* 323 */ "ecmd ::= explain cmdx",
+ /* 324 */ "trans_opt ::=",
+ /* 325 */ "trans_opt ::= TRANSACTION",
+ /* 326 */ "trans_opt ::= TRANSACTION nm",
+ /* 327 */ "savepoint_opt ::= SAVEPOINT",
+ /* 328 */ "savepoint_opt ::=",
+ /* 329 */ "cmd ::= create_table create_table_args",
+ /* 330 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 331 */ "columnlist ::= columnname carglist",
+ /* 332 */ "nm ::= ID|INDEXED",
+ /* 333 */ "nm ::= STRING",
+ /* 334 */ "nm ::= JOIN_KW",
+ /* 335 */ "typetoken ::= typename",
+ /* 336 */ "typename ::= ID|STRING",
+ /* 337 */ "signed ::= plus_num",
+ /* 338 */ "signed ::= minus_num",
+ /* 339 */ "carglist ::= carglist ccons",
+ /* 340 */ "carglist ::=",
+ /* 341 */ "ccons ::= NULL onconf",
+ /* 342 */ "conslist_opt ::= COMMA conslist",
+ /* 343 */ "conslist ::= conslist tconscomma tcons",
+ /* 344 */ "conslist ::= tcons",
+ /* 345 */ "tconscomma ::=",
+ /* 346 */ "defer_subclause_opt ::= defer_subclause",
+ /* 347 */ "resolvetype ::= raisetype",
+ /* 348 */ "selectnowith ::= oneselect",
+ /* 349 */ "oneselect ::= values",
+ /* 350 */ "sclp ::= selcollist COMMA",
+ /* 351 */ "as ::= ID|STRING",
+ /* 352 */ "expr ::= term",
+ /* 353 */ "likeop ::= LIKE_KW|MATCH",
+ /* 354 */ "exprlist ::= nexprlist",
+ /* 355 */ "nmnum ::= plus_num",
+ /* 356 */ "nmnum ::= nm",
+ /* 357 */ "nmnum ::= ON",
+ /* 358 */ "nmnum ::= DELETE",
+ /* 359 */ "nmnum ::= DEFAULT",
+ /* 360 */ "plus_num ::= INTEGER|FLOAT",
+ /* 361 */ "foreach_clause ::=",
+ /* 362 */ "foreach_clause ::= FOR EACH ROW",
+ /* 363 */ "trnm ::= nm",
+ /* 364 */ "tridxby ::=",
+ /* 365 */ "database_kw_opt ::= DATABASE",
+ /* 366 */ "database_kw_opt ::=",
+ /* 367 */ "kwcolumn_opt ::=",
+ /* 368 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 369 */ "vtabarglist ::= vtabarg",
+ /* 370 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 371 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 372 */ "anylist ::=",
+ /* 373 */ "anylist ::= anylist LP anylist RP",
+ /* 374 */ "anylist ::= anylist ANY",
+ /* 375 */ "with ::=",
 };
 #endif /* NDEBUG */
 
@@ -147801,96 +150662,97 @@ static void yy_destructor(
     ** inside the C code.
     */
 /********* Begin destructor definitions ***************************************/
-    case 174: /* select */
-    case 206: /* selectnowith */
-    case 207: /* oneselect */
-    case 219: /* values */
+    case 195: /* select */
+    case 228: /* selectnowith */
+    case 229: /* oneselect */
+    case 241: /* values */
 {
-sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+sqlite3SelectDelete(pParse->db, (yypminor->yy391));
 }
       break;
-    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 */
+    case 206: /* term */
+    case 207: /* expr */
+    case 235: /* where_opt */
+    case 237: /* having_opt */
+    case 249: /* on_opt */
+    case 264: /* case_operand */
+    case 266: /* case_else */
+    case 269: /* vinto */
+    case 276: /* when_clause */
+    case 281: /* key_opt */
+    case 295: /* filter_opt */
 {
-sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+sqlite3ExprDelete(pParse->db, (yypminor->yy102));
 }
       break;
-    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 */
+    case 211: /* eidlist_opt */
+    case 220: /* sortlist */
+    case 221: /* eidlist */
+    case 233: /* selcollist */
+    case 236: /* groupby_opt */
+    case 238: /* orderby_opt */
+    case 242: /* nexprlist */
+    case 243: /* sclp */
+    case 251: /* exprlist */
+    case 255: /* setlist */
+    case 263: /* paren_exprlist */
+    case 265: /* case_exprlist */
+    case 294: /* part_opt */
 {
-sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy94));
 }
       break;
-    case 205: /* fullname */
-    case 212: /* from */
-    case 223: /* seltablist */
-    case 224: /* stl_prefix */
-    case 230: /* xfullname */
+    case 227: /* fullname */
+    case 234: /* from */
+    case 245: /* seltablist */
+    case 246: /* stl_prefix */
+    case 252: /* xfullname */
 {
-sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy407));
 }
       break;
-    case 208: /* wqlist */
+    case 230: /* wqlist */
 {
-sqlite3WithDelete(pParse->db, (yypminor->yy449));
+sqlite3WithDelete(pParse->db, (yypminor->yy243));
 }
       break;
-    case 218: /* window_clause */
-    case 267: /* windowdefn_list */
+    case 240: /* window_clause */
+    case 290: /* windowdefn_list */
 {
-sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy379));
 }
       break;
-    case 228: /* using_opt */
-    case 231: /* idlist */
-    case 235: /* idlist_opt */
+    case 250: /* using_opt */
+    case 253: /* idlist */
+    case 257: /* idlist_opt */
 {
-sqlite3IdListDelete(pParse->db, (yypminor->yy48));
+sqlite3IdListDelete(pParse->db, (yypminor->yy76));
 }
       break;
-    case 237: /* over_clause */
-    case 268: /* windowdefn */
-    case 269: /* window */
-    case 270: /* frame_opt */
+    case 259: /* over_clause */
+    case 291: /* windowdefn */
+    case 292: /* window */
+    case 293: /* frame_opt */
 {
-sqlite3WindowDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowDelete(pParse->db, (yypminor->yy379));
 }
       break;
-    case 249: /* trigger_cmd_list */
-    case 254: /* trigger_cmd */
+    case 272: /* trigger_cmd_list */
+    case 277: /* trigger_cmd */
 {
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy11));
 }
       break;
-    case 251: /* trigger_event */
+    case 274: /* trigger_event */
 {
-sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy298).b);
 }
       break;
-    case 274: /* frame_bound */
-    case 275: /* frame_bound_s */
-    case 276: /* frame_bound_e */
+    case 297: /* frame_bound */
+    case 298: /* frame_bound_s */
+    case 299: /* frame_bound_e */
 {
-sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy389).pExpr);
 }
       break;
 /********* End destructor definitions *****************************************/
@@ -148182,380 +151044,766 @@ static void yy_shift(
   yyTraceShift(yypParser, yyNewState, "Shift");
 }
 
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
-  YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
-  signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
-} yyRuleInfo[] = {
-  {  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 ::= */
+/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
+** of that rule */
+static const YYCODETYPE yyRuleInfoLhs[] = {
+   180,  /* (0) explain ::= EXPLAIN */
+   180,  /* (1) explain ::= EXPLAIN QUERY PLAN */
+   179,  /* (2) cmdx ::= cmd */
+   181,  /* (3) cmd ::= BEGIN transtype trans_opt */
+   182,  /* (4) transtype ::= */
+   182,  /* (5) transtype ::= DEFERRED */
+   182,  /* (6) transtype ::= IMMEDIATE */
+   182,  /* (7) transtype ::= EXCLUSIVE */
+   181,  /* (8) cmd ::= COMMIT|END trans_opt */
+   181,  /* (9) cmd ::= ROLLBACK trans_opt */
+   181,  /* (10) cmd ::= SAVEPOINT nm */
+   181,  /* (11) cmd ::= RELEASE savepoint_opt nm */
+   181,  /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+   186,  /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+   188,  /* (14) createkw ::= CREATE */
+   190,  /* (15) ifnotexists ::= */
+   190,  /* (16) ifnotexists ::= IF NOT EXISTS */
+   189,  /* (17) temp ::= TEMP */
+   189,  /* (18) temp ::= */
+   187,  /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+   187,  /* (20) create_table_args ::= AS select */
+   194,  /* (21) table_options ::= */
+   194,  /* (22) table_options ::= WITHOUT nm */
+   196,  /* (23) columnname ::= nm typetoken */
+   198,  /* (24) typetoken ::= */
+   198,  /* (25) typetoken ::= typename LP signed RP */
+   198,  /* (26) typetoken ::= typename LP signed COMMA signed RP */
+   199,  /* (27) typename ::= typename ID|STRING */
+   203,  /* (28) scanpt ::= */
+   204,  /* (29) scantok ::= */
+   205,  /* (30) ccons ::= CONSTRAINT nm */
+   205,  /* (31) ccons ::= DEFAULT scantok term */
+   205,  /* (32) ccons ::= DEFAULT LP expr RP */
+   205,  /* (33) ccons ::= DEFAULT PLUS scantok term */
+   205,  /* (34) ccons ::= DEFAULT MINUS scantok term */
+   205,  /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+   205,  /* (36) ccons ::= NOT NULL onconf */
+   205,  /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+   205,  /* (38) ccons ::= UNIQUE onconf */
+   205,  /* (39) ccons ::= CHECK LP expr RP */
+   205,  /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+   205,  /* (41) ccons ::= defer_subclause */
+   205,  /* (42) ccons ::= COLLATE ID|STRING */
+   210,  /* (43) autoinc ::= */
+   210,  /* (44) autoinc ::= AUTOINCR */
+   212,  /* (45) refargs ::= */
+   212,  /* (46) refargs ::= refargs refarg */
+   214,  /* (47) refarg ::= MATCH nm */
+   214,  /* (48) refarg ::= ON INSERT refact */
+   214,  /* (49) refarg ::= ON DELETE refact */
+   214,  /* (50) refarg ::= ON UPDATE refact */
+   215,  /* (51) refact ::= SET NULL */
+   215,  /* (52) refact ::= SET DEFAULT */
+   215,  /* (53) refact ::= CASCADE */
+   215,  /* (54) refact ::= RESTRICT */
+   215,  /* (55) refact ::= NO ACTION */
+   213,  /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+   213,  /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+   216,  /* (58) init_deferred_pred_opt ::= */
+   216,  /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+   216,  /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+   193,  /* (61) conslist_opt ::= */
+   218,  /* (62) tconscomma ::= COMMA */
+   219,  /* (63) tcons ::= CONSTRAINT nm */
+   219,  /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+   219,  /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+   219,  /* (66) tcons ::= CHECK LP expr RP onconf */
+   219,  /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+   222,  /* (68) defer_subclause_opt ::= */
+   208,  /* (69) onconf ::= */
+   208,  /* (70) onconf ::= ON CONFLICT resolvetype */
+   223,  /* (71) orconf ::= */
+   223,  /* (72) orconf ::= OR resolvetype */
+   224,  /* (73) resolvetype ::= IGNORE */
+   224,  /* (74) resolvetype ::= REPLACE */
+   181,  /* (75) cmd ::= DROP TABLE ifexists fullname */
+   226,  /* (76) ifexists ::= IF EXISTS */
+   226,  /* (77) ifexists ::= */
+   181,  /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+   181,  /* (79) cmd ::= DROP VIEW ifexists fullname */
+   181,  /* (80) cmd ::= select */
+   195,  /* (81) select ::= WITH wqlist selectnowith */
+   195,  /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+   195,  /* (83) select ::= selectnowith */
+   228,  /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+   231,  /* (85) multiselect_op ::= UNION */
+   231,  /* (86) multiselect_op ::= UNION ALL */
+   231,  /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+   229,  /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+   229,  /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+   241,  /* (90) values ::= VALUES LP nexprlist RP */
+   241,  /* (91) values ::= values COMMA LP nexprlist RP */
+   232,  /* (92) distinct ::= DISTINCT */
+   232,  /* (93) distinct ::= ALL */
+   232,  /* (94) distinct ::= */
+   243,  /* (95) sclp ::= */
+   233,  /* (96) selcollist ::= sclp scanpt expr scanpt as */
+   233,  /* (97) selcollist ::= sclp scanpt STAR */
+   233,  /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+   244,  /* (99) as ::= AS nm */
+   244,  /* (100) as ::= */
+   234,  /* (101) from ::= */
+   234,  /* (102) from ::= FROM seltablist */
+   246,  /* (103) stl_prefix ::= seltablist joinop */
+   246,  /* (104) stl_prefix ::= */
+   245,  /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+   245,  /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+   245,  /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+   245,  /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+   191,  /* (109) dbnm ::= */
+   191,  /* (110) dbnm ::= DOT nm */
+   227,  /* (111) fullname ::= nm */
+   227,  /* (112) fullname ::= nm DOT nm */
+   252,  /* (113) xfullname ::= nm */
+   252,  /* (114) xfullname ::= nm DOT nm */
+   252,  /* (115) xfullname ::= nm DOT nm AS nm */
+   252,  /* (116) xfullname ::= nm AS nm */
+   247,  /* (117) joinop ::= COMMA|JOIN */
+   247,  /* (118) joinop ::= JOIN_KW JOIN */
+   247,  /* (119) joinop ::= JOIN_KW nm JOIN */
+   247,  /* (120) joinop ::= JOIN_KW nm nm JOIN */
+   249,  /* (121) on_opt ::= ON expr */
+   249,  /* (122) on_opt ::= */
+   248,  /* (123) indexed_opt ::= */
+   248,  /* (124) indexed_opt ::= INDEXED BY nm */
+   248,  /* (125) indexed_opt ::= NOT INDEXED */
+   250,  /* (126) using_opt ::= USING LP idlist RP */
+   250,  /* (127) using_opt ::= */
+   238,  /* (128) orderby_opt ::= */
+   238,  /* (129) orderby_opt ::= ORDER BY sortlist */
+   220,  /* (130) sortlist ::= sortlist COMMA expr sortorder */
+   220,  /* (131) sortlist ::= expr sortorder */
+   209,  /* (132) sortorder ::= ASC */
+   209,  /* (133) sortorder ::= DESC */
+   209,  /* (134) sortorder ::= */
+   236,  /* (135) groupby_opt ::= */
+   236,  /* (136) groupby_opt ::= GROUP BY nexprlist */
+   237,  /* (137) having_opt ::= */
+   237,  /* (138) having_opt ::= HAVING expr */
+   239,  /* (139) limit_opt ::= */
+   239,  /* (140) limit_opt ::= LIMIT expr */
+   239,  /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+   239,  /* (142) limit_opt ::= LIMIT expr COMMA expr */
+   181,  /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+   235,  /* (144) where_opt ::= */
+   235,  /* (145) where_opt ::= WHERE expr */
+   181,  /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+   255,  /* (147) setlist ::= setlist COMMA nm EQ expr */
+   255,  /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+   255,  /* (149) setlist ::= nm EQ expr */
+   255,  /* (150) setlist ::= LP idlist RP EQ expr */
+   181,  /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+   181,  /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+   258,  /* (153) upsert ::= */
+   258,  /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+   258,  /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+   258,  /* (156) upsert ::= ON CONFLICT DO NOTHING */
+   256,  /* (157) insert_cmd ::= INSERT orconf */
+   256,  /* (158) insert_cmd ::= REPLACE */
+   257,  /* (159) idlist_opt ::= */
+   257,  /* (160) idlist_opt ::= LP idlist RP */
+   253,  /* (161) idlist ::= idlist COMMA nm */
+   253,  /* (162) idlist ::= nm */
+   207,  /* (163) expr ::= LP expr RP */
+   207,  /* (164) expr ::= ID|INDEXED */
+   207,  /* (165) expr ::= JOIN_KW */
+   207,  /* (166) expr ::= nm DOT nm */
+   207,  /* (167) expr ::= nm DOT nm DOT nm */
+   206,  /* (168) term ::= NULL|FLOAT|BLOB */
+   206,  /* (169) term ::= STRING */
+   206,  /* (170) term ::= INTEGER */
+   207,  /* (171) expr ::= VARIABLE */
+   207,  /* (172) expr ::= expr COLLATE ID|STRING */
+   207,  /* (173) expr ::= CAST LP expr AS typetoken RP */
+   207,  /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+   207,  /* (175) expr ::= ID|INDEXED LP STAR RP */
+   207,  /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+   207,  /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+   206,  /* (178) term ::= CTIME_KW */
+   207,  /* (179) expr ::= LP nexprlist COMMA expr RP */
+   207,  /* (180) expr ::= expr AND expr */
+   207,  /* (181) expr ::= expr OR expr */
+   207,  /* (182) expr ::= expr LT|GT|GE|LE expr */
+   207,  /* (183) expr ::= expr EQ|NE expr */
+   207,  /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+   207,  /* (185) expr ::= expr PLUS|MINUS expr */
+   207,  /* (186) expr ::= expr STAR|SLASH|REM expr */
+   207,  /* (187) expr ::= expr CONCAT expr */
+   260,  /* (188) likeop ::= NOT LIKE_KW|MATCH */
+   207,  /* (189) expr ::= expr likeop expr */
+   207,  /* (190) expr ::= expr likeop expr ESCAPE expr */
+   207,  /* (191) expr ::= expr ISNULL|NOTNULL */
+   207,  /* (192) expr ::= expr NOT NULL */
+   207,  /* (193) expr ::= expr IS expr */
+   207,  /* (194) expr ::= expr IS NOT expr */
+   207,  /* (195) expr ::= NOT expr */
+   207,  /* (196) expr ::= BITNOT expr */
+   207,  /* (197) expr ::= PLUS|MINUS expr */
+   261,  /* (198) between_op ::= BETWEEN */
+   261,  /* (199) between_op ::= NOT BETWEEN */
+   207,  /* (200) expr ::= expr between_op expr AND expr */
+   262,  /* (201) in_op ::= IN */
+   262,  /* (202) in_op ::= NOT IN */
+   207,  /* (203) expr ::= expr in_op LP exprlist RP */
+   207,  /* (204) expr ::= LP select RP */
+   207,  /* (205) expr ::= expr in_op LP select RP */
+   207,  /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+   207,  /* (207) expr ::= EXISTS LP select RP */
+   207,  /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+   265,  /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+   265,  /* (210) case_exprlist ::= WHEN expr THEN expr */
+   266,  /* (211) case_else ::= ELSE expr */
+   266,  /* (212) case_else ::= */
+   264,  /* (213) case_operand ::= expr */
+   264,  /* (214) case_operand ::= */
+   251,  /* (215) exprlist ::= */
+   242,  /* (216) nexprlist ::= nexprlist COMMA expr */
+   242,  /* (217) nexprlist ::= expr */
+   263,  /* (218) paren_exprlist ::= */
+   263,  /* (219) paren_exprlist ::= LP exprlist RP */
+   181,  /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+   267,  /* (221) uniqueflag ::= UNIQUE */
+   267,  /* (222) uniqueflag ::= */
+   211,  /* (223) eidlist_opt ::= */
+   211,  /* (224) eidlist_opt ::= LP eidlist RP */
+   221,  /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+   221,  /* (226) eidlist ::= nm collate sortorder */
+   268,  /* (227) collate ::= */
+   268,  /* (228) collate ::= COLLATE ID|STRING */
+   181,  /* (229) cmd ::= DROP INDEX ifexists fullname */
+   181,  /* (230) cmd ::= VACUUM vinto */
+   181,  /* (231) cmd ::= VACUUM nm vinto */
+   269,  /* (232) vinto ::= INTO expr */
+   269,  /* (233) vinto ::= */
+   181,  /* (234) cmd ::= PRAGMA nm dbnm */
+   181,  /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+   181,  /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+   181,  /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+   181,  /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+   201,  /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+   202,  /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+   181,  /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+   271,  /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+   273,  /* (243) trigger_time ::= BEFORE|AFTER */
+   273,  /* (244) trigger_time ::= INSTEAD OF */
+   273,  /* (245) trigger_time ::= */
+   274,  /* (246) trigger_event ::= DELETE|INSERT */
+   274,  /* (247) trigger_event ::= UPDATE */
+   274,  /* (248) trigger_event ::= UPDATE OF idlist */
+   276,  /* (249) when_clause ::= */
+   276,  /* (250) when_clause ::= WHEN expr */
+   272,  /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+   272,  /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+   278,  /* (253) trnm ::= nm DOT nm */
+   279,  /* (254) tridxby ::= INDEXED BY nm */
+   279,  /* (255) tridxby ::= NOT INDEXED */
+   277,  /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+   277,  /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+   277,  /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+   277,  /* (259) trigger_cmd ::= scanpt select scanpt */
+   207,  /* (260) expr ::= RAISE LP IGNORE RP */
+   207,  /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+   225,  /* (262) raisetype ::= ROLLBACK */
+   225,  /* (263) raisetype ::= ABORT */
+   225,  /* (264) raisetype ::= FAIL */
+   181,  /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+   181,  /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+   181,  /* (267) cmd ::= DETACH database_kw_opt expr */
+   281,  /* (268) key_opt ::= */
+   281,  /* (269) key_opt ::= KEY expr */
+   181,  /* (270) cmd ::= REINDEX */
+   181,  /* (271) cmd ::= REINDEX nm dbnm */
+   181,  /* (272) cmd ::= ANALYZE */
+   181,  /* (273) cmd ::= ANALYZE nm dbnm */
+   181,  /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+   181,  /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+   282,  /* (276) add_column_fullname ::= fullname */
+   181,  /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+   181,  /* (278) cmd ::= create_vtab */
+   181,  /* (279) cmd ::= create_vtab LP vtabarglist RP */
+   284,  /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+   286,  /* (281) vtabarg ::= */
+   287,  /* (282) vtabargtoken ::= ANY */
+   287,  /* (283) vtabargtoken ::= lp anylist RP */
+   288,  /* (284) lp ::= LP */
+   254,  /* (285) with ::= WITH wqlist */
+   254,  /* (286) with ::= WITH RECURSIVE wqlist */
+   230,  /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+   230,  /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+   290,  /* (289) windowdefn_list ::= windowdefn */
+   290,  /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+   291,  /* (291) windowdefn ::= nm AS LP window RP */
+   292,  /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+   292,  /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+   292,  /* (294) window ::= ORDER BY sortlist frame_opt */
+   292,  /* (295) window ::= nm ORDER BY sortlist frame_opt */
+   292,  /* (296) window ::= frame_opt */
+   292,  /* (297) window ::= nm frame_opt */
+   293,  /* (298) frame_opt ::= */
+   293,  /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+   293,  /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+   296,  /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+   298,  /* (302) frame_bound_s ::= frame_bound */
+   298,  /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+   299,  /* (304) frame_bound_e ::= frame_bound */
+   299,  /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+   297,  /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+   297,  /* (307) frame_bound ::= CURRENT ROW */
+   300,  /* (308) frame_exclude_opt ::= */
+   300,  /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+   301,  /* (310) frame_exclude ::= NO OTHERS */
+   301,  /* (311) frame_exclude ::= CURRENT ROW */
+   301,  /* (312) frame_exclude ::= GROUP|TIES */
+   240,  /* (313) window_clause ::= WINDOW windowdefn_list */
+   259,  /* (314) over_clause ::= filter_opt OVER LP window RP */
+   259,  /* (315) over_clause ::= filter_opt OVER nm */
+   295,  /* (316) filter_opt ::= */
+   295,  /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+   176,  /* (318) input ::= cmdlist */
+   177,  /* (319) cmdlist ::= cmdlist ecmd */
+   177,  /* (320) cmdlist ::= ecmd */
+   178,  /* (321) ecmd ::= SEMI */
+   178,  /* (322) ecmd ::= cmdx SEMI */
+   178,  /* (323) ecmd ::= explain cmdx */
+   183,  /* (324) trans_opt ::= */
+   183,  /* (325) trans_opt ::= TRANSACTION */
+   183,  /* (326) trans_opt ::= TRANSACTION nm */
+   185,  /* (327) savepoint_opt ::= SAVEPOINT */
+   185,  /* (328) savepoint_opt ::= */
+   181,  /* (329) cmd ::= create_table create_table_args */
+   192,  /* (330) columnlist ::= columnlist COMMA columnname carglist */
+   192,  /* (331) columnlist ::= columnname carglist */
+   184,  /* (332) nm ::= ID|INDEXED */
+   184,  /* (333) nm ::= STRING */
+   184,  /* (334) nm ::= JOIN_KW */
+   198,  /* (335) typetoken ::= typename */
+   199,  /* (336) typename ::= ID|STRING */
+   200,  /* (337) signed ::= plus_num */
+   200,  /* (338) signed ::= minus_num */
+   197,  /* (339) carglist ::= carglist ccons */
+   197,  /* (340) carglist ::= */
+   205,  /* (341) ccons ::= NULL onconf */
+   193,  /* (342) conslist_opt ::= COMMA conslist */
+   217,  /* (343) conslist ::= conslist tconscomma tcons */
+   217,  /* (344) conslist ::= tcons */
+   218,  /* (345) tconscomma ::= */
+   222,  /* (346) defer_subclause_opt ::= defer_subclause */
+   224,  /* (347) resolvetype ::= raisetype */
+   228,  /* (348) selectnowith ::= oneselect */
+   229,  /* (349) oneselect ::= values */
+   243,  /* (350) sclp ::= selcollist COMMA */
+   244,  /* (351) as ::= ID|STRING */
+   207,  /* (352) expr ::= term */
+   260,  /* (353) likeop ::= LIKE_KW|MATCH */
+   251,  /* (354) exprlist ::= nexprlist */
+   270,  /* (355) nmnum ::= plus_num */
+   270,  /* (356) nmnum ::= nm */
+   270,  /* (357) nmnum ::= ON */
+   270,  /* (358) nmnum ::= DELETE */
+   270,  /* (359) nmnum ::= DEFAULT */
+   201,  /* (360) plus_num ::= INTEGER|FLOAT */
+   275,  /* (361) foreach_clause ::= */
+   275,  /* (362) foreach_clause ::= FOR EACH ROW */
+   278,  /* (363) trnm ::= nm */
+   279,  /* (364) tridxby ::= */
+   280,  /* (365) database_kw_opt ::= DATABASE */
+   280,  /* (366) database_kw_opt ::= */
+   283,  /* (367) kwcolumn_opt ::= */
+   283,  /* (368) kwcolumn_opt ::= COLUMNKW */
+   285,  /* (369) vtabarglist ::= vtabarg */
+   285,  /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+   286,  /* (371) vtabarg ::= vtabarg vtabargtoken */
+   289,  /* (372) anylist ::= */
+   289,  /* (373) anylist ::= anylist LP anylist RP */
+   289,  /* (374) anylist ::= anylist ANY */
+   254,  /* (375) with ::= */
+};
+
+/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
+** of symbols on the right-hand side of that rule. */
+static const signed char yyRuleInfoNRhs[] = {
+   -1,  /* (0) explain ::= EXPLAIN */
+   -3,  /* (1) explain ::= EXPLAIN QUERY PLAN */
+   -1,  /* (2) cmdx ::= cmd */
+   -3,  /* (3) cmd ::= BEGIN transtype trans_opt */
+    0,  /* (4) transtype ::= */
+   -1,  /* (5) transtype ::= DEFERRED */
+   -1,  /* (6) transtype ::= IMMEDIATE */
+   -1,  /* (7) transtype ::= EXCLUSIVE */
+   -2,  /* (8) cmd ::= COMMIT|END trans_opt */
+   -2,  /* (9) cmd ::= ROLLBACK trans_opt */
+   -2,  /* (10) cmd ::= SAVEPOINT nm */
+   -3,  /* (11) cmd ::= RELEASE savepoint_opt nm */
+   -5,  /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+   -6,  /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+   -1,  /* (14) createkw ::= CREATE */
+    0,  /* (15) ifnotexists ::= */
+   -3,  /* (16) ifnotexists ::= IF NOT EXISTS */
+   -1,  /* (17) temp ::= TEMP */
+    0,  /* (18) temp ::= */
+   -5,  /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+   -2,  /* (20) create_table_args ::= AS select */
+    0,  /* (21) table_options ::= */
+   -2,  /* (22) table_options ::= WITHOUT nm */
+   -2,  /* (23) columnname ::= nm typetoken */
+    0,  /* (24) typetoken ::= */
+   -4,  /* (25) typetoken ::= typename LP signed RP */
+   -6,  /* (26) typetoken ::= typename LP signed COMMA signed RP */
+   -2,  /* (27) typename ::= typename ID|STRING */
+    0,  /* (28) scanpt ::= */
+    0,  /* (29) scantok ::= */
+   -2,  /* (30) ccons ::= CONSTRAINT nm */
+   -3,  /* (31) ccons ::= DEFAULT scantok term */
+   -4,  /* (32) ccons ::= DEFAULT LP expr RP */
+   -4,  /* (33) ccons ::= DEFAULT PLUS scantok term */
+   -4,  /* (34) ccons ::= DEFAULT MINUS scantok term */
+   -3,  /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+   -3,  /* (36) ccons ::= NOT NULL onconf */
+   -5,  /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+   -2,  /* (38) ccons ::= UNIQUE onconf */
+   -4,  /* (39) ccons ::= CHECK LP expr RP */
+   -4,  /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+   -1,  /* (41) ccons ::= defer_subclause */
+   -2,  /* (42) ccons ::= COLLATE ID|STRING */
+    0,  /* (43) autoinc ::= */
+   -1,  /* (44) autoinc ::= AUTOINCR */
+    0,  /* (45) refargs ::= */
+   -2,  /* (46) refargs ::= refargs refarg */
+   -2,  /* (47) refarg ::= MATCH nm */
+   -3,  /* (48) refarg ::= ON INSERT refact */
+   -3,  /* (49) refarg ::= ON DELETE refact */
+   -3,  /* (50) refarg ::= ON UPDATE refact */
+   -2,  /* (51) refact ::= SET NULL */
+   -2,  /* (52) refact ::= SET DEFAULT */
+   -1,  /* (53) refact ::= CASCADE */
+   -1,  /* (54) refact ::= RESTRICT */
+   -2,  /* (55) refact ::= NO ACTION */
+   -3,  /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+   -2,  /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+    0,  /* (58) init_deferred_pred_opt ::= */
+   -2,  /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+   -2,  /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+    0,  /* (61) conslist_opt ::= */
+   -1,  /* (62) tconscomma ::= COMMA */
+   -2,  /* (63) tcons ::= CONSTRAINT nm */
+   -7,  /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+   -5,  /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+   -5,  /* (66) tcons ::= CHECK LP expr RP onconf */
+  -10,  /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+    0,  /* (68) defer_subclause_opt ::= */
+    0,  /* (69) onconf ::= */
+   -3,  /* (70) onconf ::= ON CONFLICT resolvetype */
+    0,  /* (71) orconf ::= */
+   -2,  /* (72) orconf ::= OR resolvetype */
+   -1,  /* (73) resolvetype ::= IGNORE */
+   -1,  /* (74) resolvetype ::= REPLACE */
+   -4,  /* (75) cmd ::= DROP TABLE ifexists fullname */
+   -2,  /* (76) ifexists ::= IF EXISTS */
+    0,  /* (77) ifexists ::= */
+   -9,  /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+   -4,  /* (79) cmd ::= DROP VIEW ifexists fullname */
+   -1,  /* (80) cmd ::= select */
+   -3,  /* (81) select ::= WITH wqlist selectnowith */
+   -4,  /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+   -1,  /* (83) select ::= selectnowith */
+   -3,  /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+   -1,  /* (85) multiselect_op ::= UNION */
+   -2,  /* (86) multiselect_op ::= UNION ALL */
+   -1,  /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+   -9,  /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+  -10,  /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+   -4,  /* (90) values ::= VALUES LP nexprlist RP */
+   -5,  /* (91) values ::= values COMMA LP nexprlist RP */
+   -1,  /* (92) distinct ::= DISTINCT */
+   -1,  /* (93) distinct ::= ALL */
+    0,  /* (94) distinct ::= */
+    0,  /* (95) sclp ::= */
+   -5,  /* (96) selcollist ::= sclp scanpt expr scanpt as */
+   -3,  /* (97) selcollist ::= sclp scanpt STAR */
+   -5,  /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+   -2,  /* (99) as ::= AS nm */
+    0,  /* (100) as ::= */
+    0,  /* (101) from ::= */
+   -2,  /* (102) from ::= FROM seltablist */
+   -2,  /* (103) stl_prefix ::= seltablist joinop */
+    0,  /* (104) stl_prefix ::= */
+   -7,  /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+   -9,  /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+   -7,  /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+   -7,  /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+    0,  /* (109) dbnm ::= */
+   -2,  /* (110) dbnm ::= DOT nm */
+   -1,  /* (111) fullname ::= nm */
+   -3,  /* (112) fullname ::= nm DOT nm */
+   -1,  /* (113) xfullname ::= nm */
+   -3,  /* (114) xfullname ::= nm DOT nm */
+   -5,  /* (115) xfullname ::= nm DOT nm AS nm */
+   -3,  /* (116) xfullname ::= nm AS nm */
+   -1,  /* (117) joinop ::= COMMA|JOIN */
+   -2,  /* (118) joinop ::= JOIN_KW JOIN */
+   -3,  /* (119) joinop ::= JOIN_KW nm JOIN */
+   -4,  /* (120) joinop ::= JOIN_KW nm nm JOIN */
+   -2,  /* (121) on_opt ::= ON expr */
+    0,  /* (122) on_opt ::= */
+    0,  /* (123) indexed_opt ::= */
+   -3,  /* (124) indexed_opt ::= INDEXED BY nm */
+   -2,  /* (125) indexed_opt ::= NOT INDEXED */
+   -4,  /* (126) using_opt ::= USING LP idlist RP */
+    0,  /* (127) using_opt ::= */
+    0,  /* (128) orderby_opt ::= */
+   -3,  /* (129) orderby_opt ::= ORDER BY sortlist */
+   -4,  /* (130) sortlist ::= sortlist COMMA expr sortorder */
+   -2,  /* (131) sortlist ::= expr sortorder */
+   -1,  /* (132) sortorder ::= ASC */
+   -1,  /* (133) sortorder ::= DESC */
+    0,  /* (134) sortorder ::= */
+    0,  /* (135) groupby_opt ::= */
+   -3,  /* (136) groupby_opt ::= GROUP BY nexprlist */
+    0,  /* (137) having_opt ::= */
+   -2,  /* (138) having_opt ::= HAVING expr */
+    0,  /* (139) limit_opt ::= */
+   -2,  /* (140) limit_opt ::= LIMIT expr */
+   -4,  /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+   -4,  /* (142) limit_opt ::= LIMIT expr COMMA expr */
+   -6,  /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+    0,  /* (144) where_opt ::= */
+   -2,  /* (145) where_opt ::= WHERE expr */
+   -8,  /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+   -5,  /* (147) setlist ::= setlist COMMA nm EQ expr */
+   -7,  /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+   -3,  /* (149) setlist ::= nm EQ expr */
+   -5,  /* (150) setlist ::= LP idlist RP EQ expr */
+   -7,  /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+   -7,  /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+    0,  /* (153) upsert ::= */
+  -11,  /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+   -8,  /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+   -4,  /* (156) upsert ::= ON CONFLICT DO NOTHING */
+   -2,  /* (157) insert_cmd ::= INSERT orconf */
+   -1,  /* (158) insert_cmd ::= REPLACE */
+    0,  /* (159) idlist_opt ::= */
+   -3,  /* (160) idlist_opt ::= LP idlist RP */
+   -3,  /* (161) idlist ::= idlist COMMA nm */
+   -1,  /* (162) idlist ::= nm */
+   -3,  /* (163) expr ::= LP expr RP */
+   -1,  /* (164) expr ::= ID|INDEXED */
+   -1,  /* (165) expr ::= JOIN_KW */
+   -3,  /* (166) expr ::= nm DOT nm */
+   -5,  /* (167) expr ::= nm DOT nm DOT nm */
+   -1,  /* (168) term ::= NULL|FLOAT|BLOB */
+   -1,  /* (169) term ::= STRING */
+   -1,  /* (170) term ::= INTEGER */
+   -1,  /* (171) expr ::= VARIABLE */
+   -3,  /* (172) expr ::= expr COLLATE ID|STRING */
+   -6,  /* (173) expr ::= CAST LP expr AS typetoken RP */
+   -5,  /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+   -4,  /* (175) expr ::= ID|INDEXED LP STAR RP */
+   -6,  /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+   -5,  /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+   -1,  /* (178) term ::= CTIME_KW */
+   -5,  /* (179) expr ::= LP nexprlist COMMA expr RP */
+   -3,  /* (180) expr ::= expr AND expr */
+   -3,  /* (181) expr ::= expr OR expr */
+   -3,  /* (182) expr ::= expr LT|GT|GE|LE expr */
+   -3,  /* (183) expr ::= expr EQ|NE expr */
+   -3,  /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+   -3,  /* (185) expr ::= expr PLUS|MINUS expr */
+   -3,  /* (186) expr ::= expr STAR|SLASH|REM expr */
+   -3,  /* (187) expr ::= expr CONCAT expr */
+   -2,  /* (188) likeop ::= NOT LIKE_KW|MATCH */
+   -3,  /* (189) expr ::= expr likeop expr */
+   -5,  /* (190) expr ::= expr likeop expr ESCAPE expr */
+   -2,  /* (191) expr ::= expr ISNULL|NOTNULL */
+   -3,  /* (192) expr ::= expr NOT NULL */
+   -3,  /* (193) expr ::= expr IS expr */
+   -4,  /* (194) expr ::= expr IS NOT expr */
+   -2,  /* (195) expr ::= NOT expr */
+   -2,  /* (196) expr ::= BITNOT expr */
+   -2,  /* (197) expr ::= PLUS|MINUS expr */
+   -1,  /* (198) between_op ::= BETWEEN */
+   -2,  /* (199) between_op ::= NOT BETWEEN */
+   -5,  /* (200) expr ::= expr between_op expr AND expr */
+   -1,  /* (201) in_op ::= IN */
+   -2,  /* (202) in_op ::= NOT IN */
+   -5,  /* (203) expr ::= expr in_op LP exprlist RP */
+   -3,  /* (204) expr ::= LP select RP */
+   -5,  /* (205) expr ::= expr in_op LP select RP */
+   -5,  /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+   -4,  /* (207) expr ::= EXISTS LP select RP */
+   -5,  /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+   -5,  /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+   -4,  /* (210) case_exprlist ::= WHEN expr THEN expr */
+   -2,  /* (211) case_else ::= ELSE expr */
+    0,  /* (212) case_else ::= */
+   -1,  /* (213) case_operand ::= expr */
+    0,  /* (214) case_operand ::= */
+    0,  /* (215) exprlist ::= */
+   -3,  /* (216) nexprlist ::= nexprlist COMMA expr */
+   -1,  /* (217) nexprlist ::= expr */
+    0,  /* (218) paren_exprlist ::= */
+   -3,  /* (219) paren_exprlist ::= LP exprlist RP */
+  -12,  /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+   -1,  /* (221) uniqueflag ::= UNIQUE */
+    0,  /* (222) uniqueflag ::= */
+    0,  /* (223) eidlist_opt ::= */
+   -3,  /* (224) eidlist_opt ::= LP eidlist RP */
+   -5,  /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+   -3,  /* (226) eidlist ::= nm collate sortorder */
+    0,  /* (227) collate ::= */
+   -2,  /* (228) collate ::= COLLATE ID|STRING */
+   -4,  /* (229) cmd ::= DROP INDEX ifexists fullname */
+   -2,  /* (230) cmd ::= VACUUM vinto */
+   -3,  /* (231) cmd ::= VACUUM nm vinto */
+   -2,  /* (232) vinto ::= INTO expr */
+    0,  /* (233) vinto ::= */
+   -3,  /* (234) cmd ::= PRAGMA nm dbnm */
+   -5,  /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+   -6,  /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+   -5,  /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+   -6,  /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+   -2,  /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+   -2,  /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+   -5,  /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+  -11,  /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+   -1,  /* (243) trigger_time ::= BEFORE|AFTER */
+   -2,  /* (244) trigger_time ::= INSTEAD OF */
+    0,  /* (245) trigger_time ::= */
+   -1,  /* (246) trigger_event ::= DELETE|INSERT */
+   -1,  /* (247) trigger_event ::= UPDATE */
+   -3,  /* (248) trigger_event ::= UPDATE OF idlist */
+    0,  /* (249) when_clause ::= */
+   -2,  /* (250) when_clause ::= WHEN expr */
+   -3,  /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+   -2,  /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+   -3,  /* (253) trnm ::= nm DOT nm */
+   -3,  /* (254) tridxby ::= INDEXED BY nm */
+   -2,  /* (255) tridxby ::= NOT INDEXED */
+   -8,  /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+   -8,  /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+   -6,  /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+   -3,  /* (259) trigger_cmd ::= scanpt select scanpt */
+   -4,  /* (260) expr ::= RAISE LP IGNORE RP */
+   -6,  /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+   -1,  /* (262) raisetype ::= ROLLBACK */
+   -1,  /* (263) raisetype ::= ABORT */
+   -1,  /* (264) raisetype ::= FAIL */
+   -4,  /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+   -6,  /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+   -3,  /* (267) cmd ::= DETACH database_kw_opt expr */
+    0,  /* (268) key_opt ::= */
+   -2,  /* (269) key_opt ::= KEY expr */
+   -1,  /* (270) cmd ::= REINDEX */
+   -3,  /* (271) cmd ::= REINDEX nm dbnm */
+   -1,  /* (272) cmd ::= ANALYZE */
+   -3,  /* (273) cmd ::= ANALYZE nm dbnm */
+   -6,  /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+   -7,  /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+   -1,  /* (276) add_column_fullname ::= fullname */
+   -8,  /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+   -1,  /* (278) cmd ::= create_vtab */
+   -4,  /* (279) cmd ::= create_vtab LP vtabarglist RP */
+   -8,  /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+    0,  /* (281) vtabarg ::= */
+   -1,  /* (282) vtabargtoken ::= ANY */
+   -3,  /* (283) vtabargtoken ::= lp anylist RP */
+   -1,  /* (284) lp ::= LP */
+   -2,  /* (285) with ::= WITH wqlist */
+   -3,  /* (286) with ::= WITH RECURSIVE wqlist */
+   -6,  /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+   -8,  /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+   -1,  /* (289) windowdefn_list ::= windowdefn */
+   -3,  /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+   -5,  /* (291) windowdefn ::= nm AS LP window RP */
+   -5,  /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+   -6,  /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+   -4,  /* (294) window ::= ORDER BY sortlist frame_opt */
+   -5,  /* (295) window ::= nm ORDER BY sortlist frame_opt */
+   -1,  /* (296) window ::= frame_opt */
+   -2,  /* (297) window ::= nm frame_opt */
+    0,  /* (298) frame_opt ::= */
+   -3,  /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+   -6,  /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+   -1,  /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+   -1,  /* (302) frame_bound_s ::= frame_bound */
+   -2,  /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+   -1,  /* (304) frame_bound_e ::= frame_bound */
+   -2,  /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+   -2,  /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+   -2,  /* (307) frame_bound ::= CURRENT ROW */
+    0,  /* (308) frame_exclude_opt ::= */
+   -2,  /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+   -2,  /* (310) frame_exclude ::= NO OTHERS */
+   -2,  /* (311) frame_exclude ::= CURRENT ROW */
+   -1,  /* (312) frame_exclude ::= GROUP|TIES */
+   -2,  /* (313) window_clause ::= WINDOW windowdefn_list */
+   -5,  /* (314) over_clause ::= filter_opt OVER LP window RP */
+   -3,  /* (315) over_clause ::= filter_opt OVER nm */
+    0,  /* (316) filter_opt ::= */
+   -5,  /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+   -1,  /* (318) input ::= cmdlist */
+   -2,  /* (319) cmdlist ::= cmdlist ecmd */
+   -1,  /* (320) cmdlist ::= ecmd */
+   -1,  /* (321) ecmd ::= SEMI */
+   -2,  /* (322) ecmd ::= cmdx SEMI */
+   -2,  /* (323) ecmd ::= explain cmdx */
+    0,  /* (324) trans_opt ::= */
+   -1,  /* (325) trans_opt ::= TRANSACTION */
+   -2,  /* (326) trans_opt ::= TRANSACTION nm */
+   -1,  /* (327) savepoint_opt ::= SAVEPOINT */
+    0,  /* (328) savepoint_opt ::= */
+   -2,  /* (329) cmd ::= create_table create_table_args */
+   -4,  /* (330) columnlist ::= columnlist COMMA columnname carglist */
+   -2,  /* (331) columnlist ::= columnname carglist */
+   -1,  /* (332) nm ::= ID|INDEXED */
+   -1,  /* (333) nm ::= STRING */
+   -1,  /* (334) nm ::= JOIN_KW */
+   -1,  /* (335) typetoken ::= typename */
+   -1,  /* (336) typename ::= ID|STRING */
+   -1,  /* (337) signed ::= plus_num */
+   -1,  /* (338) signed ::= minus_num */
+   -2,  /* (339) carglist ::= carglist ccons */
+    0,  /* (340) carglist ::= */
+   -2,  /* (341) ccons ::= NULL onconf */
+   -2,  /* (342) conslist_opt ::= COMMA conslist */
+   -3,  /* (343) conslist ::= conslist tconscomma tcons */
+   -1,  /* (344) conslist ::= tcons */
+    0,  /* (345) tconscomma ::= */
+   -1,  /* (346) defer_subclause_opt ::= defer_subclause */
+   -1,  /* (347) resolvetype ::= raisetype */
+   -1,  /* (348) selectnowith ::= oneselect */
+   -1,  /* (349) oneselect ::= values */
+   -2,  /* (350) sclp ::= selcollist COMMA */
+   -1,  /* (351) as ::= ID|STRING */
+   -1,  /* (352) expr ::= term */
+   -1,  /* (353) likeop ::= LIKE_KW|MATCH */
+   -1,  /* (354) exprlist ::= nexprlist */
+   -1,  /* (355) nmnum ::= plus_num */
+   -1,  /* (356) nmnum ::= nm */
+   -1,  /* (357) nmnum ::= ON */
+   -1,  /* (358) nmnum ::= DELETE */
+   -1,  /* (359) nmnum ::= DEFAULT */
+   -1,  /* (360) plus_num ::= INTEGER|FLOAT */
+    0,  /* (361) foreach_clause ::= */
+   -3,  /* (362) foreach_clause ::= FOR EACH ROW */
+   -1,  /* (363) trnm ::= nm */
+    0,  /* (364) tridxby ::= */
+   -1,  /* (365) database_kw_opt ::= DATABASE */
+    0,  /* (366) database_kw_opt ::= */
+    0,  /* (367) kwcolumn_opt ::= */
+   -1,  /* (368) kwcolumn_opt ::= COLUMNKW */
+   -1,  /* (369) vtabarglist ::= vtabarg */
+   -3,  /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+   -2,  /* (371) vtabarg ::= vtabarg vtabargtoken */
+    0,  /* (372) anylist ::= */
+   -4,  /* (373) anylist ::= anylist LP anylist RP */
+   -2,  /* (374) anylist ::= anylist ANY */
+    0,  /* (375) with ::= */
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -148587,7 +151835,7 @@ static YYACTIONTYPE yy_reduce(
   yymsp = yypParser->yytos;
 #ifndef NDEBUG
   if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
-    yysize = yyRuleInfo[yyruleno].nrhs;
+    yysize = yyRuleInfoNRhs[yyruleno];
     if( yysize ){
       fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
         yyTracePrompt,
@@ -148602,7 +151850,7 @@ static YYACTIONTYPE yy_reduce(
   /* Check that the stack is large enough to grow by a single entry
   ** if the RHS of the rule is empty.  This ensures that there is room
   ** enough on the stack to push the LHS value */
-  if( yyRuleInfo[yyruleno].nrhs==0 ){
+  if( yyRuleInfoNRhs[yyruleno]==0 ){
 #ifdef YYTRACKMAXSTACKDEPTH
     if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
       yypParser->yyhwm++;
@@ -148652,15 +151900,16 @@ static YYACTIONTYPE yy_reduce(
 { sqlite3FinishCoding(pParse); }
         break;
       case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy100);}
         break;
       case 4: /* transtype ::= */
-{yymsp[1].minor.yy70 = TK_DEFERRED;}
+{yymsp[1].minor.yy100 = TK_DEFERRED;}
         break;
       case 5: /* transtype ::= DEFERRED */
       case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
       case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
+      case 301: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==301);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/}
         break;
       case 8: /* cmd ::= COMMIT|END trans_opt */
       case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -148683,7 +151932,7 @@ static YYACTIONTYPE yy_reduce(
         break;
       case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy100,0,0,yymsp[-2].minor.yy100);
 }
         break;
       case 14: /* createkw ::= CREATE */
@@ -148692,38 +151941,38 @@ static YYACTIONTYPE yy_reduce(
       case 15: /* ifnotexists ::= */
       case 18: /* temp ::= */ yytestcase(yyruleno==18);
       case 21: /* table_options ::= */ yytestcase(yyruleno==21);
-      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;}
+      case 43: /* autoinc ::= */ yytestcase(yyruleno==43);
+      case 58: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==58);
+      case 68: /* defer_subclause_opt ::= */ yytestcase(yyruleno==68);
+      case 77: /* ifexists ::= */ yytestcase(yyruleno==77);
+      case 94: /* distinct ::= */ yytestcase(yyruleno==94);
+      case 227: /* collate ::= */ yytestcase(yyruleno==227);
+{yymsp[1].minor.yy100 = 0;}
         break;
       case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy70 = 1;}
+{yymsp[-2].minor.yy100 = 1;}
         break;
       case 17: /* temp ::= TEMP */
-      case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
-{yymsp[0].minor.yy70 = 1;}
+      case 44: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==44);
+{yymsp[0].minor.yy100 = 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.yy70,0);
+  sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy100,0);
 }
         break;
       case 20: /* create_table_args ::= AS select */
 {
-  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy391);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
 }
         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.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
+    yymsp[-1].minor.yy100 = TF_WithoutRowid | TF_NoVisibleRowid;
   }else{
-    yymsp[-1].minor.yy70 = 0;
+    yymsp[-1].minor.yy100 = 0;
     sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
   }
 }
@@ -148732,8 +151981,8 @@ static YYACTIONTYPE yy_reduce(
 {sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
         break;
       case 24: /* typetoken ::= */
-      case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
-      case 99: /* as ::= */ yytestcase(yyruleno==99);
+      case 61: /* conslist_opt ::= */ yytestcase(yyruleno==61);
+      case 100: /* as ::= */ yytestcase(yyruleno==100);
 {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
         break;
       case 25: /* typetoken ::= typename LP signed RP */
@@ -148752,29 +152001,35 @@ static YYACTIONTYPE yy_reduce(
       case 28: /* scanpt ::= */
 {
   assert( yyLookahead!=YYNOCODE );
-  yymsp[1].minor.yy392 = yyLookaheadToken.z;
+  yymsp[1].minor.yy528 = yyLookaheadToken.z;
 }
         break;
-      case 29: /* ccons ::= CONSTRAINT nm */
-      case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
+      case 29: /* scantok ::= */
+{
+  assert( yyLookahead!=YYNOCODE );
+  yymsp[1].minor.yy0 = yyLookaheadToken;
+}
+        break;
+      case 30: /* ccons ::= CONSTRAINT nm */
+      case 63: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==63);
 {pParse->constraintName = yymsp[0].minor.yy0;}
         break;
-      case 30: /* ccons ::= DEFAULT scanpt term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+      case 31: /* ccons ::= DEFAULT scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
         break;
-      case 31: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+      case 32: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy102,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
         break;
-      case 32: /* ccons ::= DEFAULT PLUS term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
+      case 33: /* ccons ::= DEFAULT PLUS scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
         break;
-      case 33: /* ccons ::= DEFAULT MINUS term scanpt */
+      case 34: /* ccons ::= DEFAULT MINUS scantok term */
 {
-  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
-  sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
+  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy102, 0);
+  sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
 }
         break;
-      case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
+      case 35: /* ccons ::= DEFAULT scantok ID|INDEXED */
 {
   Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
   if( p ){
@@ -148784,171 +152039,171 @@ static YYACTIONTYPE yy_reduce(
     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.yy70);}
+      case 36: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy100);}
         break;
-      case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
+      case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy100,yymsp[0].minor.yy100,yymsp[-2].minor.yy100);}
         break;
-      case 37: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
+      case 38: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy100,0,0,0,0,
                                    SQLITE_IDXTYPE_UNIQUE);}
         break;
-      case 38: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
+      case 39: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy102);}
         break;
-      case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
+      case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy94,yymsp[0].minor.yy100);}
         break;
-      case 40: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
+      case 41: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy100);}
         break;
-      case 41: /* ccons ::= COLLATE ID|STRING */
+      case 42: /* ccons ::= COLLATE ID|STRING */
 {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
         break;
-      case 44: /* refargs ::= */
-{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
+      case 45: /* refargs ::= */
+{ yymsp[1].minor.yy100 = OE_None*0x0101; /* EV: R-19803-45884 */}
         break;
-      case 45: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
+      case 46: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy100 = (yymsp[-1].minor.yy100 & ~yymsp[0].minor.yy199.mask) | yymsp[0].minor.yy199.value; }
         break;
-      case 46: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy111.value = 0;     yymsp[-1].minor.yy111.mask = 0x000000; }
+      case 47: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy199.value = 0;     yymsp[-1].minor.yy199.mask = 0x000000; }
         break;
-      case 47: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy111.value = 0;     yymsp[-2].minor.yy111.mask = 0x000000; }
+      case 48: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy199.value = 0;     yymsp[-2].minor.yy199.mask = 0x000000; }
         break;
-      case 48: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70;     yymsp[-2].minor.yy111.mask = 0x0000ff; }
+      case 49: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100;     yymsp[-2].minor.yy199.mask = 0x0000ff; }
         break;
-      case 49: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8;  yymsp[-2].minor.yy111.mask = 0x00ff00; }
+      case 50: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100<<8;  yymsp[-2].minor.yy199.mask = 0x00ff00; }
         break;
-      case 50: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy70 = OE_SetNull;  /* EV: R-33326-45252 */}
+      case 51: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy100 = OE_SetNull;  /* EV: R-33326-45252 */}
         break;
-      case 51: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy70 = OE_SetDflt;  /* EV: R-33326-45252 */}
+      case 52: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy100 = OE_SetDflt;  /* EV: R-33326-45252 */}
         break;
-      case 52: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy70 = OE_Cascade;  /* EV: R-33326-45252 */}
+      case 53: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy100 = OE_Cascade;  /* EV: R-33326-45252 */}
         break;
-      case 53: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
+      case 54: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy100 = OE_Restrict; /* EV: R-33326-45252 */}
         break;
-      case 54: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy70 = OE_None;     /* EV: R-33326-45252 */}
+      case 55: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy100 = OE_None;     /* EV: R-33326-45252 */}
         break;
-      case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy70 = 0;}
+      case 56: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy100 = 0;}
         break;
-      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;}
+      case 57: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+      case 72: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==72);
+      case 157: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==157);
+{yymsp[-1].minor.yy100 = yymsp[0].minor.yy100;}
         break;
-      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;}
+      case 59: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+      case 76: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==76);
+      case 199: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==199);
+      case 202: /* in_op ::= NOT IN */ yytestcase(yyruleno==202);
+      case 228: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==228);
+{yymsp[-1].minor.yy100 = 1;}
         break;
-      case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy70 = 0;}
+      case 60: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy100 = 0;}
         break;
-      case 61: /* tconscomma ::= COMMA */
+      case 62: /* tconscomma ::= COMMA */
 {pParse->constraintName.n = 0;}
         break;
-      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);}
+      case 64: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy94,yymsp[0].minor.yy100,yymsp[-2].minor.yy100,0);}
         break;
-      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,
+      case 65: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy94,yymsp[0].minor.yy100,0,0,0,0,
                                        SQLITE_IDXTYPE_UNIQUE);}
         break;
-      case 65: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
+      case 66: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy102);}
         break;
-      case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+      case 67: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
-    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy94, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy100);
+    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy100);
 }
         break;
-      case 68: /* onconf ::= */
-      case 70: /* orconf ::= */ yytestcase(yyruleno==70);
-{yymsp[1].minor.yy70 = OE_Default;}
+      case 69: /* onconf ::= */
+      case 71: /* orconf ::= */ yytestcase(yyruleno==71);
+{yymsp[1].minor.yy100 = OE_Default;}
         break;
-      case 69: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
+      case 70: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy100 = yymsp[0].minor.yy100;}
         break;
-      case 72: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy70 = OE_Ignore;}
+      case 73: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy100 = OE_Ignore;}
         break;
-      case 73: /* resolvetype ::= REPLACE */
-      case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
-{yymsp[0].minor.yy70 = OE_Replace;}
+      case 74: /* resolvetype ::= REPLACE */
+      case 158: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==158);
+{yymsp[0].minor.yy100 = OE_Replace;}
         break;
-      case 74: /* cmd ::= DROP TABLE ifexists fullname */
+      case 75: /* cmd ::= DROP TABLE ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy407, 0, yymsp[-1].minor.yy100);
 }
         break;
-      case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+      case 78: /* 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.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
+  sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[0].minor.yy391, yymsp[-7].minor.yy100, yymsp[-5].minor.yy100);
 }
         break;
-      case 78: /* cmd ::= DROP VIEW ifexists fullname */
+      case 79: /* cmd ::= DROP VIEW ifexists fullname */
 {
-  sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
+  sqlite3DropTable(pParse, yymsp[0].minor.yy407, 1, yymsp[-1].minor.yy100);
 }
         break;
-      case 79: /* cmd ::= select */
+      case 80: /* cmd ::= select */
 {
   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
-  sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
-  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+  sqlite3Select(pParse, yymsp[0].minor.yy391, &dest);
+  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
 }
         break;
-      case 80: /* select ::= WITH wqlist selectnowith */
+      case 81: /* select ::= WITH wqlist selectnowith */
 {
-  Select *p = yymsp[0].minor.yy489;
+  Select *p = yymsp[0].minor.yy391;
   if( p ){
-    p->pWith = yymsp[-1].minor.yy449;
+    p->pWith = yymsp[-1].minor.yy243;
     parserDoubleLinkSelect(pParse, p);
   }else{
-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
   }
-  yymsp[-2].minor.yy489 = p;
+  yymsp[-2].minor.yy391 = p;
 }
         break;
-      case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
+      case 82: /* select ::= WITH RECURSIVE wqlist selectnowith */
 {
-  Select *p = yymsp[0].minor.yy489;
+  Select *p = yymsp[0].minor.yy391;
   if( p ){
-    p->pWith = yymsp[-1].minor.yy449;
+    p->pWith = yymsp[-1].minor.yy243;
     parserDoubleLinkSelect(pParse, p);
   }else{
-    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+    sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
   }
-  yymsp[-3].minor.yy489 = p;
+  yymsp[-3].minor.yy391 = p;
 }
         break;
-      case 82: /* select ::= selectnowith */
+      case 83: /* select ::= selectnowith */
 {
-  Select *p = yymsp[0].minor.yy489;
+  Select *p = yymsp[0].minor.yy391;
   if( p ){
     parserDoubleLinkSelect(pParse, p);
   }
-  yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
+  yymsp[0].minor.yy391 = p; /*A-overwrites-X*/
 }
         break;
-      case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
+      case 84: /* selectnowith ::= selectnowith multiselect_op oneselect */
 {
-  Select *pRhs = yymsp[0].minor.yy489;
-  Select *pLhs = yymsp[-2].minor.yy489;
+  Select *pRhs = yymsp[0].minor.yy391;
+  Select *pLhs = yymsp[-2].minor.yy391;
   if( pRhs && pRhs->pPrior ){
     SrcList *pFrom;
     Token x;
@@ -148958,341 +152213,349 @@ static YYACTIONTYPE yy_reduce(
     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
   }
   if( pRhs ){
-    pRhs->op = (u8)yymsp[-1].minor.yy70;
+    pRhs->op = (u8)yymsp[-1].minor.yy100;
     pRhs->pPrior = pLhs;
     if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
     pRhs->selFlags &= ~SF_MultiValue;
-    if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
+    if( yymsp[-1].minor.yy100!=TK_ALL ) pParse->hasCompound = 1;
   }else{
     sqlite3SelectDelete(pParse->db, pLhs);
   }
-  yymsp[-2].minor.yy489 = pRhs;
+  yymsp[-2].minor.yy391 = pRhs;
 }
         break;
-      case 84: /* multiselect_op ::= UNION */
-      case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
+      case 85: /* multiselect_op ::= UNION */
+      case 87: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==87);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-OP*/}
         break;
-      case 85: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy70 = TK_ALL;}
+      case 86: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy100 = TK_ALL;}
         break;
-      case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+      case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
 {
-  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);
+  yymsp[-8].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy94,yymsp[-5].minor.yy407,yymsp[-4].minor.yy102,yymsp[-3].minor.yy94,yymsp[-2].minor.yy102,yymsp[-1].minor.yy94,yymsp[-7].minor.yy100,yymsp[0].minor.yy102);
 }
         break;
-      case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+      case 89: /* 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;
+  yymsp[-9].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy94,yymsp[-6].minor.yy407,yymsp[-5].minor.yy102,yymsp[-4].minor.yy94,yymsp[-3].minor.yy102,yymsp[-1].minor.yy94,yymsp[-8].minor.yy100,yymsp[0].minor.yy102);
+  if( yymsp[-9].minor.yy391 ){
+    yymsp[-9].minor.yy391->pWinDefn = yymsp[-2].minor.yy379;
   }else{
-    sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
+    sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy379);
   }
 }
         break;
-      case 89: /* values ::= VALUES LP nexprlist RP */
+      case 90: /* values ::= VALUES LP nexprlist RP */
 {
-  yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
+  yymsp[-3].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,0,0,0,0,0,SF_Values,0);
 }
         break;
-      case 90: /* values ::= values COMMA LP nexprlist RP */
+      case 91: /* values ::= values COMMA LP nexprlist RP */
 {
-  Select *pRight, *pLeft = yymsp[-4].minor.yy489;
-  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+  Select *pRight, *pLeft = yymsp[-4].minor.yy391;
+  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,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.yy489 = pRight;
+    yymsp[-4].minor.yy391 = pRight;
   }else{
-    yymsp[-4].minor.yy489 = pLeft;
+    yymsp[-4].minor.yy391 = pLeft;
   }
 }
         break;
-      case 91: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy70 = SF_Distinct;}
+      case 92: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy100 = SF_Distinct;}
         break;
-      case 92: /* distinct ::= ALL */
-{yymsp[0].minor.yy70 = SF_All;}
+      case 93: /* distinct ::= ALL */
+{yymsp[0].minor.yy100 = SF_All;}
         break;
-      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;}
+      case 95: /* sclp ::= */
+      case 128: /* orderby_opt ::= */ yytestcase(yyruleno==128);
+      case 135: /* groupby_opt ::= */ yytestcase(yyruleno==135);
+      case 215: /* exprlist ::= */ yytestcase(yyruleno==215);
+      case 218: /* paren_exprlist ::= */ yytestcase(yyruleno==218);
+      case 223: /* eidlist_opt ::= */ yytestcase(yyruleno==223);
+{yymsp[1].minor.yy94 = 0;}
         break;
-      case 95: /* selcollist ::= sclp scanpt expr scanpt as */
+      case 96: /* selcollist ::= sclp scanpt expr scanpt as */
 {
-   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);
+   yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[0].minor.yy0, 1);
+   sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy94,yymsp[-3].minor.yy528,yymsp[-1].minor.yy528);
 }
         break;
-      case 96: /* selcollist ::= sclp scanpt STAR */
+      case 97: /* selcollist ::= sclp scanpt STAR */
 {
   Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
-  yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
+  yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy94, p);
 }
         break;
-      case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
+      case 98: /* 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.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
+  yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, pDot);
 }
         break;
-      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);
+      case 99: /* as ::= AS nm */
+      case 110: /* dbnm ::= DOT nm */ yytestcase(yyruleno==110);
+      case 239: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==239);
+      case 240: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==240);
 {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
         break;
-      case 100: /* from ::= */
-{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
+      case 101: /* from ::= */
+{yymsp[1].minor.yy407 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy407));}
         break;
-      case 101: /* from ::= FROM seltablist */
+      case 102: /* from ::= FROM seltablist */
 {
-  yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
-  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
+  yymsp[-1].minor.yy407 = yymsp[0].minor.yy407;
+  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy407);
 }
         break;
-      case 102: /* stl_prefix ::= seltablist joinop */
+      case 103: /* stl_prefix ::= seltablist joinop */
 {
-   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;
+   if( ALWAYS(yymsp[-1].minor.yy407 && yymsp[-1].minor.yy407->nSrc>0) ) yymsp[-1].minor.yy407->a[yymsp[-1].minor.yy407->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy100;
 }
         break;
-      case 103: /* stl_prefix ::= */
-{yymsp[1].minor.yy135 = 0;}
+      case 104: /* stl_prefix ::= */
+{yymsp[1].minor.yy407 = 0;}
         break;
-      case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+      case 105: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
 {
-  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);
+  yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy407, &yymsp[-2].minor.yy0);
 }
         break;
-      case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+      case 106: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
 {
-  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);
+  yymsp[-8].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy407,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy407, yymsp[-4].minor.yy94);
 }
         break;
-      case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+      case 107: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
 {
-    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);
+    yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy391,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
   }
         break;
-      case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+      case 108: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
 {
-    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;
+    if( yymsp[-6].minor.yy407==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy102==0 && yymsp[0].minor.yy76==0 ){
+      yymsp[-6].minor.yy407 = yymsp[-4].minor.yy407;
+    }else if( yymsp[-4].minor.yy407->nSrc==1 ){
+      yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+      if( yymsp[-6].minor.yy407 ){
+        struct SrcList_item *pNew = &yymsp[-6].minor.yy407->a[yymsp[-6].minor.yy407->nSrc-1];
+        struct SrcList_item *pOld = yymsp[-4].minor.yy407->a;
         pNew->zName = pOld->zName;
         pNew->zDatabase = pOld->zDatabase;
         pNew->pSelect = pOld->pSelect;
+        if( pOld->fg.isTabFunc ){
+          pNew->u1.pFuncArg = pOld->u1.pFuncArg;
+          pOld->u1.pFuncArg = 0;
+          pOld->fg.isTabFunc = 0;
+          pNew->fg.isTabFunc = 1;
+        }
         pOld->zName = pOld->zDatabase = 0;
         pOld->pSelect = 0;
       }
-      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
+      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy407);
     }else{
       Select *pSubquery;
-      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);
+      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy407);
+      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy407,0,0,0,0,SF_NestedFrom,0);
+      yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
     }
   }
         break;
-      case 108: /* dbnm ::= */
-      case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
+      case 109: /* dbnm ::= */
+      case 123: /* indexed_opt ::= */ yytestcase(yyruleno==123);
 {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
         break;
-      case 110: /* fullname ::= nm */
+      case 111: /* 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);
+  yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+  if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
 }
-  yymsp[0].minor.yy135 = yylhsminor.yy135;
+  yymsp[0].minor.yy407 = yylhsminor.yy407;
         break;
-      case 111: /* fullname ::= nm DOT nm */
+      case 112: /* 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);
+  yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+  if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
 }
-  yymsp[-2].minor.yy135 = yylhsminor.yy135;
+  yymsp[-2].minor.yy407 = yylhsminor.yy407;
         break;
-      case 112: /* xfullname ::= nm */
-{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+      case 113: /* xfullname ::= nm */
+{yymsp[0].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
         break;
-      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*/}
+      case 114: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
         break;
-      case 114: /* xfullname ::= nm DOT nm AS nm */
+      case 115: /* 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);
+   yymsp[-4].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+   if( yymsp[-4].minor.yy407 ) yymsp[-4].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
 }
         break;
-      case 115: /* xfullname ::= nm AS nm */
+      case 116: /* 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);
+   yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+   if( yymsp[-2].minor.yy407 ) yymsp[-2].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
 }
         break;
-      case 116: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy70 = JT_INNER; }
+      case 117: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy100 = JT_INNER; }
         break;
-      case 117: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
+      case 118: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy100 = 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*/}
+      case 119: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy100 = 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*/}
+      case 120: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy100 = 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;}
+      case 121: /* on_opt ::= ON expr */
+      case 138: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==138);
+      case 145: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==145);
+      case 211: /* case_else ::= ELSE expr */ yytestcase(yyruleno==211);
+      case 232: /* vinto ::= INTO expr */ yytestcase(yyruleno==232);
+{yymsp[-1].minor.yy102 = yymsp[0].minor.yy102;}
         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;}
+      case 122: /* on_opt ::= */
+      case 137: /* having_opt ::= */ yytestcase(yyruleno==137);
+      case 139: /* limit_opt ::= */ yytestcase(yyruleno==139);
+      case 144: /* where_opt ::= */ yytestcase(yyruleno==144);
+      case 212: /* case_else ::= */ yytestcase(yyruleno==212);
+      case 214: /* case_operand ::= */ yytestcase(yyruleno==214);
+      case 233: /* vinto ::= */ yytestcase(yyruleno==233);
+{yymsp[1].minor.yy102 = 0;}
         break;
-      case 123: /* indexed_opt ::= INDEXED BY nm */
+      case 124: /* indexed_opt ::= INDEXED BY nm */
 {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
         break;
-      case 124: /* indexed_opt ::= NOT INDEXED */
+      case 125: /* indexed_opt ::= NOT INDEXED */
 {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
         break;
-      case 125: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
+      case 126: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy76 = yymsp[-1].minor.yy76;}
         break;
-      case 126: /* using_opt ::= */
-      case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
-{yymsp[1].minor.yy48 = 0;}
+      case 127: /* using_opt ::= */
+      case 159: /* idlist_opt ::= */ yytestcase(yyruleno==159);
+{yymsp[1].minor.yy76 = 0;}
         break;
-      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;}
+      case 129: /* orderby_opt ::= ORDER BY sortlist */
+      case 136: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==136);
+{yymsp[-2].minor.yy94 = yymsp[0].minor.yy94;}
         break;
-      case 129: /* sortlist ::= sortlist COMMA expr sortorder */
+      case 130: /* sortlist ::= sortlist COMMA expr sortorder */
 {
-  yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
-  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
+  yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94,yymsp[-1].minor.yy102);
+  sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy94,yymsp[0].minor.yy100);
 }
         break;
-      case 130: /* sortlist ::= expr sortorder */
+      case 131: /* sortlist ::= expr sortorder */
 {
-  yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
-  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
+  yymsp[-1].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy102); /*A-overwrites-Y*/
+  sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy94,yymsp[0].minor.yy100);
 }
         break;
-      case 131: /* sortorder ::= ASC */
-{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
+      case 132: /* sortorder ::= ASC */
+{yymsp[0].minor.yy100 = SQLITE_SO_ASC;}
         break;
-      case 132: /* sortorder ::= DESC */
-{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
+      case 133: /* sortorder ::= DESC */
+{yymsp[0].minor.yy100 = SQLITE_SO_DESC;}
         break;
-      case 133: /* sortorder ::= */
-{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
+      case 134: /* sortorder ::= */
+{yymsp[1].minor.yy100 = SQLITE_SO_UNDEFINED;}
         break;
-      case 139: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
+      case 140: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,0);}
         break;
-      case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+      case 141: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
         break;
-      case 141: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
+      case 142: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,yymsp[-2].minor.yy102);}
         break;
-      case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+      case 143: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
 {
-  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0);
-  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy407, &yymsp[-1].minor.yy0);
+  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy407,yymsp[0].minor.yy102,0,0);
 }
         break;
-      case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+      case 146: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
 {
-  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);
+  sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy407, &yymsp[-3].minor.yy0);
+  sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy94,"set list"); 
+  sqlite3Update(pParse,yymsp[-4].minor.yy407,yymsp[-1].minor.yy94,yymsp[0].minor.yy102,yymsp[-5].minor.yy100,0,0,0);
 }
         break;
-      case 146: /* setlist ::= setlist COMMA nm EQ expr */
+      case 147: /* setlist ::= setlist COMMA nm EQ expr */
 {
-  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);
+  yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
+  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, 1);
 }
         break;
-      case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+      case 148: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
 {
-  yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+  yymsp[-6].minor.yy94 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy94, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
 }
         break;
-      case 148: /* setlist ::= nm EQ expr */
+      case 149: /* setlist ::= nm EQ expr */
 {
-  yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
-  sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
+  yylhsminor.yy94 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy102);
+  sqlite3ExprListSetName(pParse, yylhsminor.yy94, &yymsp[-2].minor.yy0, 1);
 }
-  yymsp[-2].minor.yy420 = yylhsminor.yy420;
+  yymsp[-2].minor.yy94 = yylhsminor.yy94;
         break;
-      case 149: /* setlist ::= LP idlist RP EQ expr */
+      case 150: /* setlist ::= LP idlist RP EQ expr */
 {
-  yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+  yymsp[-4].minor.yy94 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
 }
         break;
-      case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+      case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
 {
-  sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
+  sqlite3Insert(pParse, yymsp[-3].minor.yy407, yymsp[-1].minor.yy391, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, yymsp[0].minor.yy95);
 }
         break;
-      case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+      case 152: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
 {
-  sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
+  sqlite3Insert(pParse, yymsp[-3].minor.yy407, 0, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, 0);
 }
         break;
-      case 152: /* upsert ::= */
-{ yymsp[1].minor.yy340 = 0; }
+      case 153: /* upsert ::= */
+{ yymsp[1].minor.yy95 = 0; }
         break;
-      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);}
+      case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+{ yymsp[-10].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy94,yymsp[-5].minor.yy102,yymsp[-1].minor.yy94,yymsp[0].minor.yy102);}
         break;
-      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); }
+      case 155: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+{ yymsp[-7].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy94,yymsp[-2].minor.yy102,0,0); }
         break;
-      case 155: /* upsert ::= ON CONFLICT DO NOTHING */
-{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+      case 156: /* upsert ::= ON CONFLICT DO NOTHING */
+{ yymsp[-3].minor.yy95 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
         break;
-      case 159: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
+      case 160: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy76 = yymsp[-1].minor.yy76;}
         break;
-      case 160: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
+      case 161: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy76 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy76,&yymsp[0].minor.yy0);}
         break;
-      case 161: /* idlist ::= nm */
-{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+      case 162: /* idlist ::= nm */
+{yymsp[0].minor.yy76 = 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;}
+      case 163: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy102 = yymsp[-1].minor.yy102;}
         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*/}
+      case 164: /* expr ::= ID|INDEXED */
+      case 165: /* expr ::= JOIN_KW */ yytestcase(yyruleno==165);
+{yymsp[0].minor.yy102=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
         break;
-      case 165: /* expr ::= nm DOT nm */
+      case 166: /* 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);
@@ -149300,11 +152563,11 @@ static YYACTIONTYPE yy_reduce(
     sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
     sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
   }
-  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+  yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
 }
-  yymsp[-2].minor.yy18 = yylhsminor.yy18;
+  yymsp[-2].minor.yy102 = yylhsminor.yy102;
         break;
-      case 166: /* expr ::= nm DOT nm DOT nm */
+      case 167: /* 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);
@@ -149314,26 +152577,26 @@ static YYACTIONTYPE yy_reduce(
     sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
     sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
   }
-  yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+  yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
 }
-  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+  yymsp[-4].minor.yy102 = yylhsminor.yy102;
         break;
-      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*/}
+      case 168: /* term ::= NULL|FLOAT|BLOB */
+      case 169: /* term ::= STRING */ yytestcase(yyruleno==169);
+{yymsp[0].minor.yy102=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
         break;
-      case 169: /* term ::= INTEGER */
+      case 170: /* term ::= INTEGER */
 {
-  yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+  yylhsminor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
 }
-  yymsp[0].minor.yy18 = yylhsminor.yy18;
+  yymsp[0].minor.yy102 = yylhsminor.yy102;
         break;
-      case 170: /* expr ::= VARIABLE */
+      case 171: /* 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.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
-    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
+    yymsp[0].minor.yy102 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy102, 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
@@ -149342,154 +152605,156 @@ static YYACTIONTYPE yy_reduce(
     assert( t.n>=2 );
     if( pParse->nested==0 ){
       sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
-      yymsp[0].minor.yy18 = 0;
+      yymsp[0].minor.yy102 = 0;
     }else{
-      yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
-      if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
+      yymsp[0].minor.yy102 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+      if( yymsp[0].minor.yy102 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy102->iTable);
     }
   }
 }
         break;
-      case 171: /* expr ::= expr COLLATE ID|STRING */
+      case 172: /* expr ::= expr COLLATE ID|STRING */
 {
-  yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
+  yymsp[-2].minor.yy102 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy102, &yymsp[0].minor.yy0, 1);
 }
         break;
-      case 172: /* expr ::= CAST LP expr AS typetoken RP */
+      case 173: /* expr ::= CAST LP expr AS typetoken RP */
 {
-  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);
+  yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy102, yymsp[-3].minor.yy102, 0);
 }
         break;
-      case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+      case 174: /* expr ::= ID|INDEXED LP distinct exprlist RP */
 {
-  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+  yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy100);
 }
-  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+  yymsp[-4].minor.yy102 = yylhsminor.yy102;
         break;
-      case 174: /* expr ::= ID|INDEXED LP STAR RP */
+      case 175: /* expr ::= ID|INDEXED LP STAR RP */
 {
-  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+  yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
 }
-  yymsp[-3].minor.yy18 = yylhsminor.yy18;
+  yymsp[-3].minor.yy102 = yylhsminor.yy102;
         break;
-      case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+      case 176: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
 {
-  yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
-  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+  yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy94, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy100);
+  sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
 }
-  yymsp[-5].minor.yy18 = yylhsminor.yy18;
+  yymsp[-5].minor.yy102 = yylhsminor.yy102;
         break;
-      case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
+      case 177: /* expr ::= ID|INDEXED LP STAR RP over_clause */
 {
-  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
-  sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+  yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+  sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
 }
-  yymsp[-4].minor.yy18 = yylhsminor.yy18;
+  yymsp[-4].minor.yy102 = yylhsminor.yy102;
         break;
-      case 177: /* term ::= CTIME_KW */
+      case 178: /* term ::= CTIME_KW */
 {
-  yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+  yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
 }
-  yymsp[0].minor.yy18 = yylhsminor.yy18;
+  yymsp[0].minor.yy102 = yylhsminor.yy102;
         break;
-      case 178: /* expr ::= LP nexprlist COMMA expr RP */
+      case 179: /* 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;
+  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy94, yymsp[-1].minor.yy102);
+  yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+  if( yymsp[-4].minor.yy102 ){
+    yymsp[-4].minor.yy102->x.pList = pList;
   }else{
     sqlite3ExprListDelete(pParse->db, pList);
   }
 }
         break;
-      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);}
+      case 180: /* expr ::= expr AND expr */
+{yymsp[-2].minor.yy102=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
         break;
-      case 187: /* likeop ::= NOT LIKE_KW|MATCH */
+      case 181: /* expr ::= expr OR expr */
+      case 182: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==182);
+      case 183: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==183);
+      case 184: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==184);
+      case 185: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==185);
+      case 186: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==186);
+      case 187: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==187);
+{yymsp[-2].minor.yy102=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
+        break;
+      case 188: /* 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 188: /* expr ::= expr likeop expr */
+      case 189: /* 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.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;
+  pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy102);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy102);
+  yymsp[-2].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+  if( bNot ) yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy102, 0);
+  if( yymsp[-2].minor.yy102 ) yymsp[-2].minor.yy102->flags |= EP_InfixFunc;
 }
         break;
-      case 189: /* expr ::= expr likeop expr ESCAPE expr */
+      case 190: /* 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.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;
+  pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy102);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+  yymsp[-4].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+  if( bNot ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
+  if( yymsp[-4].minor.yy102 ) yymsp[-4].minor.yy102->flags |= EP_InfixFunc;
 }
         break;
-      case 190: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
+      case 191: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy102,0);}
         break;
-      case 191: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
+      case 192: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy102,0);}
         break;
-      case 192: /* expr ::= expr IS expr */
+      case 193: /* expr ::= expr IS expr */
 {
-  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);
+  yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);
+  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-2].minor.yy102, TK_ISNULL);
 }
         break;
-      case 193: /* expr ::= expr IS NOT expr */
+      case 194: /* expr ::= expr IS NOT expr */
 {
-  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);
+  yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy102,yymsp[0].minor.yy102);
+  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-3].minor.yy102, TK_NOTNULL);
 }
         break;
-      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*/}
+      case 195: /* expr ::= NOT expr */
+      case 196: /* expr ::= BITNOT expr */ yytestcase(yyruleno==196);
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy102, 0);/*A-overwrites-B*/}
         break;
-      case 196: /* expr ::= PLUS|MINUS expr */
+      case 197: /* expr ::= PLUS|MINUS expr */
 {
-  yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
+  yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy102, 0);
   /*A-overwrites-B*/
 }
         break;
-      case 197: /* between_op ::= BETWEEN */
-      case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
-{yymsp[0].minor.yy70 = 0;}
+      case 198: /* between_op ::= BETWEEN */
+      case 201: /* in_op ::= IN */ yytestcase(yyruleno==201);
+{yymsp[0].minor.yy100 = 0;}
         break;
-      case 199: /* expr ::= expr between_op expr AND expr */
+      case 200: /* expr ::= expr between_op expr AND expr */
 {
-  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;
+  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+  yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy102, 0);
+  if( yymsp[-4].minor.yy102 ){
+    yymsp[-4].minor.yy102->x.pList = pList;
   }else{
     sqlite3ExprListDelete(pParse->db, pList);
   } 
-  if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+  if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
 }
         break;
-      case 202: /* expr ::= expr in_op LP exprlist RP */
+      case 203: /* expr ::= expr in_op LP exprlist RP */
 {
-    if( yymsp[-1].minor.yy420==0 ){
+    if( yymsp[-1].minor.yy94==0 ){
       /* Expressions of the form
       **
       **      expr1 IN ()
@@ -149498,9 +152763,9 @@ static YYACTIONTYPE yy_reduce(
       ** simplify to constants 0 (false) and 1 (true), respectively,
       ** regardless of the value of expr1.
       */
-      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 ){
+      sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy102);
+      yymsp[-4].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy100],1);
+    }else if( yymsp[-1].minor.yy94->nExpr==1 ){
       /* Expressions of the form:
       **
       **      expr1 IN (?1)
@@ -149517,199 +152782,199 @@ static YYACTIONTYPE yy_reduce(
       ** 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.yy420->a[0].pExpr;
-      yymsp[-1].minor.yy420->a[0].pExpr = 0;
-      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+      Expr *pRHS = yymsp[-1].minor.yy94->a[0].pExpr;
+      yymsp[-1].minor.yy94->a[0].pExpr = 0;
+      sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
       /* pRHS cannot be NULL because a malloc error would have been detected
       ** before now and control would have never reached this point */
       if( ALWAYS(pRHS) ){
         pRHS->flags &= ~EP_Collate;
         pRHS->flags |= EP_Generic;
       }
-      yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
+      yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, yymsp[-3].minor.yy100 ? TK_NE : TK_EQ, yymsp[-4].minor.yy102, pRHS);
     }else{
-      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);
+      yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+      if( yymsp[-4].minor.yy102 ){
+        yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy94;
+        sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
       }else{
-        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
       }
-      if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+      if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
     }
   }
         break;
-      case 203: /* expr ::= LP select RP */
+      case 204: /* expr ::= LP select RP */
 {
-    yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
-    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
+    yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy102, yymsp[-1].minor.yy391);
   }
         break;
-      case 204: /* expr ::= expr in_op LP select RP */
+      case 205: /* expr ::= expr in_op LP select RP */
 {
-    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);
+    yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, yymsp[-1].minor.yy391);
+    if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
   }
         break;
-      case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */
+      case 206: /* expr ::= expr in_op nm dbnm paren_exprlist */
 {
-    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
+    SrcList *pSrc = sqlite3SrcListAppend(pParse, 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.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);
+    if( yymsp[0].minor.yy94 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy94);
+    yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, pSelect);
+    if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
   }
         break;
-      case 206: /* expr ::= EXISTS LP select RP */
+      case 207: /* expr ::= EXISTS LP select RP */
 {
     Expr *p;
-    p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
-    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
+    p = yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy391);
   }
         break;
-      case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
+      case 208: /* expr ::= CASE case_operand case_exprlist case_else END */
 {
-  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);
+  yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy102, 0);
+  if( yymsp[-4].minor.yy102 ){
+    yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy102 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[-1].minor.yy102) : yymsp[-2].minor.yy94;
+    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
   }else{
-    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
-    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
+    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy94);
+    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy102);
   }
 }
         break;
-      case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+      case 209: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
 {
-  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);
+  yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+  yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
 }
         break;
-      case 209: /* case_exprlist ::= WHEN expr THEN expr */
+      case 210: /* case_exprlist ::= WHEN expr THEN expr */
 {
-  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);
+  yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+  yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94, yymsp[0].minor.yy102);
 }
         break;
-      case 212: /* case_operand ::= expr */
-{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
+      case 213: /* case_operand ::= expr */
+{yymsp[0].minor.yy102 = yymsp[0].minor.yy102; /*A-overwrites-X*/}
         break;
-      case 215: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
+      case 216: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[0].minor.yy102);}
         break;
-      case 216: /* nexprlist ::= expr */
-{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
+      case 217: /* nexprlist ::= expr */
+{yymsp[0].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy102); /*A-overwrites-Y*/}
         break;
-      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;}
+      case 219: /* paren_exprlist ::= LP exprlist RP */
+      case 224: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==224);
+{yymsp[-2].minor.yy94 = yymsp[-1].minor.yy94;}
         break;
-      case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+      case 220: /* 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.yy420, yymsp[-10].minor.yy70,
-                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
+                     sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy94, yymsp[-10].minor.yy100,
+                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy102, SQLITE_SO_ASC, yymsp[-8].minor.yy100, SQLITE_IDXTYPE_APPDEF);
   if( IN_RENAME_OBJECT && pParse->pNewIndex ){
     sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
   }
 }
         break;
-      case 220: /* uniqueflag ::= UNIQUE */
-      case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
-{yymsp[0].minor.yy70 = OE_Abort;}
+      case 221: /* uniqueflag ::= UNIQUE */
+      case 263: /* raisetype ::= ABORT */ yytestcase(yyruleno==263);
+{yymsp[0].minor.yy100 = OE_Abort;}
         break;
-      case 221: /* uniqueflag ::= */
-{yymsp[1].minor.yy70 = OE_None;}
+      case 222: /* uniqueflag ::= */
+{yymsp[1].minor.yy100 = OE_None;}
         break;
-      case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
+      case 225: /* eidlist ::= eidlist COMMA nm collate sortorder */
 {
-  yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
+  yymsp[-4].minor.yy94 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100);
 }
         break;
-      case 225: /* eidlist ::= nm collate sortorder */
+      case 226: /* eidlist ::= nm collate sortorder */
 {
-  yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
+  yymsp[-2].minor.yy94 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100); /*A-overwrites-Y*/
 }
         break;
-      case 228: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
+      case 229: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy407, yymsp[-1].minor.yy100);}
         break;
-      case 229: /* cmd ::= VACUUM */
-{sqlite3Vacuum(pParse,0);}
+      case 230: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy102);}
         break;
-      case 230: /* cmd ::= VACUUM nm */
-{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+      case 231: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy102);}
         break;
-      case 231: /* cmd ::= PRAGMA nm dbnm */
+      case 234: /* cmd ::= PRAGMA nm dbnm */
 {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
         break;
-      case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+      case 235: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
         break;
-      case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+      case 236: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
 {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
         break;
-      case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+      case 237: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
         break;
-      case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+      case 238: /* 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 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+      case 241: /* 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.yy207, &all);
+  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy11, &all);
 }
         break;
-      case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+      case 242: /* 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.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);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy100, yymsp[-4].minor.yy298.a, yymsp[-4].minor.yy298.b, yymsp[-2].minor.yy407, yymsp[0].minor.yy102, yymsp[-10].minor.yy100, yymsp[-8].minor.yy100);
   yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
 }
         break;
-      case 240: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
+      case 243: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/ }
         break;
-      case 241: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
+      case 244: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy100 = TK_INSTEAD;}
         break;
-      case 242: /* trigger_time ::= */
-{ yymsp[1].minor.yy70 = TK_BEFORE; }
+      case 245: /* trigger_time ::= */
+{ yymsp[1].minor.yy100 = TK_BEFORE; }
         break;
-      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;}
+      case 246: /* trigger_event ::= DELETE|INSERT */
+      case 247: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==247);
+{yymsp[0].minor.yy298.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy298.b = 0;}
         break;
-      case 245: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
+      case 248: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy298.a = TK_UPDATE; yymsp[-2].minor.yy298.b = yymsp[0].minor.yy76;}
         break;
-      case 246: /* when_clause ::= */
-      case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
-      case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
-{ yymsp[1].minor.yy18 = 0; }
+      case 249: /* when_clause ::= */
+      case 268: /* key_opt ::= */ yytestcase(yyruleno==268);
+      case 316: /* filter_opt ::= */ yytestcase(yyruleno==316);
+{ yymsp[1].minor.yy102 = 0; }
         break;
-      case 247: /* when_clause ::= WHEN expr */
-      case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
-{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
+      case 250: /* when_clause ::= WHEN expr */
+      case 269: /* key_opt ::= KEY expr */ yytestcase(yyruleno==269);
+{ yymsp[-1].minor.yy102 = yymsp[0].minor.yy102; }
         break;
-      case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+      case 251: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
 {
-  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;
+  assert( yymsp[-2].minor.yy11!=0 );
+  yymsp[-2].minor.yy11->pLast->pNext = yymsp[-1].minor.yy11;
+  yymsp[-2].minor.yy11->pLast = yymsp[-1].minor.yy11;
 }
         break;
-      case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
+      case 252: /* trigger_cmd_list ::= trigger_cmd SEMI */
 { 
-  assert( yymsp[-1].minor.yy207!=0 );
-  yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
+  assert( yymsp[-1].minor.yy11!=0 );
+  yymsp[-1].minor.yy11->pLast = yymsp[-1].minor.yy11;
 }
         break;
-      case 250: /* trnm ::= nm DOT nm */
+      case 253: /* trnm ::= nm DOT nm */
 {
   yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
   sqlite3ErrorMsg(pParse, 
@@ -149717,312 +152982,334 @@ static YYACTIONTYPE yy_reduce(
         "statements within triggers");
 }
         break;
-      case 251: /* tridxby ::= INDEXED BY nm */
+      case 254: /* tridxby ::= INDEXED BY nm */
 {
   sqlite3ErrorMsg(pParse,
         "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      case 252: /* tridxby ::= NOT INDEXED */
+      case 255: /* tridxby ::= NOT INDEXED */
 {
   sqlite3ErrorMsg(pParse,
         "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
         "within triggers");
 }
         break;
-      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;
+      case 256: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy102, yymsp[-6].minor.yy100, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy528);}
+  yymsp[-7].minor.yy11 = yylhsminor.yy11;
         break;
-      case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+      case 257: /* 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*/
+   yylhsminor.yy11 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy76,yymsp[-2].minor.yy391,yymsp[-6].minor.yy100,yymsp[-1].minor.yy95,yymsp[-7].minor.yy528,yymsp[0].minor.yy528);/*yylhsminor.yy11-overwrites-yymsp[-6].minor.yy100*/
 }
-  yymsp[-7].minor.yy207 = yylhsminor.yy207;
+  yymsp[-7].minor.yy11 = yylhsminor.yy11;
         break;
-      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;
+      case 258: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy102, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy528);}
+  yymsp[-5].minor.yy11 = yylhsminor.yy11;
         break;
-      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;
+      case 259: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy11 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy391, yymsp[-2].minor.yy528, yymsp[0].minor.yy528); /*yylhsminor.yy11-overwrites-yymsp[-1].minor.yy391*/}
+  yymsp[-2].minor.yy11 = yylhsminor.yy11;
         break;
-      case 257: /* expr ::= RAISE LP IGNORE RP */
+      case 260: /* expr ::= RAISE LP IGNORE RP */
 {
-  yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
-  if( yymsp[-3].minor.yy18 ){
-    yymsp[-3].minor.yy18->affinity = OE_Ignore;
+  yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
+  if( yymsp[-3].minor.yy102 ){
+    yymsp[-3].minor.yy102->affinity = OE_Ignore;
   }
 }
         break;
-      case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */
+      case 261: /* expr ::= RAISE LP raisetype COMMA nm RP */
 {
-  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;
+  yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); 
+  if( yymsp[-5].minor.yy102 ) {
+    yymsp[-5].minor.yy102->affinity = (char)yymsp[-3].minor.yy100;
   }
 }
         break;
-      case 259: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy70 = OE_Rollback;}
+      case 262: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy100 = OE_Rollback;}
         break;
-      case 261: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy70 = OE_Fail;}
+      case 264: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy100 = OE_Fail;}
         break;
-      case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
+      case 265: /* cmd ::= DROP TRIGGER ifexists fullname */
 {
-  sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
+  sqlite3DropTrigger(pParse,yymsp[0].minor.yy407,yymsp[-1].minor.yy100);
 }
         break;
-      case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+      case 266: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
 {
-  sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
+  sqlite3Attach(pParse, yymsp[-3].minor.yy102, yymsp[-1].minor.yy102, yymsp[0].minor.yy102);
 }
         break;
-      case 264: /* cmd ::= DETACH database_kw_opt expr */
+      case 267: /* cmd ::= DETACH database_kw_opt expr */
 {
-  sqlite3Detach(pParse, yymsp[0].minor.yy18);
+  sqlite3Detach(pParse, yymsp[0].minor.yy102);
 }
         break;
-      case 267: /* cmd ::= REINDEX */
+      case 270: /* cmd ::= REINDEX */
 {sqlite3Reindex(pParse, 0, 0);}
         break;
-      case 268: /* cmd ::= REINDEX nm dbnm */
+      case 271: /* cmd ::= REINDEX nm dbnm */
 {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 269: /* cmd ::= ANALYZE */
+      case 272: /* cmd ::= ANALYZE */
 {sqlite3Analyze(pParse, 0, 0);}
         break;
-      case 270: /* cmd ::= ANALYZE nm dbnm */
+      case 273: /* cmd ::= ANALYZE nm dbnm */
 {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
-      case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+      case 274: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy407,&yymsp[0].minor.yy0);
 }
         break;
-      case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+      case 275: /* 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 273: /* add_column_fullname ::= fullname */
+      case 276: /* add_column_fullname ::= fullname */
 {
   disableLookaside(pParse);
-  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy407);
 }
         break;
-      case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+      case 277: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
 {
-  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy407, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
 }
         break;
-      case 275: /* cmd ::= create_vtab */
+      case 278: /* cmd ::= create_vtab */
 {sqlite3VtabFinishParse(pParse,0);}
         break;
-      case 276: /* cmd ::= create_vtab LP vtabarglist RP */
+      case 279: /* cmd ::= create_vtab LP vtabarglist RP */
 {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+      case 280: /* 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.yy70);
+    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy100);
 }
         break;
-      case 278: /* vtabarg ::= */
+      case 281: /* vtabarg ::= */
 {sqlite3VtabArgInit(pParse);}
         break;
-      case 279: /* vtabargtoken ::= ANY */
-      case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
-      case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
+      case 282: /* vtabargtoken ::= ANY */
+      case 283: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==283);
+      case 284: /* lp ::= LP */ yytestcase(yyruleno==284);
 {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
         break;
-      case 282: /* with ::= WITH wqlist */
-      case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+      case 285: /* with ::= WITH wqlist */
+      case 286: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==286);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy243, 1); }
         break;
-      case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
+      case 287: /* 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*/
+  yymsp[-5].minor.yy243 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391); /*A-overwrites-X*/
 }
         break;
-      case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+      case 288: /* 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);
+  yymsp[-7].minor.yy243 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy243, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391);
 }
         break;
-      case 286: /* windowdefn_list ::= windowdefn */
-{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
-  yymsp[0].minor.yy327 = yylhsminor.yy327;
+      case 289: /* windowdefn_list ::= windowdefn */
+{ yylhsminor.yy379 = yymsp[0].minor.yy379; }
+  yymsp[0].minor.yy379 = yylhsminor.yy379;
         break;
-      case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+      case 290: /* 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;
+  assert( yymsp[0].minor.yy379!=0 );
+  sqlite3WindowChain(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy379);
+  yymsp[0].minor.yy379->pNextWin = yymsp[-2].minor.yy379;
+  yylhsminor.yy379 = yymsp[0].minor.yy379;
 }
-  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+  yymsp[-2].minor.yy379 = yylhsminor.yy379;
         break;
-      case 288: /* windowdefn ::= nm AS window */
+      case 291: /* windowdefn ::= nm AS LP window RP */
 {
-  if( ALWAYS(yymsp[0].minor.yy327) ){
-    yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
+  if( ALWAYS(yymsp[-1].minor.yy379) ){
+    yymsp[-1].minor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
   }
-  yylhsminor.yy327 = yymsp[0].minor.yy327;
+  yylhsminor.yy379 = yymsp[-1].minor.yy379;
 }
-  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+  yymsp[-4].minor.yy379 = yylhsminor.yy379;
         break;
-      case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
+      case 292: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
 {
-  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;
-  }
+  yymsp[-4].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, 0);
 }
         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 */
+      case 293: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
 {
-  yylhsminor.yy327 = yymsp[0].minor.yy327;
-  assert( yylhsminor.yy327!=0 );
-  yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+  yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, &yymsp[-5].minor.yy0);
 }
-  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+  yymsp[-5].minor.yy379 = yylhsminor.yy379;
         break;
-      case 306: /* over_clause ::= filter_opt OVER nm */
+      case 294: /* window ::= ORDER BY sortlist frame_opt */
 {
-  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;
+  yymsp[-3].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, 0);
+}
+        break;
+      case 295: /* window ::= nm ORDER BY sortlist frame_opt */
+{
+  yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0);
+}
+  yymsp[-4].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 296: /* window ::= frame_opt */
+{
+  yylhsminor.yy379 = yymsp[0].minor.yy379;
+}
+  yymsp[0].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 297: /* window ::= nm frame_opt */
+{
+  yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, 0, &yymsp[-1].minor.yy0);
+}
+  yymsp[-1].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 298: /* frame_opt ::= */
+{ 
+  yymsp[1].minor.yy379 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
+}
+        break;
+      case 299: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+{ 
+  yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy100, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy218);
+}
+  yymsp[-2].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 300: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+{ 
+  yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy100, yymsp[-3].minor.yy389.eType, yymsp[-3].minor.yy389.pExpr, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, yymsp[0].minor.yy218);
+}
+  yymsp[-5].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 302: /* frame_bound_s ::= frame_bound */
+      case 304: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==304);
+{yylhsminor.yy389 = yymsp[0].minor.yy389;}
+  yymsp[0].minor.yy389 = yylhsminor.yy389;
+        break;
+      case 303: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+      case 305: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==305);
+      case 307: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==307);
+{yylhsminor.yy389.eType = yymsp[-1].major; yylhsminor.yy389.pExpr = 0;}
+  yymsp[-1].minor.yy389 = yylhsminor.yy389;
+        break;
+      case 306: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+{yylhsminor.yy389.eType = yymsp[0].major; yylhsminor.yy389.pExpr = yymsp[-1].minor.yy102;}
+  yymsp[-1].minor.yy389 = yylhsminor.yy389;
+        break;
+      case 308: /* frame_exclude_opt ::= */
+{yymsp[1].minor.yy218 = 0;}
+        break;
+      case 309: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+{yymsp[-1].minor.yy218 = yymsp[0].minor.yy218;}
+        break;
+      case 310: /* frame_exclude ::= NO OTHERS */
+      case 311: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==311);
+{yymsp[-1].minor.yy218 = yymsp[-1].major; /*A-overwrites-X*/}
+        break;
+      case 312: /* frame_exclude ::= GROUP|TIES */
+{yymsp[0].minor.yy218 = yymsp[0].major; /*A-overwrites-X*/}
+        break;
+      case 313: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy379 = yymsp[0].minor.yy379; }
+        break;
+      case 314: /* over_clause ::= filter_opt OVER LP window RP */
+{
+  yylhsminor.yy379 = yymsp[-1].minor.yy379;
+  assert( yylhsminor.yy379!=0 );
+  yylhsminor.yy379->pFilter = yymsp[-4].minor.yy102;
+}
+  yymsp[-4].minor.yy379 = yylhsminor.yy379;
+        break;
+      case 315: /* over_clause ::= filter_opt OVER nm */
+{
+  yylhsminor.yy379 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+  if( yylhsminor.yy379 ){
+    yylhsminor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+    yylhsminor.yy379->pFilter = yymsp[-2].minor.yy102;
   }else{
-    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
+    sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy102);
   }
 }
-  yymsp[-2].minor.yy327 = yylhsminor.yy327;
+  yymsp[-2].minor.yy379 = yylhsminor.yy379;
         break;
-      case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
+      case 317: /* filter_opt ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy102 = yymsp[-1].minor.yy102; }
         break;
       default:
-      /* (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);
+      /* (318) input ::= cmdlist */ yytestcase(yyruleno==318);
+      /* (319) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==319);
+      /* (320) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=320);
+      /* (321) ecmd ::= SEMI */ yytestcase(yyruleno==321);
+      /* (322) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==322);
+      /* (323) ecmd ::= explain cmdx */ yytestcase(yyruleno==323);
+      /* (324) trans_opt ::= */ yytestcase(yyruleno==324);
+      /* (325) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==325);
+      /* (326) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==326);
+      /* (327) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==327);
+      /* (328) savepoint_opt ::= */ yytestcase(yyruleno==328);
+      /* (329) cmd ::= create_table create_table_args */ yytestcase(yyruleno==329);
+      /* (330) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==330);
+      /* (331) columnlist ::= columnname carglist */ yytestcase(yyruleno==331);
+      /* (332) nm ::= ID|INDEXED */ yytestcase(yyruleno==332);
+      /* (333) nm ::= STRING */ yytestcase(yyruleno==333);
+      /* (334) nm ::= JOIN_KW */ yytestcase(yyruleno==334);
+      /* (335) typetoken ::= typename */ yytestcase(yyruleno==335);
+      /* (336) typename ::= ID|STRING */ yytestcase(yyruleno==336);
+      /* (337) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=337);
+      /* (338) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=338);
+      /* (339) carglist ::= carglist ccons */ yytestcase(yyruleno==339);
+      /* (340) carglist ::= */ yytestcase(yyruleno==340);
+      /* (341) ccons ::= NULL onconf */ yytestcase(yyruleno==341);
+      /* (342) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==342);
+      /* (343) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==343);
+      /* (344) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=344);
+      /* (345) tconscomma ::= */ yytestcase(yyruleno==345);
+      /* (346) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=346);
+      /* (347) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=347);
+      /* (348) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=348);
+      /* (349) oneselect ::= values */ yytestcase(yyruleno==349);
+      /* (350) sclp ::= selcollist COMMA */ yytestcase(yyruleno==350);
+      /* (351) as ::= ID|STRING */ yytestcase(yyruleno==351);
+      /* (352) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=352);
+      /* (353) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==353);
+      /* (354) exprlist ::= nexprlist */ yytestcase(yyruleno==354);
+      /* (355) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=355);
+      /* (356) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=356);
+      /* (357) nmnum ::= ON */ yytestcase(yyruleno==357);
+      /* (358) nmnum ::= DELETE */ yytestcase(yyruleno==358);
+      /* (359) nmnum ::= DEFAULT */ yytestcase(yyruleno==359);
+      /* (360) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==360);
+      /* (361) foreach_clause ::= */ yytestcase(yyruleno==361);
+      /* (362) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==362);
+      /* (363) trnm ::= nm */ yytestcase(yyruleno==363);
+      /* (364) tridxby ::= */ yytestcase(yyruleno==364);
+      /* (365) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==365);
+      /* (366) database_kw_opt ::= */ yytestcase(yyruleno==366);
+      /* (367) kwcolumn_opt ::= */ yytestcase(yyruleno==367);
+      /* (368) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==368);
+      /* (369) vtabarglist ::= vtabarg */ yytestcase(yyruleno==369);
+      /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==370);
+      /* (371) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==371);
+      /* (372) anylist ::= */ yytestcase(yyruleno==372);
+      /* (373) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==373);
+      /* (374) anylist ::= anylist ANY */ yytestcase(yyruleno==374);
+      /* (375) with ::= */ yytestcase(yyruleno==375);
         break;
 /********** End reduce actions ************************************************/
   };
-  assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
-  yygoto = yyRuleInfo[yyruleno].lhs;
-  yysize = yyRuleInfo[yyruleno].nrhs;
+  assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
+  yygoto = yyRuleInfoLhs[yyruleno];
+  yysize = yyRuleInfoNRhs[yyruleno];
   yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
 
   /* There are no SHIFTREDUCE actions on nonterminals because the table
@@ -150230,10 +153517,9 @@ SQLITE_PRIVATE void sqlite3Parser(
         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);
         }
@@ -150480,144 +153766,144 @@ const unsigned char ebcdicToAscii[] = {
 ** is substantially reduced.  This is important for embedded applications
 ** on platforms with limited memory.
 */
-/* Hash score: 208 */
-/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */
+/* Hash score: 214 */
+/* zKWText[] encodes 950 bytes of keyword text in 629 bytes */
 /*   REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT       */
-/*   ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE         */
-/*   XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY         */
-/*   UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN      */
-/*   OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH           */
-/*   IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT     */
-/*   WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST         */
-/*   COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED         */
-/*   ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL       */
-/*   ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW      */
-/*   INDOWINITIALLYPRIMARY                                              */
-static const char zKWText[613] = {
+/*   ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYCONSTRAINTERSECTIES         */
+/*   AVEPOINTOFFSETRANSACTIONATURALTERAISEXCEPTRIGGEREFERENCES          */
+/*   UNIQUERYWITHOUTERELEASEXCLUSIVEXISTSATTACHAVINGLOBEGINNERANGE      */
+/*   BETWEENOTHINGROUPSCASCADETACHCASECOLLATECREATECURRENT_DATE         */
+/*   IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTUPDATEVALUES          */
+/*   VIRTUALIMITWHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULT               */
+/*   AUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMP        */
+/*   ARTITIONDEFERREDISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWING       */
+/*   FROMFULLIFISNULLORDERESTRICTOTHERSOVERIGHTROLLBACKROWS             */
+/*   UNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBYINITIALLYPRIMARY               */
+static const char zKWText[628] = {
   'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
   'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
   'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
   'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
-  'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
-  'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
-  'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
-  'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
-  'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
-  'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
-  'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
-  'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
-  'T','E','B','E','G','I','N','N','E','R','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',
+  'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E',
+  'T','E','M','P','O','R','A','R','Y','C','O','N','S','T','R','A','I','N',
+  'T','E','R','S','E','C','T','I','E','S','A','V','E','P','O','I','N','T',
+  'O','F','F','S','E','T','R','A','N','S','A','C','T','I','O','N','A','T',
+  'U','R','A','L','T','E','R','A','I','S','E','X','C','E','P','T','R','I',
+  'G','G','E','R','E','F','E','R','E','N','C','E','S','U','N','I','Q','U',
+  'E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S','E',
+  'X','C','L','U','S','I','V','E','X','I','S','T','S','A','T','T','A','C',
+  'H','A','V','I','N','G','L','O','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','R','O','U',
+  'P','S','C','A','S','C','A','D','E','T','A','C','H','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','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','U','P','D',
+  'A','T','E','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','T','H','E','R','S','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','B','Y',
+  '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] = {
-    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,
+    75, 111, 127,  73, 108,  29,   0,   0,  83,   0,  77,  63,   0,
+    37,  33,  78,  15,   0, 126,  86,  57, 120, 128,  19,   0,   0,
+   133,   0, 131, 123,   0,  22,  98,   0,   9,   0,   0, 117,  71,
+     0,  69,   6,   0,  49,  95, 140,   0, 129, 106,   0,   0,  54,
+     0, 109,  24,   0,  17,   0, 134,  56,  23,  26,   5,  58, 135,
+   101,   0,   0, 139, 112,  62, 138,  59, 115,  65,   0,  96,   0,
+   105,  45,   0, 104,   0,   0,   0, 100,  97, 102, 107, 119,  14,
+    31, 118,   0,  81,   0, 136, 116, 137,  61, 124, 132,  80, 121,
+    88,  30,  85,   0,   0,  99,  35, 125, 122,   0, 130,   0,   0,
+    41,   0,  91,  89,  90,   0,  20,  87, 113,  82,
 };
 /* 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[136] = {
+static const unsigned char aKWNext[140] = {
      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,  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,
+     0,   0,   0,  21,   0,   0,  12,   0,   0,   0,   0,   0,   0,
+     7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+    51,  28,   0,   0,  38,   0,   0,   0,  44,   0,   0,   0,   3,
+     0,   0,  67,   1,  66,   0,   0,   0,  36,   0,  47,   0,   0,
+     0,   0,   0,  48,  50,  76,   0,   0,  42,   0,  60,   0,   0,
+     0,  43,   0,  16,  55,  10,   0,   0,   0,   0,   0,   0,   0,
+    11,  72,  93,   0,   0,   8,   0, 110,   0, 103,  40,  53,  70,
+     0, 114,   0,  74,  52,   0,   0,  92,  39,  46,   0,  68,  32,
+    84,   0,  34,  27,  25,  18,  94,   0,  64,  79,
 };
 /* aKWLen[i] is the length (in bytes) of the i-th keyword */
-static const unsigned char aKWLen[136] = {
+static const unsigned char aKWLen[140] = {
      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,   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,
+     7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   7,
+     6,   9,   4,   2,  10,   9,   4,   9,   4,   6,   2,   3,  11,
+     6,   2,   7,   5,   5,   6,   7,  10,   6,   5,   7,   4,   5,
+     7,   9,   6,   6,   6,   4,   5,   5,   5,   7,   7,   6,   5,
+     7,   3,   6,   4,   7,   6,  12,   9,   4,   6,   4,   5,   4,
+     7,   6,   5,   6,   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,   6,   4,   5,   8,   4,   3,   9,
+     5,   5,   6,   4,   6,   2,   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[136] = {
+static const unsigned short int aKWOffset[140] = {
      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, 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,
+    86,  90,  90,  94,  99, 106, 114, 117, 123, 126, 126, 129, 131,
+   136, 140, 141, 146, 150, 154, 159, 165, 175, 178, 183, 183, 187,
+   191, 197, 205, 211, 216, 221, 224, 227, 231, 236, 242, 248, 248,
+   254, 255, 259, 265, 269, 276, 282, 294, 303, 305, 311, 315, 320,
+   322, 329, 334, 339, 345, 351, 357, 362, 365, 365, 365, 368, 372,
+   375, 384, 388, 394, 396, 403, 405, 407, 416, 420, 426, 432, 440,
+   445, 445, 445, 461, 470, 477, 478, 485, 488, 497, 501, 506, 513,
+   522, 526, 530, 532, 538, 542, 550, 556, 559, 564, 572, 572, 576,
+   585, 590, 595, 601, 604, 607, 610, 612, 617, 621,
 };
 /* aKWCode[i] is the parser symbol code for the i-th keyword */
-static const unsigned char aKWCode[136] = {
+static const unsigned char aKWCode[140] = {
   TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,     
   TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,    
   TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,    
   TK_ADD,        TK_DATABASE,   TK_AS,         TK_SELECT,     TK_TABLE,      
   TK_JOIN_KW,    TK_THEN,       TK_END,        TK_DEFERRABLE, TK_ELSE,       
-  TK_EXCEPT,     TK_TRANSACTION,TK_ACTION,     TK_ON,         TK_JOIN_KW,    
-  TK_ALTER,      TK_RAISE,      TK_EXCLUSIVE,  TK_EXISTS,     TK_SAVEPOINT,  
-  TK_INTERSECT,  TK_TRIGGER,    TK_REFERENCES, TK_CONSTRAINT, TK_INTO,       
-  TK_OFFSET,     TK_OF,         TK_SET,        TK_TEMP,       TK_TEMP,       
-  TK_OR,         TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    TK_WITH,       
-  TK_JOIN_KW,    TK_RELEASE,    TK_ATTACH,     TK_HAVING,     TK_GROUP,      
-  TK_UPDATE,     TK_BEGIN,      TK_JOIN_KW,    TK_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,    
+  TK_EXCLUDE,    TK_DELETE,     TK_TEMP,       TK_TEMP,       TK_OR,         
+  TK_CONSTRAINT, TK_INTERSECT,  TK_TIES,       TK_SAVEPOINT,  TK_INTO,       
+  TK_OFFSET,     TK_OF,         TK_SET,        TK_TRANSACTION,TK_ACTION,     
+  TK_ON,         TK_JOIN_KW,    TK_ALTER,      TK_RAISE,      TK_EXCEPT,     
+  TK_TRIGGER,    TK_REFERENCES, TK_UNIQUE,     TK_QUERY,      TK_WITHOUT,    
+  TK_WITH,       TK_JOIN_KW,    TK_RELEASE,    TK_EXCLUSIVE,  TK_EXISTS,     
+  TK_ATTACH,     TK_HAVING,     TK_LIKE_KW,    TK_BEGIN,      TK_JOIN_KW,    
+  TK_RANGE,      TK_BETWEEN,    TK_NOTHING,    TK_GROUPS,     TK_GROUP,      
+  TK_CASCADE,    TK_ASC,        TK_DETACH,     TK_CASE,       TK_COLLATE,    
+  TK_CREATE,     TK_CTIME_KW,   TK_IMMEDIATE,  TK_JOIN,       TK_INSERT,     
+  TK_LIKE_KW,    TK_MATCH,      TK_PLAN,       TK_ANALYZE,    TK_PRAGMA,     
+  TK_ABORT,      TK_UPDATE,     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_OTHERS,     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_BY,         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
@@ -150663,117 +153949,121 @@ static int keywordCode(const char *z, int n, int *pType){
       testcase( i==22 ); /* END */
       testcase( i==23 ); /* DEFERRABLE */
       testcase( i==24 ); /* ELSE */
-      testcase( i==25 ); /* EXCEPT */
-      testcase( i==26 ); /* TRANSACTION */
-      testcase( i==27 ); /* ACTION */
-      testcase( i==28 ); /* ON */
-      testcase( i==29 ); /* NATURAL */
-      testcase( i==30 ); /* ALTER */
-      testcase( i==31 ); /* RAISE */
-      testcase( i==32 ); /* EXCLUSIVE */
-      testcase( i==33 ); /* EXISTS */
-      testcase( i==34 ); /* SAVEPOINT */
-      testcase( i==35 ); /* INTERSECT */
-      testcase( i==36 ); /* TRIGGER */
-      testcase( i==37 ); /* REFERENCES */
-      testcase( i==38 ); /* CONSTRAINT */
-      testcase( i==39 ); /* INTO */
-      testcase( i==40 ); /* OFFSET */
-      testcase( i==41 ); /* OF */
-      testcase( i==42 ); /* SET */
-      testcase( i==43 ); /* TEMPORARY */
-      testcase( i==44 ); /* TEMP */
-      testcase( i==45 ); /* OR */
-      testcase( i==46 ); /* UNIQUE */
-      testcase( i==47 ); /* QUERY */
-      testcase( i==48 ); /* WITHOUT */
-      testcase( i==49 ); /* WITH */
-      testcase( i==50 ); /* OUTER */
-      testcase( i==51 ); /* RELEASE */
-      testcase( i==52 ); /* ATTACH */
-      testcase( i==53 ); /* HAVING */
-      testcase( i==54 ); /* GROUP */
-      testcase( i==55 ); /* UPDATE */
-      testcase( i==56 ); /* BEGIN */
-      testcase( i==57 ); /* INNER */
-      testcase( i==58 ); /* RANGE */
-      testcase( i==59 ); /* BETWEEN */
-      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 */
+      testcase( i==25 ); /* EXCLUDE */
+      testcase( i==26 ); /* DELETE */
+      testcase( i==27 ); /* TEMPORARY */
+      testcase( i==28 ); /* TEMP */
+      testcase( i==29 ); /* OR */
+      testcase( i==30 ); /* CONSTRAINT */
+      testcase( i==31 ); /* INTERSECT */
+      testcase( i==32 ); /* TIES */
+      testcase( i==33 ); /* SAVEPOINT */
+      testcase( i==34 ); /* INTO */
+      testcase( i==35 ); /* OFFSET */
+      testcase( i==36 ); /* OF */
+      testcase( i==37 ); /* SET */
+      testcase( i==38 ); /* TRANSACTION */
+      testcase( i==39 ); /* ACTION */
+      testcase( i==40 ); /* ON */
+      testcase( i==41 ); /* NATURAL */
+      testcase( i==42 ); /* ALTER */
+      testcase( i==43 ); /* RAISE */
+      testcase( i==44 ); /* EXCEPT */
+      testcase( i==45 ); /* TRIGGER */
+      testcase( i==46 ); /* REFERENCES */
+      testcase( i==47 ); /* UNIQUE */
+      testcase( i==48 ); /* QUERY */
+      testcase( i==49 ); /* WITHOUT */
+      testcase( i==50 ); /* WITH */
+      testcase( i==51 ); /* OUTER */
+      testcase( i==52 ); /* RELEASE */
+      testcase( i==53 ); /* EXCLUSIVE */
+      testcase( i==54 ); /* EXISTS */
+      testcase( i==55 ); /* ATTACH */
+      testcase( i==56 ); /* HAVING */
+      testcase( i==57 ); /* GLOB */
+      testcase( i==58 ); /* BEGIN */
+      testcase( i==59 ); /* INNER */
+      testcase( i==60 ); /* RANGE */
+      testcase( i==61 ); /* BETWEEN */
+      testcase( i==62 ); /* NOTHING */
+      testcase( i==63 ); /* GROUPS */
+      testcase( i==64 ); /* GROUP */
+      testcase( i==65 ); /* CASCADE */
+      testcase( i==66 ); /* ASC */
+      testcase( i==67 ); /* DETACH */
+      testcase( i==68 ); /* CASE */
+      testcase( i==69 ); /* COLLATE */
+      testcase( i==70 ); /* CREATE */
+      testcase( i==71 ); /* CURRENT_DATE */
+      testcase( i==72 ); /* IMMEDIATE */
+      testcase( i==73 ); /* JOIN */
+      testcase( i==74 ); /* INSERT */
+      testcase( i==75 ); /* LIKE */
+      testcase( i==76 ); /* MATCH */
+      testcase( i==77 ); /* PLAN */
+      testcase( i==78 ); /* ANALYZE */
+      testcase( i==79 ); /* PRAGMA */
+      testcase( i==80 ); /* ABORT */
+      testcase( i==81 ); /* UPDATE */
+      testcase( i==82 ); /* VALUES */
+      testcase( i==83 ); /* VIRTUAL */
+      testcase( i==84 ); /* LIMIT */
+      testcase( i==85 ); /* WHEN */
+      testcase( i==86 ); /* NOTNULL */
+      testcase( i==87 ); /* NOT */
+      testcase( i==88 ); /* NO */
+      testcase( i==89 ); /* NULL */
+      testcase( i==90 ); /* WHERE */
+      testcase( i==91 ); /* RECURSIVE */
+      testcase( i==92 ); /* AFTER */
+      testcase( i==93 ); /* RENAME */
+      testcase( i==94 ); /* AND */
+      testcase( i==95 ); /* DEFAULT */
+      testcase( i==96 ); /* AUTOINCREMENT */
+      testcase( i==97 ); /* TO */
+      testcase( i==98 ); /* IN */
+      testcase( i==99 ); /* CAST */
+      testcase( i==100 ); /* COLUMN */
+      testcase( i==101 ); /* COMMIT */
+      testcase( i==102 ); /* CONFLICT */
+      testcase( i==103 ); /* CROSS */
+      testcase( i==104 ); /* CURRENT_TIMESTAMP */
+      testcase( i==105 ); /* CURRENT_TIME */
+      testcase( i==106 ); /* CURRENT */
+      testcase( i==107 ); /* PARTITION */
+      testcase( i==108 ); /* DEFERRED */
+      testcase( i==109 ); /* DISTINCT */
+      testcase( i==110 ); /* IS */
+      testcase( i==111 ); /* DROP */
+      testcase( i==112 ); /* PRECEDING */
+      testcase( i==113 ); /* FAIL */
+      testcase( i==114 ); /* FILTER */
+      testcase( i==115 ); /* REPLACE */
+      testcase( i==116 ); /* FOLLOWING */
+      testcase( i==117 ); /* FROM */
+      testcase( i==118 ); /* FULL */
+      testcase( i==119 ); /* IF */
+      testcase( i==120 ); /* ISNULL */
+      testcase( i==121 ); /* ORDER */
+      testcase( i==122 ); /* RESTRICT */
+      testcase( i==123 ); /* OTHERS */
+      testcase( i==124 ); /* OVER */
+      testcase( i==125 ); /* RIGHT */
+      testcase( i==126 ); /* ROLLBACK */
+      testcase( i==127 ); /* ROWS */
+      testcase( i==128 ); /* ROW */
+      testcase( i==129 ); /* UNBOUNDED */
+      testcase( i==130 ); /* UNION */
+      testcase( i==131 ); /* USING */
+      testcase( i==132 ); /* VACUUM */
+      testcase( i==133 ); /* VIEW */
+      testcase( i==134 ); /* WINDOW */
+      testcase( i==135 ); /* DO */
+      testcase( i==136 ); /* BY */
+      testcase( i==137 ); /* INITIALLY */
+      testcase( i==138 ); /* ALL */
+      testcase( i==139 ); /* PRIMARY */
       *pType = aKWCode[i];
       break;
     }
@@ -150785,7 +154075,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
   keywordCode((char*)z, n, &id);
   return id;
 }
-#define SQLITE_N_KEYWORD 136
+#define SQLITE_N_KEYWORD 140
 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];
@@ -151218,6 +154508,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
   yyParser sEngine;    /* Space to hold the Lemon-generated Parser object */
 #endif
+  VVA_ONLY( u8 startedWithOom = db->mallocFailed );
 
   assert( zSql!=0 );
   mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -151227,7 +154518,14 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
   pParse->rc = SQLITE_OK;
   pParse->zTail = zSql;
   assert( pzErrMsg!=0 );
-  /* sqlite3ParserTrace(stdout, "parser: "); */
+#ifdef SQLITE_DEBUG
+  if( db->flags & SQLITE_ParserTrace ){
+    printf("parser: [[[%s]]]\n", zSql);
+    sqlite3ParserTrace(stdout, "parser: ");
+  }else{
+    sqlite3ParserTrace(0, 0);
+  }
+#endif
 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
   pEngine = &sEngine;
   sqlite3ParserInit(pEngine, pParse);
@@ -151242,6 +154540,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
   assert( pParse->pNewTrigger==0 );
   assert( pParse->nVar==0 );
   assert( pParse->pVList==0 );
+  pParse->pParentParse = db->pParse;
+  db->pParse = pParse;
   while( 1 ){
     n = sqlite3GetToken((u8*)zSql, &tokenType);
     mxSqlLen -= n;
@@ -151298,7 +154598,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
     sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
     lastTokenParsed = tokenType;
     zSql += n;
-    if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+    assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
+    if( pParse->rc!=SQLITE_OK ) break;
   }
   assert( nErr==0 );
 #ifdef YYTRACKMAXSTACKDEPTH
@@ -151366,10 +154667,147 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
     pParse->pZombieTab = p->pNextZombie;
     sqlite3DeleteTable(db, p);
   }
+  db->pParse = pParse->pParentParse;
+  pParse->pParentParse = 0;
   assert( nErr==0 || pParse->rc!=SQLITE_OK );
   return nErr;
 }
 
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Insert a single space character into pStr if the current string
+** ends with an identifier
+*/
+static void addSpaceSeparator(sqlite3_str *pStr){
+  if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){
+    sqlite3_str_append(pStr, " ", 1);
+  }
+}
+
+/*
+** Compute a normalization of the SQL given by zSql[0..nSql-1].  Return
+** the normalization in space obtained from sqlite3DbMalloc().  Or return
+** NULL if anything goes wrong or if zSql is NULL.
+*/
+SQLITE_PRIVATE char *sqlite3Normalize(
+  Vdbe *pVdbe,       /* VM being reprepared */
+  const char *zSql   /* The original SQL string */
+){
+  sqlite3 *db;       /* The database connection */
+  int i;             /* Next unread byte of zSql[] */
+  int n;             /* length of current token */
+  int tokenType;     /* type of current token */
+  int prevType = 0;  /* Previous non-whitespace token */
+  int nParen;        /* Number of nested levels of parentheses */
+  int iStartIN;      /* Start of RHS of IN operator in z[] */
+  int nParenAtIN;    /* Value of nParent at start of RHS of IN operator */
+  int j;             /* Bytes of normalized SQL generated so far */
+  sqlite3_str *pStr; /* The normalized SQL string under construction */
+
+  db = sqlite3VdbeDb(pVdbe);
+  tokenType = -1;
+  nParen = iStartIN = nParenAtIN = 0;
+  pStr = sqlite3_str_new(db);
+  assert( pStr!=0 );  /* sqlite3_str_new() never returns NULL */
+  for(i=0; zSql[i] && pStr->accError==0; i+=n){
+    if( tokenType!=TK_SPACE ){
+      prevType = tokenType;
+    }
+    n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
+    if( NEVER(n<=0) ) break;
+    switch( tokenType ){
+      case TK_SPACE: {
+        break;
+      }
+      case TK_NULL: {
+        if( prevType==TK_IS || prevType==TK_NOT ){
+          sqlite3_str_append(pStr, " NULL", 5);
+          break;
+        }
+        /* Fall through */
+      }
+      case TK_STRING:
+      case TK_INTEGER:
+      case TK_FLOAT:
+      case TK_VARIABLE:
+      case TK_BLOB: {
+        sqlite3_str_append(pStr, "?", 1);
+        break;
+      }
+      case TK_LP: {
+        nParen++;
+        if( prevType==TK_IN ){
+          iStartIN = pStr->nChar;
+          nParenAtIN = nParen;
+        }
+        sqlite3_str_append(pStr, "(", 1);
+        break;
+      }
+      case TK_RP: {
+        if( iStartIN>0 && nParen==nParenAtIN ){
+          assert( pStr->nChar>=iStartIN );
+          pStr->nChar = iStartIN+1;
+          sqlite3_str_append(pStr, "?,?,?", 5);
+          iStartIN = 0;
+        }
+        nParen--;
+        sqlite3_str_append(pStr, ")", 1);
+        break;
+      }
+      case TK_ID: {
+        iStartIN = 0;
+        j = pStr->nChar;
+        if( sqlite3Isquote(zSql[i]) ){
+          char *zId = sqlite3DbStrNDup(db, zSql+i, n);
+          int nId;
+          int eType = 0;
+          if( zId==0 ) break;
+          sqlite3Dequote(zId);
+          if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){
+            sqlite3_str_append(pStr, "?", 1);
+            sqlite3DbFree(db, zId);
+            break;
+          }
+          nId = sqlite3Strlen30(zId);
+          if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){
+            addSpaceSeparator(pStr);
+            sqlite3_str_append(pStr, zId, nId);
+          }else{
+            sqlite3_str_appendf(pStr, "\"%w\"", zId);
+          }
+          sqlite3DbFree(db, zId);
+        }else{
+          addSpaceSeparator(pStr);
+          sqlite3_str_append(pStr, zSql+i, n);
+        }
+        while( j<pStr->nChar ){
+          pStr->zText[j] = sqlite3Tolower(pStr->zText[j]);
+          j++;
+        }
+        break;
+      }
+      case TK_SELECT: {
+        iStartIN = 0;
+        /* fall through */
+      }
+      default: {
+        if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr);
+        j = pStr->nChar;
+        sqlite3_str_append(pStr, zSql+i, n);
+        while( j<pStr->nChar ){
+          pStr->zText[j] = sqlite3Toupper(pStr->zText[j]);
+          j++;
+        }
+        break;
+      }
+    }
+  }
+  if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1);
+  return sqlite3_str_finish(pStr);
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
 /************** End of tokenize.c ********************************************/
 /************** Begin file complete.c ****************************************/
 /*
@@ -152415,6 +155853,13 @@ SQLITE_API int sqlite3_config(int op, ...){
     }
 #endif /* SQLITE_ENABLE_SORTER_REFERENCES */
 
+#ifdef SQLITE_ENABLE_DESERIALIZE
+    case SQLITE_CONFIG_MEMDB_MAXSIZE: {
+      sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
+      break;
+    }
+#endif /* SQLITE_ENABLE_DESERIALIZE */
+
     default: {
       rc = SQLITE_ERROR;
       break;
@@ -152460,7 +155905,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
     pStart = 0;
   }else if( pBuf==0 ){
     sqlite3BeginBenignMalloc();
-    pStart = sqlite3Malloc( sz*cnt );  /* IMP: R-61949-35727 */
+    pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt );  /* IMP: R-61949-35727 */
     sqlite3EndBenignMalloc();
     if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
   }else{
@@ -152597,6 +156042,12 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
         { SQLITE_DBCONFIG_ENABLE_QPSG,           SQLITE_EnableQPSG     },
         { SQLITE_DBCONFIG_TRIGGER_EQP,           SQLITE_TriggerEQP     },
         { SQLITE_DBCONFIG_RESET_DATABASE,        SQLITE_ResetDatabase  },
+        { SQLITE_DBCONFIG_DEFENSIVE,             SQLITE_Defensive      },
+        { SQLITE_DBCONFIG_WRITABLE_SCHEMA,       SQLITE_WriteSchema|
+                                                 SQLITE_NoSchemaError  },
+        { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE,    SQLITE_LegacyAlter    },
+        { SQLITE_DBCONFIG_DQS_DDL,               SQLITE_DqsDDL         },
+        { SQLITE_DBCONFIG_DQS_DML,               SQLITE_DqsDML         },
       };
       unsigned int i;
       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -152604,11 +156055,11 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
         if( aFlagOp[i].op==op ){
           int onoff = va_arg(ap, int);
           int *pRes = va_arg(ap, int*);
-          u32 oldFlags = db->flags;
+          u64 oldFlags = db->flags;
           if( onoff>0 ){
             db->flags |= aFlagOp[i].mask;
           }else if( onoff==0 ){
-            db->flags &= ~aFlagOp[i].mask;
+            db->flags &= ~(u64)aFlagOp[i].mask;
           }
           if( oldFlags!=db->flags ){
             sqlite3ExpirePreparedStatements(db, 0);
@@ -152627,28 +156078,17 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
   return rc;
 }
 
-
-/*
-** Return true if the buffer z[0..n-1] contains all spaces.
-*/
-static int allSpaces(const char *z, int n){
-  while( n>0 && z[n-1]==' ' ){ n--; }
-  return n==0;
-}
-
 /*
 ** This is the default collating function named "BINARY" which is always
 ** available.
-**
-** If the padFlag argument is not NULL then space padding at the end
-** of strings is ignored.  This implements the RTRIM collation.
 */
 static int binCollFunc(
-  void *padFlag,
+  void *NotUsed,
   int nKey1, const void *pKey1,
   int nKey2, const void *pKey2
 ){
   int rc, n;
+  UNUSED_PARAMETER(NotUsed);
   n = nKey1<nKey2 ? nKey1 : nKey2;
   /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
   ** strings byte by byte using the memcmp() function from the standard C
@@ -152656,29 +156096,33 @@ static int binCollFunc(
   assert( pKey1 && pKey2 );
   rc = memcmp(pKey1, pKey2, n);
   if( rc==0 ){
-    if( padFlag
-     && allSpaces(((char*)pKey1)+n, nKey1-n)
-     && allSpaces(((char*)pKey2)+n, nKey2-n)
-    ){
-      /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
-      ** spaces at the end of either string do not change the result. In other
-      ** words, strings will compare equal to one another as long as they
-      ** differ only in the number of spaces at the end.
-      */
-    }else{
-      rc = nKey1 - nKey2;
-    }
+    rc = nKey1 - nKey2;
   }
   return rc;
 }
 
+/*
+** This is the collating function named "RTRIM" which is always
+** available.  Ignore trailing spaces.
+*/
+static int rtrimCollFunc(
+  void *pUser,
+  int nKey1, const void *pKey1,
+  int nKey2, const void *pKey2
+){
+  const u8 *pK1 = (const u8*)pKey1;
+  const u8 *pK2 = (const u8*)pKey2;
+  while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--;
+  while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--;
+  return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2);
+}
+
 /*
 ** 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);
+  assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
+  return p==0 || p->xCmp==binCollFunc;
 }
 
 /*
@@ -153071,7 +156515,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   /* Any deferred constraint violations have now been resolved. */
   db->nDeferredCons = 0;
   db->nDeferredImmCons = 0;
-  db->flags &= ~SQLITE_DeferFKs;
+  db->flags &= ~(u64)SQLITE_DeferFKs;
 
   /* If one has been configured, invoke the rollback-hook callback */
   if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -153813,6 +157257,8 @@ SQLITE_API void *sqlite3_profile(
   pOld = db->pProfileArg;
   db->xProfile = xProfile;
   db->pProfileArg = pArg;
+  db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK;
+  if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE;
   sqlite3_mutex_leave(db->mutex);
   return pOld;
 }
@@ -154164,7 +157610,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
     z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
   }else{
     testcase( db->pErr==0 );
-    z = (char*)sqlite3_value_text(db->pErr);
+    z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0;
     assert( !db->mallocFailed );
     if( z==0 ){
       z = sqlite3ErrStr(db->errCode);
@@ -154694,6 +158140,40 @@ SQLITE_PRIVATE int sqlite3ParseUri(
   return rc;
 }
 
+#if defined(SQLITE_HAS_CODEC)
+/*
+** Process URI filename query parameters relevant to the SQLite Encryption
+** Extension.  Return true if any of the relevant query parameters are
+** seen and return false if not.
+*/
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(
+  sqlite3 *db,           /* Database connection */
+  const char *zDb,       /* Which schema is being created/attached */
+  const char *zUri       /* URI filename */
+){
+  const char *zKey;
+  if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){
+    u8 iByte;
+    int i;
+    char zDecoded[40];
+    for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
+      iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
+      if( (i&1)!=0 ) zDecoded[i/2] = iByte;
+    }
+    sqlite3_key_v2(db, zDb, zDecoded, i/2);
+    return 1;
+  }else if( (zKey = sqlite3_uri_parameter(zUri, "key"))!=0 ){
+    sqlite3_key_v2(db, zDb, zKey, sqlite3Strlen30(zKey));
+    return 1;
+  }else if( (zKey = sqlite3_uri_parameter(zUri, "textkey"))!=0 ){
+    sqlite3_key_v2(db, zDb, zKey, -1);
+    return 1;
+  }else{
+    return 0;
+  }
+}
+#endif
+
 
 /*
 ** This routine does the work of opening a database on behalf of
@@ -154793,7 +158273,35 @@ static int openDatabase(
   db->szMmap = sqlite3GlobalConfig.szMmap;
   db->nextPagesize = 0;
   db->nMaxSorterMmap = 0x7FFFFFFF;
-  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+  db->flags |= SQLITE_ShortColNames
+                 | SQLITE_EnableTrigger
+                 | SQLITE_CacheSpill
+
+/* The SQLITE_DQS compile-time option determines the default settings
+** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
+**
+**    SQLITE_DQS     SQLITE_DBCONFIG_DQS_DDL    SQLITE_DBCONFIG_DQS_DML
+**    ----------     -----------------------    -----------------------
+**     undefined               on                          on   
+**         3                   on                          on
+**         2                   on                         off
+**         1                  off                          on
+**         0                  off                         off
+**
+** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
+** and so that is the default.  But developers are encouranged to use
+** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
+*/
+#if !defined(SQLITE_DQS)
+# define SQLITE_DQS 3
+#endif
+#if (SQLITE_DQS&1)==1
+                 | SQLITE_DqsDML
+#endif
+#if (SQLITE_DQS&2)==2
+                 | SQLITE_DqsDDL
+#endif
+
 #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
                  | SQLITE_AutoIndex
 #endif
@@ -154823,6 +158331,9 @@ static int openDatabase(
 #endif
 #if defined(SQLITE_ENABLE_QPSG)
                  | SQLITE_EnableQPSG
+#endif
+#if defined(SQLITE_DEFAULT_DEFENSIVE)
+                 | SQLITE_Defensive
 #endif
       ;
   sqlite3HashInit(&db->aCollSeq);
@@ -154841,7 +158352,7 @@ static int openDatabase(
   createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
   createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
   createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
-  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
+  createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
   if( db->mallocFailed ){
     goto opendb_out;
   }
@@ -155036,26 +158547,13 @@ opendb_out:
   }
 #endif
 #if defined(SQLITE_HAS_CODEC)
-  if( rc==SQLITE_OK ){
-    const char *zKey;
-    if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
-      u8 iByte;
-      int i;
-      char zDecoded[40];
-      for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){
-        iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
-        if( (i&1)!=0 ) zDecoded[i/2] = iByte;
-      }
-      sqlite3_key_v2(db, 0, zDecoded, i/2);
-    }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){
-      sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey));
-    }
-  }
+  if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen);
 #endif
   sqlite3_free(zOpen);
   return rc & 0xff;
 }
 
+
 /*
 ** Open a new database handle.
 */
@@ -155711,15 +159209,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){
 
     /*   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.
+    ** If parameter onoff is non-zero, subsequent calls to localtime()
+    ** and its 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_INTERNAL_FUNCS, int onoff);
+    **
+    ** 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_INTERNAL_FUNCTIONS: {
+      sqlite3GlobalConfig.bInternalFunctions = 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-
@@ -155819,6 +159328,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
       break;
     }
 #endif /* defined(YYCOVERAGE) */
+
+    /*  sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*);
+    **
+    ** This test-control causes the most recent sqlite3_result_int64() value
+    ** to be interpreted as a MEM_IntReal instead of as an MEM_Int.  Normally,
+    ** MEM_IntReal values only arise during an INSERT operation of integer
+    ** values into a REAL column, so they can be challenging to test.  This
+    ** test-control enables us to write an intreal() SQL function that can
+    ** inject an intreal() value at arbitrary places in an SQL statement,
+    ** for testing purposes.
+    */
+    case SQLITE_TESTCTRL_RESULT_INTREAL: {
+      sqlite3_context *pCtx = va_arg(ap, sqlite3_context*);
+      sqlite3ResultIntReal(pCtx);
+      break;
+    }
   }
   va_end(ap);
 #endif /* SQLITE_UNTESTABLE */
@@ -157105,6 +160630,8 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
 */
 #define FTS3_VARINT_MAX 10
 
+#define FTS3_BUFFER_PADDING 8
+
 /*
 ** FTS4 virtual tables may maintain multiple indexes - one index of all terms
 ** in the document set and zero or more prefix indexes. All indexes are stored
@@ -157137,6 +160664,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
 #define POS_COLUMN  (1)     /* Column-list terminator */
 #define POS_END     (0)     /* Position-list terminator */ 
 
+/*
+** The assert_fts3_nc() macro is similar to the assert() macro, except that it
+** is used for assert() conditions that are true only if it can be 
+** guranteed that the database is not corrupt.
+*/
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+SQLITE_API extern int sqlite3_fts3_may_be_corrupt;
+# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x))
+#else
+# define assert_fts3_nc(x) assert(x)
+#endif
+
 /*
 ** This section provides definitions to allow the
 ** FTS3 extension to be compiled outside of the 
@@ -157661,6 +161200,14 @@ SQLITE_PRIVATE int sqlite3Fts3Never(int b)  { assert( !b ); return b; }
 # endif
 #endif
 
+/*
+** This variable is set to false when running tests for which the on disk
+** structures should not be corrupt. Otherwise, true. If it is false, extra
+** assert() conditions in the fts3 code are activated - conditions that are
+** only true if it is guaranteed that the fts3 database is not corrupt.
+*/
+SQLITE_API int sqlite3_fts3_may_be_corrupt = 1;
+
 /* 
 ** Write a 64-bit variable-length integer to memory starting at p[0].
 ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -157679,7 +161226,7 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
 }
 
 #define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
-  v = (v & mask1) | ( (*ptr++) << shift );                    \
+  v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift );  \
   if( (v & mask2)==0 ){ var = v; return ret; }
 #define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
   v = (*ptr++);                                               \
@@ -157717,20 +161264,21 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
 ** a non-negative 32-bit integer before it is returned.
 */
 SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
+  const unsigned char *ptr = (const unsigned char*)p;
   u32 a;
 
 #ifndef fts3GetVarint32
-  GETVARINT_INIT(a, p, 0,  0x00,     0x80, *pi, 1);
+  GETVARINT_INIT(a, ptr, 0,  0x00,     0x80, *pi, 1);
 #else
-  a = (*p++);
+  a = (*ptr++);
   assert( a & 0x80 );
 #endif
 
-  GETVARINT_STEP(a, p, 7,  0x7F,     0x4000, *pi, 2);
-  GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *pi, 3);
-  GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
+  GETVARINT_STEP(a, ptr, 7,  0x7F,     0x4000, *pi, 2);
+  GETVARINT_STEP(a, ptr, 14, 0x3FFF,   0x200000, *pi, 3);
+  GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
   a = (a & 0x0FFFFFFF );
-  *pi = (int)(a | ((u32)(*p & 0x07) << 28));
+  *pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
   assert( 0==(a & 0x80000000) );
   assert( *pi>=0 );
   return 5;
@@ -157901,13 +161449,18 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){
   sqlite3 *db = p->db;             /* Database handle */
 
   /* Drop the shadow tables */
-  if( p->zContentTbl==0 ){
-    fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
-  }
-  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
-  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
-  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
-  fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
+  fts3DbExec(&rc, db, 
+    "DROP TABLE IF EXISTS %Q.'%q_segments';"
+    "DROP TABLE IF EXISTS %Q.'%q_segdir';"
+    "DROP TABLE IF EXISTS %Q.'%q_docsize';"
+    "DROP TABLE IF EXISTS %Q.'%q_stat';"
+    "%s DROP TABLE IF EXISTS %Q.'%q_content';",
+    zDb, p->zName,
+    zDb, p->zName,
+    zDb, p->zName,
+    zDb, p->zName,
+    (p->zContentTbl ? "--" : ""), zDb,p->zName
+  );
 
   /* If everything has worked, invoke fts3DisconnectMethod() to free the
   ** memory associated with the Fts3Table structure and return SQLITE_OK.
@@ -158139,10 +161692,10 @@ static void fts3Appendf(
 ** memory.
 */
 static char *fts3QuoteId(char const *zInput){
-  int nRet;
+  sqlite3_int64 nRet;
   char *zRet;
   nRet = 2 + (int)strlen(zInput)*2 + 1;
-  zRet = sqlite3_malloc(nRet);
+  zRet = sqlite3_malloc64(nRet);
   if( zRet ){
     int i;
     char *z = zRet;
@@ -158323,7 +161876,7 @@ static int fts3PrefixParameter(
     }
   }
 
-  aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
+  aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex);
   *apIndex = aIndex;
   if( !aIndex ){
     return SQLITE_NOMEM;
@@ -158402,7 +161955,7 @@ static int fts3ContentColumns(
 
   if( rc==SQLITE_OK ){
     const char **azCol;           /* Output array */
-    int nStr = 0;                 /* Size of all column names (incl. 0x00) */
+    sqlite3_int64 nStr = 0;       /* Size of all column names (incl. 0x00) */
     int nCol;                     /* Number of table columns */
     int i;                        /* Used to iterate through columns */
 
@@ -158412,11 +161965,11 @@ static int fts3ContentColumns(
     nCol = sqlite3_column_count(pStmt);
     for(i=0; i<nCol; i++){
       const char *zCol = sqlite3_column_name(pStmt, i);
-      nStr += (int)strlen(zCol) + 1;
+      nStr += strlen(zCol) + 1;
     }
 
     /* Allocate and populate the array to return. */
-    azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
+    azCol = (const char **)sqlite3_malloc64(sizeof(char *) * nCol + nStr);
     if( azCol==0 ){
       rc = SQLITE_NOMEM;
     }else{
@@ -158464,7 +162017,7 @@ static int fts3InitVtab(
   Fts3Table *p = 0;               /* Pointer to allocated vtab */
   int rc = SQLITE_OK;             /* Return code */
   int i;                          /* Iterator variable */
-  int nByte;                      /* Size of allocation used for *p */
+  sqlite3_int64 nByte;            /* Size of allocation used for *p */
   int iCol;                       /* Column index */
   int nString = 0;                /* Bytes required to hold all column names */
   int nCol = 0;                   /* Number of columns in the FTS table */
@@ -158498,10 +162051,10 @@ static int fts3InitVtab(
   nName = (int)strlen(argv[2]) + 1;
 
   nByte = sizeof(const char *) * (argc-2);
-  aCol = (const char **)sqlite3_malloc(nByte);
+  aCol = (const char **)sqlite3_malloc64(nByte);
   if( aCol ){
     memset((void*)aCol, 0, nByte);
-    azNotindexed = (char **)sqlite3_malloc(nByte);
+    azNotindexed = (char **)sqlite3_malloc64(nByte);
   }
   if( azNotindexed ){
     memset(azNotindexed, 0, nByte);
@@ -158696,7 +162249,7 @@ static int fts3InitVtab(
           nName +                              /* zName */
           nDb +                                /* zDb */
           nString;                             /* Space for azColumn strings */
-  p = (Fts3Table*)sqlite3_malloc(nByte);
+  p = (Fts3Table*)sqlite3_malloc64(nByte);
   if( p==0 ){
     rc = SQLITE_NOMEM;
     goto fts3_init_out;
@@ -159162,7 +162715,7 @@ static int fts3ScanInteriorNode(
   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 */
 
@@ -159200,14 +162753,14 @@ static int fts3ScanInteriorNode(
     zCsr += fts3GetVarint32(zCsr, &nSuffix);
     
     assert( nPrefix>=0 && nSuffix>=0 );
-    if( &zCsr[nSuffix]>zEnd ){
+    if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){
       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;
@@ -159475,7 +163028,7 @@ static int fts3PutColNumber(char **pp, int iCol){
 ** updated appropriately.   The caller is responsible for insuring
 ** that there is enough space in *pp to hold the complete output.
 */
-static void fts3PoslistMerge(
+static int fts3PoslistMerge(
   char **pp,                      /* Output buffer */
   char **pp1,                     /* Left input list */
   char **pp2                      /* Right input list */
@@ -159488,11 +163041,17 @@ static void fts3PoslistMerge(
     int iCol1;         /* The current column index in pp1 */
     int iCol2;         /* The current column index in pp2 */
 
-    if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
+    if( *p1==POS_COLUMN ){ 
+      fts3GetVarint32(&p1[1], &iCol1);
+      if( iCol1==0 ) return FTS_CORRUPT_VTAB;
+    }
     else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
     else iCol1 = 0;
 
-    if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
+    if( *p2==POS_COLUMN ){
+      fts3GetVarint32(&p2[1], &iCol2);
+      if( iCol2==0 ) return FTS_CORRUPT_VTAB;
+    }
     else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
     else iCol2 = 0;
 
@@ -159540,6 +163099,7 @@ static void fts3PoslistMerge(
   *pp = p;
   *pp1 = p1 + 1;
   *pp2 = p2 + 1;
+  return SQLITE_OK;
 }
 
 /*
@@ -159604,10 +163164,9 @@ static int fts3PoslistPhraseMerge(
         p += sqlite3Fts3PutVarint(p, iCol1);
       }
 
-      assert( *p1!=POS_END && *p1!=POS_COLUMN );
-      assert( *p2!=POS_END && *p2!=POS_COLUMN );
       fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
       fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
+      if( iPos1<0 || iPos2<0 ) break;
 
       while( 1 ){
         if( iPos2==iPos1+nToken 
@@ -159833,6 +163392,7 @@ static int fts3DoclistOrMerge(
   char *a2, int n2,               /* Second doclist */
   char **paOut, int *pnOut        /* OUT: Malloc'd doclist */
 ){
+  int rc = SQLITE_OK;
   sqlite3_int64 i1 = 0;
   sqlite3_int64 i2 = 0;
   sqlite3_int64 iPrev = 0;
@@ -159876,7 +163436,7 @@ static int fts3DoclistOrMerge(
   ** A symetric argument may be made if the doclists are in descending 
   ** order.
   */
-  aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1);
+  aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING);
   if( !aOut ) return SQLITE_NOMEM;
 
   p = aOut;
@@ -159887,7 +163447,8 @@ static int fts3DoclistOrMerge(
 
     if( p2 && p1 && iDiff==0 ){
       fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
-      fts3PoslistMerge(&p, &p1, &p2);
+      rc = fts3PoslistMerge(&p, &p1, &p2);
+      if( rc ) break;
       fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
       fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
     }else if( !p2 || (p1 && iDiff<0) ){
@@ -159901,10 +163462,16 @@ static int fts3DoclistOrMerge(
     }
   }
 
+  if( rc!=SQLITE_OK ){
+    sqlite3_free(aOut);
+    p = aOut = 0;
+  }else{
+    assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );
+    memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING);
+  }
   *paOut = aOut;
   *pnOut = (int)(p-aOut);
-  assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 );
-  return SQLITE_OK;
+  return rc;
 }
 
 /*
@@ -159939,7 +163506,7 @@ static int fts3DoclistPhraseMerge(
 
   assert( nDist>0 );
   if( bDescDoclist ){
-    aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
+    aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX);
     if( aOut==0 ) return SQLITE_NOMEM;
   }else{
     aOut = aRight;
@@ -160123,6 +163690,7 @@ static int fts3TermSelectMerge(
     pTS->anOutput[0] = nDoclist;
     if( pTS->aaOutput[0] ){
       memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
+      memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
     }else{
       return SQLITE_NOMEM;
     }
@@ -160174,8 +163742,8 @@ static int fts3SegReaderCursorAppend(
 ){
   if( (pCsr->nSegment%16)==0 ){
     Fts3SegReader **apNew;
-    int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
-    apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte);
+    sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
+    apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte);
     if( !apNew ){
       sqlite3Fts3SegReaderFree(pNew);
       return SQLITE_NOMEM;
@@ -160239,7 +163807,7 @@ static int fts3SegReaderCursor(
 
       /* If zTerm is not NULL, and this segment is not stored entirely on its
       ** root node, the range of leaves scanned can be reduced. Do this. */
-      if( iStartBlock && zTerm ){
+      if( iStartBlock && zTerm && zRoot ){
         sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0);
         rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi);
         if( rc!=SQLITE_OK ) goto finished;
@@ -161181,14 +164749,28 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
   Fts3Table *p = (Fts3Table*)pVtab;
   UNUSED_PARAMETER(iSavepoint);
   assert( p->inTransaction );
-  assert( p->mxSavepoint >= iSavepoint );
   TESTONLY( p->mxSavepoint = iSavepoint );
   sqlite3Fts3PendingTermsClear(p);
   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,
@@ -161211,6 +164793,7 @@ static const sqlite3_module fts3Module = {
   /* xSavepoint    */ fts3SavepointMethod,
   /* xRelease      */ fts3ReleaseMethod,
   /* xRollbackTo   */ fts3RollbackToMethod,
+  /* xShadowName   */ fts3ShadowName,
 };
 
 /*
@@ -161491,6 +165074,7 @@ static int fts3EvalPhraseLoad(
   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
@@ -161594,6 +165178,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
 
   return SQLITE_OK;
 }
+#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
 
 /*
 ** Maximum number of tokens a phrase may have to be considered for the
@@ -161938,9 +165523,10 @@ static int fts3EvalIncrPhraseNext(
       if( bEof==0 ){
         int nList = 0;
         int nByte = a[p->nToken-1].nList;
-        char *aDoclist = sqlite3_malloc(nByte+1);
+        char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
         if( !aDoclist ) return SQLITE_NOMEM;
         memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
+        memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
 
         for(i=0; i<(p->nToken-1); i++){
           if( a[i].bIgnore==0 ){
@@ -162331,7 +165917,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
   if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
     Fts3TokenAndCost *aTC;
     Fts3Expr **apOr;
-    aTC = (Fts3TokenAndCost *)sqlite3_malloc(
+    aTC = (Fts3TokenAndCost *)sqlite3_malloc64(
         sizeof(Fts3TokenAndCost) * nToken
       + sizeof(Fts3Expr *) * nOr * 2
     );
@@ -162642,7 +166228,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
    && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
   ){
     Fts3Expr *p; 
-    int nTmp = 0;                 /* Bytes of temp space */
+    sqlite3_int64 nTmp = 0;       /* Bytes of temp space */
     char *aTmp;                   /* Temp space for PoslistNearMerge() */
 
     /* Allocate temporary working space. */
@@ -162651,7 +166237,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
       nTmp += p->pRight->pPhrase->doclist.nList;
     }
     nTmp += p->pPhrase->doclist.nList;
-    aTmp = sqlite3_malloc(nTmp*2);
+    aTmp = sqlite3_malloc64(nTmp*2);
     if( !aTmp ){
       *pRc = SQLITE_NOMEM;
       res = 0;
@@ -162921,15 +166507,14 @@ static void fts3EvalRestart(
 ** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase 
 ** expression nodes.
 */
-static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
+static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
   if( pExpr ){
     Fts3Phrase *pPhrase = pExpr->pPhrase;
     if( pPhrase && pPhrase->doclist.pList ){
       int iCol = 0;
       char *p = pPhrase->doclist.pList;
 
-      assert( *p );
-      while( 1 ){
+      do{
         u8 c = 0;
         int iCnt = 0;
         while( 0xFE & (*p | c) ){
@@ -162945,11 +166530,11 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
         if( *p==0x00 ) break;
         p++;
         p += fts3GetVarint32(p, &iCol);
-      }
+      }while( iCol<nCol );
     }
 
-    fts3EvalUpdateCounts(pExpr->pLeft);
-    fts3EvalUpdateCounts(pExpr->pRight);
+    fts3EvalUpdateCounts(pExpr->pLeft, nCol);
+    fts3EvalUpdateCounts(pExpr->pRight, nCol);
   }
 }
 
@@ -162993,7 +166578,7 @@ static int fts3EvalGatherStats(
     for(p=pRoot; p; p=p->pLeft){
       Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
       assert( pE->aMI==0 );
-      pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32));
+      pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
       if( !pE->aMI ) return SQLITE_NOMEM;
       memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
     }
@@ -163019,7 +166604,7 @@ static int fts3EvalGatherStats(
       );
 
       if( rc==SQLITE_OK && pCsr->isEof==0 ){
-        fts3EvalUpdateCounts(pRoot);
+        fts3EvalUpdateCounts(pRoot, pTab->nColumn);
       }
     }
 
@@ -163369,7 +166954,7 @@ static int fts3auxConnectMethod(
   char const *zFts3;              /* Name of fts3 table */
   int nDb;                        /* Result of strlen(zDb) */
   int nFts3;                      /* Result of strlen(zFts3) */
-  int nByte;                      /* Bytes of space to allocate here */
+  sqlite3_int64 nByte;            /* Bytes of space to allocate here */
   int rc;                         /* value returned by declare_vtab() */
   Fts3auxTable *p;                /* Virtual table object to return */
 
@@ -163401,7 +166986,7 @@ static int fts3auxConnectMethod(
   if( rc!=SQLITE_OK ) return rc;
 
   nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
-  p = (Fts3auxTable *)sqlite3_malloc(nByte);
+  p = (Fts3auxTable *)sqlite3_malloc64(nByte);
   if( !p ) return SQLITE_NOMEM;
   memset(p, 0, nByte);
 
@@ -163551,7 +167136,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
 static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
   if( nSize>pCsr->nStat ){
     struct Fts3auxColstats *aNew;
-    aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat, 
+    aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat, 
         sizeof(struct Fts3auxColstats) * nSize
     );
     if( aNew==0 ) return SQLITE_NOMEM;
@@ -163719,15 +167304,15 @@ static int fts3auxFilterMethod(
     assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
     if( zStr ){
       pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
-      pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
       if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
+      pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm);
     }
   }
 
   if( iLe>=0 ){
     pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
-    pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
     if( pCsr->zStop==0 ) return SQLITE_NOMEM;
+    pCsr->nStop = (int)strlen(pCsr->zStop);
   }
   
   if( iLangid>=0 ){
@@ -163842,7 +167427,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){
      0,                           /* xRename       */
      0,                           /* xSavepoint    */
      0,                           /* xRelease      */
-     0                            /* xRollbackTo   */
+     0,                           /* xRollbackTo   */
+     0                            /* xShadowName   */
   };
   int rc;                         /* Return code */
 
@@ -163978,8 +167564,8 @@ static int fts3isspace(char c){
 ** zero the memory before returning a pointer to it. If unsuccessful, 
 ** return NULL.
 */
-static void *fts3MallocZero(int nByte){
-  void *pRet = sqlite3_malloc(nByte);
+static void *fts3MallocZero(sqlite3_int64 nByte){
+  void *pRet = sqlite3_malloc64(nByte);
   if( pRet ) memset(pRet, 0, nByte);
   return pRet;
 }
@@ -164054,7 +167640,7 @@ static int getNextToken(
   if( rc==SQLITE_OK ){
     const char *zToken;
     int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
-    int nByte;                               /* total space to allocate */
+    sqlite3_int64 nByte;                    /* total space to allocate */
 
     rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
     if( rc==SQLITE_OK ){
@@ -164108,8 +167694,8 @@ static int getNextToken(
 ** Enlarge a memory allocation.  If an out-of-memory allocation occurs,
 ** then free the old allocation.
 */
-static void *fts3ReallocOrFree(void *pOrig, int nNew){
-  void *pRet = sqlite3_realloc(pOrig, nNew);
+static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){
+  void *pRet = sqlite3_realloc64(pOrig, nNew);
   if( !pRet ){
     sqlite3_free(pOrig);
   }
@@ -164353,7 +167939,6 @@ static int getNextNode(
       int nConsumed = 0;
       pParse->nNest++;
       rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
-      if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
       *pnConsumed = (int)(zInput - z) + 1 + nConsumed;
       return rc;
     }else if( *zInput==')' ){
@@ -164652,7 +168237,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
   if( rc==SQLITE_OK ){
     if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
       Fts3Expr **apLeaf;
-      apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
+      apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
       if( 0==apLeaf ){
         rc = SQLITE_NOMEM;
       }else{
@@ -165072,7 +168657,7 @@ static void fts3ExprTestCommon(
   zExpr = (const char *)sqlite3_value_text(argv[1]);
   nExpr = sqlite3_value_bytes(argv[1]);
   nCol = argc-2;
-  azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
+  azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *));
   if( !azCol ){
     sqlite3_result_error_nomem(context);
     goto exprtest_out;
@@ -165186,8 +168771,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash
 /*
 ** Malloc and Free functions
 */
-static void *fts3HashMalloc(int n){
-  void *p = sqlite3_malloc(n);
+static void *fts3HashMalloc(sqlite3_int64 n){
+  void *p = sqlite3_malloc64(n);
   if( p ){
     memset(p, 0, n);
   }
@@ -166281,7 +169866,7 @@ static void fts3TokenizerFunc(
   nName = sqlite3_value_bytes(argv[0])+1;
 
   if( argc==2 ){
-    if( fts3TokenizerEnabled(context) ){
+    if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
       void *pOld;
       int n = sqlite3_value_bytes(argv[1]);
       if( zName==0 || n!=sizeof(pPtr) ){
@@ -166308,7 +169893,9 @@ static void fts3TokenizerFunc(
       return;
     }
   }
-  sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
+  if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){
+    sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
+  }
 }
 
 SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){
@@ -166396,8 +169983,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
     int iArg = 0;
     z = &z[n+1];
     while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){
-      int nNew = sizeof(char *)*(iArg+1);
-      char const **aNew = (const char **)sqlite3_realloc((void *)aArg, nNew);
+      sqlite3_int64 nNew = sizeof(char *)*(iArg+1);
+      char const **aNew = (const char **)sqlite3_realloc64((void *)aArg, nNew);
       if( !aNew ){
         sqlite3_free(zCopy);
         sqlite3_free((void *)aArg);
@@ -167080,7 +170667,7 @@ static int fts3tokDequoteArray(
       nByte += (int)(strlen(argv[i]) + 1);
     }
 
-    *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte);
+    *pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte);
     if( azDequote==0 ){
       rc = SQLITE_NOMEM;
     }else{
@@ -167304,7 +170891,7 @@ static int fts3tokFilterMethod(
   if( idxNum==1 ){
     const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
     int nByte = sqlite3_value_bytes(apVal[0]);
-    pCsr->zInput = sqlite3_malloc(nByte+1);
+    pCsr->zInput = sqlite3_malloc64(nByte+1);
     if( pCsr->zInput==0 ){
       rc = SQLITE_NOMEM;
     }else{
@@ -167401,7 +170988,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
      0,                           /* xRename       */
      0,                           /* xSavepoint    */
      0,                           /* xRelease      */
-     0                            /* xRollbackTo   */
+     0,                           /* xRollbackTo   */
+     0                            /* xShadowName   */
   };
   int rc;                         /* Return code */
 
@@ -167811,10 +171399,12 @@ static int fts3SqlStmt(
   
   pStmt = p->aStmt[eStmt];
   if( !pStmt ){
+    int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
     char *zSql;
     if( eStmt==SQL_CONTENT_INSERT ){
       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
     }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
+      f &= ~SQLITE_PREPARE_NO_VTAB;
       zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
     }else{
       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -167822,8 +171412,7 @@ static int fts3SqlStmt(
     if( !zSql ){
       rc = SQLITE_NOMEM;
     }else{
-      rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
-                              &pStmt, NULL);
+      rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
       sqlite3_free(zSql);
       assert( rc==SQLITE_OK || pStmt==0 );
       p->aStmt[eStmt] = pStmt;
@@ -167981,7 +171570,7 @@ static sqlite3_int64 getAbsoluteLevel(
   int iLevel                      /* Level of segments */
 ){
   sqlite3_int64 iBase;            /* First absolute level for iLangid/iIndex */
-  assert( iLangid>=0 );
+  assert_fts3_nc( iLangid>=0 );
   assert( p->nIndex>0 );
   assert( iIndex>=0 && iIndex<p->nIndex );
 
@@ -168762,7 +172351,9 @@ static int fts3SegReaderNext(
 
     /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf 
     ** blocks have already been traversed.  */
-    assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
+#ifdef CORRUPT_DB
+    assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock || CORRUPT_DB );
+#endif
     if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
       return SQLITE_OK;
     }
@@ -168789,15 +172380,19 @@ static int fts3SegReaderNext(
   ** 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;
     }
@@ -168819,7 +172414,7 @@ static int fts3SegReaderNext(
   ** 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->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
    || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
   ){
     return FTS_CORRUPT_VTAB;
@@ -169019,8 +172614,13 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
   Fts3SegReader *pReader;         /* Newly allocated SegReader object */
   int nExtra = 0;                 /* Bytes to allocate segment root node */
 
-  assert( iStartLeaf<=iEndLeaf );
+  assert( zRoot!=0 || nRoot==0 );
+#ifdef CORRUPT_DB
+  assert( zRoot!=0 || CORRUPT_DB );
+#endif
+
   if( iStartLeaf==0 ){
+    if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
     nExtra = nRoot + FTS3_NODE_PADDING;
   }
 
@@ -169040,7 +172640,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
     pReader->aNode = (char *)&pReader[1];
     pReader->rootOnly = 1;
     pReader->nNode = nRoot;
-    memcpy(pReader->aNode, zRoot, nRoot);
+    if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
     memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
   }else{
     pReader->iCurrentBlock = iStartLeaf-1;
@@ -169155,8 +172755,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
   }
 
   if( nElem>0 ){
-    int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
-    pReader = (Fts3SegReader *)sqlite3_malloc(nByte);
+    sqlite3_int64 nByte;
+    nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
+    pReader = (Fts3SegReader *)sqlite3_malloc64(nByte);
     if( !pReader ){
       rc = SQLITE_NOMEM;
     }else{
@@ -169660,6 +173261,11 @@ static int fts3SegWriterAdd(
   nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
   nSuffix = nTerm-nPrefix;
 
+  /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of 
+  ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
+  ** compared with BINARY collation. This indicates corruption.  */
+  if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
+
   /* Figure out how many bytes are required by this new entry */
   nReq = sqlite3Fts3VarintLen(nPrefix) +    /* varint containing prefix size */
     sqlite3Fts3VarintLen(nSuffix) +         /* varint containing suffix size */
@@ -170016,14 +173622,14 @@ static void fts3ColumnFilter(
 
     nList -= (int)(p - pList);
     pList = p;
-    if( nList==0 ){
+    if( nList<=0 ){
       break;
     }
     p = &pList[1];
     p += fts3GetVarint32(p, &iCurrent);
   }
 
-  if( bZero && &pList[nList]!=pEnd ){
+  if( bZero && (pEnd - &pList[nList])>0){
     memset(&pList[nList], 0, pEnd - &pList[nList]);
   }
   *ppList = pList;
@@ -170367,7 +173973,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
           }else{
             iDelta = iDocid - iPrev;
           }
-          assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
+          if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){
+            return FTS_CORRUPT_VTAB;
+          }
           assert( nDoclist>0 || iDelta==iDocid );
 
           nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
@@ -170633,8 +174241,10 @@ static int fts3SegmentMerge(
   if( rc!=SQLITE_OK ) goto finished;
 
   assert( csr.nSegment>0 );
-  assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
-  assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) );
+  assert_fts3_nc( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
+  assert_fts3_nc( 
+    iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) 
+  );
 
   memset(&filter, 0, sizeof(Fts3SegFilter));
   filter.flags = FTS3_SEGMENT_REQUIRE_POS;
@@ -170733,14 +174343,16 @@ static void fts3DecodeIntArray(
   const char *zBuf,  /* The BLOB containing the varints */
   int nBuf           /* size of the BLOB */
 ){
-  int i, j;
-  UNUSED_PARAMETER(nBuf);
-  for(i=j=0; i<N; i++){
-    sqlite3_int64 x;
-    j += sqlite3Fts3GetVarint(&zBuf[j], &x);
-    assert(j<=nBuf);
-    a[i] = (u32)(x & 0xffffffff);
+  int i = 0;
+  if( nBuf && (zBuf[nBuf-1]&0x80)==0 ){
+    int j;
+    for(i=j=0; i<N && j<nBuf; i++){
+      sqlite3_int64 x;
+      j += sqlite3Fts3GetVarint(&zBuf[j], &x);
+      a[i] = (u32)(x & 0xffffffff);
+    }
   }
+  while( i<N ) a[i++] = 0;
 }
 
 /*
@@ -170759,7 +174371,7 @@ static void fts3InsertDocsize(
   int rc;                  /* Result code from subfunctions */
 
   if( *pRC ) return;
-  pBlob = sqlite3_malloc( 10*p->nColumn );
+  pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn );
   if( pBlob==0 ){
     *pRC = SQLITE_NOMEM;
     return;
@@ -170809,7 +174421,7 @@ static void fts3UpdateDocTotals(
   const int nStat = p->nColumn+2;
 
   if( *pRC ) return;
-  a = sqlite3_malloc( (sizeof(u32)+10)*nStat );
+  a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat );
   if( a==0 ){
     *pRC = SQLITE_NOMEM;
     return;
@@ -170930,8 +174542,8 @@ static int fts3DoRebuild(Fts3Table *p){
     }
 
     if( rc==SQLITE_OK ){
-      int nByte = sizeof(u32) * (p->nColumn+1)*3;
-      aSz = (u32 *)sqlite3_malloc(nByte);
+      sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3;
+      aSz = (u32 *)sqlite3_malloc64(nByte);
       if( aSz==0 ){
         rc = SQLITE_NOMEM;
       }else{
@@ -170997,12 +174609,12 @@ static int fts3IncrmergeCsr(
 ){
   int rc;                         /* Return Code */
   sqlite3_stmt *pStmt = 0;        /* Statement used to read %_segdir entry */  
-  int nByte;                      /* Bytes allocated at pCsr->apSegment[] */
+  sqlite3_int64 nByte;            /* Bytes allocated at pCsr->apSegment[] */
 
   /* Allocate space for the Fts3MultiSegReader.aCsr[] array */
   memset(pCsr, 0, sizeof(*pCsr));
   nByte = sizeof(Fts3SegReader *) * nSeg;
-  pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte);
+  pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte);
 
   if( pCsr->apSegment==0 ){
     rc = SQLITE_NOMEM;
@@ -171145,6 +174757,9 @@ static int nodeReaderNext(NodeReader *p){
     }
     p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
 
+    if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
+      return FTS_CORRUPT_VTAB;
+    }
     blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
     if( rc==SQLITE_OK ){
       memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -171152,14 +174767,16 @@ static int nodeReaderNext(NodeReader *p){
       p->iOff += nSuffix;
       if( p->iChild==0 ){
         p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
+        if( (p->nNode-p->iOff)<p->nDoclist ){
+          return FTS_CORRUPT_VTAB;
+        }
         p->aDoclist = &p->aNode[p->iOff];
         p->iOff += p->nDoclist;
       }
     }
   }
 
-  assert( p->iOff<=p->nNode );
-
+  assert_fts3_nc( p->iOff<=p->nNode );
   return rc;
 }
 
@@ -171320,7 +174937,7 @@ static int fts3AppendToNode(
   /* Node must have already been started. There must be a doclist for a
   ** leaf node, and there must not be a doclist for an internal node.  */
   assert( pNode->n>0 );
-  assert( (pNode->a[0]=='\0')==(aDoclist!=0) );
+  assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) );
 
   blobGrowBuffer(pPrev, nTerm, &rc);
   if( rc!=SQLITE_OK ) return rc;
@@ -171536,7 +175153,7 @@ static int fts3TermCmp(
   int nCmp = MIN(nLhs, nRhs);
   int res;
 
-  res = memcmp(zLhs, zRhs, nCmp);
+  res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
   if( res==0 ) res = nLhs - nRhs;
 
   return res;
@@ -171668,10 +175285,13 @@ static int fts3IncrmergeLoad(
 
       pNode = &pWriter->aNodeWriter[nHeight];
       pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
-      blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
+      blobGrowBuffer(&pNode->block, 
+          MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+      );
       if( rc==SQLITE_OK ){
         memcpy(pNode->block.a, aRoot, nRoot);
         pNode->block.n = nRoot;
+        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
       }
 
       for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
@@ -171679,23 +175299,28 @@ static int fts3IncrmergeLoad(
         pNode = &pWriter->aNodeWriter[i];
 
         rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
-        while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
-        blobGrowBuffer(&pNode->key, reader.term.n, &rc);
-        if( rc==SQLITE_OK ){
-          memcpy(pNode->key.a, reader.term.a, reader.term.n);
-          pNode->key.n = reader.term.n;
-          if( i>0 ){
-            char *aBlock = 0;
-            int nBlock = 0;
-            pNode = &pWriter->aNodeWriter[i-1];
-            pNode->iBlock = reader.iChild;
-            rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
-            blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc);
-            if( rc==SQLITE_OK ){
-              memcpy(pNode->block.a, aBlock, nBlock);
-              pNode->block.n = nBlock;
+        if( reader.aNode ){
+          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
+          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
+          if( rc==SQLITE_OK ){
+            memcpy(pNode->key.a, reader.term.a, reader.term.n);
+            pNode->key.n = reader.term.n;
+            if( i>0 ){
+              char *aBlock = 0;
+              int nBlock = 0;
+              pNode = &pWriter->aNodeWriter[i-1];
+              pNode->iBlock = reader.iChild;
+              rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
+              blobGrowBuffer(&pNode->block, 
+                  MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+              );
+              if( rc==SQLITE_OK ){
+                memcpy(pNode->block.a, aBlock, nBlock);
+                pNode->block.n = nBlock;
+                memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
+              }
+              sqlite3_free(aBlock);
             }
-            sqlite3_free(aBlock);
           }
         }
         nodeReaderRelease(&reader);
@@ -171938,7 +175563,10 @@ static int fts3TruncateNode(
   NodeReader reader;              /* Reader object */
   Blob prev = {0, 0, 0};          /* Previous term written to new node */
   int rc = SQLITE_OK;             /* Return code */
-  int bLeaf = aNode[0]=='\0';     /* True for a leaf node */
+  int bLeaf;                       /* True for a leaf node */
+
+  if( nNode<1 ) return FTS_CORRUPT_VTAB;
+  bLeaf = aNode[0]=='\0';
 
   /* Allocate required output space */
   blobGrowBuffer(pNew, nNode, &rc);
@@ -172977,7 +176605,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
   }
 
   /* Allocate space to hold the change in document sizes */
-  aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
+  aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2);
   if( aSzDel==0 ){
     rc = SQLITE_NOMEM;
     goto update_out;
@@ -173231,17 +176859,19 @@ struct StrBuffer {
 /*
 ** Allocate a two-slot MatchinfoBuffer object.
 */
-static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
+static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
   MatchinfoBuffer *pRet;
-  int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
-  int nStr = (int)strlen(zMatchinfo);
+  sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
+                           + sizeof(MatchinfoBuffer);
+  sqlite3_int64 nStr = strlen(zMatchinfo);
 
-  pRet = sqlite3_malloc(nByte + nStr+1);
+  pRet = sqlite3_malloc64(nByte + nStr+1);
   if( pRet ){
     memset(pRet, 0, nByte);
     pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
-    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
-    pRet->nElem = nElem;
+    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
+                                      + sizeof(u32)*((int)nElem+1);
+    pRet->nElem = (int)nElem;
     pRet->zMatchinfo = ((char*)pRet) + nByte;
     memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
     pRet->aRef[0] = 1;
@@ -173281,7 +176911,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
     aOut = &p->aMatchinfo[p->nElem+2];
     xRet = fts3MIBufferFree;
   }else{
-    aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
+    aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
     if( aOut ){
       xRet = sqlite3_free;
       if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
@@ -173532,11 +177162,12 @@ static void fts3SnippetDetails(
       char *pCsr = pPhrase->pTail;
       int iCsr = pPhrase->iTail;
 
-      while( iCsr<(iStart+pIter->nSnippet) ){
+      while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
         int j;
         u64 mPhrase = (u64)1 << i;
         u64 mPos = (u64)1 << (iCsr - iStart);
-        assert( iCsr>=iStart );
+        assert( iCsr>=iStart && (iCsr - iStart)<=64 );
+        assert( i>=0 && i<=64 );
         if( (mCover|mCovered)&mPhrase ){
           iScore++;
         }else{
@@ -173578,11 +177209,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
     int iFirst = 0;
     pPhrase->pList = pCsr;
     fts3GetDeltaPosition(&pCsr, &iFirst);
-    assert( iFirst>=0 );
-    pPhrase->pHead = pCsr;
-    pPhrase->pTail = pCsr;
-    pPhrase->iHead = iFirst;
-    pPhrase->iTail = iFirst;
+    if( iFirst<0 ){
+      rc = FTS_CORRUPT_VTAB;
+    }else{
+      pPhrase->pHead = pCsr;
+      pPhrase->pTail = pCsr;
+      pPhrase->iHead = iFirst;
+      pPhrase->iTail = iFirst;
+    }
   }else{
     assert( rc!=SQLITE_OK || (
        pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 
@@ -173619,7 +177253,7 @@ static int fts3BestSnippet(
   int rc;                         /* Return Code */
   int nList;                      /* Number of phrases in expression */
   SnippetIter sIter;              /* Iterates through snippet candidates */
-  int nByte;                      /* Number of bytes of space to allocate */
+  sqlite3_int64 nByte;            /* Number of bytes of space to allocate */
   int iBestScore = -1;            /* Best snippet score found so far */
   int i;                          /* Loop counter */
 
@@ -173637,7 +177271,7 @@ static int fts3BestSnippet(
   ** the required space using malloc().
   */
   nByte = sizeof(SnippetPhrase) * nList;
-  sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
+  sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
   if( !sIter.aPhrase ){
     return SQLITE_NOMEM;
   }
@@ -173707,8 +177341,8 @@ static int fts3StringAppend(
   ** appended data.
   */
   if( pStr->n+nAppend+1>=pStr->nAlloc ){
-    int nAlloc = pStr->nAlloc+nAppend+100;
-    char *zNew = sqlite3_realloc(pStr->z, nAlloc);
+    sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
+    char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
     if( !zNew ){
       return SQLITE_NOMEM;
     }
@@ -173763,6 +177397,7 @@ static int fts3SnippetShift(
 
     for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
     for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
+    assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 );
     nDesired = (nLeft-nRight)/2;
 
     /* Ideally, the start of the snippet should be pushed forward in the
@@ -173955,7 +177590,7 @@ static int fts3ColumnlistCount(char **ppCollist){
 /*
 ** This function gathers 'y' or 'b' data for a single phrase.
 */
-static void fts3ExprLHits(
+static int fts3ExprLHits(
   Fts3Expr *pExpr,                /* Phrase expression node */
   MatchInfo *p                    /* Matchinfo context */
 ){
@@ -173985,25 +177620,29 @@ static void fts3ExprLHits(
     if( *pIter!=0x01 ) break;
     pIter++;
     pIter += fts3GetVarint32(pIter, &iCol);
+    if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB;
   }
+  return SQLITE_OK;
 }
 
 /*
 ** Gather the results for matchinfo directives 'y' and 'b'.
 */
-static void fts3ExprLHitGather(
+static int fts3ExprLHitGather(
   Fts3Expr *pExpr,
   MatchInfo *p
 ){
+  int rc = SQLITE_OK;
   assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
   if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
     if( pExpr->pLeft ){
-      fts3ExprLHitGather(pExpr->pLeft, p);
-      fts3ExprLHitGather(pExpr->pRight, p);
+      rc = fts3ExprLHitGather(pExpr->pLeft, p);
+      if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p);
     }else{
-      fts3ExprLHits(pExpr, p);
+      rc = fts3ExprLHits(pExpr, p);
     }
   }
+  return rc;
 }
 
 /*
@@ -174093,8 +177732,8 @@ static int fts3MatchinfoCheck(
   return SQLITE_ERROR;
 }
 
-static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
-  int nVal;                       /* Number of integers output by cArg */
+static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
+  size_t nVal;                      /* Number of integers output by cArg */
 
   switch( cArg ){
     case FTS3_MATCHINFO_NDOC:
@@ -174220,11 +177859,12 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
   int i;
   int iCol;
   int nToken = 0;
+  int rc = SQLITE_OK;
 
   /* Allocate and populate the array of LcsIterator objects. The array
   ** contains one element for each matchable phrase in the query.
   **/
-  aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
+  aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
   if( !aIter ) return SQLITE_NOMEM;
   memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
   (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
@@ -174240,13 +177880,16 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
     int nLive = 0;                /* Number of iterators in aIter not at EOF */
 
     for(i=0; i<pInfo->nPhrase; i++){
-      int rc;
       LcsIterator *pIt = &aIter[i];
       rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
-      if( rc!=SQLITE_OK ) return rc;
+      if( rc!=SQLITE_OK ) goto matchinfo_lcs_out;
       if( pIt->pRead ){
         pIt->iPos = pIt->iPosOffset;
-        fts3LcsIteratorAdvance(&aIter[i]);
+        fts3LcsIteratorAdvance(pIt);
+        if( pIt->pRead==0 ){
+          rc = FTS_CORRUPT_VTAB;
+          goto matchinfo_lcs_out;
+        }
         nLive++;
       }
     }
@@ -174278,8 +177921,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
     pInfo->aMatchinfo[iCol] = nLcs;
   }
 
+ matchinfo_lcs_out:
   sqlite3_free(aIter);
-  return SQLITE_OK;
+  return rc;
 }
 
 /*
@@ -174373,9 +178017,9 @@ static int fts3MatchinfoValues(
 
       case FTS3_MATCHINFO_LHITS_BM:
       case FTS3_MATCHINFO_LHITS: {
-        int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
+        size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
         memset(pInfo->aMatchinfo, 0, nZero);
-        fts3ExprLHitGather(pCsr->pExpr, pInfo);
+        rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
         break;
       }
 
@@ -174442,7 +178086,7 @@ static void fts3GetMatchinfo(
   ** initialize those elements that are constant for every row.
   */
   if( pCsr->pMIBuffer==0 ){
-    int nMatchinfo = 0;           /* Number of u32 elements in match-info */
+    size_t nMatchinfo = 0;        /* Number of u32 elements in match-info */
     int i;                        /* Used to iterate through zArg */
 
     /* Determine the number of phrases in the query */
@@ -174527,6 +178171,10 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
     return;
   }
 
+  /* Limit the snippet length to 64 tokens. */
+  if( nToken<-64 ) nToken = -64;
+  if( nToken>+64 ) nToken = +64;
+
   for(nSnippet=1; 1; nSnippet++){
 
     int iSnip;                    /* Loop counter 0..nSnippet-1 */
@@ -174628,7 +178276,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
   nTerm = pExpr->pPhrase->nToken;
   if( pList ){
     fts3GetDeltaPosition(&pList, &iPos);
-    assert( iPos>=0 );
+    assert_fts3_nc( iPos>=0 );
   }
 
   for(iTerm=0; iTerm<nTerm; iTerm++){
@@ -174669,7 +178317,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
   if( rc!=SQLITE_OK ) goto offsets_out;
 
   /* Allocate the array of TermOffset iterators. */
-  sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken);
+  sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
   if( 0==sCtx.aTerm ){
     rc = SQLITE_NOMEM;
     goto offsets_out;
@@ -174738,7 +178386,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
         /* All offsets for this column have been gathered. */
         rc = SQLITE_DONE;
       }else{
-        assert( iCurrent<=iMinPos );
+        assert_fts3_nc( iCurrent<=iMinPos );
         if( 0==(0xFE&*pTerm->pList) ){
           pTerm->pList = 0;
         }else{
@@ -174894,7 +178542,7 @@ typedef struct unicode_cursor unicode_cursor;
 
 struct unicode_tokenizer {
   sqlite3_tokenizer base;
-  int bRemoveDiacritic;
+  int eRemoveDiacritic;
   int nException;
   int *aiException;
 };
@@ -174967,7 +178615,7 @@ static int unicodeAddExceptions(
     int *aNew;                    /* New aiException[] array */
     int nNew;                     /* Number of valid entries in array aNew[] */
 
-    aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
+    aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int));
     if( aNew==0 ) return SQLITE_NOMEM;
     nNew = p->nException;
 
@@ -175039,17 +178687,20 @@ static int unicodeCreate(
   pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
   if( pNew==NULL ) return SQLITE_NOMEM;
   memset(pNew, 0, sizeof(unicode_tokenizer));
-  pNew->bRemoveDiacritic = 1;
+  pNew->eRemoveDiacritic = 1;
 
   for(i=0; rc==SQLITE_OK && i<nArg; i++){
     const char *z = azArg[i];
     int n = (int)strlen(z);
 
     if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
-      pNew->bRemoveDiacritic = 1;
+      pNew->eRemoveDiacritic = 1;
     }
     else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
-      pNew->bRemoveDiacritic = 0;
+      pNew->eRemoveDiacritic = 0;
+    }
+    else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){
+      pNew->eRemoveDiacritic = 2;
     }
     else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
       rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
@@ -175153,7 +178804,7 @@ static int unicodeNext(
 
     /* Grow the output buffer if required. */
     if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
-      char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
+      char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64);
       if( !zNew ) return SQLITE_NOMEM;
       zOut = &zNew[zOut - pCsr->zToken];
       pCsr->zToken = zNew;
@@ -175162,7 +178813,7 @@ static int unicodeNext(
 
     /* Write the folded case of the last character read to the output */
     zEnd = z;
-    iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
+    iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic);
     if( iOut ){
       WRITE_UTF8(zOut, iOut);
     }
@@ -175207,7 +178858,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
 /************** End of fts3_unicode.c ****************************************/
 /************** Begin file fts3_unicode2.c ***********************************/
 /*
-** 2012 May 25
+** 2012-05-25
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -175367,32 +179018,48 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
 ** E"). The resuls of passing a codepoint that corresponds to an
 ** uppercase letter are undefined.
 */
-static int remove_diacritic(int c){
+static int remove_diacritic(int c, int bComplex){
   unsigned short aDia[] = {
         0,  1797,  1848,  1859,  1891,  1928,  1940,  1995, 
      2024,  2040,  2060,  2110,  2168,  2206,  2264,  2286, 
      2344,  2383,  2472,  2488,  2516,  2596,  2668,  2732, 
      2782,  2842,  2894,  2954,  2984,  3000,  3028,  3336, 
-     3456,  3696,  3712,  3728,  3744,  3896,  3912,  3928, 
-     3968,  4008,  4040,  4106,  4138,  4170,  4202,  4234, 
-     4266,  4296,  4312,  4344,  4408,  4424,  4472,  4504, 
-     6148,  6198,  6264,  6280,  6360,  6429,  6505,  6529, 
-    61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, 
-    61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, 
-    62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, 
-    62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 
-    62924, 63050, 63082, 63274, 63390, 
+     3456,  3696,  3712,  3728,  3744,  3766,  3832,  3896, 
+     3912,  3928,  3944,  3968,  4008,  4040,  4056,  4106, 
+     4138,  4170,  4202,  4234,  4266,  4296,  4312,  4344, 
+     4408,  4424,  4442,  4472,  4488,  4504,  6148,  6198, 
+     6264,  6280,  6360,  6429,  6505,  6529, 61448, 61468, 
+    61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, 
+    61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 
+    61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 
+    62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 
+    62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 
+    62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 
+    63182, 63242, 63274, 63310, 63368, 63390, 
   };
-  char aChar[] = {
-    '\0', 'a',  'c',  'e',  'i',  'n',  'o',  'u',  'y',  'y',  'a',  'c',  
-    'd',  'e',  'e',  'g',  'h',  'i',  'j',  'k',  'l',  'n',  'o',  'r',  
-    's',  't',  'u',  'u',  'w',  'y',  'z',  'o',  'u',  'a',  'i',  'o',  
-    'u',  'g',  'k',  'o',  'j',  'g',  'n',  'a',  'e',  'i',  'o',  'r',  
-    'u',  's',  't',  'h',  'a',  'e',  'o',  'y',  '\0', '\0', '\0', '\0', 
-    '\0', '\0', '\0', '\0', 'a',  'b',  'd',  'd',  'e',  'f',  'g',  'h',  
-    'h',  'i',  'k',  'l',  'l',  'm',  'n',  'p',  'r',  'r',  's',  't',  
-    'u',  'v',  'w',  'w',  'x',  'y',  'z',  'h',  't',  'w',  'y',  'a',  
-    'e',  'i',  'o',  'u',  'y',  
+#define HIBIT ((unsigned char)0x80)
+  unsigned char aChar[] = {
+    '\0',      'a',       'c',       'e',       'i',       'n',       
+    'o',       'u',       'y',       'y',       'a',       'c',       
+    'd',       'e',       'e',       'g',       'h',       'i',       
+    'j',       'k',       'l',       'n',       'o',       'r',       
+    's',       't',       'u',       'u',       'w',       'y',       
+    'z',       'o',       'u',       'a',       'i',       'o',       
+    'u',       'u'|HIBIT, 'a'|HIBIT, 'g',       'k',       'o',       
+    'o'|HIBIT, 'j',       'g',       'n',       'a'|HIBIT, 'a',       
+    'e',       'i',       'o',       'r',       'u',       's',       
+    't',       'h',       'a',       'e',       'o'|HIBIT, 'o',       
+    'o'|HIBIT, 'y',       '\0',      '\0',      '\0',      '\0',      
+    '\0',      '\0',      '\0',      '\0',      'a',       'b',       
+    'c'|HIBIT, 'd',       'd',       'e'|HIBIT, 'e',       'e'|HIBIT, 
+    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
+    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
+    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
+    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
+    'w',       'x',       'y',       'z',       'h',       't',       
+    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
+    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
+    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
   };
 
   unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -175409,7 +179076,8 @@ static int remove_diacritic(int c){
     }
   }
   assert( key>=aDia[iRes] );
-  return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
+  if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
+  return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
 }
 
 
@@ -175422,8 +179090,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
   unsigned int mask1 = 0x000361F8;
   if( c<768 || c>817 ) return 0;
   return (c < 768+32) ?
-      (mask0 & (1 << (c-768))) :
-      (mask1 & (1 << (c-768-32)));
+      (mask0 & ((unsigned int)1 << (c-768))) :
+      (mask1 & ((unsigned int)1 << (c-768-32)));
 }
 
 
@@ -175436,7 +179104,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
 ** The results are undefined if the value passed to this function
 ** is less than zero.
 */
-SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
+SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
   /* Each entry in the following array defines a rule for folding a range
   ** of codepoints to lower case. The rule applies to a range of nRange
   ** codepoints starting at codepoint iCode.
@@ -175559,7 +179227,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
       assert( ret>0 );
     }
 
-    if( bRemoveDiacritic ) ret = remove_diacritic(ret);
+    if( eRemoveDiacritic ){
+      ret = remove_diacritic(ret, eRemoveDiacritic==2);
+    }
   }
   
   else if( c>=66560 && c<66600 ){
@@ -176266,7 +179936,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand(
   assert( pParse->nNode>=pParse->nAlloc );
   if( pParse->oom ) return -1;
   nNew = pParse->nAlloc*2 + 10;
-  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+  pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
   if( pNew==0 ){
     pParse->oom = 1;
     return -1;
@@ -176540,7 +180210,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
 static int jsonParseFindParents(JsonParse *pParse){
   u32 *aUp;
   assert( pParse->aUp==0 );
-  aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+  aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
   if( aUp==0 ){
     pParse->oom = 1;
     return SQLITE_NOMEM;
@@ -176602,7 +180272,7 @@ static JsonParse *jsonParseCached(
     pMatch->iHold = iMaxHold+1;
     return pMatch;
   }
-  p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+  p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
   if( p==0 ){
     sqlite3_result_error_nomem(pCtx);
     return 0;
@@ -176698,7 +180368,7 @@ static JsonNode *jsonLookupStep(
       u32 iStart, iLabel;
       JsonNode *pNode;
       iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
-      iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+      iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
       zPath += i;
       pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
       if( pParse->oom ) return 0;
@@ -177569,6 +181239,9 @@ static int jsonEachConnect(
 #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
 
@@ -177826,35 +181499,54 @@ static int jsonEachBestIndex(
   sqlite3_vtab *tab,
   sqlite3_index_info *pIdxInfo
 ){
-  int i;
-  int jsonIdx = -1;
-  int rootIdx = -1;
+  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++){
-    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;
+    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( jsonIdx<0 ){
+  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;
-    pIdxInfo->estimatedCost = 1e99;
   }else{
     pIdxInfo->estimatedCost = 1.0;
-    pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
-    pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
-    if( rootIdx<0 ){
-      pIdxInfo->idxNum = 1;
+    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{
-      pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
-      pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
-      pIdxInfo->idxNum = 3;
+      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;
@@ -177963,7 +181655,8 @@ static sqlite3_module jsonEachModule = {
   0,                         /* xRename */
   0,                         /* xSavepoint */
   0,                         /* xRelease */
-  0                          /* xRollbackTo */
+  0,                         /* xRollbackTo */
+  0                          /* xShadowName */
 };
 
 /* The methods of the json_tree virtual table. */
@@ -177990,7 +181683,8 @@ static sqlite3_module jsonTreeModule = {
   0,                         /* xRename */
   0,                         /* xSavepoint */
   0,                         /* xRelease */
-  0                          /* xRollbackTo */
+  0,                         /* xRollbackTo */
+  0                          /* xShadowName */
 };
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
@@ -178158,10 +181852,6 @@ SQLITE_API int sqlite3_json_init(
 /*   #include "sqlite3.h" */
 #endif
 
-/* #include <string.h> */
-/* #include <assert.h> */
-/* #include <stdio.h> */
-
 #ifndef SQLITE_AMALGAMATION
 #include "sqlite3rtree.h"
 typedef sqlite3_int64 i64;
@@ -178169,7 +181859,17 @@ typedef sqlite3_uint64 u64;
 typedef unsigned char u8;
 typedef unsigned short u16;
 typedef unsigned int u32;
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+# define NDEBUG 1
 #endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
+#endif
+
+/* #include <string.h> */
+/* #include <stdio.h> */
+/* #include <assert.h> */
 
 /*  The following macro is used to suppress compiler warnings.
 */
@@ -178223,6 +181923,9 @@ struct Rtree {
   u8 inWrTrans;               /* True if inside write transaction */
   u8 nAux;                    /* # of auxiliary columns in %_rowid */
   u8 nAuxNotNull;             /* Number of initial not-null aux columns */
+#ifdef SQLITE_DEBUG
+  u8 bCorrupt;                /* Shadow table corruption detected */
+#endif
   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 */ 
@@ -178282,6 +181985,15 @@ struct Rtree {
 # define RTREE_ZERO 0.0
 #endif
 
+/*
+** Set the Rtree.bCorrupt flag
+*/
+#ifdef SQLITE_DEBUG
+# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1)
+#else
+# define RTREE_IS_CORRUPT(X)
+#endif
+
 /*
 ** When doing a search of an r-tree, instances of the following structure
 ** record intermediate results from the tree walk.
@@ -178648,8 +182360,8 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){
 ** Given a node number iNode, return the corresponding key to use
 ** in the Rtree.aHash table.
 */
-static int nodeHash(i64 iNode){
-  return iNode % HASHSIZE;
+static unsigned int nodeHash(i64 iNode){
+  return ((unsigned)iNode) % HASHSIZE;
 }
 
 /*
@@ -178694,7 +182406,7 @@ static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
 */
 static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
   RtreeNode *pNode;
-  pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
+  pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize);
   if( pNode ){
     memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
     pNode->zData = (u8 *)&pNode[1];
@@ -178718,6 +182430,18 @@ static void nodeBlobReset(Rtree *pRtree){
   }
 }
 
+/*
+** Check to see if pNode is the same as pParent or any of the parents
+** of pParent.
+*/
+static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
+  do{
+    if( pNode==pParent ) return 1;
+    pParent = pParent->pParent;
+  }while( pParent );
+  return 0;
+}
+
 /*
 ** Obtain a reference to an r-tree node.
 */
@@ -178736,6 +182460,10 @@ static int nodeAcquire(
   if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
     assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
     if( pParent && !pNode->pParent ){
+      if( nodeInParentChain(pNode, pParent) ){
+        RTREE_IS_CORRUPT(pRtree);
+        return SQLITE_CORRUPT_VTAB;
+      }
       pParent->nRef++;
       pNode->pParent = pParent;
     }
@@ -178766,9 +182494,12 @@ static int nodeAcquire(
     *ppNode = 0;
     /* If unable to open an sqlite3_blob on the desired row, that can only
     ** be because the shadow tables hold erroneous data. */
-    if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
+    if( rc==SQLITE_ERROR ){
+      rc = SQLITE_CORRUPT_VTAB;
+      RTREE_IS_CORRUPT(pRtree);
+    }
   }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
-    pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
+    pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize);
     if( !pNode ){
       rc = SQLITE_NOMEM;
     }else{
@@ -178781,7 +182512,6 @@ static int nodeAcquire(
       pNode->pNext = 0;
       rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
                              pRtree->iNodeSize, 0);
-      nodeReference(pParent);
     }
   }
 
@@ -178795,6 +182525,7 @@ static int nodeAcquire(
     pRtree->iDepth = readInt16(pNode->zData);
     if( pRtree->iDepth>RTREE_MAX_DEPTH ){
       rc = SQLITE_CORRUPT_VTAB;
+      RTREE_IS_CORRUPT(pRtree);
     }
   }
 
@@ -178805,14 +182536,17 @@ static int nodeAcquire(
   if( pNode && rc==SQLITE_OK ){
     if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
       rc = SQLITE_CORRUPT_VTAB;
+      RTREE_IS_CORRUPT(pRtree);
     }
   }
 
   if( rc==SQLITE_OK ){
     if( pNode!=0 ){
+      nodeReference(pParent);
       nodeHashInsert(pRtree, pNode);
     }else{
       rc = SQLITE_CORRUPT_VTAB;
+      RTREE_IS_CORRUPT(pRtree);
     }
     *ppNode = pNode;
   }else{
@@ -179038,7 +182772,7 @@ static void rtreeRelease(Rtree *pRtree){
     pRtree->inWrTrans = 0;
     assert( pRtree->nCursor==0 );
     nodeBlobReset(pRtree);
-    assert( pRtree->nNodeRef==0 );
+    assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
     sqlite3_finalize(pRtree->pWriteNode);
     sqlite3_finalize(pRtree->pDeleteNode);
     sqlite3_finalize(pRtree->pReadRowid);
@@ -179097,7 +182831,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
   Rtree *pRtree = (Rtree *)pVTab;
   RtreeCursor *pCsr;
 
-  pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
+  pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor));
   if( pCsr ){
     memset(pCsr, 0, sizeof(RtreeCursor));
     pCsr->base.pVtab = pVTab;
@@ -179370,6 +183104,7 @@ static int nodeRowidIndex(
       return SQLITE_OK;
     }
   }
+  RTREE_IS_CORRUPT(pRtree);
   return SQLITE_CORRUPT_VTAB;
 }
 
@@ -179463,7 +183198,7 @@ static RtreeSearchPoint *rtreeEnqueue(
   RtreeSearchPoint *pNew;
   if( pCur->nPoint>=pCur->nPointAlloc ){
     int nNew = pCur->nPointAlloc*2 + 8;
-    pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
+    pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
     if( pNew==0 ) return 0;
     pCur->aPoint = pNew;
     pCur->nPointAlloc = nNew;
@@ -179865,7 +183600,7 @@ static int rtreeFilter(
     */
     rc = nodeAcquire(pRtree, 1, 0, &pRoot);
     if( rc==SQLITE_OK && argc>0 ){
-      pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
+      pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc);
       pCsr->nConstraint = argc;
       if( !pCsr->aConstraint ){
         rc = SQLITE_NOMEM;
@@ -180010,20 +183745,20 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     ){
       u8 op;
       switch( p->op ){
-        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
-        case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
-        case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
-        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
-        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
-        default:
-          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
-          op = RTREE_MATCH; 
-          break;
+        case SQLITE_INDEX_CONSTRAINT_EQ:    op = RTREE_EQ;    break;
+        case SQLITE_INDEX_CONSTRAINT_GT:    op = RTREE_GT;    break;
+        case SQLITE_INDEX_CONSTRAINT_LE:    op = RTREE_LE;    break;
+        case SQLITE_INDEX_CONSTRAINT_LT:    op = RTREE_LT;    break;
+        case SQLITE_INDEX_CONSTRAINT_GE:    op = RTREE_GE;    break;
+        case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break;
+        default:                            op = 0;           break;
+      }
+      if( op ){
+        zIdxStr[iIdx++] = op;
+        zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
+        pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
+        pIdxInfo->aConstraintUsage[ii].omit = 1;
       }
-      zIdxStr[iIdx++] = op;
-      zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
-      pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
-      pIdxInfo->aConstraintUsage[ii].omit = 1;
     }
   }
 
@@ -180059,11 +183794,11 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
 #endif
   {
     switch( pRtree->nDim ){
-      case 5:  area  = p->aCoord[9].i - p->aCoord[8].i;
-      case 4:  area *= p->aCoord[7].i - p->aCoord[6].i;
-      case 3:  area *= p->aCoord[5].i - p->aCoord[4].i;
-      case 2:  area *= p->aCoord[3].i - p->aCoord[2].i;
-      default: area *= p->aCoord[1].i - p->aCoord[0].i;
+      case 5:  area  = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i;
+      case 4:  area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i;
+      case 3:  area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i;
+      case 2:  area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i;
+      default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i;
     }
   }
   return area;
@@ -180232,12 +183967,14 @@ static int AdjustTree(
   RtreeCell *pCell                  /* This cell was just inserted */
 ){
   RtreeNode *p = pNode;
+  int cnt = 0;
   while( p->pParent ){
     RtreeNode *pParent = p->pParent;
     RtreeCell cell;
     int iCell;
 
-    if( nodeParentIndex(pRtree, p, &iCell) ){
+    if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell)  ){
+      RTREE_IS_CORRUPT(pRtree);
       return SQLITE_CORRUPT_VTAB;
     }
 
@@ -180434,9 +184171,9 @@ static int splitNodeStartree(
   int iBestSplit = 0;
   RtreeDValue fBestMargin = RTREE_ZERO;
 
-  int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
+  sqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
 
-  aaSorted = (int **)sqlite3_malloc(nByte);
+  aaSorted = (int **)sqlite3_malloc64(nByte);
   if( !aaSorted ){
     return SQLITE_NOMEM;
   }
@@ -180557,7 +184294,7 @@ static int SplitNode(
   /* Allocate an array and populate it with a copy of pCell and 
   ** all cells from node pLeft. Then zero the original node.
   */
-  aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
+  aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
   if( !aCell ){
     rc = SQLITE_NOMEM;
     goto splitnode_out;
@@ -180705,7 +184442,10 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
     }
     rc = sqlite3_reset(pRtree->pReadParent);
     if( rc==SQLITE_OK ) rc = rc2;
-    if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
+    if( rc==SQLITE_OK && !pChild->pParent ){
+      RTREE_IS_CORRUPT(pRtree);
+      rc = SQLITE_CORRUPT_VTAB;
+    }
     pChild = pChild->pParent;
   }
   return rc;
@@ -180845,7 +184585,7 @@ static int Reinsert(
   /* Allocate the buffers used by this operation. The allocation is
   ** relinquished before this function returns.
   */
-  aCell = (RtreeCell *)sqlite3_malloc(n * (
+  aCell = (RtreeCell *)sqlite3_malloc64(n * (
     sizeof(RtreeCell)     +         /* aCell array */
     sizeof(int)           +         /* aOrder array */
     sizeof(int)           +         /* aSpare array */
@@ -181019,8 +184759,12 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
     rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
   }
 
+#ifdef CORRUPT_DB
+  assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB );
+#endif
+
   /* Delete the cell in question from the leaf node. */
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK && pLeaf ){
     int rc2;
     rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
     if( rc==SQLITE_OK ){
@@ -181292,7 +185036,7 @@ static int rtreeUpdate(
         rc = rc2;
       }
     }
-    if( pRtree->nAux ){
+    if( rc==SQLITE_OK && pRtree->nAux ){
       sqlite3_stmt *pUp = pRtree->pWriteAux;
       int jj;
       sqlite3_bind_int64(pUp, 1, *pRowid);
@@ -181420,8 +185164,24 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
   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 */
@@ -181444,6 +185204,7 @@ static sqlite3_module rtreeModule = {
   rtreeSavepoint,             /* xSavepoint */
   0,                          /* xRelease */
   0,                          /* xRollbackTo */
+  rtreeShadowName             /* xShadowName */
 };
 
 static int rtreeSqlInit(
@@ -181473,6 +185234,7 @@ static int rtreeSqlInit(
   };
   sqlite3_stmt **appStmt[N_STATEMENT];
   int i;
+  const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
 
   pRtree->db = db;
 
@@ -181529,8 +185291,7 @@ static int rtreeSqlInit(
     }
     zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
     if( zSql ){
-      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
-                              appStmt[i], 0); 
+      rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); 
     }else{
       rc = SQLITE_NOMEM;
     }
@@ -181560,8 +185321,7 @@ static int rtreeSqlInit(
       if( zSql==0 ){
         rc = SQLITE_NOMEM;
       }else{
-        rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
-                                &pRtree->pWriteAux, 0); 
+        rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); 
         sqlite3_free(zSql);
       }
     }
@@ -181637,6 +185397,7 @@ static int getNodeSize(
       *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
     }else if( pRtree->iNodeSize<(512-64) ){
       rc = SQLITE_CORRUPT_VTAB;
+      RTREE_IS_CORRUPT(pRtree);
       *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
                                pRtree->zName);
     }
@@ -181692,7 +185453,7 @@ static int rtreeInit(
   /* Allocate the sqlite3_vtab structure */
   nDb = (int)strlen(argv[1]);
   nName = (int)strlen(argv[2]);
-  pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+  pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
   if( !pRtree ){
     return SQLITE_NOMEM;
   }
@@ -181789,49 +185550,45 @@ rtreeInit_fail:
 ** <num-dimension>*2 coordinates.
 */
 static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
-  char *zText = 0;
   RtreeNode node;
   Rtree tree;
   int ii;
+  int nData;
+  int errCode;
+  sqlite3_str *pOut;
 
   UNUSED_PARAMETER(nArg);
   memset(&node, 0, sizeof(RtreeNode));
   memset(&tree, 0, sizeof(Rtree));
   tree.nDim = (u8)sqlite3_value_int(apArg[0]);
+  if( tree.nDim<1 || tree.nDim>5 ) return;
   tree.nDim2 = tree.nDim*2;
   tree.nBytesPerCell = 8 + 8 * tree.nDim;
   node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
+  nData = sqlite3_value_bytes(apArg[1]);
+  if( nData<4 ) return;
+  if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
 
+  pOut = sqlite3_str_new(0);
   for(ii=0; ii<NCELL(&node); ii++){
-    char zCell[512];
-    int nCell = 0;
     RtreeCell cell;
     int jj;
 
     nodeGetCell(&tree, &node, ii, &cell);
-    sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
-    nCell = (int)strlen(zCell);
+    if( ii>0 ) sqlite3_str_append(pOut, " ", 1);
+    sqlite3_str_appendf(pOut, "{%lld", cell.iRowid);
     for(jj=0; jj<tree.nDim2; jj++){
 #ifndef SQLITE_RTREE_INT_ONLY
-      sqlite3_snprintf(512-nCell,&zCell[nCell], " %g",
-                       (double)cell.aCoord[jj].f);
+      sqlite3_str_appendf(pOut, " %g", (double)cell.aCoord[jj].f);
 #else
-      sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
-                       cell.aCoord[jj].i);
+      sqlite3_str_appendf(pOut, " %d", cell.aCoord[jj].i);
 #endif
-      nCell = (int)strlen(zCell);
-    }
-
-    if( zText ){
-      char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
-      sqlite3_free(zText);
-      zText = zTextNew;
-    }else{
-      zText = sqlite3_mprintf("{%s}", zCell);
     }
+    sqlite3_str_append(pOut, "}", 1);
   }
-  
-  sqlite3_result_text(ctx, zText, -1, sqlite3_free);
+  errCode = sqlite3_str_errcode(pOut);
+  sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free);
+  sqlite3_result_error_code(ctx, errCode);
 }
 
 /* This routine implements an SQL function that returns the "depth" parameter
@@ -181960,8 +185717,7 @@ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
 static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
   u8 *pRet = 0;                   /* Return value */
 
-  assert( pCheck->rc==SQLITE_OK );
-  if( pCheck->pGetNode==0 ){
+  if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){
     pCheck->pGetNode = rtreeCheckPrepare(pCheck,
         "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", 
         pCheck->zDb, pCheck->zTab
@@ -181973,7 +185729,7 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
     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);
+      pRet = sqlite3_malloc64(nNode);
       if( pRet==0 ){
         pCheck->rc = SQLITE_NOMEM;
       }else{
@@ -182434,14 +186190,32 @@ typedef float GeoCoord;
 **
 **      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[2];    /* 2*nVertex values. X (longitude) first, then Y */
+  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))
+
+/* Macros to access coordinates of a GeoPoly.
+** We have to use these macros, rather than just say p->a[i] in order
+** to silence (incorrect) UBSAN warnings if the array index is too large.
+*/
+#define GeoX(P,I)  (((GeoCoord*)(P)->a)[(I)*2])
+#define GeoY(P,I)  (((GeoCoord*)(P)->a)[(I)*2+1])
+
+
 /*
 ** State of a parse of a GeoJSON input.
 */
@@ -182466,7 +186240,7 @@ static void geopolySwab32(unsigned char *a){
 
 /* Skip whitespace.  Return the next non-whitespace character. */
 static char geopolySkipSpace(GeoParse *p){
-  while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
+  while( safe_isspace(p->z[0]) ) p->z++;
   return p->z[0];
 }
 
@@ -182486,7 +186260,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
   if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
   for(;; j++){
     c = z[j];
-    if( c>='0' && c<='9' ) continue;
+    if( safe_isdigit(c) ) continue;
     if( c=='.' ){
       if( z[j-1]=='-' ) return 0;
       if( seenDP ) return 0;
@@ -182508,7 +186282,17 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
     break;
   }
   if( z[j-1]<'0' ) return 0;
-  if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
+  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;
 }
@@ -182566,12 +186350,10 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
      && s.a[1]==s.a[s.nVertex*2-1]
      && (s.z++, geopolySkipSpace(&s)==0)
     ){
-      int nByte;
       GeoPoly *pOut;
       int x = 1;
       s.nVertex--;  /* Remove the redundant vertex at the end */
-      nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
-      pOut = sqlite3_malloc64( nByte );
+      pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) );
       x = 1;
       if( pOut==0 ) goto parse_json_err;
       pOut->nVertex = s.nVertex;
@@ -182626,8 +186408,9 @@ static GeoPoly *geopolyFuncParam(
         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]);
+          for(ii=0; ii<nVertex; ii++){
+            geopolySwab32((unsigned char*)&GeoX(p,ii));
+            geopolySwab32((unsigned char*)&GeoY(p,ii));
           }
           p->hdr[0] ^= 1;
         }
@@ -182686,9 +186469,9 @@ static void geopolyJsonFunc(
     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],", GeoX(p,i), GeoY(p,i));
     }
-    sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
+    sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0));
     sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
     sqlite3_free(p);
   }
@@ -182705,7 +186488,9 @@ static void geopolySvgFunc(
   int argc,
   sqlite3_value **argv
 ){
-  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+  GeoPoly *p;
+  if( argc<1 ) return;
+  p = geopolyFuncParam(context, argv[0], 0);
   if( p ){
     sqlite3 *db = sqlite3_context_db_handle(context);
     sqlite3_str *x = sqlite3_str_new(db);
@@ -182713,10 +186498,10 @@ static void geopolySvgFunc(
     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]);
+      sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i));
       cSep = ' ';
     }
-    sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
+    sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0));
     for(i=1; i<argc; i++){
       const char *z = (const char*)sqlite3_value_text(argv[i]);
       if( z && z[0] ){
@@ -182761,12 +186546,12 @@ static void geopolyXformFunc(
   int ii;
   if( p ){
     for(ii=0; ii<p->nVertex; ii++){
-      x0 = p->a[ii*2];
-      y0 = p->a[ii*2+1];
+      x0 = GeoX(p,ii);
+      y0 = GeoY(p,ii);
       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;
+      GeoX(p,ii) = x1;
+      GeoY(p,ii) = y1;
     }
     sqlite3_result_blob(context, p->hdr, 
        4+8*p->nVertex, SQLITE_TRANSIENT);
@@ -182774,6 +186559,27 @@ static void geopolyXformFunc(
   }
 }
 
+/*
+** 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 += (GeoX(p,ii) - GeoX(p,ii+1))           /* (x0 - x1) */
+              * (GeoY(p,ii) + GeoY(p,ii+1))        /* (y0 + y1) */
+              * 0.5;
+  }
+  rArea += (GeoX(p,ii) - GeoX(p,0))                /* (xN - x0) */
+           * (GeoY(p,ii) + GeoY(p,0))              /* (yN + y0) */
+           * 0.5;
+  return rArea;
+}
+
 /*
 ** Implementation of the geopoly_area(X) function.
 **
@@ -182789,21 +186595,106 @@ static void geopolyAreaFunc(
 ){
   GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
   if( 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;
-    sqlite3_result_double(context, rArea);
+    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=1, jj=p->nVertex-1; ii<jj; ii++, jj--){
+        GeoCoord t = GeoX(p,ii);
+        GeoX(p,ii) = GeoX(p,jj);
+        GeoX(p,jj) = t;
+        t = GeoY(p,ii);
+        GeoY(p,ii) = GeoY(p,jj);
+        GeoY(p,jj) = 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;
+    GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
+    GeoY(p,i) = 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:
 **
@@ -182835,20 +186726,20 @@ static GeoPoly *geopolyBBox(
   }
   if( p ){
     int ii;
-    mnX = mxX = p->a[0];
-    mnY = mxY = p->a[1];
+    mnX = mxX = GeoX(p,0);
+    mnY = mxY = GeoY(p,0);
     for(ii=1; ii<p->nVertex; ii++){
-      double r = p->a[ii*2];
+      double r = GeoX(p,ii);
       if( r<mnX ) mnX = (float)r;
       else if( r>mxX ) mxX = (float)r;
-      r = p->a[ii*2+1];
+      r = GeoY(p,ii);
       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, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
+      pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4));
       if( pOut==0 ){
         sqlite3_free(p);
         if( context ) sqlite3_result_error_nomem(context);
@@ -182861,14 +186752,14 @@ static GeoPoly *geopolyBBox(
       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;
+      GeoX(pOut,0) = mnX;
+      GeoY(pOut,0) = mnY;
+      GeoX(pOut,1) = mxX;
+      GeoY(pOut,1) = mnY;
+      GeoX(pOut,2) = mxX;
+      GeoY(pOut,2) = mxY;
+      GeoX(pOut,3) = mnX;
+      GeoY(pOut,3) = mxY;
     }else{
       sqlite3_free(p);
       aCoord[0].f = mnX;
@@ -183006,14 +186897,14 @@ static void geopolyContainsPointFunc(
   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]);
+    v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+                               GeoX(p1,ii+1),GeoY(p1,ii+1));
     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]);
+    v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+                               GeoX(p1,0),  GeoY(p1,0));
   }
   if( v==2 ){
     sqlite3_result_int(context, 1);
@@ -183135,10 +187026,10 @@ static void geopolyAddSegments(
   unsigned int i;
   GeoCoord *x;
   for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
-    x = pPoly->a + (i*2);
+    x = &GeoX(pPoly,i);
     geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
   }
-  x = pPoly->a + (i*2);
+  x = &GeoX(pPoly,i);
   geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
 }
 
@@ -183244,9 +187135,9 @@ static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
 ** Determine the overlap between two polygons
 */
 static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
-  int nVertex = p1->nVertex + p2->nVertex + 2;
+  sqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2;
   GeoOverlap *p;
-  int nByte;
+  sqlite3_int64 nByte;
   GeoEvent *pThisEvent;
   double rX;
   int rc = 0;
@@ -183258,7 +187149,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
   nByte = sizeof(GeoEvent)*nVertex*2 
            + sizeof(GeoSegment)*nVertex 
            + sizeof(GeoOverlap);
-  p = sqlite3_malloc( nByte );
+  p = sqlite3_malloc64( nByte );
   if( p==0 ) return -1;
   p->aEvent = (GeoEvent*)&p[1];
   p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
@@ -183417,8 +187308,8 @@ static int geopolyInit(
 ){
   int rc = SQLITE_OK;
   Rtree *pRtree;
-  int nDb;              /* Length of string argv[1] */
-  int nName;            /* Length of string argv[2] */
+  sqlite3_int64 nDb;              /* Length of string argv[1] */
+  sqlite3_int64 nName;            /* Length of string argv[2] */
   sqlite3_str *pSql;
   char *zSql;
   int ii;
@@ -183426,9 +187317,9 @@ static int geopolyInit(
   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);
+  nDb = strlen(argv[1]);
+  nName = strlen(argv[2]);
+  pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
   if( !pRtree ){
     return SQLITE_NOMEM;
   }
@@ -183876,7 +187767,16 @@ static int geopolyUpdate(
     if( sqlite3_value_nochange(aData[2]) ){
       sqlite3_bind_null(pUp, 2);
     }else{
-      sqlite3_bind_value(pUp, 2, aData[2]);
+      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++){
@@ -183920,7 +187820,7 @@ static int geopolyFindFunction(
 
 
 static sqlite3_module geopolyModule = {
-  2,                          /* iVersion */
+  3,                          /* iVersion */
   geopolyCreate,              /* xCreate - create a table */
   geopolyConnect,             /* xConnect - connect to an existing table */
   geopolyBestIndex,           /* xBestIndex - Determine search strategy */
@@ -183943,25 +187843,29 @@ static sqlite3_module geopolyModule = {
   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**);
-    int nArg;
+    signed char nArg;
+    unsigned char bPure;
     const char *zName;
   } aFunc[] = {
-     { geopolyAreaFunc,          1,    "geopoly_area"             },
-     { geopolyBlobFunc,          1,    "geopoly_blob"             },
-     { geopolyJsonFunc,          1,    "geopoly_json"             },
-     { geopolySvgFunc,          -1,    "geopoly_svg"              },
-     { geopolyWithinFunc,        2,    "geopoly_within"           },
-     { geopolyContainsPointFunc, 3,    "geopoly_contains_point"   },
-     { geopolyOverlapFunc,       2,    "geopoly_overlap"          },
-     { geopolyDebugFunc,         1,    "geopoly_debug"            },
-     { geopolyBBoxFunc,          1,    "geopoly_bbox"             },
-     { geopolyXformFunc,         7,    "geopoly_xform"            },
+     { 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**);
@@ -183972,8 +187876,9 @@ static int sqlite3_geopoly_init(sqlite3 *db){
   };
   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,
-                                 SQLITE_UTF8, 0,
+                                 enc, 0,
                                  aFunc[i].xFunc, 0, 0);
   }
   for(i=0; i<sizeof(aAgg)/sizeof(aAgg[0]) && rc==SQLITE_OK; i++){
@@ -184069,12 +187974,12 @@ static void rtreeMatchArgFree(void *pArg){
 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
   RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
   RtreeMatchArg *pBlob;
-  int nBlob;
+  sqlite3_int64 nBlob;
   int memErr = 0;
 
   nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
            + nArg*sizeof(sqlite3_value*);
-  pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
+  pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob);
   if( !pBlob ){
     sqlite3_result_error_nomem(ctx);
   }else{
@@ -184785,7 +188690,7 @@ static int icuCreate(
   if( argc>0 ){
     n = strlen(argv[0])+1;
   }
-  p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
+  p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n);
   if( !p ){
     return SQLITE_NOMEM;
   }
@@ -184842,7 +188747,7 @@ static int icuOpen(
     nInput = strlen(zInput);
   }
   nChar = nInput+1;
-  pCsr = (IcuCursor *)sqlite3_malloc(
+  pCsr = (IcuCursor *)sqlite3_malloc64(
       sizeof(IcuCursor) +                /* IcuCursor */
       ((nChar+3)&~3) * sizeof(UChar) +   /* IcuCursor.aChar[] */
       (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */
@@ -185414,7 +189319,11 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open(
 ** name of the state database is "<database>-vacuum", where <database>
 ** is the name of the target database file. In this case, on UNIX, if the
 ** state database is not already present in the file-system, it is created
-** with the same permissions as the target db is made.
+** with the same permissions as the target db is made. 
+**
+** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the 
+** state database ends with "-vactmp". This name is reserved for internal 
+** use.
 **
 ** This function does not delete the state database after an RBU vacuum
 ** is completed, even if it created it. However, if the call to
@@ -185835,6 +189744,11 @@ struct RbuUpdateStmt {
 **   it points to an array of flags nTblCol elements in size. The flag is
 **   set for each column that is either a part of the PK or a part of an
 **   index. Or clear otherwise.
+**
+**   If there are one or more partial indexes on the table, all fields of
+**   this array set set to 1. This is because in that case, the module has
+**   no way to tell which fields will be required to add and remove entries
+**   from the partial indexes.
 **   
 */
 struct RbuObjIter {
@@ -186000,7 +189914,8 @@ struct rbu_vfs {
   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 */
 };
 
 /*
@@ -186029,6 +189944,7 @@ struct rbu_file {
   const char *zWal;               /* Wal filename for this main db file */
   rbu_file *pWalFd;               /* Wal file descriptor for this main db */
   rbu_file *pMainNext;            /* Next MAIN_DB file */
+  rbu_file *pMainRbuNext;         /* Next MAIN_DB file with pRbu!=0 */
 };
 
 /*
@@ -186277,6 +190193,7 @@ static void rbuFossilDeltaFunc(
   }else{
     nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
     if( nOut2!=nOut ){
+      sqlite3_free(aOut);
       sqlite3_result_error(context, "corrupt fossil delta", -1);
     }else{
       sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
@@ -186517,7 +190434,8 @@ static void rbuTargetNameFunc(
   zIn = (const char*)sqlite3_value_text(argv[0]);
   if( zIn ){
     if( rbuIsVacuum(p) ){
-      if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
+      assert( argc==2 );
+      if( 0==sqlite3_value_int(argv[1]) ){
         sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
       }
     }else{
@@ -186627,7 +190545,7 @@ static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){
 ** immediately without attempting the allocation or modifying the stored
 ** error code.
 */
-static void *rbuMalloc(sqlite3rbu *p, int nByte){
+static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){
   void *pRet = 0;
   if( p->rc==SQLITE_OK ){
     assert( nByte>0 );
@@ -186648,7 +190566,7 @@ static void *rbuMalloc(sqlite3rbu *p, int nByte){
 ** error code in the RBU handle passed as the first argument.
 */
 static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
-  int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
+  sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
   char **azNew;
 
   azNew = (char**)rbuMalloc(p, nByte);
@@ -186842,8 +190760,12 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
   pIter->nIndex = 0;
   while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
     const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
+    int bPartial = sqlite3_column_int(pList, 4);
     sqlite3_stmt *pXInfo = 0;
     if( zIdx==0 ) break;
+    if( bPartial ){
+      memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
+    }
     p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
         sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
     );
@@ -186964,7 +190886,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
         }
 
         pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
-        pIter->abTblPk[iOrder] = (iPk!=0);
+        assert( iPk>=0 );
+        pIter->abTblPk[iOrder] = (u8)iPk;
         pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
         iOrder++;
       }
@@ -186999,6 +190922,213 @@ static char *rbuObjIterGetCollist(
   return zList;
 }
 
+/*
+** Return a comma separated list of the quoted PRIMARY KEY column names,
+** in order, for the current table. Before each column name, add the text
+** zPre. After each column name, add the zPost text. Use zSeparator as
+** the separator text (usually ", ").
+*/
+static char *rbuObjIterGetPkList(
+  sqlite3rbu *p,                  /* RBU object */
+  RbuObjIter *pIter,              /* Object iterator for column names */
+  const char *zPre,               /* Before each quoted column name */
+  const char *zSeparator,         /* Separator to use between columns */
+  const char *zPost               /* After each quoted column name */
+){
+  int iPk = 1;
+  char *zRet = 0;
+  const char *zSep = "";
+  while( 1 ){
+    int i;
+    for(i=0; i<pIter->nTblCol; i++){
+      if( (int)pIter->abTblPk[i]==iPk ){
+        const char *zCol = pIter->azTblCol[i];
+        zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
+        zSep = zSeparator;
+        break;
+      }
+    }
+    if( i==pIter->nTblCol ) break;
+    iPk++;
+  }
+  return zRet;
+}
+
+/*
+** This function is called as part of restarting an RBU vacuum within 
+** stage 1 of the process (while the *-oal file is being built) while
+** updating a table (not an index). The table may be a rowid table or
+** a WITHOUT ROWID table. It queries the target database to find the 
+** largest key that has already been written to the target table and
+** constructs a WHERE clause that can be used to extract the remaining
+** rows from the source table. For a rowid table, the WHERE clause
+** is of the form:
+**
+**     "WHERE _rowid_ > ?"
+**
+** and for WITHOUT ROWID tables:
+**
+**     "WHERE (key1, key2) > (?, ?)"
+**
+** Instead of "?" placeholders, the actual WHERE clauses created by
+** this function contain literal SQL values.
+*/
+static char *rbuVacuumTableStart(
+  sqlite3rbu *p,                  /* RBU handle */
+  RbuObjIter *pIter,              /* RBU iterator object */
+  int bRowid,                     /* True for a rowid table */
+  const char *zWrite              /* Target table name prefix */
+){
+  sqlite3_stmt *pMax = 0;
+  char *zRet = 0;
+  if( bRowid ){
+    p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, 
+        sqlite3_mprintf(
+          "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
+        )
+    );
+    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+      sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
+      zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
+    }
+    rbuFinalize(p, pMax);
+  }else{
+    char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
+    char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
+    char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
+
+    if( p->rc==SQLITE_OK ){
+      p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, 
+          sqlite3_mprintf(
+            "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", 
+                zSelect, zWrite, pIter->zTbl, zOrder
+          )
+      );
+      if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+        const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
+        zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
+      }
+      rbuFinalize(p, pMax);
+    }
+
+    sqlite3_free(zOrder);
+    sqlite3_free(zSelect);
+    sqlite3_free(zList);
+  }
+  return zRet;
+}
+
+/*
+** This function is called as part of restating an RBU vacuum when the
+** current operation is writing content to an index. If possible, it
+** queries the target index b-tree for the largest key already written to
+** it, then composes and returns an expression that can be used in a WHERE 
+** clause to select the remaining required rows from the source table. 
+** It is only possible to return such an expression if:
+**
+**   * The index contains no DESC columns, and
+**   * The last key written to the index before the operation was 
+**     suspended does not contain any NULL values.
+**
+** The expression is of the form:
+**
+**   (index-field1, index-field2, ...) > (?, ?, ...)
+**
+** except that the "?" placeholders are replaced with literal values.
+**
+** If the expression cannot be created, NULL is returned. In this case,
+** the caller has to use an OFFSET clause to extract only the required 
+** rows from the sourct table, just as it does for an RBU update operation.
+*/
+char *rbuVacuumIndexStart(
+  sqlite3rbu *p,                  /* RBU handle */
+  RbuObjIter *pIter               /* RBU iterator object */
+){
+  char *zOrder = 0;
+  char *zLhs = 0;
+  char *zSelect = 0;
+  char *zVector = 0;
+  char *zRet = 0;
+  int bFailed = 0;
+  const char *zSep = "";
+  int iCol = 0;
+  sqlite3_stmt *pXInfo = 0;
+
+  p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+      sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
+  );
+  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+    int iCid = sqlite3_column_int(pXInfo, 1);
+    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+    const char *zCol;
+    if( sqlite3_column_int(pXInfo, 3) ){
+      bFailed = 1;
+      break;
+    }
+
+    if( iCid<0 ){
+      if( pIter->eType==RBU_PK_IPK ){
+        int i;
+        for(i=0; pIter->abTblPk[i]==0; i++);
+        assert( i<pIter->nTblCol );
+        zCol = pIter->azTblCol[i];
+      }else{
+        zCol = "_rowid_";
+      }
+    }else{
+      zCol = pIter->azTblCol[iCid];
+    }
+
+    zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q",
+        zLhs, zSep, zCol, zCollate
+        );
+    zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC",
+        zOrder, zSep, iCol, zCol, zCollate
+        );
+    zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")",
+        zSelect, zSep, iCol, zCol
+        );
+    zSep = ", ";
+    iCol++;
+  }
+  rbuFinalize(p, pXInfo);
+  if( bFailed ) goto index_start_out;
+
+  if( p->rc==SQLITE_OK ){
+    sqlite3_stmt *pSel = 0;
+
+    p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg,
+        sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1",
+          zSelect, pIter->zTbl, zOrder
+        )
+    );
+    if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){
+      zSep = "";
+      for(iCol=0; iCol<pIter->nCol; iCol++){
+        const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol);
+        if( zQuoted[0]=='N' ){
+          bFailed = 1;
+          break;
+        }
+        zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted);
+        zSep = ", ";
+      }
+
+      if( !bFailed ){
+        zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector);
+      }
+    }
+    rbuFinalize(p, pSel);
+  }
+
+ index_start_out:
+  sqlite3_free(zOrder);
+  sqlite3_free(zSelect);
+  sqlite3_free(zVector);
+  sqlite3_free(zLhs);
+  return zRet;
+}
+
 /*
 ** This function is used to create a SELECT list (the list of SQL 
 ** expressions that follows a SELECT keyword) for a SELECT statement 
@@ -187288,7 +191418,7 @@ static char *rbuObjIterGetSetlist(
 */
 static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){
   char *zRet = 0;
-  int nByte = nBind*2 + 1;
+  sqlite3_int64 nByte = 2*(sqlite3_int64)nBind + 1;
 
   zRet = (char*)rbuMalloc(p, nByte);
   if( zRet ){
@@ -187550,6 +191680,62 @@ static void rbuTmpInsertFunc(
   }
 }
 
+static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
+  sqlite3_stmt *pStmt = 0;
+  int rc = p->rc;
+  char *zRet = 0;
+
+  if( rc==SQLITE_OK ){
+    rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
+        "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
+    );
+  }
+  if( rc==SQLITE_OK ){
+    int rc2;
+    rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
+    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
+      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
+      if( zSql ){
+        int nParen = 0;           /* Number of open parenthesis */
+        int i;
+        for(i=0; zSql[i]; i++){
+          char c = zSql[i];
+          if( c=='(' ){
+            nParen++;
+          }
+          else if( c==')' ){
+            nParen--;
+            if( nParen==0 ){
+              i++;
+              break;
+            }
+          }else if( c=='"' || c=='\'' || c=='`' ){
+            for(i++; 1; i++){
+              if( zSql[i]==c ){
+                if( zSql[i+1]!=c ) break;
+                i++;
+              }
+            }
+          }else if( c=='[' ){
+            for(i++; 1; i++){
+              if( zSql[i]==']' ) break;
+            }
+          }
+        }
+        if( zSql[i] ){
+          zRet = rbuStrndup(&zSql[i], &rc);
+        }
+      }
+    }
+
+    rc2 = sqlite3_finalize(pStmt);
+    if( rc==SQLITE_OK ) rc = rc2;
+  }
+
+  p->rc = rc;
+  return zRet;
+}
+
 /*
 ** Ensure that the SQLite statement handles required to update the 
 ** target database object currently indicated by the iterator passed 
@@ -187579,6 +191765,7 @@ static int rbuObjIterPrepareAll(
       char *zImposterPK = 0;      /* Primary key declaration for imposter */
       char *zWhere = 0;           /* WHERE clause on PK columns */
       char *zBind = 0;
+      char *zPart = 0;
       int nBind = 0;
 
       assert( pIter->eType!=RBU_PK_VTAB );
@@ -187586,6 +191773,7 @@ static int rbuObjIterPrepareAll(
           p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
       );
       zBind = rbuObjIterGetBindlist(p, nBind);
+      zPart = rbuObjIterGetIndexWhere(p, pIter);
 
       /* Create the imposter table used to write to this index. */
       sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
@@ -187617,39 +191805,58 @@ static int rbuObjIterPrepareAll(
       if( p->rc==SQLITE_OK ){
         char *zSql;
         if( rbuIsVacuum(p) ){
+          char *zStart = 0;
+          if( nOffset ){
+            zStart = rbuVacuumIndexStart(p, pIter);
+            if( zStart ){
+              sqlite3_free(zLimit);
+              zLimit = 0;
+            }
+          }
+
           zSql = sqlite3_mprintf(
-              "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
+              "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s",
               zCollist, 
               pIter->zDataTbl,
+              zPart, 
+              (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart,
               zCollist, zLimit
           );
+          sqlite3_free(zStart);
         }else
 
         if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
           zSql = sqlite3_mprintf(
-              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
+              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
               zCollist, p->zStateDb, pIter->zDataTbl,
-              zCollist, zLimit
+              zPart, zCollist, zLimit
           );
         }else{
           zSql = sqlite3_mprintf(
-              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
+              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s "
               "UNION ALL "
               "SELECT %s, rbu_control FROM '%q' "
-              "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
+              "%s %s typeof(rbu_control)='integer' AND rbu_control!=1 "
               "ORDER BY %s%s",
-              zCollist, p->zStateDb, pIter->zDataTbl, 
+              zCollist, p->zStateDb, pIter->zDataTbl, zPart,
               zCollist, pIter->zDataTbl, 
+              zPart,
+              (zPart ? "AND" : "WHERE"),
               zCollist, zLimit
           );
         }
-        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
+        if( p->rc==SQLITE_OK ){
+          p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql);
+        }else{
+          sqlite3_free(zSql);
+        }
       }
 
       sqlite3_free(zImposterCols);
       sqlite3_free(zImposterPK);
       sqlite3_free(zWhere);
       sqlite3_free(zBind);
+      sqlite3_free(zPart);
     }else{
       int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
                     ||(pIter->eType==RBU_PK_NONE)
@@ -187742,18 +191949,42 @@ static int rbuObjIterPrepareAll(
       /* Create the SELECT statement to read keys from data_xxx */
       if( p->rc==SQLITE_OK ){
         const char *zRbuRowid = "";
+        char *zStart = 0;
+        char *zOrder = 0;
         if( bRbuRowid ){
           zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid";
         }
-        p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
-            sqlite3_mprintf(
-              "SELECT %s,%s rbu_control%s FROM '%q'%s", 
-              zCollist, 
-              (rbuIsVacuum(p) ? "0 AS " : ""),
-              zRbuRowid,
-              pIter->zDataTbl, zLimit
-            )
-        );
+
+        if( rbuIsVacuum(p) ){
+          if( nOffset ){
+            zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite);
+            if( zStart ){
+              sqlite3_free(zLimit);
+              zLimit = 0;
+            }
+          }
+          if( bRbuRowid ){
+            zOrder = rbuMPrintf(p, "_rowid_");
+          }else{
+            zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", "");
+          }
+        }
+
+        if( p->rc==SQLITE_OK ){
+          p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz,
+              sqlite3_mprintf(
+                "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s",
+                zCollist, 
+                (rbuIsVacuum(p) ? "0 AS " : ""),
+                zRbuRowid,
+                pIter->zDataTbl, (zStart ? zStart : ""), 
+                (zOrder ? "ORDER BY" : ""), zOrder,
+                zLimit
+              )
+          );
+        }
+        sqlite3_free(zStart);
+        sqlite3_free(zOrder);
       }
 
       sqlite3_free(zWhere);
@@ -188070,7 +192301,7 @@ static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
         if( *zExtra=='\0' ) zExtra = 0;
       }
 
-      zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", 
+      zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", 
           sqlite3_db_filename(p->dbRbu, "main"),
           (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
       );
@@ -189336,6 +193567,12 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
   const char *zState
 ){
   if( zTarget==0 ){ return rbuMisuseError(); }
+  if( zState ){
+    int n = strlen(zState);
+    if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
+      return rbuMisuseError();
+    }
+  }
   /* TODO: Check that both arguments are non-NULL */
   return openRbuHandle(0, zTarget, zState);
 }
@@ -189532,7 +193769,10 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
   if( p->eStage==RBU_STAGE_OAL ){
     assert( rc!=SQLITE_DONE );
     if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0);
-    if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0);
+    if( rc==SQLITE_OK ){ 
+      const char *zBegin = rbuIsVacuum(p) ? "BEGIN" : "BEGIN IMMEDIATE";
+      rc = sqlite3_exec(p->dbRbu, zBegin, 0, 0, 0);
+    }
     if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0);
   }
 
@@ -189625,6 +193865,69 @@ static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
   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.
 */
@@ -189642,17 +193945,14 @@ static int rbuVfsClose(sqlite3_file *pFile){
   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);
@@ -189911,6 +194211,7 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
       }else if( rc==SQLITE_NOTFOUND ){
         pRbu->pTargetFd = p;
         p->pRbu = pRbu;
+        rbuMainlistAdd(p);
         if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
         rc = SQLITE_OK;
       }
@@ -189973,10 +194274,7 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
     if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
   }else{
     int bCapture = 0;
-    if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
-     && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE
-     && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
-    ){
+    if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){
       bCapture = 1;
     }
 
@@ -190009,20 +194307,24 @@ static int rbuVfsShmMap(
   ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 
   ** instead of a file on disk.  */
   assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
-  if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
-    if( iRegion<=p->nShm ){
-      int nByte = (iRegion+1) * sizeof(char*);
-      char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
-      if( apNew==0 ){
-        rc = SQLITE_NOMEM;
-      }else{
-        memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
-        p->apShm = apNew;
-        p->nShm = iRegion+1;
-      }
+  if( eStage==RBU_STAGE_OAL ){
+    sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
+    char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
+
+    /* This is an RBU connection that uses its own heap memory for the
+    ** pages of the *-shm file. Since no other process can have run
+    ** recovery, the connection must request *-shm pages in order
+    ** from start to finish.  */
+    assert( iRegion==p->nShm );
+    if( apNew==0 ){
+      rc = SQLITE_NOMEM;
+    }else{
+      memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
+      p->apShm = apNew;
+      p->nShm = iRegion+1;
     }
 
-    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
+    if( rc==SQLITE_OK ){
       char *pNew = (char*)sqlite3_malloc64(szRegion);
       if( pNew==0 ){
         rc = SQLITE_NOMEM;
@@ -190072,20 +194374,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
   return rc;
 }
 
-/*
-** Given that zWal points to a buffer containing a wal file name passed to 
-** either the xOpen() or xAccess() VFS method, return a pointer to the
-** file-handle opened by the same database connection on the corresponding
-** database file.
-*/
-static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
-  rbu_file *pDb;
-  sqlite3_mutex_enter(pRbuVfs->mutex);
-  for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
-  sqlite3_mutex_leave(pRbuVfs->mutex);
-  return pDb;
-}
-
 /* 
 ** A main database named zName has just been opened. The following 
 ** function returns a pointer to a buffer owned by SQLite that contains
@@ -190164,7 +194452,7 @@ static int rbuVfsOpen(
       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
@@ -190216,10 +194504,7 @@ static int rbuVfsOpen(
     ** 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);
@@ -190267,8 +194552,9 @@ static int rbuVfsAccess(
   **      file opened instead.
   */
   if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
-    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
-    if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+    rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
+    if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){
+      assert( pDb->pRbu );
       if( *pResOut ){
         rc = SQLITE_CANTOPEN;
       }else{
@@ -190680,17 +194966,15 @@ static int statDisconnect(sqlite3_vtab *pVtab){
 static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
   int i;
 
-  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
-
   /* Look for a valid schema=? constraint.  If found, change the idxNum to
   ** 1 and request the value of that constraint be sent to xFilter.  And
   ** lower the cost estimate to encourage the constrained version to be
   ** used.
   */
   for(i=0; i<pIdxInfo->nConstraint; i++){
-    if( pIdxInfo->aConstraint[i].usable==0 ) continue;
-    if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
     if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+    if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
+    if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
     pIdxInfo->idxNum = 1;
     pIdxInfo->estimatedCost = 1.0;
     pIdxInfo->aConstraintUsage[i].argvIndex = 1;
@@ -190740,7 +195024,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
   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++){
@@ -190748,6 +195032,12 @@ static void statClearPage(StatPage *p){
     }
     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));
@@ -190810,22 +195100,33 @@ static int statDecodePage(Btree *pBt, StatPage *p){
   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;
-
-  isLeaf = (p->flags==0x0A || p->flags==0x0D);
-  nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+  szPage = sqlite3BtreeGetPageSize(pBt);
 
   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 */
@@ -190842,6 +195143,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
       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;
@@ -190858,13 +195160,14 @@ static int statDecodePage(Btree *pBt, StatPage *p){
         }
         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);
@@ -190888,6 +195191,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){
   }
 
   return SQLITE_OK;
+
+statPageIsCorrupt:
+  p->flags = 0;
+  statClearCells(p);
+  return SQLITE_OK;
 }
 
 /*
@@ -190995,6 +195303,10 @@ statNextRestart:
       goto statNextRestart; /* Tail recursion */
     }
     pCsr->iPage++;
+    if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
+      statResetCsr(pCsr);
+      return SQLITE_CORRUPT_BKPT;
+    }
     assert( p==&pCsr->aPage[pCsr->iPage-1] );
 
     if( p->iCell==p->nCell ){
@@ -191066,7 +195378,6 @@ static int statFilter(
   StatTable *pTab = (StatTable*)(pCursor->pVtab);
   char *zSql;
   int rc = SQLITE_OK;
-  char *zMaster;
 
   if( idxNum==1 ){
     const char *zDbase = (const char*)sqlite3_value_text(argv[0]);
@@ -191082,13 +195393,12 @@ static int statFilter(
   statResetCsr(pCsr);
   sqlite3_finalize(pCsr->pStmt);
   pCsr->pStmt = 0;
-  zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
   zSql = sqlite3_mprintf(
       "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
       "  UNION ALL  "
       "SELECT name, rootpage, type"
-      "  FROM \"%w\".%s WHERE rootpage!=0"
-      "  ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster);
+      "  FROM \"%w\".sqlite_master WHERE rootpage!=0"
+      "  ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName);
   if( zSql==0 ){
     return SQLITE_NOMEM_BKPT;
   }else{
@@ -191183,6 +195493,7 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
     0,                            /* xSavepoint */
     0,                            /* xRelease */
     0,                            /* xRollbackTo */
+    0                             /* xShadowName */
   };
   return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
 }
@@ -191313,9 +195624,8 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
     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;
@@ -191507,6 +195817,10 @@ static int dbpageUpdate(
   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;
@@ -191597,6 +195911,7 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
     0,                            /* xSavepoint */
     0,                            /* xRelease */
     0,                            /* xRollbackTo */
+    0                             /* xShadowName */
   };
   return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
 }
@@ -191633,6 +195948,8 @@ typedef struct SessionInput SessionInput;
 # endif
 #endif
 
+static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
+
 typedef struct SessionHook SessionHook;
 struct SessionHook {
   void *pCtx;
@@ -191695,6 +196012,7 @@ struct sqlite3_changeset_iter {
   SessionInput in;                /* Input buffer or stream */
   SessionBuffer tblhdr;           /* Buffer to hold apValue/zTab/abPK/ */
   int bPatchset;                  /* True if this is a patchset */
+  int bInvert;                    /* True to invert changeset */
   int rc;                         /* Iterator error code */
   sqlite3_stmt *pConflict;        /* Points to conflicting row, if any */
   char *zTab;                     /* Current table */
@@ -191851,6 +196169,42 @@ struct SessionTable {
 ** 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.
 */
 
 /*
@@ -191932,7 +196286,7 @@ static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){
 static int sessionSerializeValue(
   u8 *aBuf,                       /* If non-NULL, write serialized value here */
   sqlite3_value *pValue,          /* Value to serialize */
-  int *pnWrite                    /* IN/OUT: Increment by bytes written */
+  sqlite3_int64 *pnWrite          /* IN/OUT: Increment by bytes written */
 ){
   int nByte;                      /* Size of serialized value in bytes */
 
@@ -192471,9 +196825,9 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
   if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
     int i;
     SessionChange **apNew;
-    int nNew = (pTab->nChange ? pTab->nChange : 128) * 2;
+    sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);
 
-    apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew);
+    apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew);
     if( apNew==0 ){
       if( pTab->nChange==0 ){
         return SQLITE_ERROR;
@@ -192539,7 +196893,7 @@ static int sessionTableInfo(
   char *zPragma;
   sqlite3_stmt *pStmt;
   int rc;
-  int nByte;
+  sqlite3_int64 nByte;
   int nDbCol = 0;
   int nThis;
   int i;
@@ -192582,7 +196936,7 @@ static int sessionTableInfo(
 
   if( rc==SQLITE_OK ){
     nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1);
-    pAlloc = sqlite3_malloc(nByte);
+    pAlloc = sqlite3_malloc64(nByte);
     if( pAlloc==0 ){
       rc = SQLITE_NOMEM;
     }
@@ -192723,7 +197077,7 @@ static void sessionPreupdateOneChange(
   int iHash; 
   int bNull = 0; 
   int rc = SQLITE_OK;
-  SessionStat1Ctx stat1 = {0};
+  SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
 
   if( pSession->rc ) return;
 
@@ -192780,7 +197134,7 @@ static void sessionPreupdateOneChange(
       ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK
       ** values (if this is an INSERT). */
       SessionChange *pChange; /* New change object */
-      int nByte;              /* Number of bytes to allocate */
+      sqlite3_int64 nByte;    /* Number of bytes to allocate */
       int i;                  /* Used to iterate through columns */
   
       assert( rc==SQLITE_OK );
@@ -192805,7 +197159,7 @@ static void sessionPreupdateOneChange(
       }
   
       /* Allocate the change object */
-      pChange = (SessionChange *)sqlite3_malloc(nByte);
+      pChange = (SessionChange *)sqlite3_malloc64(nByte);
       if( !pChange ){
         rc = SQLITE_NOMEM;
         goto error_out;
@@ -193193,7 +197547,9 @@ SQLITE_API int sqlite3session_diff(
       }
       sqlite3_free((char*)azCol);
       if( bMismatch ){
-        *pzErrMsg = sqlite3_mprintf("table schemas do not match");
+        if( pzErrMsg ){
+          *pzErrMsg = sqlite3_mprintf("table schemas do not match");
+        }
         rc = SQLITE_SCHEMA;
       }
       if( bHasPk==0 ){
@@ -193249,7 +197605,7 @@ SQLITE_API int sqlite3session_create(
   *ppSession = 0;
 
   /* Allocate and populate the new session object. */
-  pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1);
+  pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1);
   if( !pNew ) return SQLITE_NOMEM;
   memset(pNew, 0, sizeof(sqlite3_session));
   pNew->db = db;
@@ -193368,7 +197724,7 @@ SQLITE_API int sqlite3session_attach(
 
     if( !pTab ){
       /* Allocate new SessionTable object. */
-      pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
+      pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1);
       if( !pTab ){
         rc = SQLITE_NOMEM;
       }else{
@@ -193398,15 +197754,15 @@ SQLITE_API int sqlite3session_attach(
 ** If successful, return zero. Otherwise, if an OOM condition is encountered,
 ** set *pRc to SQLITE_NOMEM and return non-zero.
 */
-static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
-  if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
+static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
+  if( *pRc==SQLITE_OK && (size_t)(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{
@@ -193428,7 +197784,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
 static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){
   int rc = *pRc;
   if( rc==SQLITE_OK ){
-    int nByte = 0;
+    sqlite3_int64 nByte = 0;
     rc = sessionSerializeValue(0, pVal, &nByte);
     sessionBufferGrow(p, nByte, &rc);
     if( rc==SQLITE_OK ){
@@ -194004,12 +198360,12 @@ static int sessionGenerateChangeset(
             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;
@@ -194148,7 +198504,8 @@ static int sessionChangesetStart(
   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 */
@@ -194168,6 +198525,7 @@ static int sessionChangesetStart(
   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;
@@ -194182,7 +198540,16 @@ SQLITE_API int sqlite3changeset_start(
   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);
 }
 
 /*
@@ -194193,7 +198560,16 @@ SQLITE_API int sqlite3changeset_start_strm(
   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);
 }
 
 /*
@@ -194201,7 +198577,7 @@ SQLITE_API int sqlite3changeset_start_strm(
 ** 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 ){
@@ -194224,7 +198600,7 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){
   int rc = SQLITE_OK;
   if( pIn->xInput ){
     while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
-      int nNew = SESSIONS_STRM_CHUNK_SIZE;
+      int nNew = sessions_strm_chunk_size;
 
       if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
       if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
@@ -194284,7 +198660,7 @@ static int sessionValueSetStr(
   ** argument to sqlite3ValueSetStr() and have the copy created 
   ** automatically. But doing so makes it difficult to detect any OOM
   ** error. Hence the code to create the copy externally. */
-  u8 *aCopy = sqlite3_malloc(nData+1);
+  u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1);
   if( aCopy==0 ) return SQLITE_NOMEM;
   memcpy(aCopy, aData, nData);
   sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free);
@@ -194496,7 +198872,7 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
   }
 
   if( rc==SQLITE_OK ){
-    int iPK = sizeof(sqlite3_value*)*p->nCol*2;
+    size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
     memset(p->tblhdr.aBuf, 0, iPK);
     memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
     p->in.iNext += nCopy;
@@ -194572,10 +198948,10 @@ static int sessionChangesetNext(
     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);
   }
 
@@ -194600,33 +198976,39 @@ static int sessionChangesetNext(
     *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;
     }
   }
 
@@ -194891,7 +199273,7 @@ static int sessionChangesetInvert(
         int iCol;
 
         if( 0==apVal ){
-          apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2);
+          apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2);
           if( 0==apVal ){
             rc = SQLITE_NOMEM;
             goto finished_invert;
@@ -194943,7 +199325,7 @@ static int sessionChangesetInvert(
     }
 
     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;
@@ -195022,7 +199404,8 @@ struct SessionApplyCtx {
   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 */
 };
 
 /*
@@ -195404,7 +199787,7 @@ static int sessionSeekToRow(
 }
 
 /*
-** This function is called from within sqlite3changset_apply_v2() when
+** This function is called from within sqlite3changeset_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 
@@ -195419,35 +199802,36 @@ static int sessionRebaseAdd(
   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;
-  }
-
-  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);
+  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;
     }
-    sessionAppendValue(&p->rebase, pVal, &rc);
-  }
 
+    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;
 }
 
@@ -195790,9 +200174,9 @@ static int sessionRetryConstraints(
     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*);
+      size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
       int rc2;
       pIter2->bPatchset = bPatchset;
       pIter2->zTab = (char*)zTab;
@@ -195856,6 +200240,7 @@ static int sessionChangesetApply(
 
   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);
@@ -196006,7 +200391,8 @@ static int sessionChangesetApply(
     }
   }
 
-  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;
@@ -196044,7 +200430,8 @@ SQLITE_API int sqlite3changeset_apply_v2(
   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
@@ -196101,7 +200488,8 @@ SQLITE_API int sqlite3changeset_apply_v2_strm(
   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
@@ -196158,7 +200546,7 @@ static int sessionChangeMerge(
   int rc = SQLITE_OK;
 
   if( !pExist ){
-    pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
+    pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec);
     if( !pNew ){
       return SQLITE_NOMEM;
     }
@@ -196191,8 +200579,8 @@ static int sessionChangeMerge(
     if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
       *ppNew = pExist;
     }else{
-      int nByte = nRec + pExist->nRecord + sizeof(SessionChange);
-      pNew = (SessionChange*)sqlite3_malloc(nByte);
+      sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange);
+      pNew = (SessionChange*)sqlite3_malloc64(nByte);
       if( pNew==0 ){
         rc = SQLITE_NOMEM;
       }else{
@@ -196252,14 +200640,14 @@ static int sessionChangeMerge(
       assert( pNew==0 );
     }else{
       u8 *aExist = pExist->aRecord;
-      int nByte;
+      sqlite3_int64 nByte;
       u8 *aCsr;
 
       /* Allocate a new SessionChange object. Ensure that the aRecord[]
       ** buffer of the new object is large enough to hold any record that
       ** may be generated by combining the input records.  */
       nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
-      pNew = (SessionChange *)sqlite3_malloc(nByte);
+      pNew = (SessionChange *)sqlite3_malloc64(nByte);
       if( !pNew ){
         sqlite3_free(pExist);
         return SQLITE_NOMEM;
@@ -196365,7 +200753,7 @@ static int sessionChangesetToHash(
       if( !pTab ){
         SessionTable **ppTab;
 
-        pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1);
+        pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
         if( !pTab ){
           rc = SQLITE_NOMEM;
           break;
@@ -196474,13 +200862,12 @@ static int sessionChangegroupOutput(
         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 ){
@@ -196871,7 +201258,7 @@ static int sessionRebase(
       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;
     }
@@ -196982,6 +201369,27 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){
   }
 }
 
+/* 
+** Global configuration
+*/
+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;
+    }
+    default:
+      rc = SQLITE_MISUSE;
+      break;
+  }
+  return rc;
+}
+
 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
 
 /************** End of sqlite3session.c **************************************/
@@ -197119,12 +201527,8 @@ struct Fts5PhraseIter {
 **
 **   Usually, output parameter *piPhrase is set to the phrase number, *piCol
 **   to the column in which it occurs and *piOff the token offset of the
-**   first token of the phrase. The exception is if the table was created
-**   with the offsets=0 option specified. In this case *piOff is always
-**   set to -1.
-**
-**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
-**   if an error occurs.
+**   first token of the phrase. Returns SQLITE_OK if successful, or an error
+**   code (i.e. SQLITE_NOMEM) if an error occurs.
 **
 **   This API can be quite slow if used with an FTS5 table created with the
 **   "detail=none" or "detail=column" option. 
@@ -197165,7 +201569,7 @@ struct Fts5PhraseIter {
 **   Save the pointer passed as the second argument as the extension functions 
 **   "auxiliary data". The pointer may then be retrieved by the current or any
 **   future invocation of the same fts5 extension function made as part of
-**   of the same MATCH query using the xGetAuxdata() API.
+**   the same MATCH query using the xGetAuxdata() API.
 **
 **   Each extension function is allocated a single auxiliary data slot for
 **   each FTS query (MATCH expression). If the extension function is invoked 
@@ -197180,7 +201584,7 @@ struct Fts5PhraseIter {
 **   The xDelete callback, if one is specified, is also invoked on the
 **   auxiliary data pointer after the FTS5 query has finished.
 **
-**   If an error (e.g. an OOM condition) occurs within this function, an
+**   If an error (e.g. an OOM condition) occurs within this function,
 **   the auxiliary data is set to NULL and an error code returned. If the
 **   xDelete parameter was not NULL, it is invoked on the auxiliary data
 **   pointer before returning.
@@ -197413,11 +201817,11 @@ struct Fts5ExtensionApi {
 **            the tokenizer substitutes "first" for "1st" and the query works
 **            as expected.
 **
-**       <li> By adding multiple synonyms for a single term to the FTS index.
-**            In this case, when tokenizing query text, the tokenizer may 
-**            provide multiple synonyms for a single term within the document.
-**            FTS5 then queries the index for each synonym individually. For
-**            example, faced with the query:
+**       <li> By querying the index for all synonyms of each query term
+**            separately. In this case, when tokenizing query text, the
+**            tokenizer may provide multiple synonyms for a single term 
+**            within the document. FTS5 then queries the index for each 
+**            synonym individually. For example, faced with the query:
 **
 **   <codeblock>
 **     ... MATCH 'first place'</codeblock>
@@ -197441,7 +201845,7 @@ struct Fts5ExtensionApi {
 **            "place".
 **
 **            This way, even if the tokenizer does not provide synonyms
-**            when tokenizing query text (it should not - to do would be
+**            when tokenizing query text (it should not - to do so would be
 **            inefficient), it doesn't matter if the user queries for 
 **            'first + place' or '1st + place', as there are entries in the
 **            FTS index corresponding to both forms of the first token.
@@ -197666,6 +202070,12 @@ SQLITE_API extern int sqlite3_fts5_may_be_corrupt;
 # define assert_nc(x) assert(x)
 #endif
 
+/*
+** A version of memcmp() that does not cause asan errors if one of the pointer
+** parameters is NULL and the number of bytes to compare is zero.
+*/
+#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
+
 /* Mark a function parameter as unused, to suppress nuisance compiler
 ** warnings. */
 #ifndef UNUSED_PARAM
@@ -197853,7 +202263,7 @@ static void sqlite3Fts5Put32(u8*, int);
 static int sqlite3Fts5Get32(const u8*);
 
 #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
-#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
+#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
 
 typedef struct Fts5PoslistReader Fts5PoslistReader;
 struct Fts5PoslistReader {
@@ -197888,7 +202298,7 @@ static int sqlite3Fts5PoslistNext64(
 );
 
 /* Malloc utility */
-static void *sqlite3Fts5MallocZero(int *pRc, int nByte);
+static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte);
 static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn);
 
 /* Character set tests (like isspace(), isalpha() etc.) */
@@ -198099,9 +202509,19 @@ static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
 
 
 /**************************************************************************
-** Interface to code in fts5.c. 
+** Interface to code in fts5_main.c. 
 */
 
+/*
+** Virtual-table object.
+*/
+typedef struct Fts5Table Fts5Table;
+struct Fts5Table {
+  sqlite3_vtab base;              /* Base class used by SQLite core */
+  Fts5Config *pConfig;            /* Virtual table configuration */
+  Fts5Index *pIndex;              /* Full-text index */
+};
+
 static int sqlite3Fts5GetTokenizer(
   Fts5Global*, 
   const char **azArg,
@@ -198111,7 +202531,9 @@ static int sqlite3Fts5GetTokenizer(
   char **pzErr
 );
 
-static Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **);
+static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
+
+static int sqlite3Fts5FlushToDisk(Fts5Table*);
 
 /*
 ** End of interface to code in fts5.c.
@@ -198144,8 +202566,9 @@ static void sqlite3Fts5HashClear(Fts5Hash*);
 
 static int sqlite3Fts5HashQuery(
   Fts5Hash*,                      /* Hash table to query */
+  int nPre,
   const char *pTerm, int nTerm,   /* Query term */
-  const u8 **ppDoclist,           /* OUT: Pointer to doclist for pTerm */
+  void **ppObj,                   /* OUT: Pointer to doclist for pTerm */
   int *pnDoclist                  /* OUT: Size of doclist in bytes */
 );
 
@@ -198367,7 +202790,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c);
 static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
 
 static int sqlite3Fts5UnicodeCatParse(const char*, u8*);
-static int sqlite3Fts5UnicodeCategory(int iCode);
+static int sqlite3Fts5UnicodeCategory(u32 iCode);
 static void sqlite3Fts5UnicodeAscii(u8*, u8*);
 /*
 ** End of interface to code in fts5_unicode2.c.
@@ -198416,6 +202839,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*);
 ** input grammar file:
 */
 /* #include <stdio.h> */
+/* #include <assert.h> */
 /************ Begin %include sections from the grammar ************************/
 
 /* #include "fts5Int.h" */
@@ -199270,41 +203694,70 @@ static void fts5yy_shift(
   fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
 }
 
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
-  fts5YYCODETYPE lhs;       /* Symbol on the left-hand side of the rule */
-  signed char nrhs;     /* Negative of the number of RHS symbols in the rule */
-} fts5yyRuleInfo[] = {
-  {   16,   -1 }, /* (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 ::= */
+/* For rule J, fts5yyRuleInfoLhs[J] contains the symbol on the left-hand side
+** of that rule */
+static const fts5YYCODETYPE fts5yyRuleInfoLhs[] = {
+    16,  /* (0) input ::= expr */
+    20,  /* (1) colset ::= MINUS LCP colsetlist RCP */
+    20,  /* (2) colset ::= LCP colsetlist RCP */
+    20,  /* (3) colset ::= STRING */
+    20,  /* (4) colset ::= MINUS STRING */
+    21,  /* (5) colsetlist ::= colsetlist STRING */
+    21,  /* (6) colsetlist ::= STRING */
+    17,  /* (7) expr ::= expr AND expr */
+    17,  /* (8) expr ::= expr OR expr */
+    17,  /* (9) expr ::= expr NOT expr */
+    17,  /* (10) expr ::= colset COLON LP expr RP */
+    17,  /* (11) expr ::= LP expr RP */
+    17,  /* (12) expr ::= exprlist */
+    19,  /* (13) exprlist ::= cnearset */
+    19,  /* (14) exprlist ::= exprlist cnearset */
+    18,  /* (15) cnearset ::= nearset */
+    18,  /* (16) cnearset ::= colset COLON nearset */
+    22,  /* (17) nearset ::= phrase */
+    22,  /* (18) nearset ::= CARET phrase */
+    22,  /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+    23,  /* (20) nearphrases ::= phrase */
+    23,  /* (21) nearphrases ::= nearphrases phrase */
+    25,  /* (22) neardist_opt ::= */
+    25,  /* (23) neardist_opt ::= COMMA STRING */
+    24,  /* (24) phrase ::= phrase PLUS STRING star_opt */
+    24,  /* (25) phrase ::= STRING star_opt */
+    26,  /* (26) star_opt ::= STAR */
+    26,  /* (27) star_opt ::= */
+};
+
+/* For rule J, fts5yyRuleInfoNRhs[J] contains the negative of the number
+** of symbols on the right-hand side of that rule. */
+static const signed char fts5yyRuleInfoNRhs[] = {
+   -1,  /* (0) input ::= expr */
+   -4,  /* (1) colset ::= MINUS LCP colsetlist RCP */
+   -3,  /* (2) colset ::= LCP colsetlist RCP */
+   -1,  /* (3) colset ::= STRING */
+   -2,  /* (4) colset ::= MINUS STRING */
+   -2,  /* (5) colsetlist ::= colsetlist STRING */
+   -1,  /* (6) colsetlist ::= STRING */
+   -3,  /* (7) expr ::= expr AND expr */
+   -3,  /* (8) expr ::= expr OR expr */
+   -3,  /* (9) expr ::= expr NOT expr */
+   -5,  /* (10) expr ::= colset COLON LP expr RP */
+   -3,  /* (11) expr ::= LP expr RP */
+   -1,  /* (12) expr ::= exprlist */
+   -1,  /* (13) exprlist ::= cnearset */
+   -2,  /* (14) exprlist ::= exprlist cnearset */
+   -1,  /* (15) cnearset ::= nearset */
+   -3,  /* (16) cnearset ::= colset COLON nearset */
+   -1,  /* (17) nearset ::= phrase */
+   -2,  /* (18) nearset ::= CARET phrase */
+   -5,  /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+   -1,  /* (20) nearphrases ::= phrase */
+   -2,  /* (21) nearphrases ::= nearphrases phrase */
+    0,  /* (22) neardist_opt ::= */
+   -2,  /* (23) neardist_opt ::= COMMA STRING */
+   -4,  /* (24) phrase ::= phrase PLUS STRING star_opt */
+   -2,  /* (25) phrase ::= STRING star_opt */
+   -1,  /* (26) star_opt ::= STAR */
+    0,  /* (27) star_opt ::= */
 };
 
 static void fts5yy_accept(fts5yyParser*);  /* Forward Declaration */
@@ -199336,7 +203789,7 @@ static fts5YYACTIONTYPE fts5yy_reduce(
   fts5yymsp = fts5yypParser->fts5yytos;
 #ifndef NDEBUG
   if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
-    fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+    fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
     if( fts5yysize ){
       fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
         fts5yyTracePrompt,
@@ -199351,7 +203804,7 @@ static fts5YYACTIONTYPE fts5yy_reduce(
   /* Check that the stack is large enough to grow by a single entry
   ** if the RHS of the rule is empty.  This ensures that there is room
   ** enough on the stack to push the LHS value */
-  if( fts5yyRuleInfo[fts5yyruleno].nrhs==0 ){
+  if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){
 #ifdef fts5YYTRACKMAXSTACKDEPTH
     if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){
       fts5yypParser->fts5yyhwm++;
@@ -199535,9 +203988,9 @@ static fts5YYACTIONTYPE fts5yy_reduce(
         break;
 /********** End reduce actions ************************************************/
   };
-  assert( fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
-  fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
-  fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
+  assert( fts5yyruleno<sizeof(fts5yyRuleInfoLhs)/sizeof(fts5yyRuleInfoLhs[0]) );
+  fts5yygoto = fts5yyRuleInfoLhs[fts5yyruleno];
+  fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
   fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto);
 
   /* There are no SHIFTREDUCE actions on nonterminals because the table
@@ -199743,10 +204196,9 @@ static void sqlite3Fts5Parser(
         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);
         }
@@ -199969,7 +204421,7 @@ static void fts5HighlightAppend(
   HighlightContext *p, 
   const char *z, int n
 ){
-  if( *pRc==SQLITE_OK ){
+  if( *pRc==SQLITE_OK && z ){
     if( n<0 ) n = (int)strlen(z);
     p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z);
     if( p->zOut==0 ) *pRc = SQLITE_NOMEM;
@@ -200101,7 +204553,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
     int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
     int *aNew;
 
-    aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
+    aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int));
     if( aNew==0 ) return SQLITE_NOMEM;
     p->aFirst = aNew;
     p->nFirstAlloc = nNew;
@@ -200168,11 +204620,12 @@ static int fts5SnippetScore(
   int nInst;
   int nScore = 0;
   int iLast = 0;
+  sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken;
 
   rc = pApi->xInstCount(pFts, &nInst);
   for(i=0; i<nInst && rc==SQLITE_OK; i++){
     rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
-    if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
+    if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){
       nScore += (aSeen[ip] ? 1 : 1000);
       aSeen[ip] = 1;
       if( iFirst<0 ) iFirst = iOff;
@@ -200182,10 +204635,10 @@ static int fts5SnippetScore(
 
   *pnScore = nScore;
   if( piPos ){
-    int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
+    sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
     if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
     if( iAdj<0 ) iAdj = 0;
-    *piPos = iAdj;
+    *piPos = (int)iAdj;
   }
 
   return rc;
@@ -200275,7 +204728,9 @@ static void fts5SnippetFunction(
         int jj;
 
         rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
-        if( ic!=i || rc!=SQLITE_OK ) continue;
+        if( ic!=i ) continue;
+        if( io>nDocsize ) rc = FTS5_CORRUPT;
+        if( rc!=SQLITE_OK ) continue;
         memset(aSeen, 0, nPhrase);
         rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
             io, nToken, &nScore, &iAdj
@@ -200401,17 +204856,17 @@ static int fts5Bm25GetData(
     int nPhrase;                  /* Number of phrases in query */
     sqlite3_int64 nRow = 0;       /* Number of rows in table */
     sqlite3_int64 nToken = 0;     /* Number of tokens in table */
-    int nByte;                    /* Bytes of space to allocate */
+    sqlite3_int64 nByte;          /* Bytes of space to allocate */
     int i;
 
     /* Allocate the Fts5Bm25Data object */
     nPhrase = pApi->xPhraseCount(pFts);
     nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double);
-    p = (Fts5Bm25Data*)sqlite3_malloc(nByte);
+    p = (Fts5Bm25Data*)sqlite3_malloc64(nByte);
     if( p==0 ){
       rc = SQLITE_NOMEM;
     }else{
-      memset(p, 0, nByte);
+      memset(p, 0, (size_t)nByte);
       p->nPhrase = nPhrase;
       p->aIDF = (double*)&p[1];
       p->aFreq = &p->aIDF[nPhrase];
@@ -200419,6 +204874,7 @@ static int fts5Bm25GetData(
 
     /* Calculate the average document length for this FTS5 table */
     if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow);
+    assert( rc!=SQLITE_OK || nRow>0 );
     if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken);
     if( rc==SQLITE_OK ) p->avgdl = (double)nToken  / (double)nRow;
 
@@ -200544,8 +205000,6 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){
   return rc;
 }
 
-
-
 /*
 ** 2014 May 31
 **
@@ -200565,17 +205019,17 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){
 
 static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){
   if( (u32)pBuf->nSpace<nByte ){
-    u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
+    u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64;
     u8 *pNew;
     while( nNew<nByte ){
       nNew = nNew * 2;
     }
-    pNew = sqlite3_realloc(pBuf->p, nNew);
+    pNew = sqlite3_realloc64(pBuf->p, nNew);
     if( pNew==0 ){
       *pRc = SQLITE_NOMEM;
       return 1;
     }else{
-      pBuf->nSpace = nNew;
+      pBuf->nSpace = (int)nNew;
       pBuf->p = pNew;
     }
   }
@@ -200600,7 +205054,7 @@ static void sqlite3Fts5Put32(u8 *aBuf, int iVal){
 }
 
 static int sqlite3Fts5Get32(const u8 *aBuf){
-  return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3];
+  return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]);
 }
 
 /*
@@ -200726,12 +205180,21 @@ static int sqlite3Fts5PoslistNext64(
     i64 iOff = *piOff;
     int iVal;
     fts5FastGetVarint32(a, i, iVal);
-    if( iVal==1 ){
+    if( iVal<=1 ){
+      if( iVal==0 ){
+        *pi = i;
+        return 0;
+      }
       fts5FastGetVarint32(a, i, iVal);
       iOff = ((i64)iVal) << 32;
       fts5FastGetVarint32(a, i, iVal);
+      if( iVal<2 ){
+        /* This is a corrupt record. So stop parsing it here. */
+        *piOff = -1;
+        return 1;
+      }
     }
-    *piOff = iOff + (iVal-2);
+    *piOff = iOff + ((iVal-2) & 0x7FFFFFFF);
     *pi = i;
     return 0;
   }
@@ -200792,14 +205255,14 @@ static int sqlite3Fts5PoslistWriterAppend(
   return SQLITE_OK;
 }
 
-static void *sqlite3Fts5MallocZero(int *pRc, int nByte){
+static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){
   void *pRet = 0;
   if( *pRc==SQLITE_OK ){
-    pRet = sqlite3_malloc(nByte);
+    pRet = sqlite3_malloc64(nByte);
     if( pRet==0 ){
       if( nByte>0 ) *pRc = SQLITE_NOMEM;
     }else{
-      memset(pRet, 0, nByte);
+      memset(pRet, 0, (size_t)nByte);
     }
   }
   return pRet;
@@ -201238,7 +205701,7 @@ static int fts5ConfigParseSpecial(
 
   if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
     const char *p = (const char*)zArg;
-    int nArg = (int)strlen(zArg) + 1;
+    sqlite3_int64 nArg = strlen(zArg) + 1;
     char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
     char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
     char *pSpace = pDel;
@@ -201268,7 +205731,7 @@ static int fts5ConfigParseSpecial(
           rc = SQLITE_ERROR;
         }else{
           rc = sqlite3Fts5GetTokenizer(pGlobal, 
-              (const char**)azArg, nArg, &pConfig->pTok, &pConfig->pTokApi,
+              (const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi,
               pzErr
           );
         }
@@ -201368,8 +205831,8 @@ static const char *fts5ConfigGobbleWord(
 ){
   const char *zRet = 0;
 
-  int nIn = (int)strlen(zIn);
-  char *zOut = sqlite3_malloc(nIn+1);
+  sqlite3_int64 nIn = strlen(zIn);
+  char *zOut = sqlite3_malloc64(nIn+1);
 
   assert( *pRc==SQLITE_OK );
   *pbQuoted = 0;
@@ -201378,7 +205841,7 @@ static const char *fts5ConfigGobbleWord(
   if( zOut==0 ){
     *pRc = SQLITE_NOMEM;
   }else{
-    memcpy(zOut, zIn, nIn+1);
+    memcpy(zOut, zIn, (size_t)(nIn+1));
     if( fts5_isopenquote(zOut[0]) ){
       int ii = fts5Dequote(zOut);
       zRet = &zIn[ii];
@@ -201472,7 +205935,7 @@ static int sqlite3Fts5ConfigParse(
   int rc = SQLITE_OK;             /* Return code */
   Fts5Config *pRet;               /* New object to return */
   int i;
-  int nByte;
+  sqlite3_int64 nByte;
 
   *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
   if( pRet==0 ) return SQLITE_NOMEM;
@@ -202116,7 +206579,7 @@ static int fts5ExprGetToken(
   return tok;
 }
 
-static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); }
+static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);}
 static void fts5ParseFree(void *p){ sqlite3_free(p); }
 
 static int sqlite3Fts5ExprNew(
@@ -202261,8 +206724,8 @@ static int fts5ExprSynonymList(
     if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){
       if( pIter->nData==0 ) continue;
       if( nIter==nAlloc ){
-        int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
-        Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+        sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
+        Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
         if( aNew==0 ){
           rc = SQLITE_NOMEM;
           goto synonym_poslist_out;
@@ -202342,8 +206805,8 @@ static int fts5ExprPhraseIsMatch(
   /* If the aStatic[] array is not large enough, allocate a large array
   ** using sqlite3_malloc(). This approach could be improved upon. */
   if( pPhrase->nTerm>ArraySize(aStatic) ){
-    int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
-    aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
+    sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
+    aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte);
     if( !aIter ) return SQLITE_NOMEM;
   }
   memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
@@ -202477,7 +206940,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
   /* If the aStatic[] array is not large enough, allocate a large array
   ** using sqlite3_malloc(). This approach could be improved upon. */
   if( pNear->nPhrase>ArraySize(aStatic) ){
-    int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
+    sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
     a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
   }else{
     memset(aStatic, 0, sizeof(aStatic));
@@ -203386,18 +207849,20 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
       return pNear;
     }
     if( pNear==0 ){
-      int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
-      pRet = sqlite3_malloc(nByte);
+      sqlite3_int64 nByte;
+      nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
+      pRet = sqlite3_malloc64(nByte);
       if( pRet==0 ){
         pParse->rc = SQLITE_NOMEM;
       }else{
-        memset(pRet, 0, nByte);
+        memset(pRet, 0, (size_t)nByte);
       }
     }else if( (pNear->nPhrase % SZALLOC)==0 ){
       int nNew = pNear->nPhrase + SZALLOC;
-      int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
+      sqlite3_int64 nByte;
 
-      pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte);
+      nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
+      pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
       if( pRet==0 ){
         pParse->rc = SQLITE_NOMEM;
       }
@@ -203461,12 +207926,12 @@ static int fts5ParseTokenize(
 
   if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){
     Fts5ExprTerm *pSyn;
-    int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
-    pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
+    sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
+    pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte);
     if( pSyn==0 ){
       rc = SQLITE_NOMEM;
     }else{
-      memset(pSyn, 0, nByte);
+      memset(pSyn, 0, (size_t)nByte);
       pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
       memcpy(pSyn->zTerm, pToken, nToken);
       pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
@@ -203478,7 +207943,7 @@ static int fts5ParseTokenize(
       Fts5ExprPhrase *pNew;
       int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
 
-      pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase, 
+      pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, 
           sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
       );
       if( pNew==0 ){
@@ -203564,9 +208029,9 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
 
     if( pAppend==0 ){
       if( (pParse->nPhrase % 8)==0 ){
-        int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
+        sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8);
         Fts5ExprPhrase **apNew;
-        apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte);
+        apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte);
         if( apNew==0 ){
           pParse->rc = SQLITE_NOMEM;
           fts5ExprPhraseFree(sCtx.pPhrase);
@@ -203621,10 +208086,12 @@ static int sqlite3Fts5ExprClonePhrase(
   if( rc==SQLITE_OK ){
     Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
     if( pColsetOrig ){
-      int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
-      Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
+      sqlite3_int64 nByte;
+      Fts5Colset *pColset;
+      nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
+      pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
       if( pColset ){ 
-        memcpy(pColset, pColsetOrig, nByte);
+        memcpy(pColset, pColsetOrig, (size_t)nByte);
       }
       pNew->pRoot->pNear->pColset = pColset;
     }
@@ -203742,7 +208209,7 @@ static Fts5Colset *fts5ParseColset(
   assert( pParse->rc==SQLITE_OK );
   assert( iCol>=0 && iCol<pParse->pConfig->nCol );
 
-  pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
+  pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
   if( pNew==0 ){
     pParse->rc = SQLITE_NOMEM;
   }else{
@@ -203838,10 +208305,10 @@ static Fts5Colset *sqlite3Fts5ParseColset(
 static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
   Fts5Colset *pRet;
   if( pOrig ){
-    int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
+    sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
     pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
     if( pRet ){ 
-      memcpy(pRet, pOrig, nByte);
+      memcpy(pRet, pOrig, (size_t)nByte);
     }
   }else{
     pRet = 0;
@@ -203992,7 +208459,7 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
 
   if( pParse->rc==SQLITE_OK ){
     int nChild = 0;               /* Number of children of returned node */
-    int nByte;                    /* Bytes of space to allocate for this node */
+    sqlite3_int64 nByte;          /* Bytes of space to allocate for this node */
  
     assert( (eType!=FTS5_STRING && !pNear)
          || (eType==FTS5_STRING && !pLeft && !pRight)
@@ -204124,7 +208591,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
 }
 
 static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
-  int nByte = 0;
+  sqlite3_int64 nByte = 0;
   Fts5ExprTerm *p;
   char *zQuoted;
 
@@ -204132,7 +208599,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){
   for(p=pTerm; p; p=p->pSynonym){
     nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2;
   }
-  zQuoted = sqlite3_malloc(nByte);
+  zQuoted = sqlite3_malloc64(nByte);
 
   if( zQuoted ){
     int i = 0;
@@ -204372,7 +208839,7 @@ static void fts5ExprFunction(
   }
 
   nConfig = 3 + (nArg-iArg);
-  azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig);
+  azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig);
   if( azConfig==0 ){
     sqlite3_result_error_nomem(pCtx);
     return;
@@ -204458,7 +208925,7 @@ static void fts5ExprIsAlnum(
   sqlite3Fts5UnicodeCatParse("N*", aArr);
   sqlite3Fts5UnicodeCatParse("Co", aArr);
   iCode = sqlite3_value_int(apVal[0]);
-  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
+  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
 }
 
 static void fts5ExprFold(
@@ -204553,7 +209020,7 @@ struct Fts5PoslistPopulator {
 
 static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
   Fts5PoslistPopulator *pRet;
-  pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
+  pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
   if( pRet ){
     int i;
     memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
@@ -204753,7 +209220,6 @@ static int sqlite3Fts5ExprPhraseCollist(
   return rc;
 }
 
-
 /*
 ** 2014 August 11
 **
@@ -204846,20 +209312,20 @@ static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte
   if( pNew==0 ){
     rc = SQLITE_NOMEM;
   }else{
-    int nByte;
+    sqlite3_int64 nByte;
     memset(pNew, 0, sizeof(Fts5Hash));
     pNew->pnByte = pnByte;
     pNew->eDetail = pConfig->eDetail;
 
     pNew->nSlot = 1024;
     nByte = sizeof(Fts5HashEntry*) * pNew->nSlot;
-    pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte);
+    pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte);
     if( pNew->aSlot==0 ){
       sqlite3_free(pNew);
       *ppNew = 0;
       rc = SQLITE_NOMEM;
     }else{
-      memset(pNew->aSlot, 0, nByte);
+      memset(pNew->aSlot, 0, (size_t)nByte);
     }
   }
   return rc;
@@ -204921,7 +209387,7 @@ static int fts5HashResize(Fts5Hash *pHash){
   Fts5HashEntry **apNew;
   Fts5HashEntry **apOld = pHash->aSlot;
 
-  apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*));
+  apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*));
   if( !apNew ) return SQLITE_NOMEM;
   memset(apNew, 0, nNew*sizeof(Fts5HashEntry*));
 
@@ -204943,19 +209409,25 @@ static int fts5HashResize(Fts5Hash *pHash){
   return SQLITE_OK;
 }
 
-static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
+static int fts5HashAddPoslistSize(
+  Fts5Hash *pHash, 
+  Fts5HashEntry *p,
+  Fts5HashEntry *p2
+){
+  int nRet = 0;
   if( p->iSzPoslist ){
-    u8 *pPtr = (u8*)p;
+    u8 *pPtr = p2 ? (u8*)p2 : (u8*)p;
+    int nData = p->nData;
     if( pHash->eDetail==FTS5_DETAIL_NONE ){
-      assert( p->nData==p->iSzPoslist );
+      assert( nData==p->iSzPoslist );
       if( p->bDel ){
-        pPtr[p->nData++] = 0x00;
+        pPtr[nData++] = 0x00;
         if( p->bContent ){
-          pPtr[p->nData++] = 0x00;
+          pPtr[nData++] = 0x00;
         }
       }
     }else{
-      int nSz = (p->nData - p->iSzPoslist - 1);       /* Size in bytes */
+      int nSz = (nData - p->iSzPoslist - 1);       /* Size in bytes */
       int nPos = nSz*2 + p->bDel;                     /* Value of nPos field */
 
       assert( p->bDel==0 || p->bDel==1 );
@@ -204965,14 +209437,19 @@ static void fts5HashAddPoslistSize(Fts5Hash *pHash, Fts5HashEntry *p){
         int nByte = sqlite3Fts5GetVarintLen((u32)nPos);
         memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz);
         sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos);
-        p->nData += (nByte-1);
+        nData += (nByte-1);
       }
     }
 
-    p->iSzPoslist = 0;
-    p->bDel = 0;
-    p->bContent = 0;
+    nRet = nData - p->nData;
+    if( p2==0 ){
+      p->iSzPoslist = 0;
+      p->bDel = 0;
+      p->bContent = 0;
+      p->nData = nData;
+    }
   }
+  return nRet;
 }
 
 /*
@@ -205015,7 +209492,7 @@ static int sqlite3Fts5HashWrite(
   if( p==0 ){
     /* Figure out how much space to allocate */
     char *zKey;
-    int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
+    sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64;
     if( nByte<128 ) nByte = 128;
 
     /* Grow the Fts5Hash.aSlot[] array if necessary. */
@@ -205026,10 +209503,10 @@ static int sqlite3Fts5HashWrite(
     }
 
     /* Allocate new Fts5HashEntry and add it to the hash table. */
-    p = (Fts5HashEntry*)sqlite3_malloc(nByte);
+    p = (Fts5HashEntry*)sqlite3_malloc64(nByte);
     if( !p ) return SQLITE_NOMEM;
     memset(p, 0, sizeof(Fts5HashEntry));
-    p->nAlloc = nByte;
+    p->nAlloc = (int)nByte;
     zKey = fts5EntryKey(p);
     zKey[0] = bByte;
     memcpy(&zKey[1], pToken, nToken);
@@ -205065,12 +209542,12 @@ static int sqlite3Fts5HashWrite(
     **     + 5 bytes for the new position offset (32-bit max).
     */
     if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){
-      int nNew = p->nAlloc * 2;
+      sqlite3_int64 nNew = p->nAlloc * 2;
       Fts5HashEntry *pNew;
       Fts5HashEntry **pp;
-      pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew);
+      pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew);
       if( pNew==0 ) return SQLITE_NOMEM;
-      pNew->nAlloc = nNew;
+      pNew->nAlloc = (int)nNew;
       for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext);
       *pp = pNew;
       p = pNew;
@@ -205084,7 +209561,7 @@ static int sqlite3Fts5HashWrite(
   /* If this is a new rowid, append the 4-byte size field for the previous
   ** entry, and the new rowid for this entry.  */
   if( iRowid!=p->iRowid ){
-    fts5HashAddPoslistSize(pHash, p);
+    fts5HashAddPoslistSize(pHash, p, 0);
     p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid);
     p->iRowid = iRowid;
     bNew = 1;
@@ -205194,14 +209671,16 @@ static int fts5HashEntrySort(
   int i;
 
   *ppSorted = 0;
-  ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot);
+  ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot);
   if( !ap ) return SQLITE_NOMEM;
   memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot);
 
   for(iSlot=0; iSlot<pHash->nSlot; iSlot++){
     Fts5HashEntry *pIter;
     for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){
-      if( pTerm==0 || 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm) ){
+      if( pTerm==0 
+       || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm))
+      ){
         Fts5HashEntry *pEntry = pIter;
         pEntry->pScanNext = 0;
         for(i=0; ap[i]; i++){
@@ -205229,8 +209708,9 @@ static int fts5HashEntrySort(
 */
 static int sqlite3Fts5HashQuery(
   Fts5Hash *pHash,                /* Hash table to query */
+  int nPre,
   const char *pTerm, int nTerm,   /* Query term */
-  const u8 **ppDoclist,           /* OUT: Pointer to doclist for pTerm */
+  void **ppOut,                   /* OUT: Pointer to new object */
   int *pnDoclist                  /* OUT: Size of doclist in bytes */
 ){
   unsigned int iHash = fts5HashKey(pHash->nSlot, (const u8*)pTerm, nTerm);
@@ -205239,15 +209719,25 @@ static int sqlite3Fts5HashQuery(
 
   for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
     zKey = fts5EntryKey(p);
-    if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break;
+    assert( p->nKey+1==(int)strlen(zKey) );
+    if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break;
   }
 
   if( p ){
-    fts5HashAddPoslistSize(pHash, p);
-    *ppDoclist = (const u8*)&zKey[nTerm+1];
-    *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
+    int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1;
+    int nList = p->nData - nHashPre;
+    u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10));
+    if( pRet ){
+      Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre];
+      memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList);
+      nList += fts5HashAddPoslistSize(pHash, p, pFaux);
+      *pnDoclist = nList;
+    }else{
+      *pnDoclist = 0;
+      return SQLITE_NOMEM;
+    }
   }else{
-    *ppDoclist = 0;
+    *ppOut = 0;
     *pnDoclist = 0;
   }
 
@@ -205280,7 +209770,7 @@ static void sqlite3Fts5HashScanEntry(
   if( (p = pHash->pScan) ){
     char *zKey = fts5EntryKey(p);
     int nTerm = (int)strlen(zKey);
-    fts5HashAddPoslistSize(pHash, p);
+    fts5HashAddPoslistSize(pHash, p, 0);
     *pzTerm = zKey;
     *ppDoclist = (const u8*)&zKey[nTerm+1];
     *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1);
@@ -205291,7 +209781,6 @@ static void sqlite3Fts5HashScanEntry(
   }
 }
 
-
 /*
 ** 2014 May 31
 **
@@ -205806,7 +210295,6 @@ struct Fts5Iter {
   Fts5IndexIter base;             /* Base class containing output vars */
 
   Fts5Index *pIndex;              /* Index that owns this iterator */
-  Fts5Structure *pStruct;         /* Database structure for this iterator */
   Fts5Buffer poslist;             /* Buffer containing current poslist */
   Fts5Colset *pColset;            /* Restrict matches to these columns */
 
@@ -205867,7 +210355,7 @@ static u16 fts5GetU16(const u8 *aIn){
 ** If an OOM error is encountered, return NULL and set the error code in
 ** the Fts5Index handle passed as the first argument.
 */
-static void *fts5IdxMalloc(Fts5Index *p, int nByte){
+static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){
   return sqlite3Fts5MallocZero(&p->rc, nByte);
 }
 
@@ -205901,7 +210389,7 @@ static int fts5BufferCompareBlob(
 */
 static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
   int nCmp = MIN(pLeft->n, pRight->n);
-  int res = memcmp(pLeft->p, pRight->p, nCmp);
+  int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
   return (res==0 ? (pLeft->n - pRight->n) : res);
 }
 
@@ -205967,8 +210455,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
     if( rc==SQLITE_OK ){
       u8 *aOut = 0;               /* Read blob data into this buffer */
       int nByte = sqlite3_blob_bytes(p->pReader);
-      int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
-      pRet = (Fts5Data*)sqlite3_malloc(nAlloc);
+      sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
+      pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
       if( pRet ){
         pRet->nn = nByte;
         aOut = pRet->p = (u8*)&pRet[1];
@@ -205984,6 +210472,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
         pRet = 0;
       }else{
         /* TODO1: Fix this */
+        pRet->p[nByte] = 0x00;
         pRet->szLeaf = fts5GetU16(&pRet->p[2]);
       }
     }
@@ -206023,7 +210512,8 @@ static int fts5IndexPrepareStmt(
   if( p->rc==SQLITE_OK ){
     if( zSql ){
       p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
-                                 SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
+          SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
+          ppStmt, 0);
     }else{
       p->rc = SQLITE_NOMEM;
     }
@@ -206064,23 +210554,12 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
   if( p->rc!=SQLITE_OK ) return;
 
   if( p->pDeleter==0 ){
-    int rc;
     Fts5Config *pConfig = p->pConfig;
     char *zSql = sqlite3_mprintf(
         "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
           pConfig->zDb, pConfig->zName
     );
-    if( zSql==0 ){
-      rc = SQLITE_NOMEM;
-    }else{
-      rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
-                              SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
-      sqlite3_free(zSql);
-    }
-    if( rc!=SQLITE_OK ){
-      p->rc = rc;
-      return;
-    }
+    if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;
   }
 
   sqlite3_bind_int64(p->pDeleter, 1, iFirst);
@@ -206152,7 +210631,7 @@ static int fts5StructureDecode(
   int iLvl;
   int nLevel = 0;
   int nSegment = 0;
-  int nByte;                      /* Bytes of space to allocate at pRet */
+  sqlite3_int64 nByte;            /* Bytes of space to allocate at pRet */
   Fts5Structure *pRet = 0;        /* Structure object to return */
 
   /* Grab the cookie value */
@@ -206163,6 +210642,11 @@ static int fts5StructureDecode(
   ** structure record.  */
   i += fts5GetVarint32(&pData[i], nLevel);
   i += fts5GetVarint32(&pData[i], nSegment);
+  if( nLevel>FTS5_MAX_SEGMENT   || nLevel<0
+   || nSegment>FTS5_MAX_SEGMENT || nSegment<0
+  ){
+    return FTS5_CORRUPT;
+  }
   nByte = (
       sizeof(Fts5Structure) +                    /* Main structure */
       sizeof(Fts5StructureLevel) * (nLevel-1)    /* aLevel[] array */
@@ -206185,25 +210669,35 @@ static int fts5StructureDecode(
       }else{
         i += fts5GetVarint32(&pData[i], pLvl->nMerge);
         i += fts5GetVarint32(&pData[i], nTotal);
-        assert( nTotal>=pLvl->nMerge );
+        if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
         pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
             nTotal * sizeof(Fts5StructureSegment)
         );
+        nSegment -= nTotal;
       }
 
       if( rc==SQLITE_OK ){
         pLvl->nSeg = nTotal;
         for(iSeg=0; iSeg<nTotal; iSeg++){
+          Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
           if( i>=nData ){
             rc = FTS5_CORRUPT;
             break;
           }
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
+          i += fts5GetVarint32(&pData[i], pSeg->iSegid);
+          i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
+          i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
+          if( pSeg->pgnoLast<pSeg->pgnoFirst ){
+            rc = FTS5_CORRUPT;
+            break;
+          }
         }
+        if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
+        if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
       }
     }
+    if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
+
     if( rc!=SQLITE_OK ){
       fts5StructureRelease(pRet);
       pRet = 0;
@@ -206221,12 +210715,12 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
   if( *pRc==SQLITE_OK ){
     Fts5Structure *pStruct = *ppStruct;
     int nLevel = pStruct->nLevel;
-    int nByte = (
+    sqlite3_int64 nByte = (
         sizeof(Fts5Structure) +                  /* Main structure */
         sizeof(Fts5StructureLevel) * (nLevel+1)  /* aLevel[] array */
     );
 
-    pStruct = sqlite3_realloc(pStruct, nByte);
+    pStruct = sqlite3_realloc64(pStruct, nByte);
     if( pStruct ){
       memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel));
       pStruct->nLevel++;
@@ -206251,10 +210745,10 @@ static void fts5StructureExtendLevel(
   if( *pRc==SQLITE_OK ){
     Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
     Fts5StructureSegment *aNew;
-    int nByte;
+    sqlite3_int64 nByte;
 
     nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment);
-    aNew = sqlite3_realloc(pLvl->aSeg, nByte);
+    aNew = sqlite3_realloc64(pLvl->aSeg, nByte);
     if( aNew ){
       if( bInsert==0 ){
         memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra);
@@ -206281,7 +210775,7 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){
     /* TODO: Do we need this if the leaf-index is appended? Probably... */
     memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING);
     p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet);
-    if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){
+    if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){
       p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie);
     }
     fts5DataRelease(pData);
@@ -206768,10 +211262,10 @@ static Fts5DlidxIter *fts5DlidxIterInit(
   int bDone = 0;
 
   for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
-    int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
+    sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
     Fts5DlidxIter *pNew;
 
-    pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte);
+    pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
     if( pNew==0 ){
       p->rc = SQLITE_NOMEM;
     }else{
@@ -206941,12 +211435,13 @@ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
   int nNew;                       /* Bytes of new data */
 
   iOff += fts5GetVarint32(&a[iOff], nNew);
-  if( iOff+nNew>pIter->pLeaf->nn ){
+  if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){
     p->rc = FTS5_CORRUPT;
     return;
   }
   pIter->term.n = nKeep;
   fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+  assert( pIter->term.n<=pIter->term.nSpace );
   iOff += nNew;
   pIter->iTermLeafOffset = iOff;
   pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -207011,7 +211506,7 @@ static void fts5SegIterInit(
   if( p->rc==SQLITE_OK ){
     pIter->iLeafOffset = 4;
     assert_nc( pIter->pLeaf->nn>4 );
-    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
+    assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
     pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
     fts5SegIterLoadTerm(p, pIter, 0);
     fts5SegIterLoadNPos(p, pIter);
@@ -207067,7 +211562,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){
     /* If necessary, grow the pIter->aRowidOffset[] array. */
     if( iRowidOffset>=pIter->nRowidOffset ){
       int nNew = pIter->nRowidOffset + 8;
-      int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int));
+      int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int));
       if( aNew==0 ){
         p->rc = SQLITE_NOMEM;
         break;
@@ -207521,10 +212016,10 @@ static void fts5LeafSeek(
   int szLeaf = pIter->pLeaf->szLeaf;
   int n = pIter->pLeaf->nn;
 
-  int nMatch = 0;
-  int nKeep = 0;
-  int nNew = 0;
-  int iTermOff;
+  u32 nMatch = 0;
+  u32 nKeep = 0;
+  u32 nNew = 0;
+  u32 iTermOff;
   int iPgidx;                     /* Current offset in pgidx */
   int bEndOfPage = 0;
 
@@ -207548,15 +212043,15 @@ static void fts5LeafSeek(
 
     assert( nKeep>=nMatch );
     if( nKeep==nMatch ){
-      int nCmp;
-      int i;
-      nCmp = MIN(nNew, nTerm-nMatch);
+      u32 nCmp;
+      u32 i;
+      nCmp = (u32)MIN(nNew, nTerm-nMatch);
       for(i=0; i<nCmp; i++){
         if( a[iOff+i]!=pTerm[nMatch+i] ) break;
       }
       nMatch += i;
 
-      if( nTerm==nMatch ){
+      if( (u32)nTerm==nMatch ){
         if( i==nNew ){
           goto search_success;
         }else{
@@ -207600,6 +212095,7 @@ static void fts5LeafSeek(
         iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
         if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
           p->rc = FTS5_CORRUPT;
+          return;
         }else{
           nKeep = 0;
           iTermOff = iOff;
@@ -207612,8 +212108,11 @@ static void fts5LeafSeek(
   }
 
  search_success:
-
   pIter->iLeafOffset = iOff + nNew;
+  if( pIter->iLeafOffset>n || nNew<1 ){
+    p->rc = FTS5_CORRUPT;
+    return;
+  }
   pIter->iTermLeafOffset = pIter->iLeafOffset;
   pIter->iTermLeafPgno = pIter->iLeafPgno;
 
@@ -207720,7 +212219,7 @@ static void fts5SegIterSeekInit(
   **   4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points
   **      to an entry with a term greater than or equal to (pTerm/nTerm).
   */
-  assert( p->rc!=SQLITE_OK                                          /* 1 */
+  assert_nc( p->rc!=SQLITE_OK                                       /* 1 */
    || pIter->pLeaf==0                                               /* 2 */
    || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0          /* 3 */
    || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0)  /* 4 */
@@ -207741,31 +212240,40 @@ static void fts5SegIterHashInit(
   int flags,                      /* Mask of FTS5INDEX_XXX flags */
   Fts5SegIter *pIter              /* Object to populate */
 ){
-  const u8 *pList = 0;
   int nList = 0;
   const u8 *z = 0;
   int n = 0;
+  Fts5Data *pLeaf = 0;
 
   assert( p->pHash );
   assert( p->rc==SQLITE_OK );
 
   if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){
+    const u8 *pList = 0;
+
     p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm);
     sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList);
     n = (z ? (int)strlen((const char*)z) : 0);
+    if( pList ){
+      pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
+      if( pLeaf ){
+        pLeaf->p = (u8*)pList;
+      }
+    }
   }else{
-    pIter->flags |= FTS5_SEGITER_ONETERM;
-    sqlite3Fts5HashQuery(p->pHash, (const char*)pTerm, nTerm, &pList, &nList);
+    p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), 
+        (const char*)pTerm, nTerm, (void**)&pLeaf, &nList
+    );
+    if( pLeaf ){
+      pLeaf->p = (u8*)&pLeaf[1];
+    }
     z = pTerm;
     n = nTerm;
+    pIter->flags |= FTS5_SEGITER_ONETERM;
   }
 
-  if( pList ){
-    Fts5Data *pLeaf;
+  if( pLeaf ){
     sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z);
-    pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
-    if( pLeaf==0 ) return;
-    pLeaf->p = (u8*)pList;
     pLeaf->nn = pLeaf->szLeaf = nList;
     pIter->pLeaf = pLeaf;
     pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid);
@@ -207818,7 +212326,7 @@ static void fts5AssertComparisonResult(
       assert( pRes->iFirst==i1 );
     }else{
       int nMin = MIN(p1->term.n, p2->term.n);
-      int res = memcmp(p1->term.p, p2->term.p, nMin);
+      int res = fts5Memcmp(p1->term.p, p2->term.p, nMin);
       if( res==0 ) res = p1->term.n - p2->term.n;
 
       if( res==0 ){
@@ -207918,8 +212426,8 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
   }else{
     int res = fts5BufferCompare(&p1->term, &p2->term);
     if( res==0 ){
-      assert( i2>i1 );
-      assert( i2!=0 );
+      assert_nc( i2>i1 );
+      assert_nc( i2!=0 );
       pRes->bTermEq = 1;
       if( p1->iRowid==p2->iRowid ){
         p1->bDel = p2->bDel;
@@ -208041,7 +212549,6 @@ static void fts5MultiIterFree(Fts5Iter *pIter){
     for(i=0; i<pIter->nSeg; i++){
       fts5SegIterClear(&pIter->aSeg[i]);
     }
-    fts5StructureRelease(pIter->pStruct);
     fts5BufferFree(&pIter->poslist);
     sqlite3_free(pIter);
   }
@@ -208389,7 +212896,8 @@ static void fts5SegiterPoslist(
   Fts5Colset *pColset,
   Fts5Buffer *pBuf
 ){
-  if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
+  if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
+    memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
     if( pColset==0 ){
       fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
     }else{
@@ -208687,9 +213195,7 @@ static void fts5MultiIterNew(
   if( pNew==0 ) return;
   pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
   pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
-  pNew->pStruct = pStruct;
   pNew->pColset = pColset;
-  fts5StructureRef(pStruct);
   if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
     fts5IterSetOutputCb(&p->rc, pNew);
   }
@@ -208867,24 +213373,24 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
       for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
         for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
           int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
-          if( iId<=FTS5_MAX_SEGMENT ){
-            aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
+          if( iId<=FTS5_MAX_SEGMENT && iId>0 ){
+            aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
           }
         }
       }
 
       for(i=0; aUsed[i]==0xFFFFFFFF; i++);
       mask = aUsed[i];
-      for(iSegid=0; mask & (1 << iSegid); iSegid++);
+      for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
       iSegid += 1 + i*32;
 
 #ifdef SQLITE_DEBUG
       for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
         for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
-          assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
+          assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
         }
       }
-      assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
+      assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
 
       {
         sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
@@ -208892,7 +213398,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){
           u8 aBlob[2] = {0xff, 0xff};
           sqlite3_bind_int(pIdxSelect, 1, iSegid);
           sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
-          assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
+          assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
           p->rc = sqlite3_reset(pIdxSelect);
           sqlite3_bind_null(pIdxSelect, 2);
         }
@@ -208962,13 +213468,13 @@ static int fts5WriteDlidxGrow(
   int nLvl
 ){
   if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
-    Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc(
+    Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64(
         pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
     );
     if( aDlidx==0 ){
       p->rc = SQLITE_NOMEM;
     }else{
-      int nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
+      size_t nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
       memset(&aDlidx[pWriter->nDlidx], 0, nByte);
       pWriter->aDlidx = aDlidx;
       pWriter->nDlidx = nLvl;
@@ -209041,8 +213547,10 @@ static void fts5WriteBtreeTerm(
   int nTerm, const u8 *pTerm      /* First term on new page */
 ){
   fts5WriteFlushBtree(p, pWriter);
-  fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
-  pWriter->iBtPage = pWriter->writer.pgno;
+  if( p->rc==SQLITE_OK ){
+    fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm);
+    pWriter->iBtPage = pWriter->writer.pgno;
+  }
 }
 
 /*
@@ -209193,6 +213701,7 @@ static void fts5WriteAppendTerm(
   int nPrefix;                    /* Bytes of prefix compression for term */
   Fts5PageWriter *pPage = &pWriter->writer;
   Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
+  int nMin = MIN(pPage->term.n, nTerm);
 
   assert( p->rc==SQLITE_OK );
   assert( pPage->buf.n>=4 );
@@ -209202,6 +213711,7 @@ static void fts5WriteAppendTerm(
   if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
     if( pPage->buf.n>4 ){
       fts5WriteFlushLeaf(p, pWriter);
+      if( p->rc!=SQLITE_OK ) return;
     }
     fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING);
   }
@@ -209234,13 +213744,14 @@ static void fts5WriteAppendTerm(
       ** inefficient, but still correct.  */
       int n = nTerm;
       if( pPage->term.n ){
-        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+        n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
       }
       fts5WriteBtreeTerm(p, pWriter, n, pTerm);
+      if( p->rc!=SQLITE_OK ) return;
       pPage = &pWriter->writer;
     }
   }else{
-    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+    nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
     fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
   }
 
@@ -209287,7 +213798,7 @@ static void fts5WriteAppendRowid(
     if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){
       fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid);
     }else{
-      assert( p->rc || iRowid>pWriter->iPrevRowid );
+      assert_nc( p->rc || iRowid>pWriter->iPrevRowid );
       fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid);
     }
     pWriter->iPrevRowid = iRowid;
@@ -209409,7 +213920,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
   int i;
   Fts5Buffer buf;
   memset(&buf, 0, sizeof(Fts5Buffer));
-  for(i=0; i<pIter->nSeg; i++){
+  for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){
     Fts5SegIter *pSeg = &pIter->aSeg[i];
     if( pSeg->pSeg==0 ){
       /* no-op */
@@ -209427,35 +213938,44 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
       u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00};
 
       iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno);
-      pData = fts5DataRead(p, iLeafRowid);
+      pData = fts5LeafRead(p, iLeafRowid);
       if( pData ){
-        fts5BufferZero(&buf);
-        fts5BufferGrow(&p->rc, &buf, pData->nn);
-        fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
-        fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
-        fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
-        fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]);
-        if( p->rc==SQLITE_OK ){
-          /* Set the szLeaf field */
-          fts5PutU16(&buf.p[2], (u16)buf.n);
-        }
+        if( iOff>pData->szLeaf ){
+          /* This can occur if the pages that the segments occupy overlap - if
+          ** a single page has been assigned to more than one segment. In
+          ** this case a prior iteration of this loop may have corrupted the
+          ** segment currently being trimmed.  */
+          p->rc = FTS5_CORRUPT;
+        }else{
+          fts5BufferZero(&buf);
+          fts5BufferGrow(&p->rc, &buf, pData->nn);
+          fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
+          fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
+          fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
+          fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]);
+          if( p->rc==SQLITE_OK ){
+            /* Set the szLeaf field */
+            fts5PutU16(&buf.p[2], (u16)buf.n);
+          }
 
-        /* Set up the new page-index array */
-        fts5BufferAppendVarint(&p->rc, &buf, 4);
-        if( pSeg->iLeafPgno==pSeg->iTermLeafPgno 
-         && pSeg->iEndofDoclist<pData->szLeaf 
-        ){
-          int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
-          fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
-          fts5BufferAppendBlob(&p->rc, &buf, 
-              pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
-          );
-        }
+          /* Set up the new page-index array */
+          fts5BufferAppendVarint(&p->rc, &buf, 4);
+          if( pSeg->iLeafPgno==pSeg->iTermLeafPgno 
+           && pSeg->iEndofDoclist<pData->szLeaf
+           && pSeg->iPgidxOff<=pData->nn
+          ){
+            int nDiff = pData->szLeaf - pSeg->iEndofDoclist;
+            fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4);
+            fts5BufferAppendBlob(&p->rc, &buf, 
+                pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff]
+            );
+          }
 
+          pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
+          fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
+          fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
+        }
         fts5DataRelease(pData);
-        pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno;
-        fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid);
-        fts5DataWrite(p, iLeafRowid, buf.p, buf.n);
       }
     }
   }
@@ -209547,7 +214067,7 @@ static void fts5IndexMergeLevel(
     const u8 *pTerm;
 
     pTerm = fts5MultiIterTerm(pIter, &nTerm);
-    if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){
+    if( nTerm!=term.n || fts5Memcmp(pTerm, term.p, nTerm) ){
       if( pnRem && writer.nLeafWritten>nRem ){
         break;
       }
@@ -209802,6 +214322,7 @@ static void fts5FlushOneHash(Fts5Index *p){
       /* Write the term for this entry to disk. */
       sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
       fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
+      if( p->rc!=SQLITE_OK ) break;
 
       assert( writer.bFirstRowidInPage==0 );
       if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
@@ -209824,6 +214345,7 @@ static void fts5FlushOneHash(Fts5Index *p){
             pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
             writer.bFirstRowidInPage = 0;
             fts5WriteDlidxAppend(p, &writer, iRowid);
+            if( p->rc!=SQLITE_OK ) break;
           }else{
             pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
           }
@@ -209881,7 +214403,7 @@ static void fts5FlushOneHash(Fts5Index *p){
       /* TODO2: Doclist terminator written here. */
       /* pBuf->p[pBuf->n++] = '\0'; */
       assert( pBuf->n<=pBuf->nSpace );
-      sqlite3Fts5HashScanNext(pHash);
+      if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash);
     }
     sqlite3Fts5HashClear(pHash);
     fts5WriteFinish(p, &writer, &pgnoLast);
@@ -209925,7 +214447,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
   Fts5Structure *pStruct
 ){
   Fts5Structure *pNew = 0;
-  int nByte = sizeof(Fts5Structure);
+  sqlite3_int64 nByte = sizeof(Fts5Structure);
   int nSeg = pStruct->nSegment;
   int i;
 
@@ -210055,11 +214577,13 @@ static void fts5AppendPoslist(
   Fts5Buffer *pBuf
 ){
   int nData = pMulti->base.nData;
+  int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING;
   assert( nData>0 );
-  if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){
+  if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nByte) ){
     fts5BufferSafeAppendVarint(pBuf, iDelta);
     fts5BufferSafeAppendVarint(pBuf, nData*2);
     fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData);
+    memset(&pBuf->p[pBuf->n], 0, FTS5_DATA_ZERO_PADDING);
   }
 }
 
@@ -210212,8 +214736,14 @@ static void fts5MergePrefixLists(
     ** 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;
+    ** was.  
+    **
+    ** Or, if the input position-lists are corrupt, then the output might
+    ** include up to 2 extra 10-byte positions created by interpreting -1
+    ** (the value PoslistNext64() uses for EOF) as a position and appending
+    ** it to the output. This can happen at most once for each input 
+    ** position-list, hence two 10 byte paddings.  */
+    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return;
     fts5DoclistIterInit(p1, &i1);
     fts5DoclistIterInit(p2, &i2);
 
@@ -210224,6 +214754,7 @@ static void fts5MergePrefixLists(
         fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
         fts5DoclistIterNext(&i1);
         if( i1.aPoslist==0 ) break;
+        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
       }
       else if( i2.iRowid!=i1.iRowid ){
         /* Copy entry from i2 */
@@ -210231,6 +214762,7 @@ static void fts5MergePrefixLists(
         fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
         fts5DoclistIterNext(&i2);
         if( i2.aPoslist==0 ) break;
+        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
       }
       else{
         /* Merge the two position lists. */ 
@@ -210240,6 +214772,8 @@ static void fts5MergePrefixLists(
         int iOff2 = 0;
         u8 *a1 = &i1.aPoslist[i1.nSize];
         u8 *a2 = &i2.aPoslist[i2.nSize];
+        int nCopy;
+        u8 *aCopy;
 
         i64 iPrev = 0;
         Fts5PoslistWriter writer;
@@ -210252,7 +214786,7 @@ static void fts5MergePrefixLists(
 
         sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
         sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
-        assert( iPos1>=0 && iPos2>=0 );
+        assert_nc( iPos1>=0 && iPos2>=0 );
 
         if( iPos1<iPos2 ){
           sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
@@ -210261,7 +214795,6 @@ static void fts5MergePrefixLists(
           sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
           sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
         }
-
         if( iPos1>=0 && iPos2>=0 ){
           while( 1 ){
             if( iPos1<iPos2 ){
@@ -210271,7 +214804,7 @@ static void fts5MergePrefixLists(
               sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
               if( iPos1<0 ) break;
             }else{
-              assert( iPos2!=iPrev );
+              assert_nc( iPos2!=iPrev );
               sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
               sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
               if( iPos2<0 ) break;
@@ -210283,11 +214816,16 @@ static void fts5MergePrefixLists(
           if( iPos1!=iPrev ){
             sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1);
           }
-          fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1);
+          aCopy = &a1[iOff1];
+          nCopy = i1.nPoslist - iOff1;
         }else{
-          assert( iPos2>=0 && iPos2!=iPrev );
+          assert_nc( iPos2>=0 && iPos2!=iPrev );
           sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2);
-          fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2);
+          aCopy = &a2[iOff2];
+          nCopy = i2.nPoslist - iOff2;
+        }
+        if( nCopy>0 ){
+          fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy);
         }
 
         /* WRITEPOSLISTSIZE */
@@ -210295,7 +214833,9 @@ static void fts5MergePrefixLists(
         fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
         fts5DoclistIterNext(&i1);
         fts5DoclistIterNext(&i2);
+        assert_nc( out.n<=(p1->n+p2->n+9) );
         if( i1.aPoslist==0 || i2.aPoslist==0 ) break;
+        assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) );
       }
     }
 
@@ -210307,7 +214847,7 @@ static void fts5MergePrefixLists(
       fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
       fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
     }
-    assert( out.n<=(p1->n+p2->n+9) );
+    assert_nc( out.n<=(p1->n+p2->n+9) );
 
     fts5BufferSet(&p->rc, p1, out.n, out.p);
     fts5BufferFree(&tmp);
@@ -210396,7 +214936,7 @@ static void fts5SetupPrefixIter(
     }
     fts5MultiIterFree(p1);
 
-    pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
+    pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING);
     if( pData ){
       pData->p = (u8*)&pData[1];
       pData->nn = pData->szLeaf = doclist.n;
@@ -210696,7 +215236,7 @@ static int sqlite3Fts5IndexQuery(
       fts5CloseReader(p);
     }
 
-    *ppIter = &pRet->base;
+    *ppIter = (Fts5IndexIter*)pRet;
     sqlite3Fts5BufferFree(&buf);
   }
   return fts5IndexReturn(p);
@@ -211158,11 +215698,11 @@ static void fts5IndexIntegrityCheckSegment(
 
       iOff = fts5LeafFirstTermOff(pLeaf);
       iRowidOff = fts5LeafFirstRowidOff(pLeaf);
-      if( iRowidOff>=iOff ){
+      if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
         p->rc = FTS5_CORRUPT;
       }else{
         iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
-        res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
+        res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
         if( res==0 ) res = nTerm - nIdxTerm;
         if( res<0 ) p->rc = FTS5_CORRUPT;
       }
@@ -211557,7 +216097,7 @@ static void fts5DecodeFunction(
   u8 *a = 0;
   Fts5Buffer s;                   /* Build up text to return here */
   int rc = SQLITE_OK;             /* Return code */
-  int nSpace = 0;
+  sqlite3_int64 nSpace = 0;
   int eDetailNone = (sqlite3_user_data(pCtx)!=0);
 
   assert( nArg==2 );
@@ -211573,8 +216113,7 @@ static void fts5DecodeFunction(
   nSpace = n + FTS5_DATA_ZERO_PADDING;
   a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
   if( a==0 ) goto decode_out;
-  memcpy(a, aBlob, n);
-
+  if( n>0 ) memcpy(a, aBlob, n);
 
   fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
 
@@ -211669,6 +216208,9 @@ static void fts5DecodeFunction(
       iPgidxOff = szLeaf = fts5GetU16(&a[2]);
       if( iPgidxOff<n ){
         fts5GetVarint32(&a[iPgidxOff], iTermOff);
+      }else if( iPgidxOff>n ){
+        rc = FTS5_CORRUPT;
+        goto decode_out;
       }
     }
 
@@ -211680,14 +216222,22 @@ static void fts5DecodeFunction(
     }else{
       iOff = szLeaf;
     }
+    if( iOff>n ){
+      rc = FTS5_CORRUPT;
+      goto decode_out;
+    }
     fts5DecodePoslist(&rc, &s, &a[4], iOff-4);
 
     /* Decode any more doclist data that appears on the page before the
     ** first term. */
     nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff;
+    if( nDoclist+iOff>n ){
+      rc = FTS5_CORRUPT;
+      goto decode_out;
+    }
     fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist);
 
-    while( iPgidxOff<n ){
+    while( iPgidxOff<n && rc==SQLITE_OK ){
       int bFirst = (iPgidxOff==szLeaf);     /* True for first term on page */
       int nByte;                            /* Bytes of data */
       int iEnd;
@@ -211702,12 +216252,24 @@ static void fts5DecodeFunction(
       }else{
         iEnd = szLeaf;
       }
+      if( iEnd>szLeaf ){
+        rc = FTS5_CORRUPT;
+        break;
+      }
 
       if( bFirst==0 ){
         iOff += fts5GetVarint32(&a[iOff], nByte);
+        if( nByte>term.n ){
+          rc = FTS5_CORRUPT;
+          break;
+        }
         term.n = nByte;
       }
       iOff += fts5GetVarint32(&a[iOff], nByte);
+      if( iOff+nByte>n ){
+        rc = FTS5_CORRUPT;
+        break;
+      }
       fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]);
       iOff += nByte;
 
@@ -211831,8 +216393,8 @@ SQLITE_API int sqlite3_fts5_may_be_corrupt = 1;
 typedef struct Fts5Auxdata Fts5Auxdata;
 typedef struct Fts5Auxiliary Fts5Auxiliary;
 typedef struct Fts5Cursor Fts5Cursor;
+typedef struct Fts5FullTable Fts5FullTable;
 typedef struct Fts5Sorter Fts5Sorter;
-typedef struct Fts5Table Fts5Table;
 typedef struct Fts5TokenizerModule Fts5TokenizerModule;
 
 /*
@@ -211913,13 +216475,8 @@ struct Fts5TokenizerModule {
   Fts5TokenizerModule *pNext;     /* Next registered tokenizer module */
 };
 
-/*
-** Virtual-table object.
-*/
-struct Fts5Table {
-  sqlite3_vtab base;              /* Base class used by SQLite core */
-  Fts5Config *pConfig;            /* Virtual table configuration */
-  Fts5Index *pIndex;              /* Full-text index */
+struct Fts5FullTable {
+  Fts5Table p;                    /* Public class members from fts5Int.h */
   Fts5Storage *pStorage;          /* Document store */
   Fts5Global *pGlobal;            /* Global (connection wide) data */
   Fts5Cursor *pSortCsr;           /* Sort data from this cursor */
@@ -212057,7 +216614,7 @@ struct Fts5Auxdata {
 #define FTS5_SAVEPOINT  5
 #define FTS5_RELEASE    6
 #define FTS5_ROLLBACKTO 7
-static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
+static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
   switch( op ){
     case FTS5_BEGIN:
       assert( p->ts.eState==0 );
@@ -212096,7 +216653,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
 
     case FTS5_ROLLBACKTO:
       assert( p->ts.eState==1 );
-      assert( iSavepoint>=0 );
+      assert( iSavepoint>=-1 );
       assert( iSavepoint<=p->ts.iSavepoint );
       p->ts.iSavepoint = iSavepoint;
       break;
@@ -212109,18 +216666,18 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){
 /*
 ** Return true if pTab is a contentless table.
 */
-static int fts5IsContentless(Fts5Table *pTab){
-  return pTab->pConfig->eContent==FTS5_CONTENT_NONE;
+static int fts5IsContentless(Fts5FullTable *pTab){
+  return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE;
 }
 
 /*
 ** Delete a virtual table handle allocated by fts5InitVtab(). 
 */
-static void fts5FreeVtab(Fts5Table *pTab){
+static void fts5FreeVtab(Fts5FullTable *pTab){
   if( pTab ){
-    sqlite3Fts5IndexClose(pTab->pIndex);
+    sqlite3Fts5IndexClose(pTab->p.pIndex);
     sqlite3Fts5StorageClose(pTab->pStorage);
-    sqlite3Fts5ConfigFree(pTab->pConfig);
+    sqlite3Fts5ConfigFree(pTab->p.pConfig);
     sqlite3_free(pTab);
   }
 }
@@ -212129,7 +216686,7 @@ static void fts5FreeVtab(Fts5Table *pTab){
 ** The xDisconnect() virtual table method.
 */
 static int fts5DisconnectMethod(sqlite3_vtab *pVtab){
-  fts5FreeVtab((Fts5Table*)pVtab);
+  fts5FreeVtab((Fts5FullTable*)pVtab);
   return SQLITE_OK;
 }
 
@@ -212140,7 +216697,7 @@ static int fts5DestroyMethod(sqlite3_vtab *pVtab){
   Fts5Table *pTab = (Fts5Table*)pVtab;
   int rc = sqlite3Fts5DropAll(pTab->pConfig);
   if( rc==SQLITE_OK ){
-    fts5FreeVtab((Fts5Table*)pVtab);
+    fts5FreeVtab((Fts5FullTable*)pVtab);
   }
   return rc;
 }
@@ -212169,28 +216726,28 @@ static int fts5InitVtab(
   const char **azConfig = (const char**)argv;
   int rc = SQLITE_OK;             /* Return code */
   Fts5Config *pConfig = 0;        /* Results of parsing argc/argv */
-  Fts5Table *pTab = 0;            /* New virtual table object */
+  Fts5FullTable *pTab = 0;        /* New virtual table object */
 
   /* Allocate the new vtab object and parse the configuration */
-  pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table));
+  pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable));
   if( rc==SQLITE_OK ){
     rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr);
     assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
   }
   if( rc==SQLITE_OK ){
-    pTab->pConfig = pConfig;
+    pTab->p.pConfig = pConfig;
     pTab->pGlobal = pGlobal;
   }
 
   /* Open the index sub-system */
   if( rc==SQLITE_OK ){
-    rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr);
+    rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr);
   }
 
   /* Open the storage sub-system */
   if( rc==SQLITE_OK ){
     rc = sqlite3Fts5StorageOpen(
-        pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr
+        pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr
     );
   }
 
@@ -212203,8 +216760,8 @@ static int fts5InitVtab(
   if( rc==SQLITE_OK ){
     assert( pConfig->pzErrmsg==0 );
     pConfig->pzErrmsg = pzErr;
-    rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
-    sqlite3Fts5IndexRollback(pTab->pIndex);
+    rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
+    sqlite3Fts5IndexRollback(pTab->p.pIndex);
     pConfig->pzErrmsg = 0;
   }
 
@@ -212417,7 +216974,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
   return SQLITE_OK;
 }
 
-static int fts5NewTransaction(Fts5Table *pTab){
+static int fts5NewTransaction(Fts5FullTable *pTab){
   Fts5Cursor *pCsr;
   for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
     if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
@@ -212429,19 +216986,19 @@ static int fts5NewTransaction(Fts5Table *pTab){
 ** Implementation of xOpen method.
 */
 static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
-  Fts5Table *pTab = (Fts5Table*)pVTab;
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVTab;
+  Fts5Config *pConfig = pTab->p.pConfig;
   Fts5Cursor *pCsr = 0;           /* New cursor object */
-  int nByte;                      /* Bytes of space to allocate */
+  sqlite3_int64 nByte;            /* Bytes of space to allocate */
   int rc;                         /* Return code */
 
   rc = fts5NewTransaction(pTab);
   if( rc==SQLITE_OK ){
     nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
-    pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
+    pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte);
     if( pCsr ){
       Fts5Global *pGlobal = pTab->pGlobal;
-      memset(pCsr, 0, nByte);
+      memset(pCsr, 0, (size_t)nByte);
       pCsr->aColumnSize = (int*)&pCsr[1];
       pCsr->pNext = pGlobal->pCsr;
       pGlobal->pCsr = pCsr;
@@ -212476,7 +217033,7 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){
 }
 
 static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
   Fts5Auxdata *pData;
   Fts5Auxdata *pNext;
 
@@ -212520,7 +217077,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
 */
 static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
   if( pCursor ){
-    Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
+    Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
     Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
     Fts5Cursor **pp;
 
@@ -212577,7 +217134,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
 ** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors 
 ** open on table pTab.
 */
-static void fts5TripCursors(Fts5Table *pTab){
+static void fts5TripCursors(Fts5FullTable *pTab){
   Fts5Cursor *pCsr;
   for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
     if( pCsr->ePlan==FTS5_PLAN_MATCH
@@ -212604,11 +217161,11 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){
   int rc = SQLITE_OK;
   assert( *pbSkip==0 );
   if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
-    Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+    Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
     int bDesc = pCsr->bDesc;
     i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
 
-    rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
+    rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc);
     if( rc==SQLITE_OK &&  iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
       *pbSkip = 1;
     }
@@ -212705,20 +217262,24 @@ static int fts5PrepareStatement(
   return rc;
 } 
 
-static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
-  Fts5Config *pConfig = pTab->pConfig;
+static int fts5CursorFirstSorted(
+  Fts5FullTable *pTab, 
+  Fts5Cursor *pCsr, 
+  int bDesc
+){
+  Fts5Config *pConfig = pTab->p.pConfig;
   Fts5Sorter *pSorter;
   int nPhrase;
-  int nByte;
+  sqlite3_int64 nByte;
   int rc;
   const char *zRank = pCsr->zRank;
   const char *zRankArgs = pCsr->zRankArgs;
   
   nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
   nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
-  pSorter = (Fts5Sorter*)sqlite3_malloc(nByte);
+  pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
   if( pSorter==0 ) return SQLITE_NOMEM;
-  memset(pSorter, 0, nByte);
+  memset(pSorter, 0, (size_t)nByte);
   pSorter->nIdx = nPhrase;
 
   /* TODO: It would be better to have some system for reusing statement
@@ -212753,10 +217314,10 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
   return rc;
 }
 
-static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
+static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){
   int rc;
   Fts5Expr *pExpr = pCsr->pExpr;
-  rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc);
+  rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc);
   if( sqlite3Fts5ExprEof(pExpr) ){
     CsrFlagSet(pCsr, FTS5CSR_EOF);
   }
@@ -212771,7 +217332,7 @@ static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){
 ** parameters.
 */
 static int fts5SpecialMatch(
-  Fts5Table *pTab, 
+  Fts5FullTable *pTab, 
   Fts5Cursor *pCsr, 
   const char *zQuery
 ){
@@ -212782,18 +217343,18 @@ static int fts5SpecialMatch(
   while( z[0]==' ' ) z++;
   for(n=0; z[n] && z[n]!=' '; n++);
 
-  assert( pTab->base.zErrMsg==0 );
+  assert( pTab->p.base.zErrMsg==0 );
   pCsr->ePlan = FTS5_PLAN_SPECIAL;
 
   if( 0==sqlite3_strnicmp("reads", z, n) ){
-    pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex);
+    pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex);
   }
   else if( 0==sqlite3_strnicmp("id", z, n) ){
     pCsr->iSpecial = pCsr->iCsrId;
   }
   else{
     /* An unrecognized directive. Return an error message. */
-    pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
+    pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z);
     rc = SQLITE_ERROR;
   }
 
@@ -212805,7 +217366,7 @@ static int fts5SpecialMatch(
 ** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary
 ** structure. Otherwise, if no such function exists, return NULL.
 */
-static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
+static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){
   Fts5Auxiliary *pAux;
 
   for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){
@@ -212818,8 +217379,8 @@ static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){
 
 
 static int fts5FindRankFunction(Fts5Cursor *pCsr){
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
+  Fts5Config *pConfig = pTab->p.pConfig;
   int rc = SQLITE_OK;
   Fts5Auxiliary *pAux = 0;
   const char *zRank = pCsr->zRank;
@@ -212835,7 +217396,7 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
       assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 );
       if( rc==SQLITE_OK ){
         if( SQLITE_ROW==sqlite3_step(pStmt) ){
-          int nByte;
+          sqlite3_int64 nByte;
           pCsr->nRankArg = sqlite3_column_count(pStmt);
           nByte = sizeof(sqlite3_value*)*pCsr->nRankArg;
           pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte);
@@ -212857,8 +217418,8 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){
   if( rc==SQLITE_OK ){
     pAux = fts5FindAuxiliary(pTab, zRank);
     if( pAux==0 ){
-      assert( pTab->base.zErrMsg==0 );
-      pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
+      assert( pTab->p.base.zErrMsg==0 );
+      pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank);
       rc = SQLITE_ERROR;
     }
   }
@@ -212933,8 +217494,8 @@ static int fts5FilterMethod(
   int nVal,                       /* Number of elements in apVal */
   sqlite3_value **apVal           /* Arguments for the indexing scheme */
 ){
-  Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
+  Fts5Config *pConfig = pTab->p.pConfig;
   Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
   int rc = SQLITE_OK;             /* Error code */
   int iVal = 0;                   /* Counter for apVal[] */
@@ -212963,8 +217524,8 @@ static int fts5FilterMethod(
   assert( pCsr->zRank==0 );
   assert( pCsr->zRankArgs==0 );
 
-  assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg );
-  pConfig->pzErrmsg = &pTab->base.zErrMsg;
+  assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg );
+  pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
 
   /* Decode the arguments passed through to this function.
   **
@@ -213030,7 +217591,7 @@ static int fts5FilterMethod(
         ** but a request for an internal parameter.  */
         rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]);
       }else{
-        char **pzErr = &pTab->base.zErrMsg;
+        char **pzErr = &pTab->p.base.zErrMsg;
         rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr);
         if( rc==SQLITE_OK ){
           if( bOrderByRank ){
@@ -213053,7 +217614,7 @@ static int fts5FilterMethod(
     ** by rowid (ePlan==FTS5_PLAN_ROWID).  */
     pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
     rc = sqlite3Fts5StorageStmt(
-        pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg
+        pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
     );
     if( rc==SQLITE_OK ){
       if( pCsr->ePlan==FTS5_PLAN_ROWID ){
@@ -213136,12 +217697,12 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
 
   /* If the cursor does not yet have a statement handle, obtain one now. */ 
   if( pCsr->pStmt==0 ){
-    Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+    Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
     int eStmt = fts5StmtType(pCsr);
     rc = sqlite3Fts5StorageStmt(
-        pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0)
+        pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0)
     );
-    assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 );
+    assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 );
     assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) );
   }
 
@@ -213163,11 +217724,11 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
   return rc;
 }
 
-static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
+static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
   va_list ap;                     /* ... printf arguments */
   va_start(ap, zFormat);
-  assert( p->base.zErrMsg==0 );
-  p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
+  assert( p->p.base.zErrMsg==0 );
+  p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
   va_end(ap);
 }
 
@@ -213187,11 +217748,11 @@ static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){
 ** more commands are added to this function.
 */
 static int fts5SpecialInsert(
-  Fts5Table *pTab,                /* Fts5 table object */
+  Fts5FullTable *pTab,            /* Fts5 table object */
   const char *zCmd,               /* Text inserted into table-name column */
   sqlite3_value *pVal             /* Value inserted into rank column */
 ){
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5Config *pConfig = pTab->p.pConfig;
   int rc = SQLITE_OK;
   int bError = 0;
 
@@ -213226,9 +217787,9 @@ static int fts5SpecialInsert(
     pConfig->bPrefixIndex = sqlite3_value_int(pVal);
 #endif
   }else{
-    rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
+    rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
     if( rc==SQLITE_OK ){
-      rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
+      rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError);
     }
     if( rc==SQLITE_OK ){
       if( bError ){
@@ -213242,7 +217803,7 @@ static int fts5SpecialInsert(
 }
 
 static int fts5SpecialDelete(
-  Fts5Table *pTab, 
+  Fts5FullTable *pTab, 
   sqlite3_value **apVal
 ){
   int rc = SQLITE_OK;
@@ -213256,7 +217817,7 @@ static int fts5SpecialDelete(
 
 static void fts5StorageInsert(
   int *pRc, 
-  Fts5Table *pTab, 
+  Fts5FullTable *pTab, 
   sqlite3_value **apVal, 
   i64 *piRowid
 ){
@@ -213290,8 +217851,8 @@ static int fts5UpdateMethod(
   sqlite3_value **apVal,          /* Array of arguments */
   sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
 ){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
+  Fts5Config *pConfig = pTab->p.pConfig;
   int eType0;                     /* value_type() of apVal[0] */
   int rc = SQLITE_OK;             /* Return code */
 
@@ -213300,12 +217861,11 @@ static int fts5UpdateMethod(
 
   assert( pVtab->zErrMsg==0 );
   assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
-  assert( nArg==1 
-      || sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
-      || sqlite3_value_type(apVal[1])==SQLITE_NULL 
+  assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER 
+       || sqlite3_value_type(apVal[0])==SQLITE_NULL 
   );
-  assert( pTab->pConfig->pzErrmsg==0 );
-  pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+  assert( pTab->p.pConfig->pzErrmsg==0 );
+  pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
 
   /* Put any active cursors into REQUIRE_SEEK state. */
   fts5TripCursors(pTab);
@@ -213346,7 +217906,7 @@ static int fts5UpdateMethod(
     /* Filter out attempts to run UPDATE or DELETE on contentless tables.
     ** This is not suported.  */
     if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
-      pTab->base.zErrMsg = sqlite3_mprintf(
+      pTab->p.base.zErrMsg = sqlite3_mprintf(
           "cannot %s contentless fts5 table: %s", 
           (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
       );
@@ -213359,46 +217919,52 @@ static int fts5UpdateMethod(
       rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
     }
 
-    /* INSERT */
-    else if( eType0!=SQLITE_INTEGER ){     
-      /* If this is a REPLACE, first remove the current entry (if any) */
-      if( eConflict==SQLITE_REPLACE 
-       && sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
-      ){
-        i64 iNew = sqlite3_value_int64(apVal[1]);  /* Rowid to delete */
-        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
-      }
-      fts5StorageInsert(&rc, pTab, apVal, pRowid);
-    }
-
-    /* UPDATE */
+    /* INSERT or UPDATE */
     else{
-      i64 iOld = sqlite3_value_int64(apVal[0]);  /* Old rowid */
-      i64 iNew = sqlite3_value_int64(apVal[1]);  /* New rowid */
-      if( iOld!=iNew ){
-        if( eConflict==SQLITE_REPLACE ){
-          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
-          if( rc==SQLITE_OK ){
-            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
-          }
-          fts5StorageInsert(&rc, pTab, apVal, pRowid);
-        }else{
-          rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
-          if( rc==SQLITE_OK ){
-            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
-          }
-          if( rc==SQLITE_OK ){
-            rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
-          }
+      int eType1 = sqlite3_value_numeric_type(apVal[1]);
+
+      if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
+        rc = SQLITE_MISMATCH;
+      }
+
+      else if( eType0!=SQLITE_INTEGER ){     
+        /* If this is a REPLACE, first remove the current entry (if any) */
+        if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
+          i64 iNew = sqlite3_value_int64(apVal[1]);  /* Rowid to delete */
+          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
         }
-      }else{
-        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
         fts5StorageInsert(&rc, pTab, apVal, pRowid);
       }
+
+      /* UPDATE */
+      else{
+        i64 iOld = sqlite3_value_int64(apVal[0]);  /* Old rowid */
+        i64 iNew = sqlite3_value_int64(apVal[1]);  /* New rowid */
+        if( eType1==SQLITE_INTEGER && iOld!=iNew ){
+          if( eConflict==SQLITE_REPLACE ){
+            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+            if( rc==SQLITE_OK ){
+              rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+            }
+            fts5StorageInsert(&rc, pTab, apVal, pRowid);
+          }else{
+            rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
+            if( rc==SQLITE_OK ){
+              rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+            }
+            if( rc==SQLITE_OK ){
+              rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
+            }
+          }
+        }else{
+          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+          fts5StorageInsert(&rc, pTab, apVal, pRowid);
+        }
+      }
     }
   }
 
-  pTab->pConfig->pzErrmsg = 0;
+  pTab->p.pConfig->pzErrmsg = 0;
   return rc;
 }
 
@@ -213407,12 +217973,12 @@ static int fts5UpdateMethod(
 */
 static int fts5SyncMethod(sqlite3_vtab *pVtab){
   int rc;
-  Fts5Table *pTab = (Fts5Table*)pVtab;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
   fts5CheckTransactionState(pTab, FTS5_SYNC, 0);
-  pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
+  pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
   fts5TripCursors(pTab);
   rc = sqlite3Fts5StorageSync(pTab->pStorage);
-  pTab->pConfig->pzErrmsg = 0;
+  pTab->p.pConfig->pzErrmsg = 0;
   return rc;
 }
 
@@ -213420,8 +217986,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
 ** Implementation of xBegin() method. 
 */
 static int fts5BeginMethod(sqlite3_vtab *pVtab){
-  fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
-  fts5NewTransaction((Fts5Table*)pVtab);
+  fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
+  fts5NewTransaction((Fts5FullTable*)pVtab);
   return SQLITE_OK;
 }
 
@@ -213432,7 +217998,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){
 */
 static int fts5CommitMethod(sqlite3_vtab *pVtab){
   UNUSED_PARAM(pVtab);  /* Call below is a no-op for NDEBUG builds */
-  fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
+  fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0);
   return SQLITE_OK;
 }
 
@@ -213442,7 +218008,7 @@ static int fts5CommitMethod(sqlite3_vtab *pVtab){
 */
 static int fts5RollbackMethod(sqlite3_vtab *pVtab){
   int rc;
-  Fts5Table *pTab = (Fts5Table*)pVtab;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
   fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
   rc = sqlite3Fts5StorageRollback(pTab->pStorage);
   return rc;
@@ -213466,13 +218032,13 @@ static int fts5ApiColumnTotalSize(
   sqlite3_int64 *pnToken
 ){
   Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
   return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken);
 }
 
 static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
   Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
   return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
 }
 
@@ -213507,7 +218073,9 @@ static int fts5ApiColumnText(
 ){
   int rc = SQLITE_OK;
   Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
-  if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){
+  if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) 
+   || pCsr->ePlan==FTS5_PLAN_SPECIAL 
+  ){
     *pz = 0;
     *pn = 0;
   }else{
@@ -213576,10 +218144,11 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
   int rc = SQLITE_OK;
   Fts5PoslistReader *aIter;       /* One iterator for each phrase */
   int nIter;                      /* Number of iterators/phrases */
+  int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol;
   
   nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
   if( pCsr->aInstIter==0 ){
-    int nByte = sizeof(Fts5PoslistReader) * nIter;
+    sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter;
     pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte);
   }
   aIter = pCsr->aInstIter;
@@ -213614,7 +218183,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
         nInst++;
         if( nInst>=pCsr->nInstAlloc ){
           pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32;
-          aInst = (int*)sqlite3_realloc(
+          aInst = (int*)sqlite3_realloc64(
               pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3
               );
           if( aInst ){
@@ -213629,6 +218198,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
         aInst[0] = iBest;
         aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
         aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
+        if( aInst[1]<0 || aInst[1]>=nCol ){
+          rc = FTS5_CORRUPT;
+          break;
+        }
         sqlite3Fts5PoslistReaderNext(&aIter[iBest]);
       }
     }
@@ -213701,8 +218274,8 @@ static int fts5ColumnSizeCb(
 
 static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
   Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
+  Fts5Config *pConfig = pTab->p.pConfig;
   int rc = SQLITE_OK;
 
   if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
@@ -213958,7 +218531,7 @@ static int fts5ApiQueryPhrase(
   int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*)
 ){
   Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
-  Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab);
   int rc;
   Fts5Cursor *pNew = 0;
 
@@ -214035,25 +218608,19 @@ static void fts5ApiCallback(
 
 
 /*
-** Given cursor id iId, return a pointer to the corresponding Fts5Index 
+** Given cursor id iId, return a pointer to the corresponding Fts5Table 
 ** object. Or NULL If the cursor id does not exist.
-**
-** If successful, set *ppConfig to point to the associated config object 
-** before returning.
 */
-static Fts5Index *sqlite3Fts5IndexFromCsrid(
+static Fts5Table *sqlite3Fts5TableFromCsrid(
   Fts5Global *pGlobal,            /* FTS5 global context for db handle */
-  i64 iCsrId,                     /* Id of cursor to find */
-  Fts5Config **ppConfig           /* OUT: Configuration object */
+  i64 iCsrId                      /* Id of cursor to find */
 ){
   Fts5Cursor *pCsr;
-  Fts5Table *pTab;
-
   pCsr = fts5CursorFromCsrid(pGlobal, iCsrId);
-  pTab = (Fts5Table*)pCsr->base.pVtab;
-  *ppConfig = pTab->pConfig;
-
-  return pTab->pIndex;
+  if( pCsr ){
+    return (Fts5Table*)pCsr->base.pVtab;
+  }
+  return 0;
 }
 
 /*
@@ -214133,8 +218700,8 @@ static int fts5ColumnMethod(
   sqlite3_context *pCtx,          /* Context for sqlite3_result_xxx() calls */
   int iCol                        /* Index of column to read value from */
 ){
-  Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
-  Fts5Config *pConfig = pTab->pConfig;
+  Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab);
+  Fts5Config *pConfig = pTab->p.pConfig;
   Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
   int rc = SQLITE_OK;
   
@@ -214186,7 +218753,7 @@ static int fts5FindFunctionMethod(
   void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
   void **ppArg                    /* OUT: User data for *pxFunc */
 ){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
   Fts5Auxiliary *pAux;
 
   UNUSED_PARAM(nUnused);
@@ -214208,21 +218775,24 @@ static int fts5RenameMethod(
   sqlite3_vtab *pVtab,            /* Virtual table handle */
   const char *zName               /* New name of table */
 ){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
   return sqlite3Fts5StorageRename(pTab->pStorage, zName);
 }
 
+static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){
+  fts5TripCursors((Fts5FullTable*)pTab);
+  return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage);
+}
+
 /*
 ** The xSavepoint() method.
 **
 ** Flush the contents of the pending-terms table to disk.
 */
 static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
   UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
-  fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
-  fts5TripCursors(pTab);
-  return sqlite3Fts5StorageSync(pTab->pStorage);
+  fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint);
+  return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
 }
 
 /*
@@ -214231,11 +218801,9 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
 ** This is a no-op.
 */
 static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
   UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
-  fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
-  fts5TripCursors(pTab);
-  return sqlite3Fts5StorageSync(pTab->pStorage);
+  fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint);
+  return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab);
 }
 
 /*
@@ -214244,7 +218812,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
 ** Discard the contents of the pending terms table.
 */
 static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
-  Fts5Table *pTab = (Fts5Table*)pVtab;
+  Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
   UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
   fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
   fts5TripCursors(pTab);
@@ -214265,14 +218833,14 @@ static int fts5CreateAux(
   int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
   if( rc==SQLITE_OK ){
     Fts5Auxiliary *pAux;
-    int nName;                      /* Size of zName in bytes, including \0 */
-    int nByte;                      /* Bytes of space to allocate */
+    sqlite3_int64 nName;            /* Size of zName in bytes, including \0 */
+    sqlite3_int64 nByte;            /* Bytes of space to allocate */
 
-    nName = (int)strlen(zName) + 1;
+    nName = strlen(zName) + 1;
     nByte = sizeof(Fts5Auxiliary) + nName;
-    pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
+    pAux = (Fts5Auxiliary*)sqlite3_malloc64(nByte);
     if( pAux ){
-      memset(pAux, 0, nByte);
+      memset(pAux, 0, (size_t)nByte);
       pAux->zFunc = (char*)&pAux[1];
       memcpy(pAux->zFunc, zName, nName);
       pAux->pGlobal = pGlobal;
@@ -214302,15 +218870,15 @@ static int fts5CreateTokenizer(
 ){
   Fts5Global *pGlobal = (Fts5Global*)pApi;
   Fts5TokenizerModule *pNew;
-  int nName;                      /* Size of zName and its \0 terminator */
-  int nByte;                      /* Bytes of space to allocate */
+  sqlite3_int64 nName;            /* Size of zName and its \0 terminator */
+  sqlite3_int64 nByte;            /* Bytes of space to allocate */
   int rc = SQLITE_OK;
 
-  nName = (int)strlen(zName) + 1;
+  nName = strlen(zName) + 1;
   nByte = sizeof(Fts5TokenizerModule) + nName;
-  pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
+  pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
   if( pNew ){
-    memset(pNew, 0, nByte);
+    memset(pNew, 0, (size_t)nByte);
     pNew->zName = (char*)&pNew[1];
     memcpy(pNew->zName, zName, nName);
     pNew->pUserData = pUserData;
@@ -214445,12 +219013,27 @@ static void fts5SourceIdFunc(
 ){
   assert( nArg==0 );
   UNUSED_PARAM2(nArg, apUnused);
-  sqlite3_result_text(pCtx, "fts5: 2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7", -1, SQLITE_TRANSIENT);
+  sqlite3_result_text(pCtx, "fts5: 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6", -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,
@@ -214473,6 +219056,7 @@ static int fts5Init(sqlite3 *db){
     /* xSavepoint    */ fts5SavepointMethod,
     /* xRelease      */ fts5ReleaseMethod,
     /* xRollbackTo   */ fts5RollbackToMethod,
+    /* xShadowName   */ fts5ShadowName
   };
 
   int rc;
@@ -214678,7 +219262,7 @@ static int fts5StorageGetStmt(
         char *zBind;
         int i;
 
-        zBind = sqlite3_malloc(1 + nCol*2);
+        zBind = sqlite3_malloc64(1 + nCol*2);
         if( zBind ){
           for(i=0; i<nCol; i++){
             zBind[i*2] = '?';
@@ -214699,8 +219283,9 @@ static int fts5StorageGetStmt(
     if( zSql==0 ){
       rc = SQLITE_NOMEM;
     }else{
-      rc = sqlite3_prepare_v3(pC->db, zSql, -1,
-                              SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
+      int f = SQLITE_PREPARE_PERSISTENT;
+      if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
+      rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
       sqlite3_free(zSql);
       if( rc!=SQLITE_OK && pzErrMsg ){
         *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
@@ -214844,14 +219429,14 @@ static int sqlite3Fts5StorageOpen(
 ){
   int rc = SQLITE_OK;
   Fts5Storage *p;                 /* New object */
-  int nByte;                      /* Bytes of space to allocate */
+  sqlite3_int64 nByte;            /* Bytes of space to allocate */
 
   nByte = sizeof(Fts5Storage)               /* Fts5Storage object */
         + pConfig->nCol * sizeof(i64);      /* Fts5Storage.aTotalSize[] */
-  *pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
+  *pp = p = (Fts5Storage*)sqlite3_malloc64(nByte);
   if( !p ) return SQLITE_NOMEM;
 
-  memset(p, 0, nByte);
+  memset(p, 0, (size_t)nByte);
   p->aTotalSize = (i64*)&p[1];
   p->pConfig = pConfig;
   p->pIndex = pIndex;
@@ -214859,7 +219444,7 @@ static int sqlite3Fts5StorageOpen(
   if( bCreate ){
     if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
       int nDefn = 32 + pConfig->nCol*10;
-      char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10);
+      char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
       if( zDefn==0 ){
         rc = SQLITE_NOMEM;
       }else{
@@ -215150,7 +219735,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
   Fts5Config *pConfig = p->pConfig;
   sqlite3_stmt *pScan = 0;
   Fts5InsertCtx ctx;
-  int rc;
+  int rc, rc2;
 
   memset(&ctx, 0, sizeof(Fts5InsertCtx));
   ctx.pStorage = p;
@@ -215189,6 +219774,8 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
     }
   }
   sqlite3_free(buf.p);
+  rc2 = sqlite3_reset(pScan);
+  if( rc==SQLITE_OK ) rc = rc2;
 
   /* Write the averages record */
   if( rc==SQLITE_OK ){
@@ -215438,7 +220025,7 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){
 
   memset(&ctx, 0, sizeof(Fts5IntegrityCtx));
   ctx.pConfig = p->pConfig;
-  aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64)));
+  aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64)));
   if( !aTotalSize ) return SQLITE_NOMEM;
   aColSize = (int*)&aTotalSize[pConfig->nCol];
   memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol);
@@ -215638,7 +220225,13 @@ static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){
 static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
   int rc = fts5StorageLoadTotals(p, 0);
   if( rc==SQLITE_OK ){
+    /* nTotalRow being zero does not necessarily indicate a corrupt 
+    ** database - it might be that the FTS5 table really does contain zero
+    ** rows. However this function is only called from the xRowCount() API,
+    ** and there is no way for that API to be invoked if the table contains
+    ** no rows. Hence the FTS5_CORRUPT return.  */
     *pnRow = p->nTotalRow;
+    if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT;
   }
   return rc;
 }
@@ -215848,7 +220441,7 @@ static int fts5AsciiTokenize(
     nByte = ie-is;
     if( nByte>nFold ){
       if( pFold!=aFold ) sqlite3_free(pFold);
-      pFold = sqlite3_malloc(nByte*2);
+      pFold = sqlite3_malloc64((sqlite3_int64)nByte*2);
       if( pFold==0 ){
         rc = SQLITE_NOMEM;
         break;
@@ -215930,13 +220523,18 @@ struct Unicode61Tokenizer {
   unsigned char aTokenChar[128];  /* ASCII range token characters */
   char *aFold;                    /* Buffer to fold text into */
   int nFold;                      /* Size of aFold[] in bytes */
-  int bRemoveDiacritic;           /* True if remove_diacritics=1 is set */
+  int eRemoveDiacritic;           /* True if remove_diacritics=1 is set */
   int nException;
   int *aiException;
 
   unsigned char aCategory[32];    /* True for token char categories */
 };
 
+/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */
+#define FTS5_REMOVE_DIACRITICS_NONE    0
+#define FTS5_REMOVE_DIACRITICS_SIMPLE  1
+#define FTS5_REMOVE_DIACRITICS_COMPLEX 2
+
 static int fts5UnicodeAddExceptions(
   Unicode61Tokenizer *p,          /* Tokenizer object */
   const char *z,                  /* Characters to treat as exceptions */
@@ -215947,13 +220545,14 @@ static int fts5UnicodeAddExceptions(
   int *aNew;
 
   if( n>0 ){
-    aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
+    aNew = (int*)sqlite3_realloc64(p->aiException,
+                                   (n+p->nException)*sizeof(int));
     if( aNew ){
       int nNew = p->nException;
       const unsigned char *zCsr = (const unsigned char*)z;
       const unsigned char *zTerm = (const unsigned char*)&z[n];
       while( zCsr<zTerm ){
-        int iCode;
+        u32 iCode;
         int bToken;
         READ_UTF8(zCsr, zTerm, iCode);
         if( iCode<128 ){
@@ -215965,7 +220564,7 @@ static int fts5UnicodeAddExceptions(
           if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
             int i;
             for(i=0; i<nNew; i++){
-              if( aNew[i]>iCode ) break;
+              if( (u32)aNew[i]>iCode ) break;
             }
             memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
             aNew[i] = iCode;
@@ -216057,9 +220656,9 @@ static int fts5UnicodeCreate(
       int i;
       memset(p, 0, sizeof(Unicode61Tokenizer));
 
-      p->bRemoveDiacritic = 1;
+      p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
       p->nFold = 64;
-      p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
+      p->aFold = sqlite3_malloc64(p->nFold * sizeof(char));
       if( p->aFold==0 ){
         rc = SQLITE_NOMEM;
       }
@@ -216078,10 +220677,15 @@ static int fts5UnicodeCreate(
       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] ){
+          if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
             rc = SQLITE_ERROR;
+          }else{
+            p->eRemoveDiacritic = (zArg[0] - '0');
+            assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE
+                 || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE
+                 || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX
+            );
           }
-          p->bRemoveDiacritic = (zArg[0]=='1');
         }else
         if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
           rc = fts5UnicodeAddExceptions(p, zArg, 1);
@@ -216115,7 +220719,7 @@ static int fts5UnicodeCreate(
 */
 static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
   return (
-    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
+    p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
     ^ fts5UnicodeIsException(p, iCode)
   );
 }
@@ -216144,7 +220748,7 @@ static int fts5UnicodeTokenize(
   /* Each iteration of this loop gobbles up a contiguous run of separators,
   ** then the next token.  */
   while( rc==SQLITE_OK ){
-    int iCode;                    /* non-ASCII codepoint read from input */
+    u32 iCode;                    /* non-ASCII codepoint read from input */
     char *zOut = aFold;
     int is;
     int ie;
@@ -216176,7 +220780,7 @@ static int fts5UnicodeTokenize(
       /* Grow the output buffer so that there is sufficient space to fit the
       ** largest possible utf-8 character.  */
       if( zOut>pEnd ){
-        aFold = sqlite3_malloc(nFold*2);
+        aFold = sqlite3_malloc64((sqlite3_int64)nFold*2);
         if( aFold==0 ){
           rc = SQLITE_NOMEM;
           goto tokenize_done;
@@ -216195,7 +220799,7 @@ static int fts5UnicodeTokenize(
         READ_UTF8(zCsr, zTerm, iCode);
         if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){
  non_ascii_tokenchar:
-          iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic);
+          iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic);
           if( iCode ) WRITE_UTF8(zOut, iCode);
         }else{
           break;
@@ -216971,10 +221575,8 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
   return rc;
 }
 
-
-
 /*
-** 2012 May 25
+** 2012-05-25
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -217003,32 +221605,48 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
 ** E"). The resuls of passing a codepoint that corresponds to an
 ** uppercase letter are undefined.
 */
-static int fts5_remove_diacritic(int c){
+static int fts5_remove_diacritic(int c, int bComplex){
   unsigned short aDia[] = {
         0,  1797,  1848,  1859,  1891,  1928,  1940,  1995, 
      2024,  2040,  2060,  2110,  2168,  2206,  2264,  2286, 
      2344,  2383,  2472,  2488,  2516,  2596,  2668,  2732, 
      2782,  2842,  2894,  2954,  2984,  3000,  3028,  3336, 
-     3456,  3696,  3712,  3728,  3744,  3896,  3912,  3928, 
-     3968,  4008,  4040,  4106,  4138,  4170,  4202,  4234, 
-     4266,  4296,  4312,  4344,  4408,  4424,  4472,  4504, 
-     6148,  6198,  6264,  6280,  6360,  6429,  6505,  6529, 
-    61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, 
-    61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, 
-    62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, 
-    62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 
-    62924, 63050, 63082, 63274, 63390, 
+     3456,  3696,  3712,  3728,  3744,  3766,  3832,  3896, 
+     3912,  3928,  3944,  3968,  4008,  4040,  4056,  4106, 
+     4138,  4170,  4202,  4234,  4266,  4296,  4312,  4344, 
+     4408,  4424,  4442,  4472,  4488,  4504,  6148,  6198, 
+     6264,  6280,  6360,  6429,  6505,  6529, 61448, 61468, 
+    61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, 
+    61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 
+    61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 
+    62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 
+    62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 
+    62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 
+    63182, 63242, 63274, 63310, 63368, 63390, 
   };
-  char aChar[] = {
-    '\0', 'a',  'c',  'e',  'i',  'n',  'o',  'u',  'y',  'y',  'a',  'c',  
-    'd',  'e',  'e',  'g',  'h',  'i',  'j',  'k',  'l',  'n',  'o',  'r',  
-    's',  't',  'u',  'u',  'w',  'y',  'z',  'o',  'u',  'a',  'i',  'o',  
-    'u',  'g',  'k',  'o',  'j',  'g',  'n',  'a',  'e',  'i',  'o',  'r',  
-    'u',  's',  't',  'h',  'a',  'e',  'o',  'y',  '\0', '\0', '\0', '\0', 
-    '\0', '\0', '\0', '\0', 'a',  'b',  'd',  'd',  'e',  'f',  'g',  'h',  
-    'h',  'i',  'k',  'l',  'l',  'm',  'n',  'p',  'r',  'r',  's',  't',  
-    'u',  'v',  'w',  'w',  'x',  'y',  'z',  'h',  't',  'w',  'y',  'a',  
-    'e',  'i',  'o',  'u',  'y',  
+#define HIBIT ((unsigned char)0x80)
+  unsigned char aChar[] = {
+    '\0',      'a',       'c',       'e',       'i',       'n',       
+    'o',       'u',       'y',       'y',       'a',       'c',       
+    'd',       'e',       'e',       'g',       'h',       'i',       
+    'j',       'k',       'l',       'n',       'o',       'r',       
+    's',       't',       'u',       'u',       'w',       'y',       
+    'z',       'o',       'u',       'a',       'i',       'o',       
+    'u',       'u'|HIBIT, 'a'|HIBIT, 'g',       'k',       'o',       
+    'o'|HIBIT, 'j',       'g',       'n',       'a'|HIBIT, 'a',       
+    'e',       'i',       'o',       'r',       'u',       's',       
+    't',       'h',       'a',       'e',       'o'|HIBIT, 'o',       
+    'o'|HIBIT, 'y',       '\0',      '\0',      '\0',      '\0',      
+    '\0',      '\0',      '\0',      '\0',      'a',       'b',       
+    'c'|HIBIT, 'd',       'd',       'e'|HIBIT, 'e',       'e'|HIBIT, 
+    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
+    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
+    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
+    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
+    'w',       'x',       'y',       'z',       'h',       't',       
+    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
+    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
+    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
   };
 
   unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -217045,7 +221663,8 @@ static int fts5_remove_diacritic(int c){
     }
   }
   assert( key>=aDia[iRes] );
-  return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
+  if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
+  return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
 }
 
 
@@ -217058,8 +221677,8 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){
   unsigned int mask1 = 0x000361F8;
   if( c<768 || c>817 ) return 0;
   return (c < 768+32) ?
-      (mask0 & (1 << (c-768))) :
-      (mask1 & (1 << (c-768-32)));
+      (mask0 & ((unsigned int)1 << (c-768))) :
+      (mask1 & ((unsigned int)1 << (c-768-32)));
 }
 
 
@@ -217072,7 +221691,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){
 ** The results are undefined if the value passed to this function
 ** is less than zero.
 */
-static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
+static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){
   /* Each entry in the following array defines a rule for folding a range
   ** of codepoints to lower case. The rule applies to a range of nRange
   ** codepoints starting at codepoint iCode.
@@ -217195,7 +221814,9 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
       assert( ret>0 );
     }
 
-    if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret);
+    if( eRemoveDiacritic ){
+      ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2);
+    }
   }
   
   else if( c>=66560 && c<66600 ){
@@ -217206,12 +221827,6 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){
 }
 
 
-#if 0
-static int sqlite3Fts5UnicodeNCat(void) { 
-  return 32;
-}
-#endif
-
 static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
   aArray[0] = 1;
   switch( zCat[0] ){
@@ -217693,7 +222308,7 @@ static u16 aFts5UnicodeData[] = {
     34,    3074,  7692,  63,    63,    
   };
 
-static int sqlite3Fts5UnicodeCategory(int iCode) { 
+static int sqlite3Fts5UnicodeCategory(u32 iCode) { 
   int iRes = -1;
   int iHi;
   int iLo;
@@ -217737,7 +222352,6 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
   }
 }
 
-
 /*
 ** 2015 May 30
 **
@@ -217816,7 +222430,7 @@ static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){
     u8 n;
     p -= 2;
     n = sqlite3Fts5GetVarint(p, &v64);
-    *v = (u32)v64;
+    *v = ((u32)v64) & 0x7FFFFFFF;
     assert( n>3 && n<=9 );
     return n;
   }
@@ -218083,7 +222697,6 @@ static int sqlite3Fts5GetVarintLen(u32 iVal){
   return 5;
 }
 
-
 /*
 ** 2015 May 08
 **
@@ -218141,7 +222754,7 @@ struct Fts5VocabTable {
 struct Fts5VocabCursor {
   sqlite3_vtab_cursor base;
   sqlite3_stmt *pStmt;            /* Statement holding lock on pIndex */
-  Fts5Index *pIndex;              /* Associated FTS5 index */
+  Fts5Table *pFts5;               /* Associated FTS5 table */
 
   int bEof;                       /* True if this cursor is at EOF */
   Fts5IndexIter *pIter;           /* Term/rowid iterator object */
@@ -218150,7 +222763,6 @@ struct Fts5VocabCursor {
   char *zLeTerm;                  /* (term <= $zLeTerm) paramater, or NULL */
 
   /* These are used by 'col' tables only */
-  Fts5Config *pConfig;            /* Fts5 table configuration */
   int iCol;
   i64 *aCnt;
   i64 *aDoc;
@@ -218413,8 +223025,7 @@ static int fts5VocabOpenMethod(
   sqlite3_vtab_cursor **ppCsr
 ){
   Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab;
-  Fts5Index *pIndex = 0;
-  Fts5Config *pConfig = 0;
+  Fts5Table *pFts5 = 0;
   Fts5VocabCursor *pCsr = 0;
   int rc = SQLITE_OK;
   sqlite3_stmt *pStmt = 0;
@@ -218433,31 +223044,34 @@ static int fts5VocabOpenMethod(
 
   if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
     i64 iId = sqlite3_column_int64(pStmt, 0);
-    pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig);
+    pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId);
   }
 
-  if( rc==SQLITE_OK && pIndex==0 ){
-    rc = sqlite3_finalize(pStmt);
-    pStmt = 0;
-    if( rc==SQLITE_OK ){
-      pVTab->zErrMsg = sqlite3_mprintf(
-          "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
-      );
-      rc = SQLITE_ERROR;
+  if( rc==SQLITE_OK ){
+    if( pFts5==0 ){
+      rc = sqlite3_finalize(pStmt);
+      pStmt = 0;
+      if( rc==SQLITE_OK ){
+        pVTab->zErrMsg = sqlite3_mprintf(
+            "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
+            );
+        rc = SQLITE_ERROR;
+      }
+    }else{
+      rc = sqlite3Fts5FlushToDisk(pFts5);
     }
   }
 
   if( rc==SQLITE_OK ){
-    int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor);
+    int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
     pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
   }
 
   if( pCsr ){
-    pCsr->pIndex = pIndex;
+    pCsr->pFts5 = pFts5;
     pCsr->pStmt = pStmt;
-    pCsr->pConfig = pConfig;
     pCsr->aCnt = (i64*)&pCsr[1];
-    pCsr->aDoc = &pCsr->aCnt[pConfig->nCol];
+    pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol];
   }else{
     sqlite3_finalize(pStmt);
   }
@@ -218473,6 +223087,7 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){
   sqlite3_free(pCsr->zLeTerm);
   pCsr->nLeTerm = -1;
   pCsr->zLeTerm = 0;
+  pCsr->bEof = 0;
 }
 
 /*
@@ -218511,12 +223126,14 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
 }
 
 static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
-  int eDetail = pCsr->pConfig->eDetail;
+  int eDetail = pCsr->pFts5->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) 
   ){
@@ -218526,7 +223143,7 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
     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;
@@ -218544,7 +223161,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
   Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
   Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
   int rc = SQLITE_OK;
-  int nCol = pCsr->pConfig->nCol;
+  int nCol = pCsr->pFts5->pConfig->nCol;
 
   pCsr->rowid++;
 
@@ -218566,6 +223183,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
       int nTerm;
 
       zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+      assert( nTerm>=0 );
       if( pCsr->nLeTerm>=0 ){
         int nCmp = MIN(nTerm, pCsr->nLeTerm);
         int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
@@ -218582,7 +223200,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
 
       assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
       while( rc==SQLITE_OK ){
-        int eDetail = pCsr->pConfig->eDetail;
+        int eDetail = pCsr->pFts5->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 */
@@ -218605,7 +223223,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
               int iCol = -1;
               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
                 int ii = FTS5_POS2COLUMN(iPos);
-                pCsr->aCnt[ii]++;
                 if( iCol!=ii ){
                   if( ii>=nCol ){
                     rc = FTS5_CORRUPT;
@@ -218614,6 +223231,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
                   pCsr->aDoc[ii]++;
                   iCol = ii;
                 }
+                pCsr->aCnt[ii]++;
               }
             }else if( eDetail==FTS5_DETAIL_COLUMNS ){
               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
@@ -218642,7 +223260,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
 
         if( rc==SQLITE_OK ){
           zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
-          if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
+          if( nTerm!=pCsr->term.n 
+          || (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm)) 
+          ){
             break;
           }
           if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
@@ -218652,8 +223272,10 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
   }
 
   if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){
-    while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++;
-    assert( pCsr->iCol<pCsr->pConfig->nCol );
+    for(/* noop */; pCsr->iCol<nCol && pCsr->aDoc[pCsr->iCol]==0; pCsr->iCol++);
+    if( pCsr->iCol==nCol ){
+      rc = FTS5_CORRUPT;
+    }
   }
   return rc;
 }
@@ -218700,6 +223322,7 @@ static int fts5VocabFilterMethod(
     }
     if( pLe ){
       const char *zCopy = (const char *)sqlite3_value_text(pLe);
+      if( zCopy==0 ) zCopy = "";
       pCsr->nLeTerm = sqlite3_value_bytes(pLe);
       pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1);
       if( pCsr->zLeTerm==0 ){
@@ -218711,14 +223334,15 @@ static int fts5VocabFilterMethod(
   }
 
   if( rc==SQLITE_OK ){
-    rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
+    Fts5Index *pIndex = pCsr->pFts5->pIndex;
+    rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
   }
   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)
+  if( rc==SQLITE_OK && !pCsr->bEof 
+   && (eType!=FTS5_VOCAB_INSTANCE 
+    || pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE)
   ){
     rc = fts5VocabNextMethod(pCursor);
   }
@@ -218741,7 +223365,7 @@ static int fts5VocabColumnMethod(
   int iCol                        /* Index of column to read value from */
 ){
   Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
-  int eDetail = pCsr->pConfig->eDetail;
+  int eDetail = pCsr->pFts5->pConfig->eDetail;
   int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType;
   i64 iVal = 0;
 
@@ -218753,7 +223377,7 @@ static int fts5VocabColumnMethod(
     assert( iCol==1 || iCol==2 || iCol==3 );
     if( iCol==1 ){
       if( eDetail!=FTS5_DETAIL_NONE ){
-        const char *z = pCsr->pConfig->azCol[pCsr->iCol];
+        const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol];
         sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
       }
     }else if( iCol==2 ){
@@ -218781,8 +223405,8 @@ static int fts5VocabColumnMethod(
         }else if( eDetail==FTS5_DETAIL_COLUMNS ){
           ii = (int)pCsr->iInstPos;
         }
-        if( ii>=0 && ii<pCsr->pConfig->nCol ){
-          const char *z = pCsr->pConfig->azCol[ii];
+        if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){
+          const char *z = pCsr->pFts5->pConfig->azCol[ii];
           sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
         }
         break;
@@ -218841,6 +223465,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
     /* xSavepoint    */ 0,
     /* xRelease      */ 0,
     /* xRollbackTo   */ 0,
+    /* xShadowName   */ 0
   };
   void *p = (void*)pGlobal;
 
@@ -218848,8 +223473,6 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
 }
 
 
-
-
     
 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
 
@@ -219123,6 +223746,7 @@ static sqlite3_module stmtModule = {
   0,                         /* xSavepoint */
   0,                         /* xRelease */
   0,                         /* xRollbackTo */
+  0,                         /* xShadowName */
 };
 
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -219155,9 +223779,9 @@ SQLITE_API int sqlite3_stmt_init(
 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
 
 /************** End of stmt.c ************************************************/
-#if __LINE__!=219157
+#if __LINE__!=223781
 #undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID      "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792alt2"
+#define SQLITE_SOURCE_ID      "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88alt2"
 #endif
 /* Return the source-id for this library */
 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
index 05d11a8a6f..a85240a167 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
@@ -124,9 +124,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.25.2"
-#define SQLITE_VERSION_NUMBER 3025002
-#define SQLITE_SOURCE_ID      "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
+#define SQLITE_VERSION        "3.29.0"
+#define SQLITE_VERSION_NUMBER 3029000
+#define SQLITE_SOURCE_ID      "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -190,6 +190,9 @@ SQLITE_API int sqlite3_libversion_number(void);
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
 SQLITE_API const char *sqlite3_compileoption_get(int N);
+#else
+# define sqlite3_compileoption_used(X) 0
+# define sqlite3_compileoption_get(X)  ((void*)0)
 #endif
 
 /*
@@ -824,6 +827,15 @@ struct sqlite3_io_methods {
 ** file space based on this hint in order to help writes to the database
 ** file run faster.
 **
+** <li>[[SQLITE_FCNTL_SIZE_LIMIT]]
+** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that
+** implements [sqlite3_deserialize()] to set an upper bound on the size
+** of the in-memory database.  The argument is a pointer to a [sqlite3_int64].
+** If the integer pointed to is negative, then it is filled in with the
+** current limit.  Otherwise the limit is set to the larger of the value
+** of the integer pointed to and the current database size.  The integer
+** pointed to is set to the new limit.
+**
 ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
 ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
 ** extends and truncates the database file in chunks of a size specified
@@ -1132,6 +1144,7 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
 #define SQLITE_FCNTL_LOCK_TIMEOUT           34
 #define SQLITE_FCNTL_DATA_VERSION           35
+#define SQLITE_FCNTL_SIZE_LIMIT             36
 
 /* deprecated names */
 #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1284,8 +1297,14 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
 ** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
 ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
 ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable.   The file can be a
-** directory.
+** to test whether a file is at least readable.  The SQLITE_ACCESS_READ
+** flag is never actually used and is not implemented in the built-in
+** VFSes of SQLite.  The file is named by the second argument and can be a
+** directory. The xAccess method returns [SQLITE_OK] on success or some
+** non-zero error code if there is an I/O error or if the name of
+** the file given in the second argument is illegal.  If SQLITE_OK
+** is returned, then non-zero or zero is written into *pResOut to indicate
+** whether or not the file is accessible.  
 **
 ** ^SQLite will always allocate at least mxPathname+1 bytes for the
 ** output buffer xFullPathname.  The exact size of the output buffer
@@ -1973,6 +1992,17 @@ struct sqlite3_mem_methods {
 ** 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.
+**
+** [[SQLITE_CONFIG_MEMDB_MAXSIZE]]
+** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE
+** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter
+** [sqlite3_int64] parameter which is the default maximum size for an in-memory
+** database created using [sqlite3_deserialize()].  This default maximum
+** size can be adjusted up or down for individual databases using the
+** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control].  If this
+** configuration setting is never used, then the default maximum is determined
+** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option.  If that
+** compile-time option is not set, then the default maximum is 1073741824.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -2003,6 +2033,7 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
 #define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
 #define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
+#define SQLITE_CONFIG_MEMDB_MAXSIZE       29  /* sqlite3_int64 */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -2018,6 +2049,7 @@ struct sqlite3_mem_methods {
 ** 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].
@@ -2040,6 +2072,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -2050,6 +2083,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -2060,9 +2094,10 @@ struct sqlite3_mem_methods {
 ** 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
+** <dd> ^This option is used to enable or disable the
+** [fts3_tokenizer()] function which is part of the
 ** [FTS3] full-text search engine extension.
 ** There should be two additional arguments.
 ** The first argument is an integer which is 0 to disable fts3_tokenizer() or
@@ -2073,6 +2108,7 @@ struct sqlite3_mem_methods {
 ** 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.
@@ -2090,7 +2126,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -2099,6 +2135,7 @@ struct sqlite3_mem_methods {
 ** 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 
@@ -2112,7 +2149,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -2128,7 +2165,7 @@ struct sqlite3_mem_methods {
 ** 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
@@ -2140,7 +2177,7 @@ struct sqlite3_mem_methods {
 ** it is not disabled, 1 if it is.  
 ** </dd>
 **
-** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
+** [[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
@@ -2159,6 +2196,58 @@ struct sqlite3_mem_methods {
 ** 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> The [PRAGMA journal_mode=OFF] statement.
+** <li> Writes to the [sqlite_dbpage] virtual table.
+** <li> Direct writes to [shadow tables].
+** </ul>
+** </dd>
+**
+** [[SQLITE_DBCONFIG_WRITABLE_SCHEMA]] <dt>SQLITE_DBCONFIG_WRITABLE_SCHEMA</dt>
+** <dd>The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the
+** "writable_schema" flag. This has the same effect and is logically equivalent
+** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF].
+** The first argument to this setting is an integer which is 0 to disable 
+** the writable_schema, positive to enable writable_schema, 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 writable_schema
+** is enabled or disabled following this call.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]]
+** <dt>SQLITE_DBCONFIG_LEGACY_ALTER_TABLE</dt>
+** <dd>The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates
+** the legacy behavior of the [ALTER TABLE RENAME] command such it
+** behaves as it did prior to [version 3.24.0] (2018-06-04).  See the
+** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for
+** additional information. This feature can also be turned on and off
+** using the [PRAGMA legacy_alter_table] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DML]]
+** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DML statement
+** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_DQS_DDL]]
+** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
+** the legacy [double-quoted string literal] misfeature for DDL statements,
+** such as CREATE TABLE and CREATE INDEX. The
+** default value of this setting is determined by the [-DSQLITE_DQS]
+** compile-time option.
 ** </dd>
 ** </dl>
 */
@@ -2172,7 +2261,12 @@ struct sqlite3_mem_methods {
 #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_MAX                   1009 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_DEFENSIVE             1010 /* int int* */
+#define SQLITE_DBCONFIG_WRITABLE_SCHEMA       1011 /* int int* */
+#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE    1012 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DML               1013 /* int int* */
+#define SQLITE_DBCONFIG_DQS_DDL               1014 /* int int* */
+#define SQLITE_DBCONFIG_MAX                   1014 /* Largest DBCONFIG */
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -2329,7 +2423,7 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** 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
+** 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
@@ -2973,9 +3067,9 @@ SQLITE_API int sqlite3_set_authorizer(
 ** time is in units of nanoseconds, however the current implementation
 ** is only capable of millisecond resolution so the six least significant
 ** digits in the time are meaningless.  Future versions of SQLite
-** might provide greater resolution on the profiler callback.  The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
+** might provide greater resolution on the profiler callback.  Invoking
+** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the
+** profile callback.
 */
 SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
    void(*xTrace)(void*,const char*), void*);
@@ -3389,6 +3483,8 @@ SQLITE_API int sqlite3_open_v2(
 ** is not a database file pathname pointer that SQLite passed into the xOpen
 ** VFS method, then the behavior of this routine is undefined and probably
 ** undesirable.
+**
+** See the [URI filename] documentation for additional information.
 */
 SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
 SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
@@ -3610,9 +3706,24 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** 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 is a no-op. This flag used
+** to be required for any prepared statement that wanted to use the
+** [sqlite3_normalized_sql()] interface.  However, the
+** [sqlite3_normalized_sql()] interface is now available to all
+** prepared statements, regardless of whether or not they use this
+** flag.
+**
+** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
+** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
+** to return an error (error code SQLITE_ERROR) if the statement uses
+** any virtual tables.
 ** </dl>
 */
 #define SQLITE_PREPARE_PERSISTENT              0x01
+#define SQLITE_PREPARE_NORMALIZE               0x02
+#define SQLITE_PREPARE_NO_VTAB                 0x04
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
@@ -3770,6 +3881,11 @@ SQLITE_API int sqlite3_prepare16_v3(
 ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
 ** string containing the SQL text of prepared statement P with
 ** [bound parameters] expanded.
+** ^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
@@ -3785,14 +3901,16 @@ SQLITE_API int sqlite3_prepare16_v3(
 ** 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()].
 */
 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
@@ -3830,6 +3948,18 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
 */
 SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 
+/*
+** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement
+** METHOD: sqlite3_stmt
+**
+** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the
+** prepared statement S is an EXPLAIN statement, or 2 if the
+** statement S is an EXPLAIN QUERY PLAN.
+** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is
+** an ordinary statement or a NULL pointer.
+*/
+SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);
+
 /*
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
 ** METHOD: sqlite3_stmt
@@ -3969,7 +4099,9 @@ typedef struct sqlite3_context sqlite3_context;
 ** ^The fifth argument to the BLOB and string binding interfaces
 ** is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
-** to dispose of the BLOB or string even if the call to bind API fails.
+** to dispose of the BLOB or string even if the call to the bind API fails,
+** except the destructor is not called if the third parameter is a NULL
+** pointer or the fourth parameter is negative.
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
 ** information is in static, unmanaged space and does not need to be freed.
@@ -4886,6 +5018,8 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** <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.
+** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
 ** </table></blockquote>
 **
 ** <b>Details:</b>
@@ -4947,6 +5081,11 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** than within an [xUpdate] method call for an UPDATE statement, then
 ** the return value is arbitrary and meaningless.
 **
+** ^The sqlite3_value_frombind(X) interface returns non-zero if the
+** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+** interfaces.  ^If X comes from an SQL literal value, or a table column,
+** and expression, then sqlite3_value_frombind(X) returns zero.
+**
 ** 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
@@ -4992,6 +5131,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*);
+SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
 
 /*
 ** CAPI3REF: Finding The Subtype Of SQL Values
@@ -5727,7 +5867,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 ** associated with database N of connection D.  ^The main database file
 ** has the name "main".  If there is no attached database N on the database
 ** connection D, or if database N is a temporary or in-memory database, then
-** a NULL pointer is returned.
+** this function will return either a NULL pointer or an empty string.
 **
 ** ^The filename returned by this function is the output of the
 ** xFullPathname method of the [VFS].  ^In other words, the filename
@@ -6282,6 +6422,9 @@ struct sqlite3_module {
   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*);
 };
 
 /*
@@ -7204,6 +7347,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
 #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
@@ -7214,7 +7358,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_SORTER_MMAP             24
 #define SQLITE_TESTCTRL_IMPOSTER                25
 #define SQLITE_TESTCTRL_PARSER_COVERAGE         26
-#define SQLITE_TESTCTRL_LAST                    26  /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_RESULT_INTREAL          27
+#define SQLITE_TESTCTRL_LAST                    27  /* Largest TESTCTRL */
 
 /*
 ** CAPI3REF: SQL Keyword Checking
@@ -8616,6 +8761,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
 ** 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,
@@ -9385,7 +9531,7 @@ struct sqlite3_rtree_query_info {
   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 */
@@ -9881,12 +10027,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
 ** 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 */
   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
 
 
 /*
@@ -9930,7 +10102,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
 ** sqlite3changeset_next() is called on the iterator or until the 
 ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
 ** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
 ** is an indirect change, or false (0) otherwise. See the documentation for
 ** [sqlite3session_indirect()] for a description of direct and indirect
 ** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
@@ -10541,7 +10713,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
   ),
   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 */
 );
 
 /*
@@ -10559,8 +10731,14 @@ SQLITE_API int sqlite3changeset_apply_v2(
 **   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
@@ -10791,7 +10969,7 @@ SQLITE_API int sqlite3rebaser_configure(
 ** 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 
+** is set to point to the new buffer containing the rebased changeset 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)
@@ -10954,6 +11132,12 @@ SQLITE_API int sqlite3changeset_start_strm(
   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),
@@ -10980,6 +11164,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
   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++.
@@ -11113,12 +11336,8 @@ struct Fts5PhraseIter {
 **
 **   Usually, output parameter *piPhrase is set to the phrase number, *piCol
 **   to the column in which it occurs and *piOff the token offset of the
-**   first token of the phrase. The exception is if the table was created
-**   with the offsets=0 option specified. In this case *piOff is always
-**   set to -1.
-**
-**   Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) 
-**   if an error occurs.
+**   first token of the phrase. Returns SQLITE_OK if successful, or an error
+**   code (i.e. SQLITE_NOMEM) if an error occurs.
 **
 **   This API can be quite slow if used with an FTS5 table created with the
 **   "detail=none" or "detail=column" option. 
@@ -11159,7 +11378,7 @@ struct Fts5PhraseIter {
 **   Save the pointer passed as the second argument as the extension functions 
 **   "auxiliary data". The pointer may then be retrieved by the current or any
 **   future invocation of the same fts5 extension function made as part of
-**   of the same MATCH query using the xGetAuxdata() API.
+**   the same MATCH query using the xGetAuxdata() API.
 **
 **   Each extension function is allocated a single auxiliary data slot for
 **   each FTS query (MATCH expression). If the extension function is invoked 
@@ -11174,7 +11393,7 @@ struct Fts5PhraseIter {
 **   The xDelete callback, if one is specified, is also invoked on the
 **   auxiliary data pointer after the FTS5 query has finished.
 **
-**   If an error (e.g. an OOM condition) occurs within this function, an
+**   If an error (e.g. an OOM condition) occurs within this function,
 **   the auxiliary data is set to NULL and an error code returned. If the
 **   xDelete parameter was not NULL, it is invoked on the auxiliary data
 **   pointer before returning.
@@ -11407,11 +11626,11 @@ struct Fts5ExtensionApi {
 **            the tokenizer substitutes "first" for "1st" and the query works
 **            as expected.
 **
-**       <li> By adding multiple synonyms for a single term to the FTS index.
-**            In this case, when tokenizing query text, the tokenizer may 
-**            provide multiple synonyms for a single term within the document.
-**            FTS5 then queries the index for each synonym individually. For
-**            example, faced with the query:
+**       <li> By querying the index for all synonyms of each query term
+**            separately. In this case, when tokenizing query text, the
+**            tokenizer may provide multiple synonyms for a single term 
+**            within the document. FTS5 then queries the index for each 
+**            synonym individually. For example, faced with the query:
 **
 **   <codeblock>
 **     ... MATCH 'first place'</codeblock>
@@ -11435,7 +11654,7 @@ struct Fts5ExtensionApi {
 **            "place".
 **
 **            This way, even if the tokenizer does not provide synonyms
-**            when tokenizing query text (it should not - to do would be
+**            when tokenizing query text (it should not - to do so would be
 **            inefficient), it doesn't matter if the user queries for 
 **            'first + place' or '1st + place', as there are entries in the
 **            FTS index corresponding to both forms of the first token.
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3.go b/vendor/github.com/mattn/go-sqlite3/sqlite3.go
index 942b0b5bcb..9e9e91a1f5 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3.go
@@ -683,7 +683,7 @@ func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool
 		ai.stepArgConverters = append(ai.stepArgConverters, conv)
 	}
 	if step.IsVariadic() {
-		conv, err := callbackArg(t.In(start + stepNArgs).Elem())
+		conv, err := callbackArg(step.In(start + stepNArgs).Elem())
 		if err != nil {
 			return err
 		}
@@ -740,6 +740,8 @@ func (c *SQLiteConn) RegisterAggregator(name string, impl interface{}, pure bool
 
 // AutoCommit return which currently auto commit or not.
 func (c *SQLiteConn) AutoCommit() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
 	return int(C.sqlite3_get_autocommit(c.db)) != 0
 }
 
@@ -1340,6 +1342,9 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 		mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE,
 		nil)
 	if rv != 0 {
+		if db != nil {
+			C.sqlite3_close_v2(db)
+		}
 		return nil, Error{Code: ErrNo(rv)}
 	}
 	if db == nil {
@@ -1376,7 +1381,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 	//  - Activate User Authentication
 	//		Check if the user wants to activate User Authentication.
 	//		If so then first create a temporary AuthConn to the database
-	//		This is possible because we are already succesfully authenticated.
+	//		This is possible because we are already successfully authenticated.
 	//
 	//	- Check if `sqlite_user`` table exists
 	//		YES				=> Add the provided user from DSN as Admin User and
@@ -1387,7 +1392,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
 	// Create connection to SQLite
 	conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
 
-	// Password Cipher has to be registerd before authentication
+	// Password Cipher has to be registered before authentication
 	if len(authCrypt) > 0 {
 		switch strings.ToUpper(authCrypt) {
 		case "SHA1":
@@ -1674,7 +1679,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
 	defer C.free(unsafe.Pointer(pquery))
 	var s *C.sqlite3_stmt
 	var tail *C.char
-	rv := C._sqlite3_prepare_v2_internal(c.db, pquery, -1, &s, &tail)
+	rv := C._sqlite3_prepare_v2_internal(c.db, pquery, C.int(-1), &s, &tail)
 	if rv != C.SQLITE_OK {
 		return nil, c.lastError()
 	}
@@ -1718,7 +1723,7 @@ func (c *SQLiteConn) GetFilename(schemaName string) string {
 // GetLimit returns the current value of a run-time limit.
 // See: sqlite3_limit, http://www.sqlite.org/c3ref/limit.html
 func (c *SQLiteConn) GetLimit(id int) int {
-	return int(C._sqlite3_limit(c.db, C.int(id), -1))
+	return int(C._sqlite3_limit(c.db, C.int(id), C.int(-1)))
 }
 
 // SetLimit changes the value of a run-time limits.
@@ -2024,16 +2029,11 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
 		case C.SQLITE_BLOB:
 			p := C.sqlite3_column_blob(rc.s.s, C.int(i))
 			if p == nil {
-				dest[i] = nil
+				dest[i] = []byte{}
 				continue
 			}
-			n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
-			switch dest[i].(type) {
-			default:
-				slice := make([]byte, n)
-				copy(slice[:], (*[1 << 30]byte)(p)[0:n])
-				dest[i] = slice
-			}
+			n := C.sqlite3_column_bytes(rc.s.s, C.int(i))
+			dest[i] = C.GoBytes(p, n)
 		case C.SQLITE_NULL:
 			dest[i] = nil
 		case C.SQLITE_TEXT:
@@ -2062,9 +2062,8 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
 				}
 				dest[i] = t
 			default:
-				dest[i] = []byte(s)
+				dest[i] = s
 			}
-
 		}
 	}
 	return nil
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
index d397c8cfe6..afd93333d7 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
@@ -13,7 +13,7 @@ import (
 
 // This file provides several different implementations for the
 // default embedded sqlite_crypt function.
-// This function is uses a ceasar-cypher by default
+// This function is uses a caesar-cypher by default
 // and is used within the UserAuthentication module to encode
 // the password.
 //
@@ -40,7 +40,7 @@ import (
 // password X, sqlite_crypt(X,NULL) is run.  A new random salt is selected
 // when the second argument is NULL.
 //
-// The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher
+// The built-in version of of sqlite_crypt() uses a simple Caesar-cypher
 // which prevents passwords from being revealed by searching the raw database
 // for ASCII text, but is otherwise trivally broken.  For better password
 // security, the database should be encrypted using the SQLite Encryption
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go b/vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
index 43e6418808..82b7fea09f 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
@@ -10,7 +10,6 @@ package sqlite3
 
 import (
 	"database/sql/driver"
-	"errors"
 
 	"context"
 )
@@ -18,7 +17,8 @@ import (
 // Ping implement Pinger.
 func (c *SQLiteConn) Ping(ctx context.Context) error {
 	if c.db == nil {
-		return errors.New("Connection was closed")
+		// must be ErrBadConn for sql to close the database
+		return driver.ErrBadConn
 	}
 	return nil
 }
diff --git a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
index 50e6866ac4..dd515d711b 100644
--- a/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
+++ b/vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
@@ -311,12 +311,18 @@ struct sqlite3_api_routines {
   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*);
+  /* Version 3.28.0 and later */
+  int (*stmt_isexplain)(sqlite3_stmt*);
+  int (*value_frombind)(sqlite3_value*);
 };
 
 /*
@@ -604,6 +610,11 @@ typedef int (*sqlite3_loadext_entry)(
 #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
+/* Version 3.28.0 and later */
+#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
+#define sqlite3_value_frombind         sqlite3_api->frombind
 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
 
 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db.go b/vendor/github.com/syndtr/goleveldb/leveldb/db.go
index b27c38d37e..90fedf7bd7 100644
--- a/vendor/github.com/syndtr/goleveldb/leveldb/db.go
+++ b/vendor/github.com/syndtr/goleveldb/leveldb/db.go
@@ -872,6 +872,10 @@ func (db *DB) Has(key []byte, ro *opt.ReadOptions) (ret bool, err error) {
 // DB. And a nil Range.Limit is treated as a key after all keys in
 // the DB.
 //
+// WARNING: Any slice returned by interator (e.g. slice returned by calling
+// Iterator.Key() or Iterator.Key() methods), its content should not be modified
+// unless noted otherwise.
+//
 // The iterator must be released after use, by calling Release method.
 //
 // Also read Iterator documentation of the leveldb/iterator package.
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go
index 2c69d2e531..c2ad70c847 100644
--- a/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go
+++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go
@@ -142,6 +142,10 @@ func (snap *Snapshot) Has(key []byte, ro *opt.ReadOptions) (ret bool, err error)
 // DB. And a nil Range.Limit is treated as a key after all keys in
 // the DB.
 //
+// WARNING: Any slice returned by interator (e.g. slice returned by calling
+// Iterator.Key() or Iterator.Value() methods), its content should not be
+// modified unless noted otherwise.
+//
 // The iterator must be released after use, by calling Release method.
 // Releasing the snapshot doesn't mean releasing the iterator too, the
 // iterator would be still valid until released.
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go
index b8f7e7d21d..1a00001882 100644
--- a/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go
+++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go
@@ -69,6 +69,10 @@ func (tr *Transaction) Has(key []byte, ro *opt.ReadOptions) (bool, error) {
 // DB. And a nil Range.Limit is treated as a key after all keys in
 // the DB.
 //
+// WARNING: Any slice returned by interator (e.g. slice returned by calling
+// Iterator.Key() or Iterator.Key() methods), its content should not be modified
+// unless noted otherwise.
+//
 // The iterator must be released after use, by calling Release method.
 //
 // Also read Iterator documentation of the leveldb/iterator package.
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go b/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go
index b661c08a93..824e47f5f4 100644
--- a/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go
+++ b/vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go
@@ -397,6 +397,10 @@ func (p *DB) Find(key []byte) (rkey, value []byte, err error) {
 // DB. And a nil Range.Limit is treated as a key after all keys in
 // the DB.
 //
+// WARNING: Any slice returned by interator (e.g. slice returned by calling
+// Iterator.Key() or Iterator.Key() methods), its content should not be modified
+// unless noted otherwise.
+//
 // The iterator must be released after use, by calling Release method.
 //
 // Also read Iterator documentation of the leveldb/iterator package.
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go b/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go
index 16cfbaa006..496feb6fb4 100644
--- a/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go
+++ b/vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go
@@ -787,6 +787,10 @@ func (r *Reader) getDataIterErr(dataBH blockHandle, slice *util.Range, verifyChe
 // table. And a nil Range.Limit is treated as a key after all keys in
 // the table.
 //
+// WARNING: Any slice returned by interator (e.g. slice returned by calling
+// Iterator.Key() or Iterator.Key() methods), its content should not be modified
+// unless noted otherwise.
+//
 // The returned iterator is not safe for concurrent use and should be released
 // after use.
 //
diff --git a/vendor/github.com/Unknwon/cae/.gitignore b/vendor/github.com/unknwon/cae/.gitignore
similarity index 100%
rename from vendor/github.com/Unknwon/cae/.gitignore
rename to vendor/github.com/unknwon/cae/.gitignore
diff --git a/vendor/github.com/go-macaron/i18n/LICENSE b/vendor/github.com/unknwon/cae/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/i18n/LICENSE
rename to vendor/github.com/unknwon/cae/LICENSE
diff --git a/vendor/github.com/Unknwon/cae/README.md b/vendor/github.com/unknwon/cae/README.md
similarity index 87%
rename from vendor/github.com/Unknwon/cae/README.md
rename to vendor/github.com/unknwon/cae/README.md
index e72de97205..ff6f97ec15 100644
--- a/vendor/github.com/Unknwon/cae/README.md
+++ b/vendor/github.com/unknwon/cae/README.md
@@ -1,7 +1,7 @@
 Compression and Archive Extensions
 ==================================
 
-[![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/cae)
+[![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/unknwon/cae)
 
 [中文文档](README_ZH.md)
 
@@ -11,11 +11,11 @@ But this package has some modifications depends on Go-style.
 
 Reference: [PHP:Compression and Archive Extensions](http://www.php.net/manual/en/refs.compression.php).
 
-Code Convention: based on [Go Code Convention](https://github.com/Unknwon/go-code-convention).
+Code Convention: based on [Go Code Convention](https://github.com/unknwon/go-code-convention).
 
 ### Implementations
 
-Package `zip`([Go Walker](http://gowalker.org/github.com/Unknwon/cae/zip)) and `tz`([Go Walker](http://gowalker.org/github.com/Unknwon/cae/tz)) both enable you to transparently read or write ZIP/TAR.GZ compressed archives and the files inside them.
+Package `zip`([Go Walker](http://gowalker.org/github.com/unknwon/cae/zip)) and `tz`([Go Walker](http://gowalker.org/github.com/unknwon/cae/tz)) both enable you to transparently read or write ZIP/TAR.GZ compressed archives and the files inside them.
 
 - Features:
 	- Add file or directory from everywhere to archive, no one-to-one limitation.
diff --git a/vendor/github.com/Unknwon/cae/README_ZH.md b/vendor/github.com/unknwon/cae/README_ZH.md
similarity index 81%
rename from vendor/github.com/Unknwon/cae/README_ZH.md
rename to vendor/github.com/unknwon/cae/README_ZH.md
index e2f8747ee4..d5c361e3dc 100644
--- a/vendor/github.com/Unknwon/cae/README_ZH.md
+++ b/vendor/github.com/unknwon/cae/README_ZH.md
@@ -1,7 +1,7 @@
 压缩与打包扩展
 =============
 
-[![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/cae)
+[![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/unknwon/cae)
 
 包 cae 实现了 PHP 风格的压缩与打包扩展。
 
@@ -9,11 +9,11 @@
 
 引用:[PHP:Compression and Archive Extensions](http://www.php.net/manual/en/refs.compression.php)
 
-编码规范:基于 [Go 编码规范](https://github.com/Unknwon/go-code-convention)
+编码规范:基于 [Go 编码规范](https://github.com/unknwon/go-code-convention)
 
 ### 实现
 
-包 `zip`([Go Walker](http://gowalker.org/github.com/Unknwon/cae/zip)) 和 `tz`([Go Walker](http://gowalker.org/github.com/Unknwon/cae/tz)) 都允许你轻易的读取或写入 ZIP/TAR.GZ 压缩档案和其内部文件。
+包 `zip`([Go Walker](http://gowalker.org/github.com/unknwon/cae/zip)) 和 `tz`([Go Walker](http://gowalker.org/github.com/unknwon/cae/tz)) 都允许你轻易的读取或写入 ZIP/TAR.GZ 压缩档案和其内部文件。
 
 - 特性:
 	- 将任意位置的文件或目录加入档案,没有一对一的操作限制。
diff --git a/vendor/github.com/Unknwon/cae/cae.go b/vendor/github.com/unknwon/cae/cae.go
similarity index 100%
rename from vendor/github.com/Unknwon/cae/cae.go
rename to vendor/github.com/unknwon/cae/cae.go
diff --git a/vendor/github.com/Unknwon/cae/zip/read.go b/vendor/github.com/unknwon/cae/zip/read.go
similarity index 100%
rename from vendor/github.com/Unknwon/cae/zip/read.go
rename to vendor/github.com/unknwon/cae/zip/read.go
diff --git a/vendor/github.com/Unknwon/cae/zip/stream.go b/vendor/github.com/unknwon/cae/zip/stream.go
similarity index 100%
rename from vendor/github.com/Unknwon/cae/zip/stream.go
rename to vendor/github.com/unknwon/cae/zip/stream.go
diff --git a/vendor/github.com/Unknwon/cae/zip/write.go b/vendor/github.com/unknwon/cae/zip/write.go
similarity index 99%
rename from vendor/github.com/Unknwon/cae/zip/write.go
rename to vendor/github.com/unknwon/cae/zip/write.go
index 076d0e3446..5d4679602c 100644
--- a/vendor/github.com/Unknwon/cae/zip/write.go
+++ b/vendor/github.com/unknwon/cae/zip/write.go
@@ -23,7 +23,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/Unknwon/cae"
+	"github.com/unknwon/cae"
 )
 
 // Switcher of printing trace information when pack and extract.
@@ -231,7 +231,7 @@ func packFile(srcFile string, recPath string, zw *zip.Writer, fi os.FileInfo) er
 				return err
 			}
 			defer f.Close()
-			
+
 			if _, err = io.Copy(fw, f); err != nil {
 				return err
 			}
diff --git a/vendor/github.com/Unknwon/cae/zip/zip.go b/vendor/github.com/unknwon/cae/zip/zip.go
similarity index 99%
rename from vendor/github.com/Unknwon/cae/zip/zip.go
rename to vendor/github.com/unknwon/cae/zip/zip.go
index 21086f825e..b5d7d1071c 100644
--- a/vendor/github.com/Unknwon/cae/zip/zip.go
+++ b/vendor/github.com/unknwon/cae/zip/zip.go
@@ -23,7 +23,7 @@ import (
 	"path"
 	"strings"
 
-	"github.com/Unknwon/cae"
+	"github.com/unknwon/cae"
 )
 
 // A File represents a file or directory entry in archive.
diff --git a/vendor/github.com/Unknwon/com/.gitignore b/vendor/github.com/unknwon/com/.gitignore
similarity index 100%
rename from vendor/github.com/Unknwon/com/.gitignore
rename to vendor/github.com/unknwon/com/.gitignore
diff --git a/vendor/gopkg.in/macaron.v1/.travis.yml b/vendor/github.com/unknwon/com/.travis.yml
similarity index 55%
rename from vendor/gopkg.in/macaron.v1/.travis.yml
rename to vendor/github.com/unknwon/com/.travis.yml
index f331c2c84a..b36cd5c197 100644
--- a/vendor/gopkg.in/macaron.v1/.travis.yml
+++ b/vendor/github.com/unknwon/com/.travis.yml
@@ -1,11 +1,15 @@
-sudo: false
 language: go
+
 go:
+  - 1.3.x
+  - 1.4.x
+  - 1.5.x
   - 1.6.x
   - 1.7.x
   - 1.8.x
   - 1.9.x
   - 1.10.x
   - 1.11.x
+  - 1.12.x
 
-script: go test -v -cover -race
+install: go get -v -t
diff --git a/vendor/github.com/go-macaron/session/LICENSE b/vendor/github.com/unknwon/com/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/session/LICENSE
rename to vendor/github.com/unknwon/com/LICENSE
diff --git a/vendor/github.com/Unknwon/com/README.md b/vendor/github.com/unknwon/com/README.md
similarity index 74%
rename from vendor/github.com/Unknwon/com/README.md
rename to vendor/github.com/unknwon/com/README.md
index 8d821abd65..da0a23bc99 100644
--- a/vendor/github.com/Unknwon/com/README.md
+++ b/vendor/github.com/unknwon/com/README.md
@@ -1,13 +1,13 @@
 Common Functions
 ================
 
-[![Build Status](https://travis-ci.org/Unknwon/com.svg)](https://travis-ci.org/Unknwon/com) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/com)
+[![Build Status](https://travis-ci.org/unknwon/com.svg)](https://travis-ci.org/unknwon/com) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/unknwon/com)
 
 This is an open source project for commonly used functions for the Go programming language.
 
-This package need >= **go 1.2**
+This package need >= **go 1.3**
 
-Code Convention: based on [Go Code Convention](https://github.com/Unknwon/go-code-convention).
+Code Convention: based on [Go Code Convention](https://github.com/unknwon/go-code-convention).
 
 ## Contribute
 
diff --git a/vendor/github.com/Unknwon/com/cmd.go b/vendor/github.com/unknwon/com/cmd.go
similarity index 99%
rename from vendor/github.com/Unknwon/com/cmd.go
rename to vendor/github.com/unknwon/com/cmd.go
index dc7086d8f7..5b4bbaee97 100644
--- a/vendor/github.com/Unknwon/com/cmd.go
+++ b/vendor/github.com/unknwon/com/cmd.go
@@ -1,4 +1,4 @@
-// +build go1.2
+// +build go1.3
 
 // Copyright 2013 com authors
 //
diff --git a/vendor/github.com/Unknwon/com/convert.go b/vendor/github.com/unknwon/com/convert.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/convert.go
rename to vendor/github.com/unknwon/com/convert.go
diff --git a/vendor/github.com/Unknwon/com/dir.go b/vendor/github.com/unknwon/com/dir.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/dir.go
rename to vendor/github.com/unknwon/com/dir.go
diff --git a/vendor/github.com/Unknwon/com/file.go b/vendor/github.com/unknwon/com/file.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/file.go
rename to vendor/github.com/unknwon/com/file.go
diff --git a/vendor/github.com/Unknwon/com/go.mod b/vendor/github.com/unknwon/com/go.mod
similarity index 90%
rename from vendor/github.com/Unknwon/com/go.mod
rename to vendor/github.com/unknwon/com/go.mod
index 0bb87b46af..43834a963c 100644
--- a/vendor/github.com/Unknwon/com/go.mod
+++ b/vendor/github.com/unknwon/com/go.mod
@@ -1,4 +1,4 @@
-module github.com/Unknwon/com
+module github.com/unknwon/com
 
 require (
 	github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
diff --git a/vendor/github.com/Unknwon/com/go.sum b/vendor/github.com/unknwon/com/go.sum
similarity index 100%
rename from vendor/github.com/Unknwon/com/go.sum
rename to vendor/github.com/unknwon/com/go.sum
diff --git a/vendor/github.com/Unknwon/com/html.go b/vendor/github.com/unknwon/com/html.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/html.go
rename to vendor/github.com/unknwon/com/html.go
diff --git a/vendor/github.com/Unknwon/com/http.go b/vendor/github.com/unknwon/com/http.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/http.go
rename to vendor/github.com/unknwon/com/http.go
diff --git a/vendor/github.com/Unknwon/com/math.go b/vendor/github.com/unknwon/com/math.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/math.go
rename to vendor/github.com/unknwon/com/math.go
diff --git a/vendor/github.com/Unknwon/com/path.go b/vendor/github.com/unknwon/com/path.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/path.go
rename to vendor/github.com/unknwon/com/path.go
diff --git a/vendor/github.com/Unknwon/com/regex.go b/vendor/github.com/unknwon/com/regex.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/regex.go
rename to vendor/github.com/unknwon/com/regex.go
diff --git a/vendor/github.com/Unknwon/com/slice.go b/vendor/github.com/unknwon/com/slice.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/slice.go
rename to vendor/github.com/unknwon/com/slice.go
diff --git a/vendor/github.com/Unknwon/com/string.go b/vendor/github.com/unknwon/com/string.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/string.go
rename to vendor/github.com/unknwon/com/string.go
diff --git a/vendor/github.com/Unknwon/com/time.go b/vendor/github.com/unknwon/com/time.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/time.go
rename to vendor/github.com/unknwon/com/time.go
diff --git a/vendor/github.com/Unknwon/com/url.go b/vendor/github.com/unknwon/com/url.go
similarity index 100%
rename from vendor/github.com/Unknwon/com/url.go
rename to vendor/github.com/unknwon/com/url.go
diff --git a/vendor/github.com/Unknwon/i18n/.gitignore b/vendor/github.com/unknwon/i18n/.gitignore
similarity index 100%
rename from vendor/github.com/Unknwon/i18n/.gitignore
rename to vendor/github.com/unknwon/i18n/.gitignore
diff --git a/vendor/github.com/go-macaron/toolbox/LICENSE b/vendor/github.com/unknwon/i18n/LICENSE
similarity index 100%
rename from vendor/github.com/go-macaron/toolbox/LICENSE
rename to vendor/github.com/unknwon/i18n/LICENSE
diff --git a/vendor/github.com/Unknwon/i18n/Makefile b/vendor/github.com/unknwon/i18n/Makefile
similarity index 100%
rename from vendor/github.com/Unknwon/i18n/Makefile
rename to vendor/github.com/unknwon/i18n/Makefile
diff --git a/vendor/github.com/Unknwon/i18n/README.md b/vendor/github.com/unknwon/i18n/README.md
similarity index 86%
rename from vendor/github.com/Unknwon/i18n/README.md
rename to vendor/github.com/unknwon/i18n/README.md
index 7503e41f28..4e3bff7526 100644
--- a/vendor/github.com/Unknwon/i18n/README.md
+++ b/vendor/github.com/unknwon/i18n/README.md
@@ -1,5 +1,4 @@
-i18n [![GoDoc](https://godoc.org/github.com/Unknwon/i18n?status.svg)](https://godoc.org/github.com/Unknwon/i18n) [![Sourcegraph](https://sourcegraph.com/github.com/Unknwon/i18n/-/badge.svg)](https://sourcegraph.com/github.com/Unknwon/i18n?badge)
-====
+# i18n [![GoDoc](https://godoc.org/github.com/unknwon/i18n?status.svg)](https://godoc.org/github.com/unknwon/i18n)
 
 Package i18n is for app Internationalization and Localization.
 
@@ -16,10 +15,10 @@ You can use following command to install this module:
 First of all, you have to import this package:
 
 ```go
-import "github.com/Unknwon/i18n"
+import "github.com/unknwon/i18n"
 ```
 
-The format of locale files is very like INI format configuration file, which is basically key-value pairs. But this module has some improvements. Every language corresponding to a locale file, for example, under `conf/locale` folder of [gogsweb](https://github.com/gogits/gogsweb/tree/master/conf/locale), there are two files called `locale_en-US.ini` and `locale_zh-CN.ini`.
+The format of locale files is very like INI format configuration file, which is basically key-value pairs. But this module has some improvements. Every language corresponding to a locale file, for example, suppose there are two files called `locale_en-US.ini` and `locale_zh-CN.ini`.
 
 The name and extensions of locale files can be anything, but we strongly recommend you to follow the style of gogsweb.
 
@@ -119,7 +118,7 @@ to get expect result.
 
 Module i18n provides a command line helper tool beei18n for simplify steps of your development. You can install it as follows:
 
-	go get github.com/Unknwon/i18n/ui18n
+	go get github.com/unknwon/i18n/ui18n
 
 ### Sync locale files
 
diff --git a/vendor/github.com/unknwon/i18n/go.mod b/vendor/github.com/unknwon/i18n/go.mod
new file mode 100644
index 0000000000..4d252d68ea
--- /dev/null
+++ b/vendor/github.com/unknwon/i18n/go.mod
@@ -0,0 +1,9 @@
+module github.com/unknwon/i18n
+
+go 1.12
+
+require (
+	github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
+	github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+	gopkg.in/ini.v1 v1.46.0
+)
diff --git a/vendor/github.com/unknwon/i18n/go.sum b/vendor/github.com/unknwon/i18n/go.sum
new file mode 100644
index 0000000000..8bb9e76563
--- /dev/null
+++ b/vendor/github.com/unknwon/i18n/go.sum
@@ -0,0 +1,21 @@
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
+github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
+github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
+github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+gopkg.in/ini.v1 v1.46.0 h1:VeDZbLYGaupuvIrsYCEOe/L/2Pcs5n7hdO1ZTjporag=
+gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/vendor/github.com/Unknwon/i18n/i18n.go b/vendor/github.com/unknwon/i18n/i18n.go
similarity index 100%
rename from vendor/github.com/Unknwon/i18n/i18n.go
rename to vendor/github.com/unknwon/i18n/i18n.go
diff --git a/vendor/github.com/Unknwon/paginater/.gitignore b/vendor/github.com/unknwon/paginater/.gitignore
similarity index 100%
rename from vendor/github.com/Unknwon/paginater/.gitignore
rename to vendor/github.com/unknwon/paginater/.gitignore
diff --git a/vendor/github.com/Unknwon/paginater/LICENSE b/vendor/github.com/unknwon/paginater/LICENSE
similarity index 100%
rename from vendor/github.com/Unknwon/paginater/LICENSE
rename to vendor/github.com/unknwon/paginater/LICENSE
diff --git a/vendor/github.com/Unknwon/paginater/README.md b/vendor/github.com/unknwon/paginater/README.md
similarity index 100%
rename from vendor/github.com/Unknwon/paginater/README.md
rename to vendor/github.com/unknwon/paginater/README.md
diff --git a/vendor/github.com/Unknwon/paginater/paginater.go b/vendor/github.com/unknwon/paginater/paginater.go
similarity index 100%
rename from vendor/github.com/Unknwon/paginater/paginater.go
rename to vendor/github.com/unknwon/paginater/paginater.go
diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go
index bbc1cb9c34..a6ec19e14c 100644
--- a/vendor/google.golang.org/appengine/internal/api.go
+++ b/vendor/google.golang.org/appengine/internal/api.go
@@ -44,6 +44,7 @@ var (
 	curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
 	userIPHeader       = http.CanonicalHeaderKey("X-AppEngine-User-IP")
 	remoteAddrHeader   = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
+	devRequestIdHeader = http.CanonicalHeaderKey("X-Appengine-Dev-Request-Id")
 
 	// Outgoing headers.
 	apiEndpointHeader      = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
@@ -494,6 +495,9 @@ func Call(ctx netcontext.Context, service, method string, in, out proto.Message)
 	if ticket == "" {
 		ticket = DefaultTicket()
 	}
+	if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
+		ticket = dri
+	}
 	req := &remotepb.Request{
 		ServiceName: &service,
 		Method:      &method,
diff --git a/vendor/gopkg.in/bufio.v1/.travis.yml b/vendor/gopkg.in/bufio.v1/.travis.yml
deleted file mode 100644
index ccca6bb4a6..0000000000
--- a/vendor/gopkg.in/bufio.v1/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: go
-
-go:
-  - 1.0
-  - 1.1
-  - 1.2
-  - tip
-
-install:
-  - go get launchpad.net/gocheck
-  - go get gopkg.in/bufio.v1
diff --git a/vendor/gopkg.in/bufio.v1/LICENSE b/vendor/gopkg.in/bufio.v1/LICENSE
deleted file mode 100644
index 07a316cbf4..0000000000
--- a/vendor/gopkg.in/bufio.v1/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2013 The bufio Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/gopkg.in/bufio.v1/Makefile b/vendor/gopkg.in/bufio.v1/Makefile
deleted file mode 100644
index 038ed47e94..0000000000
--- a/vendor/gopkg.in/bufio.v1/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-all:
-	go test gopkg.in/bufio.v1
diff --git a/vendor/gopkg.in/bufio.v1/README.md b/vendor/gopkg.in/bufio.v1/README.md
deleted file mode 100644
index bfb85ee544..0000000000
--- a/vendor/gopkg.in/bufio.v1/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-bufio
-=====
-
-This is a fork of the http://golang.org/pkg/bufio/ package. It adds `ReadN` method that allows reading next `n` bytes from the internal buffer without allocating intermediate buffer. This method works just like the [Buffer.Next](http://golang.org/pkg/bytes/#Buffer.Next) method, but has slightly different signature.
diff --git a/vendor/gopkg.in/bufio.v1/buffer.go b/vendor/gopkg.in/bufio.v1/buffer.go
deleted file mode 100644
index 8b915605b6..0000000000
--- a/vendor/gopkg.in/bufio.v1/buffer.go
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bufio
-
-// Simple byte buffer for marshaling data.
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"unicode/utf8"
-)
-
-// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
-// The zero value for Buffer is an empty buffer ready to use.
-type Buffer struct {
-	buf       []byte            // contents are the bytes buf[off : len(buf)]
-	off       int               // read at &buf[off], write at &buf[len(buf)]
-	runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
-	bootstrap [64]byte          // memory to hold first slice; helps small buffers (Printf) avoid allocation.
-	lastRead  readOp            // last read operation, so that Unread* can work correctly.
-}
-
-// The readOp constants describe the last action performed on
-// the buffer, so that UnreadRune and UnreadByte can
-// check for invalid usage.
-type readOp int
-
-const (
-	opInvalid  readOp = iota // Non-read operation.
-	opReadRune               // Read rune.
-	opRead                   // Any other read operation.
-)
-
-// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
-var ErrTooLarge = errors.New("bytes.Buffer: too large")
-
-// Bytes returns a slice of the contents of the unread portion of the buffer;
-// len(b.Bytes()) == b.Len().  If the caller changes the contents of the
-// returned slice, the contents of the buffer will change provided there
-// are no intervening method calls on the Buffer.
-func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
-
-// String returns the contents of the unread portion of the buffer
-// as a string.  If the Buffer is a nil pointer, it returns "<nil>".
-func (b *Buffer) String() string {
-	if b == nil {
-		// Special case, useful in debugging.
-		return "<nil>"
-	}
-	return string(b.buf[b.off:])
-}
-
-// Len returns the number of bytes of the unread portion of the buffer;
-// b.Len() == len(b.Bytes()).
-func (b *Buffer) Len() int { return len(b.buf) - b.off }
-
-// Truncate discards all but the first n unread bytes from the buffer.
-// It panics if n is negative or greater than the length of the buffer.
-func (b *Buffer) Truncate(n int) {
-	b.lastRead = opInvalid
-	switch {
-	case n < 0 || n > b.Len():
-		panic("bytes.Buffer: truncation out of range")
-	case n == 0:
-		// Reuse buffer space.
-		b.off = 0
-	}
-	b.buf = b.buf[0 : b.off+n]
-}
-
-// Reset resets the buffer so it has no content.
-// b.Reset() is the same as b.Truncate(0).
-func (b *Buffer) Reset() { b.Truncate(0) }
-
-// grow grows the buffer to guarantee space for n more bytes.
-// It returns the index where bytes should be written.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) grow(n int) int {
-	m := b.Len()
-	// If buffer is empty, reset to recover space.
-	if m == 0 && b.off != 0 {
-		b.Truncate(0)
-	}
-	if len(b.buf)+n > cap(b.buf) {
-		var buf []byte
-		if b.buf == nil && n <= len(b.bootstrap) {
-			buf = b.bootstrap[0:]
-		} else if m+n <= cap(b.buf)/2 {
-			// We can slide things down instead of allocating a new
-			// slice. We only need m+n <= cap(b.buf) to slide, but
-			// we instead let capacity get twice as large so we
-			// don't spend all our time copying.
-			copy(b.buf[:], b.buf[b.off:])
-			buf = b.buf[:m]
-		} else {
-			// not enough space anywhere
-			buf = makeSlice(2*cap(b.buf) + n)
-			copy(buf, b.buf[b.off:])
-		}
-		b.buf = buf
-		b.off = 0
-	}
-	b.buf = b.buf[0 : b.off+m+n]
-	return b.off + m
-}
-
-// Grow grows the buffer's capacity, if necessary, to guarantee space for
-// another n bytes. After Grow(n), at least n bytes can be written to the
-// buffer without another allocation.
-// If n is negative, Grow will panic.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) Grow(n int) {
-	if n < 0 {
-		panic("bytes.Buffer.Grow: negative count")
-	}
-	m := b.grow(n)
-	b.buf = b.buf[0:m]
-}
-
-// Write appends the contents of p to the buffer, growing the buffer as
-// needed. The return value n is the length of p; err is always nil. If the
-// buffer becomes too large, Write will panic with ErrTooLarge.
-func (b *Buffer) Write(p []byte) (n int, err error) {
-	b.lastRead = opInvalid
-	m := b.grow(len(p))
-	return copy(b.buf[m:], p), nil
-}
-
-// WriteString appends the contents of s to the buffer, growing the buffer as
-// needed. The return value n is the length of s; err is always nil. If the
-// buffer becomes too large, WriteString will panic with ErrTooLarge.
-func (b *Buffer) WriteString(s string) (n int, err error) {
-	b.lastRead = opInvalid
-	m := b.grow(len(s))
-	return copy(b.buf[m:], s), nil
-}
-
-// MinRead is the minimum slice size passed to a Read call by
-// Buffer.ReadFrom.  As long as the Buffer has at least MinRead bytes beyond
-// what is required to hold the contents of r, ReadFrom will not grow the
-// underlying buffer.
-const MinRead = 512
-
-// ReadFrom reads data from r until EOF and appends it to the buffer, growing
-// the buffer as needed. The return value n is the number of bytes read. Any
-// error except io.EOF encountered during the read is also returned. If the
-// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
-func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
-	b.lastRead = opInvalid
-	// If buffer is empty, reset to recover space.
-	if b.off >= len(b.buf) {
-		b.Truncate(0)
-	}
-	for {
-		if free := cap(b.buf) - len(b.buf); free < MinRead {
-			// not enough space at end
-			newBuf := b.buf
-			if b.off+free < MinRead {
-				// not enough space using beginning of buffer;
-				// double buffer capacity
-				newBuf = makeSlice(2*cap(b.buf) + MinRead)
-			}
-			copy(newBuf, b.buf[b.off:])
-			b.buf = newBuf[:len(b.buf)-b.off]
-			b.off = 0
-		}
-		m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
-		b.buf = b.buf[0 : len(b.buf)+m]
-		n += int64(m)
-		if e == io.EOF {
-			break
-		}
-		if e != nil {
-			return n, e
-		}
-	}
-	return n, nil // err is EOF, so return nil explicitly
-}
-
-// makeSlice allocates a slice of size n. If the allocation fails, it panics
-// with ErrTooLarge.
-func makeSlice(n int) []byte {
-	// If the make fails, give a known error.
-	defer func() {
-		if recover() != nil {
-			panic(ErrTooLarge)
-		}
-	}()
-	return make([]byte, n)
-}
-
-// WriteTo writes data to w until the buffer is drained or an error occurs.
-// The return value n is the number of bytes written; it always fits into an
-// int, but it is int64 to match the io.WriterTo interface. Any error
-// encountered during the write is also returned.
-func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
-	b.lastRead = opInvalid
-	if b.off < len(b.buf) {
-		nBytes := b.Len()
-		m, e := w.Write(b.buf[b.off:])
-		if m > nBytes {
-			panic("bytes.Buffer.WriteTo: invalid Write count")
-		}
-		b.off += m
-		n = int64(m)
-		if e != nil {
-			return n, e
-		}
-		// all bytes should have been written, by definition of
-		// Write method in io.Writer
-		if m != nBytes {
-			return n, io.ErrShortWrite
-		}
-	}
-	// Buffer is now empty; reset.
-	b.Truncate(0)
-	return
-}
-
-// WriteByte appends the byte c to the buffer, growing the buffer as needed.
-// The returned error is always nil, but is included to match bufio.Writer's
-// WriteByte. If the buffer becomes too large, WriteByte will panic with
-// ErrTooLarge.
-func (b *Buffer) WriteByte(c byte) error {
-	b.lastRead = opInvalid
-	m := b.grow(1)
-	b.buf[m] = c
-	return nil
-}
-
-// WriteRune appends the UTF-8 encoding of Unicode code point r to the
-// buffer, returning its length and an error, which is always nil but is
-// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
-// if it becomes too large, WriteRune will panic with ErrTooLarge.
-func (b *Buffer) WriteRune(r rune) (n int, err error) {
-	if r < utf8.RuneSelf {
-		b.WriteByte(byte(r))
-		return 1, nil
-	}
-	n = utf8.EncodeRune(b.runeBytes[0:], r)
-	b.Write(b.runeBytes[0:n])
-	return n, nil
-}
-
-// Read reads the next len(p) bytes from the buffer or until the buffer
-// is drained.  The return value n is the number of bytes read.  If the
-// buffer has no data to return, err is io.EOF (unless len(p) is zero);
-// otherwise it is nil.
-func (b *Buffer) Read(p []byte) (n int, err error) {
-	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
-		// Buffer is empty, reset to recover space.
-		b.Truncate(0)
-		if len(p) == 0 {
-			return
-		}
-		return 0, io.EOF
-	}
-	n = copy(p, b.buf[b.off:])
-	b.off += n
-	if n > 0 {
-		b.lastRead = opRead
-	}
-	return
-}
-
-// Next returns a slice containing the next n bytes from the buffer,
-// advancing the buffer as if the bytes had been returned by Read.
-// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
-// The slice is only valid until the next call to a read or write method.
-func (b *Buffer) Next(n int) []byte {
-	b.lastRead = opInvalid
-	m := b.Len()
-	if n > m {
-		n = m
-	}
-	data := b.buf[b.off : b.off+n]
-	b.off += n
-	if n > 0 {
-		b.lastRead = opRead
-	}
-	return data
-}
-
-// ReadByte reads and returns the next byte from the buffer.
-// If no byte is available, it returns error io.EOF.
-func (b *Buffer) ReadByte() (c byte, err error) {
-	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
-		// Buffer is empty, reset to recover space.
-		b.Truncate(0)
-		return 0, io.EOF
-	}
-	c = b.buf[b.off]
-	b.off++
-	b.lastRead = opRead
-	return c, nil
-}
-
-// ReadRune reads and returns the next UTF-8-encoded
-// Unicode code point from the buffer.
-// If no bytes are available, the error returned is io.EOF.
-// If the bytes are an erroneous UTF-8 encoding, it
-// consumes one byte and returns U+FFFD, 1.
-func (b *Buffer) ReadRune() (r rune, size int, err error) {
-	b.lastRead = opInvalid
-	if b.off >= len(b.buf) {
-		// Buffer is empty, reset to recover space.
-		b.Truncate(0)
-		return 0, 0, io.EOF
-	}
-	b.lastRead = opReadRune
-	c := b.buf[b.off]
-	if c < utf8.RuneSelf {
-		b.off++
-		return rune(c), 1, nil
-	}
-	r, n := utf8.DecodeRune(b.buf[b.off:])
-	b.off += n
-	return r, n, nil
-}
-
-// UnreadRune unreads the last rune returned by ReadRune.
-// If the most recent read or write operation on the buffer was
-// not a ReadRune, UnreadRune returns an error.  (In this regard
-// it is stricter than UnreadByte, which will unread the last byte
-// from any read operation.)
-func (b *Buffer) UnreadRune() error {
-	if b.lastRead != opReadRune {
-		return errors.New("bytes.Buffer: UnreadRune: previous operation was not ReadRune")
-	}
-	b.lastRead = opInvalid
-	if b.off > 0 {
-		_, n := utf8.DecodeLastRune(b.buf[0:b.off])
-		b.off -= n
-	}
-	return nil
-}
-
-// UnreadByte unreads the last byte returned by the most recent
-// read operation.  If write has happened since the last read, UnreadByte
-// returns an error.
-func (b *Buffer) UnreadByte() error {
-	if b.lastRead != opReadRune && b.lastRead != opRead {
-		return errors.New("bytes.Buffer: UnreadByte: previous operation was not a read")
-	}
-	b.lastRead = opInvalid
-	if b.off > 0 {
-		b.off--
-	}
-	return nil
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
-	slice, err := b.readSlice(delim)
-	// return a copy of slice. The buffer's backing array may
-	// be overwritten by later calls.
-	line = append(line, slice...)
-	return
-}
-
-// readSlice is like ReadBytes but returns a reference to internal buffer data.
-func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
-	i := bytes.IndexByte(b.buf[b.off:], delim)
-	end := b.off + i + 1
-	if i < 0 {
-		end = len(b.buf)
-		err = io.EOF
-	}
-	line = b.buf[b.off:end]
-	b.off = end
-	b.lastRead = opRead
-	return line, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end
-// in delim.
-func (b *Buffer) ReadString(delim byte) (line string, err error) {
-	slice, err := b.readSlice(delim)
-	return string(slice), err
-}
-
-// NewBuffer creates and initializes a new Buffer using buf as its initial
-// contents.  It is intended to prepare a Buffer to read existing data.  It
-// can also be used to size the internal buffer for writing. To do that,
-// buf should have the desired capacity but a length of zero.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
-
-// NewBufferString creates and initializes a new Buffer using string s as its
-// initial contents. It is intended to prepare a buffer to read an existing
-// string.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBufferString(s string) *Buffer {
-	return &Buffer{buf: []byte(s)}
-}
diff --git a/vendor/gopkg.in/bufio.v1/bufio.go b/vendor/gopkg.in/bufio.v1/bufio.go
deleted file mode 100644
index 8f5cdc084d..0000000000
--- a/vendor/gopkg.in/bufio.v1/bufio.go
+++ /dev/null
@@ -1,728 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bufio implements buffered I/O.  It wraps an io.Reader or io.Writer
-// object, creating another object (Reader or Writer) that also implements
-// the interface but provides buffering and some help for textual I/O.
-package bufio
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"unicode/utf8"
-)
-
-const (
-	defaultBufSize = 4096
-)
-
-var (
-	ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
-	ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
-	ErrBufferFull        = errors.New("bufio: buffer full")
-	ErrNegativeCount     = errors.New("bufio: negative count")
-)
-
-// Buffered input.
-
-// Reader implements buffering for an io.Reader object.
-type Reader struct {
-	buf          []byte
-	rd           io.Reader
-	r, w         int
-	err          error
-	lastByte     int
-	lastRuneSize int
-}
-
-const minReadBufferSize = 16
-const maxConsecutiveEmptyReads = 100
-
-// NewReaderSize returns a new Reader whose buffer has at least the specified
-// size. If the argument io.Reader is already a Reader with large enough
-// size, it returns the underlying Reader.
-func NewReaderSize(rd io.Reader, size int) *Reader {
-	// Is it already a Reader?
-	b, ok := rd.(*Reader)
-	if ok && len(b.buf) >= size {
-		return b
-	}
-	if size < minReadBufferSize {
-		size = minReadBufferSize
-	}
-	r := new(Reader)
-	r.reset(make([]byte, size), rd)
-	return r
-}
-
-// NewReader returns a new Reader whose buffer has the default size.
-func NewReader(rd io.Reader) *Reader {
-	return NewReaderSize(rd, defaultBufSize)
-}
-
-// Reset discards any buffered data, resets all state, and switches
-// the buffered reader to read from r.
-func (b *Reader) Reset(r io.Reader) {
-	b.reset(b.buf, r)
-}
-
-func (b *Reader) reset(buf []byte, r io.Reader) {
-	*b = Reader{
-		buf:          buf,
-		rd:           r,
-		lastByte:     -1,
-		lastRuneSize: -1,
-	}
-}
-
-var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
-
-// fill reads a new chunk into the buffer.
-func (b *Reader) fill() {
-	// Slide existing data to beginning.
-	if b.r > 0 {
-		copy(b.buf, b.buf[b.r:b.w])
-		b.w -= b.r
-		b.r = 0
-	}
-
-	if b.w >= len(b.buf) {
-		panic("bufio: tried to fill full buffer")
-	}
-
-	// Read new data: try a limited number of times.
-	for i := maxConsecutiveEmptyReads; i > 0; i-- {
-		n, err := b.rd.Read(b.buf[b.w:])
-		if n < 0 {
-			panic(errNegativeRead)
-		}
-		b.w += n
-		if err != nil {
-			b.err = err
-			return
-		}
-		if n > 0 {
-			return
-		}
-	}
-	b.err = io.ErrNoProgress
-}
-
-func (b *Reader) readErr() error {
-	err := b.err
-	b.err = nil
-	return err
-}
-
-// Peek returns the next n bytes without advancing the reader. The bytes stop
-// being valid at the next read call. If Peek returns fewer than n bytes, it
-// also returns an error explaining why the read is short. The error is
-// ErrBufferFull if n is larger than b's buffer size.
-func (b *Reader) Peek(n int) ([]byte, error) {
-	if n < 0 {
-		return nil, ErrNegativeCount
-	}
-	if n > len(b.buf) {
-		return nil, ErrBufferFull
-	}
-	// 0 <= n <= len(b.buf)
-	for b.w-b.r < n && b.err == nil {
-		b.fill() // b.w-b.r < len(b.buf) => buffer is not full
-	}
-	m := b.w - b.r
-	if m > n {
-		m = n
-	}
-	var err error
-	if m < n {
-		err = b.readErr()
-		if err == nil {
-			err = ErrBufferFull
-		}
-	}
-	return b.buf[b.r : b.r+m], err
-}
-
-// Read reads data into p.
-// It returns the number of bytes read into p.
-// It calls Read at most once on the underlying Reader,
-// hence n may be less than len(p).
-// At EOF, the count will be zero and err will be io.EOF.
-func (b *Reader) Read(p []byte) (n int, err error) {
-	n = len(p)
-	if n == 0 {
-		return 0, b.readErr()
-	}
-	if b.r == b.w {
-		if b.err != nil {
-			return 0, b.readErr()
-		}
-		if len(p) >= len(b.buf) {
-			// Large read, empty buffer.
-			// Read directly into p to avoid copy.
-			n, b.err = b.rd.Read(p)
-			if n < 0 {
-				panic(errNegativeRead)
-			}
-			if n > 0 {
-				b.lastByte = int(p[n-1])
-				b.lastRuneSize = -1
-			}
-			return n, b.readErr()
-		}
-		b.fill() // buffer is empty
-		if b.w == b.r {
-			return 0, b.readErr()
-		}
-	}
-
-	if n > b.w-b.r {
-		n = b.w - b.r
-	}
-	copy(p[0:n], b.buf[b.r:])
-	b.r += n
-	b.lastByte = int(b.buf[b.r-1])
-	b.lastRuneSize = -1
-	return n, nil
-}
-
-// ReadByte reads and returns a single byte.
-// If no byte is available, returns an error.
-func (b *Reader) ReadByte() (c byte, err error) {
-	b.lastRuneSize = -1
-	for b.r == b.w {
-		if b.err != nil {
-			return 0, b.readErr()
-		}
-		b.fill() // buffer is empty
-	}
-	c = b.buf[b.r]
-	b.r++
-	b.lastByte = int(c)
-	return c, nil
-}
-
-// UnreadByte unreads the last byte.  Only the most recently read byte can be unread.
-func (b *Reader) UnreadByte() error {
-	if b.lastByte < 0 || b.r == 0 && b.w > 0 {
-		return ErrInvalidUnreadByte
-	}
-	// b.r > 0 || b.w == 0
-	if b.r > 0 {
-		b.r--
-	} else {
-		// b.r == 0 && b.w == 0
-		b.w = 1
-	}
-	b.buf[b.r] = byte(b.lastByte)
-	b.lastByte = -1
-	b.lastRuneSize = -1
-	return nil
-}
-
-// ReadRune reads a single UTF-8 encoded Unicode character and returns the
-// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
-// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
-func (b *Reader) ReadRune() (r rune, size int, err error) {
-	for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil && b.w-b.r < len(b.buf) {
-		b.fill() // b.w-b.r < len(buf) => buffer is not full
-	}
-	b.lastRuneSize = -1
-	if b.r == b.w {
-		return 0, 0, b.readErr()
-	}
-	r, size = rune(b.buf[b.r]), 1
-	if r >= 0x80 {
-		r, size = utf8.DecodeRune(b.buf[b.r:b.w])
-	}
-	b.r += size
-	b.lastByte = int(b.buf[b.r-1])
-	b.lastRuneSize = size
-	return r, size, nil
-}
-
-// UnreadRune unreads the last rune.  If the most recent read operation on
-// the buffer was not a ReadRune, UnreadRune returns an error.  (In this
-// regard it is stricter than UnreadByte, which will unread the last byte
-// from any read operation.)
-func (b *Reader) UnreadRune() error {
-	if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
-		return ErrInvalidUnreadRune
-	}
-	b.r -= b.lastRuneSize
-	b.lastByte = -1
-	b.lastRuneSize = -1
-	return nil
-}
-
-// Buffered returns the number of bytes that can be read from the current buffer.
-func (b *Reader) Buffered() int { return b.w - b.r }
-
-// ReadSlice reads until the first occurrence of delim in the input,
-// returning a slice pointing at the bytes in the buffer.
-// The bytes stop being valid at the next read.
-// If ReadSlice encounters an error before finding a delimiter,
-// it returns all the data in the buffer and the error itself (often io.EOF).
-// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
-// Because the data returned from ReadSlice will be overwritten
-// by the next I/O operation, most clients should use
-// ReadBytes or ReadString instead.
-// ReadSlice returns err != nil if and only if line does not end in delim.
-func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
-	for {
-		// Search buffer.
-		if i := bytes.IndexByte(b.buf[b.r:b.w], delim); i >= 0 {
-			line = b.buf[b.r : b.r+i+1]
-			b.r += i + 1
-			break
-		}
-
-		// Pending error?
-		if b.err != nil {
-			line = b.buf[b.r:b.w]
-			b.r = b.w
-			err = b.readErr()
-			break
-		}
-
-		// Buffer full?
-		if n := b.Buffered(); n >= len(b.buf) {
-			b.r = b.w
-			line = b.buf
-			err = ErrBufferFull
-			break
-		}
-
-		b.fill() // buffer is not full
-	}
-
-	// Handle last byte, if any.
-	if i := len(line) - 1; i >= 0 {
-		b.lastByte = int(line[i])
-	}
-
-	return
-}
-
-// ReadN tries to read exactly n bytes.
-// The bytes stop being valid at the next read call.
-// If ReadN encounters an error before reading n bytes,
-// it returns all the data in the buffer and the error itself (often io.EOF).
-// ReadN fails with error ErrBufferFull if the buffer fills
-// without reading N bytes.
-// Because the data returned from ReadN will be overwritten
-// by the next I/O operation, most clients should use
-// ReadBytes or ReadString instead.
-func (b *Reader) ReadN(n int) ([]byte, error) {
-	for b.Buffered() < n {
-		if b.err != nil {
-			buf := b.buf[b.r:b.w]
-			b.r = b.w
-			return buf, b.readErr()
-		}
-
-		// Buffer is full?
-		if b.Buffered() >= len(b.buf) {
-			b.r = b.w
-			return b.buf, ErrBufferFull
-		}
-
-		b.fill()
-	}
-	buf := b.buf[b.r : b.r+n]
-	b.r += n
-	return buf, nil
-}
-
-// ReadLine is a low-level line-reading primitive. Most callers should use
-// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
-//
-// ReadLine tries to return a single line, not including the end-of-line bytes.
-// If the line was too long for the buffer then isPrefix is set and the
-// beginning of the line is returned. The rest of the line will be returned
-// from future calls. isPrefix will be false when returning the last fragment
-// of the line. The returned buffer is only valid until the next call to
-// ReadLine. ReadLine either returns a non-nil line or it returns an error,
-// never both.
-//
-// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
-// No indication or error is given if the input ends without a final line end.
-// Calling UnreadByte after ReadLine will always unread the last byte read
-// (possibly a character belonging to the line end) even if that byte is not
-// part of the line returned by ReadLine.
-func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
-	line, err = b.ReadSlice('\n')
-	if err == ErrBufferFull {
-		// Handle the case where "\r\n" straddles the buffer.
-		if len(line) > 0 && line[len(line)-1] == '\r' {
-			// Put the '\r' back on buf and drop it from line.
-			// Let the next call to ReadLine check for "\r\n".
-			if b.r == 0 {
-				// should be unreachable
-				panic("bufio: tried to rewind past start of buffer")
-			}
-			b.r--
-			line = line[:len(line)-1]
-		}
-		return line, true, nil
-	}
-
-	if len(line) == 0 {
-		if err != nil {
-			line = nil
-		}
-		return
-	}
-	err = nil
-
-	if line[len(line)-1] == '\n' {
-		drop := 1
-		if len(line) > 1 && line[len(line)-2] == '\r' {
-			drop = 2
-		}
-		line = line[:len(line)-drop]
-	}
-	return
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
-	// Use ReadSlice to look for array,
-	// accumulating full buffers.
-	var frag []byte
-	var full [][]byte
-	err = nil
-
-	for {
-		var e error
-		frag, e = b.ReadSlice(delim)
-		if e == nil { // got final fragment
-			break
-		}
-		if e != ErrBufferFull { // unexpected error
-			err = e
-			break
-		}
-
-		// Make a copy of the buffer.
-		buf := make([]byte, len(frag))
-		copy(buf, frag)
-		full = append(full, buf)
-	}
-
-	// Allocate new buffer to hold the full pieces and the fragment.
-	n := 0
-	for i := range full {
-		n += len(full[i])
-	}
-	n += len(frag)
-
-	// Copy full pieces and fragment in.
-	buf := make([]byte, n)
-	n = 0
-	for i := range full {
-		n += copy(buf[n:], full[i])
-	}
-	copy(buf[n:], frag)
-	return buf, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadString(delim byte) (line string, err error) {
-	bytes, err := b.ReadBytes(delim)
-	line = string(bytes)
-	return line, err
-}
-
-// WriteTo implements io.WriterTo.
-func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
-	n, err = b.writeBuf(w)
-	if err != nil {
-		return
-	}
-
-	if r, ok := b.rd.(io.WriterTo); ok {
-		m, err := r.WriteTo(w)
-		n += m
-		return n, err
-	}
-
-	if w, ok := w.(io.ReaderFrom); ok {
-		m, err := w.ReadFrom(b.rd)
-		n += m
-		return n, err
-	}
-
-	if b.w-b.r < len(b.buf) {
-		b.fill() // buffer not full
-	}
-
-	for b.r < b.w {
-		// b.r < b.w => buffer is not empty
-		m, err := b.writeBuf(w)
-		n += m
-		if err != nil {
-			return n, err
-		}
-		b.fill() // buffer is empty
-	}
-
-	if b.err == io.EOF {
-		b.err = nil
-	}
-
-	return n, b.readErr()
-}
-
-// writeBuf writes the Reader's buffer to the writer.
-func (b *Reader) writeBuf(w io.Writer) (int64, error) {
-	n, err := w.Write(b.buf[b.r:b.w])
-	if n < b.r-b.w {
-		panic(errors.New("bufio: writer did not write all data"))
-	}
-	b.r += n
-	return int64(n), err
-}
-
-// buffered output
-
-// Writer implements buffering for an io.Writer object.
-// If an error occurs writing to a Writer, no more data will be
-// accepted and all subsequent writes will return the error.
-// After all data has been written, the client should call the
-// Flush method to guarantee all data has been forwarded to
-// the underlying io.Writer.
-type Writer struct {
-	err error
-	buf []byte
-	n   int
-	wr  io.Writer
-}
-
-// NewWriterSize returns a new Writer whose buffer has at least the specified
-// size. If the argument io.Writer is already a Writer with large enough
-// size, it returns the underlying Writer.
-func NewWriterSize(w io.Writer, size int) *Writer {
-	// Is it already a Writer?
-	b, ok := w.(*Writer)
-	if ok && len(b.buf) >= size {
-		return b
-	}
-	if size <= 0 {
-		size = defaultBufSize
-	}
-	return &Writer{
-		buf: make([]byte, size),
-		wr:  w,
-	}
-}
-
-// NewWriter returns a new Writer whose buffer has the default size.
-func NewWriter(w io.Writer) *Writer {
-	return NewWriterSize(w, defaultBufSize)
-}
-
-// Reset discards any unflushed buffered data, clears any error, and
-// resets b to write its output to w.
-func (b *Writer) Reset(w io.Writer) {
-	b.err = nil
-	b.n = 0
-	b.wr = w
-}
-
-// Flush writes any buffered data to the underlying io.Writer.
-func (b *Writer) Flush() error {
-	err := b.flush()
-	return err
-}
-
-func (b *Writer) flush() error {
-	if b.err != nil {
-		return b.err
-	}
-	if b.n == 0 {
-		return nil
-	}
-	n, err := b.wr.Write(b.buf[0:b.n])
-	if n < b.n && err == nil {
-		err = io.ErrShortWrite
-	}
-	if err != nil {
-		if n > 0 && n < b.n {
-			copy(b.buf[0:b.n-n], b.buf[n:b.n])
-		}
-		b.n -= n
-		b.err = err
-		return err
-	}
-	b.n = 0
-	return nil
-}
-
-// Available returns how many bytes are unused in the buffer.
-func (b *Writer) Available() int { return len(b.buf) - b.n }
-
-// Buffered returns the number of bytes that have been written into the current buffer.
-func (b *Writer) Buffered() int { return b.n }
-
-// Write writes the contents of p into the buffer.
-// It returns the number of bytes written.
-// If nn < len(p), it also returns an error explaining
-// why the write is short.
-func (b *Writer) Write(p []byte) (nn int, err error) {
-	for len(p) > b.Available() && b.err == nil {
-		var n int
-		if b.Buffered() == 0 {
-			// Large write, empty buffer.
-			// Write directly from p to avoid copy.
-			n, b.err = b.wr.Write(p)
-		} else {
-			n = copy(b.buf[b.n:], p)
-			b.n += n
-			b.flush()
-		}
-		nn += n
-		p = p[n:]
-	}
-	if b.err != nil {
-		return nn, b.err
-	}
-	n := copy(b.buf[b.n:], p)
-	b.n += n
-	nn += n
-	return nn, nil
-}
-
-// WriteByte writes a single byte.
-func (b *Writer) WriteByte(c byte) error {
-	if b.err != nil {
-		return b.err
-	}
-	if b.Available() <= 0 && b.flush() != nil {
-		return b.err
-	}
-	b.buf[b.n] = c
-	b.n++
-	return nil
-}
-
-// WriteRune writes a single Unicode code point, returning
-// the number of bytes written and any error.
-func (b *Writer) WriteRune(r rune) (size int, err error) {
-	if r < utf8.RuneSelf {
-		err = b.WriteByte(byte(r))
-		if err != nil {
-			return 0, err
-		}
-		return 1, nil
-	}
-	if b.err != nil {
-		return 0, b.err
-	}
-	n := b.Available()
-	if n < utf8.UTFMax {
-		if b.flush(); b.err != nil {
-			return 0, b.err
-		}
-		n = b.Available()
-		if n < utf8.UTFMax {
-			// Can only happen if buffer is silly small.
-			return b.WriteString(string(r))
-		}
-	}
-	size = utf8.EncodeRune(b.buf[b.n:], r)
-	b.n += size
-	return size, nil
-}
-
-// WriteString writes a string.
-// It returns the number of bytes written.
-// If the count is less than len(s), it also returns an error explaining
-// why the write is short.
-func (b *Writer) WriteString(s string) (int, error) {
-	nn := 0
-	for len(s) > b.Available() && b.err == nil {
-		n := copy(b.buf[b.n:], s)
-		b.n += n
-		nn += n
-		s = s[n:]
-		b.flush()
-	}
-	if b.err != nil {
-		return nn, b.err
-	}
-	n := copy(b.buf[b.n:], s)
-	b.n += n
-	nn += n
-	return nn, nil
-}
-
-// ReadFrom implements io.ReaderFrom.
-func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
-	if b.Buffered() == 0 {
-		if w, ok := b.wr.(io.ReaderFrom); ok {
-			return w.ReadFrom(r)
-		}
-	}
-	var m int
-	for {
-		if b.Available() == 0 {
-			if err1 := b.flush(); err1 != nil {
-				return n, err1
-			}
-		}
-		nr := 0
-		for nr < maxConsecutiveEmptyReads {
-			m, err = r.Read(b.buf[b.n:])
-			if m != 0 || err != nil {
-				break
-			}
-			nr++
-		}
-		if nr == maxConsecutiveEmptyReads {
-			return n, io.ErrNoProgress
-		}
-		b.n += m
-		n += int64(m)
-		if err != nil {
-			break
-		}
-	}
-	if err == io.EOF {
-		// If we filled the buffer exactly, flush pre-emptively.
-		if b.Available() == 0 {
-			err = b.flush()
-		} else {
-			err = nil
-		}
-	}
-	return n, err
-}
-
-// buffered input and output
-
-// ReadWriter stores pointers to a Reader and a Writer.
-// It implements io.ReadWriter.
-type ReadWriter struct {
-	*Reader
-	*Writer
-}
-
-// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
-func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
-	return &ReadWriter{r, w}
-}
diff --git a/vendor/gopkg.in/ini.v1/.travis.yml b/vendor/gopkg.in/ini.v1/.travis.yml
index c8ea49ccc6..08682ef840 100644
--- a/vendor/gopkg.in/ini.v1/.travis.yml
+++ b/vendor/gopkg.in/ini.v1/.travis.yml
@@ -7,7 +7,9 @@ go:
   - 1.9.x
   - 1.10.x
   - 1.11.x
+  - 1.12.x
 
+install: skip
 script:
   - go get golang.org/x/tools/cmd/cover
   - go get github.com/smartystreets/goconvey
diff --git a/vendor/gopkg.in/ini.v1/README.md b/vendor/gopkg.in/ini.v1/README.md
index ae4dfc3a5a..036c56d63b 100644
--- a/vendor/gopkg.in/ini.v1/README.md
+++ b/vendor/gopkg.in/ini.v1/README.md
@@ -22,19 +22,27 @@ Package ini provides INI file read and write functionality in Go.
 
 The minimum requirement of Go is **1.6**.
 
-To use a tagged revision:
-
 ```sh
 $ go get gopkg.in/ini.v1
 ```
 
-To use with latest changes:
+Please add `-u` flag to update in the future.
 
-```sh
-$ go get github.com/go-ini/ini
+## Go Modules
+
+For historical reason, people use two different import paths for this package: `github.com/go-ini/ini` and `gopkg.in/ini.v1`. If you get error similar to the following one:
+
+```
+go: finding github.com/go-ini/ini v0.0.0-00010101000000-000000000000
+go: github.com/go-ini/ini@v0.0.0-00010101000000-000000000000: unknown revision 000000000000
+go: error loading module requirements
 ```
 
-Please add `-u` flag to update in the future.
+It is because one of your dependencies is using deprecated import path `github.com/go-ini/ini`, you can make a quick fix by adding the following line to your `go.mod` file (`v.1.44.0` was the latest version tagged on `master` branch):
+
+```
+replace github.com/go-ini/ini => gopkg.in/ini.v1 v1.44.0
+```
 
 ## Getting Help
 
diff --git a/vendor/gopkg.in/ini.v1/error.go b/vendor/gopkg.in/ini.v1/error.go
index 80afe74315..d88347c54b 100644
--- a/vendor/gopkg.in/ini.v1/error.go
+++ b/vendor/gopkg.in/ini.v1/error.go
@@ -18,10 +18,12 @@ import (
 	"fmt"
 )
 
+// ErrDelimiterNotFound indicates the error type of no delimiter is found which there should be one.
 type ErrDelimiterNotFound struct {
 	Line string
 }
 
+// IsErrDelimiterNotFound returns true if the given error is an instance of ErrDelimiterNotFound.
 func IsErrDelimiterNotFound(err error) bool {
 	_, ok := err.(ErrDelimiterNotFound)
 	return ok
diff --git a/vendor/gopkg.in/ini.v1/file.go b/vendor/gopkg.in/ini.v1/file.go
index 0ed0eafd02..b38aadd1f8 100644
--- a/vendor/gopkg.in/ini.v1/file.go
+++ b/vendor/gopkg.in/ini.v1/file.go
@@ -68,7 +68,7 @@ func Empty() *File {
 func (f *File) NewSection(name string) (*Section, error) {
 	if len(name) == 0 {
 		return nil, errors.New("error creating new section: empty section name")
-	} else if f.options.Insensitive && name != DEFAULT_SECTION {
+	} else if f.options.Insensitive && name != DefaultSection {
 		name = strings.ToLower(name)
 	}
 
@@ -111,7 +111,7 @@ func (f *File) NewSections(names ...string) (err error) {
 // GetSection returns section by given name.
 func (f *File) GetSection(name string) (*Section, error) {
 	if len(name) == 0 {
-		name = DEFAULT_SECTION
+		name = DefaultSection
 	}
 	if f.options.Insensitive {
 		name = strings.ToLower(name)
@@ -141,7 +141,7 @@ func (f *File) Section(name string) *Section {
 	return sec
 }
 
-// Section returns list of Section.
+// Sections returns a list of Section stored in the current instance.
 func (f *File) Sections() []*Section {
 	if f.BlockMode {
 		f.lock.RLock()
@@ -175,7 +175,7 @@ func (f *File) DeleteSection(name string) {
 	}
 
 	if len(name) == 0 {
-		name = DEFAULT_SECTION
+		name = DefaultSection
 	}
 
 	for i, s := range f.sectionList {
@@ -306,7 +306,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
 		for _, kname := range sec.keyList {
 			key := sec.Key(kname)
 			if len(key.Comment) > 0 {
-				if len(indent) > 0 && sname != DEFAULT_SECTION {
+				if len(indent) > 0 && sname != DefaultSection {
 					buf.WriteString(indent)
 				}
 
@@ -325,7 +325,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
 				}
 			}
 
-			if len(indent) > 0 && sname != DEFAULT_SECTION {
+			if len(indent) > 0 && sname != DefaultSection {
 				buf.WriteString(indent)
 			}
 
diff --git a/vendor/gopkg.in/ini.v1/ini.go b/vendor/gopkg.in/ini.v1/ini.go
index f827a1ef99..36c072cdf3 100644
--- a/vendor/gopkg.in/ini.v1/ini.go
+++ b/vendor/gopkg.in/ini.v1/ini.go
@@ -28,44 +28,46 @@ import (
 )
 
 const (
-	// Name for default section. You can use this constant or the string literal.
+	// DefaultSection is the name of default section. You can use this constant or the string literal.
 	// In most of cases, an empty string is all you need to access the section.
-	DEFAULT_SECTION = "DEFAULT"
+	DefaultSection = "DEFAULT"
+	// Deprecated: Use "DefaultSection" instead.
+	DEFAULT_SECTION = DefaultSection
 
 	// Maximum allowed depth when recursively substituing variable names.
-	_DEPTH_VALUES = 99
-	_VERSION      = "1.42.0"
+	depthValues = 99
+	version     = "1.46.0"
 )
 
 // Version returns current package version literal.
 func Version() string {
-	return _VERSION
+	return version
 }
 
 var (
-	// Delimiter to determine or compose a new line.
-	// This variable will be changed to "\r\n" automatically on Windows
-	// at package init time.
+	// LineBreak is the delimiter to determine or compose a new line.
+	// This variable will be changed to "\r\n" automatically on Windows at package init time.
 	LineBreak = "\n"
 
-	// Place custom spaces when PrettyFormat and PrettyEqual are both disabled
-	DefaultFormatLeft  = ""
+	// DefaultFormatLeft places custom spaces on the left when PrettyFormat and PrettyEqual are both disabled.
+	DefaultFormatLeft = ""
+	// DefaultFormatRight places custom spaces on the right when PrettyFormat and PrettyEqual are both disabled.
 	DefaultFormatRight = ""
 
 	// Variable regexp pattern: %(variable)s
 	varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
 
-	// Indicate whether to align "=" sign with spaces to produce pretty output
+	// PrettyFormat indicates whether to align "=" sign with spaces to produce pretty output
 	// or reduce all possible spaces for compact format.
 	PrettyFormat = true
 
-	// Place spaces around "=" sign even when PrettyFormat is false
+	// PrettyEqual places spaces around "=" sign even when PrettyFormat is false.
 	PrettyEqual = false
 
-	// Explicitly write DEFAULT section header
+	// DefaultHeader explicitly writes default section header.
 	DefaultHeader = false
 
-	// Indicate whether to put a line between sections
+	// PrettySection indicates whether to put a line between sections.
 	PrettySection = true
 )
 
@@ -129,6 +131,7 @@ func parseDataSource(source interface{}) (dataSource, error) {
 	}
 }
 
+// LoadOptions contains all customized options used for load data source(s).
 type LoadOptions struct {
 	// Loose indicates whether the parser should ignore nonexistent files or return error.
 	Loose bool
@@ -174,6 +177,7 @@ type LoadOptions struct {
 	PreserveSurroundedQuote bool
 }
 
+// LoadSources allows caller to apply customized options for loading from data source(s).
 func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
 	sources := make([]dataSource, len(others)+1)
 	sources[0], err = parseDataSource(source)
diff --git a/vendor/gopkg.in/ini.v1/key.go b/vendor/gopkg.in/ini.v1/key.go
index 0fee0dc7e4..38860ff4bd 100644
--- a/vendor/gopkg.in/ini.v1/key.go
+++ b/vendor/gopkg.in/ini.v1/key.go
@@ -77,6 +77,7 @@ func (k *Key) addNestedValue(val string) error {
 	return nil
 }
 
+// AddNestedValue adds a nested value to the key.
 func (k *Key) AddNestedValue(val string) error {
 	if !k.s.f.options.AllowNestedValues {
 		return errors.New("nested value is not allowed")
@@ -126,7 +127,7 @@ func (k *Key) transformValue(val string) string {
 	if !strings.Contains(val, "%") {
 		return val
 	}
-	for i := 0; i < _DEPTH_VALUES; i++ {
+	for i := 0; i < depthValues; i++ {
 		vr := varPattern.FindString(val)
 		if len(vr) == 0 {
 			break
@@ -186,8 +187,8 @@ func (k *Key) Float64() (float64, error) {
 
 // Int returns int type value.
 func (k *Key) Int() (int, error) {
-    v, err := strconv.ParseInt(k.String(), 0, 64)
-    return int(v), err
+	v, err := strconv.ParseInt(k.String(), 0, 64)
+	return int(v), err
 }
 
 // Int64 returns int64 type value.
@@ -491,7 +492,7 @@ func (k *Key) Strings(delim string) []string {
 				buf.WriteRune(runes[idx])
 			}
 		}
-		idx += 1
+		idx++
 		if idx == len(runes) {
 			break
 		}
@@ -669,7 +670,7 @@ func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int,
 	vals := make([]int, 0, len(strs))
 	for _, str := range strs {
 		valInt64, err := strconv.ParseInt(str, 0, 64)
-		val := int(valInt64)        
+		val := int(valInt64)
 		if err != nil && returnOnInvalid {
 			return nil, err
 		}
diff --git a/vendor/gopkg.in/ini.v1/parser.go b/vendor/gopkg.in/ini.v1/parser.go
index f20073d1b4..7c22a25c1a 100644
--- a/vendor/gopkg.in/ini.v1/parser.go
+++ b/vendor/gopkg.in/ini.v1/parser.go
@@ -27,25 +27,29 @@ import (
 
 var pythonMultiline = regexp.MustCompile("^(\\s+)([^\n]+)")
 
-type tokenType int
-
-const (
-	_TOKEN_INVALID tokenType = iota
-	_TOKEN_COMMENT
-	_TOKEN_SECTION
-	_TOKEN_KEY
-)
+type parserOptions struct {
+	IgnoreContinuation          bool
+	IgnoreInlineComment         bool
+	AllowPythonMultilineValues  bool
+	SpaceBeforeInlineComment    bool
+	UnescapeValueDoubleQuotes   bool
+	UnescapeValueCommentSymbols bool
+	PreserveSurroundedQuote     bool
+}
 
 type parser struct {
 	buf     *bufio.Reader
+	options parserOptions
+
 	isEOF   bool
 	count   int
 	comment *bytes.Buffer
 }
 
-func newParser(r io.Reader) *parser {
+func newParser(r io.Reader, opts parserOptions) *parser {
 	return &parser{
 		buf:     bufio.NewReader(r),
+		options: opts,
 		count:   1,
 		comment: &bytes.Buffer{},
 	}
@@ -196,12 +200,13 @@ func hasSurroundedQuote(in string, quote byte) bool {
 		strings.IndexByte(in[1:], quote) == len(in)-2
 }
 
-func (p *parser) readValue(in []byte,
-	parserBufferSize int,
-	ignoreContinuation, ignoreInlineComment, unescapeValueDoubleQuotes, unescapeValueCommentSymbols, allowPythonMultilines, spaceBeforeInlineComment, preserveSurroundedQuote bool) (string, error) {
+func (p *parser) readValue(in []byte, bufferSize int) (string, error) {
 
 	line := strings.TrimLeftFunc(string(in), unicode.IsSpace)
 	if len(line) == 0 {
+		if p.options.AllowPythonMultilineValues && len(in) > 0 && in[len(in)-1] == '\n' {
+			return p.readPythonMultilines(line, bufferSize)
+		}
 		return "", nil
 	}
 
@@ -210,7 +215,7 @@ func (p *parser) readValue(in []byte,
 		valQuote = `"""`
 	} else if line[0] == '`' {
 		valQuote = "`"
-	} else if unescapeValueDoubleQuotes && line[0] == '"' {
+	} else if p.options.UnescapeValueDoubleQuotes && line[0] == '"' {
 		valQuote = `"`
 	}
 
@@ -222,7 +227,7 @@ func (p *parser) readValue(in []byte,
 			return p.readMultilines(line, line[startIdx:], valQuote)
 		}
 
-		if unescapeValueDoubleQuotes && valQuote == `"` {
+		if p.options.UnescapeValueDoubleQuotes && valQuote == `"` {
 			return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil
 		}
 		return line[startIdx : pos+startIdx], nil
@@ -234,14 +239,14 @@ func (p *parser) readValue(in []byte,
 	trimmedLastChar := line[len(line)-1]
 
 	// Check continuation lines when desired
-	if !ignoreContinuation && trimmedLastChar == '\\' {
+	if !p.options.IgnoreContinuation && trimmedLastChar == '\\' {
 		return p.readContinuationLines(line[:len(line)-1])
 	}
 
 	// Check if ignore inline comment
-	if !ignoreInlineComment {
+	if !p.options.IgnoreInlineComment {
 		var i int
-		if spaceBeforeInlineComment {
+		if p.options.SpaceBeforeInlineComment {
 			i = strings.Index(line, " #")
 			if i == -1 {
 				i = strings.Index(line, " ;")
@@ -260,65 +265,75 @@ func (p *parser) readValue(in []byte,
 
 	// Trim single and double quotes
 	if (hasSurroundedQuote(line, '\'') ||
-		hasSurroundedQuote(line, '"')) && !preserveSurroundedQuote {
+		hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote {
 		line = line[1 : len(line)-1]
-	} else if len(valQuote) == 0 && unescapeValueCommentSymbols {
+	} else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols {
 		if strings.Contains(line, `\;`) {
 			line = strings.Replace(line, `\;`, ";", -1)
 		}
 		if strings.Contains(line, `\#`) {
 			line = strings.Replace(line, `\#`, "#", -1)
 		}
-	} else if allowPythonMultilines && lastChar == '\n' {
-		parserBufferPeekResult, _ := p.buf.Peek(parserBufferSize)
-		peekBuffer := bytes.NewBuffer(parserBufferPeekResult)
-
-		val := line
-
-		for {
-			peekData, peekErr := peekBuffer.ReadBytes('\n')
-			if peekErr != nil {
-				if peekErr == io.EOF {
-					return val, nil
-				}
-				return "", peekErr
-			}
-
-			peekMatches := pythonMultiline.FindStringSubmatch(string(peekData))
-			if len(peekMatches) != 3 {
-				return val, nil
-			}
-
-			// NOTE: Return if not a python-ini multi-line value.
-			currentIdentSize := len(peekMatches[1])
-			if currentIdentSize <= 0 {
-				return val, nil
-			}
-
-			// NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer.
-			_, err := p.readUntil('\n')
-			if err != nil {
-				return "", err
-			}
-
-			val += fmt.Sprintf("\n%s", peekMatches[2])
-		}
+	} else if p.options.AllowPythonMultilineValues && lastChar == '\n' {
+		return p.readPythonMultilines(line, bufferSize)
 	}
 
 	return line, nil
 }
 
+func (p *parser) readPythonMultilines(line string, bufferSize int) (string, error) {
+	parserBufferPeekResult, _ := p.buf.Peek(bufferSize)
+	peekBuffer := bytes.NewBuffer(parserBufferPeekResult)
+
+	for {
+		peekData, peekErr := peekBuffer.ReadBytes('\n')
+		if peekErr != nil {
+			if peekErr == io.EOF {
+				return line, nil
+			}
+			return "", peekErr
+		}
+
+		peekMatches := pythonMultiline.FindStringSubmatch(string(peekData))
+		if len(peekMatches) != 3 {
+			return line, nil
+		}
+
+		// NOTE: Return if not a python-ini multi-line value.
+		currentIdentSize := len(peekMatches[1])
+		if currentIdentSize <= 0 {
+			return line, nil
+		}
+
+		// NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer.
+		_, err := p.readUntil('\n')
+		if err != nil {
+			return "", err
+		}
+
+		line += fmt.Sprintf("\n%s", peekMatches[2])
+	}
+}
+
 // parse parses data through an io.Reader.
 func (f *File) parse(reader io.Reader) (err error) {
-	p := newParser(reader)
+	p := newParser(reader, parserOptions{
+		IgnoreContinuation:          f.options.IgnoreContinuation,
+		IgnoreInlineComment:         f.options.IgnoreInlineComment,
+		AllowPythonMultilineValues:  f.options.AllowPythonMultilineValues,
+		SpaceBeforeInlineComment:    f.options.SpaceBeforeInlineComment,
+		UnescapeValueDoubleQuotes:   f.options.UnescapeValueDoubleQuotes,
+		UnescapeValueCommentSymbols: f.options.UnescapeValueCommentSymbols,
+		PreserveSurroundedQuote:     f.options.PreserveSurroundedQuote,
+	})
 	if err = p.BOM(); err != nil {
 		return fmt.Errorf("BOM: %v", err)
 	}
 
 	// Ignore error because default section name is never empty string.
-	name := DEFAULT_SECTION
+	name := DefaultSection
 	if f.options.Insensitive {
-		name = strings.ToLower(DEFAULT_SECTION)
+		name = strings.ToLower(DefaultSection)
 	}
 	section, _ := f.NewSection(name)
 
@@ -426,15 +441,7 @@ func (f *File) parse(reader io.Reader) (err error) {
 			if IsErrDelimiterNotFound(err) {
 				switch {
 				case f.options.AllowBooleanKeys:
-					kname, err := p.readValue(line,
-						parserBufferSize,
-						f.options.IgnoreContinuation,
-						f.options.IgnoreInlineComment,
-						f.options.UnescapeValueDoubleQuotes,
-						f.options.UnescapeValueCommentSymbols,
-						f.options.AllowPythonMultilineValues,
-						f.options.SpaceBeforeInlineComment,
-						f.options.PreserveSurroundedQuote)
+					kname, err := p.readValue(line, parserBufferSize)
 					if err != nil {
 						return err
 					}
@@ -461,15 +468,7 @@ func (f *File) parse(reader io.Reader) (err error) {
 			p.count++
 		}
 
-		value, err := p.readValue(line[offset:],
-			parserBufferSize,
-			f.options.IgnoreContinuation,
-			f.options.IgnoreInlineComment,
-			f.options.UnescapeValueDoubleQuotes,
-			f.options.UnescapeValueCommentSymbols,
-			f.options.AllowPythonMultilineValues,
-			f.options.SpaceBeforeInlineComment,
-			f.options.PreserveSurroundedQuote)
+		value, err := p.readValue(line[offset:], parserBufferSize)
 		if err != nil {
 			return err
 		}
diff --git a/vendor/gopkg.in/ini.v1/section.go b/vendor/gopkg.in/ini.v1/section.go
index bc32c620d6..0bd3e13015 100644
--- a/vendor/gopkg.in/ini.v1/section.go
+++ b/vendor/gopkg.in/ini.v1/section.go
@@ -106,7 +106,6 @@ func (s *Section) NewBooleanKey(name string) (*Key, error) {
 
 // GetKey returns key in section by given name.
 func (s *Section) GetKey(name string) (*Key, error) {
-	// FIXME: change to section level lock?
 	if s.f.BlockMode {
 		s.f.lock.RLock()
 	}
@@ -129,9 +128,8 @@ func (s *Section) GetKey(name string) (*Key, error) {
 					continue
 				}
 				return sec.GetKey(name)
-			} else {
-				break
 			}
+			break
 		}
 		return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
 	}
@@ -144,8 +142,7 @@ func (s *Section) HasKey(name string) bool {
 	return key != nil
 }
 
-// Haskey is a backwards-compatible name for HasKey.
-// TODO: delete me in v2
+// Deprecated: Use "HasKey" instead.
 func (s *Section) Haskey(name string) bool {
 	return s.HasKey(name)
 }
diff --git a/vendor/gopkg.in/ini.v1/struct.go b/vendor/gopkg.in/ini.v1/struct.go
index a9dfed078a..c713f8296c 100644
--- a/vendor/gopkg.in/ini.v1/struct.go
+++ b/vendor/gopkg.in/ini.v1/struct.go
@@ -149,7 +149,7 @@ func wrapStrictError(err error, isStrict bool) error {
 
 // setWithProperType sets proper value to field based on its type,
 // but it does not return error for failing parsing,
-// because we want to use default value that is already assigned to strcut.
+// because we want to use default value that is already assigned to struct.
 func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error {
 	switch t.Kind() {
 	case reflect.String:
@@ -205,6 +205,17 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri
 		field.Set(reflect.ValueOf(timeVal))
 	case reflect.Slice:
 		return setSliceWithProperType(key, field, delim, allowShadow, isStrict)
+	case reflect.Ptr:
+		switch t.Elem().Kind() {
+		case reflect.Bool:
+			boolVal, err := key.Bool()
+			if err != nil {
+				return wrapStrictError(err, isStrict)
+			}
+			field.Set(reflect.ValueOf(&boolVal))
+		default:
+			return fmt.Errorf("unsupported type '%s'", t)
+		}
 	default:
 		return fmt.Errorf("unsupported type '%s'", t)
 	}
@@ -244,14 +255,21 @@ func (s *Section) mapTo(val reflect.Value, isStrict bool) error {
 			continue
 		}
 
-		isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
 		isStruct := tpField.Type.Kind() == reflect.Struct
+		isStructPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct
+		isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
 		if isAnonymous {
 			field.Set(reflect.New(tpField.Type.Elem()))
 		}
 
-		if isAnonymous || isStruct {
+		if isAnonymous || isStruct || isStructPtr {
 			if sec, err := s.f.GetSection(fieldName); err == nil {
+				// Only set the field to non-nil struct value if we have
+				// a section for it. Otherwise, we end up with a non-nil
+				// struct ptr even though there is no data.
+				if isStructPtr && field.IsNil() {
+					field.Set(reflect.New(tpField.Type.Elem()))
+				}
 				if err = sec.mapTo(field, isStrict); err != nil {
 					return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
 				}
@@ -283,7 +301,7 @@ func (s *Section) MapTo(v interface{}) error {
 	return s.mapTo(val, false)
 }
 
-// MapTo maps section to given struct in strict mode,
+// StrictMapTo maps section to given struct in strict mode,
 // which returns all possible error including value parsing error.
 func (s *Section) StrictMapTo(v interface{}) error {
 	typ := reflect.TypeOf(v)
@@ -303,13 +321,13 @@ func (f *File) MapTo(v interface{}) error {
 	return f.Section("").MapTo(v)
 }
 
-// MapTo maps file to given struct in strict mode,
+// StrictMapTo maps file to given struct in strict mode,
 // which returns all possible error including value parsing error.
 func (f *File) StrictMapTo(v interface{}) error {
 	return f.Section("").StrictMapTo(v)
 }
 
-// MapTo maps data sources to given struct with name mapper.
+// MapToWithMapper maps data sources to given struct with name mapper.
 func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error {
 	cfg, err := Load(source, others...)
 	if err != nil {
@@ -342,14 +360,43 @@ func StrictMapTo(v, source interface{}, others ...interface{}) error {
 }
 
 // reflectSliceWithProperType does the opposite thing as setSliceWithProperType.
-func reflectSliceWithProperType(key *Key, field reflect.Value, delim string) error {
+func reflectSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow bool) error {
 	slice := field.Slice(0, field.Len())
 	if field.Len() == 0 {
 		return nil
 	}
+	sliceOf := field.Type().Elem().Kind()
+
+	if allowShadow {
+		var keyWithShadows *Key
+		for i := 0; i < field.Len(); i++ {
+			var val string
+			switch sliceOf {
+			case reflect.String:
+				val = slice.Index(i).String()
+			case reflect.Int, reflect.Int64:
+				val = fmt.Sprint(slice.Index(i).Int())
+			case reflect.Uint, reflect.Uint64:
+				val = fmt.Sprint(slice.Index(i).Uint())
+			case reflect.Float64:
+				val = fmt.Sprint(slice.Index(i).Float())
+			case reflectTime:
+				val = slice.Index(i).Interface().(time.Time).Format(time.RFC3339)
+			default:
+				return fmt.Errorf("unsupported type '[]%s'", sliceOf)
+			}
+
+			if i == 0 {
+				keyWithShadows = newKey(key.s, key.name, val)
+			} else {
+				keyWithShadows.AddShadow(val)
+			}
+		}
+		key = keyWithShadows
+		return nil
+	}
 
 	var buf bytes.Buffer
-	sliceOf := field.Type().Elem().Kind()
 	for i := 0; i < field.Len(); i++ {
 		switch sliceOf {
 		case reflect.String:
@@ -367,12 +414,12 @@ func reflectSliceWithProperType(key *Key, field reflect.Value, delim string) err
 		}
 		buf.WriteString(delim)
 	}
-	key.SetValue(buf.String()[:buf.Len()-1])
+	key.SetValue(buf.String()[:buf.Len()-len(delim)])
 	return nil
 }
 
 // reflectWithProperType does the opposite thing as setWithProperType.
-func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
+func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow bool) error {
 	switch t.Kind() {
 	case reflect.String:
 		key.SetValue(field.String())
@@ -387,7 +434,11 @@ func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim
 	case reflectTime:
 		key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339)))
 	case reflect.Slice:
-		return reflectSliceWithProperType(key, field, delim)
+		return reflectSliceWithProperType(key, field, delim, allowShadow)
+	case reflect.Ptr:
+		if !field.IsNil() {
+			return reflectWithProperType(t.Elem(), key, field.Elem(), delim, allowShadow)
+		}
 	default:
 		return fmt.Errorf("unsupported type '%s'", t)
 	}
@@ -432,12 +483,12 @@ func (s *Section) reflectFrom(val reflect.Value) error {
 			continue
 		}
 
-		opts := strings.SplitN(tag, ",", 2)
-		if len(opts) == 2 && opts[1] == "omitempty" && isEmptyValue(field) {
+		rawName, omitEmpty, allowShadow := parseTagOptions(tag)
+		if omitEmpty && isEmptyValue(field) {
 			continue
 		}
 
-		fieldName := s.parseFieldName(tpField.Name, opts[0])
+		fieldName := s.parseFieldName(tpField.Name, rawName)
 		if len(fieldName) == 0 || !field.CanSet() {
 			continue
 		}
@@ -473,7 +524,7 @@ func (s *Section) reflectFrom(val reflect.Value) error {
 			key.Comment = tpField.Tag.Get("comment")
 		}
 
-		if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
+		if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim")), allowShadow); err != nil {
 			return fmt.Errorf("error reflecting field (%s): %v", fieldName, err)
 		}
 
@@ -500,7 +551,7 @@ func (f *File) ReflectFrom(v interface{}) error {
 	return f.Section("").ReflectFrom(v)
 }
 
-// ReflectFrom reflects data sources from given struct with name mapper.
+// ReflectFromWithMapper reflects data sources from given struct with name mapper.
 func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error {
 	cfg.NameMapper = mapper
 	return cfg.ReflectFrom(v)
diff --git a/vendor/gopkg.in/redis.v2/.travis.yml b/vendor/gopkg.in/redis.v2/.travis.yml
deleted file mode 100644
index c3cf4b8a6e..0000000000
--- a/vendor/gopkg.in/redis.v2/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: go
-
-services:
-- redis-server
-
-go:
-  - 1.1
-  - 1.2
-  - 1.3
-  - tip
-
-install:
-  - go get gopkg.in/bufio.v1
-  - go get gopkg.in/check.v1
-  - mkdir -p $HOME/gopath/src/gopkg.in
-  - ln -s `pwd` $HOME/gopath/src/gopkg.in/redis.v2
-
-before_script:
-  - redis-server testdata/sentinel.conf --sentinel &
diff --git a/vendor/gopkg.in/redis.v2/LICENSE b/vendor/gopkg.in/redis.v2/LICENSE
deleted file mode 100644
index 6855a95feb..0000000000
--- a/vendor/gopkg.in/redis.v2/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 The Redis Go Client Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/gopkg.in/redis.v2/Makefile b/vendor/gopkg.in/redis.v2/Makefile
deleted file mode 100644
index b250d9bfa9..0000000000
--- a/vendor/gopkg.in/redis.v2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-all:
-	go test gopkg.in/redis.v2 -cpu=1,2,4
-	go test gopkg.in/redis.v2 -short -race
diff --git a/vendor/gopkg.in/redis.v2/README.md b/vendor/gopkg.in/redis.v2/README.md
deleted file mode 100644
index ddf875f9a1..0000000000
--- a/vendor/gopkg.in/redis.v2/README.md
+++ /dev/null
@@ -1,46 +0,0 @@
-Redis client for Golang [![Build Status](https://travis-ci.org/go-redis/redis.png?branch=master)](https://travis-ci.org/go-redis/redis)
-=======================
-
-Supports:
-
-- Redis 2.8 commands except QUIT, MONITOR, SLOWLOG and SYNC.
-- Pub/sub.
-- Transactions.
-- Pipelining.
-- Connection pool.
-- TLS connections.
-- Thread safety.
-- Timeouts.
-- Redis Sentinel.
-
-API docs: http://godoc.org/gopkg.in/redis.v2.
-Examples: http://godoc.org/gopkg.in/redis.v2#pkg-examples.
-
-Installation
-------------
-
-Install:
-
-    go get gopkg.in/redis.v2
-
-Look and feel
--------------
-
-Some corner cases:
-
-    SORT list LIMIT 0 2 ASC
-    vals, err := client.Sort("list", redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()
-
-    ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
-    vals, err := client.ZRangeByScoreWithScores("zset", redis.ZRangeByScore{
-        Min: "-inf",
-        Max: "+inf",
-        Offset: 0,
-        Count: 2,
-    }).Result()
-
-    ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
-    vals, err := client.ZInterStore("out", redis.ZStore{Weights: []int64{2, 3}}, "zset1", "zset2").Result()
-
-    EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
-    vals, err := client.Eval("return {KEYS[1],ARGV[1]}", []string{"key"}, []string{"hello"}).Result()
diff --git a/vendor/gopkg.in/redis.v2/command.go b/vendor/gopkg.in/redis.v2/command.go
deleted file mode 100644
index d7c76cf92a..0000000000
--- a/vendor/gopkg.in/redis.v2/command.go
+++ /dev/null
@@ -1,597 +0,0 @@
-package redis
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-	"time"
-
-	"gopkg.in/bufio.v1"
-)
-
-var (
-	_ Cmder = (*Cmd)(nil)
-	_ Cmder = (*SliceCmd)(nil)
-	_ Cmder = (*StatusCmd)(nil)
-	_ Cmder = (*IntCmd)(nil)
-	_ Cmder = (*DurationCmd)(nil)
-	_ Cmder = (*BoolCmd)(nil)
-	_ Cmder = (*StringCmd)(nil)
-	_ Cmder = (*FloatCmd)(nil)
-	_ Cmder = (*StringSliceCmd)(nil)
-	_ Cmder = (*BoolSliceCmd)(nil)
-	_ Cmder = (*StringStringMapCmd)(nil)
-	_ Cmder = (*ZSliceCmd)(nil)
-	_ Cmder = (*ScanCmd)(nil)
-)
-
-type Cmder interface {
-	args() []string
-	parseReply(*bufio.Reader) error
-	setErr(error)
-
-	writeTimeout() *time.Duration
-	readTimeout() *time.Duration
-
-	Err() error
-	String() string
-}
-
-func setCmdsErr(cmds []Cmder, e error) {
-	for _, cmd := range cmds {
-		cmd.setErr(e)
-	}
-}
-
-func cmdString(cmd Cmder, val interface{}) string {
-	s := strings.Join(cmd.args(), " ")
-	if err := cmd.Err(); err != nil {
-		return s + ": " + err.Error()
-	}
-	if val != nil {
-		return s + ": " + fmt.Sprint(val)
-	}
-	return s
-
-}
-
-//------------------------------------------------------------------------------
-
-type baseCmd struct {
-	_args []string
-
-	err error
-
-	_writeTimeout, _readTimeout *time.Duration
-}
-
-func newBaseCmd(args ...string) *baseCmd {
-	return &baseCmd{
-		_args: args,
-	}
-}
-
-func (cmd *baseCmd) Err() error {
-	if cmd.err != nil {
-		return cmd.err
-	}
-	return nil
-}
-
-func (cmd *baseCmd) args() []string {
-	return cmd._args
-}
-
-func (cmd *baseCmd) readTimeout() *time.Duration {
-	return cmd._readTimeout
-}
-
-func (cmd *baseCmd) setReadTimeout(d time.Duration) {
-	cmd._readTimeout = &d
-}
-
-func (cmd *baseCmd) writeTimeout() *time.Duration {
-	return cmd._writeTimeout
-}
-
-func (cmd *baseCmd) setWriteTimeout(d time.Duration) {
-	cmd._writeTimeout = &d
-}
-
-func (cmd *baseCmd) setErr(e error) {
-	cmd.err = e
-}
-
-//------------------------------------------------------------------------------
-
-type Cmd struct {
-	*baseCmd
-
-	val interface{}
-}
-
-func NewCmd(args ...string) *Cmd {
-	return &Cmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *Cmd) Val() interface{} {
-	return cmd.val
-}
-
-func (cmd *Cmd) Result() (interface{}, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *Cmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *Cmd) parseReply(rd *bufio.Reader) error {
-	cmd.val, cmd.err = parseReply(rd, parseSlice)
-	return cmd.err
-}
-
-//------------------------------------------------------------------------------
-
-type SliceCmd struct {
-	*baseCmd
-
-	val []interface{}
-}
-
-func NewSliceCmd(args ...string) *SliceCmd {
-	return &SliceCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *SliceCmd) Val() []interface{} {
-	return cmd.val
-}
-
-func (cmd *SliceCmd) Result() ([]interface{}, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *SliceCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *SliceCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, parseSlice)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.([]interface{})
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type StatusCmd struct {
-	*baseCmd
-
-	val string
-}
-
-func NewStatusCmd(args ...string) *StatusCmd {
-	return &StatusCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *StatusCmd) Val() string {
-	return cmd.val
-}
-
-func (cmd *StatusCmd) Result() (string, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *StatusCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *StatusCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.(string)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type IntCmd struct {
-	*baseCmd
-
-	val int64
-}
-
-func NewIntCmd(args ...string) *IntCmd {
-	return &IntCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *IntCmd) Val() int64 {
-	return cmd.val
-}
-
-func (cmd *IntCmd) Result() (int64, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *IntCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *IntCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.(int64)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type DurationCmd struct {
-	*baseCmd
-
-	val       time.Duration
-	precision time.Duration
-}
-
-func NewDurationCmd(precision time.Duration, args ...string) *DurationCmd {
-	return &DurationCmd{
-		baseCmd:   newBaseCmd(args...),
-		precision: precision,
-	}
-}
-
-func (cmd *DurationCmd) Val() time.Duration {
-	return cmd.val
-}
-
-func (cmd *DurationCmd) Result() (time.Duration, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *DurationCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *DurationCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = time.Duration(v.(int64)) * cmd.precision
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type BoolCmd struct {
-	*baseCmd
-
-	val bool
-}
-
-func NewBoolCmd(args ...string) *BoolCmd {
-	return &BoolCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *BoolCmd) Val() bool {
-	return cmd.val
-}
-
-func (cmd *BoolCmd) Result() (bool, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *BoolCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *BoolCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.(int64) == 1
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type StringCmd struct {
-	*baseCmd
-
-	val string
-}
-
-func NewStringCmd(args ...string) *StringCmd {
-	return &StringCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *StringCmd) Val() string {
-	return cmd.val
-}
-
-func (cmd *StringCmd) Result() (string, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *StringCmd) Int64() (int64, error) {
-	if cmd.err != nil {
-		return 0, cmd.err
-	}
-	return strconv.ParseInt(cmd.val, 10, 64)
-}
-
-func (cmd *StringCmd) Uint64() (uint64, error) {
-	if cmd.err != nil {
-		return 0, cmd.err
-	}
-	return strconv.ParseUint(cmd.val, 10, 64)
-}
-
-func (cmd *StringCmd) Float64() (float64, error) {
-	if cmd.err != nil {
-		return 0, cmd.err
-	}
-	return strconv.ParseFloat(cmd.val, 64)
-}
-
-func (cmd *StringCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *StringCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.(string)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type FloatCmd struct {
-	*baseCmd
-
-	val float64
-}
-
-func NewFloatCmd(args ...string) *FloatCmd {
-	return &FloatCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *FloatCmd) Val() float64 {
-	return cmd.val
-}
-
-func (cmd *FloatCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *FloatCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, nil)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val, cmd.err = strconv.ParseFloat(v.(string), 64)
-	return cmd.err
-}
-
-//------------------------------------------------------------------------------
-
-type StringSliceCmd struct {
-	*baseCmd
-
-	val []string
-}
-
-func NewStringSliceCmd(args ...string) *StringSliceCmd {
-	return &StringSliceCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *StringSliceCmd) Val() []string {
-	return cmd.val
-}
-
-func (cmd *StringSliceCmd) Result() ([]string, error) {
-	return cmd.Val(), cmd.Err()
-}
-
-func (cmd *StringSliceCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *StringSliceCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, parseStringSlice)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.([]string)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type BoolSliceCmd struct {
-	*baseCmd
-
-	val []bool
-}
-
-func NewBoolSliceCmd(args ...string) *BoolSliceCmd {
-	return &BoolSliceCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *BoolSliceCmd) Val() []bool {
-	return cmd.val
-}
-
-func (cmd *BoolSliceCmd) Result() ([]bool, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *BoolSliceCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *BoolSliceCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, parseBoolSlice)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.([]bool)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type StringStringMapCmd struct {
-	*baseCmd
-
-	val map[string]string
-}
-
-func NewStringStringMapCmd(args ...string) *StringStringMapCmd {
-	return &StringStringMapCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *StringStringMapCmd) Val() map[string]string {
-	return cmd.val
-}
-
-func (cmd *StringStringMapCmd) Result() (map[string]string, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *StringStringMapCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *StringStringMapCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, parseStringStringMap)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.(map[string]string)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type ZSliceCmd struct {
-	*baseCmd
-
-	val []Z
-}
-
-func NewZSliceCmd(args ...string) *ZSliceCmd {
-	return &ZSliceCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *ZSliceCmd) Val() []Z {
-	return cmd.val
-}
-
-func (cmd *ZSliceCmd) Result() ([]Z, error) {
-	return cmd.val, cmd.err
-}
-
-func (cmd *ZSliceCmd) String() string {
-	return cmdString(cmd, cmd.val)
-}
-
-func (cmd *ZSliceCmd) parseReply(rd *bufio.Reader) error {
-	v, err := parseReply(rd, parseZSlice)
-	if err != nil {
-		cmd.err = err
-		return err
-	}
-	cmd.val = v.([]Z)
-	return nil
-}
-
-//------------------------------------------------------------------------------
-
-type ScanCmd struct {
-	*baseCmd
-
-	cursor int64
-	keys   []string
-}
-
-func NewScanCmd(args ...string) *ScanCmd {
-	return &ScanCmd{
-		baseCmd: newBaseCmd(args...),
-	}
-}
-
-func (cmd *ScanCmd) Val() (int64, []string) {
-	return cmd.cursor, cmd.keys
-}
-
-func (cmd *ScanCmd) Result() (int64, []string, error) {
-	return cmd.cursor, cmd.keys, cmd.err
-}
-
-func (cmd *ScanCmd) String() string {
-	return cmdString(cmd, cmd.keys)
-}
-
-func (cmd *ScanCmd) parseReply(rd *bufio.Reader) error {
-	vi, err := parseReply(rd, parseSlice)
-	if err != nil {
-		cmd.err = err
-		return cmd.err
-	}
-	v := vi.([]interface{})
-
-	cmd.cursor, cmd.err = strconv.ParseInt(v[0].(string), 10, 64)
-	if cmd.err != nil {
-		return cmd.err
-	}
-
-	keys := v[1].([]interface{})
-	for _, keyi := range keys {
-		cmd.keys = append(cmd.keys, keyi.(string))
-	}
-
-	return nil
-}
diff --git a/vendor/gopkg.in/redis.v2/commands.go b/vendor/gopkg.in/redis.v2/commands.go
deleted file mode 100644
index 6068bab17e..0000000000
--- a/vendor/gopkg.in/redis.v2/commands.go
+++ /dev/null
@@ -1,1246 +0,0 @@
-package redis
-
-import (
-	"io"
-	"strconv"
-	"time"
-)
-
-func formatFloat(f float64) string {
-	return strconv.FormatFloat(f, 'f', -1, 64)
-}
-
-func readTimeout(sec int64) time.Duration {
-	if sec == 0 {
-		return 0
-	}
-	return time.Duration(sec+1) * time.Second
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) Auth(password string) *StatusCmd {
-	cmd := NewStatusCmd("AUTH", password)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Echo(message string) *StringCmd {
-	cmd := NewStringCmd("ECHO", message)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Ping() *StatusCmd {
-	cmd := NewStatusCmd("PING")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Quit() *StatusCmd {
-	panic("not implemented")
-}
-
-func (c *Client) Select(index int64) *StatusCmd {
-	cmd := NewStatusCmd("SELECT", strconv.FormatInt(index, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) Del(keys ...string) *IntCmd {
-	args := append([]string{"DEL"}, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Dump(key string) *StringCmd {
-	cmd := NewStringCmd("DUMP", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Exists(key string) *BoolCmd {
-	cmd := NewBoolCmd("EXISTS", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Expire(key string, dur time.Duration) *BoolCmd {
-	cmd := NewBoolCmd("EXPIRE", key, strconv.FormatInt(int64(dur/time.Second), 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ExpireAt(key string, tm time.Time) *BoolCmd {
-	cmd := NewBoolCmd("EXPIREAT", key, strconv.FormatInt(tm.Unix(), 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Keys(pattern string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("KEYS", pattern)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Migrate(host, port, key string, db, timeout int64) *StatusCmd {
-	cmd := NewStatusCmd(
-		"MIGRATE",
-		host,
-		port,
-		key,
-		strconv.FormatInt(db, 10),
-		strconv.FormatInt(timeout, 10),
-	)
-	cmd.setReadTimeout(readTimeout(timeout))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Move(key string, db int64) *BoolCmd {
-	cmd := NewBoolCmd("MOVE", key, strconv.FormatInt(db, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ObjectRefCount(keys ...string) *IntCmd {
-	args := append([]string{"OBJECT", "REFCOUNT"}, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ObjectEncoding(keys ...string) *StringCmd {
-	args := append([]string{"OBJECT", "ENCODING"}, keys...)
-	cmd := NewStringCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ObjectIdleTime(keys ...string) *DurationCmd {
-	args := append([]string{"OBJECT", "IDLETIME"}, keys...)
-	cmd := NewDurationCmd(time.Second, args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Persist(key string) *BoolCmd {
-	cmd := NewBoolCmd("PERSIST", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PExpire(key string, dur time.Duration) *BoolCmd {
-	cmd := NewBoolCmd("PEXPIRE", key, strconv.FormatInt(int64(dur/time.Millisecond), 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PExpireAt(key string, tm time.Time) *BoolCmd {
-	cmd := NewBoolCmd(
-		"PEXPIREAT",
-		key,
-		strconv.FormatInt(tm.UnixNano()/int64(time.Millisecond), 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PTTL(key string) *DurationCmd {
-	cmd := NewDurationCmd(time.Millisecond, "PTTL", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RandomKey() *StringCmd {
-	cmd := NewStringCmd("RANDOMKEY")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Rename(key, newkey string) *StatusCmd {
-	cmd := NewStatusCmd("RENAME", key, newkey)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RenameNX(key, newkey string) *BoolCmd {
-	cmd := NewBoolCmd("RENAMENX", key, newkey)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Restore(key string, ttl int64, value string) *StatusCmd {
-	cmd := NewStatusCmd(
-		"RESTORE",
-		key,
-		strconv.FormatInt(ttl, 10),
-		value,
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-type Sort struct {
-	By            string
-	Offset, Count float64
-	Get           []string
-	Order         string
-	IsAlpha       bool
-	Store         string
-}
-
-func (c *Client) Sort(key string, sort Sort) *StringSliceCmd {
-	args := []string{"SORT", key}
-	if sort.By != "" {
-		args = append(args, "BY", sort.By)
-	}
-	if sort.Offset != 0 || sort.Count != 0 {
-		args = append(args, "LIMIT", formatFloat(sort.Offset), formatFloat(sort.Count))
-	}
-	for _, get := range sort.Get {
-		args = append(args, "GET", get)
-	}
-	if sort.Order != "" {
-		args = append(args, sort.Order)
-	}
-	if sort.IsAlpha {
-		args = append(args, "ALPHA")
-	}
-	if sort.Store != "" {
-		args = append(args, "STORE", sort.Store)
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) TTL(key string) *DurationCmd {
-	cmd := NewDurationCmd(time.Second, "TTL", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Type(key string) *StatusCmd {
-	cmd := NewStatusCmd("TYPE", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Scan(cursor int64, match string, count int64) *ScanCmd {
-	args := []string{"SCAN", strconv.FormatInt(cursor, 10)}
-	if match != "" {
-		args = append(args, "MATCH", match)
-	}
-	if count > 0 {
-		args = append(args, "COUNT", strconv.FormatInt(count, 10))
-	}
-	cmd := NewScanCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SScan(key string, cursor int64, match string, count int64) *ScanCmd {
-	args := []string{"SSCAN", key, strconv.FormatInt(cursor, 10)}
-	if match != "" {
-		args = append(args, "MATCH", match)
-	}
-	if count > 0 {
-		args = append(args, "COUNT", strconv.FormatInt(count, 10))
-	}
-	cmd := NewScanCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HScan(key string, cursor int64, match string, count int64) *ScanCmd {
-	args := []string{"HSCAN", key, strconv.FormatInt(cursor, 10)}
-	if match != "" {
-		args = append(args, "MATCH", match)
-	}
-	if count > 0 {
-		args = append(args, "COUNT", strconv.FormatInt(count, 10))
-	}
-	cmd := NewScanCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZScan(key string, cursor int64, match string, count int64) *ScanCmd {
-	args := []string{"ZSCAN", key, strconv.FormatInt(cursor, 10)}
-	if match != "" {
-		args = append(args, "MATCH", match)
-	}
-	if count > 0 {
-		args = append(args, "COUNT", strconv.FormatInt(count, 10))
-	}
-	cmd := NewScanCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) Append(key, value string) *IntCmd {
-	cmd := NewIntCmd("APPEND", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-type BitCount struct {
-	Start, End int64
-}
-
-func (c *Client) BitCount(key string, bitCount *BitCount) *IntCmd {
-	args := []string{"BITCOUNT", key}
-	if bitCount != nil {
-		args = append(
-			args,
-			strconv.FormatInt(bitCount.Start, 10),
-			strconv.FormatInt(bitCount.End, 10),
-		)
-	}
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) bitOp(op, destKey string, keys ...string) *IntCmd {
-	args := []string{"BITOP", op, destKey}
-	args = append(args, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) BitOpAnd(destKey string, keys ...string) *IntCmd {
-	return c.bitOp("AND", destKey, keys...)
-}
-
-func (c *Client) BitOpOr(destKey string, keys ...string) *IntCmd {
-	return c.bitOp("OR", destKey, keys...)
-}
-
-func (c *Client) BitOpXor(destKey string, keys ...string) *IntCmd {
-	return c.bitOp("XOR", destKey, keys...)
-}
-
-func (c *Client) BitOpNot(destKey string, key string) *IntCmd {
-	return c.bitOp("NOT", destKey, key)
-}
-
-func (c *Client) Decr(key string) *IntCmd {
-	cmd := NewIntCmd("DECR", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) DecrBy(key string, decrement int64) *IntCmd {
-	cmd := NewIntCmd("DECRBY", key, strconv.FormatInt(decrement, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Get(key string) *StringCmd {
-	cmd := NewStringCmd("GET", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) GetBit(key string, offset int64) *IntCmd {
-	cmd := NewIntCmd("GETBIT", key, strconv.FormatInt(offset, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) GetRange(key string, start, end int64) *StringCmd {
-	cmd := NewStringCmd(
-		"GETRANGE",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(end, 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) GetSet(key, value string) *StringCmd {
-	cmd := NewStringCmd("GETSET", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Incr(key string) *IntCmd {
-	cmd := NewIntCmd("INCR", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) IncrBy(key string, value int64) *IntCmd {
-	cmd := NewIntCmd("INCRBY", key, strconv.FormatInt(value, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) IncrByFloat(key string, value float64) *FloatCmd {
-	cmd := NewFloatCmd("INCRBYFLOAT", key, formatFloat(value))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) MGet(keys ...string) *SliceCmd {
-	args := append([]string{"MGET"}, keys...)
-	cmd := NewSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) MSet(pairs ...string) *StatusCmd {
-	args := append([]string{"MSET"}, pairs...)
-	cmd := NewStatusCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) MSetNX(pairs ...string) *BoolCmd {
-	args := append([]string{"MSETNX"}, pairs...)
-	cmd := NewBoolCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PSetEx(key string, dur time.Duration, value string) *StatusCmd {
-	cmd := NewStatusCmd(
-		"PSETEX",
-		key,
-		strconv.FormatInt(int64(dur/time.Millisecond), 10),
-		value,
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Set(key, value string) *StatusCmd {
-	cmd := NewStatusCmd("SET", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SetBit(key string, offset int64, value int) *IntCmd {
-	cmd := NewIntCmd(
-		"SETBIT",
-		key,
-		strconv.FormatInt(offset, 10),
-		strconv.FormatInt(int64(value), 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SetEx(key string, dur time.Duration, value string) *StatusCmd {
-	cmd := NewStatusCmd("SETEX", key, strconv.FormatInt(int64(dur/time.Second), 10), value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SetNX(key, value string) *BoolCmd {
-	cmd := NewBoolCmd("SETNX", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SetRange(key string, offset int64, value string) *IntCmd {
-	cmd := NewIntCmd("SETRANGE", key, strconv.FormatInt(offset, 10), value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) StrLen(key string) *IntCmd {
-	cmd := NewIntCmd("STRLEN", key)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) HDel(key string, fields ...string) *IntCmd {
-	args := append([]string{"HDEL", key}, fields...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HExists(key, field string) *BoolCmd {
-	cmd := NewBoolCmd("HEXISTS", key, field)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HGet(key, field string) *StringCmd {
-	cmd := NewStringCmd("HGET", key, field)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HGetAll(key string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("HGETALL", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HGetAllMap(key string) *StringStringMapCmd {
-	cmd := NewStringStringMapCmd("HGETALL", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HIncrBy(key, field string, incr int64) *IntCmd {
-	cmd := NewIntCmd("HINCRBY", key, field, strconv.FormatInt(incr, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HIncrByFloat(key, field string, incr float64) *FloatCmd {
-	cmd := NewFloatCmd("HINCRBYFLOAT", key, field, formatFloat(incr))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HKeys(key string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("HKEYS", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HLen(key string) *IntCmd {
-	cmd := NewIntCmd("HLEN", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HMGet(key string, fields ...string) *SliceCmd {
-	args := append([]string{"HMGET", key}, fields...)
-	cmd := NewSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HMSet(key, field, value string, pairs ...string) *StatusCmd {
-	args := append([]string{"HMSET", key, field, value}, pairs...)
-	cmd := NewStatusCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HSet(key, field, value string) *BoolCmd {
-	cmd := NewBoolCmd("HSET", key, field, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HSetNX(key, field, value string) *BoolCmd {
-	cmd := NewBoolCmd("HSETNX", key, field, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) HVals(key string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("HVALS", key)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) BLPop(timeout int64, keys ...string) *StringSliceCmd {
-	args := append([]string{"BLPOP"}, keys...)
-	args = append(args, strconv.FormatInt(timeout, 10))
-	cmd := NewStringSliceCmd(args...)
-	cmd.setReadTimeout(readTimeout(timeout))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) BRPop(timeout int64, keys ...string) *StringSliceCmd {
-	args := append([]string{"BRPOP"}, keys...)
-	args = append(args, strconv.FormatInt(timeout, 10))
-	cmd := NewStringSliceCmd(args...)
-	cmd.setReadTimeout(readTimeout(timeout))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) BRPopLPush(source, destination string, timeout int64) *StringCmd {
-	cmd := NewStringCmd(
-		"BRPOPLPUSH",
-		source,
-		destination,
-		strconv.FormatInt(timeout, 10),
-	)
-	cmd.setReadTimeout(readTimeout(timeout))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LIndex(key string, index int64) *StringCmd {
-	cmd := NewStringCmd("LINDEX", key, strconv.FormatInt(index, 10))
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LInsert(key, op, pivot, value string) *IntCmd {
-	cmd := NewIntCmd("LINSERT", key, op, pivot, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LLen(key string) *IntCmd {
-	cmd := NewIntCmd("LLEN", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LPop(key string) *StringCmd {
-	cmd := NewStringCmd("LPOP", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LPush(key string, values ...string) *IntCmd {
-	args := append([]string{"LPUSH", key}, values...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LPushX(key, value string) *IntCmd {
-	cmd := NewIntCmd("LPUSHX", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LRange(key string, start, stop int64) *StringSliceCmd {
-	cmd := NewStringSliceCmd(
-		"LRANGE",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(stop, 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LRem(key string, count int64, value string) *IntCmd {
-	cmd := NewIntCmd("LREM", key, strconv.FormatInt(count, 10), value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LSet(key string, index int64, value string) *StatusCmd {
-	cmd := NewStatusCmd("LSET", key, strconv.FormatInt(index, 10), value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LTrim(key string, start, stop int64) *StatusCmd {
-	cmd := NewStatusCmd(
-		"LTRIM",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(stop, 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RPop(key string) *StringCmd {
-	cmd := NewStringCmd("RPOP", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RPopLPush(source, destination string) *StringCmd {
-	cmd := NewStringCmd("RPOPLPUSH", source, destination)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RPush(key string, values ...string) *IntCmd {
-	args := append([]string{"RPUSH", key}, values...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) RPushX(key string, value string) *IntCmd {
-	cmd := NewIntCmd("RPUSHX", key, value)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) SAdd(key string, members ...string) *IntCmd {
-	args := append([]string{"SADD", key}, members...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SCard(key string) *IntCmd {
-	cmd := NewIntCmd("SCARD", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SDiff(keys ...string) *StringSliceCmd {
-	args := append([]string{"SDIFF"}, keys...)
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SDiffStore(destination string, keys ...string) *IntCmd {
-	args := append([]string{"SDIFFSTORE", destination}, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SInter(keys ...string) *StringSliceCmd {
-	args := append([]string{"SINTER"}, keys...)
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SInterStore(destination string, keys ...string) *IntCmd {
-	args := append([]string{"SINTERSTORE", destination}, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SIsMember(key, member string) *BoolCmd {
-	cmd := NewBoolCmd("SISMEMBER", key, member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SMembers(key string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("SMEMBERS", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SMove(source, destination, member string) *BoolCmd {
-	cmd := NewBoolCmd("SMOVE", source, destination, member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SPop(key string) *StringCmd {
-	cmd := NewStringCmd("SPOP", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SRandMember(key string) *StringCmd {
-	cmd := NewStringCmd("SRANDMEMBER", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SRem(key string, members ...string) *IntCmd {
-	args := append([]string{"SREM", key}, members...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SUnion(keys ...string) *StringSliceCmd {
-	args := append([]string{"SUNION"}, keys...)
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SUnionStore(destination string, keys ...string) *IntCmd {
-	args := append([]string{"SUNIONSTORE", destination}, keys...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-type Z struct {
-	Score  float64
-	Member string
-}
-
-type ZStore struct {
-	Weights   []int64
-	Aggregate string
-}
-
-func (c *Client) ZAdd(key string, members ...Z) *IntCmd {
-	args := []string{"ZADD", key}
-	for _, m := range members {
-		args = append(args, formatFloat(m.Score), m.Member)
-	}
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZCard(key string) *IntCmd {
-	cmd := NewIntCmd("ZCARD", key)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZCount(key, min, max string) *IntCmd {
-	cmd := NewIntCmd("ZCOUNT", key, min, max)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZIncrBy(key string, increment float64, member string) *FloatCmd {
-	cmd := NewFloatCmd("ZINCRBY", key, formatFloat(increment), member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZInterStore(
-	destination string,
-	store ZStore,
-	keys ...string,
-) *IntCmd {
-	args := []string{"ZINTERSTORE", destination, strconv.FormatInt(int64(len(keys)), 10)}
-	args = append(args, keys...)
-	if len(store.Weights) > 0 {
-		args = append(args, "WEIGHTS")
-		for _, weight := range store.Weights {
-			args = append(args, strconv.FormatInt(weight, 10))
-		}
-	}
-	if store.Aggregate != "" {
-		args = append(args, "AGGREGATE", store.Aggregate)
-	}
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) zRange(key string, start, stop int64, withScores bool) *StringSliceCmd {
-	args := []string{
-		"ZRANGE",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(stop, 10),
-	}
-	if withScores {
-		args = append(args, "WITHSCORES")
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRange(key string, start, stop int64) *StringSliceCmd {
-	return c.zRange(key, start, stop, false)
-}
-
-func (c *Client) ZRangeWithScores(key string, start, stop int64) *ZSliceCmd {
-	args := []string{
-		"ZRANGE",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(stop, 10),
-		"WITHSCORES",
-	}
-	cmd := NewZSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-type ZRangeByScore struct {
-	Min, Max string
-
-	Offset, Count int64
-}
-
-func (c *Client) zRangeByScore(key string, opt ZRangeByScore, withScores bool) *StringSliceCmd {
-	args := []string{"ZRANGEBYSCORE", key, opt.Min, opt.Max}
-	if withScores {
-		args = append(args, "WITHSCORES")
-	}
-	if opt.Offset != 0 || opt.Count != 0 {
-		args = append(
-			args,
-			"LIMIT",
-			strconv.FormatInt(opt.Offset, 10),
-			strconv.FormatInt(opt.Count, 10),
-		)
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRangeByScore(key string, opt ZRangeByScore) *StringSliceCmd {
-	return c.zRangeByScore(key, opt, false)
-}
-
-func (c *Client) ZRangeByScoreWithScores(key string, opt ZRangeByScore) *ZSliceCmd {
-	args := []string{"ZRANGEBYSCORE", key, opt.Min, opt.Max, "WITHSCORES"}
-	if opt.Offset != 0 || opt.Count != 0 {
-		args = append(
-			args,
-			"LIMIT",
-			strconv.FormatInt(opt.Offset, 10),
-			strconv.FormatInt(opt.Count, 10),
-		)
-	}
-	cmd := NewZSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRank(key, member string) *IntCmd {
-	cmd := NewIntCmd("ZRANK", key, member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRem(key string, members ...string) *IntCmd {
-	args := append([]string{"ZREM", key}, members...)
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRemRangeByRank(key string, start, stop int64) *IntCmd {
-	cmd := NewIntCmd(
-		"ZREMRANGEBYRANK",
-		key,
-		strconv.FormatInt(start, 10),
-		strconv.FormatInt(stop, 10),
-	)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRemRangeByScore(key, min, max string) *IntCmd {
-	cmd := NewIntCmd("ZREMRANGEBYSCORE", key, min, max)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) zRevRange(key, start, stop string, withScores bool) *StringSliceCmd {
-	args := []string{"ZREVRANGE", key, start, stop}
-	if withScores {
-		args = append(args, "WITHSCORES")
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRevRange(key, start, stop string) *StringSliceCmd {
-	return c.zRevRange(key, start, stop, false)
-}
-
-func (c *Client) ZRevRangeWithScores(key, start, stop string) *ZSliceCmd {
-	args := []string{"ZREVRANGE", key, start, stop, "WITHSCORES"}
-	cmd := NewZSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) zRevRangeByScore(key string, opt ZRangeByScore, withScores bool) *StringSliceCmd {
-	args := []string{"ZREVRANGEBYSCORE", key, opt.Max, opt.Min}
-	if withScores {
-		args = append(args, "WITHSCORES")
-	}
-	if opt.Offset != 0 || opt.Count != 0 {
-		args = append(
-			args,
-			"LIMIT",
-			strconv.FormatInt(opt.Offset, 10),
-			strconv.FormatInt(opt.Count, 10),
-		)
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRevRangeByScore(key string, opt ZRangeByScore) *StringSliceCmd {
-	return c.zRevRangeByScore(key, opt, false)
-}
-
-func (c *Client) ZRevRangeByScoreWithScores(key string, opt ZRangeByScore) *ZSliceCmd {
-	args := []string{"ZREVRANGEBYSCORE", key, opt.Max, opt.Min, "WITHSCORES"}
-	if opt.Offset != 0 || opt.Count != 0 {
-		args = append(
-			args,
-			"LIMIT",
-			strconv.FormatInt(opt.Offset, 10),
-			strconv.FormatInt(opt.Count, 10),
-		)
-	}
-	cmd := NewZSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZRevRank(key, member string) *IntCmd {
-	cmd := NewIntCmd("ZREVRANK", key, member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZScore(key, member string) *FloatCmd {
-	cmd := NewFloatCmd("ZSCORE", key, member)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ZUnionStore(
-	destination string,
-	store ZStore,
-	keys ...string,
-) *IntCmd {
-	args := []string{"ZUNIONSTORE", destination, strconv.FormatInt(int64(len(keys)), 10)}
-	args = append(args, keys...)
-	if len(store.Weights) > 0 {
-		args = append(args, "WEIGHTS")
-		for _, weight := range store.Weights {
-			args = append(args, strconv.FormatInt(weight, 10))
-		}
-	}
-	if store.Aggregate != "" {
-		args = append(args, "AGGREGATE", store.Aggregate)
-	}
-	cmd := NewIntCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) BgRewriteAOF() *StatusCmd {
-	cmd := NewStatusCmd("BGREWRITEAOF")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) BgSave() *StatusCmd {
-	cmd := NewStatusCmd("BGSAVE")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ClientKill(ipPort string) *StatusCmd {
-	cmd := NewStatusCmd("CLIENT", "KILL", ipPort)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ClientList() *StringCmd {
-	cmd := NewStringCmd("CLIENT", "LIST")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ConfigGet(parameter string) *SliceCmd {
-	cmd := NewSliceCmd("CONFIG", "GET", parameter)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ConfigResetStat() *StatusCmd {
-	cmd := NewStatusCmd("CONFIG", "RESETSTAT")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ConfigSet(parameter, value string) *StatusCmd {
-	cmd := NewStatusCmd("CONFIG", "SET", parameter, value)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) DbSize() *IntCmd {
-	cmd := NewIntCmd("DBSIZE")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) FlushAll() *StatusCmd {
-	cmd := NewStatusCmd("FLUSHALL")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) FlushDb() *StatusCmd {
-	cmd := NewStatusCmd("FLUSHDB")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Info() *StringCmd {
-	cmd := NewStringCmd("INFO")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) LastSave() *IntCmd {
-	cmd := NewIntCmd("LASTSAVE")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) Save() *StatusCmd {
-	cmd := NewStatusCmd("SAVE")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) shutdown(modifier string) *StatusCmd {
-	var args []string
-	if modifier == "" {
-		args = []string{"SHUTDOWN"}
-	} else {
-		args = []string{"SHUTDOWN", modifier}
-	}
-	cmd := NewStatusCmd(args...)
-	c.Process(cmd)
-	if err := cmd.Err(); err != nil {
-		if err == io.EOF {
-			// Server quit as expected.
-			cmd.err = nil
-		}
-	} else {
-		// Server did not quit. String reply contains the reason.
-		cmd.err = errorf(cmd.val)
-		cmd.val = ""
-	}
-	return cmd
-}
-
-func (c *Client) Shutdown() *StatusCmd {
-	return c.shutdown("")
-}
-
-func (c *Client) ShutdownSave() *StatusCmd {
-	return c.shutdown("SAVE")
-}
-
-func (c *Client) ShutdownNoSave() *StatusCmd {
-	return c.shutdown("NOSAVE")
-}
-
-func (c *Client) SlaveOf(host, port string) *StatusCmd {
-	cmd := NewStatusCmd("SLAVEOF", host, port)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) SlowLog() {
-	panic("not implemented")
-}
-
-func (c *Client) Sync() {
-	panic("not implemented")
-}
-
-func (c *Client) Time() *StringSliceCmd {
-	cmd := NewStringSliceCmd("TIME")
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) Eval(script string, keys []string, args []string) *Cmd {
-	cmdArgs := []string{"EVAL", script, strconv.FormatInt(int64(len(keys)), 10)}
-	cmdArgs = append(cmdArgs, keys...)
-	cmdArgs = append(cmdArgs, args...)
-	cmd := NewCmd(cmdArgs...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) EvalSha(sha1 string, keys []string, args []string) *Cmd {
-	cmdArgs := []string{"EVALSHA", sha1, strconv.FormatInt(int64(len(keys)), 10)}
-	cmdArgs = append(cmdArgs, keys...)
-	cmdArgs = append(cmdArgs, args...)
-	cmd := NewCmd(cmdArgs...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ScriptExists(scripts ...string) *BoolSliceCmd {
-	args := append([]string{"SCRIPT", "EXISTS"}, scripts...)
-	cmd := NewBoolSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ScriptFlush() *StatusCmd {
-	cmd := NewStatusCmd("SCRIPT", "FLUSH")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ScriptKill() *StatusCmd {
-	cmd := NewStatusCmd("SCRIPT", "KILL")
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) ScriptLoad(script string) *StringCmd {
-	cmd := NewStringCmd("SCRIPT", "LOAD", script)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) DebugObject(key string) *StringCmd {
-	cmd := NewStringCmd("DEBUG", "OBJECT", key)
-	c.Process(cmd)
-	return cmd
-}
-
-//------------------------------------------------------------------------------
-
-func (c *Client) PubSubChannels(pattern string) *StringSliceCmd {
-	args := []string{"PUBSUB", "CHANNELS"}
-	if pattern != "*" {
-		args = append(args, pattern)
-	}
-	cmd := NewStringSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PubSubNumSub(channels ...string) *SliceCmd {
-	args := []string{"PUBSUB", "NUMSUB"}
-	args = append(args, channels...)
-	cmd := NewSliceCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Client) PubSubNumPat() *IntCmd {
-	cmd := NewIntCmd("PUBSUB", "NUMPAT")
-	c.Process(cmd)
-	return cmd
-}
diff --git a/vendor/gopkg.in/redis.v2/doc.go b/vendor/gopkg.in/redis.v2/doc.go
deleted file mode 100644
index 55262533a6..0000000000
--- a/vendor/gopkg.in/redis.v2/doc.go
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
-Package redis implements a Redis client.
-*/
-package redis
diff --git a/vendor/gopkg.in/redis.v2/error.go b/vendor/gopkg.in/redis.v2/error.go
deleted file mode 100644
index 667fffdc68..0000000000
--- a/vendor/gopkg.in/redis.v2/error.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package redis
-
-import (
-	"fmt"
-)
-
-// Redis nil reply.
-var Nil = errorf("redis: nil")
-
-// Redis transaction failed.
-var TxFailedErr = errorf("redis: transaction failed")
-
-type redisError struct {
-	s string
-}
-
-func errorf(s string, args ...interface{}) redisError {
-	return redisError{s: fmt.Sprintf(s, args...)}
-}
-
-func (err redisError) Error() string {
-	return err.s
-}
diff --git a/vendor/gopkg.in/redis.v2/multi.go b/vendor/gopkg.in/redis.v2/multi.go
deleted file mode 100644
index bff38dfaaa..0000000000
--- a/vendor/gopkg.in/redis.v2/multi.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package redis
-
-import (
-	"errors"
-	"fmt"
-)
-
-var errDiscard = errors.New("redis: Discard can be used only inside Exec")
-
-// Not thread-safe.
-type Multi struct {
-	*Client
-}
-
-func (c *Client) Multi() *Multi {
-	return &Multi{
-		Client: &Client{
-			baseClient: &baseClient{
-				opt:      c.opt,
-				connPool: newSingleConnPool(c.connPool, true),
-			},
-		},
-	}
-}
-
-func (c *Multi) Close() error {
-	if err := c.Unwatch().Err(); err != nil {
-		return err
-	}
-	return c.Client.Close()
-}
-
-func (c *Multi) Watch(keys ...string) *StatusCmd {
-	args := append([]string{"WATCH"}, keys...)
-	cmd := NewStatusCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Multi) Unwatch(keys ...string) *StatusCmd {
-	args := append([]string{"UNWATCH"}, keys...)
-	cmd := NewStatusCmd(args...)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *Multi) Discard() error {
-	if c.cmds == nil {
-		return errDiscard
-	}
-	c.cmds = c.cmds[:1]
-	return nil
-}
-
-// Exec always returns list of commands. If transaction fails
-// TxFailedErr is returned. Otherwise Exec returns error of the first
-// failed command or nil.
-func (c *Multi) Exec(f func() error) ([]Cmder, error) {
-	c.cmds = []Cmder{NewStatusCmd("MULTI")}
-	if err := f(); err != nil {
-		return nil, err
-	}
-	c.cmds = append(c.cmds, NewSliceCmd("EXEC"))
-
-	cmds := c.cmds
-	c.cmds = nil
-
-	if len(cmds) == 2 {
-		return []Cmder{}, nil
-	}
-
-	cn, err := c.conn()
-	if err != nil {
-		setCmdsErr(cmds[1:len(cmds)-1], err)
-		return cmds[1 : len(cmds)-1], err
-	}
-
-	err = c.execCmds(cn, cmds)
-	if err != nil {
-		c.freeConn(cn, err)
-		return cmds[1 : len(cmds)-1], err
-	}
-
-	c.putConn(cn)
-	return cmds[1 : len(cmds)-1], nil
-}
-
-func (c *Multi) execCmds(cn *conn, cmds []Cmder) error {
-	err := c.writeCmd(cn, cmds...)
-	if err != nil {
-		setCmdsErr(cmds[1:len(cmds)-1], err)
-		return err
-	}
-
-	statusCmd := NewStatusCmd()
-
-	// Omit last command (EXEC).
-	cmdsLen := len(cmds) - 1
-
-	// Parse queued replies.
-	for i := 0; i < cmdsLen; i++ {
-		if err := statusCmd.parseReply(cn.rd); err != nil {
-			setCmdsErr(cmds[1:len(cmds)-1], err)
-			return err
-		}
-	}
-
-	// Parse number of replies.
-	line, err := readLine(cn.rd)
-	if err != nil {
-		setCmdsErr(cmds[1:len(cmds)-1], err)
-		return err
-	}
-	if line[0] != '*' {
-		err := fmt.Errorf("redis: expected '*', but got line %q", line)
-		setCmdsErr(cmds[1:len(cmds)-1], err)
-		return err
-	}
-	if len(line) == 3 && line[1] == '-' && line[2] == '1' {
-		setCmdsErr(cmds[1:len(cmds)-1], TxFailedErr)
-		return TxFailedErr
-	}
-
-	var firstCmdErr error
-
-	// Parse replies.
-	// Loop starts from 1 to omit MULTI cmd.
-	for i := 1; i < cmdsLen; i++ {
-		cmd := cmds[i]
-		if err := cmd.parseReply(cn.rd); err != nil {
-			if firstCmdErr == nil {
-				firstCmdErr = err
-			}
-		}
-	}
-
-	return firstCmdErr
-}
diff --git a/vendor/gopkg.in/redis.v2/parser.go b/vendor/gopkg.in/redis.v2/parser.go
deleted file mode 100644
index b4c380c764..0000000000
--- a/vendor/gopkg.in/redis.v2/parser.go
+++ /dev/null
@@ -1,262 +0,0 @@
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"strconv"
-
-	"gopkg.in/bufio.v1"
-)
-
-type multiBulkParser func(rd *bufio.Reader, n int64) (interface{}, error)
-
-var (
-	errReaderTooSmall = errors.New("redis: reader is too small")
-)
-
-//------------------------------------------------------------------------------
-
-func appendArgs(buf []byte, args []string) []byte {
-	buf = append(buf, '*')
-	buf = strconv.AppendUint(buf, uint64(len(args)), 10)
-	buf = append(buf, '\r', '\n')
-	for _, arg := range args {
-		buf = append(buf, '$')
-		buf = strconv.AppendUint(buf, uint64(len(arg)), 10)
-		buf = append(buf, '\r', '\n')
-		buf = append(buf, arg...)
-		buf = append(buf, '\r', '\n')
-	}
-	return buf
-}
-
-//------------------------------------------------------------------------------
-
-func readLine(rd *bufio.Reader) ([]byte, error) {
-	line, isPrefix, err := rd.ReadLine()
-	if err != nil {
-		return line, err
-	}
-	if isPrefix {
-		return line, errReaderTooSmall
-	}
-	return line, nil
-}
-
-func readN(rd *bufio.Reader, n int) ([]byte, error) {
-	b, err := rd.ReadN(n)
-	if err == bufio.ErrBufferFull {
-		tmp := make([]byte, n)
-		r := copy(tmp, b)
-		b = tmp
-
-		for {
-			nn, err := rd.Read(b[r:])
-			r += nn
-			if r >= n {
-				// Ignore error if we read enough.
-				break
-			}
-			if err != nil {
-				return nil, err
-			}
-		}
-	} else if err != nil {
-		return nil, err
-	}
-	return b, nil
-}
-
-//------------------------------------------------------------------------------
-
-func parseReq(rd *bufio.Reader) ([]string, error) {
-	line, err := readLine(rd)
-	if err != nil {
-		return nil, err
-	}
-
-	if line[0] != '*' {
-		return []string{string(line)}, nil
-	}
-	numReplies, err := strconv.ParseInt(string(line[1:]), 10, 64)
-	if err != nil {
-		return nil, err
-	}
-
-	args := make([]string, 0, numReplies)
-	for i := int64(0); i < numReplies; i++ {
-		line, err = readLine(rd)
-		if err != nil {
-			return nil, err
-		}
-		if line[0] != '$' {
-			return nil, fmt.Errorf("redis: expected '$', but got %q", line)
-		}
-
-		argLen, err := strconv.ParseInt(string(line[1:]), 10, 32)
-		if err != nil {
-			return nil, err
-		}
-
-		arg, err := readN(rd, int(argLen)+2)
-		if err != nil {
-			return nil, err
-		}
-		args = append(args, string(arg[:argLen]))
-	}
-	return args, nil
-}
-
-//------------------------------------------------------------------------------
-
-func parseReply(rd *bufio.Reader, p multiBulkParser) (interface{}, error) {
-	line, err := readLine(rd)
-	if err != nil {
-		return nil, err
-	}
-
-	switch line[0] {
-	case '-':
-		return nil, errorf(string(line[1:]))
-	case '+':
-		return string(line[1:]), nil
-	case ':':
-		v, err := strconv.ParseInt(string(line[1:]), 10, 64)
-		if err != nil {
-			return nil, err
-		}
-		return v, nil
-	case '$':
-		if len(line) == 3 && line[1] == '-' && line[2] == '1' {
-			return nil, Nil
-		}
-
-		replyLen, err := strconv.Atoi(string(line[1:]))
-		if err != nil {
-			return nil, err
-		}
-
-		b, err := readN(rd, replyLen+2)
-		if err != nil {
-			return nil, err
-		}
-		return string(b[:replyLen]), nil
-	case '*':
-		if len(line) == 3 && line[1] == '-' && line[2] == '1' {
-			return nil, Nil
-		}
-
-		repliesNum, err := strconv.ParseInt(string(line[1:]), 10, 64)
-		if err != nil {
-			return nil, err
-		}
-
-		return p(rd, repliesNum)
-	}
-	return nil, fmt.Errorf("redis: can't parse %q", line)
-}
-
-func parseSlice(rd *bufio.Reader, n int64) (interface{}, error) {
-	vals := make([]interface{}, 0, n)
-	for i := int64(0); i < n; i++ {
-		v, err := parseReply(rd, parseSlice)
-		if err == Nil {
-			vals = append(vals, nil)
-		} else if err != nil {
-			return nil, err
-		} else {
-			vals = append(vals, v)
-		}
-	}
-	return vals, nil
-}
-
-func parseStringSlice(rd *bufio.Reader, n int64) (interface{}, error) {
-	vals := make([]string, 0, n)
-	for i := int64(0); i < n; i++ {
-		viface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		v, ok := viface.(string)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected string", viface)
-		}
-		vals = append(vals, v)
-	}
-	return vals, nil
-}
-
-func parseBoolSlice(rd *bufio.Reader, n int64) (interface{}, error) {
-	vals := make([]bool, 0, n)
-	for i := int64(0); i < n; i++ {
-		viface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		v, ok := viface.(int64)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected int64", viface)
-		}
-		vals = append(vals, v == 1)
-	}
-	return vals, nil
-}
-
-func parseStringStringMap(rd *bufio.Reader, n int64) (interface{}, error) {
-	m := make(map[string]string, n/2)
-	for i := int64(0); i < n; i += 2 {
-		keyiface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		key, ok := keyiface.(string)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected string", keyiface)
-		}
-
-		valueiface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		value, ok := valueiface.(string)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected string", valueiface)
-		}
-
-		m[key] = value
-	}
-	return m, nil
-}
-
-func parseZSlice(rd *bufio.Reader, n int64) (interface{}, error) {
-	zz := make([]Z, n/2)
-	for i := int64(0); i < n; i += 2 {
-		z := &zz[i/2]
-
-		memberiface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		member, ok := memberiface.(string)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected string", memberiface)
-		}
-		z.Member = member
-
-		scoreiface, err := parseReply(rd, nil)
-		if err != nil {
-			return nil, err
-		}
-		scorestr, ok := scoreiface.(string)
-		if !ok {
-			return nil, fmt.Errorf("got %T, expected string", scoreiface)
-		}
-		score, err := strconv.ParseFloat(scorestr, 64)
-		if err != nil {
-			return nil, err
-		}
-		z.Score = score
-	}
-	return zz, nil
-}
diff --git a/vendor/gopkg.in/redis.v2/pipeline.go b/vendor/gopkg.in/redis.v2/pipeline.go
deleted file mode 100644
index 540d6c51d9..0000000000
--- a/vendor/gopkg.in/redis.v2/pipeline.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package redis
-
-// Not thread-safe.
-type Pipeline struct {
-	*Client
-
-	closed bool
-}
-
-func (c *Client) Pipeline() *Pipeline {
-	return &Pipeline{
-		Client: &Client{
-			baseClient: &baseClient{
-				opt:      c.opt,
-				connPool: c.connPool,
-
-				cmds: make([]Cmder, 0),
-			},
-		},
-	}
-}
-
-func (c *Client) Pipelined(f func(*Pipeline) error) ([]Cmder, error) {
-	pc := c.Pipeline()
-	if err := f(pc); err != nil {
-		return nil, err
-	}
-	cmds, err := pc.Exec()
-	pc.Close()
-	return cmds, err
-}
-
-func (c *Pipeline) Close() error {
-	c.closed = true
-	return nil
-}
-
-func (c *Pipeline) Discard() error {
-	if c.closed {
-		return errClosed
-	}
-	c.cmds = c.cmds[:0]
-	return nil
-}
-
-// Exec always returns list of commands and error of the first failed
-// command if any.
-func (c *Pipeline) Exec() ([]Cmder, error) {
-	if c.closed {
-		return nil, errClosed
-	}
-
-	cmds := c.cmds
-	c.cmds = make([]Cmder, 0)
-
-	if len(cmds) == 0 {
-		return []Cmder{}, nil
-	}
-
-	cn, err := c.conn()
-	if err != nil {
-		setCmdsErr(cmds, err)
-		return cmds, err
-	}
-
-	if err := c.execCmds(cn, cmds); err != nil {
-		c.freeConn(cn, err)
-		return cmds, err
-	}
-
-	c.putConn(cn)
-	return cmds, nil
-}
-
-func (c *Pipeline) execCmds(cn *conn, cmds []Cmder) error {
-	if err := c.writeCmd(cn, cmds...); err != nil {
-		setCmdsErr(cmds, err)
-		return err
-	}
-
-	var firstCmdErr error
-	for _, cmd := range cmds {
-		if err := cmd.parseReply(cn.rd); err != nil {
-			if firstCmdErr == nil {
-				firstCmdErr = err
-			}
-		}
-	}
-
-	return firstCmdErr
-}
diff --git a/vendor/gopkg.in/redis.v2/pool.go b/vendor/gopkg.in/redis.v2/pool.go
deleted file mode 100644
index bca4d19633..0000000000
--- a/vendor/gopkg.in/redis.v2/pool.go
+++ /dev/null
@@ -1,405 +0,0 @@
-package redis
-
-import (
-	"container/list"
-	"errors"
-	"log"
-	"net"
-	"sync"
-	"time"
-
-	"gopkg.in/bufio.v1"
-)
-
-var (
-	errClosed      = errors.New("redis: client is closed")
-	errRateLimited = errors.New("redis: you open connections too fast")
-)
-
-var (
-	zeroTime = time.Time{}
-)
-
-type pool interface {
-	Get() (*conn, bool, error)
-	Put(*conn) error
-	Remove(*conn) error
-	Len() int
-	Size() int
-	Close() error
-	Filter(func(*conn) bool)
-}
-
-//------------------------------------------------------------------------------
-
-type conn struct {
-	netcn net.Conn
-	rd    *bufio.Reader
-	buf   []byte
-
-	inUse  bool
-	usedAt time.Time
-
-	readTimeout  time.Duration
-	writeTimeout time.Duration
-
-	elem *list.Element
-}
-
-func newConnFunc(dial func() (net.Conn, error)) func() (*conn, error) {
-	return func() (*conn, error) {
-		netcn, err := dial()
-		if err != nil {
-			return nil, err
-		}
-		cn := &conn{
-			netcn: netcn,
-			buf:   make([]byte, 0, 64),
-		}
-		cn.rd = bufio.NewReader(cn)
-		return cn, nil
-	}
-}
-
-func (cn *conn) Read(b []byte) (int, error) {
-	if cn.readTimeout != 0 {
-		cn.netcn.SetReadDeadline(time.Now().Add(cn.readTimeout))
-	} else {
-		cn.netcn.SetReadDeadline(zeroTime)
-	}
-	return cn.netcn.Read(b)
-}
-
-func (cn *conn) Write(b []byte) (int, error) {
-	if cn.writeTimeout != 0 {
-		cn.netcn.SetWriteDeadline(time.Now().Add(cn.writeTimeout))
-	} else {
-		cn.netcn.SetWriteDeadline(zeroTime)
-	}
-	return cn.netcn.Write(b)
-}
-
-func (cn *conn) RemoteAddr() net.Addr {
-	return cn.netcn.RemoteAddr()
-}
-
-func (cn *conn) Close() error {
-	return cn.netcn.Close()
-}
-
-//------------------------------------------------------------------------------
-
-type connPool struct {
-	dial func() (*conn, error)
-	rl   *rateLimiter
-
-	opt *options
-
-	cond  *sync.Cond
-	conns *list.List
-
-	idleNum int
-	closed  bool
-}
-
-func newConnPool(dial func() (*conn, error), opt *options) *connPool {
-	return &connPool{
-		dial: dial,
-		rl:   newRateLimiter(time.Second, 2*opt.PoolSize),
-
-		opt: opt,
-
-		cond:  sync.NewCond(&sync.Mutex{}),
-		conns: list.New(),
-	}
-}
-
-func (p *connPool) new() (*conn, error) {
-	if !p.rl.Check() {
-		return nil, errRateLimited
-	}
-	return p.dial()
-}
-
-func (p *connPool) Get() (*conn, bool, error) {
-	p.cond.L.Lock()
-
-	if p.closed {
-		p.cond.L.Unlock()
-		return nil, false, errClosed
-	}
-
-	if p.opt.IdleTimeout > 0 {
-		for el := p.conns.Front(); el != nil; el = el.Next() {
-			cn := el.Value.(*conn)
-			if cn.inUse {
-				break
-			}
-			if time.Since(cn.usedAt) > p.opt.IdleTimeout {
-				if err := p.remove(cn); err != nil {
-					log.Printf("remove failed: %s", err)
-				}
-			}
-		}
-	}
-
-	for p.conns.Len() >= p.opt.PoolSize && p.idleNum == 0 {
-		p.cond.Wait()
-	}
-
-	if p.idleNum > 0 {
-		elem := p.conns.Front()
-		cn := elem.Value.(*conn)
-		if cn.inUse {
-			panic("pool: precondition failed")
-		}
-		cn.inUse = true
-		p.conns.MoveToBack(elem)
-		p.idleNum--
-
-		p.cond.L.Unlock()
-		return cn, false, nil
-	}
-
-	if p.conns.Len() < p.opt.PoolSize {
-		cn, err := p.new()
-		if err != nil {
-			p.cond.L.Unlock()
-			return nil, false, err
-		}
-
-		cn.inUse = true
-		cn.elem = p.conns.PushBack(cn)
-
-		p.cond.L.Unlock()
-		return cn, true, nil
-	}
-
-	panic("not reached")
-}
-
-func (p *connPool) Put(cn *conn) error {
-	if cn.rd.Buffered() != 0 {
-		b, _ := cn.rd.ReadN(cn.rd.Buffered())
-		log.Printf("redis: connection has unread data: %q", b)
-		return p.Remove(cn)
-	}
-
-	if p.opt.IdleTimeout > 0 {
-		cn.usedAt = time.Now()
-	}
-
-	p.cond.L.Lock()
-	if p.closed {
-		p.cond.L.Unlock()
-		return errClosed
-	}
-	cn.inUse = false
-	p.conns.MoveToFront(cn.elem)
-	p.idleNum++
-	p.cond.Signal()
-	p.cond.L.Unlock()
-
-	return nil
-}
-
-func (p *connPool) Remove(cn *conn) error {
-	p.cond.L.Lock()
-	if p.closed {
-		// Noop, connection is already closed.
-		p.cond.L.Unlock()
-		return nil
-	}
-	err := p.remove(cn)
-	p.cond.Signal()
-	p.cond.L.Unlock()
-	return err
-}
-
-func (p *connPool) remove(cn *conn) error {
-	p.conns.Remove(cn.elem)
-	cn.elem = nil
-	if !cn.inUse {
-		p.idleNum--
-	}
-	return cn.Close()
-}
-
-// Len returns number of idle connections.
-func (p *connPool) Len() int {
-	defer p.cond.L.Unlock()
-	p.cond.L.Lock()
-	return p.idleNum
-}
-
-// Size returns number of connections in the pool.
-func (p *connPool) Size() int {
-	defer p.cond.L.Unlock()
-	p.cond.L.Lock()
-	return p.conns.Len()
-}
-
-func (p *connPool) Filter(f func(*conn) bool) {
-	p.cond.L.Lock()
-	for el, next := p.conns.Front(), p.conns.Front(); el != nil; el = next {
-		next = el.Next()
-		cn := el.Value.(*conn)
-		if !f(cn) {
-			p.remove(cn)
-		}
-	}
-	p.cond.L.Unlock()
-}
-
-func (p *connPool) Close() error {
-	defer p.cond.L.Unlock()
-	p.cond.L.Lock()
-	if p.closed {
-		return nil
-	}
-	p.closed = true
-	p.rl.Close()
-	var retErr error
-	for {
-		e := p.conns.Front()
-		if e == nil {
-			break
-		}
-		if err := p.remove(e.Value.(*conn)); err != nil {
-			log.Printf("cn.Close failed: %s", err)
-			retErr = err
-		}
-	}
-	return retErr
-}
-
-//------------------------------------------------------------------------------
-
-type singleConnPool struct {
-	pool pool
-
-	cnMtx sync.Mutex
-	cn    *conn
-
-	reusable bool
-
-	closed bool
-}
-
-func newSingleConnPool(pool pool, reusable bool) *singleConnPool {
-	return &singleConnPool{
-		pool:     pool,
-		reusable: reusable,
-	}
-}
-
-func (p *singleConnPool) SetConn(cn *conn) {
-	p.cnMtx.Lock()
-	p.cn = cn
-	p.cnMtx.Unlock()
-}
-
-func (p *singleConnPool) Get() (*conn, bool, error) {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-
-	if p.closed {
-		return nil, false, errClosed
-	}
-	if p.cn != nil {
-		return p.cn, false, nil
-	}
-
-	cn, isNew, err := p.pool.Get()
-	if err != nil {
-		return nil, false, err
-	}
-	p.cn = cn
-
-	return p.cn, isNew, nil
-}
-
-func (p *singleConnPool) Put(cn *conn) error {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-	if p.cn != cn {
-		panic("p.cn != cn")
-	}
-	if p.closed {
-		return errClosed
-	}
-	return nil
-}
-
-func (p *singleConnPool) put() error {
-	err := p.pool.Put(p.cn)
-	p.cn = nil
-	return err
-}
-
-func (p *singleConnPool) Remove(cn *conn) error {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-	if p.cn == nil {
-		panic("p.cn == nil")
-	}
-	if p.cn != cn {
-		panic("p.cn != cn")
-	}
-	if p.closed {
-		return errClosed
-	}
-	return p.remove()
-}
-
-func (p *singleConnPool) remove() error {
-	err := p.pool.Remove(p.cn)
-	p.cn = nil
-	return err
-}
-
-func (p *singleConnPool) Len() int {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-	if p.cn == nil {
-		return 0
-	}
-	return 1
-}
-
-func (p *singleConnPool) Size() int {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-	if p.cn == nil {
-		return 0
-	}
-	return 1
-}
-
-func (p *singleConnPool) Filter(f func(*conn) bool) {
-	p.cnMtx.Lock()
-	if p.cn != nil {
-		if !f(p.cn) {
-			p.remove()
-		}
-	}
-	p.cnMtx.Unlock()
-}
-
-func (p *singleConnPool) Close() error {
-	defer p.cnMtx.Unlock()
-	p.cnMtx.Lock()
-	if p.closed {
-		return nil
-	}
-	p.closed = true
-	var err error
-	if p.cn != nil {
-		if p.reusable {
-			err = p.put()
-		} else {
-			err = p.remove()
-		}
-	}
-	return err
-}
diff --git a/vendor/gopkg.in/redis.v2/pubsub.go b/vendor/gopkg.in/redis.v2/pubsub.go
deleted file mode 100644
index 6ac130bac4..0000000000
--- a/vendor/gopkg.in/redis.v2/pubsub.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package redis
-
-import (
-	"fmt"
-	"time"
-)
-
-// Not thread-safe.
-type PubSub struct {
-	*baseClient
-}
-
-func (c *Client) PubSub() *PubSub {
-	return &PubSub{
-		baseClient: &baseClient{
-			opt:      c.opt,
-			connPool: newSingleConnPool(c.connPool, false),
-		},
-	}
-}
-
-func (c *Client) Publish(channel, message string) *IntCmd {
-	req := NewIntCmd("PUBLISH", channel, message)
-	c.Process(req)
-	return req
-}
-
-type Message struct {
-	Channel string
-	Payload string
-}
-
-func (m *Message) String() string {
-	return fmt.Sprintf("Message<%s: %s>", m.Channel, m.Payload)
-}
-
-type PMessage struct {
-	Channel string
-	Pattern string
-	Payload string
-}
-
-func (m *PMessage) String() string {
-	return fmt.Sprintf("PMessage<%s: %s>", m.Channel, m.Payload)
-}
-
-type Subscription struct {
-	Kind    string
-	Channel string
-	Count   int
-}
-
-func (m *Subscription) String() string {
-	return fmt.Sprintf("%s: %s", m.Kind, m.Channel)
-}
-
-func (c *PubSub) Receive() (interface{}, error) {
-	return c.ReceiveTimeout(0)
-}
-
-func (c *PubSub) ReceiveTimeout(timeout time.Duration) (interface{}, error) {
-	cn, err := c.conn()
-	if err != nil {
-		return nil, err
-	}
-	cn.readTimeout = timeout
-
-	cmd := NewSliceCmd()
-	if err := cmd.parseReply(cn.rd); err != nil {
-		return nil, err
-	}
-
-	reply := cmd.Val()
-
-	msgName := reply[0].(string)
-	switch msgName {
-	case "subscribe", "unsubscribe", "psubscribe", "punsubscribe":
-		return &Subscription{
-			Kind:    msgName,
-			Channel: reply[1].(string),
-			Count:   int(reply[2].(int64)),
-		}, nil
-	case "message":
-		return &Message{
-			Channel: reply[1].(string),
-			Payload: reply[2].(string),
-		}, nil
-	case "pmessage":
-		return &PMessage{
-			Pattern: reply[1].(string),
-			Channel: reply[2].(string),
-			Payload: reply[3].(string),
-		}, nil
-	}
-	return nil, fmt.Errorf("redis: unsupported message name: %q", msgName)
-}
-
-func (c *PubSub) subscribe(cmd string, channels ...string) error {
-	cn, err := c.conn()
-	if err != nil {
-		return err
-	}
-
-	args := append([]string{cmd}, channels...)
-	req := NewSliceCmd(args...)
-	return c.writeCmd(cn, req)
-}
-
-func (c *PubSub) Subscribe(channels ...string) error {
-	return c.subscribe("SUBSCRIBE", channels...)
-}
-
-func (c *PubSub) PSubscribe(patterns ...string) error {
-	return c.subscribe("PSUBSCRIBE", patterns...)
-}
-
-func (c *PubSub) unsubscribe(cmd string, channels ...string) error {
-	cn, err := c.conn()
-	if err != nil {
-		return err
-	}
-
-	args := append([]string{cmd}, channels...)
-	req := NewSliceCmd(args...)
-	return c.writeCmd(cn, req)
-}
-
-func (c *PubSub) Unsubscribe(channels ...string) error {
-	return c.unsubscribe("UNSUBSCRIBE", channels...)
-}
-
-func (c *PubSub) PUnsubscribe(patterns ...string) error {
-	return c.unsubscribe("PUNSUBSCRIBE", patterns...)
-}
diff --git a/vendor/gopkg.in/redis.v2/rate_limit.go b/vendor/gopkg.in/redis.v2/rate_limit.go
deleted file mode 100644
index 20d8512707..0000000000
--- a/vendor/gopkg.in/redis.v2/rate_limit.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package redis
-
-import (
-	"sync/atomic"
-	"time"
-)
-
-type rateLimiter struct {
-	v int64
-
-	_closed int64
-}
-
-func newRateLimiter(limit time.Duration, bucketSize int) *rateLimiter {
-	rl := &rateLimiter{
-		v: int64(bucketSize),
-	}
-	go rl.loop(limit, int64(bucketSize))
-	return rl
-}
-
-func (rl *rateLimiter) loop(limit time.Duration, bucketSize int64) {
-	for {
-		if rl.closed() {
-			break
-		}
-		if v := atomic.LoadInt64(&rl.v); v < bucketSize {
-			atomic.AddInt64(&rl.v, 1)
-		}
-		time.Sleep(limit)
-	}
-}
-
-func (rl *rateLimiter) Check() bool {
-	for {
-		if v := atomic.LoadInt64(&rl.v); v > 0 {
-			if atomic.CompareAndSwapInt64(&rl.v, v, v-1) {
-				return true
-			}
-		} else {
-			return false
-		}
-	}
-}
-
-func (rl *rateLimiter) Close() error {
-	atomic.StoreInt64(&rl._closed, 1)
-	return nil
-}
-
-func (rl *rateLimiter) closed() bool {
-	return atomic.LoadInt64(&rl._closed) == 1
-}
diff --git a/vendor/gopkg.in/redis.v2/redis.go b/vendor/gopkg.in/redis.v2/redis.go
deleted file mode 100644
index 0d15dc8f85..0000000000
--- a/vendor/gopkg.in/redis.v2/redis.go
+++ /dev/null
@@ -1,231 +0,0 @@
-package redis
-
-import (
-	"log"
-	"net"
-	"time"
-)
-
-type baseClient struct {
-	connPool pool
-	opt      *options
-	cmds     []Cmder
-}
-
-func (c *baseClient) writeCmd(cn *conn, cmds ...Cmder) error {
-	buf := cn.buf[:0]
-	for _, cmd := range cmds {
-		buf = appendArgs(buf, cmd.args())
-	}
-
-	_, err := cn.Write(buf)
-	return err
-}
-
-func (c *baseClient) conn() (*conn, error) {
-	cn, isNew, err := c.connPool.Get()
-	if err != nil {
-		return nil, err
-	}
-
-	if isNew {
-		if err := c.initConn(cn); err != nil {
-			c.removeConn(cn)
-			return nil, err
-		}
-	}
-
-	return cn, nil
-}
-
-func (c *baseClient) initConn(cn *conn) error {
-	if c.opt.Password == "" && c.opt.DB == 0 {
-		return nil
-	}
-
-	pool := newSingleConnPool(c.connPool, false)
-	pool.SetConn(cn)
-
-	// Client is not closed because we want to reuse underlying connection.
-	client := &Client{
-		baseClient: &baseClient{
-			opt:      c.opt,
-			connPool: pool,
-		},
-	}
-
-	if c.opt.Password != "" {
-		if err := client.Auth(c.opt.Password).Err(); err != nil {
-			return err
-		}
-	}
-
-	if c.opt.DB > 0 {
-		if err := client.Select(c.opt.DB).Err(); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (c *baseClient) freeConn(cn *conn, ei error) error {
-	if cn.rd.Buffered() > 0 {
-		return c.connPool.Remove(cn)
-	}
-	if _, ok := ei.(redisError); ok {
-		return c.connPool.Put(cn)
-	}
-	return c.connPool.Remove(cn)
-}
-
-func (c *baseClient) removeConn(cn *conn) {
-	if err := c.connPool.Remove(cn); err != nil {
-		log.Printf("pool.Remove failed: %s", err)
-	}
-}
-
-func (c *baseClient) putConn(cn *conn) {
-	if err := c.connPool.Put(cn); err != nil {
-		log.Printf("pool.Put failed: %s", err)
-	}
-}
-
-func (c *baseClient) Process(cmd Cmder) {
-	if c.cmds == nil {
-		c.run(cmd)
-	} else {
-		c.cmds = append(c.cmds, cmd)
-	}
-}
-
-func (c *baseClient) run(cmd Cmder) {
-	cn, err := c.conn()
-	if err != nil {
-		cmd.setErr(err)
-		return
-	}
-
-	if timeout := cmd.writeTimeout(); timeout != nil {
-		cn.writeTimeout = *timeout
-	} else {
-		cn.writeTimeout = c.opt.WriteTimeout
-	}
-
-	if timeout := cmd.readTimeout(); timeout != nil {
-		cn.readTimeout = *timeout
-	} else {
-		cn.readTimeout = c.opt.ReadTimeout
-	}
-
-	if err := c.writeCmd(cn, cmd); err != nil {
-		c.freeConn(cn, err)
-		cmd.setErr(err)
-		return
-	}
-
-	if err := cmd.parseReply(cn.rd); err != nil {
-		c.freeConn(cn, err)
-		return
-	}
-
-	c.putConn(cn)
-}
-
-// Close closes the client, releasing any open resources.
-func (c *baseClient) Close() error {
-	return c.connPool.Close()
-}
-
-//------------------------------------------------------------------------------
-
-type options struct {
-	Password string
-	DB       int64
-
-	DialTimeout  time.Duration
-	ReadTimeout  time.Duration
-	WriteTimeout time.Duration
-
-	PoolSize    int
-	IdleTimeout time.Duration
-}
-
-type Options struct {
-	Network string
-	Addr    string
-
-	// Dialer creates new network connection and has priority over
-	// Network and Addr options.
-	Dialer func() (net.Conn, error)
-
-	Password string
-	DB       int64
-
-	DialTimeout  time.Duration
-	ReadTimeout  time.Duration
-	WriteTimeout time.Duration
-
-	PoolSize    int
-	IdleTimeout time.Duration
-}
-
-func (opt *Options) getPoolSize() int {
-	if opt.PoolSize == 0 {
-		return 10
-	}
-	return opt.PoolSize
-}
-
-func (opt *Options) getDialTimeout() time.Duration {
-	if opt.DialTimeout == 0 {
-		return 5 * time.Second
-	}
-	return opt.DialTimeout
-}
-
-func (opt *Options) options() *options {
-	return &options{
-		DB:       opt.DB,
-		Password: opt.Password,
-
-		DialTimeout:  opt.getDialTimeout(),
-		ReadTimeout:  opt.ReadTimeout,
-		WriteTimeout: opt.WriteTimeout,
-
-		PoolSize:    opt.getPoolSize(),
-		IdleTimeout: opt.IdleTimeout,
-	}
-}
-
-type Client struct {
-	*baseClient
-}
-
-func NewClient(clOpt *Options) *Client {
-	opt := clOpt.options()
-	dialer := clOpt.Dialer
-	if dialer == nil {
-		dialer = func() (net.Conn, error) {
-			return net.DialTimeout(clOpt.Network, clOpt.Addr, opt.DialTimeout)
-		}
-	}
-	return &Client{
-		baseClient: &baseClient{
-			opt:      opt,
-			connPool: newConnPool(newConnFunc(dialer), opt),
-		},
-	}
-}
-
-// Deprecated. Use NewClient instead.
-func NewTCPClient(opt *Options) *Client {
-	opt.Network = "tcp"
-	return NewClient(opt)
-}
-
-// Deprecated. Use NewClient instead.
-func NewUnixClient(opt *Options) *Client {
-	opt.Network = "unix"
-	return NewClient(opt)
-}
diff --git a/vendor/gopkg.in/redis.v2/script.go b/vendor/gopkg.in/redis.v2/script.go
deleted file mode 100644
index 96c35f5149..0000000000
--- a/vendor/gopkg.in/redis.v2/script.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package redis
-
-import (
-	"crypto/sha1"
-	"encoding/hex"
-	"io"
-	"strings"
-)
-
-type scripter interface {
-	Eval(script string, keys []string, args []string) *Cmd
-	EvalSha(sha1 string, keys []string, args []string) *Cmd
-	ScriptExists(scripts ...string) *BoolSliceCmd
-	ScriptLoad(script string) *StringCmd
-}
-
-type Script struct {
-	src, hash string
-}
-
-func NewScript(src string) *Script {
-	h := sha1.New()
-	io.WriteString(h, src)
-	return &Script{
-		src:  src,
-		hash: hex.EncodeToString(h.Sum(nil)),
-	}
-}
-
-func (s *Script) Load(c scripter) *StringCmd {
-	return c.ScriptLoad(s.src)
-}
-
-func (s *Script) Exists(c scripter) *BoolSliceCmd {
-	return c.ScriptExists(s.src)
-}
-
-func (s *Script) Eval(c scripter, keys []string, args []string) *Cmd {
-	return c.Eval(s.src, keys, args)
-}
-
-func (s *Script) EvalSha(c scripter, keys []string, args []string) *Cmd {
-	return c.EvalSha(s.hash, keys, args)
-}
-
-func (s *Script) Run(c *Client, keys []string, args []string) *Cmd {
-	r := s.EvalSha(c, keys, args)
-	if err := r.Err(); err != nil && strings.HasPrefix(err.Error(), "NOSCRIPT ") {
-		return s.Eval(c, keys, args)
-	}
-	return r
-}
diff --git a/vendor/gopkg.in/redis.v2/sentinel.go b/vendor/gopkg.in/redis.v2/sentinel.go
deleted file mode 100644
index d3ffeca9a5..0000000000
--- a/vendor/gopkg.in/redis.v2/sentinel.go
+++ /dev/null
@@ -1,291 +0,0 @@
-package redis
-
-import (
-	"errors"
-	"log"
-	"net"
-	"strings"
-	"sync"
-	"time"
-)
-
-//------------------------------------------------------------------------------
-
-type FailoverOptions struct {
-	MasterName    string
-	SentinelAddrs []string
-
-	Password string
-	DB       int64
-
-	PoolSize int
-
-	DialTimeout  time.Duration
-	ReadTimeout  time.Duration
-	WriteTimeout time.Duration
-	IdleTimeout  time.Duration
-}
-
-func (opt *FailoverOptions) getPoolSize() int {
-	if opt.PoolSize == 0 {
-		return 10
-	}
-	return opt.PoolSize
-}
-
-func (opt *FailoverOptions) getDialTimeout() time.Duration {
-	if opt.DialTimeout == 0 {
-		return 5 * time.Second
-	}
-	return opt.DialTimeout
-}
-
-func (opt *FailoverOptions) options() *options {
-	return &options{
-		DB:       opt.DB,
-		Password: opt.Password,
-
-		DialTimeout:  opt.getDialTimeout(),
-		ReadTimeout:  opt.ReadTimeout,
-		WriteTimeout: opt.WriteTimeout,
-
-		PoolSize:    opt.getPoolSize(),
-		IdleTimeout: opt.IdleTimeout,
-	}
-}
-
-func NewFailoverClient(failoverOpt *FailoverOptions) *Client {
-	opt := failoverOpt.options()
-	failover := &sentinelFailover{
-		masterName:    failoverOpt.MasterName,
-		sentinelAddrs: failoverOpt.SentinelAddrs,
-
-		opt: opt,
-	}
-	return &Client{
-		baseClient: &baseClient{
-			opt:      opt,
-			connPool: failover.Pool(),
-		},
-	}
-}
-
-//------------------------------------------------------------------------------
-
-type sentinelClient struct {
-	*baseClient
-}
-
-func newSentinel(clOpt *Options) *sentinelClient {
-	opt := clOpt.options()
-	opt.Password = ""
-	opt.DB = 0
-	dialer := func() (net.Conn, error) {
-		return net.DialTimeout("tcp", clOpt.Addr, opt.DialTimeout)
-	}
-	return &sentinelClient{
-		baseClient: &baseClient{
-			opt:      opt,
-			connPool: newConnPool(newConnFunc(dialer), opt),
-		},
-	}
-}
-
-func (c *sentinelClient) PubSub() *PubSub {
-	return &PubSub{
-		baseClient: &baseClient{
-			opt:      c.opt,
-			connPool: newSingleConnPool(c.connPool, false),
-		},
-	}
-}
-
-func (c *sentinelClient) GetMasterAddrByName(name string) *StringSliceCmd {
-	cmd := NewStringSliceCmd("SENTINEL", "get-master-addr-by-name", name)
-	c.Process(cmd)
-	return cmd
-}
-
-func (c *sentinelClient) Sentinels(name string) *SliceCmd {
-	cmd := NewSliceCmd("SENTINEL", "sentinels", name)
-	c.Process(cmd)
-	return cmd
-}
-
-type sentinelFailover struct {
-	masterName    string
-	sentinelAddrs []string
-
-	opt *options
-
-	pool     pool
-	poolOnce sync.Once
-
-	lock      sync.RWMutex
-	_sentinel *sentinelClient
-}
-
-func (d *sentinelFailover) dial() (net.Conn, error) {
-	addr, err := d.MasterAddr()
-	if err != nil {
-		return nil, err
-	}
-	return net.DialTimeout("tcp", addr, d.opt.DialTimeout)
-}
-
-func (d *sentinelFailover) Pool() pool {
-	d.poolOnce.Do(func() {
-		d.pool = newConnPool(newConnFunc(d.dial), d.opt)
-	})
-	return d.pool
-}
-
-func (d *sentinelFailover) MasterAddr() (string, error) {
-	defer d.lock.Unlock()
-	d.lock.Lock()
-
-	// Try last working sentinel.
-	if d._sentinel != nil {
-		addr, err := d._sentinel.GetMasterAddrByName(d.masterName).Result()
-		if err != nil {
-			log.Printf("redis-sentinel: GetMasterAddrByName %q failed: %s", d.masterName, err)
-			d.resetSentinel()
-		} else {
-			addr := net.JoinHostPort(addr[0], addr[1])
-			log.Printf("redis-sentinel: %q addr is %s", d.masterName, addr)
-			return addr, nil
-		}
-	}
-
-	for i, sentinelAddr := range d.sentinelAddrs {
-		sentinel := newSentinel(&Options{
-			Addr: sentinelAddr,
-
-			DB:       d.opt.DB,
-			Password: d.opt.Password,
-
-			DialTimeout:  d.opt.DialTimeout,
-			ReadTimeout:  d.opt.ReadTimeout,
-			WriteTimeout: d.opt.WriteTimeout,
-
-			PoolSize:    d.opt.PoolSize,
-			IdleTimeout: d.opt.IdleTimeout,
-		})
-		masterAddr, err := sentinel.GetMasterAddrByName(d.masterName).Result()
-		if err != nil {
-			log.Printf("redis-sentinel: GetMasterAddrByName %q failed: %s", d.masterName, err)
-			sentinel.Close()
-			continue
-		}
-
-		// Push working sentinel to the top.
-		d.sentinelAddrs[0], d.sentinelAddrs[i] = d.sentinelAddrs[i], d.sentinelAddrs[0]
-
-		d.setSentinel(sentinel)
-		addr := net.JoinHostPort(masterAddr[0], masterAddr[1])
-		log.Printf("redis-sentinel: %q addr is %s", d.masterName, addr)
-		return addr, nil
-	}
-
-	return "", errors.New("redis: all sentinels are unreachable")
-}
-
-func (d *sentinelFailover) setSentinel(sentinel *sentinelClient) {
-	d.discoverSentinels(sentinel)
-	d._sentinel = sentinel
-	go d.listen()
-}
-
-func (d *sentinelFailover) discoverSentinels(sentinel *sentinelClient) {
-	sentinels, err := sentinel.Sentinels(d.masterName).Result()
-	if err != nil {
-		log.Printf("redis-sentinel: Sentinels %q failed: %s", d.masterName, err)
-		return
-	}
-	for _, sentinel := range sentinels {
-		vals := sentinel.([]interface{})
-		for i := 0; i < len(vals); i += 2 {
-			key := vals[i].(string)
-			if key == "name" {
-				sentinelAddr := vals[i+1].(string)
-				if !contains(d.sentinelAddrs, sentinelAddr) {
-					log.Printf(
-						"redis-sentinel: discovered new %q sentinel: %s",
-						d.masterName, sentinelAddr,
-					)
-					d.sentinelAddrs = append(d.sentinelAddrs, sentinelAddr)
-				}
-			}
-		}
-	}
-}
-
-func (d *sentinelFailover) listen() {
-	var pubsub *PubSub
-	for {
-		if pubsub == nil {
-			pubsub = d._sentinel.PubSub()
-			if err := pubsub.Subscribe("+switch-master"); err != nil {
-				log.Printf("redis-sentinel: Subscribe failed: %s", err)
-				d.lock.Lock()
-				d.resetSentinel()
-				d.lock.Unlock()
-				return
-			}
-		}
-
-		msgIface, err := pubsub.Receive()
-		if err != nil {
-			log.Printf("redis-sentinel: Receive failed: %s", err)
-			pubsub.Close()
-			return
-		}
-
-		switch msg := msgIface.(type) {
-		case *Message:
-			switch msg.Channel {
-			case "+switch-master":
-				parts := strings.Split(msg.Payload, " ")
-				if parts[0] != d.masterName {
-					log.Printf("redis-sentinel: ignore new %s addr", parts[0])
-					continue
-				}
-				addr := net.JoinHostPort(parts[3], parts[4])
-				log.Printf(
-					"redis-sentinel: new %q addr is %s",
-					d.masterName, addr,
-				)
-				d.pool.Filter(func(cn *conn) bool {
-					if cn.RemoteAddr().String() != addr {
-						log.Printf(
-							"redis-sentinel: closing connection to old master %s",
-							cn.RemoteAddr(),
-						)
-						return false
-					}
-					return true
-				})
-			default:
-				log.Printf("redis-sentinel: unsupported message: %s", msg)
-			}
-		case *Subscription:
-			// Ignore.
-		default:
-			log.Printf("redis-sentinel: unsupported message: %s", msgIface)
-		}
-	}
-}
-
-func (d *sentinelFailover) resetSentinel() {
-	d._sentinel.Close()
-	d._sentinel = nil
-}
-
-func contains(slice []string, str string) bool {
-	for _, s := range slice {
-		if s == str {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 0f1de7d856..3cbee9f5ca 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,20 +1,39 @@
 # cloud.google.com/go v0.37.4
 cloud.google.com/go/civil
+# gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b
+gitea.com/macaron/binding
+# gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76
+gitea.com/macaron/cache
+gitea.com/macaron/cache/memcache
+gitea.com/macaron/cache/redis
+# gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae
+gitea.com/macaron/captcha
+# gitea.com/macaron/cors v0.0.0-20190821152825-7dcef4a17175
+gitea.com/macaron/cors
+# gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439
+gitea.com/macaron/csrf
+# gitea.com/macaron/i18n v0.0.0-20190822004228-474e714e2223
+gitea.com/macaron/i18n
+# gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
+gitea.com/macaron/inject
+# gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+gitea.com/macaron/macaron
+# gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705
+gitea.com/macaron/session
+gitea.com/macaron/session/couchbase
+gitea.com/macaron/session/memcache
+gitea.com/macaron/session/mysql
+gitea.com/macaron/session/nodb
+gitea.com/macaron/session/postgres
+gitea.com/macaron/session/redis
+# gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
+gitea.com/macaron/toolbox
 # github.com/BurntSushi/toml v0.3.1
 github.com/BurntSushi/toml
 # github.com/PuerkitoBio/goquery v0.0.0-20170324135448-ed7d758e9a34
 github.com/PuerkitoBio/goquery
 # github.com/RoaringBitmap/roaring v0.4.7
 github.com/RoaringBitmap/roaring
-# github.com/Unknwon/cae v0.0.0-20160715032808-c6aac99ea2ca
-github.com/Unknwon/cae/zip
-github.com/Unknwon/cae
-# github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755
-github.com/Unknwon/com
-# github.com/Unknwon/i18n v0.0.0-20171114194641-b64d33658966
-github.com/Unknwon/i18n
-# github.com/Unknwon/paginater v0.0.0-20151104151617-7748a72e0141
-github.com/Unknwon/paginater
 # github.com/andybalholm/cascadia v0.0.0-20161224141413-349dd0209470
 github.com/andybalholm/cascadia
 # github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239
@@ -68,14 +87,14 @@ github.com/blevesearch/segment
 github.com/boombuler/barcode
 github.com/boombuler/barcode/qr
 github.com/boombuler/barcode/utils
-# github.com/bradfitz/gomemcache v0.0.0-20160117192205-fb1f79c6b65a
+# github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668
 github.com/bradfitz/gomemcache/memcache
 # github.com/chaseadamsio/goorgeous v0.0.0-20170901132237-098da33fde5f
 github.com/chaseadamsio/goorgeous
-# github.com/couchbase/gomemcached v0.0.0-20181122193126-5125a94a666c
+# github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d
 github.com/couchbase/gomemcached
 github.com/couchbase/gomemcached/client
-# github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a
+# github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b
 github.com/couchbase/goutils/logging
 github.com/couchbase/goutils/scramsha
 # github.com/couchbase/vellum v0.0.0-20190111184608-e91b68ff3efe
@@ -83,7 +102,7 @@ github.com/couchbase/vellum
 github.com/couchbase/vellum/levenshtein2
 github.com/couchbase/vellum/regexp
 github.com/couchbase/vellum/utf8
-# github.com/couchbaselabs/go-couchbase v0.0.0-20190117181324-d904413d884d
+# github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7
 github.com/couchbaselabs/go-couchbase
 # github.com/davecgh/go-spew v1.1.1
 github.com/davecgh/go-spew/spew
@@ -93,7 +112,7 @@ github.com/denisenkom/go-mssqldb/internal/cp
 github.com/denisenkom/go-mssqldb/internal/querytext
 # github.com/dgrijalva/jwt-go v3.2.0+incompatible
 github.com/dgrijalva/jwt-go
-# github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712
+# github.com/edsrzf/mmap-go v1.0.0
 github.com/edsrzf/mmap-go
 # github.com/emirpasic/gods v1.12.0
 github.com/emirpasic/gods/trees/binaryheap
@@ -119,32 +138,6 @@ github.com/facebookgo/stats
 github.com/gliderlabs/ssh
 # github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd
 github.com/glycerine/go-unsnap-stream
-# github.com/go-macaron/binding v0.0.0-20160711225916-9440f336b443
-github.com/go-macaron/binding
-# github.com/go-macaron/cache v0.0.0-20151013081102-561735312776
-github.com/go-macaron/cache
-github.com/go-macaron/cache/memcache
-github.com/go-macaron/cache/redis
-# github.com/go-macaron/captcha v0.0.0-20190710000913-8dc5911259df
-github.com/go-macaron/captcha
-# github.com/go-macaron/cors v0.0.0-20190309005821-6fd6a9bfe14e9
-github.com/go-macaron/cors
-# github.com/go-macaron/csrf v0.0.0-20190131233648-3751b136073c
-github.com/go-macaron/csrf
-# github.com/go-macaron/i18n v0.0.0-20190131234336-56731837a73b
-github.com/go-macaron/i18n
-# github.com/go-macaron/inject v0.0.0-20160627170012-d8a0b8677191
-github.com/go-macaron/inject
-# github.com/go-macaron/session v0.0.0-20190131233854-0a0a789bf193
-github.com/go-macaron/session
-github.com/go-macaron/session/couchbase
-github.com/go-macaron/session/memcache
-github.com/go-macaron/session/mysql
-github.com/go-macaron/session/nodb
-github.com/go-macaron/session/postgres
-github.com/go-macaron/session/redis
-# github.com/go-macaron/toolbox v0.0.0-20180818072302-a77f45a7ce90
-github.com/go-macaron/toolbox
 # github.com/go-redis/redis v6.15.2+incompatible
 github.com/go-redis/redis
 github.com/go-redis/redis/internal
@@ -211,7 +204,7 @@ github.com/klauspost/crc32
 # github.com/lafriks/xormstore v1.1.0
 github.com/lafriks/xormstore
 github.com/lafriks/xormstore/util
-# github.com/lib/pq v1.1.0
+# github.com/lib/pq v1.2.0
 github.com/lib/pq
 github.com/lib/pq/oid
 github.com/lib/pq/scram
@@ -241,7 +234,7 @@ github.com/markbates/goth/providers/openidConnect
 github.com/markbates/goth/providers/twitter
 # github.com/mattn/go-isatty v0.0.7
 github.com/mattn/go-isatty
-# github.com/mattn/go-sqlite3 v1.10.0
+# github.com/mattn/go-sqlite3 v1.11.0
 github.com/mattn/go-sqlite3
 # github.com/matttproud/golang_protobuf_extensions v1.0.1
 github.com/matttproud/golang_protobuf_extensions/pbutil
@@ -308,7 +301,7 @@ github.com/steveyen/gtreap
 # github.com/stretchr/testify v1.3.0
 github.com/stretchr/testify/assert
 github.com/stretchr/testify/require
-# github.com/syndtr/goleveldb v0.0.0-20190203031304-2f17a3356c66
+# github.com/syndtr/goleveldb v1.0.0
 github.com/syndtr/goleveldb/leveldb
 github.com/syndtr/goleveldb/leveldb/cache
 github.com/syndtr/goleveldb/leveldb/comparer
@@ -325,6 +318,15 @@ github.com/syndtr/goleveldb/leveldb/util
 github.com/tinylib/msgp/msgp
 # github.com/tstranex/u2f v1.0.0
 github.com/tstranex/u2f
+# github.com/unknwon/cae v0.0.0-20190822084630-55a0b64484a1
+github.com/unknwon/cae/zip
+github.com/unknwon/cae
+# github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+github.com/unknwon/com
+# github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
+github.com/unknwon/i18n
+# github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
+github.com/unknwon/paginater
 # github.com/urfave/cli v1.20.0
 github.com/urfave/cli
 # github.com/willf/bitset v0.0.0-20180426185212-8ce1146b8621
@@ -397,7 +399,7 @@ golang.org/x/text/internal/language/compact
 golang.org/x/text/internal/utf8internal
 golang.org/x/text/runes
 golang.org/x/text/internal/tag
-# google.golang.org/appengine v1.4.0
+# google.golang.org/appengine v1.6.1
 google.golang.org/appengine/cloudsql
 google.golang.org/appengine/urlfetch
 google.golang.org/appengine/internal
@@ -410,20 +412,14 @@ google.golang.org/appengine/internal/remote_api
 gopkg.in/alexcesaro/quotedprintable.v3
 # gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175
 gopkg.in/asn1-ber.v1
-# gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e
-gopkg.in/bufio.v1
 # gopkg.in/editorconfig/editorconfig-core-go.v1 v1.3.0
 gopkg.in/editorconfig/editorconfig-core-go.v1
 # gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
 gopkg.in/gomail.v2
-# gopkg.in/ini.v1 v1.42.0
+# gopkg.in/ini.v1 v1.46.0
 gopkg.in/ini.v1
 # gopkg.in/ldap.v3 v3.0.2
 gopkg.in/ldap.v3
-# gopkg.in/macaron.v1 v1.3.2
-gopkg.in/macaron.v1
-# gopkg.in/redis.v2 v2.3.2
-gopkg.in/redis.v2
 # gopkg.in/src-d/go-billy.v4 v4.3.2
 gopkg.in/src-d/go-billy.v4/osfs
 gopkg.in/src-d/go-billy.v4