Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix an issue in ANALYZE when STAT3 is disabled but both sqlite_stat2 and sqlite_stat3 tables exist. Also add testability tweaks to the STAT3 code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | stat3-trunk |
Files: | files | file ages | folders |
SHA1: |
3ca7e449e2e20d95e516cf7fe87bfa0b |
User & Date: | drh 2011-09-22 18:46:34.844 |
Context
2011-09-22
| ||
20:52 | Remove the restriction on the number of entries per index in sqlite_stat3. (check-in: 374343c8ad user: drh tags: stat3-trunk) | |
18:46 | Fix an issue in ANALYZE when STAT3 is disabled but both sqlite_stat2 and sqlite_stat3 tables exist. Also add testability tweaks to the STAT3 code. (check-in: 3ca7e449e2 user: drh tags: stat3-trunk) | |
00:28 | Fix an uninitialized variable and a misuse of memcpy(). (check-in: ee110d5a4a user: drh tags: stat3-trunk) | |
Changes
Changes to src/analyze.c.
︙ | ︙ | |||
168 169 170 171 172 173 174 | pDb = &db->aDb[iDb]; /* Drop all statistics tables that this version of SQLite does not ** understand. */ for(i=0; i<ArraySize(azToDrop); i++){ Table *pTab = sqlite3FindTable(db, azToDrop[i], pDb->zName); | > | > > | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | pDb = &db->aDb[iDb]; /* Drop all statistics tables that this version of SQLite does not ** understand. */ for(i=0; i<ArraySize(azToDrop); i++){ Table *pTab = sqlite3FindTable(db, azToDrop[i], pDb->zName); if( pTab ){ sqlite3CodeDropTable(pParse, pTab, iDb, 0); break; } } /* Create new statistic tables if they do not exist, or clear them ** if they do already exist. */ for(i=0; i<ArraySize(aTable); i++){ const char *zTab = aTable[i].zName; |
︙ | ︙ | |||
334 335 336 337 338 339 340 | }else{ if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ doInsert = 1; } } if( !doInsert ) return; if( p->nSample==p->mxSample ){ | | | < | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | }else{ if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ doInsert = 1; } } if( !doInsert ) return; if( p->nSample==p->mxSample ){ assert( p->nSample - iMin - 1 >= 0 ); memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); pSample = &p->a[p->nSample-1]; }else{ pSample = &p->a[p->nSample++]; } pSample->iRowid = rowid; pSample->nEq = nEq; pSample->nLt = nLt; |
︙ | ︙ | |||
409 410 411 412 413 414 415 | ){ int n = sqlite3_value_int(argv[1]); Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); assert( p!=0 ); if( p->nSample<=n ) return; switch( argc ){ | | | | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | ){ int n = sqlite3_value_int(argv[1]); Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); assert( p!=0 ); if( p->nSample<=n ) return; switch( argc ){ case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; case 3: sqlite3_result_int64(context, p->a[n].nEq); break; case 4: sqlite3_result_int64(context, p->a[n].nLt); break; default: sqlite3_result_int64(context, p->a[n].nDLt); break; } } static const FuncDef stat3GetFuncdef = { -1, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ 0, /* pUserData */ |
︙ | ︙ | |||
968 969 970 971 972 973 974 975 976 977 978 979 980 981 | zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); if( nSample>255 ) continue; pIdx = sqlite3FindIndex(db, zIndex, zDb); if( pIdx==0 ) continue; assert( pIdx->nSample==0 ); pIdx->nSample = (u8)nSample; pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); pIdx->avgEq = pIdx->aiRowEst[1]; if( pIdx->aSample==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); return SQLITE_NOMEM; | > | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 | zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); if( nSample>255 ) continue; pIdx = sqlite3FindIndex(db, zIndex, zDb); if( pIdx==0 ) continue; assert( pIdx->nSample==0 ); testcase( nSample==255 ); pIdx->nSample = (u8)nSample; pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); pIdx->avgEq = pIdx->aiRowEst[1]; if( pIdx->aSample==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); return SQLITE_NOMEM; |
︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 | default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { const char *z = (const char *)( (eType==SQLITE_BLOB) ? sqlite3_column_blob(pStmt, 4): sqlite3_column_text(pStmt, 4) ); int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; | < | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { const char *z = (const char *)( (eType==SQLITE_BLOB) ? sqlite3_column_blob(pStmt, 4): sqlite3_column_text(pStmt, 4) ); int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; pSample->nByte = n; if( n < 1){ pSample->u.z = 0; }else{ pSample->u.z = sqlite3Malloc(n); if( pSample->u.z==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1520 1521 1522 1523 1524 1525 1526 | struct IndexSample { union { char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ double r; /* Value if eType is SQLITE_FLOAT */ i64 i; /* Value if eType is SQLITE_INTEGER */ } u; u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ | | | 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 | struct IndexSample { union { char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ double r; /* Value if eType is SQLITE_FLOAT */ i64 i; /* Value if eType is SQLITE_INTEGER */ } u; u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ int nByte; /* Size in byte of text or blob. */ tRowcnt nEq; /* Est. number of rows where the key equals this sample */ tRowcnt nLt; /* Est. number of rows where key is less than this sample */ tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ }; /* ** Each token coming out of the lexer is an instance of |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 | IndexSample *aSample; int i, eType; int isEq = 0; i64 v; double r, rS; assert( roundUp==0 || roundUp==1 ); if( pVal==0 ) return SQLITE_ERROR; n = pIdx->aiRowEst[0]; aSample = pIdx->aSample; i = 0; eType = sqlite3_value_type(pVal); if( eType==SQLITE_INTEGER ){ | > | 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 | IndexSample *aSample; int i, eType; int isEq = 0; i64 v; double r, rS; assert( roundUp==0 || roundUp==1 ); assert( pIdx->nSample>0 ); if( pVal==0 ) return SQLITE_ERROR; n = pIdx->aiRowEst[0]; aSample = pIdx->aSample; i = 0; eType = sqlite3_value_type(pVal); if( eType==SQLITE_INTEGER ){ |
︙ | ︙ | |||
2490 2491 2492 2493 2494 2495 2496 | if( rS>=r ){ isEq = rS==r; break; } } }else if( eType==SQLITE_NULL ){ i = 0; | | | 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 | if( rS>=r ){ isEq = rS==r; break; } } }else if( eType==SQLITE_NULL ){ i = 0; if( aSample[0].eType==SQLITE_NULL ) isEq = 1; }else{ assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); for(i=0; i<pIdx->nSample; i++){ if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){ break; } } |
︙ | ︙ | |||
2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 | ){ sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ u8 aff; /* Column affinity */ int rc; /* Subfunction return code */ tRowcnt a[2]; /* Statistics */ assert( p->aSample!=0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; if( pExpr ){ rc = valueFromExpr(pParse, pExpr, aff, &pRhs); if( rc ) goto whereEqualScanEst_cancel; }else{ pRhs = sqlite3ValueNew(pParse->db); } | > | 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 | ){ sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ u8 aff; /* Column affinity */ int rc; /* Subfunction return code */ tRowcnt a[2]; /* Statistics */ assert( p->aSample!=0 ); assert( p->nSample>0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; if( pExpr ){ rc = valueFromExpr(pParse, pExpr, aff, &pRhs); if( rc ) goto whereEqualScanEst_cancel; }else{ pRhs = sqlite3ValueNew(pParse->db); } |
︙ | ︙ |