-C Merge\svarious\sminor\scode\sand\sdocumentation\sfixes\sfrom\strunk\sinto\sthe\npatch\sbranch\sfor\s3.51.
-D 2025-11-13T11:34:38.886
+C Fix\sa\sproblem\sin\sthe\sEXISTS-to-JOIN\soptimization\sso\nthat\sit\sworks\swith\snested\sWHERE\sand\sEXISTS\sstatements.
+D 2025-11-13T11:42:16.192
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036
F src/tclsqlite.h 614b3780a62522bc9f8f2b9fb22689e8009958e7aa77e572d0f3149050af348a
-F src/test1.c d27c91455865fb191eb1b2c892e7586c5e3d9d3977f54913c8e70e2e8e5148b3
+F src/test1.c 5d061afe479c7364842e0170be7220dea13389575fa6030d30b3e20bec4e1f75
F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff
F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a
F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0
F src/wal.c 505a98fbc599a971d92cb90371cf54546c404cd61e04fd093e7b0c8ff978f9b6
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
-F src/where.c 7d17cd5cb883b2166097957e20c4aab2d0d98e0c1141002ef77b5f6b9deed844
+F src/where.c 1b554a868134cbc9ca2192385403c0b63e5073ff01a6cdd600a846c09f843165
F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
F src/wherecode.c 71c5c6804b7f882dec8ec858758accae02fcfca13df3cc720f1f258e663ec7c5
F src/whereexpr.c 403a44eeec1a0f0914fccc6a59376b6924bc00ef6728fe6ffce4cf3051b320fc
F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac
-F test/existsexpr.test 9c4b77c4729281cc2ae63b9b460d0598ce28cc7876135e3e2c21629bbc8d077a
+F test/existsexpr.test e4674fb8d610e82540126ed252e6aa48922882e1bcec6522d7e5a44fe715be61
F test/existsexpr2.test dc23e76389eff3d29f6488ff733012a3560cd67ec8cfaecbecd52cced5d5af11
F test/existsfault.test ff41c11f3052c1bbd4f8dd557802310026253d67d7c4e3a180c16d2f0862973e
F test/expr.test db981f8a85520e99ae20aab7ad2e9b5b0437ed09159b57ced434c672075d2e61
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1b908c439a4d2614cb6a4cec36d8d876eec68b1e2e80d6aad7e21d61d159df7d
-Q +36cd33f634a45900f6e52ba07aa20242a5f2b29c7cbe19be968c52ffef34fcde
-Q +45d820ca227eb1ade4dda498b0f94b2c5df4bab3fc5fcdd517ee125a43d16f4d
-Q +4954b94763052ed60ad2ae610e4f5c18fdba4475a39eb369408e984c89805e97
-Q +5f5a736f88bc9bc6c9c83d2cbfd74c0b5357d7417d9993d34a78f0b7317ff796
-Q +62ad2350e368dc337ba2d0fb6847d07c40a6f79520dd6414d22b5b54983b0b12
-Q +7a644178c8d289ca18631844b2d73b32fddc72afcc80906633dd38c14eba2ca9
-R 14565952030a019021e7f14d5b14445b
+P 9a00fe5eb69050ddc569d2a857309c2779a48414135f0967531999b7afd84283
+Q +d1e901eddc25175174d0706238ae0c33bfa5569e0c2ba4f1164b7a9600203442
+R 50310af12bdcc0c8ac9be14dcd737b8d
U drh
-Z e997942eb71c33e24bddc68463d572ec
+Z a55d2a43b6abbb44864f052cf9b0c30a
# Remove this line to create a well-formed Fossil manifest.
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);
+ if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
+ /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
+ ** loop(s) will be the inner-most loops of the join. There might be
+ ** multiple EXISTS loops, but they will all be nested, and the join
+ ** order will not have been changed by the query planner. If the
+ ** inner-most EXISTS loop sees a single successful row, it should
+ ** break out of *all* EXISTS loops. But only the inner-most of the
+ ** nested EXISTS loops should do this breakout. */
+ int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
+ while( nOuter<i ){
+ if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
+ nOuter++;
+ }
+ testcase( nOuter>0 );
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
+ VdbeComment((v, "EXISTS break"));
}
/* The common case: Advance to the next row */
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t0 LIMIT 0);
} {}
+#-------------------------------------------------------------------------
+reset_db
+
+do_execsql_test 9.0 {
+ CREATE TABLE t1(xx);
+ INSERT INTO t1 VALUES('big string value');
+} {}
+
+do_execsql_test 9.1 {
+ PRAGMA automatic_index = off;
+ CREATE TABLE t2(ii);
+ INSERT INTO t2 VALUES(100);
+ INSERT INTO t2 VALUES(200);
+}
+
+do_execsql_test 9.2 {
+ CREATE TABLE t3(yy);
+ INSERT INTO t3 VALUES(200);
+}
+
+do_execsql_test 9.3 {
+ SELECT 1 FROM t2 WHERE EXISTS ( SELECT 1 FROM t3 WHERE yy==t2.ii )
+} {1}
+
+do_execsql_test 9.4 {
+ SELECT EXISTS (
+ SELECT 1 FROM t2 WHERE EXISTS ( SELECT 1 FROM t3 WHERE yy==t2.ii )
+ )
+} {1}
+
+do_execsql_test 9.5 {
+ SELECT 1234 WHERE EXISTS (
+ SELECT 1 FROM t2 WHERE EXISTS ( SELECT 1 FROM t3 WHERE yy==t2.ii )
+ )
+} {1234}
+
+set Q {
+ SELECT * FROM t1 WHERE
+ EXISTS (
+ SELECT 1 FROM t2 WHERE EXISTS ( SELECT 1 FROM t3 WHERE yy==t2.ii )
+ )
+}
+
+do_execsql_test 9.5 $Q {{big string value}}
+catch { optimization_control db exists-to-join 0 }
+db cache flush
+do_execsql_test 9.6 $Q {{big string value}}
+
finish_test