diff --git a/manifest b/manifest index 32218e8eda..f152345340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sdisplay\sof\sthe\sP4\soperand\sof\sCursorHint\sin\sEXPLAIN\soutput\sto\nfunction\snotation. -D 2015-08-15T00:51:23.737 +C Avoid\sgenerating\shints\susing\sconstraints\sthat\sare\salso\sused\sto\sinitialize\sthe\ncursor,\ssince\spresumably\sthe\scursor\salready\sknows\sabout\sthose\sconstraints. +D 2015-08-17T17:19:28.483 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -414,7 +414,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c ef95e56b6e7cdfa3ae0b6f72e3578391addfa965 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 16045545fb44878a7ba61db645521f30f9265893 +F src/wherecode.c 148c5dc225551309f489a5c44b8a0f7800c9794b F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -560,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test 0d79cce943e4e61910d9a5cf73b1e57b2b42429f +F test/cursorhint.test b1f86e9c959231094d8fe214518667548083063e F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1374,7 +1374,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 83a844357e132683ab3d88eee0fe32a8beeb6662 -R 64f1f656f75dd3e1a8b619dc73ce4cbc +P bee73d429cb0e99b43fb191ac15e298d0353b135 +R f415b0a9be4e26d1aeb927a138261bed U drh -Z 780f279750b73ad9a07ce3a651ba66ad +Z dbc2b5253d321af49bf9c502e3a1dded diff --git a/manifest.uuid b/manifest.uuid index dd4f395a20..6fdfe94f71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bee73d429cb0e99b43fb191ac15e298d0353b135 \ No newline at end of file +142b048ac778620dd4e448c2e969982eb8188501 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 5052e2d378..5e7710ae8a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -669,8 +669,9 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( - WhereInfo *pWInfo, - WhereLevel *pLevel + WhereInfo *pWInfo, /* The where clause */ + WhereLevel *pLevel, /* Which loop to provide hints for */ + WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ ){ Parse *pParse = pWInfo->pParse; sqlite3 *db = pParse->db; @@ -680,7 +681,8 @@ static void codeCursorHint( int iCur; WhereClause *pWC; WhereTerm *pTerm; - int i; + WhereLoop *pWLoop; + int i, j; struct CCurHint sHint; Walker sWalker; @@ -694,18 +696,33 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; + pWLoop = pLevel->pWLoop; for(i=0; inTerm; i++){ pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + + /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize + ** the cursor. No need to hint initialization terms. */ + if( pTerm!=pEndRange ){ + for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; + } + + /* No subqueries or non-deterministic functions allowed */ if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + + /* For an index scan, make sure referenced columns are actually in + ** the index. */ if( sHint.pIdx!=0 ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintCheckExpr; sqlite3WalkExpr(&sWalker, pTerm->pExpr); if( sWalker.eCode ) continue; } + + /* If we survive all prior tests, that means this term is worth hinting */ pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ @@ -717,7 +734,7 @@ static void codeCursorHint( } } #else -# define codeCursorHint(A,B) /* No-op */ +# define codeCursorHint(A,B,C) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* @@ -883,7 +900,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pStart = pEnd; pEnd = pTerm; } - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, pEnd); if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ @@ -1106,7 +1123,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, pRangeEnd); nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; @@ -1534,7 +1551,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); diff --git a/test/cursorhint.test b/test/cursorhint.test index 9d12c90d7b..4ff7faa859 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -94,13 +94,18 @@ do_test 3.2 { # Indexed queries # -do_test 4.1 { +do_test 4.1asc { db eval { CREATE INDEX t1bc ON t1(b,c); CREATE INDEX t2yz ON t2(y,z); } p4_of_opcode db CursorHint { - SELECT * FROM t1 WHERE b>11; + SELECT * FROM t1 WHERE b>11 ORDER BY b ASC; + } +} {} +do_test 4.1desc { + p4_of_opcode db CursorHint { + SELECT * FROM t1 WHERE b>11 ORDER BY b DESC; } } {GT(c0,11)} do_test 4.2 { @@ -108,16 +113,41 @@ do_test 4.2 { SELECT * FROM t1 WHERE b>11; } } {02 00} -do_test 4.3 { +do_test 4.3asc { p4_of_opcode db CursorHint { - SELECT c FROM t1 WHERE b>11; + SELECT c FROM t1 WHERE b<11 ORDER BY b ASC; } -} {GT(c0,11)} +} {LT(c0,11)} +do_test 4.3desc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b<11 ORDER BY b DESC; + } +} {} do_test 4.4 { p5_of_opcode db OpenRead . { - SELECT c FROM t1 WHERE b>11; + SELECT c FROM t1 WHERE b<11; } } {00} +do_test 4.5asc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC; + } +} {LE(c0,20)} +do_test 4.5desc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC; + } +} {GE(c0,10)} +do_test 4.6asc { + p4_of_opcode db CursorHint { + SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC; + } +} {LE(c1,20)} +do_test 4.6desc { + p4_of_opcode db CursorHint { + SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC; + } +} {GE(c1,10)} finish_test