]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix byte-code register allocation in ANALYZE for STAT4 when there multiple
authordrh <>
Fri, 24 Mar 2023 16:57:21 +0000 (16:57 +0000)
committerdrh <>
Fri, 24 Mar 2023 16:57:21 +0000 (16:57 +0000)
indexes with differing numbers of columns.
[forum:/forumpost/bc39e531e5|forum post bc39e531e5].

FossilOrigin-Name: 2bf5413dc2c19d5feb32e5b01aa9b990ec2f74f45f5ca0dca15215f8c9dbc9b9

manifest
manifest.uuid
src/analyze.c
test/analyzeE.test

index c21f9a0e05f57e93bf4ff20758c01b2edffbf2f0..5fd3858c5aec5d56e30ca6c2ab419669fd35a6de 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sattempt\sto\sbring\sSTAT4\sup\sto\s100%\sMC/DC\sat\s[55a26c67ed4a3a93]\sand\nat\s[168fa2fb22b8c1ad]\sare\sincorrect.\s\sBack\sthem\sout\sand\sreplace\sthem\swith\na\ssimple\sNEVER()\smacro.\s\sError\sreported\sby\n[forum:/forumpost/dc4854437b|forum\spost\sdc4854437b].
-D 2023-03-23T10:54:07.499
+C Fix\sbyte-code\sregister\sallocation\sin\sANALYZE\sfor\sSTAT4\swhen\sthere\smultiple\nindexes\swith\sdiffering\snumbers\sof\scolumns.\n[forum:/forumpost/bc39e531e5|forum\spost\sbc39e531e5].
+D 2023-03-24T16:57:21.318
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -558,7 +558,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2
 F src/alter.c 3ca2f449c890f8b86ec9e06f0c4fccf0648941c3308a16904cb2852227db83f7
-F src/analyze.c b597c382f23b19cce563211181e84b7e8edddd6871d5f630bbadedb57e562806
+F src/analyze.c 26e68072d62d0a28b2dd8619f76be876db9b4ff6e8ad1fd4ed3ac56b1cb045c4
 F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39
 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
 F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
@@ -753,7 +753,7 @@ F test/analyze8.test 29ef237d8a59b39cc31c3310134fefe96a690b195e3deed5ecb65283908
 F test/analyze9.test 30e1cb99336045a384a11d97900720184333c88174b3b89bc07444ea39e7df19
 F test/analyzeC.test 1111830ad355d29a294a5dda654dd5f6a8622c6a223a4f7b7b3d091df7a7a42b
 F test/analyzeD.test 485f621cfd2ef0a8f8ac79672586651bfa495bd899db50461bb4b558400ab3c1
-F test/analyzeE.test 3e35783c15180c475bf0e1d69089ea8cb17f4af44fbca0938ccd476af8ac6aa8
+F test/analyzeE.test 8770de3834bb9aea1c892f4d155a5bd9578c23c0c3f199dc6f1b5d597b5bf65c
 F test/analyzeF.test 40b5cc3ad7b10e81020d7ca86f1417647ecfae7477cfd88acc5aa7ae1068f949
 F test/analyzeG.test 623be33038c49648872746c8dd8b23b5792c08fef173c55e82f1b12fca259852
 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
@@ -2051,8 +2051,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 8fbdf7d10400c4f54fc3d8bc823f97818de860deeeed35ab6ad717260cd301e0
-R b1afaa2171dcf7fcb417d71a6c9fd64f
+P 5992370a89f8de7a6e941130b381f85d369856dbdb7860405e6fb17dad2293df
+R 77e3e44c3db2ed26a66a9624f00b38b1
 U drh
-Z cd2206df50c0abaeae5a80127570c62a
+Z cb6078c6d4f127cf1058bdefbeb157d4
 # Remove this line to create a well-formed Fossil manifest.
index c65144d6e19c2442251130a97a0b7abbdb8994d9..b1168025de8f4a6e14c0000bc3119d85b88a4d3d 100644 (file)
@@ -1 +1 @@
-5992370a89f8de7a6e941130b381f85d369856dbdb7860405e6fb17dad2293df
\ No newline at end of file
+2bf5413dc2c19d5feb32e5b01aa9b990ec2f74f45f5ca0dca15215f8c9dbc9b9
\ No newline at end of file
index f3356ea3cac0be81dc8bd55247ef3381084281f6..2eaabd6be480ab19f8aafd1e2313436bbc89f51e 100644 (file)
@@ -994,8 +994,11 @@ static void analyzeOneTable(
   int regIdxname = iMem++;     /* Register containing index name */
   int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
   int regPrev = iMem;          /* MUST BE LAST (see below) */
+#ifdef SQLITE_ENABLE_STAT4
+  int doOnce = 1;              /* Flag for a one-time computation */
+#endif
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
-  Table *pStat1 = 0; 
+  Table *pStat1 = 0;
 #endif
 
   pParse->nMem = MAX(pParse->nMem, iMem);
@@ -1276,7 +1279,25 @@ static void analyzeOneTable(
       int addrIsNull;
       u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
 
-      pParse->nMem = MAX(pParse->nMem, regCol+nCol);
+      if( doOnce ){
+        int mxCol = nCol;
+        Index *pX;
+
+        /* Compute the maximum number of columns in any index */
+        for(pX=pTab->pIndex; pX; pX=pX->pNext){
+          int nColX;                     /* Number of columns in pX */
+          if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){
+            nColX = pX->nKeyCol;
+          }else{
+            nColX = pX->nColumn;
+          }
+          if( nColX>mxCol ) mxCol = nColX;
+        }
+
+        /* Allocate space to compute results for the largest index */
+        pParse->nMem = MAX(pParse->nMem, regCol+mxCol);
+        doOnce = 0;
+      }
 
       addrNext = sqlite3VdbeCurrentAddr(v);
       callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
index 9f65b7a320d594025994fb2f06478904ee84d9d2..9b5a27b87a097086b28befe31fa7838038f3fca2 100644 (file)
@@ -251,4 +251,30 @@ do_execsql_test analyzeE-5.0 {
   SELECT * FROM t0 WHERE t0.c1 BETWEEN '' AND (ABS(''));
 } {{}}
 
+# 2023-03-24 https://sqlite.org/forum/forumpost/bc39e531e5
+#
+reset_db
+do_execsql_test analyzeE-6.0 {
+  CREATE TABLE t1(x);
+  CREATE INDEX i1 ON t1(x,x,x,x,x||2);
+  CREATE INDEX i2 ON t1(1<2);
+  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
+    INSERT INTO t1(x) SELECT x FROM c;
+  ANALYZE;
+} {}
+do_execsql_test analyzeE-6.1 {
+  SELECT count(*)>1 FROM sqlite_stat4 WHERE idx='i2' AND neq='1000 1';
+} 1
+do_execsql_test analyzeE-6.2 {
+  SELECT count(*) FROM sqlite_stat4 WHERE idx='i2' AND neq<>'1000 1';
+} 0
+do_execsql_test analyzeE-6.3 {
+  SELECT count(*)>1 FROM sqlite_stat4 WHERE idx='i1' AND neq='1 1 1 1 1 1';
+} 1
+do_execsql_test analyzeE-6.4 {
+  SELECT count(*) FROM sqlite_stat4 WHERE idx='i1' AND neq<>'1 1 1 1 1 1';
+} 0
+
+
+
 finish_test