提交 d04b4cb7 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add support for IN(UNNEST(?)

上级 21036320
......@@ -490,7 +490,7 @@ Instead, use a prepared statement with arrays as in the following example:
</p>
<pre>
PreparedStatement prep = conn.prepareStatement(
"SELECT * FROM TEST WHERE ID = ANY(?)");
"SELECT * FROM TEST WHERE ID IN(UNNEST(?))");
prep.setObject(1, new Object[] { "1", "2" });
ResultSet rs = prep.executeQuery();
</pre>
......
......@@ -8,6 +8,8 @@ package org.h2.expression;
import java.util.ArrayList;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.expression.function.Function;
import org.h2.expression.function.TableFunction;
import org.h2.index.IndexCondition;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
......@@ -103,6 +105,18 @@ public class ConditionIn extends Condition {
}
if (size == 1) {
Expression right = valueList.get(0);
if (right instanceof TableFunction) {
TableFunction tf = (TableFunction) right;
if (tf.getFunctionType() == Function.UNNEST) {
Expression[] args = tf.getArgs();
if (args.length == 1) {
Expression arg = args[0];
if (arg instanceof Parameter) {
return new ConditionInParameter(database, left, (Parameter) arg);
}
}
}
}
Expression expr = new Comparison(session, Comparison.EQUAL, left, right);
expr = expr.optimize(session);
return expr;
......
......@@ -18,7 +18,7 @@ import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull;
/**
* A condition with parameter as {@code = ANY(?)}.
* A condition with parameter as {@code IN(UNNEST(?))}.
*/
public class ConditionInParameter extends Condition {
private static final class ParameterList extends AbstractList<Expression> {
......@@ -60,12 +60,12 @@ public class ConditionInParameter extends Condition {
private final Parameter parameter;
/**
* Create a new {@code = ANY(?)} condition.
* Create a new {@code IN(UNNEST(?))} condition.
*
* @param database
* the database
* @param left
* the expression before {@code = ANY(?)}
* the expression before {@code IN(UNNEST(?))}
* @param parameter
* parameter
*/
......@@ -84,8 +84,10 @@ public class ConditionInParameter extends Condition {
boolean result = false;
boolean hasNull = false;
Value value = parameter.getValue(session);
if (value instanceof ValueArray) {
for (Value r : ((ValueArray) value).getList()) {
if (value == ValueNull.INSTANCE) {
hasNull = true;
} else {
for (Value r : ((ValueArray) value.convertTo(Value.ARRAY)).getList()) {
if (r == ValueNull.INSTANCE) {
hasNull = true;
} else {
......@@ -95,12 +97,6 @@ public class ConditionInParameter extends Condition {
}
}
}
} else {
if (value == ValueNull.INSTANCE) {
hasNull = true;
} else {
result = Comparison.compareNotNull(database, l, value, Comparison.EQUAL);
}
}
if (!result && hasNull) {
return ValueNull.INSTANCE;
......@@ -142,8 +138,8 @@ public class ConditionInParameter extends Condition {
@Override
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(" = ANY(");
return parameter.getSQL(builder).append("))");
left.getSQL(builder).append(" IN(UNNEST(");
return parameter.getSQL(builder).append(")))");
}
@Override
......
......@@ -1635,6 +1635,12 @@ public class TestPreparedStatement extends TestDb {
anyParameterCheck(ps, values, expected);
ps = conn.prepareStatement("SELECT ID FROM TEST INNER JOIN TABLE(X INT=?) T ON TEST.VALUE = T.X");
anyParameterCheck(ps, values, expected);
// Test expression IN(UNNEST(?))
ps = conn.prepareStatement("SELECT ID FROM TEST WHERE VALUE IN(UNNEST(?))");
assertThrows(ErrorCode.PARAMETER_NOT_SET_1, ps).executeQuery();
anyParameterCheck(ps, values, expected);
anyParameterCheck(ps, 300, new int[] {30});
anyParameterCheck(ps, -5, new int[0]);
// Test expression = ANY(?)
ps = conn.prepareStatement("SELECT ID FROM TEST WHERE VALUE = ANY(?)");
assertThrows(ErrorCode.PARAMETER_NOT_SET_1, ps).executeQuery();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论