diff options
author | drh <drh@noemail.net> | 2015-08-27 18:24:02 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2015-08-27 18:24:02 +0000 |
commit | 6860e6fa6fec87334b5c9fe1bc3d0be45cf5ef49 (patch) | |
tree | 2cdbd99e5a1de4477e36bc8989d159c56ae67212 /src | |
parent | b377020ca9d7dab4079c17cb351f54fe2ec1fc99 (diff) | |
download | sqlite-6860e6fa6fec87334b5c9fe1bc3d0be45cf5ef49.tar.gz sqlite-6860e6fa6fec87334b5c9fe1bc3d0be45cf5ef49.zip |
Activate the ability to use expressions in indexes in a query. There are some
test failures, but mostly this seems to work.
FossilOrigin-Name: 42f93f582eccd8a778189aa6c113874f995ab751
Diffstat (limited to 'src')
-rw-r--r-- | src/insert.c | 5 | ||||
-rw-r--r-- | src/where.c | 7 | ||||
-rw-r--r-- | src/whereInt.h | 1 | ||||
-rw-r--r-- | src/whereexpr.c | 6 |
4 files changed, 17 insertions, 2 deletions
diff --git a/src/insert.c b/src/insert.c index 149096c04..73879303d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -93,9 +93,12 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ }else if( x==(-1) ){ pIdx->zColAff[n] = SQLITE_AFF_INTEGER; }else{ + char aff; assert( x==(-2) ); assert( pIdx->aColExpr!=0 ); - pIdx->zColAff[n] = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + if( aff==0 ) aff = SQLITE_AFF_BLOB; + pIdx->zColAff[n] = aff; } } pIdx->zColAff[n] = 0; diff --git a/src/where.c b/src/where.c index 62a90cade..ad1eecd92 100644 --- a/src/where.c +++ b/src/where.c @@ -180,10 +180,13 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ while( pScan->iEquiv<=pScan->nEquiv ){ iCur = pScan->aiCur[pScan->iEquiv-1]; iColumn = pScan->aiColumn[pScan->iEquiv-1]; + assert( iColumn!=(-2) || pScan->pIdxExpr!=0 ); while( (pWC = pScan->pWC)!=0 ){ for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){ if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn + && (iColumn!=(-2) + || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0) && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 @@ -273,9 +276,11 @@ static WhereTerm *whereScanInit( /* memset(pScan, 0, sizeof(*pScan)); */ pScan->pOrigWC = pWC; pScan->pWC = pWC; + pScan->pIdxExpr = 0; if( pIdx ){ j = iColumn; iColumn = pIdx->aiColumn[j]; + if( iColumn==(-2) ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; } if( pIdx && iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; @@ -2224,7 +2229,7 @@ static int whereLoopAddBtreeIndex( int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; assert( saved_nEq==pNew->u.btree.nEq ); - if( iCol==(-1) || (nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ + if( iCol==(-1) || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol>=0 && pProbe->uniqNotNull==0 ){ pNew->wsFlags |= WHERE_UNQ_WANTED; }else{ diff --git a/src/whereInt.h b/src/whereInt.h index 7138b85b2..65c118004 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -286,6 +286,7 @@ struct WhereScan { WhereClause *pOrigWC; /* Original, innermost WhereClause */ WhereClause *pWC; /* WhereClause currently being scanned */ char *zCollName; /* Required collating sequence, if not NULL */ + Expr *pIdxExpr; /* Search for this index expression */ char idxaff; /* Must match this affinity, if zCollName!=NULL */ unsigned char nEquiv; /* Number of entries in aEquiv[] */ unsigned char iEquiv; /* Next unused slot in aEquiv[] */ diff --git a/src/whereexpr.c b/src/whereexpr.c index 88eb5b70a..631a7e0dc 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -872,6 +872,12 @@ static void exprAnalyze( pTerm->leftCursor = pLeft->iTable; pTerm->u.leftColumn = pLeft->iColumn; pTerm->eOperator = operatorMask(op) & opMask; + }else if( prereqLeft!=0 && (prereqLeft&(prereqLeft-1))==0 ){ + int i; + for(i=0; (prereqLeft>>i)<1; i++){} + pTerm->leftCursor = pMaskSet->ix[i]; + pTerm->u.leftColumn = -2; + pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight && pRight->op==TK_COLUMN ){ |