SQLite4
Check-in [8a25008dfe]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:8a25008dfe3b6b4bbae05cbc7951b93ade088b9e
Date: 2013-06-25 15:28:18
User: dan
Comment:Fix comments and a memory leak in analyze.c.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

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);