From: drh Date: Tue, 16 Oct 2012 21:08:03 +0000 (+0000) Subject: An optimization that converts "a IN (b)" into "a==b". Seems to work, but needs X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c097019e74d8a77881bfdf9198b6b08bdea619f;p=thirdparty%2Fsqlite.git An optimization that converts "a IN (b)" into "a==b". Seems to work, but needs additional test cases. FossilOrigin-Name: 8b4c3c5e506267c18550063cb9bd93519c871b0e --- diff --git a/manifest b/manifest index be0f0a1ebc..d829be1c7c 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 915ba49368..c764606f88 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c3af657fee6153842d660a6ce29aa7d791ebd38 \ No newline at end of file +8b4c3c5e506267c18550063cb9bd93519c871b0e \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 94433d5391..1115154a87 100644 --- a/src/parse.y +++ b/src/parse.y @@ -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); }