From: drh <> Date: Wed, 9 Jul 2025 20:11:49 +0000 (+0000) Subject: Fix the empty-table optimization on INTERSECT so that it does not try to X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33c2e37f981af6766a6309f24a54b91fa3fa9080;p=thirdparty%2Fsqlite.git Fix the empty-table optimization on INTERSECT so that it does not try to use an uninitialized register for LIMIT processing. FossilOrigin-Name: 6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f --- diff --git a/manifest b/manifest index 58cfe31140..a8c30532d4 100644 --- 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. diff --git a/manifest.uuid b/manifest.uuid index bedccbe899..b9c5f04af2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -498ee8d514e64cdc93a8d68e1971b6326c6132daf25067936bec921c42494caa +6918ada008507b4564ca0dc5f4f6818c49a42eb14a16285b2074e21dcc8f2c3f diff --git a/src/select.c b/src/select.c index 99b05c76a3..1b12663138 100644 --- a/src/select.c +++ b/src/select.c @@ -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);