aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/where.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/where.c b/src/where.c
index 10121c4e3..49d536432 100644
--- a/src/where.c
+++ b/src/where.c
@@ -1657,6 +1657,7 @@ static void bestTransientIndex(
double costTempIdx; /* per-query cost of the transient index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
+ Table *pTable; /* Table tht might be indexed */
if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
/* We already have some kind of index in use for this query. */
@@ -1678,11 +1679,14 @@ static void bestTransientIndex(
}
/* Search for any equality comparison term */
+ pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( pTerm->leftCursor==pSrc->iCursor
&& (pTerm->prereqRight & notReady)==0
&& (pTerm->eOperator & WO_EQ)!=0
+ && sqlite3IndexAffinityOk(pTerm->pExpr,
+ pTable->aCol[pTerm->u.leftColumn].affinity)
){
WHERETRACE(("auto-index reduces cost from %.2f to %.2f\n",
pCost->rCost, costTempIdx));
@@ -1719,6 +1723,7 @@ static void constructTransientIndex(
int addrTop; /* Top of the index fill loop */
int regRecord; /* Register holding an index record */
int n; /* Column counter */
+ CollSeq *pColl; /* Collating sequence to on a column */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
@@ -1730,16 +1735,21 @@ static void constructTransientIndex(
/* Count the number of columns that will be added to the index */
nColumn = 0;
+ pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( pTerm->leftCursor==pSrc->iCursor
&& (pTerm->prereqRight & notReady)==0
&& (pTerm->eOperator & WO_EQ)!=0
+ && sqlite3IndexAffinityOk(pTerm->pExpr,
+ pTable->aCol[pTerm->u.leftColumn].affinity)
){
nColumn++;
}
}
assert( nColumn>0 );
+ pLevel->plan.nEq = nColumn;
+ pLevel->plan.wsFlags = WHERE_COLUMN_EQ | WO_EQ;
/* Construct the Index object to describe this index */
nByte = sizeof(Index);
@@ -1754,17 +1764,21 @@ static void constructTransientIndex(
pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
pIdx->zName = "auto-index";
pIdx->nColumn = nColumn;
- pIdx->pTable = pTable = pSrc->pTab;
+ pIdx->pTable = pTable;
n = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( pTerm->leftCursor==pSrc->iCursor
&& (pTerm->prereqRight & notReady)==0
&& (pTerm->eOperator & WO_EQ)!=0
+ && sqlite3IndexAffinityOk(pTerm->pExpr,
+ pTable->aCol[pTerm->u.leftColumn].affinity)
){
int iCol = pTerm->u.leftColumn;
+ Expr *pX;
pIdx->aiColumn[n] = iCol;
- pIdx->azColl[n] = pTable->aCol[iCol].zColl;
- if( pIdx->azColl[n]==0 ) pIdx->azColl[n] = "BINARY";
+ pX = pTerm->pExpr;
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
+ pIdx->azColl[n] = pColl->zName;
n++;
}
}
@@ -1775,6 +1789,7 @@ static void constructTransientIndex(
assert( pLevel->iIdxCur>=0 );
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pLevel->iIdxCur, nColumn+1, 0,
(char*)pKeyinfo, P4_KEYINFO_HANDOFF);
+ VdbeComment((v, "auto-idx for %s", pTable->zName));
/* Fill the transient index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
@@ -4060,8 +4075,14 @@ WhereInfo *sqlite3WhereBegin(
#endif /* SQLITE_OMIT_EXPLAIN */
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab;
+ pLevel->iTabCur = pTabItem->iCursor;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue;
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
+ if( pLevel->plan.wsFlags & WHERE_TEMP_INDEX ){
+ constructTransientIndex(pParse, pWC, pTabItem, notReady, pLevel);
+ }
+ continue;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
@@ -4084,7 +4105,6 @@ WhereInfo *sqlite3WhereBegin(
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
- pLevel->iTabCur = pTabItem->iCursor;
if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
constructTransientIndex(pParse, pWC, pTabItem, notReady, pLevel);
}else if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){