提交 4ee69cc5 authored 作者: Thomas Mueller's avatar Thomas Mueller

Optimize IN(...) queries: there was a bug in version 1.3.170 for comparison of…

Optimize IN(...) queries: there was a bug in version 1.3.170 for comparison of the type "X IN(NULL, NULL)". Fixed.
上级 894b0783
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Timestamps with timezone that were passed as a string were not always
<ul><li>Optimize IN(...) queries: there was a bug in version 1.3.170 for comparison of the type
"X IN(NULL, NULL)". Fixed.
</li><li>Timestamps with timezone that were passed as a string were not always
converted correctly. For example "2012-11-06T23:00:00.000Z" was converted to
"2012-11-06" instead of to "2012-11-07" in the timezone CET.
Thanks a lot to Steve Hruda for reporting the problem!
......
......@@ -81,11 +81,15 @@ public class ConditionIn extends Condition {
}
boolean allValuesConstant = true;
boolean allValuesSameType = true;
boolean allValuesNull = true;
int size = valueList.size();
Expression lastExpr = null;
for (int i = 0; i < size; i++) {
Expression e = valueList.get(i);
e = e.optimize(session);
if (e.isConstant() && e.getValue(session) != ValueNull.INSTANCE) {
allValuesNull = false;
}
if (allValuesConstant && !e.isConstant()) {
allValuesConstant = false;
}
......@@ -104,7 +108,7 @@ public class ConditionIn extends Condition {
expr = expr.optimize(session);
return expr;
}
if (allValuesConstant && allValuesSameType) {
if (allValuesConstant && allValuesSameType && !allValuesNull) {
Expression expr = new ConditionInConstantSet(session, left, valueList);
expr = expr.optimize(session);
return expr;
......
......@@ -53,14 +53,24 @@ public class ConditionInConstantSet extends Condition {
if (leftVal == ValueNull.INSTANCE) {
return leftVal;
}
boolean setHasNull = valueSet.contains(ValueNull.INSTANCE);
Value firstRightVal = valueSet.iterator().next();
leftVal = leftVal.convertTo(firstRightVal.getType());
Value firstRightValue = null;
for (Value v : valueSet) {
if (v != ValueNull.INSTANCE) {
firstRightValue = v;
break;
}
}
if (firstRightValue == null) {
throw DbException.throwInternalError();
}
leftVal = leftVal.convertTo(firstRightValue.getType());
boolean result = valueSet.contains(leftVal);
if (!result && setHasNull) {
if (!result) {
boolean setHasNull = valueSet.contains(ValueNull.INSTANCE);
if (setHasNull) {
return ValueNull.INSTANCE;
}
}
return ValueBoolean.get(result);
}
......
......@@ -23,6 +23,11 @@ create table test(id int, name varchar);
insert into test values(5, 'b'), (5, 'b'), (20, 'a');
> update count: 3
select id from test where name in(null, null);
> ID
> --
> rows: 0
select * from (select * from test order by name limit 1) where id < 10;
> ID NAME
> -- ----
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论