]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
An optimization that converts "a IN (b)" into "a==b". Seems to work, but needs degenerate_IN
authordrh <drh@noemail.net>
Tue, 16 Oct 2012 21:08:03 +0000 (21:08 +0000)
committerdrh <drh@noemail.net>
Tue, 16 Oct 2012 21:08:03 +0000 (21:08 +0000)
additional test cases.

FossilOrigin-Name: 8b4c3c5e506267c18550063cb9bd93519c871b0e

manifest
manifest.uuid
src/parse.y

index be0f0a1ebcbed5b417bff9b681d462f16e447d4e..d829be1c7c5d3df788b94ec03ab718472726870e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Correct\scomments\sand\senhance\sreadability\sof\sthe\smkvsix\stool.
-D 2012-10-15T20:28:22.029
+C An\soptimization\sthat\sconverts\s"a\sIN\s(b)"\sinto\s"a==b".\s\sSeems\sto\swork,\sbut\sneeds\nadditional\stest\scases.
+D 2012-10-16T21:08:03.250
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5f4f26109f9d80829122e0e09f9cda008fa065fb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -164,7 +164,7 @@ F src/os_unix.c 0d3a39dd576c9f384fd7772a2dadc67b144c6ce7
 F src/os_win.c 28bd027791252a4012dffd4d64355a1eb84d761c
 F src/pager.c 36642c0955c19840b5445e7e9da7b5b0d8235346
 F src/pager.h 1109a06578ec5574dc2c74cf8d9f69daf36fe3e0
-F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
+F src/parse.y bf81c919e1fd5b52299e608a2d42ca82673afbf4
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
 F src/pcache1.c 9fd22671c270b35131ef480bbc00392b8b5f8ab9
@@ -1021,7 +1021,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
-P 629a42d47a0d8f73de900f469845ce800bdb8959
-R c7830c7c0cb344c8cb6a175c95e5eb7f
-U mistachkin
-Z f2086ddd83e8b281e8d53ba90c91d2db
+P 2c3af657fee6153842d660a6ce29aa7d791ebd38
+R 135ac3559d095a4b2053b49a5e92f83d
+T *branch * degenerate_IN
+T *sym-degenerate_IN *
+T -sym-trunk *
+U drh
+Z 7ac7ea0812fe7c335bb0c6658e1b8dd3
index 915ba493680eb7e7ef9000908593c8d328a24e92..c764606f88d95e16e8f9d5d9644d59e1a320afa7 100644 (file)
@@ -1 +1 @@
-2c3af657fee6153842d660a6ce29aa7d791ebd38
\ No newline at end of file
+8b4c3c5e506267c18550063cb9bd93519c871b0e
\ No newline at end of file
index 94433d53917233d58af31ca8981ab39ab23f0525..1115154a878043df54bf37e22a32614efff9d685 100644 (file)
@@ -998,7 +998,9 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
   in_op(A) ::= IN.      {A = 0;}
   in_op(A) ::= NOT IN.  {A = 1;}
   expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
-    if( Y==0 ){
+    sqlite3 *db = pParse->db;
+    ExprList *pY = Y;
+    if( pY==0 ){
       /* Expressions of the form
       **
       **      expr1 IN ()
@@ -1008,14 +1010,24 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
       ** regardless of the value of expr1.
       */
       A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]);
-      sqlite3ExprDelete(pParse->db, X.pExpr);
+      sqlite3ExprDelete(db, X.pExpr);
+    }else if( pY->nExpr==1 ){
+      /* If the RHS of the IN operator has a single term, simplify as follows:
+      **
+      **      expr1 IN (Y)        -->      expr1 = Y
+      **      expr1 NOT IN (Y)    -->      expr1 <> Y
+      */
+      assert( TK_EQ==TK_NE+1 );
+      A.pExpr = sqlite3PExpr(pParse, TK_EQ-N, X.pExpr, pY->a[0].pExpr, 0);
+      pY->a[0].pExpr = 0;
+      sqlite3ExprListDelete(db, pY);
     }else{
       A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
       if( A.pExpr ){
-        A.pExpr->x.pList = Y;
+        A.pExpr->x.pList = pY;
         sqlite3ExprSetHeight(pParse, A.pExpr);
       }else{
-        sqlite3ExprListDelete(pParse->db, Y);
+        sqlite3ExprListDelete(pParse->db, pY);
       }
       if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
     }