diff --git a/manifest b/manifest index 0c5a5294e3..ec12a04f7c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\sMSVC\smakefile. -D 2015-05-13T04:50:30.732 +C An\searly\sattempt\sto\sget\sindexes\sto\swork\swith\sthe\sIS\soperator.\s\sThis\scode\npasses\stests,\sbut\smuch\smore\stesting\sis\sneeded\sto\sverify\sthat\sit\sworks\son\nall\scorner\scases. +D 2015-05-13T15:24:07.257 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -307,8 +307,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c ce2cb2d06faab54d1bce3e739bec79e063dd9113 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 85fff9c40569ccb79c3177419b339e7d7df566cb -F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c +F src/where.c 48e3c1f0a8a7ecbaeb5a57c195254243d49430ba +F src/whereInt.h 6b5a8ac7b4adc055176c3330d755735ed674335d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 @@ -1258,7 +1258,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b33f1bacfdb34fe66b7b073e68bfac38498d6e88 -R 786cf9bafb843a30daaea508385a36b1 -U mistachkin -Z cf0d8cd171ac487c0fd87c289759c254 +P 59e3e9e764440b7feaafadff74f422535d21bca2 +R 9f6038338a4c8e424f8c4ba92f9afc16 +T *branch * index-is-operator +T *sym-index-is-operator * +T -sym-trunk * +U drh +Z a0eadd388567e992c46f2fabbded464e diff --git a/manifest.uuid b/manifest.uuid index af09740391..877d59c28e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59e3e9e764440b7feaafadff74f422535d21bca2 \ No newline at end of file +6f7f1673d00d216a5aa456acb44793a14f3b3d91 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 85eb00b46b..6bbfaca879 100644 --- a/src/where.c +++ b/src/where.c @@ -363,7 +363,7 @@ static int allowedOp(int op){ assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL; + return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; } /* @@ -416,6 +416,8 @@ static u16 operatorMask(int op){ c = WO_IN; }else if( op==TK_ISNULL ){ c = WO_ISNULL; + }else if( op==TK_IS ){ + c = WO_EQ; }else{ assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); c = (u16)(WO_EQ<<(op-TK_EQ)); @@ -427,6 +429,7 @@ static u16 operatorMask(int op){ assert( op!=TK_LE || c==WO_LE ); assert( op!=TK_GT || c==WO_GT ); assert( op!=TK_GE || c==WO_GE ); + assert( op!=TK_IS || c==WO_EQ ); return c; } @@ -1254,6 +1257,7 @@ static void exprAnalyze( pTerm->u.leftColumn = pLeft->iColumn; pTerm->eOperator = operatorMask(op) & opMask; } + if( op==TK_IS ) pTerm->wtFlags |= TERM_NULLOK; if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; @@ -1278,6 +1282,7 @@ static void exprAnalyze( pTerm->eOperator |= WO_EQUIV; eExtraOp = WO_EQUIV; } + if( op==TK_IS ) pNew->wtFlags |= TERM_NULLOK; }else{ pDup = pExpr; pNew = pTerm; @@ -1468,10 +1473,8 @@ static void exprAnalyze( ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a ** virtual term of that form. ** - ** Note that the virtual term must be tagged with TERM_VNULL. This - ** TERM_VNULL tag will suppress the not-null check at the beginning - ** of the loop. Without the TERM_VNULL flag, the not-null check at - ** the start of the loop will prevent any results from being returned. + ** Note that the virtual term must be tagged with both TERM_VNULL + ** and TERM_NULLOK. */ if( pExpr->op==TK_NOTNULL && pExpr->pLeft->op==TK_COLUMN @@ -1488,7 +1491,7 @@ static void exprAnalyze( sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0); idxNew = whereClauseInsert(pWC, pNewExpr, - TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL|TERM_NULLOK); if( idxNew ){ pNewTerm = &pWC->a[idxNew]; pNewTerm->prereqRight = 0; @@ -2792,7 +2795,7 @@ static int codeEqualityTerm( int iReg; /* Register holding results */ assert( iTarget>0 ); - if( pX->op==TK_EQ ){ + if( pX->op==TK_EQ || pX->op==TK_IS ){ iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; @@ -2977,7 +2980,9 @@ static int codeAllEqualityTerms( testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ Expr *pRight = pTerm->pExpr->pRight; - if( sqlite3ExprCanBeNull(pRight) ){ + if( (pTerm->wtFlags & TERM_NULLOK)==0 + && sqlite3ExprCanBeNull(pRight) + ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } @@ -3626,7 +3631,7 @@ static Bitmask codeOneLoopStart( Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); - if( (pRangeStart->wtFlags & TERM_VNULL)==0 + if( (pRangeStart->wtFlags & TERM_NULLOK)==0 && sqlite3ExprCanBeNull(pRight) ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); @@ -3672,7 +3677,7 @@ static Bitmask codeOneLoopStart( sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); sqlite3ExprCode(pParse, pRight, regBase+nEq); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); - if( (pRangeEnd->wtFlags & TERM_VNULL)==0 + if( (pRangeEnd->wtFlags & TERM_NULLOK)==0 && sqlite3ExprCanBeNull(pRight) ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); @@ -4158,9 +4163,10 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){ if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; - sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n", - iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb, - pTerm->eOperator); + sqlite3DebugPrintf( + "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n", + iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb, + pTerm->eOperator, pTerm->wtFlags); sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } diff --git a/src/whereInt.h b/src/whereInt.h index 04cc2029d8..915d7b8d68 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -280,6 +280,7 @@ struct WhereTerm { #define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ #define TERM_LIKE 0x400 /* The original LIKE operator */ +#define TERM_NULLOK 0x800 /* Comparison operators against NULL work */ /* ** An instance of the WhereScan object is used as an iterator for locating