]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make CROSS JOIN a join reorder barrier again, as the SQLite documentation says it...
authordrh <>
Fri, 30 Jan 2026 17:10:22 +0000 (17:10 +0000)
committerdrh <>
Fri, 30 Jan 2026 17:10:22 +0000 (17:10 +0000)
mistakenly stopped being a join barrier with check-in [c1ea064948ba08c4].

FossilOrigin-Name: d294106ecb78d765305ab740007f4a678e28baa13ae403fe57ea9cbfc259620f

manifest
manifest.uuid
src/where.c
test/where2.test

index ea4319c89707b6074a119ab7f0165d0da5189ec4..aa0bc802d047fa6e6ee8b06576ed41c64e7611ba 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\snew\sCLI\sso\sthat\sthe\s".eqp"\ssetting\sdoes\snot\saffect\sthe\soutput\sof\sother\sdot\ncommands\ssuch\sas\s.schema\sor\s.tables.
-D 2026-01-30T16:03:22.503
+C Make\sCROSS\sJOIN\sa\sjoin\sreorder\sbarrier\sagain,\sas\sthe\sSQLite\sdocumentation\ssays\sit\sis.\s\sIt\nmistakenly\sstopped\sbeing\sa\sjoin\sbarrier\swith\scheck-in\s[c1ea064948ba08c4].
+D 2026-01-30T17:10:22.815
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -820,7 +820,7 @@ F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
 F src/wal.c 505a98fbc599a971d92cb90371cf54546c404cd61e04fd093e7b0c8ff978f9b6
 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
-F src/where.c 13ba955e83c92d60d7da92f22ffc332741c720638f149b0783f9de2446963c2d
+F src/where.c 4992c31e356b185a71bb3e9fc1ac6d747864240d5da4e81ec39b7ab38706332e
 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
 F src/wherecode.c 71c5c6804b7f882dec8ec858758accae02fcfca13df3cc720f1f258e663ec7c5
 F src/whereexpr.c cadb37fbaa2cb6d1ec1687923c3ac21aed4187d198f4500c00a01abb24c3cb44
@@ -2024,7 +2024,7 @@ F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9
 F test/walthread.test d562f51a61191ccfab64940df7aa1cef87c902fa5ab742590ef7f859dfe6a44b
 F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1
 F test/where.test 5087c72d26fd075a1644c8512be9fe18de9bf2d2b0754f7fd9b74a1c6540c4fc
-F test/where2.test 52237a8cb27ebbf6583469429bb5733d1b94ac37d09c3dbd0f487952ed0ab3f8
+F test/where2.test 1dbff4ab847068a52b927a0c1a7cf7faed4c8cae081fbcdac9b052a3a209aefa
 F test/where3.test 4ccb156ae33de86414a52775a6f590a9d60ba2cbc7a93a24fa331b7bcf5b6030
 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8
 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
@@ -2194,8 +2194,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 293ec20e29e46d822a98302f8a0ba52ad6f74a7e93f780536d393730c2edbf61
-R 6219427f72f1032a75f0a00a557f2be0
+P a5a1b69b3feedb507ecfe2e9ddc039d7c01e1bb54e3e881df5010481886cdef9
+R 2c69c84e0f52c569a5c3b3b4ea6a7f1a
 U drh
-Z 9a3047fdcb8c1ee9e50be3311ebce2d4
+Z fa98c5b69b350e02a0236ff7a868f9da
 # Remove this line to create a well-formed Fossil manifest.
index 6b3edb18fbe32ac6d90be63a934774c7c92b6786..37ae2bd790107473a3509df49f5b94171e5a9fff 100644 (file)
@@ -1 +1 @@
-a5a1b69b3feedb507ecfe2e9ddc039d7c01e1bb54e3e881df5010481886cdef9
+d294106ecb78d765305ab740007f4a678e28baa13ae403fe57ea9cbfc259620f
index 141746fbbc9a8b7372b5dcf32d22929a6d2ebe89..4c367f65575fb55375ff3c4a0a13704e6ddeeec9 100644 (file)
@@ -4849,7 +4849,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
   sqlite3 *db = pWInfo->pParse->db;
   int rc = SQLITE_OK;
   int bFirstPastRJ = 0;
-  int hasRightJoin = 0;
+  int hasRightCrossJoin = 0;
   WhereLoop *pNew;
 
 
@@ -4876,12 +4876,20 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
       ** prevents the right operand of a RIGHT JOIN from being swapped with
       ** other elements even further to the right.
       **
-      ** The JT_LTORJ case and the hasRightJoin flag work together to
-      ** prevent FROM-clause terms from moving from the right side of
-      ** a LEFT JOIN over to the left side of that join if the LEFT JOIN
-      ** is itself on the left side of a RIGHT JOIN.
+      ** The hasRightCrossJoin flag prevent FROM-clause terms from moving
+      ** from the right side of a LEFT JOIN or CROSS JOIN over to the
+      ** left side of that same join.  This is a required restriction in
+      ** the case of LEFT JOIN - an incorrect answer may results if it is
+      ** not enforced.  This restriction is not required for CROSS JOIN.
+      ** It is provided merely as a means of controlling join order, under
+      ** the theory that no real-world queries that care about performance
+      ** actually use the CROSS JOIN syntax.
       */
-      if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1;
+      if( pItem->fg.jointype & (JT_LTORJ|JT_CROSS) ){
+        testcase( pItem->fg.jointype & JT_LTORJ );
+        testcase( pItem->fg.jointype & JT_CROSS );
+        hasRightCrossJoin = 1;
+      }
       mPrereq |= mPrior;
       bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
     }else if( pItem->fg.fromExists ){
@@ -4895,7 +4903,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
           mPrereq |= (pTerm->prereqAll & (pNew->maskSelf-1));
         }
       }
-    }else if( !hasRightJoin ){
+    }else if( !hasRightCrossJoin ){
       mPrereq = 0;
     }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
index 83740bffdf98240038cd918fa8301132784bbaa7..6045cb11777cd47bbd18e3e64a5653073cf7e196 100644 (file)
@@ -794,4 +794,41 @@ do_execsql_test where2-15.1 {
    ORDER BY a,EXISTS(SELECT 1 FROM t1 LEFT JOIN (SELECT x AS y FROM t2) AS s2 ON t1.b=s2.y),x;
 } {12 34 NULL | 56 78 78 | 90 12 12 |}
 
+# Demonstrate that CROSS JOIN is a join reordering barrier.
+#
+reset_db
+do_execsql_test where2-16.1 {
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
+  CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT);
+  CREATE TABLE t3(e INTEGER PRIMARY KEY, f INT);
+  CREATE TABLE t4(g INTEGER PRIMARY KEY, h INT);
+}
+
+# Here the query planner wants to move t4 forward so that it is in front of
+# t1.  Ensure that does not happen.
+do_execsql_test where2-16.2 {
+  EXPLAIN QUERY PLAN
+  SELECT *
+    FROM t1, t2 CROSS JOIN t3, t4
+   WHERE t4.g=1
+     AND t1.a=t4.h
+     AND t2.c=t1.b
+     AND t3.e=t2.d;
+} {~/.* t4 .* t[12] .*/}
+
+# In this case the planner wants to move t1 to come after t4.  Ensure that
+# does not happen.
+do_execsql_test where2-16.2 {
+  EXPLAIN QUERY PLAN
+  SELECT *
+    FROM t1, t2 CROSS JOIN t3, t4
+   WHERE t2.c=1
+     AND t3.e=t2.d
+     AND t4.g=t3.f
+     AND t1.a=t4.h;
+} {~/.* t[34] .* t1 .*/}
+
+
+
+
 finish_test