aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2009-08-18 16:24:58 +0000
committerdan <dan@noemail.net>2009-08-18 16:24:58 +0000
commite275dc3fb865fad483dad13a37a6b82314c698cb (patch)
treea44fa5f4e36957d351f03fb773b8c34ba9c67fa6 /src
parent02fa469619720661e02b351d78b001d1fbc3451a (diff)
downloadsqlite-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.c260
-rw-r--r--src/build.c9
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/vdbe.c49
-rw-r--r--src/where.c40
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;