]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the empty-table optimization on INTERSECT so that it does not try to
authordrh <>
Wed, 9 Jul 2025 20:11:49 +0000 (20:11 +0000)
committerdrh <>
Wed, 9 Jul 2025 20:11:49 +0000 (20:11 +0000)
use an uninitialized register for LIMIT processing.

FossilOrigin-Name: 6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f

manifest
manifest.uuid
src/select.c

index 58cfe31140a51c7d7a19c7eee9d85039b11c4451..a8c30532d4681642f4549a3c9858b55d72701cdc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\spossible\suser-after\sfree\sfollowing\sOOM\sin\sthe\sEXISTS-to-JOIN\noptimization.
-D 2025-07-08T22:11:39.260
+C Fix\sthe\sempty-table\soptimization\son\sINTERSECT\sso\sthat\sit\sdoes\snot\stry\sto\nuse\san\suninitialized\sregister\sfor\sLIMIT\sprocessing.
+D 2025-07-09T20:11:49.196
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -785,7 +785,7 @@ F src/printf.c 71b6d3a0093bf23f473e25480ca0024e8962681506c75f4ffd3d343a3f0ab113
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c d3ee7ed308d46f4ee6d3bb6316d8d6f87158f93a7fd616732138cc953cf364f0
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 33a46f68191ac6cb00409417593adb03be68c8078d36ebe079a3a0914b220d93
+F src/select.c fc003cad96a105765261f7b6c5f4596e505894262bb5593cb29e10b682800d12
 F src/shell.c.in 73c0eeb7c265d59b99219d5aa055f412f07842088d8036b6d259927d85dd1bbf
 F src/sqlite.h.in 5c54f2461a1ea529bab8499148a2b238e2d4bb571d59e8ea5322d0c190abb693
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
@@ -2211,8 +2211,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 720387f8604f7cd997f1850ed62ce6ab32608155d7f02a89c695041caafc4067
-R 06654310fbfa0a3e107f5e62dfa928dd
+P 498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa
+R ebdf1d802e5dd88fbc80d28dd0639cd8
 U drh
-Z d3919178e62d3c6ffc666ec27b2d4fc8
+Z 51edd06328595496523194f72341809d
 # Remove this line to create a well-formed Fossil manifest.
index bedccbe899ed41e80d614de8832b5b19c9730e16..b9c5f04af2b3450c9824b0a345d46623ef7bc696 100644 (file)
@@ -1 +1 @@
-498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa
+6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f
index 99b05c76a35af3d55eee20e86aef1f0d5026dbc7..1b12663138b4c69dedce48c0691c45a14ce6c1ea 100644 (file)
@@ -3130,7 +3130,7 @@ static int multiSelect(
         int tab1, tab2;
         int iCont, iBreak, iStart;
         Expr *pLimit;
-        int addr;
+        int addr, iLimit, iOffset;
         SelectDest intersectdest;
         int r1;
         int emptyBypass;
@@ -3157,6 +3157,11 @@ static int multiSelect(
         if( rc ){
           goto multi_select_end;
         }
+
+        /* Initialize LIMIT counters before checking to see if the LHS
+        ** is empty, in case the jump is taken */
+        iBreak = sqlite3VdbeMakeLabel(pParse);
+        computeLimitRegisters(pParse, p, iBreak);
         emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v);
  
         /* Code the current SELECT into temporary table "tab2"
@@ -3164,9 +3169,17 @@ static int multiSelect(
         addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
         assert( p->addrOpenEphm[1] == -1 );
         p->addrOpenEphm[1] = addr;
-        p->pPrior = 0;
+
+        /* Disable prior SELECTs and the LIMIT counters during the computation
+        ** of the RHS select */
         pLimit = p->pLimit;
+        iLimit = p->iLimit;
+        iOffset = p->iOffset;
+        p->pPrior = 0;
         p->pLimit = 0;
+        p->iLimit = 0;
+        p->iOffset = 0;
+
         intersectdest.iSDParm = tab2;
         ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                           sqlite3SelectOpName(p->op)));
@@ -3179,19 +3192,21 @@ static int multiSelect(
           p->nSelectRow = pPrior->nSelectRow;
         }
         sqlite3ExprDelete(db, p->pLimit);
+
+        /* Reinstate the LIMIT counters prior to running the final intersect */
         p->pLimit = pLimit;
+        p->iLimit = iLimit;
+        p->iOffset = iOffset;
  
         /* Generate code to take the intersection of the two temporary
         ** tables.
         */
         if( rc ) break;
         assert( p->pEList );
-        iBreak = sqlite3VdbeMakeLabel(pParse);
-        iCont = sqlite3VdbeMakeLabel(pParse);
-        computeLimitRegisters(pParse, p, iBreak);
         sqlite3VdbeAddOp1(v, OP_Rewind, tab1);
         r1 = sqlite3GetTempReg(pParse);
         iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
+        iCont = sqlite3VdbeMakeLabel(pParse);
         sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
         VdbeCoverage(v);
         sqlite3ReleaseTempReg(pParse, r1);