]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a long-standing problem with DISTINCT LEFT JOIN queries.
authordan <Dan Kennedy>
Thu, 5 Mar 2026 14:39:27 +0000 (14:39 +0000)
committerdan <Dan Kennedy>
Thu, 5 Mar 2026 14:39:27 +0000 (14:39 +0000)
FossilOrigin-Name: f43294a5582b540a33c584ec8c69b6a5006a4d243ad5cf36125b2b0806e3518b

manifest
manifest.tags
manifest.uuid
src/where.c
test/distinct2.test

index ff582d3103c2ec290c039c1dbe017d04a3fb259f..49e7b5f812c3dcf22086c7a56f0cdfd9c58029ed 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sa\slittle\sflexibility\sto\scheckpoint\ssizes\sin\sthe\swalrestart.test\sscript.
-D 2026-03-05T00:30:05.130
+C Fix\sa\slong-standing\sproblem\swith\sDISTINCT\sLEFT\sJOIN\squeries.
+D 2026-03-05T14:39:27.298
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -811,7 +811,7 @@ F src/vxworks.h 9d18819c5235b49c2340a8a4d48195ec5d5afb637b152406de95a9436beeaeab
 F src/wal.c 88d94fd15a75f6eda831fa32d1148a267ea37bf0a4b69829a73dfde06244b08f
 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
-F src/where.c 9f09ee7b260010138d5f9fb5f195b98051119eae3096a99d72ff16c83230f4af
+F src/where.c d17b2ed5977d823bf0af8e78a029c05539b82f350cdf07e3427c288ce655e4ab
 F src/whereInt.h 8d94cb116c9e06205c3d5ac87af065fc044f8cf08bfdccd94b6ea1c1308e65da
 F src/wherecode.c 783ecd30061c875c919a5163e4b55f9a0eccdaf7c9b17ad2908a1668a8766bc4
 F src/whereexpr.c e9f7185fba366d9365aa7a97329609e4cf00b3dd0400d069fbaa5187350c17c6
@@ -1050,7 +1050,7 @@ F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad
 F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
 F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014
-F test/distinct2.test a6af6a90b2c1eea64c3cc87ea7f8feb832053f7276fe3c212abacf646de4762a
+F test/distinct2.test 072f33e1348b5cae4156e7ca4c124d21053f77d96d5d960a1ba21806416074ab
 F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f
 F test/dotcmd01.sql 0388a778912ed08436ae5c80e03389d8bd347fa724611193257a18c69692019d
 F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52
@@ -2189,8 +2189,11 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 61f8a28591a833b1f5834a347feefeba8414fecc7ff154f1b6ef19963f181812
-R ae5ae7b3ea3c5883e95986d59e781f25
-U drh
-Z 684be6d6a05353fa19523ecf503b665a
+P e438b564ca84377746464034d770e9c1f5899d935c6a4dffc546acb92afb800e
+R 0c0331354057ee00c385580cdf2cbb8e
+T *branch * pending-3.52
+T *sym-pending-3.52 *
+T -sym-trunk *
+U dan
+Z 2ed2ecdf12f98df5afd42bce2e836452
 # Remove this line to create a well-formed Fossil manifest.
index bec971799ff1b8ee641c166c7aeb22d12c785393..0249cadd8a708e16bc0a2a5697d853e3b8126379 100644 (file)
@@ -1,2 +1,2 @@
-branch trunk
-tag trunk
+branch pending-3.52
+tag pending-3.52
index 0ab5334eccc9feef86d842698d8c016fd104f26f..11ad8e3e34d808b5c9b1da4b122f7b7ad88a3671 100644 (file)
@@ -1 +1 @@
-e438b564ca84377746464034d770e9c1f5899d935c6a4dffc546acb92afb800e
+f43294a5582b540a33c584ec8c69b6a5006a4d243ad5cf36125b2b0806e3518b
index 2ef2ce0bee8e639642aa448b9279755cd5adde94..216a75c2332f14443cb0d8e9787610c95387aa52 100644 (file)
@@ -7554,6 +7554,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
       ){
         int r1 = pParse->nMem+1;
         int j, op;
+        int addrIfNull;
+        if( pLevel->iLeftJoin ){
+          addrIfNull = sqlite3VdbeAddOp2(v, OP_IfNullRow, pLevel->iIdxCur, r1);
+        }
         for(j=0; j<n; j++){
           sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j);
         }
@@ -7563,6 +7567,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
         VdbeCoverageIf(v, op==OP_SeekLT);
         VdbeCoverageIf(v, op==OP_SeekGT);
         sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
+        if( pLevel->iLeftJoin ){
+          sqlite3VdbeJumpHere(v, addrIfNull);
+        }
       }
 #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
     }
index 5de4d30940dca543012deff0128ac551a9195e05..a410d9abbfda13a4b11af24a638cbdc93ddff497 100644 (file)
@@ -380,4 +380,36 @@ do_execsql_test 5080 {
               );
 } 0
 
+#-------------------------------------------------------------------------
+# 2026-03-05 - do not "skip-ahead" of a null-row on the RHS of a 
+# LEFT JOIN.
+#
+reset_db
+
+do_execsql_test 6000 {
+  CREATE TABLE t1(c1 UNIQUE NOT NULL);
+  INSERT INTO t1 VALUES(1);
+  CREATE TABLE t0(c0 UNIQUE);
+  INSERT INTO t0 VALUES(0);
+  WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<1000)
+    INSERT INTO t0(c0) SELECT NULL FROM c;
+} {}
+
+do_execsql_test 6010 {
+  SELECT DISTINCT * FROM t1 LEFT OUTER JOIN t0 ON c0>c1;
+} {1 {}}
+
+do_execsql_test 6020 {
+  SELECT DISTINCT * FROM t1 FULL OUTER JOIN t0 ON c0>c1;
+} {1 {} {} 0 {} {}}
+
+do_execsql_test 6040 {
+  ANALYZE;
+  SELECT DISTINCT * FROM t1 LEFT OUTER JOIN t0 ON c0>c1;
+} {1 {}}
+
+do_execsql_test 6050 {
+  SELECT DISTINCT * FROM t1 FULL OUTER JOIN t0 ON c0>c1;
+} {1 {} {} 0 {} {}}
+
 finish_test