Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value). There are no automated tests for this yet. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | cursor-hints |
Files: | files | file ages | folders |
SHA1: |
f9dddd008c6ef7940a1d66363fbb456c |
User & Date: | dan 2014-07-14 19:04:29.385 |
Original Comment: | In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value). |
Context
2014-07-15
| ||
11:59 | Add simple tests for new sqlite3BtreeCursorHint() functionality. (check-in: 1efa6ed584 user: dan tags: cursor-hints) | |
2014-07-14
| ||
19:04 | In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value). There are no automated tests for this yet. (check-in: f9dddd008c user: dan tags: cursor-hints) | |
2013-12-07
| ||
23:35 | Do not allow cursor hints to use expressions containing subqueries. This change fixes the problem seen in the previous check-in. (check-in: bfefc57554 user: drh tags: cursor-hints) | |
Changes
Changes to src/where.c.
︙ | ︙ | |||
2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 | } } #else # define explainOneScan(u,v,w,x,y,z) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_CURSOR_HINTS /* ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( WhereInfo *pWInfo, int iLevel ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 | } } #else # define explainOneScan(u,v,w,x,y,z) #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_CURSOR_HINTS /* ** 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: ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and ** ** 2) transform the expression node to a TK_REGISTER node that reads ** from the newly populated register. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; if( pExpr->op==TK_COLUMN && pExpr->iTable!=pWalker->u.i ){ Vdbe *v = pWalker->pParse->pVdbe; int reg = ++pWalker->pParse->nMem; /* Register for column value */ sqlite3ExprCodeGetColumnOfTable( v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg ); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pExpr->op==TK_AGG_FUNCTION ){ /* An aggregate function in the WHERE clause of a query means this must ** be a correlated sub-query, and expression pExpr is an aggregate from ** the parent context. Do not walk the function arguments in this case. ** ** todo: It should be possible to replace this node with a TK_REGISTER ** expression, as the result of the expression must be stored in a ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ rc = WRC_Prune; } return rc; } /* ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( WhereInfo *pWInfo, int iLevel ){ |
︙ | ︙ | |||
2735 2736 2737 2738 2739 2740 2741 | WhereLoop *pWLoop; int i, j; if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; pLevel = &pWInfo->a[iLevel]; pWLoop = pLevel->pWLoop; iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; | < > | | > > > > > > > | < | 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 | WhereLoop *pWLoop; int i, j; 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; i<pWC->nTerm; 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; if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; for(j=0; j<pWLoop->nLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} if( j<pWLoop->nLTerm ) continue; pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ const char *a = (const char*)pExpr; Walker sWalker; memset(&sWalker, 0, sizeof(sWalker)); sWalker.xExprCallback = codeCursorHintFixExpr; sWalker.pParse = pParse; sWalker.u.i = pLevel->iTabCur; sqlite3WalkExpr(&sWalker, pExpr); sqlite3VdbeAddOp4(v, OP_CursorHint, pLevel->iTabCur, iCur, 0, a, P4_EXPR); } } #else # define codeCursorHint(A,B) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ |
︙ | ︙ |