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

Do not use SimpleResultSet in JdbcArray and remove incorrect bound check

上级 18a3975b
......@@ -9,21 +9,22 @@ import java.sql.Array;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.Map;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.message.TraceObject;
import org.h2.tools.SimpleResultSet;
import org.h2.result.SimpleResult;
import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueLong;
/**
* Represents an ARRAY value.
*/
public class JdbcArray extends TraceObject implements Array {
private Value value;
private ValueArray value;
private final JdbcConnection conn;
/**
......@@ -32,7 +33,7 @@ public class JdbcArray extends TraceObject implements Array {
public JdbcArray(JdbcConnection conn, Value value, int id) {
setTrace(conn.getSession().getTrace(), TraceObject.ARRAY, id);
this.conn = conn;
this.value = value;
this.value = (ValueArray) value.convertTo(Value.ARRAY);
}
/**
......@@ -166,7 +167,7 @@ public class JdbcArray extends TraceObject implements Array {
try {
debugCodeCall("getResultSet");
checkClosed();
return getResultSet(get(), 0);
return getResultSetImpl(1L, Integer.MAX_VALUE);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -187,7 +188,7 @@ public class JdbcArray extends TraceObject implements Array {
}
checkClosed();
JdbcConnection.checkMap(map);
return getResultSet(get(), 0);
return getResultSetImpl(1L, Integer.MAX_VALUE);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -210,7 +211,7 @@ public class JdbcArray extends TraceObject implements Array {
debugCode("getResultSet("+index+", " + count+");");
}
checkClosed();
return getResultSet(get(index, count), index - 1);
return getResultSetImpl(index, count);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -237,7 +238,7 @@ public class JdbcArray extends TraceObject implements Array {
}
checkClosed();
JdbcConnection.checkMap(map);
return getResultSet(get(index, count), index - 1);
return getResultSetImpl(index, count);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -252,15 +253,18 @@ public class JdbcArray extends TraceObject implements Array {
value = null;
}
private static ResultSet getResultSet(Object[] array, long offset) {
SimpleResultSet rs = new SimpleResultSet();
rs.addColumn("INDEX", Types.BIGINT, 0, 0);
private ResultSet getResultSetImpl(long index, int count) {
int id = getNextId(TraceObject.RESULT_SET);
SimpleResult rs = new SimpleResult();
rs.addColumn("INDEX", "INDEX", Value.LONG, 0, 0, ValueLong.DISPLAY_SIZE);
// TODO array result set: there are multiple data types possible
rs.addColumn("VALUE", Types.NULL, 0, 0);
for (int i = 0; i < array.length; i++) {
rs.addRow(offset + i + 1, array[i]);
rs.addColumn("VALUE", "VALUE", Value.NULL, 0, 0, 15);
Value[] values = value.getList();
count = checkRange(index, count, values.length);
for (int i = (int) index; i < index + count; i++) {
rs.addRow(ValueLong.get(i), values[i - 1]);
}
return rs;
return new JdbcResultSet(conn, null, null, rs, id, false, true, false);
}
private void checkClosed() {
......@@ -271,21 +275,28 @@ public class JdbcArray extends TraceObject implements Array {
}
private Object[] get() {
return (Object[]) value.convertTo(Value.ARRAY).getObject();
return (Object[]) value.getObject();
}
private Object[] get(long index, int count) {
Object[] array = get();
if (count < 0 || count > array.length) {
throw DbException.getInvalidValueException("count (1.."
+ array.length + ")", count);
Value[] values = value.getList();
count = checkRange(index, count, values.length);
Object[] a = new Object[count];
for (int i = 0, j = (int) index - 1; i < count; i++, j++) {
a[i] = values[j].getObject();
}
if (index < 1 || index > array.length) {
throw DbException.getInvalidValueException("index (1.."
+ array.length + ")", index);
return a;
}
private static int checkRange(long index, int count, int len) {
if (index < 1 || index > len) {
throw DbException.getInvalidValueException("index (1.." + len + ')', index);
}
int rem = len - (int) index + 1;
if (count < 0) {
throw DbException.getInvalidValueException("count (0.." + rem + ')', count);
}
int offset = (int) (index - 1);
return Arrays.copyOfRange(array, offset, offset + count);
return Math.min(rem, count);
}
/**
......
......@@ -963,7 +963,7 @@ public class TestFunctions extends TestDb implements AggregateFunction {
assertEquals(0, ((Integer) array[0]).intValue());
assertEquals("Hello", (String) array[1]);
assertThrows(ErrorCode.INVALID_VALUE_2, a).getArray(1, -1);
assertThrows(ErrorCode.INVALID_VALUE_2, a).getArray(1, 3);
assertEquals(2, ((Object[]) a.getArray(1, 3)).length);
assertEquals(0, ((Object[]) a.getArray(1, 0)).length);
assertEquals(0, ((Object[]) a.getArray(2, 0)).length);
assertThrows(ErrorCode.INVALID_VALUE_2, a).getArray(0, 0);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论