提交 0d1df876 authored 作者: noelgrandin's avatar noelgrandin

Fix bug in performing IN queries with multiple values when IGNORECASE=TRUE

上级 2c35d8c3
...@@ -262,8 +262,7 @@ public class Comparison extends Condition { ...@@ -262,8 +262,7 @@ public class Comparison extends Condition {
* @param l the first value * @param l the first value
* @param r the second value * @param r the second value
* @param compareType the compare type * @param compareType the compare type
* @return the result of the comparison (1 if the first value is bigger, -1 * @return true if the comparison indicated by the comparison type evaluates to true
* if smaller, 0 if both are equal)
*/ */
static boolean compareNotNull(Database database, Value l, Value r, int compareType) { static boolean compareNotNull(Database database, Value l, Value r, int compareType) {
boolean result; boolean result;
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
package org.h2.expression; package org.h2.expression;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.Comparator;
import java.util.TreeSet;
import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.IndexCondition; import org.h2.index.IndexCondition;
import org.h2.message.DbException; import org.h2.message.DbException;
...@@ -30,7 +32,7 @@ public class ConditionInConstantSet extends Condition { ...@@ -30,7 +32,7 @@ public class ConditionInConstantSet extends Condition {
private Expression left; private Expression left;
private int queryLevel; private int queryLevel;
private final ArrayList<Expression> valueList; private final ArrayList<Expression> valueList;
private final HashSet<Value> valueSet; private final TreeSet<Value> valueSet;
/** /**
* Create a new IN(..) condition. * Create a new IN(..) condition.
...@@ -39,10 +41,15 @@ public class ConditionInConstantSet extends Condition { ...@@ -39,10 +41,15 @@ public class ConditionInConstantSet extends Condition {
* @param left the expression before IN * @param left the expression before IN
* @param valueList the value list (at least two elements) * @param valueList the value list (at least two elements)
*/ */
public ConditionInConstantSet(Session session, Expression left, ArrayList<Expression> valueList) { public ConditionInConstantSet(final Session session, Expression left, ArrayList<Expression> valueList) {
this.left = left; this.left = left;
this.valueList = valueList; this.valueList = valueList;
this.valueSet = new HashSet<Value>(valueList.size()); this.valueSet = new TreeSet<Value>(new Comparator<Value>() {
@Override
public int compare(Value o1, Value o2) {
return session.getDatabase().compare(o1, o2);
}
});
int type = left.getType(); int type = left.getType();
for (Expression expression : valueList) { for (Expression expression : valueList) {
valueSet.add(expression.getValue(session).convertTo(type)); valueSet.add(expression.getValue(session).convertTo(type));
......
...@@ -54,7 +54,8 @@ public class TestOptimizations extends TestBase { ...@@ -54,7 +54,8 @@ public class TestOptimizations extends TestBase {
testAutoAnalyze(); testAutoAnalyze();
testInAndBetween(); testInAndBetween();
testNestedIn(); testNestedIn();
testConstantIn(); testConstantIn1();
testConstantIn2();
testNestedInSelectAndLike(); testNestedInSelectAndLike();
testNestedInSelect(); testNestedInSelect();
testInSelectJoin(); testInSelectJoin();
...@@ -372,7 +373,7 @@ public class TestOptimizations extends TestBase { ...@@ -372,7 +373,7 @@ public class TestOptimizations extends TestBase {
conn.close(); conn.close();
} }
private void testConstantIn() throws SQLException { private void testConstantIn1() throws SQLException {
deleteDb("optimizations"); deleteDb("optimizations");
Connection conn = getConnection("optimizations"); Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
...@@ -387,6 +388,26 @@ public class TestOptimizations extends TestBase { ...@@ -387,6 +388,26 @@ public class TestOptimizations extends TestBase {
conn.close(); conn.close();
} }
private void testConstantIn2() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations;IGNORECASE=TRUE");
Statement stat = conn.createStatement();
stat.executeUpdate("CREATE TABLE testValues (x VARCHAR(50))");
stat.executeUpdate("INSERT INTO testValues (x) SELECT 'foo' x");
ResultSet resultSet;
resultSet = stat.executeQuery("SELECT x FROM testValues WHERE x IN ('foo')");
assertTrue(resultSet.next());
resultSet = stat.executeQuery("SELECT x FROM testValues WHERE x IN ('FOO')");
assertTrue(resultSet.next());
resultSet = stat.executeQuery("SELECT x FROM testValues WHERE x IN ('foo','bar')");
assertTrue(resultSet.next());
resultSet = stat.executeQuery("SELECT x FROM testValues WHERE x IN ('FOO','bar')");
assertTrue(resultSet.next());
conn.close();
}
private void testNestedInSelect() throws SQLException { private void testNestedInSelect() throws SQLException {
deleteDb("optimizations"); deleteDb("optimizations");
Connection conn = getConnection("optimizations"); Connection conn = getConnection("optimizations");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论