From: drh Date: Thu, 20 Mar 2014 14:56:47 +0000 (+0000) Subject: Previous check-in is not quite correct. "x IN (?)" is not exactly the same X-Git-Tag: version-3.8.5~117 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a8d14261c7b47208176f750f95b2472fecd63bf;p=thirdparty%2Fsqlite.git Previous check-in is not quite correct. "x IN (?)" is not exactly the same as "x==?" do to collation and affinity issues. The correct converstion should be to "x==(+? COLLATE binary)". The current check-in fixes this problem and provides test cases. Ticket [e39d032577df69] FossilOrigin-Name: 2ff3b25f40fd117c8a2da1d1a3625f6b167b7b16 --- diff --git a/manifest b/manifest index 16ca144d3e..5d2b629021 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Convert\sexpressions\sof\sthe\sform\s"X\sIN\s(?)"\swith\sexactly\sone\svalue\son\sthe\nRHS\sof\sthe\sIN\sinto\sequality\stests:\s\s"X=?".\s\sAdd\stest\scases\sto\sverify\sthat\nstatements\swork\scorrectly\son\sthis\scorner\scase.\nFix\sfor\sticket\s[e39d032577df6942]. -D 2014-03-20T13:26:47.152 +C Previous\scheck-in\sis\snot\squite\scorrect.\s\s"x\sIN\s(?)"\sis\snot\sexactly\sthe\ssame\nas\s"x==?"\sdo\sto\scollation\sand\saffinity\sissues.\s\sThe\scorrect\sconverstion\sshould\nbe\sto\s"x==(+?\sCOLLATE\sbinary)".\s\sThe\scurrent\scheck-in\sfixes\sthis\sproblem\sand\nprovides\stest\scases.\s\sTicket\s[e39d032577df69] +D 2014-03-20T14:56:47.071 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -207,7 +207,7 @@ F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5 F src/os_win.c e71678ac927d0a0fb11d993db20a9748eabf808e F src/pager.c 97a8908bf4e6e7c3adea09d3597cfa48ae33ab4e F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 52d749e7fd1289d9a576fe88782d9637a2f7bb6d +F src/parse.y c9189eca0888ecd2711c77a199ae7a7c86f57546 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c @@ -593,7 +593,7 @@ F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test ed42587bed8c8e2219a09a6a6e3675edffc011da +F test/in4.test 18202389003284e8e019750c04e4bc6333df9c99 F test/in5.test 99f9a40af01711b06d2d614ecfe96129f334fba3 F test/incrblob.test e81846d214f3637622620fbde7cd526781cfe328 F test/incrblob2.test bf4d549aa4a466d7fbe3e3a3693d3861263d5600 @@ -1156,7 +1156,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ca3140813198ab7ce470cf86334e55207f3461f9 -R abb091fc1f04a82c7540caf08b56e8dd +P e68b427afbc82e201c64474117851aa4c9eb0c92 +R 8739dc742c6ff38e89fff08724b87c5b U drh -Z 8ed34cb3369a2d9b188815f2f4b333aa +Z c6097cc93dfeb105af183d7216a869ad diff --git a/manifest.uuid b/manifest.uuid index 6fc3864b4f..7bb62d8aab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e68b427afbc82e201c64474117851aa4c9eb0c92 \ No newline at end of file +2ff3b25f40fd117c8a2da1d1a3625f6b167b7b16 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 1e6d859881..24b8b98afc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1028,12 +1028,14 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { ** ** with exactly one value on the RHS can be simplified to: ** - ** expr1 == ?1 - ** expr1 <> ?2 + ** expr1 == (+?1 COLLATE binary) + ** expr1 <> (+?2 COLLATE binary) */ - Expr *pRHS = Y->a[0].pExpr; + static const Token collBin = { "binary", 6 }; + Expr *pRHS = sqlite3ExprAddCollateToken(pParse, Y->a[0].pExpr, &collBin); Y->a[0].pExpr = 0; sqlite3ExprListDelete(pParse->db, Y); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0, 0); A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, X.pExpr, pRHS, 0); }else{ A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0); diff --git a/test/in4.test b/test/in4.test index b8ae4d9825..5828a83cc5 100644 --- a/test/in4.test +++ b/test/in4.test @@ -245,6 +245,65 @@ do_execsql_test in4-3.48 { SELECT * FROM t3 WHERE x NOT IN (10); } {~/OpenEphemeral/} +# Make sure that when "x IN (?)" is converted into "x==?" that collating +# sequence and affinity computations do not get messed up. +# +do_execsql_test in4-4.1 { + CREATE TABLE t4a(a TEXT, b TEXT COLLATE nocase, c); + INSERT INTO t4a VALUES('ABC','abc',1); + INSERT INTO t4a VALUES('def','xyz',2); + INSERT INTO t4a VALUES('ghi','ghi',3); + SELECT c FROM t4a WHERE a=b ORDER BY c; +} {3} +do_execsql_test in4-4.2 { + SELECT c FROM t4a WHERE b=a ORDER BY c; +} {1 3} +do_execsql_test in4-4.3 { + SELECT c FROM t4a WHERE (a||'')=b ORDER BY c; +} {1 3} +do_execsql_test in4-4.4 { + SELECT c FROM t4a WHERE (a||'')=(b||'') ORDER BY c; +} {3} +do_execsql_test in4-4.5 { + SELECT c FROM t4a WHERE a IN (b) ORDER BY c; +} {3} +do_execsql_test in4-4.6 { + SELECT c FROM t4a WHERE (a||'') IN (b) ORDER BY c; +} {3} + + +do_execsql_test in4-4.11 { + CREATE TABLE t4b(a TEXT, b NUMERIC, c); + INSERT INTO t4b VALUES('1.0',1,4); + SELECT c FROM t4b WHERE a=b; +} {4} +do_execsql_test in4-4.12 { + SELECT c FROM t4b WHERE b=a; +} {4} +do_execsql_test in4-4.13 { + SELECT c FROM t4b WHERE +a=b; +} {4} +do_execsql_test in4-4.14 { + SELECT c FROM t4b WHERE a=+b; +} {} +do_execsql_test in4-4.15 { + SELECT c FROM t4b WHERE +b=a; +} {} +do_execsql_test in4-4.16 { + SELECT c FROM t4b WHERE b=+a; +} {4} +do_execsql_test in4-4.17 { + SELECT c FROM t4b WHERE a IN (b); +} {} +do_execsql_test in4-4.18 { + SELECT c FROM t4b WHERE b IN (a); +} {4} +do_execsql_test in4-4.19 { + SELECT c FROM t4b WHERE +b IN (a); +} {} + + + finish_test