]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Factor out the code generator for BETWEEN into a subroutine.
authordrh <drh@noemail.net>
Thu, 12 Nov 2009 13:32:22 +0000 (13:32 +0000)
committerdrh <drh@noemail.net>
Thu, 12 Nov 2009 13:32:22 +0000 (13:32 +0000)
FossilOrigin-Name: 5735f60b23460e7677b9c982a26bc13b0f4ed02b

manifest
manifest.uuid
src/expr.c

index 4e029ff51e30f24ca5b22620506b7f8d35f8977a..6c8b3a1433af98f68b5f7f0ebede58dba8d97fff 100644 (file)
--- 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-----
index e10db54a287c93a91ecbb595647c5b5ebf933bef..6690415674ce2a1481506bb1c8fa10c0b4be8caf 100644 (file)
@@ -1 +1 @@
-d7b3801dc7fad1b002f892fb5d82047ebff98369
\ No newline at end of file
+5735f60b23460e7677b9c982a26bc13b0f4ed02b
\ No newline at end of file
index 249ab9037cd6306b28526c0d7ab8ed138d4ee998..b16657c610827ac863925209d1941f2a17d76aea 100644 (file)
@@ -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, &regFree1);
+  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, &regFree1);
-      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, &regFree1);
-      testcase( regFree1==0 );
-      exprX.op = TK_REGISTER;
-      testcase( jumpIfNull==0 );
-      sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
+      exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull);
       break;
     }
     default: {