From: drh Date: Thu, 27 Aug 2015 18:24:02 +0000 (+0000) Subject: Activate the ability to use expressions in indexes in a query. There are some X-Git-Tag: version-3.9.0~150^2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6860e6fa6fec87334b5c9fe1bc3d0be45cf5ef49;p=thirdparty%2Fsqlite.git 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 --- diff --git a/manifest b/manifest index 1f899d463c..2b7ae5a002 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\schanges\sfrom\strunk. -D 2015-08-27T16:07:02.026 +C Activate\sthe\sability\sto\suse\sexpressions\sin\sindexes\sin\sa\squery.\s\sThere\sare\ssome\ntest\sfailures,\sbut\smostly\sthis\sseems\sto\swork. +D 2015-08-27T18:24:02.056 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e2218eb228374422969de7b1680eda6864affcef F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -297,7 +297,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b459da1440fd10cb839c716685701f619e3d86a5 +F src/insert.c ef4da9af15ed852509fe49ff9570da6bf4819db6 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 92bafa308607dd985ca389a788cd9e0a2b608712 @@ -414,10 +414,10 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 7b62bfb9a6d98cbba33bfc7914f823a9ad854b33 -F src/whereInt.h 901c17c1e3c82745ad9b85b4471543fa59c980e9 +F src/where.c 29851b4a1a93934fef1bde3d0a1e7407efd57543 +F src/whereInt.h 292d3ac90da4eab1e03ac8452f1add746bcafaa1 F src/wherecode.c 3d9113cc307ffeed58db41fe9f2d807c94787ab5 -F src/whereexpr.c 1a308d1ee5144890d21ea9cf70d49bc96a83432b +F src/whereexpr.c 990ed42b5940d4000e7e61887a4bbed412c80488 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1380,7 +1380,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5611130a595e7f0b6d5f21d76f2755e9c09c7810 cbc3c9a8bf169ae0b21f26855038502c6cc25cfe -R 5eb2cbc19058900f308a8789aae8ba36 +P c80e9e8e8cc1e7676d7c782ee0827726875db79e +R ff3e8c131dda72b26dbe6f001a80b515 U drh -Z a8340d48ea4d99e733a68ecfeafbe44a +Z 3e34cddbe64a99afb651902a91a49bea diff --git a/manifest.uuid b/manifest.uuid index f9a3e724f5..62cf69b6e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c80e9e8e8cc1e7676d7c782ee0827726875db79e \ No newline at end of file +42f93f582eccd8a778189aa6c113874f995ab751 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 149096c045..73879303de 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 62a90cade1..ad1eecd920 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; knTerm; 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 7138b85b25..65c1180048 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 88eb5b70aa..631a7e0dce 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 ){