aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2016-08-26 19:31:29 +0000
committerdrh <drh@noemail.net>2016-08-26 19:31:29 +0000
commit6fc8f364908faf289d19ebd349c0a4c2995bcd95 (patch)
tree9ffb144a5a712522be28e9745484f0e57a44d0a1 /src/expr.c
parent0c36fca004ee51ef626a3df0e74d191fbdc609fe (diff)
downloadsqlite-6fc8f364908faf289d19ebd349c0a4c2995bcd95.tar.gz
sqlite-6fc8f364908faf289d19ebd349c0a4c2995bcd95.zip
Enhance sqlite3FindInIndex() so that it is able to make use of the
primary keys at the end of an index. FossilOrigin-Name: 4b589fbfcc4265902de0f552961d2df497a184da
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/expr.c b/src/expr.c
index a62538c55..3a5075719 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2099,11 +2099,11 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
- Parse *pParse,
- Expr *pX,
- u32 inFlags,
- int *prRhsHasNull,
- int *aiMap
+ Parse *pParse, /* Parsing context */
+ Expr *pX, /* The right-hand side (RHS) of the IN operator */
+ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
+ int *prRhsHasNull, /* Register holding NULL status. See notes */
+ int *aiMap /* Mapping from Index fields to RHS fields */
){
Select *p; /* SELECT to the right of IN operator */
int eType = 0; /* Type of RHS table. IN_INDEX_* */
@@ -2200,9 +2200,13 @@ int sqlite3FindInIndex(
** to this collation sequence. */
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
- if( pIdx->nKeyCol<nExpr ) continue;
- if( mustBeUnique && (pIdx->nKeyCol!=nExpr || !IsUniqueIndex(pIdx)) ){
- continue;
+ if( pIdx->nColumn<nExpr ) continue;
+ if( mustBeUnique ){
+ if( pIdx->nKeyCol>nExpr
+ ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
+ ){
+ continue;
+ }
}
for(i=0; i<nExpr; i++){
@@ -2211,11 +2215,11 @@ int sqlite3FindInIndex(
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
int j;
- if( pReq==0 ) break;
-
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
for(j=0; j<nExpr; j++){
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
assert( pIdx->azColl[j] );
+ if( pReq==0 ) continue;
if( sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ) continue;
break;
}