-C Fix\sa\scrash\sthat\scan\soccur\sfollowing\san\sOOM\sfault.
-D 2013-08-15T18:43:21.395
+C Fix\sa\scrash\sthat\scan\soccur\sif\sthe\ssqlite_stat3\sor\ssqlite_stat4\stable\sis\scorrupt.
+D 2013-08-15T19:56:32.997
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c e60d6329f77e84bac0a300d5227c28a05f5ff5de
+F src/analyze.c 9533c7e948398bf9628178d6bf9a7845d7e29046
F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
F test/analyze6.test 19151da2c4e918905d2081b74ac5c4d47fc850ab
F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f
F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88
-F test/analyze9.test 83e74db42a49bb185e05f3a44a5d65323aba8a40
+F test/analyze9.test b73f9514af962a139d2c61d7741b0ba090789ea2
F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 71070c9fce86103f174220e07771df99b2e01405
-R fd0e4baaf9a9ffd0fe23644f24c090cf
+P 9f80b2687012ab7c4d6d654fe19f40878bd78bd8
+R abb1a9d20998265ab3bcabc4adb13b2c
U dan
-Z 1c4d6e6edcc7281c470c7559e77faff9
+Z 4cffc531446b09bd876c8b206583a719
}
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3)
+
+/*
+** Populate the pIdx->aAvgEq[] array based on the samples currently
+** stored in pIdx->aSample[].
+*/
+static void initAvgEq(Index *pIdx){
+ if( pIdx ){
+ IndexSample *aSample = pIdx->aSample;
+ IndexSample *pFinal = &aSample[pIdx->nSample-1];
+ int iCol;
+ for(iCol=0; iCol<pIdx->nColumn; iCol++){
+ int i; /* Used to iterate through samples */
+ tRowcnt sumEq = 0; /* Sum of the nEq values */
+ int nSum = 0; /* Number of terms contributing to sumEq */
+ tRowcnt avgEq = 0;
+ tRowcnt nDLt = pFinal->anDLt[iCol];
+
+ /* Set nSum to the number of distinct (iCol+1) field prefixes that
+ ** occur in the stat4 table for this index before pFinal. Set
+ ** sumEq to the sum of the nEq values for column iCol for the same
+ ** set (adding the value only once where there exist dupicate
+ ** prefixes). */
+ for(i=0; i<(pIdx->nSample-1); i++){
+ if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
+ sumEq += aSample[i].anEq[iCol];
+ nSum++;
+ }
+ }
+ if( nDLt>nSum ){
+ avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
+ }
+ if( avgEq==0 ) avgEq = 1;
+ pIdx->aAvgEq[iCol] = avgEq;
+ if( pIdx->nSampleCol==1 ) break;
+ }
+ }
+}
+
/*
** Load the content from either the sqlite_stat4 or sqlite_stat3 table
** into the relevant Index.aSample[] arrays.
sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
char *zSql; /* Text of the SQL statement */
Index *pPrevIdx = 0; /* Previous index in the loop */
- int idx = 0; /* slot in pIdx->aSample[] for next sample */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
assert( db->lookaside.bEnabled==0 );
nAvgCol = pIdx->nColumn;
}
pIdx->nSampleCol = nIdxCol;
- pIdx->nSample = nSample;
nByte = sizeof(IndexSample) * nSample;
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
- for(i=0; i<pIdx->nSample; i++){
+ for(i=0; i<nSample; i++){
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */
- int i; /* Loop counter */
int nCol = 1; /* Number of columns in index */
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
pIdx = sqlite3FindIndex(db, zIndex, zDb);
if( pIdx==0 ) continue;
- if( pIdx==pPrevIdx ){
- idx++;
- }else{
- pPrevIdx = pIdx;
- idx = 0;
- }
- assert( idx<pIdx->nSample );
/* This next condition is true if data has already been loaded from
** the sqlite_stat4 table. In this case ignore stat3 data. */
- if( bStat3 && pIdx->aSample[idx].anEq[0] ) continue;
- pSample = &pIdx->aSample[idx];
-
- if( bStat3==0 ){
- nCol = pIdx->nColumn+1;
+ nCol = pIdx->nSampleCol;
+ if( bStat3 && nCol>1 ) continue;
+ if( pIdx!=pPrevIdx ){
+ initAvgEq(pPrevIdx);
+ pPrevIdx = pIdx;
}
+ pSample = &pIdx->aSample[pIdx->nSample++];
decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0);
decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0);
decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0);
- if( idx==pIdx->nSample-1 ){
- IndexSample *aSample = pIdx->aSample;
- int iCol;
- for(iCol=0; iCol<pIdx->nColumn; iCol++){
- tRowcnt sumEq = 0; /* Sum of the nEq values */
- int nSum = 0; /* Number of terms contributing to sumEq */
- tRowcnt avgEq = 0;
- tRowcnt nDLt = pSample->anDLt[iCol];
-
- /* Set nSum to the number of distinct (iCol+1) field prefixes that
- ** occur in the stat4 table for this index before pSample. Set
- ** sumEq to the sum of the nEq values for column iCol for the same
- ** set (adding the value only once where there exist dupicate
- ** prefixes). */
- for(i=0; i<(pIdx->nSample-1); i++){
- if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
- sumEq += aSample[i].anEq[iCol];
- nSum++;
- }
- }
- if( nDLt>nSum ){
- avgEq = (pSample->anLt[iCol] - sumEq)/(nDLt - nSum);
- }
- if( avgEq==0 ) avgEq = 1;
- pIdx->aAvgEq[iCol] = avgEq;
- if( bStat3 ) break;
- }
- }
-
pSample->n = sqlite3_column_bytes(pStmt, 4);
pSample->p = sqlite3DbMallocZero(db, pSample->n);
if( pSample->p==0 ){
}
memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
}
+ initAvgEq(pPrevIdx);
return sqlite3_finalize(pStmt);
}
ANALYZE;
}
+#-------------------------------------------------------------------------
+# This was also crashing.
+#
+reset_db
+do_execsql_test 6.1 {
+ CREATE TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a);
+ CREATE INDEX i2 ON t1(b);
+ INSERT INTO t1 VALUES(1, 1);
+ INSERT INTO t1 VALUES(2, 2);
+ INSERT INTO t1 VALUES(3, 3);
+ INSERT INTO t1 VALUES(4, 4);
+ INSERT INTO t1 VALUES(5, 5);
+ ANALYZE;
+ PRAGMA writable_schema = 1;
+ CREATE TEMP TABLE x1 AS
+ SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat4
+ ORDER BY (rowid%5), rowid;
+ DELETE FROM sqlite_stat4;
+ INSERT INTO sqlite_stat4 SELECT * FROM x1;
+ PRAGMA writable_schema = 0;
+ ANALYZE sqlite_master;
+}
+do_execsql_test 6.2 {
+ SELECT * FROM t1 WHERE a = 'abc';
+}
+
finish_test