Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix byte-code register allocation in ANALYZE for STAT4 when there multiple indexes with differing numbers of columns. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | branch-3.41 |
Files: | files | file ages | folders |
SHA3-256: |
13c8c60bb6b4447b52895dd63a4dffaf |
User & Date: | drh 2023-03-24 17:01:29 |
References
2023-03-25
| ||
18:33 | The fix at [13c8c60bb6b4447b] was incomplete in that it failed to clear the reusable register cache that might contain registers in the STAT4 buffer region. This additional change corrects the problem. (check-in: 671bf6f5 user: drh tags: branch-3.41) | |
Context
2023-03-24
| ||
20:39 | Fix the handling of indexed expressions in an outer query that appear as corelated values inside an aggregate function within a subquery. (check-in: 76b90f26 user: drh tags: branch-3.41) | |
17:01 | Fix byte-code register allocation in ANALYZE for STAT4 when there multiple indexes with differing numbers of columns. (check-in: 13c8c60b user: drh tags: branch-3.41) | |
16:57 | Fix byte-code register allocation in ANALYZE for STAT4 when there multiple indexes with differing numbers of columns. forum post bc39e531e5. This problem arose when expression indexes were added by check-in [2131a5ca53f0e9b0]. (check-in: 2bf5413d user: drh tags: trunk) | |
2023-03-23
| ||
10:58 | The attempt to bring STAT4 up to 100% MC/DC at [55a26c67ed4a3a93] and at [168fa2fb22b8c1ad] are incorrect. Back them out and replace them with a simple NEVER() macro. Error reported by forum post dc4854437b. (check-in: 76e683c5 user: drh tags: branch-3.41) | |
Changes
Changes to src/analyze.c.
︙ | ︙ | |||
990 991 992 993 994 995 996 997 | int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regTemp = iMem++; /* Temporary use register */ int regTemp2 = iMem++; /* Second temporary use register */ int regTabname = iMem++; /* Register containing table name */ 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_PREUPDATE_HOOK | > > > | | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regTemp = iMem++; /* Temporary use register */ int regTemp2 = iMem++; /* Second temporary use register */ int regTabname = iMem++; /* Register containing table name */ 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; #endif pParse->nMem = MAX(pParse->nMem, iMem); v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ return; } |
︙ | ︙ | |||
1272 1273 1274 1275 1276 1277 1278 | int regSample = regStat1+3; int regCol = regStat1+4; int regSampleRowid = regCol + nCol; int addrNext; int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; | > > > > > > > > > > > > > > > > | > > | 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | int regSample = regStat1+3; int regCol = regStat1+4; int regSampleRowid = regCol + nCol; int addrNext; int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; 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); addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); callStatGet(pParse, regStat, STAT_GET_NEQ, regEq); callStatGet(pParse, regStat, STAT_GET_NLT, regLt); |
︙ | ︙ |
Changes to test/analyzeE.test.
︙ | ︙ | |||
246 247 248 249 250 251 252 253 254 | PRAGMA encoding = 'UTF-16'; CREATE TABLE t0 (c1 TEXT); INSERT INTO t0 VALUES (''); CREATE INDEX i0 ON t0(c1); ANALYZE; SELECT * FROM t0 WHERE t0.c1 BETWEEN '' AND (ABS('')); } {{}} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | PRAGMA encoding = 'UTF-16'; CREATE TABLE t0 (c1 TEXT); INSERT INTO t0 VALUES (''); CREATE INDEX i0 ON t0(c1); ANALYZE; 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 |