Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch enhanced-stat1 Excluding Merge-Ins
This is equivalent to a diff from 8d2120c354 to ee34db31a0
2024-01-01
| ||
15:49 | Improved defenses against deliberately corrupted sqlite_stat1 tables. (Closed-Leaf check-in: ee34db31a0 user: drh tags: enhanced-stat1) | |
15:35 | Fix a harmless compiler warning. (check-in: b5aa1aea38 user: drh tags: enhanced-stat1) | |
2023-12-31
| ||
04:01 | Use SQLITE_ENABLE_STAT4 in both the WASM and JNI builds. (check-in: 99d11e6d0a user: stephan tags: trunk) | |
2023-12-29
| ||
19:03 | Attempt to improve the ANALYZE command so that it does a better job of detecting lopsided indexes and makes appropriate changes to the sqlite_stat1 table. (check-in: 4b70b94616 user: drh tags: enhanced-stat1) | |
04:29 | Minor doc touchup in the JS bits. (check-in: 8d2120c354 user: stephan tags: trunk) | |
2023-12-28
| ||
21:02 | Enable SQLITE_DIRECT_OVERFLOW_READ unless it is specifically disabled using the -DSQLITE_DIRECT_OVERFLOW_READ=0 compile-time option. (check-in: 630604a4e6 user: drh tags: trunk) | |
Changes to src/analyze.c.
︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 272 273 274 275 | ** information. */ typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; struct StatSample { tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ #ifdef SQLITE_ENABLE_STAT4 tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ u8 *aRowid; /* Key for WITHOUT ROWID tables */ } u; u32 nRowid; /* Sizeof aRowid[] */ | > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | ** information. */ typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; struct StatSample { tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ tRowcnt *amxEq; /* Maximum length run of equal values */ #ifdef SQLITE_ENABLE_STAT4 tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ u8 *aRowid; /* Key for WITHOUT ROWID tables */ } u; u32 nRowid; /* Sizeof aRowid[] */ |
︙ | ︙ | |||
421 422 423 424 425 426 427 428 429 430 431 432 433 434 | nKeyCol = sqlite3_value_int(argv[1]); assert( nKeyCol<=nCol ); assert( nKeyCol>0 ); /* Allocate the space required for the StatAccum object */ n = sizeof(*p) + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 if( mxSample ){ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample); } | > | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | nKeyCol = sqlite3_value_int(argv[1]); assert( nKeyCol<=nCol ); assert( nKeyCol>0 ); /* Allocate the space required for the StatAccum object */ n = sizeof(*p) + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ + sizeof(tRowcnt)*nColUp /* StatAccum.amxEq */ + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 if( mxSample ){ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample); } |
︙ | ︙ | |||
443 444 445 446 447 448 449 | p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; p->nLimit = sqlite3_value_int64(argv[3]); p->nCol = nCol; p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; | > | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; p->nLimit = sqlite3_value_int64(argv[3]); p->nCol = nCol; p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; p->current.amxEq = &p->current.anDLt[nColUp]; p->current.anEq = &p->current.amxEq[nColUp]; #ifdef SQLITE_ENABLE_STAT4 p->mxSample = p->nLimit==0 ? mxSample : 0; if( mxSample ){ u8 *pSpace; /* Allocated space not yet assigned */ int i; /* Used to iterate through p->aSample[] */ |
︙ | ︙ | |||
712 713 714 715 716 717 718 | UNUSED_PARAMETER( argc ); UNUSED_PARAMETER( context ); assert( p->nCol>0 ); assert( iChng<p->nCol ); if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ | | > > > > > > | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | UNUSED_PARAMETER( argc ); UNUSED_PARAMETER( context ); assert( p->nCol>0 ); assert( iChng<p->nCol ); if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ for(i=0; i<p->nCol; i++){ p->current.anEq[i] = 1; p->current.amxEq[i] = 1; } }else{ /* Second and subsequent calls get processed here */ #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ) samplePushPrevious(p, iChng); #endif /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ for(i=0; i<iChng; i++){ p->current.anEq[i]++; } for(i=iChng; i<p->nCol; i++){ p->current.anDLt[i]++; #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; #endif if( p->current.amxEq[i]<p->current.anEq[i] ){ p->current.amxEq[i] = p->current.anEq[i]; } p->current.anEq[i] = 1; } } p->nRow++; #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ){ |
︙ | ︙ | |||
837 838 839 840 841 842 843 | ** the index. The first integer in the list is the total number of ** entries in the index. There is one additional integer in the list ** for each indexed column. This additional integer is an estimate of ** the number of rows matched by a equality query on the index using ** a key with the corresponding number of fields. In other words, ** if the index is on columns (a,b) and the sqlite_stat1 value is ** "100 10 2", then SQLite estimates that: | | | | | | < < | > > > | < > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | ** the index. The first integer in the list is the total number of ** entries in the index. There is one additional integer in the list ** for each indexed column. This additional integer is an estimate of ** the number of rows matched by a equality query on the index using ** a key with the corresponding number of fields. In other words, ** if the index is on columns (a,b) and the sqlite_stat1 value is ** "100 10 2", then SQLite estimates that: ** | | | ** | | `-- "WHERE a=? AND b=?" matches approximately 2 rows ** | `---- "WHERE a=?" matches approximately 10 rows ** `-------- There are approximately 100 rows in the index total ** ** If D is the count of distinct values and K is the total number of ** rows, then each estimate is usually computed as: ** ** I = (K+D-1)/D ** ** Adjustments to the I value are made in some cases. See comments ** in-line below. */ sqlite3_str sStat; /* Text of the constructed "stat" line */ int i; /* Loop counter */ int bUneven = 0; /* True if the uneven=... argument is needed */ u64 nRow; /* Number of rows in the index */ sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); nRow = p->nSkipAhead ? p->nEst : p->nRow; sqlite3_str_appendf(&sStat, "%llu", nRow); for(i=0; i<p->nKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; u64 mx = p->current.amxEq[i]; if( nDistinct==1 && p->nLimit>0 ){ /* If we never saw more than a single value in a PRAGMA analysis_limit ** search, then set the estimated number of matching rows to the ** estimated number of rows in the index. */ iVal = p->nEst; }else if( iVal<mx/10 ){ /* ^^-- TUNING: threshold for when var=... is reported. ** tag-20231231-01: Report var=... if the maximum run of identical ** values ever reaches or exceeds 10 (or so) times the average run ** for any column of the index. ** ** The reporting threshold of 10 is tunable, but if changed, one ** should also consider changing the aiRowLogEst adjustment factor at ** tag-20231231-02. */ bUneven = 1; }else if( iVal==2 && p->nRow*10 <= nDistinct*11 ){ /* If the value is less than or equal to 1.1, round it down to 1.0 */ iVal = 1; } sqlite3_str_appendf(&sStat, " %llu", iVal); assert( p->current.anEq[i] ); } if( bUneven ){ char cSep = '='; sqlite3_str_appendf(&sStat, " var"); for(i=0; i<p->nKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; u64 mx = p->current.amxEq[i]; int iRatio = mx/iVal; sqlite3_str_appendf(&sStat, "%c%d", cSep, iRatio); cSep = ','; } } sqlite3ResultStrAccum(context, &sStat); } #ifdef SQLITE_ENABLE_STAT4 else if( eCall==STAT_GET_ROWID ){ if( p->iGet<0 ){ samplePushPrevious(p, 0); |
︙ | ︙ | |||
1510 1511 1512 1513 1514 1515 1516 | tRowcnt v; #ifdef SQLITE_ENABLE_STAT4 if( z==0 ) z = ""; #else assert( z!=0 ); #endif | | | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 | tRowcnt v; #ifdef SQLITE_ENABLE_STAT4 if( z==0 ) z = ""; #else assert( z!=0 ); #endif for(i=0; i<nOut; i++){ v = 0; while( (c=z[0])>='0' && c<='9' ){ v = v*10 + c - '0'; z++; } #ifdef SQLITE_ENABLE_STAT4 if( aOut ) aOut[i] = v; |
︙ | ︙ | |||
1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | #ifndef SQLITE_ENABLE_STAT4 assert( pIndex!=0 ); { #else if( pIndex ){ #endif pIndex->bUnordered = 0; pIndex->noSkipScan = 0; while( z[0] ){ if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ int sz = sqlite3Atoi(z+3); if( sz<2 ) sz = 2; pIndex->szIdxRow = sqlite3LogEst(sz); }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; } #ifdef SQLITE_ENABLE_COSTMULT else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); } #endif while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } } } /* ** This callback is invoked once for each index when reading the ** sqlite_stat1 table. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 | #ifndef SQLITE_ENABLE_STAT4 assert( pIndex!=0 ); { #else if( pIndex ){ #endif pIndex->bUnordered = 0; pIndex->noSkipScan = 0; pIndex->bSlow = 0; assert( aLog!=0 ); while( z[0] ){ if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ int sz = sqlite3Atoi(z+3); if( sz<2 ) sz = 2; pIndex->szIdxRow = sqlite3LogEst(sz); }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; }else if( sqlite3_strglob("var=[0-9]*", z)==0 ){ /* An argument like "var=N1,N2,...NN" means that the maximum length ** run of the same value is Nx times longer than the average for ** the X-th column of the index. ** ** For this implementation, go through the iaRowLogEst[] array and ** increase each value by 1/10th of the average value, to account ** for the variability of the estimate. ** ** tag-20231231-02: The 1/10th value is tunable. See the tuning ** comment in the body of the loop. The ANALYZE command only ** inserts a var=... argument if one or more of the Nx values is ** within the tuning range, so if changing the tuning factor here, ** consider also changing it at tag-20232131-01. ** ** The stat column continue to hold the average run length for the ** initial integers, for backwards compatibility. */ int jj = 1; int kk = 4; LogEst mx = aLog[0]; for(jj=1; sqlite3Isdigit(z[kk]) && jj<nOut; jj++){ u64 vx = z[kk++] - '0'; LogEst scale; while( sqlite3Isdigit(z[kk]) ){ vx = vx*10 + z[kk++]-'0'; } scale = sqlite3LogEst(vx); if( scale>33 ){ /* ^^----- TUNING --------------vv See tag 20231231-02 */ LogEst adjusted = aLog[jj] + scale - 33; if( adjusted>mx ) adjusted = mx; aLog[jj] = adjusted; } if( z[kk]==',' ) kk++; } } #ifdef SQLITE_ENABLE_COSTMULT else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); } #endif while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } /* Set the bSlow flag if the peak number of rows obtained ** from a full equality match is so large that a full table scan ** seems likely to be faster than using the index. */ if( aLog[0] > 66 /* Index has more than 100 rows */ && aLog[0] <= aLog[pIndex->nKeyCol] /* And only a single value seen */ ){ pIndex->bSlow = 1; } } } /* ** This callback is invoked once for each index when reading the ** sqlite_stat1 table. ** |
︙ | ︙ | |||
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 | pIndex->hasStat1 = 1; if( pIndex->pPartIdxWhere==0 ){ pTable->nRowLogEst = pIndex->aiRowLogEst[0]; pTable->tabFlags |= TF_HasStat1; } }else{ Index fakeIdx; fakeIdx.szIdxRow = pTable->szTabRow; #ifdef SQLITE_ENABLE_COSTMULT fakeIdx.pTable = pTable; #endif decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); pTable->szTabRow = fakeIdx.szIdxRow; pTable->tabFlags |= TF_HasStat1; | > | 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 | pIndex->hasStat1 = 1; if( pIndex->pPartIdxWhere==0 ){ pTable->nRowLogEst = pIndex->aiRowLogEst[0]; pTable->tabFlags |= TF_HasStat1; } }else{ Index fakeIdx; memset(&fakeIdx, 0, sizeof(fakeIdx)); fakeIdx.szIdxRow = pTable->szTabRow; #ifdef SQLITE_ENABLE_COSTMULT fakeIdx.pTable = pTable; #endif decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); pTable->szTabRow = fakeIdx.szIdxRow; pTable->tabFlags |= TF_HasStat1; |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 | ); } } } break; #ifdef SQLITE_DEBUG case PragTyp_STATS: { Index *pIdx; HashElem *i; | > > > > > > > > > > > > > > | | | > > > > > > > > | | > | > | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 | ); } } } break; #ifdef SQLITE_DEBUG /* The output of this pragma is undocumented in the official documentation ** because it is subject to change, and we don't want people coming to ** rely on it. ** ** Columns: ** tbl Name of a table that is being described ** idx Name of an index (belonging to tbl) being described ** wdth LogEst of the on-disk estimated bytes per row ** hght LogEst of the estimated number of rows ** flgs tabFlags for tables ** est aiRowLogEst[] values for indexes + "slow" flag */ case PragTyp_STATS: { Index *pIdx; HashElem *i; sqlite3_str est; sqlite3StrAccumInit(&est, 0, 0, 0, SQLITE_MAX_LENGTH); pParse->nMem = 6; sqlite3CodeVerifySchema(pParse, iDb); for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); sqlite3VdbeMultiLoad(v, 1, "ssiiis", sqlite3PreferredTableName(pTab->zName), 0, pTab->szTabRow, pTab->nRowLogEst, pTab->tabFlags, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int j; est.nChar = 0; for(j=1; j<pIdx->nKeyCol+1; j++){ if( j>1 ) sqlite3_str_append(&est, " ", 1); sqlite3_str_appendf(&est, "%d", pIdx->aiRowLogEst[j]); } if( pIdx->bSlow ) sqlite3_str_append(&est, " slow", 5); sqlite3VdbeMultiLoad(v, 2, "siiisX", pIdx->zName, pIdx->szIdxRow, pIdx->aiRowLogEst[0], pIdx->hasStat1, sqlite3_str_value(&est)); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); sqlite3_str_reset(&est); } } } break; #endif case PragTyp_INDEX_INFO: if( zRight ){ |
︙ | ︙ |
Changes to src/pragma.h.
︙ | ︙ | |||
85 86 87 88 89 90 91 | /* table_info reuses 8 */ /* 15 */ "schema", /* Used by: table_list */ /* 16 */ "name", /* 17 */ "type", /* 18 */ "ncol", /* 19 */ "wr", /* 20 */ "strict", | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | < | > | | | | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | /* table_info reuses 8 */ /* 15 */ "schema", /* Used by: table_list */ /* 16 */ "name", /* 17 */ "type", /* 18 */ "ncol", /* 19 */ "wr", /* 20 */ "strict", /* 21 */ "tbl", /* Used by: stats */ /* 22 */ "idx", /* 23 */ "wdth", /* 24 */ "hght", /* 25 */ "flgs", /* 26 */ "est", /* 27 */ "seqno", /* Used by: index_xinfo */ /* 28 */ "cid", /* 29 */ "name", /* 30 */ "desc", /* 31 */ "coll", /* 32 */ "key", /* 33 */ "name", /* Used by: function_list */ /* 34 */ "builtin", /* 35 */ "type", /* 36 */ "enc", /* 37 */ "narg", /* 38 */ "flags", /* 39 */ "seq", /* Used by: index_list */ /* 40 */ "name", /* 41 */ "unique", /* 42 */ "origin", /* 43 */ "partial", /* 44 */ "table", /* Used by: foreign_key_check */ /* 45 */ "rowid", /* 46 */ "parent", /* 47 */ "fkid", /* index_info reuses 27 */ /* 48 */ "seq", /* Used by: database_list */ /* 49 */ "name", /* 50 */ "file", /* 51 */ "busy", /* Used by: wal_checkpoint */ /* 52 */ "log", /* 53 */ "checkpointed", /* collation_list reuses 39 */ /* 54 */ "database", /* Used by: lock_status */ /* 55 */ "status", /* 56 */ "cache_size", /* Used by: default_cache_size */ /* module_list pragma_list reuses 9 */ /* 57 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ typedef struct PragmaName { const char *const zName; /* Name of pragma */ u8 ePragTyp; /* PragTyp_XXX value */ u8 mPragFlg; /* Zero or more PragFlg_XXX values */ |
︙ | ︙ | |||
174 175 176 177 178 179 180 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_AutoIndex }, #endif #endif {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_AutoIndex }, #endif #endif {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 57, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", /* ePragTyp: */ PragTyp_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, |
︙ | ︙ | |||
213 214 215 216 217 218 219 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 39, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) {/* zName: */ "compile_options", /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
248 249 250 251 252 253 254 | /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_Result0, | | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 48, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 56, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "defer_foreign_keys", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, |
︙ | ︙ | |||
285 286 287 288 289 290 291 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, | | | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 44, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) {/* zName: */ "foreign_key_list", /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 8, |
︙ | ︙ | |||
328 329 330 331 332 333 334 | /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 33, 6, /* iArg: */ 0 }, #endif #endif {/* zName: */ "hard_heap_limit", /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
357 358 359 360 361 362 363 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, | | | | | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 27, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 39, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 27, 6, /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "integrity_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
407 408 409 410 411 412 413 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 54, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "locking_mode", /* ePragTyp: */ PragTyp_LOCKING_MODE, /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
546 547 548 549 550 551 552 | /* iArg: */ SQLITE_SqlTrace }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | /* iArg: */ SQLITE_SqlTrace }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, /* ColNames: */ 21, 6, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "synchronous", /* ePragTyp: */ PragTyp_SYNCHRONOUS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
642 643 644 645 646 647 648 | /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, | | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, /* ColNames: */ 51, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; /* Number of pragmas: 68 on by default, 78 total. */ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int mxSample; /* Number of slots allocated to aSample[] */ | > | 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bSlow:1; /* This index is not good for equality lookups */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int mxSample; /* Number of slots allocated to aSample[] */ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
2969 2970 2971 2972 2973 2974 2975 | assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); if( pNew->wsFlags & WHERE_BTM_LIMIT ){ opMask = WO_LT|WO_LE; }else{ assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } | > | > > | 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 | assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); if( pNew->wsFlags & WHERE_BTM_LIMIT ){ opMask = WO_LT|WO_LE; }else{ assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } if( pProbe->bUnordered || pProbe->bSlow ){ if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); if( pProbe->bSlow ) opMask &= ~(WO_EQ|WO_IN|WO_IS); } assert( pNew->u.btree.nEq<pProbe->nColumn ); assert( pNew->u.btree.nEq<pProbe->nKeyCol || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY ); saved_nEq = pNew->u.btree.nEq; saved_nBtm = pNew->u.btree.nBtm; |
︙ | ︙ |
Changes to tool/mkpragmatab.tcl.
︙ | ︙ | |||
243 244 245 246 247 248 249 | TYPE: TABLE_LIST FLAG: NeedSchema Result1 COLS: schema name type ncol wr strict IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: stats FLAG: NeedSchema Result0 SchemaReq | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | TYPE: TABLE_LIST FLAG: NeedSchema Result1 COLS: schema name type ncol wr strict IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) NAME: stats FLAG: NeedSchema Result0 SchemaReq COLS: tbl idx wdth hght flgs est IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) NAME: index_info TYPE: INDEX_INFO ARG: 0 FLAG: NeedSchema Result1 SchemaOpt COLS: seqno cid name |
︙ | ︙ |