]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge in the exists-to-join optimization that has been modified
authordrh <>
Wed, 2 Jul 2025 20:46:02 +0000 (20:46 +0000)
committerdrh <>
Wed, 2 Jul 2025 20:46:02 +0000 (20:46 +0000)
to relax the requirement of having an indexed join constraint.

FossilOrigin-Name: 1c1aef2b7feae29066d0330699ab634ef41f5b60cdcd479a60cb1a5409553138

12 files changed:
1  2 
manifest
manifest.uuid
src/build.c
src/resolve.c
src/select.c
src/sqliteInt.h
src/where.c
src/wherecode.c
test/eqp.test
test/existsexpr.test
test/json101.test
test/notnull2.test

diff --cc manifest
index e466a3906140f8dc498a00ad2d1414ddd512e251,9acc65a748c86642ea81bc96d5217834d84b20db..8caec32f551098a99db636ea09c566307caaeb2c
+++ b/manifest
@@@ -1,14 -1,14 +1,14 @@@
- C Fix\sVDBE\scoverage
- D 2025-07-02T17:43:59.873
 -C Merge\sall\sthe\slatest\strunk\senhancements\sinto\sthe\sexists-to-join\sbranch.
 -D 2024-07-31T23:46:10.492
++C Merge\sin\sthe\sexists-to-join\soptimization\sthat\shas\sbeen\smodified\nto\srelax\sthe\srequirement\sof\shaving\san\sindexed\sjoin\sconstraint.
++D 2025-07-02T20:46:02.299
 +F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
  F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
  F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 -F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
 -F Makefile.in 58c2cc5010aa5fd5e8eef6fe24d4ebcec7dc2e8c56f135d4f49e90a099bbc531
 -F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
 -F Makefile.msc 993f8addade63bcac7192416e7161ceee60edcee2376299ea48b2a74c66ac2d5
 -F README.md 6358805260a03ebead84e168bbf3740ddf3f683b477e478567186aa7afb490d3
 -F VERSION 0db40f92c04378404eb45bff93e9e42c148c7e54fd3da99469ed21e22411f5a6
 -F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
 +F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
 +F Makefile.in d8bc4aee9fb645c9f2ff0e3a30585d17a0df076bb6a33f0f20bab4999abb45a0
 +F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
 +F Makefile.msc ec2011bbdfc917d6a1c7c173dabb29c14ead0dd8e2e0b67278a00ae4ba576a77
 +F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1
 +F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8
  F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5
  F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031
  F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@@ -716,40 -686,43 +716,40 @@@ F mptest/crash01.test 61e61469e257df085
  F mptest/crash02.subtest f4ef05adcd15d60e5d2bd654204f2c008b519df8
  F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0
  F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
 -F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
  F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
  F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
 -F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 -F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
 -F src/alter.c e1b6782b85dd758f89e5c588e4e3eb82638c2dafc0c857b79a43bb8ec1746fca
 -F src/analyze.c 5c4e2bfd0aa8e5157f7fb91a17d86905510a74397326dc5767ec4e0588a4eea5
 -F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39
 -F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
 +F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
 +F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da
 +F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
 +F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
 +F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
  F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
 -F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
 -F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
 -F src/btree.c 8b42fc7d9efdb2df05c30e8f91ff6cfbd979724ae24bf90269028468b7a13333
 -F src/btree.h 55066f513eb095db935169dab1dc2f7c7a747ef223c533f5d4ad4dfed346cbd0
 -F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6
 -F src/build.c 9e6a971156db6285f726fb03ddd9d47cb0a3648198b611f462021ac96fa24135
 -F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
 +F src/bitvec.c e242d4496774dfc88fa278177dd23b607dce369ccafb3f61b41638eea2c9b399
 +F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea
 +F src/btree.c 96fcbe6db6af625e5a14c34d8f13688d1d22c5f924a436b12395aaf09ec65944
 +F src/btree.h e823c46d87f63d904d735a24b76146d19f51f04445ea561f71cc3382fd1307f0
 +F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886
- F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f
++F src/build.c f0a3d935954b1b344b929f5092f94e535ac98cf72bb8bcd3e72fb3dfa982e169
 +F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859
  F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 -F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
 -F src/date.c 13dd752847afb32ed70510ad7345a5b9c841f51ad904dba5d010f1fa3a6a324e
 -F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
 -F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
 -F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
 -F src/expr.c fe958028b36af640b70b2174354c044f75b8c4a4645c921592122aa2a022083a
 +F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9
 +F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6
 +F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
 +F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
 +F src/expr.c e3d3b6e60b86fac772bd4d4f0c6fe1d01bef3851754a9c1215d2f8574296cbd2
  F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 -F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a
 -F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f
 -F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90
 -F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
 -F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
 +F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f
 +F src/func.c de47a8295503aa130baae5e6d9868ecf4f7c4dbffa65d83ad1f70bdbac0ee2d6
 +F src/global.c a19e4b1ca1335f560e9560e590fc13081e21f670643367f99cb9e8f9dc7d615b
 +F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7
 +F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
  F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
  F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
 -F src/insert.c 4bd7c7e54a1062dcd0214b7a6296f7194eb10fb14d3ddca1ed20b01c2a86a18c
 -F src/json.c 5b6a1d6015997b9ee848a32948720bdb26a0ef2de5a2127ebf7355ce66dbdc0d
 +F src/insert.c dfd311b0ac2d4f6359e62013db67799757f4d2cc56cca5c10f4888acfbbfa3fd
 +F src/json.c cb87977b1ee25ee7d27505d65a9261b687395bf895342c8ba566b7c01aee2047
  F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 -F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
 -F src/main.c 8a59d297ec77e6b78550433bfccb95a1b26f2fb69aaaf233206e21579a1cfcc1
 +F src/loadext.c d7edd8e671237539d795d30daaf888908a2c82e99bade4c78f3be021e8b7d655
 +F src/main.c eb46066bf2f0bec2dd89229572de5a9c479c47da134e2422e7a0056e9510cbee
  F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
  F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
  F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@@ -770,54 -743,56 +770,54 @@@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b
  F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
  F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
  F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
 -F src/os_unix.c 2ea8d3ed496b8d1f9332a9505653424e5464fd797ea9d91f8e2e62f9dd0298d0
 -F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
 -F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 -F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
 -F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
 -F src/parse.y 2bd540b3b1e79017eb41fca2396633a75e7dd430c05383c61fe52c6f4e97c6d8
 +F src/os_unix.c 04e054ab86d86a7be99ebe5265922687791a40df5afc781d059beb47f4a40acd
 +F src/os_win.c b8d3cfdf2f40e2f9715b7d8df64f3c0c7ee18743a2dd0c4fc70c1d57fa1aadc7
 +F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
 +F src/pager.c 23c0f17deb892da6b32fef1f465507df7ab5cd01d774288cb43695658a649259
 +F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
 +F src/parse.y 619c3e92a54686c5e47923688c4b9bf7ec534a4690db5677acc28b299c403250
  F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
  F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 -F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
 -F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684
 -F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
 -F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
 -F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9
 +F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
 +F src/pragma.c 30b535d0a66348df844ee36f890617b4cf45e9a22dcbc47ec3ca92909c50aaf1
 +F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126
 +F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113
  F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
- F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64
 -F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804
++F src/resolve.c 9583e6eb8066400d377db9b130ebf46d461b59fccf1d018a5010d55b9bea217c
  F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
- F src/select.c fc2fe502971df1205a3231d3b3c8b0cc9ed4779cecbd060952c9558e22b6b02d
 -F src/select.c cb28a79bda149b1a1c80797795c1249c6ae8c1a392a6a96ac4cb7c881757c385
 -F src/shell.c.in 44c02fd1581d95e066b479241e081f37dc95c98452badd03627ef2a1c21bdc80
 -F src/sqlite.h.in 1ad9110150773c38ebababbad11b5cb361bcd3997676dec1c91ac5e0416a7b86
 -F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 -F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
 -F src/sqliteInt.h 146e1f57a480efff0bb17a2c61a66b61fe0b6b93b76958b2aeeac56c44190fb7
 -F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
 -F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
++F src/select.c 30d7e450179a123c2a4dd9000592da196f5a6766688773cb11b921294afa11bf
 +F src/shell.c.in 4f14a1f5196b6006abc8e73cc8fd6c1a62cf940396f8ba909d6711f35f074bb6
 +F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693
 +F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 +F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
- F src/sqliteInt.h 005542f8760edf9b62f014abccb876cf64533b64475a40a89402054d62535288
++F src/sqliteInt.h fcb2fd7eb47f6731ca8d4cbfbada95f24665bcc8a5ec44e2d24942220eb32453
 +F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
 +F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
  F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 -F src/tclsqlite.c 8e86ab2595c2ff7bb155331fb173e560180235bceaacce7931a718b1c2e6dfb4
 -F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262
 -F src/test1.c 51159784f29d3dfd4b50fd6ed9c43c8f7f36925c501a3ad3083528e5e5544bd7
 -F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
 -F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
 -F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
 -F src/test5.c bb87279ed12e199486894e6c83e58dc8cd1de9524ace171d59219d3ab696a0c1
 -F src/test6.c 763b92489f11f4a77b773f0d3b8369ab0edd5292ac794043062c337019f12d8a
 +F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036
 +F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
 +F src/test1.c 13cc07851f989141b29f7ca3c6c90f6d18f90081ab423c66716c8cb29d277d1f
 +F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
 +F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
 +F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
 +F src/test5.c 38fa635a70a94f2aa8b47ecbab15d821386205d27ad4159c3551ab3ba45efa11
 +F src/test6.c 9722054d37257459f1b8988e59e7db1dd630bfb291f16b2759764e778a9d1899
  F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0
 -F src/test9.c 7a708ad27f8fda79113e5e15de66632710958c401e64c2f22bc04e2f5a7a1b62
 -F src/test_async.c 0101173cf8137ba5473a84a695281fa9dedc2a1d155998c68623f2978017ad98
 +F src/test9.c df9ddc7db6ef1b8cf745866ee229090779728bcbe660c7f297d3127ab21d92af
  F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f
 -F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d9719a7
 +F src/test_backup.c a2bfd90d2ff2511b8635507bdb30fa9b605ade19c16b533066cae3077f5bdb72
  F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6
 -F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5
 +F src/test_blob.c 77b994e17f2c87055f44fd96c9a206c5a7155bae2cda2769af60c2f3582f962c
  F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5
 -F src/test_config.c 46eaf39842cace9d540aeefb50fe24dd3204a622893a97952cbb49c20b2f8b21
 -F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f
 +F src/test_config.c 7f412406592794636d6226268e26d413850a9f799bc5f3c01afc2820b165fca8
 +F src/test_delete.c d0e8f6dc55cfc98a7c27c057fb88d512260564bf0b611482656c68b8f7f401ed
  F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383
  F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86
 -F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5
 -F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851
 -F src/test_hexio.c af6db9300edd2d7b786a2d40d64177cad4b8ee22085e8ca5fe812cdeffdb6502
 -F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e
 -F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5
 +F src/test_fs.c a946408c81231feff4b6a2c18068f20aefe254dc82288687128af8b7520d32cb
 +F src/test_func.c 858d4dddb7acf88222ebcba7cffb585f6dde83e4a15b838c0d05ccdf8d5219b9
 +F src/test_hexio.c a90baa0a8ab5e7cfe2216a61c9a31cfd1f8378353a3d23e25fa94c09aa755bb0
 +F src/test_init.c 1649e02448f536e53172f6b1ff873254fe9a0c6c8a4502a2d25c0cc7b11945ea
 +F src/test_intarray.c 3fcf8ca7bb5c8776ea83f6aa9b66f8df0d1f37a99207b0097c8486f9c15cedbf
  F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293
  F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287
  F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
@@@ -844,37 -822,37 +844,37 @@@ F src/test_vfs.c b4135c1308516adf0dfd49
  F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
  F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
  F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 -F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68
 -F src/treeview.c 774838df4e25956ca34ff79bef150266412cfc2640620d04e22d5c8a55a98992
 -F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f
 -F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7
 -F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65
 -F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
 -F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375
 -F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
 -F src/vdbe.c de13de572eccb688b2b7cf50e2f9005c44bf9ae89e35245ef8eadfc60dfd2764
 -F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
 -F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
 -F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df
 -F src/vdbeaux.c 25d685cafe119ff890c94345e884ea558a6b5d823bfa52ba708eb8ff3c70aa71
 -F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
 -F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89
 -F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547
 +F src/tokenize.c 3e37ac2b6cbb9b0abe33827b0153c27595269afd7152b48019808974481aca2c
 +F src/treeview.c d85ce76e6d1498d781957c07cb234da6d77ce0ed2d196480d516f54dabc62279
 +F src/trigger.c 3ffb8ed6b64dbcc0ccae6e82435d01be3bf547e13b814e2d46f7df9bef84748e
 +F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
 +F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 +F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
 +F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
 +F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
 +F src/vdbe.c e505b8b879a330e8dafbe3ed9582eae2fc671b44a64748d1b58c07e4e0f527da
 +F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958
 +F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e
 +F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df
 +F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7
 +F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd
 +F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21
 +F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe
  F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
  F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
 -F src/vtab.c 5fb499d20494b7eecaadb7584634af9afcb374cb0524912b475fcb1712458a1b
 +F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859
  F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 -F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
 +F src/wal.c 20be6f0a25a80b7897cf2a5369bfd37ef198e6f0b6cdef16d83eee856056b159
  F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 -F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
 -F src/where.c d87a4160e26a7a96a2f7ca283b147b1b283b54ba545c46acb14cfcc6ec37ae9e
 -F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65
 -F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c
 -F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290
 -F src/window.c 1e40ffc509bae21e466f6106382d238e91eb73edd4ba10e66ca4fd7af2b96896
 +F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
- F src/where.c b11e56a24d01ae9b293f702c9de6dd16ced6b886be0d7cccb8bdeb62c8d92362
++F src/where.c 458b2089adc9ad65b2585fdf705b716e74abef146f20472962368cd784898f65
 +F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
- F src/wherecode.c 504f3c1270c3ffd51ebcdf7a31de08aa51a63b33a2ccdf8f5736afe3dfa73d45
++F src/wherecode.c 2917e70e12f7b238285240e564329374f20e4270fe90c36e0d19b6770754a7c4
 +F src/whereexpr.c 566ca4382e07a4ba1fd86c97ae0781cdf84004c7d9c59466bf5db75733548807
 +F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5
  F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 -F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
 -F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
 +F test/affinity2.test 4d7a34d328e58ca2a2d78fd76c27614a41ca7ddf4312ded9c68c04f430b3b47d
 +F test/affinity3.test 9b7d1133e11d5edd7805573c4ab6f3ba73b0b74a1f280d5b130d4bf3506a93ff
  F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
  F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829
  F test/aggnested.test 610b0ce2c3e8f3daee25f9752800ee8d785db10da4aa1fbeea0ea1aabaf1d704
@@@ -1127,20 -1107,22 +1127,23 @@@ F test/e_walauto.test 248af31e73c98df23
  F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0
  F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66
  F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62
 -F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a
 -F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec
 +F test/enc.test b5503a87b31cea8a5084c6e447383f9ca08933bd2f29d97b6b6201081b2343eb
 +F test/enc2.test 872afe58db772e7dfa1ad8e0759f8cc820e9efc8172d460fae83023101c2e435
  F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087
  F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020
- F test/eqp.test 82f221e8cd588434d7f3bba9a0f4c78cbe7a541615a41632e12f50608bfb4a99
 -F test/eqp.test 815418b69f6be3a27037b1736c54699c72cc3e2e6b0bc878c01464d1dcec65fe
++F test/eqp.test 800fb69fae9086b76dc767931a9973355187d673f69cd2ccfd3c455528af7859
  F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd
  F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9
 +F test/errofst1.test 6da78363739ba8991f498396ab331b5d64e7ab5c4172c12b5884683ef523ac53
  F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0
  F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747
  F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e
  F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
  F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
 -F test/existsexpr.test bf1201621070e79c1060c1a8cf7d65d81fc6b336d94a371c63ecb08d357af2fd
++F test/existsexpr.test d87e7ee394935f9b4a9a1a488f3faa55abd20dd85152efaf2034881a079c7ba1
+ F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11
+ F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e
 -F test/expr.test 5c06696478212e5a04e04b043f993373f6f8e5ce5a80f5548a84703b123b6caa
 +F test/expr.test 4ada8eb822c45ef27a36851a258004d43c1e95e7c82585a1217e732084e4482c
  F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8
  F test/exprfault.test da33606d799718e2f8e34efd0e5858884a1ad87f608774c552a7f5517cc27181
  F test/exprfault2.test c49e84273898969af5dbc4fe6a3f4335f14639799f343590336c9ddf84425965
@@@ -1385,11 -1364,11 +1388,11 @@@ F test/jrnlmode3.test 556b447a05be0e096
  F test/json/README.md de59d5ba0bd2796d797115688630a6405bbf43a2891bad445ac6b9f38b83f236
  F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
  F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307
 -F test/json/json-speed-check.sh 912ee03e700a65c827ee0c7b4752c21ec5ef69cf7679d2f482ca817042bead52 x
 +F test/json/json-speed-check.sh 7d5898808ce7542762318306ae6075a30f5e7ee115c4a409f487e123afe91d88 x
  F test/json/jsonb-q1.txt 1e180fe6491efab307e318b22879e3a736ac9a96539bbde7911a13ee5b33abc7
- F test/json101.test 8237a484c256965eab1678fd950a32ac56325bb7d0dadbd095a46b0ddd95d62b
 -F test/json101.test 30db5b055b103ccabc53a29cfe6cda3345d07e171aeb25403dafa04f19e98b19
 -F test/json102.test 4b3a0f94535f033239b67c13dbee8b47d2b5ee467e0f2fdab5eadf370bbe5fd3
 -F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
++F test/json101.test cf53254f0f0c1399a01b21fc58fee0e63a12a556be91b9ee9faccdb8b82c083c
 +F test/json102.test 9b2e5ada10845ff84853b3feaae2ce51ce7145ae458f74c6a6cecc6ef6ee3ae1
 +F test/json103.test 355746a6b66aa438f214b4fae454b13068fad2444b5f693e0d538ad1c059b264
  F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
  F test/json105.test 043838b56e68f3252a0dcf5be1689016f6f3f05056f8dcfcdc9d074f4d932988
  F test/json106.test 4aed3afd16549045d198a8d9cea00deea96e1f2ecf55864dce96cac558b8abef
@@@ -1494,7 -1473,7 +1497,7 @@@ F test/notify1.test 669b2b743618efdc18c
  F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
  F test/notify3.test 796c7b7157f55c93b4e672b724e9c923a6fc6aa72ac419379a623e2350472e22
  F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18
--F test/notnull2.test 2ac7b4e04917148c7a1a9ed36df20150175ce942f07f5714375b29acbaca7106
++F test/notnull2.test 5b7dd6e82c409b2d011ad6acf19ae4bf0816a9c69ccf600b529d7405d7c49874
  F test/notnullfault.test fc4bb7845582a2b3db376001ef49118393b1b11abe0d24adb03db057ee2b73d5
  F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f
  F test/nulls1.test 7a5e4346ee4285034100b4cd20e6784f16a9d6c927e44ecdf10034086bbee9c9
@@@ -2206,10 -2180,31 +2209,10 @@@ F tool/vdbe-compress.tcl fa2f37ab39b2a0
  F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e
  F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
  F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 -F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 +F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
  F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
- P eaad6ac707a5960d9518d4049b7b1759e7512727ce87be3c402408144bda0a97
- R 19ae64c3af637e68252816fb2a35fc7d
 -F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85
 -F vsixtest/App.xaml.cpp 41158ee43269820136fa3bba00c0bd91b26cc38b650ee392aec2a8d823e54318
 -F vsixtest/App.xaml.h 4a9768e2983d05600ad1e1c2f1b00a132967da9f
 -F vsixtest/Assets/LockScreenLogo.scale-200.png e820c9a3deb909197081b0bf3216c06e13905f0a
 -F vsixtest/Assets/SplashScreen.scale-200.png cab70988ca71bebec7bfeb3b6dbafe17b9ab0b4a
 -F vsixtest/Assets/Square150x150Logo.scale-200.png e17b40817db7a239fc239d83efcc951fb824e3ff
 -F vsixtest/Assets/Square44x44Logo.scale-200.png 2f166237094dea94d952d10b9eeae81806844f1c
 -F vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png 5f6a6d391b95a3061ccca6e6fdd6955ede63b4ed
 -F vsixtest/Assets/StoreLogo.png 0828b7257db74a4ecd5eeb6b7b4971f0fdc4d9d1
 -F vsixtest/Assets/Wide310x150Logo.scale-200.png 04ddefe5bc5f43ae12a7433f6f236ddab101ac42
 -F vsixtest/MainPage.xaml 34f49897e3ca533a7e74506ba0759b66eebce151
 -F vsixtest/MainPage.xaml.cpp 7f31fc6de751b64676c0924c97a5485d950a91d7
 -F vsixtest/MainPage.xaml.h cc05cca10d50a003f6c6e4448b701cdd07f52f29
 -F vsixtest/Package.appxmanifest 6b6db1eb7df3a315c5d681059754d5f0e0c47a93
 -F vsixtest/pch.cpp cb823cfac36f1a39a7eb0acbd7e9a0b0de8f23af
 -F vsixtest/pch.h 9cab7980f2ac4baa40807d8b5e52af32a21cf78c
 -F vsixtest/vsixtest.sln 77cadbe4e96c1fe1bf51cd77de9e9b0a12ada547
 -F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080bb302912
 -F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 -F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 -F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
 -P fc643f8a12e9b7448136b281f798e18dfebe0a3df5115d930b965c8a33933e2d ea9d88f9ca3399bca83bf03893689a927b73e481604b94527e42de43f103eb46
 -R 9c00435044c1639ccc94034122bfb21c
++P ff593a16d61cc5c588d1737deb822abb90b1759475a4cabfcf608978b1191487 9084a4c8726a2c7ba1c381886e29c7b86121d531282be0d63d5988d84f6f448d
++R f60eba1acfa64dc97c08e5ab9333e9b4
  U drh
- Z 04fda6f3c6a7b8123cd1480694a7568d
 -Z 82c98548b7e1b613f913739aef63c0fc
++Z 4c3d6c95c910f93bc2abb148fe548800
  # Remove this line to create a well-formed Fossil manifest.
diff --cc manifest.uuid
index faaf6064f7c59be0b24756218263d8634694d04e,3b6545ee37bab27889b9fae65986320251a3e7d5..70909c9c3eb8982d6503c81b996f5eb7040f7e27
@@@ -1,1 -1,1 +1,1 @@@
- ff593a16d61cc5c588d1737deb822abb90b1759475a4cabfcf608978b1191487
 -9084a4c8726a2c7ba1c381886e29c7b86121d531282be0d63d5988d84f6f448d
++1c1aef2b7feae29066d0330699ab634ef41f5b60cdcd479a60cb1a5409553138
diff --cc src/build.c
Simple merge
diff --cc src/resolve.c
Simple merge
diff --cc src/select.c
index d35103cddf7a2f3107ab1f385900a8f2ec621702,6a4d0397f8f8b36a779bc8cd46a1821eb7bb8611..fd99dc91fe6acb541ef5040f9703150feb99184d
@@@ -384,7 -359,7 +384,7 @@@ static int tableAndColumnIndex
    int iEnd,            /* Last member of pSrc->a[] to check */
    const char *zCol,    /* Name of the column we are looking for */
    int *piTab,          /* Write index of pSrc->a[] here */
--  int *piCol,          /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
++  int *piCol,          /* Write index of pSrc->a[*piTab].pSTab->aCol[] here */
    int bIgnoreHidden    /* Ignore hidden columns */
  ){
    int i;               /* For looping over tables in pSrc */
@@@ -4658,10 -4590,10 +4658,10 @@@ static int flattenSubquery
    ** complete, since there may still exist Expr.pTab entries that
    ** refer to the subquery even after flattening.  Ticket #3346.
    **
--  ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
++  ** pSubitem->pSTab is always non-NULL by test restrictions and tests above.
    */
 -  if( ALWAYS(pSubitem->pTab!=0) ){
 -    Table *pTabToDel = pSubitem->pTab;
 +  if( ALWAYS(pSubitem->pSTab!=0) ){
 +    Table *pTabToDel = pSubitem->pSTab;
      if( pTabToDel->nTabRef==1 ){
        Parse *pToplevel = sqlite3ParseToplevel(pParse);
        sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
@@@ -5771,7 -5692,7 +5771,7 @@@ With *sqlite3WithPush(Parse *pParse, Wi
  ** CTE expression, through routine checks to see if the reference is
  ** a recursive reference to the CTE.
  **
--** If pFrom matches a CTE according to either of these two above, pFrom->pTab
++** If pFrom matches a CTE according to either of these two above, pFrom->pSTab
  ** and other fields are populated accordingly.
  **
  ** Return 0 if no match is found.
@@@ -7398,8 -7295,165 +7398,76 @@@ static int fromClauseTermCanBeCoroutine
    return 1;
  }
  
 -/*
 -** sqlite3WalkExpr() callback used by exprReferencesTable().
 -*/
 -static int exprReferencesTableExprCb(Walker *pWalker, Expr *pExpr){
 -  if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.iCur ){
 -    pWalker->eCode = 1;
 -  }
 -  return WRC_Continue;
 -}
 -
 -/*
 -** Return true if the expression passed as the first argument refers
 -** to cursor number iCur. Otherwise return false.
 -*/
 -static int exprReferencesTable(Expr *pExpr, int iCur){
 -  Walker w;
 -  memset(&w, 0, sizeof(w));
 -  w.u.iCur = iCur;
 -  w.xExprCallback = exprReferencesTableExprCb;
 -  w.xSelectCallback = sqlite3SelectWalkNoop;
 -  sqlite3WalkExpr(&w, pExpr);
 -  return w.eCode;
 -}
 -
 -/*
 -** Index pIdx is a UNIQUE index on the table accessed by cursor number 
 -** iCsr. This function returns a mask of the index columns that are
 -** constrained to match a single, non-NULL value by the WHERE clause
 -** passed as the 4th argument. For example, if the index is:
 -**
 -**      CREATE UNIQUE INDEX idx ON tbl(a, b, c);
 -**
 -** and pWhere:
 -**
 -**      WHERE a=? AND c=?
 -**
 -** then this function returns 5.
 -*/
 -static u64 findConstIdxTerms(
 -  Parse *pParse, 
 -  int iCsr,
 -  Index *pIdx, 
 -  Expr *pWhere
 -){
 -  u64 m = 0;
 -  if( pWhere->op==TK_AND ){
 -    m = findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pLeft);
 -    m |= findConstIdxTerms(pParse, iCsr, pIdx, pWhere->pRight);
 -  }else if( pWhere->op==TK_EQ ){
 -    Expr *pLeft = sqlite3ExprSkipCollateAndLikely(pWhere->pLeft);
 -    Expr *pRight = sqlite3ExprSkipCollateAndLikely(pWhere->pRight);
 -    if( pRight->op==TK_COLUMN && pRight->iTable==iCsr ){
 -      SWAP(Expr*, pLeft, pRight);
 -    }
 -    if( pLeft->op==TK_COLUMN 
 -     && pLeft->iTable==iCsr 
 -     && exprReferencesTable(pRight, iCsr)==0
 -    ){
 -      if( pIdx ){
 -        int ii;
 -        for(ii=0; ii<pIdx->nKeyCol; ii++){
 -          assert( pIdx->azColl[ii] );
 -          if( pLeft->iColumn==pIdx->aiColumn[ii] ){
 -            CollSeq *pColl = sqlite3ExprCompareCollSeq(pParse, pWhere);
 -            if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[ii])==0 ){
 -              m |= ((u64)1 << ii);
 -              break;
 -            }
 -          }
 -        }
 -      }else{
 -        if( pLeft->iColumn<0 ) m = 1;
 -      }
 -    }
 -  }
 -  return m;
 -}
 -
+ /*
+ ** Argument pWhere is the WHERE clause belonging to SELECT statement p. This
+ ** function attempts to transform expressions of the form:
+ **
+ **     EXISTS (SELECT ...)
+ **
+ ** into joins. For example, given
+ **
+ **    CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT);
+ **    CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day));
+ **
+ **    SELECT name FROM sailors AS S WHERE EXISTS (
+ **      SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25'
+ **    );
+ **
+ ** the SELECT statement may be transformed as follows:
+ **
+ **    SELECT name FROM sailors AS S, reserves AS R
+ **      WHERE S.sid = R.sid AND R.day = '2022-10-25';
+ */
 -static void existsToJoin(Parse *pParse, Select *p, Expr *pWhere){
++static SQLITE_NOINLINE void existsToJoin(
++  Parse *pParse,
++  Select *p,
++  Expr *pWhere
++){
+   if( pWhere 
+    && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) 
+    && p->pSrc->nSrc>0
+    && p->pSrc->nSrc<BMS
+    && pParse->db->mallocFailed==0 
+   ){
+     if( pWhere->op==TK_AND ){
+       Expr *pRight = pWhere->pRight;
+       existsToJoin(pParse, p, pWhere->pLeft);
+       existsToJoin(pParse, p, pRight);
+     }
+     else if( pWhere->op==TK_EXISTS ){
+       Select *pSub = pWhere->x.pSelect;
+       if( pSub->pSrc->nSrc==1 
+        && (pSub->selFlags & (SF_Aggregate|SF_Correlated))==SF_Correlated
+        && pSub->pWhere
+       ){
 -        int bTransform = 0;       /* True if EXISTS can be made into join */
 -        Table *pTab = pSub->pSrc->a[0].pTab;
 -        int iCsr = pSub->pSrc->a[0].iCursor;
 -        Index *pIdx;
 -        if( HasRowid(pTab) && findConstIdxTerms(pParse, iCsr, 0,pSub->pWhere) ){
 -          bTransform = 1;
 -        }
 -        for(pIdx=pTab->pIndex; pIdx && bTransform==0; pIdx=pIdx->pNext){
 -          if( pIdx->onError && pIdx->nKeyCol<=63 ){
 -            u64 c = findConstIdxTerms(pParse, iCsr, pIdx, pSub->pWhere);
 -            if( c==((u64)1 << pIdx->nKeyCol)-1 ){
 -              bTransform = 1;
 -            }
 -          }
 -        }
 -        if( bTransform ){
 -          memset(pWhere, 0, sizeof(*pWhere));
 -          pWhere->op = TK_INTEGER;
 -          pWhere->u.iValue = 1;
 -          ExprSetProperty(pWhere, EP_IntValue);
 -
 -          assert( p->pWhere!=0 );
 -          p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc);
 -          p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere);
 -
 -          pSub->pWhere = 0;
 -          pSub->pSrc = 0;
 -          sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
++        memset(pWhere, 0, sizeof(*pWhere));
++        pWhere->op = TK_INTEGER;
++        pWhere->u.iValue = 1;
++        ExprSetProperty(pWhere, EP_IntValue);
++
++        assert( p->pWhere!=0 );
++        pSub->pSrc->a[0].fg.fromExists = 1;
++        pSub->pSrc->a[0].fg.jointype |= JT_CROSS;
++        p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc);
++        p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSub->pWhere);
++
++        pSub->pWhere = 0;
++        pSub->pSrc = 0;
++        sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub);
+ #if TREETRACE_ENABLED
 -          if( sqlite3TreeTrace & 0x100000 ){
 -            TREETRACE(0x100000,pParse,p,
 -                      ("After EXISTS-to-JOIN optimization:\n"));
 -            sqlite3TreeViewSelect(0, p, 0);
 -          }
 -#endif
++        if( sqlite3TreeTrace & 0x100000 ){
++          TREETRACE(0x100000,pParse,p,
++                    ("After EXISTS-to-JOIN optimization:\n"));
++          sqlite3TreeViewSelect(0, p, 0);
+         }
++#endif
+       }
+     }
+   }
+ }
  /*
 -** Generate code for the SELECT statement given in the p argument. 
 +** Generate byte-code for the SELECT statement given in the p argument. 
  **
  ** The results are returned according to the SelectDest structure.
  ** See comments in sqliteInt.h for further information.
@@@ -7766,10 -7781,17 +7834,17 @@@ int sqlite3Select
    }
  #endif
  
+   /* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt
+   ** to change it into a join.  */
+   if( pParse->bHasExists && OptimizationEnabled(db,SQLITE_ExistsToJoin) ){
+     existsToJoin(pParse, p, p->pWhere);
+     pTabList = p->pSrc;
+   }
    /* Do the WHERE-clause constant propagation optimization if this is
 -  ** a join.  No need to speed time on this operation for non-join queries
 +  ** a join.  No need to spend time on this operation for non-join queries
    ** as the equivalent optimization will be handled by query planner in
 -  ** sqlite3WhereBegin().
 +  ** sqlite3WhereBegin().  tag-select-0330
    */
    if( p->pWhere!=0
     && p->pWhere->op==TK_AND
diff --cc src/sqliteInt.h
index 36a21d92ef765f53fa0ba54367b93724679b80b5,bfe0bf94bf5ecc1161d6374cae7ea653af1ec6fa..6ae456f595756ddd00992917b9a0a40500593cdc
@@@ -1153,7 -1129,7 +1153,8 @@@ extern u32 sqlite3TreeTrace
  **   0x00020000     Transform DISTINCT into GROUP BY
  **   0x00040000     SELECT tree dump after all code has been generated
  **   0x00080000     NOT NULL strength reduction
 -**   0x00100000     EXISTS-to-JOIN optimization
 +**   0x00100000     Pointers are all shown as zero
++**   0x00200000     EXISTS-to-JOIN optimization
  */
  
  /*
@@@ -1924,8 -1928,7 +1925,9 @@@ struct sqlite3 
  #define SQLITE_Coroutines     0x02000000 /* Co-routines for subqueries */
  #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
  #define SQLITE_OnePass        0x08000000 /* Single-pass DELETE and UPDATE */
 -#define SQLITE_ExistsToJoin   0x10000000 /* The EXISTS-to-JOIN optimization */
 +#define SQLITE_OrderBySubq    0x10000000 /* ORDER BY in subquery helps outer */
 +#define SQLITE_StarQuery      0x20000000 /* Heurists for star queries */
++#define SQLITE_ExistsToJoin   0x40000000 /* The EXISTS-to-JOIN optimization */
  #define SQLITE_AllOpts        0xffffffff /* All optimizations */
  
  /*
@@@ -3368,10 -3318,12 +3370,11 @@@ struct SrcItem 
      unsigned isSynthUsing :1;  /* u3.pUsing is synthesized from NATURAL */
      unsigned isNestedFrom :1;  /* pSelect is a SF_NestedFrom subquery */
      unsigned rowidUsed :1;     /* The ROWID of this table is referenced */
 +    unsigned fixedSchema :1;   /* Uses u4.pSchema, not u4.zDatabase */
 +    unsigned hadSchema :1;     /* Had u4.zDatabase before u4.pSchema */
++    unsigned fromExists :1;    /* Comes from WHERE EXISTS(...) */
    } fg;
    int iCursor;      /* The VDBE cursor number used to access this table */
 -  union {
 -    Expr *pOn;        /* fg.isUsing==0 =>  The ON clause of a join */
 -    IdList *pUsing;   /* fg.isUsing==1 =>  The USING clause of a join */
 -  } u3;
    Bitmask colUsed;  /* Bit N set if column N used. Details above for N>62 */
    union {
      char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
@@@ -3900,11 -3834,10 +3903,12 @@@ struct Parse 
    u8 disableLookaside; /* Number of times lookaside has been disabled */
    u8 prepFlags;        /* SQLITE_PREPARE_* flags */
    u8 withinRJSubrtn;   /* Nesting level for RIGHT JOIN body subroutines */
 -  u8 bHasWith;         /* True if statement contains WITH */
+   u8 bHasExists;       /* Has a correlated "EXISTS (SELECT ....)" expression */
    u8 mSubrtnSig;       /* mini Bloom filter on available SubrtnSig.selId */
 +  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
 +  u8 bReturning;       /* Coding a RETURNING trigger */
 +  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
 +  u8 disableTriggers;  /* True to disable triggers */
  #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
    u8 earlyCleanup;     /* OOM inside sqlite3ParserAddCleanup() */
  #endif
diff --cc src/where.c
index 4a0c3988cbd14b3ed34177daa2ef363412da8521,a9a258995606615e40f74a04504c038d7589151c..69b206a22ea4b56a5dabab3b4777a31583501332
@@@ -3518,6 -3456,6 +3518,7 @@@ static int whereLoopAddBtreeIndex
     && pProbe->hasStat1!=0
     && OptimizationEnabled(db, SQLITE_SkipScan)
     && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
++   && pSrc->fg.fromExists==0
     && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
    ){
      LogEst nIter;
@@@ -7397,6 -7144,6 +7398,9 @@@ void sqlite3WhereEnd(WhereInfo *pWInfo)
          sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
        }
  #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
++      if( pTabList->a[pLevel->iFrom].fg.fromExists ){
++        sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
++      }
        /* The common case: Advance to the next row */
        if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
        sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
diff --cc src/wherecode.c
index cc672aa83996fd5e8b2939f7417293fe786f42c1,098af7375ee9f1c66cbeb5c98e8eba4421bc6272..9c611001bbe160f84c46d2763fe18d8e7896a00a
@@@ -132,9 -135,7 +132,10 @@@ void sqlite3WhereAddExplainText
      int isSearch;                 /* True for a SEARCH. False for SCAN. */
      WhereLoop *pLoop;             /* The controlling WhereLoop object */
      u32 flags;                    /* Flags that describe this loop */
 +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
      char *zMsg;                   /* Text to add to EQP output */
 +#endif
++    const char *zFormat;
      StrAccum str;                 /* EQP output string */
      char zBuf[100];               /* Initial space for EQP output string */
  
  
      sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
      str.printfFlags = SQLITE_PRINTF_INTERNAL;
--    sqlite3_str_appendf(&str, "%s %S", isSearch ? "SEARCH" : "SCAN", pItem);
++    if( pItem->fg.fromExists ){
++      zFormat = "SINGLETON %S";
++    }else if( isSearch ){
++      zFormat = "SEARCH %S";
++    }else{
++      zFormat = "SCAN %S";
++    }
++    sqlite3_str_appendf(&str, zFormat, pItem);
      if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
        const char *zFmt = 0;
        Index *pIdx;
diff --cc test/eqp.test
index 5d2659be770a32130785feff735e4c65a525aad8,7da78665a9da92df40e31d473f2cadf033b27dbb..b7e7acd8a063a74decc571a99075f4b7070f9612
@@@ -338,8 -327,8 +338,7 @@@ det 3.3.3 
  } {
    QUERY PLAN
    |--SCAN t1
--  `--CORRELATED SCALAR SUBQUERY xxxxxx
--     `--SCAN t2
++  `--SINGLETON t2
  }
  
  #-------------------------------------------------------------------------
index 0000000000000000000000000000000000000000,81aa5799f047e689666d3939107b136263f2653e..51b9234b7f6d551cbf65b415420eae83ab7a834a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,428 +1,426 @@@
 -} {/SUBQUERY/}
+ # 2024 May 25
+ #
+ # The author disclaims copyright to this source code.  In place of
+ # a legal notice, here is a blessing:
+ #
+ #    May you do good and not evil.
+ #    May you find forgiveness for yourself and forgive others.
+ #    May you share freely, never taking more than you give.
+ #
+ #***********************************************************************
+ #
+ set testdir [file dirname $argv0]
+ source $testdir/tester.tcl
+ source $testdir/lock_common.tcl
+ set testprefix existsexpr
+ do_execsql_test 1.0 {
+   CREATE TABLE x1(a, b, PRIMARY KEY(a)) WITHOUT ROWID;
+   INSERT INTO x1 VALUES(1, 2), (3, 4), (5, 6);
+   CREATE INDEX x1b ON x1(b);
+   CREATE TABLE x2(x, y);
+   INSERT INTO x2 VALUES(1, 2), (3, 4), (5, 6);
+ }
+ do_execsql_test 1.1 {
+   SELECT 1 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=5)
+ } {1}
+ do_execsql_test 1.2 {
+   SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x)
+ } {1 2 3 4 5 6}
+ # With "a=x", the UNIQUE index means the EXIST can be transformed to a join.
+ # So no "SUBQUERY". With "b=x", the index is not UNIQUE and so there is a
+ # "SUBQUERY".
+ do_execsql_test 1.3.1 {
+   EXPLAIN QUERY PLAN
+   SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x)
+ } {~/SUBQUERY/}
+ do_execsql_test 1.3.2 {
+   EXPLAIN QUERY PLAN
+   SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE b=x)
 -do_execsql_test 2.5 {
++} {~/SUBQUERY/}
+ do_execsql_test 1.4.1 {
+   EXPLAIN QUERY PLAN
+   SELECT * FROM x2 WHERE x=1 AND EXISTS (SELECT 1 FROM x1 WHERE a=x)
+ } {~/SUBQUERY/}
+ do_execsql_test 1.4.2 {
+   EXPLAIN QUERY PLAN
+   SELECT * FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x) AND y=2
+ } {~/SUBQUERY/}
+ do_execsql_test 1.5 {
+   SELECT count(*) FROM x2 WHERE EXISTS (SELECT 1 FROM x1 WHERE a=x)
+ } {3}
+ #-------------------------------------------------------------------------
+ do_execsql_test 2.0 {
+   CREATE TABLE t1(a, b);
+   WITH s(i) AS (
+     SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000
+   ) INSERT INTO t1 SELECT i, i FROM s;
+   CREATE TABLE t2(c, d);
+   WITH s(i) AS (
+     SELECT 10 UNION ALL SELECT i+10 FROM s WHERE i<1000
+   ) INSERT INTO t2 SELECT i, i FROM s;
+ }
+ do_execsql_test 2.1 {
+   SELECT count(*) FROM t1;
+   SELECT count(*) FROM t2;
+ } {1000 100}
+ do_execsql_test 2.2 {
+   SELECT count(*) FROM t1, t2 WHERE a=c;
+ } {100}
+ do_execsql_test 2.3 {
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a)
+ } {100}
+ do_eqp_test 2.4 {
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a)
+ } {SCAN t1}
 -} {SCAN t1*SEARCH t2}
++do_execsql_test 2.4.0 {
+   CREATE UNIQUE INDEX t2c ON t2(c);
+   CREATE UNIQUE INDEX t1a ON t1(a);
+ }
+ do_eqp_test 2.4.1 {
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a);
 -} {SCAN t2*SEARCH t1}
++} {SCAN t1*SINGLETON t2}
+ do_execsql_test 2.4.2 {
+   ANALYZE;
+ }
+ do_eqp_test 2.4.3 {
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a);
 -do_subquery_test 3.4 1 {
++} {SCAN t1*SINGLETON t2}
+ do_execsql_test 2.4.4 {
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a);
+ } {100}
+ do_execsql_test 2.5.1 {
+   EXPLAIN QUERY PLAN
+   SELECT count(*) FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.rowid=a);
+ } {~/SUBQUERY/}
+ #-------------------------------------------------------------------------
+ proc do_subquery_test {tn bSub sql res} {
+   set r1(0) ~/SUBQUERY/
+   set r1(1) /SUBQUERY/
+   do_execsql_test $tn.1 "explain query plan $sql" $r1($bSub)
+   do_execsql_test $tn.2 $sql $res
+ }
+ do_execsql_test 3.0 {
+   CREATE TABLE y1(a, b, c);
+   CREATE TABLE y2(x, y, z);
+   CREATE UNIQUE INDEX y2zy ON y2(z, y);
+   INSERT INTO y1 VALUES(1, 1, 1);
+   INSERT INTO y1 VALUES(2, 2, 2);
+   INSERT INTO y1 VALUES(3, 3, 3);
+   INSERT INTO y1 VALUES(4, 4, 4);
+   INSERT INTO y2 VALUES(1, 1, 1);
+   INSERT INTO y2 VALUES(3, 3, 3);
+ }
+ do_subquery_test 3.1 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=a AND y=b AND x=z
+   )
+ } {
+   1 1 1          3 3 3
+ }    
+ do_subquery_test 3.2 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=max(a,b) AND y=min(b,a) AND x=z
+   )
+ } {
+   1 1 1          3 3 3
+ }    
+ do_subquery_test 3.3 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=max(a,b) AND y=min(b,a) AND c!=3
+   )
+ } {
+   1 1 1
+ }    
 -do_subquery_test 3.6 1 {
++do_subquery_test 3.4 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=max(a,b) AND b=3
+   )
+ } {
+   3 3 3
+ }    
+ do_subquery_test 3.5 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=a-1 AND y=a-1
+   )
+ } {
+   2 2 2
+   4 4 4
+ }    
 -do_subquery_test 4.2 1 {
++do_subquery_test 3.6 0 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 WHERE z=a-1 AND y+1=a
+   )
+ } {
+   2 2 2
+   4 4 4
+ }    
+ do_subquery_test 3.7 1 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT count(*) FROM y2 WHERE z=a-1 AND y=a-1
+   )
+ } {
+   1 1 1
+   2 2 2
+   3 3 3
+   4 4 4
+ }    
+ do_subquery_test 3.8 1 {
+   SELECT * FROM y1 WHERE EXISTS ( SELECT a+1 FROM y2 )
+ } {
+   1 1 1
+   2 2 2
+   3 3 3
+   4 4 4
+ }    
+ do_subquery_test 3.9 1 {
+   SELECT * FROM y1 WHERE EXISTS ( 
+       SELECT 1 FROM y2 one, y2 two WHERE one.z=a-1 AND one.y=a-1
+   )
+ } {
+   2 2 2
+   4 4 4
+ }    
+ #-------------------------------------------------------------------------
+ reset_db
+ do_execsql_test 4.0 {
+   CREATE TABLE tx1(a TEXT COLLATE nocase, b TEXT);
+   CREATE UNIQUE INDEX tx1ab ON tx1(a, b);
+   INSERT INTO tx1 VALUES('a', 'a');
+   INSERT INTO tx1 VALUES('B', 'b');
+   INSERT INTO tx1 VALUES('c', 'c');
+   INSERT INTO tx1 VALUES('D', 'd');
+   INSERT INTO tx1 VALUES('e', 'e');
+   CREATE TABLE tx2(x, y);
+   INSERT INTO tx2 VALUES('A', 'a');
+   INSERT INTO tx2 VALUES('b', 'b');
+   INSERT INTO tx2 VALUES('C', 'c');
+   INSERT INTO tx2 VALUES('D', 'd');
+ }
+ do_subquery_test 4.1 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x AND b=y
+   )
+ } {
+   A a
+   b b
+   C c
+   D d
+ }
+ do_subquery_test 4.1.1 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE (a COLLATE nocase)=x AND b=y
+   )
+ } {
+   A a   b b   C c   D d
+ }
+ do_subquery_test 4.1.2 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x AND (b COLLATE binary)=y
+   )
+ } {
+   A a   b b   C c   D d
+ }
+ do_subquery_test 4.1.1 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE x=(a COLLATE nocase) AND b=y
+   )
+ } {
+   A a   b b   C c   D d
+ }
+ do_subquery_test 4.1.2 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x AND y=(b COLLATE binary)
+   )
+ } {
+   A a   b b   C c   D d
+ }
 -do_subquery_test 4.4 1 {
++do_subquery_test 4.2 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x AND b=y COLLATE nocase
+   )
+ } {
+   A a
+   b b
+   C c
+   D d
+ }
+ do_execsql_test 4.3 {
+   DROP INDEX tx1ab;
+   CREATE UNIQUE INDEX tx1ab ON tx1(a COLLATE binary, b);
+ }
 -do_subquery_test 5.6 1 "
++do_subquery_test 4.4 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x AND b=y
+   )
+ } {
+   A a
+   b b
+   C c
+   D d
+ }
+ do_subquery_test 4.4 0 {
+   SELECT * FROM tx2 WHERE EXISTS (
+     SELECT 1 FROM tx1 WHERE a=x COLLATE binary AND b=y
+   )
+ } {
+   D d
+ }
+ do_subquery_test 4.4 1 {
+   SELECT EXISTS ( SELECT x FROM tx1 ) FROM tx2
+ } {
+   1 1 1 1
+ }
+ do_subquery_test 4.4 1 {
+   SELECT (SELECT EXISTS ( SELECT x FROM tx1 ) WHERE 1) FROM tx2
+ } {
+   1 1 1 1
+ }
+ #-------------------------------------------------------------------------
+ proc cols {s f} {
+   set lCols [list]
+   for {set i $s} {$i<=$f} {incr i} {
+     lappend lCols [format "c%02d" $i]
+   }
+   join $lCols ", "
+ }
+ proc vals {n val} {
+   set lVal [list]
+   for {set i 0} {$i<$n} {incr i} {
+     lappend lVal $val
+   }
+   join $lVal ", "
+ }
+ proc exprs {s f} {
+   set lExpr [list]
+   for {set i $s} {$i<=$f} {incr i} {
+     lappend lExpr [format "c%02d = o" $i]
+   }
+   join $lExpr " AND "
+ }
+ do_execsql_test 5.0 "
+   CREATE TABLE a1( [cols 0 99] );
+ "
+ do_execsql_test 5.1 "
+   -- 63 column index
+   CREATE UNIQUE INDEX a1idx1 ON a1( [cols 0 62] );
+ "
+ do_execsql_test 5.2 "
+   -- 64 column index
+   CREATE UNIQUE INDEX a1idx2 ON a1( [cols 10 73] );
+ "
+ do_execsql_test 5.2 "
+   -- 65 column index
+   CREATE UNIQUE INDEX a1idx3 ON a1( [cols 20 84] );
+ "
+ do_test 5.3 {
+   foreach v {1 2 3 4 5 6} {
+     execsql "INSERT INTO a1 VALUES( [vals 100 $v] )"
+   }
+ } {}
+ do_execsql_test 5.4 {
+   CREATE TABLE a2(o);
+   INSERT INTO a2 VALUES(2), (5); 
+ }
+ do_subquery_test 5.5 0 "
+   SELECT o FROM a2 WHERE EXISTS (
+     SELECT 1 FROM a1 WHERE [exprs 0 62]
+   )
+ " {
+   2 5
+ }
 -do_subquery_test 5.7 1 "
++do_subquery_test 5.6 0 "
+   SELECT o FROM a2 WHERE EXISTS (
+     SELECT 1 FROM a1 WHERE [exprs 10 73]
+   )
+ " {
+   2 5
+ }
 -
 -
++do_subquery_test 5.7 0 "
+   SELECT o FROM a2 WHERE EXISTS (
+     SELECT 1 FROM a1 WHERE [exprs 20 84]
+   )
+ " {
+   2 5
+ }
+ #-------------------------------------------------------------------------
+ reset_db
+ do_execsql_test 6.0 {
+   CREATE TABLE t1(a, b UNIQUE, c UNIQUE);
+   CREATE TABLE t2(a INfEGER PRIMARY KEY, b);
+   CREATE UNIQUE INDEX t2b ON t2(b);
+ }
+ do_catchsql_test 6.1 {
+   SELECT a FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c COLLATE f = a)
+ } {1 {no such collation sequence: f}}
+ #-------------------------------------------------------------------------
+ reset_db
+ do_execsql_test 7.0 {
+   CREATE TABLE t1(x);
+   CREATE TABLE t2(y UNIQUE);
+   INSERT INTO t1 VALUES(1), (2);
+   INSERT INTO t2 VALUES(1), (3);
+   SELECT * FROM t1 one LEFT JOIN t1 two ON (one.x=two.x AND EXISTS (
+     SELECT 1 FROM t2 WHERE y=one.x
+   ));
+ } {
+   1 1
+   2 {}
+ }
+ finish_test
index e22902f869b7bd01959fa3194314cf78df093df4,3963ffbb6bc259539950eb5b3eb1ccded9e46853..7582d14a64421412c8e21ff936e630bba45d0c04
@@@ -892,15 -892,15 +892,15 @@@ do_execsql_test json101-13.100 
    INSERT INTO t2(id,json) VALUES(4,'{"value":4}');
    INSERT INTO t2(id,json) VALUES(5,'{"value":5}');
    INSERT INTO t2(id,json) VALUES(6,'{"value":6}');
--  SELECT * FROM t1 CROSS JOIN t2
++  SELECT *, 'NL' FROM t1 CROSS JOIN t2
     WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z
                   WHERE Z.value==t2.id);
--} {1 {{"items":[3,5]}} 3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}}}
++} {1 {{"items":[3,5]}} 3 {{"value":3}} NL 1 {{"items":[3,5]}} 5 {{"value":5}} NL}
  do_execsql_test json101-13.110 {
--  SELECT * FROM t2 CROSS JOIN t1
++  SELECT *, 'NL' FROM t2 CROSS JOIN t1
     WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z
                   WHERE Z.value==t2.id);
--} {3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}} 1 {{"items":[3,5]}}}
++} {3 {{"value":3}} 1 {{"items":[3,5]}} NL 5 {{"value":5}} 1 {{"items":[3,5]}} NL}
  
  # 2018-05-16
  # Incorrect fullkey output from json_each()
index 09161efbdbf5f4dc016f083e386018bcab90055c,09161efbdbf5f4dc016f083e386018bcab90055c..67d7c26a8da7a68f9b6278987252a2c0ea6a19ed
@@@ -66,7 -66,7 +66,7 @@@ do_vmstep_test 1.5.2 
    SELECT count(*) FROM t2 WHERE EXISTS(
      SELECT 1 FROM t1 WHERE t1.a=450 AND t2.c IS NULL
    )
--} +8000 {0}
++} 4000 {0}
  
  #-------------------------------------------------------------------------
  reset_db