提交 00b69a6b authored 作者: noelgrandin's avatar noelgrandin

Fix bug in optimising SELECT * FROM A WHERE X=1 OR X=2 OR X=3 into SELECT * FROM…

Fix bug in optimising SELECT * FROM A WHERE X=1 OR X=2 OR X=3 into SELECT * FROM A WHERE X IN (1,2,3)
上级 d300858c
......@@ -35,6 +35,7 @@ Change Log
</li><li>Issue 274: Sybase/MSSQLServer compatibility - Add GETDATE and CHARINDEX system functions
</li><li>Issue 274: Sybase/MSSQLServer compatibility - swap parameters of CONVERT function.
</li><li>Issue 274: Sybase/MSSQLServer compatibility - support index clause e.g. "select * from test (index table1_index)"
</li><li>Fix bug in optimising SELECT * FROM A WHERE X=1 OR X=2 OR X=3 into SELECT * FROM A WHERE X IN (1,2,3)
</li></ul>
<h2>Version 1.3.171 (2013-03-17)</h2>
......
......@@ -171,6 +171,16 @@ public class ConditionAndOr extends Condition {
if (added != null) {
return added.optimize(session);
}
} else if (left instanceof ConditionInConstantSet && right instanceof Comparison) {
Expression added = ((ConditionInConstantSet) left).getAdditional((Comparison) right);
if (added != null) {
return added.optimize(session);
}
} else if (right instanceof ConditionInConstantSet && left instanceof Comparison) {
Expression added = ((ConditionInConstantSet) right).getAdditional((Comparison) left);
if (added != null) {
return added.optimize(session);
}
}
}
// TODO optimization: convert .. OR .. to UNION if the cost is lower
......
......@@ -132,4 +132,19 @@ public class ConditionInConstantSet extends Condition {
return cost;
}
/**
* Add an additional element if possible. Example: given two conditions
* A IN(1, 2) OR A=3, the constant 3 is added: A IN(1, 2, 3).
*
* @param other the second condition
* @return null if the condition was not added, or the new condition
*/
Expression getAdditional(Comparison other) {
Expression add = other.getIfEquals(left);
if (add != null) {
valueList.add(add);
return this;
}
return null;
}
}
......@@ -69,6 +69,7 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(true);
testMinMaxCountOptimization(false);
testOrderedIndexes();
testConvertOrToIn();
deleteDb("optimizations");
}
......@@ -812,4 +813,20 @@ public class TestOptimizations extends TestBase {
conn.close();
}
private void testConvertOrToIn() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar(255))");
stat.execute("insert into test values(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')");
ResultSet rs = stat.executeQuery("EXPLAIN PLAN FOR SELECT * FROM test WHERE ID=1 OR ID=2 OR ID=3 OR ID=4 OR ID=5");
rs.next();
assertContains(rs.getString(1), "ID IN(1, 2, 3, 4, 5)");
stat.execute("DROP TABLE test");
conn.close();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论