From: drh Date: Thu, 12 Nov 2009 13:32:22 +0000 (+0000) Subject: Factor out the code generator for BETWEEN into a subroutine. X-Git-Tag: fts3-refactor~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36c563a29349cab10621db06dd3992bc281ce58e;p=thirdparty%2Fsqlite.git Factor out the code generator for BETWEEN into a subroutine. FossilOrigin-Name: 5735f60b23460e7677b9c982a26bc13b0f4ed02b --- diff --git a/manifest b/manifest index 4e029ff51e..6c8b3a1433 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Update\scomment\sfor\ssubstrFunc().\s\sAdded\sadditional\sSUBSTR()\stest\scases. -D 2009-11-12T05:04:50 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Factor\sout\sthe\scode\sgenerator\sfor\sBETWEEN\sinto\sa\ssubroutine. +D 2009-11-12T13:32:23 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -114,7 +117,7 @@ F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f F src/complete.c 77016e5a2766cf8b84381397152d2c99ea4b218f F src/date.c a79c0a8f219370b972e320741f995a3bef9df33f F src/delete.c ec04635d152debdab70d4b30c5516b59282075ea -F src/expr.c be605c60ff84699f3087209f2f86a140a6a5e96c +F src/expr.c 64330769c242615f037290c2dcdfded8bb53b537 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 41219cba186bcf0a053e42327dfa23aaba4f834a F src/func.c bf54e1202cbfb28bf4b1fd9b58899009ae76716f @@ -768,7 +771,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e8aec08bee1c8d593474561898037aed571e64ce -R eff535e110e372495a1d64aaae18bfd2 -U shaneh -Z 84a73f30a17aaa895fe2eee2c345ef85 +P d7b3801dc7fad1b002f892fb5d82047ebff98369 +R 8f2a35eead76fc902fb56cbc9c8e7046 +U drh +Z ae99e07341da03fa353722abb2f83700 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFK/A5roxKgR168RlERAnPLAJ0Sxm4g2oTIdPyR4JvF7/DwSMTZ7ACdHf/0 +GxIVBC/bE7L6MXpVSt2rKxI= +=OMih +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index e10db54a28..6690415674 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d7b3801dc7fad1b002f892fb5d82047ebff98369 \ No newline at end of file +5735f60b23460e7677b9c982a26bc13b0f4ed02b \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 249ab9037c..b16657c610 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2991,6 +2991,62 @@ int sqlite3ExprCodeExprList( 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 @@ -3090,36 +3146,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } case TK_BETWEEN: { - /* x BETWEEN y AND z - ** - ** Is equivalent to - ** - ** x>=y AND x<=z - ** - ** Code it as such, taking care to do the common subexpression - ** elementation of x. - */ - Expr exprAnd; - Expr compLeft; - Expr compRight; - Expr exprX; - - 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); - testcase( regFree1==0 ); - exprX.op = TK_REGISTER; - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull); break; } default: { @@ -3250,36 +3277,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ break; } case TK_BETWEEN: { - /* x BETWEEN y AND z - ** - ** Is equivalent to - ** - ** x>=y AND x<=z - ** - ** Code it as such, taking care to do the common subexpression - ** elementation of x. - */ - Expr exprAnd; - Expr compLeft; - Expr compRight; - Expr exprX; - - 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); - testcase( regFree1==0 ); - exprX.op = TK_REGISTER; - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull); break; } default: {