提交 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 ...@@ -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 - 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 - 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>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> </li></ul>
<h2>Version 1.3.171 (2013-03-17)</h2> <h2>Version 1.3.171 (2013-03-17)</h2>
......
...@@ -171,6 +171,16 @@ public class ConditionAndOr extends Condition { ...@@ -171,6 +171,16 @@ public class ConditionAndOr extends Condition {
if (added != null) { if (added != null) {
return added.optimize(session); 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 // TODO optimization: convert .. OR .. to UNION if the cost is lower
......
...@@ -132,4 +132,19 @@ public class ConditionInConstantSet extends Condition { ...@@ -132,4 +132,19 @@ public class ConditionInConstantSet extends Condition {
return cost; 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 { ...@@ -69,6 +69,7 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization(true); testMinMaxCountOptimization(true);
testMinMaxCountOptimization(false); testMinMaxCountOptimization(false);
testOrderedIndexes(); testOrderedIndexes();
testConvertOrToIn();
deleteDb("optimizations"); deleteDb("optimizations");
} }
...@@ -812,4 +813,20 @@ public class TestOptimizations extends TestBase { ...@@ -812,4 +813,20 @@ public class TestOptimizations extends TestBase {
conn.close(); 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论