From 0df57012da9866182f78f202aa89156b050fb426 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 15:05:55 +0000 Subject: [PATCH] Refactor the sqlite3BtreeCursorHint() interface for improved maintainability. FossilOrigin-Name: fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a --- manifest | 18 ++++++++--------- manifest.uuid | 2 +- src/btree.c | 40 ++++++++++++++++++++++---------------- src/btree.h | 51 +++++++++++++++++++++++++++++++++++++++++++------ src/vdbe.c | 16 +++++++++------- src/wherecode.c | 6 ++---- 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index fbb13100cf..4a1861f11c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sCursorHint\sso\sthat\sit\sincludes\sthe\sscan\sboundary\sconstraints.\nOn\sthe\sexpression\stext\sfor\sthe\sCursorHint\sopcode,\sshow\srowid\scorrectly. -D 2015-08-14T01:03:21.023 +C Refactor\sthe\ssqlite3BtreeCursorHint()\sinterface\sfor\simproved\smaintainability. +D 2015-08-14T15:05:55.881 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,8 +277,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 060f2482ef871363617b13c68a1d1c09faf356cc -F src/btree.h 88803367b892853c05052e12a946b66508eb6610 +F src/btree.c 84ae3d2d5b0f74257ecb95badc9c9516e6bf6cb6 +F src/btree.h a1f058c495f5020068b864b67b89b13896174137 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c 4acc35c4e0a2d94c906abd164568cd6fc989cfbb F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -399,7 +399,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c eeef2e6ee7c377c31a1b3f6c2b2812f3f711c2d7 +F src/vdbe.c 74561c2d15895f930f08e4216d454efaaaf530c4 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 @@ -415,7 +415,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c c745d3aa78ad1aa8982febb99f2f17ee5cbac069 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 28d838348209430566640907b4c59eb51dc34493 +F src/wherecode.c 3180ac6422b82e4d71fbaae8727f9dd036efd320 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1375,7 +1375,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 608ab4ac1911d5f32a17ea043bd5f0748598691d -R f6a8eae9d2bc039b93361863b21e0bb5 +P f0d428d13a787251c2ca7685fec2a91b550eefba +R 3107bb0cdaaeeac152b5b9d7e7511034 U drh -Z f7fd48c7e80e896401cf3a4f28b4906c +Z 84636ad24c17c3565bc4b3192fff4413 diff --git a/manifest.uuid b/manifest.uuid index 372777a718..d53c4b5ca8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0d428d13a787251c2ca7685fec2a91b550eefba \ No newline at end of file +fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 159ca2b039..0ef1a0555d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -839,16 +839,32 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ #ifdef SQLITE_ENABLE_CURSOR_HINTS /* -** Give a hint to the cursor that it only has to deliver rows for which -** the expression pExpr is true. Within this expression, rows of the -** cursor are identified by Expr.op==TK_COLUMN with Expr.iTable==iTable. +** Provide hints to the cursor. The particular hint given (and the type +** and number of the varargs parameters) is determined by the eHintType +** parameter. See the definitions of the BTREE_HINT_* macros for details. ** -** This interfaces is not used by the standard storage engine of SQLite. -** It is only useful to application that replace SQLite's built-in storage -** engine with their own. +** Hints are not (currently) used by the native SQLite implementation. +** This mechanism is provided for systems that substitute an alternative +** storage engine. */ -void sqlite3BtreeCursorHint(BtCursor *pCur, int iTable, const Expr *pExpr){ - /* Alternative storage engines might use this. */ +void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ + va_list ap; + va_start(ap, eHintType); + switch( eHintType ){ + case BTREE_HINT_FLAGS: { + pCur->hints = va_arg(ap, unsigned int); + assert( pCur->hints==BTREE_SEEK_EQ || pCur->hints==BTREE_BULKLOAD + || pCur->hints==0 ); + break; + } + case BTREE_HINT_RANGE: { + (void)va_arg(ap, Expr*); + (void)va_arg(ap, struct Mem*); + /* Range expression not used in this implementation */ + break; + } + } + va_end(ap); } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ @@ -9564,14 +9580,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ return rc; } -/* -** set the mask of hint flags for cursor pCsr. -*/ -void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ - assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 ); - pCsr->hints = mask; -} - #ifdef SQLITE_DEBUG /* ** Return true if the cursor has a hint specified. This routine is diff --git a/src/btree.h b/src/btree.h index 05246b765d..de6f3b9467 100644 --- a/src/btree.h +++ b/src/btree.h @@ -150,8 +150,47 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_DATA_VERSION 15 /* A virtual meta-value */ /* -** Values that may be OR'd together to form the second argument of an -** sqlite3BtreeCursorHints() call. +** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() +** interface. +** +** Note that cursor hints are not used by the canonical SQLite b-tree +** ayer. Cursor hints are provided so that systems that substitute their +** on custom b-tree layer can have access to additional information that might +** boost performance. Hints are only provided if SQLite is compiled with +** SQLITE_ENABLE_CURSOR_HINTS. The hinting interface is undocumented +** (except for comments such as this) and is subject to change from one +** release of SQLite to the next. +** +** BTREE_HINT_FLAGS (arguments: unsigned int) +** +** Some combinatation of BTREE_BULKLOAD and BTREE_SEEK_EQ flags. The +** argument is a single unsigned integer which overwrites all prior +** flag settings. +** +** BTREE_HINT_RANGE (arguments: Expr*, Mem*) +** +** The first argument is an Expr* (which is guaranteed to be constant for +** the lifetime of the cursor) that defines constraints on which rows +** might be fetched with this cursor. The Expr* tree may contain +** TK_REGISTER nodes that refer to values stored in the array of registers +** passed as the second parameter. In other words, if Expr.op==TK_REGISTER +** then the value of the node is the value in Mem[pExpr.iTable]. Any +** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th +** column of the b-tree of the cursor. The Expr tree will not contain +** any function calls nor subqueries nor references to b-trees other than +** the cursor being hinted. +** +** The design of the _RANGE hint is aid b-tree implementations that try +** to prefetch content from remote machines - to provide those +** implementations with limits on what needs to be prefetched and thereby +** reduce network bandwidth. +*/ +#define BTREE_HINT_FLAGS 1 /* Set flags indicating cursor usage */ +#define BTREE_HINT_RANGE 2 /* Range constraints on queries */ + +/* +** Values that may be OR'd together to form the argument to the +** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): ** ** The BTREE_BULKLOAD flag is set on index cursors when the index is going ** to be filled with content that is already in sorted order. @@ -165,6 +204,10 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS +void sqlite3BtreeCursorHint(BtCursor*, int, ...); +#endif + int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ @@ -185,9 +228,6 @@ int sqlite3BtreeMovetoUnpacked( ); int sqlite3BtreeCursorHasMoved(BtCursor*); int sqlite3BtreeCursorRestore(BtCursor*, int*); -#ifdef SQLITE_ENABLE_CURSOR_HINTS -void sqlite3BtreeCursorHint(BtCursor*, int, const Expr*); -#endif int sqlite3BtreeDelete(BtCursor*); int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, @@ -211,7 +251,6 @@ int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeIncrblobCursor(BtCursor *); void sqlite3BtreeClearCursor(BtCursor *); int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); -void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); #ifdef SQLITE_DEBUG int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); #endif diff --git a/src/vdbe.c b/src/vdbe.c index fc53511057..f1a5545444 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3384,8 +3384,10 @@ case OP_OpenWrite: open_cursor_set_hints: assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); - sqlite3BtreeCursorHints(pCur->pCursor, - (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); +#ifdef SQLITE_ENABLE_CURSOR_HINTS + sqlite3BtreeCursorHint(pCur->pCursor, BTREE_HINT_FLAGS, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); +#endif break; } @@ -6553,12 +6555,12 @@ case OP_Init: { /* jump */ } #ifdef SQLITE_ENABLE_CURSOR_HINTS -/* Opcode: CursorHint P1 P2 * P4 * +/* Opcode: CursorHint P1 * * P4 * ** ** Provide a hint to cursor P1 that it only needs to return rows that -** satisfy the Expr tree given in P4. P2 is the table number of cursor P1 -** such that references to cursor P1 in the Expr tree are given by -** Expr.iTable==P2. +** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer +** to values currently held in registers. TK_COLUMN terms in the P4 +** expression refer to columns in the b-tree to which cursor P1 is pointing. */ case OP_CursorHint: { VdbeCursor *pC; @@ -6567,7 +6569,7 @@ case OP_CursorHint: { assert( pOp->p4type==P4_EXPR ); pC = p->apCsr[pOp->p1]; if( pC ){ - sqlite3BtreeCursorHint(pC->pCursor, pOp->p2, pOp->p4.pExpr); + sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); #ifdef SQLITE_TEST void sqlite3BtreeCursorHintTest(Mem*, Expr*); sqlite3BtreeCursorHintTest(p->aMem, pOp->p4.pExpr); diff --git a/src/wherecode.c b/src/wherecode.c index b00ff71276..7b9db0cb2f 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,7 +592,7 @@ static void whereLikeOptimizationStringFixup( /* ** This function is called on every node of an expression tree used as an ** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN -** that accesses any cursor other than (pWalker->u.i), do the following: +** that accesses any cursor other than (pWalker->u.n), do the following: ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and @@ -638,12 +638,10 @@ static void codeCursorHint( int iCur; WhereClause *pWC; WhereTerm *pTerm; - WhereLoop *pWLoop; - int i, j; + int i; if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; pLevel = &pWInfo->a[iLevel]; - pWLoop = pLevel->pWLoop; iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; pWC = &pWInfo->sWC; for(i=0; inTerm; i++){