diff options
author | dan <dan@noemail.net> | 2009-08-18 16:24:58 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2009-08-18 16:24:58 +0000 |
commit | e275dc3fb865fad483dad13a37a6b82314c698cb (patch) | |
tree | a44fa5f4e36957d351f03fb773b8c34ba9c67fa6 /src | |
parent | 02fa469619720661e02b351d78b001d1fbc3451a (diff) | |
download | sqlite-e275dc3fb865fad483dad13a37a6b82314c698cb.tar.gz sqlite-e275dc3fb865fad483dad13a37a6b82314c698cb.zip |
Change the sqlite_stat2 schema to be more flexible.
FossilOrigin-Name: ded9dec6459baf21e01f63250db5ace57f390e7a
Diffstat (limited to 'src')
-rw-r--r-- | src/analyze.c | 260 | ||||
-rw-r--r-- | src/build.c | 9 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/vdbe.c | 49 | ||||
-rw-r--r-- | src/where.c | 40 |
5 files changed, 176 insertions, 183 deletions
diff --git a/src/analyze.c b/src/analyze.c index e8c7c3717..c6c279f27 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -32,7 +32,7 @@ static void openStatTable( const char *zWhere /* Delete entries associated with this table */ ){ const char *aName[] = { "sqlite_stat1", "sqlite_stat2" }; - const char *aCols[] = { "tbl,idx,stat", "tbl,idx," SQLITE_INDEX_SAMPLE_COLS }; + const char *aCols[] = { "tbl,idx,stat", "tbl,idx,sampleno,sample" }; int aRoot[] = {0, 0}; int aCreateTbl[] = {0, 0}; @@ -94,7 +94,6 @@ static void analyzeOneTable( ){ Index *pIdx; /* An index to being analyzed */ int iIdxCur; /* Index of VdbeCursor for index being analyzed */ - int nCol; /* Number of columns in the index */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int topOfLoop; /* The top of the loop */ @@ -102,6 +101,21 @@ static void analyzeOneTable( int addr; /* The address of an instruction */ int iDb; /* Index of database containing pTab */ + + /* Assign the required registers. */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regSampleno = iMem++; /* Register containing next sample number */ + int regCol = iMem++; /* Content of a column analyzed table */ + + int regSamplerecno = iMem++; /* Next sample index record number */ + int regRecno = iMem++; /* Register next index record number */ + int regRec = iMem++; /* Register holding completed record */ + int regTemp = iMem++; /* Temporary use register */ + int regTemp2 = iMem++; /* Temporary use register */ + int regRowid = iMem++; /* Rowid for the inserted record */ + int regCount = iMem++; /* Total number of records in table */ + v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){ /* Do no analysis for tables that have no indices */ @@ -120,39 +134,43 @@ static void analyzeOneTable( /* Establish a read-lock on the table at the shared-cache level. */ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - iMem += 3; iIdxCur = pParse->nTab++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol = pIdx->nColumn; KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - int regFields; /* Register block for building records */ - int regRec; /* Register holding completed record */ - int regTemp; /* Temporary use register */ - int regCol; /* Content of a column from the table being analyzed */ - int regRowid; /* Rowid for the inserted record */ - int regF2; - int regStat2; - - /* Open a cursor to the index to be analyzed - */ + + if( iMem+1+(nCol*2)>pParse->nMem ){ + pParse->nMem = iMem+1+(nCol*2); + } + + /* Open a cursor to the index to be analyzed. */ assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) ); - nCol = pIdx->nColumn; sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); - regStat2 = iMem+nCol*2+1; - regFields = regStat2+2+SQLITE_INDEX_SAMPLES; - regTemp = regRowid = regCol = regFields+3; - regRec = regCol+1; - if( regRec>pParse->nMem ){ - pParse->nMem = regRec; - } - /* Fill in the register with the total number of rows. */ + /* If this iteration of the loop is generating code to analyze the + ** first index in the pTab->pIndex list, then register regCount has + ** not been populated. In this case populate it now. */ if( pTab->pIndex==pIdx ){ - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, iMem-3); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); + sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); } - sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem-2); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem-1); + sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); + + /* Zero the regSampleno and regRecno registers. */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno); + + /* If there are less than INDEX_SAMPLES records in the index, then + ** set the contents of regSampleRecno to integer value INDEX_SAMPLES. + ** Otherwise, set it to zero. This is to ensure that if there are + ** less than the said number of entries in the index, no samples at + ** all are collected. */ + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno); + sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, sqlite3VdbeCurrentAddr(v)+2, + regCount); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regSamplerecno); /* Memory cells are used as follows. All memory cell addresses are ** offset by iMem. That is, cell 0 below is actually cell iMem, cell @@ -167,8 +185,6 @@ static void analyzeOneTable( ** nCol+1..2*nCol: Previous value of indexed columns, from left to ** right. ** - ** 2*nCol+1..2*nCol+10: 10 evenly spaced samples. - ** ** Cells iMem through iMem+nCol are initialized to 0. The others ** are initialized to NULL. */ @@ -179,7 +195,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1); } - /* Start the analysis loop. This loop runs through all the entries inof + /* Start the analysis loop. This loop runs through all the entries in ** the index b-tree. */ endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); @@ -189,15 +205,45 @@ static void analyzeOneTable( for(i=0; i<nCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol); if( i==0 ){ - sqlite3VdbeAddOp3(v, OP_Sample, iMem-3, regCol, regStat2+2); + + /* Check if the record that cursor iIdxCur points to contains a + ** value that should be stored in the sqlite_stat2 table. If so, + ** store it. */ + int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno); + assert( regTabname+1==regIdxname + && regTabname+2==regSampleno + && regTabname+3==regCol + ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid); + + /* Calculate new values for regSamplerecno and regSampleno. + ** + ** sampleno = sampleno + 1 + ** samplerecno = samplerecno+(remaining records)/(remaining samples) + */ + sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1); + sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regCount, regTemp); + sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2); + sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2); + sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp); + sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno); + + sqlite3VdbeJumpHere(v, ne); + sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1); } + + assert( sqlite3VdbeCurrentAddr(v)==(topOfLoop+14+2*i) ); sqlite3VdbeAddOp3(v, OP_Ne, regCol, 0, iMem+nCol+i+1); + /**** TODO: add collating sequence *****/ sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; i<nCol; i++){ - sqlite3VdbeJumpHere(v, topOfLoop + 1 + 2*(i + 1)); + sqlite3VdbeJumpHere(v, topOfLoop+14+2*i); sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); } @@ -226,33 +272,20 @@ static void analyzeOneTable( ** is never possible. */ addr = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); - sqlite3VdbeAddOp4(v, OP_String8, 0, regFields, 0, pTab->zName, 0); - sqlite3VdbeAddOp4(v, OP_String8, 0, regFields+1, 0, pIdx->zName, 0); - regF2 = regFields+2; - sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regF2); + sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno); for(i=0; i<nCol; i++){ sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0); - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regF2, regF2); + sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno); sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp); sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1); sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp); sqlite3VdbeAddOp1(v, OP_ToInt, regTemp); - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regF2, regF2); + sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno); } - sqlite3VdbeAddOp4(v, OP_MakeRecord, regFields, 3, regRec, "aaa", 0); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - - /* Store the results in sqlite_stat2. */ - sqlite3VdbeAddOp4(v, OP_String8, 0, regStat2, 0, pTab->zName, 0); - sqlite3VdbeAddOp4(v, OP_String8, 0, regStat2+1, 0, pIdx->zName, 0); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regStat2, SQLITE_INDEX_SAMPLES+2, - regRec, "aabbbbbbbbbb", 0 - ); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid); - sqlite3VdbeJumpHere(v, addr); } } @@ -461,85 +494,80 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ sqlite3DbFree(db, zSql); } - /* Load the statistics from the sqlite_stat2 table */ + /* Load the statistics from the sqlite_stat2 table. */ if( rc==SQLITE_OK ){ + sqlite3_stmt *pStmt = 0; + zSql = sqlite3MPrintf(db, - "SELECT idx," SQLITE_INDEX_SAMPLE_COLS " FROM %Q.sqlite_stat2", - sInfo.zDatabase + "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase ); - if( zSql ){ - sqlite3_stmt *pStmt = 0; - (void)sqlite3SafetyOff(db); - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); - if( rc==SQLITE_OK ){ - while( SQLITE_ROW==sqlite3_step(pStmt) ){ - char *zIndex = (char *)sqlite3_column_text(pStmt, 0); - Index *pIdx; - pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase); - if( pIdx ){ - char *pSpace; - IndexSample *pSample; - int iCol; - int nAlloc = SQLITE_INDEX_SAMPLES * sizeof(IndexSample); - for(iCol=1; iCol<=SQLITE_INDEX_SAMPLES; iCol++){ - int eType = sqlite3_column_type(pStmt, iCol); - if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ - nAlloc += sqlite3_column_bytes(pStmt, iCol); + if( !zSql ){ + return SQLITE_NOMEM; + } + + (void)sqlite3SafetyOff(db); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + assert( rc!=SQLITE_MISUSE ); + (void)sqlite3SafetyOn(db); + sqlite3DbFree(db, zSql); + (void)sqlite3SafetyOff(db); + + if( rc==SQLITE_OK ){ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex = (char *)sqlite3_column_text(pStmt, 0); + Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase); + if( pIdx ){ + int iSample = sqlite3_column_int(pStmt, 1); + if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){ + int eType = sqlite3_column_type(pStmt, 2); + + if( pIdx->aSample==0 ){ + pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(db, + sizeof(IndexSample)*SQLITE_INDEX_SAMPLES + ); + if( pIdx->aSample==0 ){ + break; } - } - pSample = sqlite3DbMallocRaw(db, nAlloc); - if( !pSample ){ - rc = SQLITE_NOMEM; - break; - } - sqlite3DbFree(db, pIdx->aSample); - pIdx->aSample = pSample; - pSpace = (char *)&pSample[SQLITE_INDEX_SAMPLES]; - for(iCol=1; iCol<=SQLITE_INDEX_SAMPLES; iCol++){ - int eType = sqlite3_column_type(pStmt, iCol); - pSample[iCol-1].eType = eType; - switch( eType ){ - case SQLITE_BLOB: - case SQLITE_TEXT: { - const char *z = (const char *)( - (eType==SQLITE_BLOB) ? - sqlite3_column_blob(pStmt, iCol): - sqlite3_column_text(pStmt, iCol) - ); - int n = sqlite3_column_bytes(pStmt, iCol); - if( n>24 ){ - n = 24; - } - pSample[iCol-1].nByte = n; - pSample[iCol-1].u.z = pSpace; - memcpy(pSpace, z, n); - pSpace += n; - break; + } + + if( pIdx->aSample ){ + IndexSample *pSample = &pIdx->aSample[iSample]; + if( pSample->eType==SQLITE_TEXT || pSample->eType==SQLITE_BLOB ){ + sqlite3DbFree(db, pSample->u.z); + } + pSample->eType = eType; + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + pSample->u.r = sqlite3_column_double(pStmt, 2); + }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + const char *z = (const char *)( + (eType==SQLITE_BLOB) ? + sqlite3_column_blob(pStmt, 2): + sqlite3_column_text(pStmt, 2) + ); + int n = sqlite3_column_bytes(pStmt, 2); + if( n>24 ){ + n = 24; } - case SQLITE_INTEGER: - case SQLITE_FLOAT: - pSample[iCol-1].u.r = sqlite3_column_double(pStmt, iCol); - break; - case SQLITE_NULL: + pSample->nByte = n; + pSample->u.z = sqlite3DbMallocRaw(db, n); + if( pSample->u.z ){ + memcpy(pSample->u.z, z, n); + }else{ break; - } - } - } - } - if( rc==SQLITE_NOMEM ){ - sqlite3_finalize(pStmt); - }else{ - rc = sqlite3_finalize(pStmt); - } + } + } + } + } + } } - (void)sqlite3SafetyOn(db); - sqlite3DbFree(db, zSql); - }else{ - rc = SQLITE_NOMEM; + rc = sqlite3_finalize(pStmt); } + (void)sqlite3SafetyOn(db); } - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + } return rc; } diff --git a/src/build.c b/src/build.c index 8cf9ec753..3e9b0ec96 100644 --- a/src/build.c +++ b/src/build.c @@ -343,6 +343,15 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ static void freeIndex(Index *p){ sqlite3 *db = p->pTable->dbMem; /* testcase( db==0 ); */ + if( p->aSample ){ + int i; + for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ + int e = p->aSample[i].eType; + if( e==SQLITE_BLOB || e==SQLITE_TEXT ){ + sqlite3DbFree(db, p->aSample[i].u.z); + } + } + } sqlite3DbFree(db, p->aSample); sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3912715e5..56dd912ac 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -78,7 +78,6 @@ #endif #define SQLITE_INDEX_SAMPLES 10 -#define SQLITE_INDEX_SAMPLE_COLS "s1,s2,s3,s4,s5,s6,s7,s8,s9,s10" /* ** This macro is used to "hide" some ugliness in casting an int diff --git a/src/vdbe.c b/src/vdbe.c index 9bae94084..44d12f68d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1205,9 +1205,9 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ /* Opcode: Divide P1 P2 P3 * * ** ** Divide the value in register P1 by the value in register P2 -** and store the result in register P3. If the value in register P2 -** is zero, then the result is NULL. -** If either input is NULL, the result is NULL. +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * ** @@ -4974,49 +4974,6 @@ case OP_Expire: { break; } - -/* Opcode: Sample P1 P2 P3 * * -** -** Register P1 contains the total number of rows in the index being -** analyzed. Register P1+1 contains an integer between 0 and 9, the -** index of the next sample required. Register P1+2 contains an index -** between 1 and *P1, the number of the next sample required. Register -** P1+3 contains the current row index. -** -** If the integer in register P1+3 is the same as the integer in register -** P1+1, then the following takes place: -** -** (a) the contents of register P1+1 is incremented. -** -** (b) the contents of the register identified by parameter P2 is -** copied to register number (P3 + X), where X is the newly -** incremented value of register P1+1. -** -** (c) register P1+2 is set to the index of the next sample required. -*/ -case OP_Sample: { - int p1 = pOp->p1; - i64 iReq = p->aMem[p1+2].u.i; - i64 iRow = p->aMem[p1+3].u.i; - - while( iReq==iRow ){ - i64 nRow = p->aMem[p1].u.i; - int iSample = ++p->aMem[p1+1].u.i; - Mem *pReg = &p->aMem[pOp->p3 + iSample - 1]; - - assert( pReg<&p->aMem[p->nMem] ); - sqlite3VdbeMemShallowCopy(pReg, &p->aMem[pOp->p2], MEM_Ephem); - Deephemeralize(pReg); - if( iSample==SQLITE_INDEX_SAMPLES ){ - iReq = 0; - }else{ - iReq = iRow + (nRow-iRow)/(SQLITE_INDEX_SAMPLES - iSample); - p->aMem[p1+2].u.i = iReq; - } - } - break; -} - #ifndef SQLITE_OMIT_SHARED_CACHE /* Opcode: TableLock P1 P2 P3 P4 * ** diff --git a/src/where.c b/src/where.c index d96578f54..16d89606c 100644 --- a/src/where.c +++ b/src/where.c @@ -1929,40 +1929,40 @@ static int whereRangeRegion( if( eType==SQLITE_BLOB ){ z = (const u8 *)sqlite3_value_blob(pVal); pColl = db->pDfltColl; - assert( pColl->enc==SQLITE_UTF8 ); + assert( pColl->enc==SQLITE_UTF8 ); }else{ - pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, *pIdx->azColl, 0); - if( sqlite3CheckCollSeq(pParse, pColl) ){ - return SQLITE_ERROR; - } + pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, *pIdx->azColl, 0); + if( sqlite3CheckCollSeq(pParse, pColl) ){ + return SQLITE_ERROR; + } z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); - if( !z ){ - return SQLITE_NOMEM; - } + if( !z ){ + return SQLITE_NOMEM; + } assert( z && pColl && pColl->xCmp ); } n = sqlite3ValueBytes(pVal, pColl->enc); for(i=0; i<SQLITE_INDEX_SAMPLES; i++){ - int r; + int r; int eSampletype = aSample[i].eType; if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue; if( (eSampletype!=eType) ) break; if( pColl->enc==SQLITE_UTF8 ){ - r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); + r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); }else{ - int nSample; - char *zSample = sqlite3Utf8to16( + int nSample; + char *zSample = sqlite3Utf8to16( db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample ); - if( !zSample ){ - assert( db->mallocFailed ); - return SQLITE_NOMEM; - } - r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); - sqlite3DbFree(db, zSample); + if( !zSample ){ + assert( db->mallocFailed ); + return SQLITE_NOMEM; + } + r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); + sqlite3DbFree(db, zSample); } - if( r>0 ) break; + if( r>0 ) break; } } @@ -2246,7 +2246,7 @@ static void bestBtreeIndex( if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); - whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound); + whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound); if( pTop ){ wsFlags |= WHERE_TOP_LIMIT; used |= pTop->prereqRight; |