-C Very\sslight\ssmaller\sand\sfaster\ssqlite3SelectNew()
-D 2017-04-11T16:44:39.910
+C Smaller\sand\sfaster\simplementation\sof\sexprMightBeIndexed().
+D 2017-04-11T18:06:48.387
F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a
F src/where.c 1d14e18f32231fa7969e718e7b60ef749b0065e2a7e1b6b00883b20732d280f1
F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df
F src/wherecode.c 943e32e9dccd0af802e0683ae11071c8bd808364e5908a5fb66758bd404c8681
-F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c
+F src/whereexpr.c e913aaa7b73ffcce66abcea5f197e2c538d48b5df78d0b7bba8ff4d73cc2e745
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e
-R 5f2f74eb29544d7d3c639e823e92116e
+P 4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a
+R 1aa45dcbe6873a793fc57d44af855002
U drh
-Z 7231f0f16860dcf4ac8b22d5fa5d18a1
+Z c24847878c6bf2e9fe8bedbea41e582e
** Expression pExpr is one operand of a comparison operator that might
** be useful for indexing. This routine checks to see if pExpr appears
** in any index. Return TRUE (1) if pExpr is an indexed term and return
-** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
-** number of the table that is indexed and *piColumn to the column number
+** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor
+** number of the table that is indexed and aiCurCol[1] to the column number
** of the column that is indexed, or XN_EXPR (-2) if an expression is being
** indexed.
**
** true even if that particular column is not indexed, because the column
** might be added to an automatic index later.
*/
-static int exprMightBeIndexed(
+static SQLITE_NOINLINE int exprMightBeIndexed2(
SrcList *pFrom, /* The FROM clause */
- int op, /* The specific comparison operator */
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
- Expr *pExpr, /* An operand of a comparison operator */
- int *piCur, /* Write the referenced table cursor number here */
- int *piColumn /* Write the referenced table column number here */
+ int *aiCurCol, /* Write the referenced table cursor and column here */
+ Expr *pExpr /* An operand of a comparison operator */
){
Index *pIdx;
int i;
int iCur;
-
+ for(i=0; mPrereq>1; i++, mPrereq>>=1){}
+ iCur = pFrom->a[i].iCursor;
+ for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->aColExpr==0 ) continue;
+ for(i=0; i<pIdx->nKeyCol; i++){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ aiCurCol[0] = iCur;
+ aiCurCol[1] = XN_EXPR;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+static int exprMightBeIndexed(
+ SrcList *pFrom, /* The FROM clause */
+ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
+ int *aiCurCol, /* Write the referenced table cursor & column here */
+ Expr *pExpr, /* An operand of a comparison operator */
+ int op /* The specific comparison operator */
+){
/* If this expression is a vector to the left or right of a
** inequality constraint (>, <, >= or <=), perform the processing
** on the first element of the vector. */
}
if( pExpr->op==TK_COLUMN ){
- *piCur = pExpr->iTable;
- *piColumn = pExpr->iColumn;
+ aiCurCol[0] = pExpr->iTable;
+ aiCurCol[1] = pExpr->iColumn;
return 1;
}
if( mPrereq==0 ) return 0; /* No table references */
if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */
- for(i=0; mPrereq>1; i++, mPrereq>>=1){}
- iCur = pFrom->a[i].iCursor;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->aColExpr==0 ) continue;
- for(i=0; i<pIdx->nKeyCol; i++){
- if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
- if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
- *piCur = iCur;
- *piColumn = XN_EXPR;
- return 1;
- }
- }
- }
- return 0;
+ return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
}
/*
pTerm->iParent = -1;
pTerm->eOperator = 0;
if( allowedOp(op) ){
- int iCur, iColumn;
+ int aiCurCol[2];
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
}
- if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
- pTerm->leftCursor = iCur;
- pTerm->u.leftColumn = iColumn;
+ if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
+ pTerm->leftCursor = aiCurCol[0];
+ pTerm->u.leftColumn = aiCurCol[1];
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
- && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
+ && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
){
WhereTerm *pNew;
Expr *pDup;
pNew = pTerm;
}
exprCommute(pParse, pDup);
- pNew->leftCursor = iCur;
- pNew->u.leftColumn = iColumn;
+ pNew->leftCursor = aiCurCol[0];
+ pNew->u.leftColumn = aiCurCol[1];
testcase( (prereqLeft | extraRight) != prereqLeft );
pNew->prereqRight = prereqLeft | extraRight;
pNew->prereqAll = prereqAll;