Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Factor out the code generator for BETWEEN into a subroutine. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5735f60b23460e7677b9c982a26bc13b |
User & Date: | drh 2009-11-12 13:32:23.000 |
Context
2009-11-12
| ||
17:52 | Factor out the IN operator code generation into a subroutine. Use this subroutine to implement both logic and branching versions of the IN operator. (check-in: fcff5b7e2d user: drh tags: trunk) | |
13:32 | Factor out the code generator for BETWEEN into a subroutine. (check-in: 5735f60b23 user: drh tags: trunk) | |
05:04 | Update comment for substrFunc(). Added additional SUBSTR() test cases. (check-in: d7b3801dc7 user: shaneh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 | } if( doHardCopy && !pParse->db->mallocFailed ){ sqlite3ExprHardCopy(pParse, target, n); } } return n; } /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution ** continues straight thru if the expression is false. ** ** If the expression evaluates to NULL (neither true nor false), then | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 | } if( doHardCopy && !pParse->db->mallocFailed ){ sqlite3ExprHardCopy(pParse, target, n); } } return n; } /* ** Generate code for a BETWEEN operator. ** ** x BETWEEN y AND z ** ** The above is equivalent to ** ** x>=y AND x<=z ** ** Code it as such, taking care to do the common subexpression ** elementation of x. */ static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The BETWEEN expression */ int dest, /* Jump here if the jump is taken */ int jumpIfTrue, /* Take the jump if the BETWEEN is true */ int jumpIfNull /* Take the jump if the BETWEEN is NULL */ ){ Expr exprAnd; /* The AND operator in x>=y AND x<=z */ Expr compLeft; /* The x>=y term */ Expr compRight; /* The x<=z term */ Expr exprX; /* The x subexpression */ int regFree1 = 0; /* Temporary use register */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); exprX = *pExpr->pLeft; exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; compLeft.op = TK_GE; compLeft.pLeft = &exprX; compLeft.pRight = pExpr->x.pList->a[0].pExpr; compRight.op = TK_LE; compRight.pLeft = &exprX; compRight.pRight = pExpr->x.pList->a[1].pExpr; exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, ®Free1); exprX.op = TK_REGISTER; if( jumpIfTrue ){ sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); }else{ sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); } sqlite3ReleaseTempReg(pParse, regFree1); /* Ensure adequate test coverage */ testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 ); testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 ); testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 ); testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 ); testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 ); testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 ); testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 ); testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 ); } /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution ** continues straight thru if the expression is false. ** ** If the expression evaluates to NULL (neither true nor false), then |
︙ | ︙ | |||
3086 3087 3088 3089 3090 3091 3092 | testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( regFree1==0 ); break; } case TK_BETWEEN: { | < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < | 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 | testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( regFree1==0 ); break; } case TK_BETWEEN: { exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); break; } default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); |
︙ | ︙ | |||
3246 3247 3248 3249 3250 3251 3252 | testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( regFree1==0 ); break; } case TK_BETWEEN: { | < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < | 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 | testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( regFree1==0 ); break; } case TK_BETWEEN: { exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); break; } default: { r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); |
︙ | ︙ |