提交 2c065a21 authored 作者: Thomas Mueller's avatar Thomas Mueller

Statements with IN(..) conditions could produce the wrong result when using…

Statements with IN(..) conditions could produce the wrong result when using views or nested select statements.
上级 94a2a328
......@@ -211,15 +211,23 @@ public class IndexCondition {
/**
* Get the comparison bit mask.
*
* @param conditionCount the number of index conditions
* @return the mask
*/
public int getMask() {
public int getMask(int conditionCount) {
switch (compareType) {
case Comparison.FALSE:
return ALWAYS_FALSE;
case Comparison.EQUAL:
return EQUALITY;
case Comparison.IN_LIST:
case Comparison.IN_QUERY:
if (conditionCount > 1) {
// if there are more conditions, don't use the index on IN(..)
// IN(..) can not be combined with other conditions,
// otherwise the query returns the wrong result
return 0;
}
return EQUALITY;
case Comparison.BIGGER_EQUAL:
case Comparison.BIGGER:
......
......@@ -145,7 +145,7 @@ public class TableFilter implements ColumnResolver {
break;
}
int id = condition.getColumn().getColumnId();
masks[id] |= condition.getMask();
masks[id] |= condition.getMask(indexConditions.size());
}
}
item = table.getBestPlanItem(session, masks);
......
......@@ -38,6 +38,7 @@ public class TestOptimizations extends TestBase {
}
public void test() throws Exception {
testNestedIn();
testNestedInSelectAndLike();
testNestedInSelect();
testInSelectJoin();
......@@ -59,6 +60,32 @@ public class TestOptimizations extends TestBase {
deleteDb("optimizations");
}
private void testNestedIn() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
ResultSet rs;
stat.execute("create table accounts(id integer primary key, status varchar(255), tag varchar(255))");
stat.execute("insert into accounts values (31, 'X', 'A')");
stat.execute("create table parent(id int)");
stat.execute("insert into parent values(31)");
stat.execute("create view test_view as select a.status, a.tag from accounts a, parent t where a.id = t.id");
rs = stat.executeQuery("select * from test_view where status='X' and tag in ('A','B')");
assertTrue(rs.next());
rs = stat.executeQuery("select * from (select a.status, a.tag from accounts a, parent t where a.id = t.id) x where status='X' and tag in ('A','B')");
assertTrue(rs.next());
stat.execute("create table test(id int primary key, name varchar(255))");
stat.execute("create unique index idx_name on test(name, id)");
stat.execute("insert into test values(1, 'Hello'), (2, 'World')");
rs = stat.executeQuery("select * from (select * from test) where id=1 and name in('Hello', 'World')");
assertTrue(rs.next());
stat.execute("drop table test");
conn.close();
}
private void testNestedInSelect() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论