Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix comments and a memory leak in analyze.c. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 8a25008dfe3b6b4bbae05cbc7951b93ade088b9e |
User & Date: | dan 2013-06-25 15:28:18 |
Context
2013-06-25
| ||
16:22 | Also run analyze8.test as part of src4.test. check-in: 21b5123716 user: dan tags: trunk | |
15:28 | Fix comments and a memory leak in analyze.c. check-in: 8a25008dfe user: dan tags: trunk | |
14:47 | Have the planner always consider the PK index, even when it does not serve to satisfy any contraints or ordering requirements. check-in: 95933bb7ca user: dan tags: trunk | |
Changes
Changes to src/analyze.c.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 ... 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 ... 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 ... 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 ... 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 ... 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 ... 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat ** column contains a single integer which is the (estimated) number of ** rows in the table identified by sqlite_stat1.tbl. ** ** Format for sqlite_stat3: ** ** The sqlite_stat3 table may contain multiple entries for each index. ** The idx column names the index and the tbl column is the table of the ** index. If the idx and tbl columns are the same, then the sample is ** of the INTEGER PRIMARY KEY. The sample column is a value taken from ** the left-most column of the index. The nEq column is the approximate ** number of entires in the index whose left-most column exactly matches ** the sample. nLt is the approximate number of entires whose left-most ** column is less than the sample. The nDLt column is the approximate ** number of distinct left-most entries in the index that are less than ** the sample. ** ** Future versions of SQLite might change to store a string containing ** multiple integers values in the nDLt column of sqlite_stat3. The first ** integer will be the number of prior index entries that are distinct in ** the left-most column. The second integer will be the number of prior index ** entries that are distinct in the first two columns. The third integer ** will be the number of prior index entries that are distinct in the first ................................................................................ aRoot[i] = pPK->tnum; assert( aRoot[i]>0 ); if( zWhere ){ sqlite4NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere ); }else{ /* The sqlite_stat[12] table already exists. Delete all rows. */ sqlite4VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); } } } /* Open the sqlite_stat[13] tables for writing. */ for(i=0; i<ArraySize(aTable); i++){ ................................................................................ int mxSample; /* Maximum number of samples to accumulate */ int nSample; /* Current number of samples */ u32 iPrn; /* Pseudo-random number used for sampling */ struct Stat3Sample { void *pKey; /* Index key for this sample */ int nKey; /* Bytes of pKey in use */ int nAlloc; /* Bytes of space allocated at pKey */ tRowcnt nEq; /* sqlite_stat3.nEq */ tRowcnt nLt; /* sqlite_stat3.nLt */ tRowcnt nDLt; /* sqlite_stat3.nDLt */ u8 isPSample; /* True if a periodic sample */ u32 iHash; /* Tiebreaker hash */ } *a; /* An array of samples */ }; #ifdef SQLITE4_ENABLE_STAT3 static void delStat3Accum(void *pCtx, void *p){ sqlite4 *db = (sqlite4*)pCtx; sqlite4DbFree(db, p); } /* ** Implementation of the stat3_init(C,S) SQL function. The two parameters ** are the number of rows in the table or index (C) and the number of samples ** to accumulate (S). ................................................................................ }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]; memset(pSample, 0, sizeof(struct Stat3Sample)); }else{ pSample = &p->a[p->nSample++]; } pKey = sqlite4_value_blob(argv[3], &nKey); if( nKey>pSample->nAlloc ){ sqlite4 *db = sqlite4_context_db_handle(context); ................................................................................ 0, /* xFinalize */ "stat3_get", /* zName */ 0, /* pHash */ 0 /* pDestructor */ }; #endif /* SQLITE4_ENABLE_STAT3 */ /* ** Generate code to do an analysis of all indices associated with ** a single table. */ static void analyzeOneTable( Parse *pParse, /* Parser context */ Table *pTab, /* Table whose indices are to be analyzed */ ................................................................................ #endif iIdxCur = pParse->nTab++; sqlite4VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; KeyInfo *pKey; int *aChngAddr; /* Array of jump instruction addresses */ int regCnt; /* Total number of rows in table. */ int regPrev; /* Previous index key read from database */ int aregCard; /* Cardinality array registers */ #ifdef SQLITE4_ENABLE_STAT3 int addrAddimm; /* Address at top of stat3 output loop */ int addrIsnull; /* Another address within the stat3 loop */ #endif if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); nCol = pIdx->nColumn; aChngAddr = sqlite4DbMallocRaw(db, sizeof(int)*nCol); if( aChngAddr==0 ) continue; pKey = sqlite4IndexKeyinfo(pParse, pIdx); if( iMem+1+(nCol*2)>pParse->nMem ){ pParse->nMem = iMem+1+(nCol*2); } /* Open a cursor to the index to be analyzed. */ assert( iDb==sqlite4SchemaToIndex(db, pIdx->pSchema) ); ................................................................................ sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); sqlite4VdbeChangeP5(v, OPFLAG_APPEND); if( pParse->nMem<regRec ) pParse->nMem = regRec; sqlite4VdbeJumpHere(v, jZeroRows); } /* ** Generate code that will cause the most recent index analysis to ** be loaded into internal hash tables where is can be used. */ static void loadAnalysis(Parse *pParse, int iDb){ Vdbe *v = sqlite4GetVdbe(pParse); |
| | | | | | | | | | < | > > > | > > > > > > > > > > < < < < < < < |
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 ... 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 ... 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 ... 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 ... 418 419 420 421 422 423 424 425 426 427 428 429 430 431 ... 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 ... 663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat ** column contains a single integer which is the (estimated) number of ** rows in the table identified by sqlite_stat1.tbl. ** ** Format for sqlite_stat3: ** ** The sqlite_stat3 table may contain multiple entries for each index. ** The idx column names the index and the tbl column contains the name ** of the indexed table. If the idx and tbl columns are the same, then the ** sample is of the PRIMARY KEY index. The sample column is a value taken ** from the left-most column of the index encoded using the key-encoding. ** The nEq column is the approximate number of entires in the index whose ** left-most column exactly matches the sample. nLt is the approximate ** number of entires whose left-most column is less than the sample. The ** nDLt column is the approximate number of distinct left-most entries in ** the index that are less than the sample. ** ** Future versions of SQLite might change to store a string containing ** multiple integers values in the nDLt column of sqlite_stat3. The first ** integer will be the number of prior index entries that are distinct in ** the left-most column. The second integer will be the number of prior index ** entries that are distinct in the first two columns. The third integer ** will be the number of prior index entries that are distinct in the first ................................................................................ aRoot[i] = pPK->tnum; assert( aRoot[i]>0 ); if( zWhere ){ sqlite4NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere ); }else{ /* The sqlite_stat[13] table already exists. Delete all rows. */ sqlite4VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); } } } /* Open the sqlite_stat[13] tables for writing. */ for(i=0; i<ArraySize(aTable); i++){ ................................................................................ int mxSample; /* Maximum number of samples to accumulate */ int nSample; /* Current number of samples */ u32 iPrn; /* Pseudo-random number used for sampling */ struct Stat3Sample { void *pKey; /* Index key for this sample */ int nKey; /* Bytes of pKey in use */ int nAlloc; /* Bytes of space allocated at pKey */ tRowcnt nEq; /* sqlite_stat3.nEq */ tRowcnt nLt; /* sqlite_stat3.nLt */ tRowcnt nDLt; /* sqlite_stat3.nDLt */ u8 isPSample; /* True if a periodic sample */ u32 iHash; /* Tiebreaker value (pseudo-random) */ } *a; /* An array of samples */ }; #ifdef SQLITE4_ENABLE_STAT3 /* ** Delete a Stat3Accum object. */ static void delStat3Accum(void *pCtx, void *pDel){ sqlite4 *db = (sqlite4*)pCtx; Stat3Accum *p = (Stat3Accum*)pDel; int i; for(i=0; i<p->nSample; i++){ sqlite4DbFree(db, p->a[i].pKey); } sqlite4DbFree(db, p); } /* ** Implementation of the stat3_init(C,S) SQL function. The two parameters ** are the number of rows in the table or index (C) and the number of samples ** to accumulate (S). ................................................................................ }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 ){ void *pKey = p->a[iMin].pKey; int nAlloc = p->a[iMin].nAlloc; 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]; memset(pSample, 0, sizeof(struct Stat3Sample)); pSample->pKey = pKey; pSample->nAlloc = nAlloc; }else{ pSample = &p->a[p->nSample++]; } pKey = sqlite4_value_blob(argv[3], &nKey); if( nKey>pSample->nAlloc ){ sqlite4 *db = sqlite4_context_db_handle(context); ................................................................................ 0, /* xFinalize */ "stat3_get", /* zName */ 0, /* pHash */ 0 /* pDestructor */ }; #endif /* SQLITE4_ENABLE_STAT3 */ /* ** Generate code to do an analysis of all indices associated with ** a single table. */ static void analyzeOneTable( Parse *pParse, /* Parser context */ Table *pTab, /* Table whose indices are to be analyzed */ ................................................................................ #endif iIdxCur = pParse->nTab++; sqlite4VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; KeyInfo *pKey; int regCnt; /* Total number of rows in table. */ int regPrev; /* Previous index key read from database */ int aregCard; /* Cardinality array registers */ #ifdef SQLITE4_ENABLE_STAT3 int addrAddimm; /* Address at top of stat3 output loop */ int addrIsnull; /* Another address within the stat3 loop */ #endif if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); nCol = pIdx->nColumn; pKey = sqlite4IndexKeyinfo(pParse, pIdx); if( iMem+1+(nCol*2)>pParse->nMem ){ pParse->nMem = iMem+1+(nCol*2); } /* Open a cursor to the index to be analyzed. */ assert( iDb==sqlite4SchemaToIndex(db, pIdx->pSchema) ); ................................................................................ sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); sqlite4VdbeChangeP5(v, OPFLAG_APPEND); if( pParse->nMem<regRec ) pParse->nMem = regRec; sqlite4VdbeJumpHere(v, jZeroRows); } /* ** Generate code that will cause the most recent index analysis to ** be loaded into internal hash tables where is can be used. */ static void loadAnalysis(Parse *pParse, int iDb){ Vdbe *v = sqlite4GetVdbe(pParse); |