提交 cebe254a authored 作者: Thomas Mueller's avatar Thomas Mueller

A prepared statement if type CALL that returned a result set could throw a…

A prepared statement if type CALL that returned a result set could throw a NullPointerExecption if executed multiple times.
上级 1fb40cce
......@@ -15,7 +15,6 @@ import org.h2.expression.ExpressionVisitor;
import org.h2.result.LocalResult;
import org.h2.result.ResultInterface;
import org.h2.value.Value;
import org.h2.value.ValueResultSet;
/**
* This class represents the statement
......@@ -23,6 +22,7 @@ import org.h2.value.ValueResultSet;
*/
public class Call extends Prepared {
private boolean isResultSet;
private Expression expression;
private Expression[] expressions;
......@@ -31,9 +31,8 @@ public class Call extends Prepared {
}
public ResultInterface queryMeta() {
int expressionType = expression.getType();
LocalResult result;
if (expressionType == Value.RESULT_SET) {
if (isResultSet) {
Expression[] expr = expression.getExpressionColumns(session);
result = new LocalResult(session, expr, expr.length);
} else {
......@@ -62,8 +61,9 @@ public class Call extends Prepared {
public ResultInterface query(int maxrows) {
setCurrentRowNumber(1);
Value v = expression.getValue(session);
if (v.getType() == Value.RESULT_SET) {
ResultSet rs = ((ValueResultSet) v).getResultSet();
if (isResultSet) {
v = v.convertTo(Value.RESULT_SET);
ResultSet rs = v.getResultSet();
return LocalResult.read(session, rs, maxrows);
}
LocalResult result = new LocalResult(session, expressions, 1);
......@@ -76,6 +76,10 @@ public class Call extends Prepared {
public void prepare() {
expression = expression.optimize(session);
expressions = new Expression[] { expression };
isResultSet = expression.getType() == Value.RESULT_SET;
if (isResultSet) {
prepareAlways = true;
}
}
public void setExpression(Expression expression) {
......@@ -99,4 +103,8 @@ public class Call extends Prepared {
return CommandInterface.CALL;
}
public boolean isCacheable() {
return !isResultSet;
}
}
......@@ -13,6 +13,7 @@ import java.lang.ref.SoftReference;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
......@@ -24,6 +25,7 @@ import org.h2.store.DataHandler;
import org.h2.store.LobStorage;
import org.h2.tools.SimpleResultSet;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
......@@ -1068,6 +1070,13 @@ public abstract class Value {
return this;
}
public ResultSet getResultSet() {
SimpleResultSet rs = new SimpleResultSet();
rs.addColumn("X", DataType.convertTypeToSQLType(getType()), MathUtils.convertLongToInt(getPrecision()), getScale());
rs.addRow(getObject());
return rs;
}
/**
* A "binary large object".
*/
......
......@@ -44,6 +44,7 @@ public class TestPreparedStatement extends TestBase {
public void test() throws Exception {
deleteDb("preparedStatement");
Connection conn = getConnection("preparedStatement");
testCallTablePrepared(conn);
testValues(conn);
testToString(conn);
testExecuteUpdateCall(conn);
......@@ -80,6 +81,12 @@ public class TestPreparedStatement extends TestBase {
deleteDb("preparedStatement");
}
private void testCallTablePrepared(Connection conn) throws SQLException {
PreparedStatement prep = conn.prepareStatement("call table(x int = (1))");
prep.executeQuery();
prep.executeQuery();
}
private void testValues(Connection conn) throws SQLException {
PreparedStatement prep = conn.prepareStatement("values(?, ?)");
prep.setInt(1, 1);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论