提交 5d7d2dd8 authored 作者: Thomas Mueller's avatar Thomas Mueller

If a value of a result set was itself a result set, the result could only be read once.

上级 94520f3f
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Column constraints are also visible in views (patch from Nicolas Fortin for H2GIS).
<ul><li>If a value of a result set was itself a result set, the result
could only be read once.
</li><li>Column constraints are also visible in views (patch from Nicolas Fortin for H2GIS).
</li><li>Granting a additional right to a role that already had a right for that table was not working.
</li><li>Spatial index: a few bugs have been fixed (using spatial constraints in views,
transferring geometry objects over TCP/IP).
......
......@@ -135,6 +135,7 @@ public class TableFunction extends Function {
int maxrows) {
int columnCount = rs.getVisibleColumnCount();
SimpleResultSet simple = new SimpleResultSet();
simple.setAutoClose(false);
for (int i = 0; i < columnCount; i++) {
String name = rs.getColumnName(i);
int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i));
......
......@@ -64,149 +64,6 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
private ArrayList<Column> columns = New.arrayList();
private boolean autoClose = true;
/**
* This class holds the data of a result column.
*/
static class Column {
/**
* The column label.
*/
String name;
/**
* The column type Name
*/
String sqlTypeName;
/**
* The SQL type.
*/
int sqlType;
/**
* The precision.
*/
int precision;
/**
* The scale.
*/
int scale;
}
/**
* A simple array implementation,
* backed by an object array
*/
public static class SimpleArray implements Array {
private final Object[] value;
SimpleArray(Object[] value) {
this.value = value;
}
/**
* Get the object array.
*
* @return the object array
*/
@Override
public Object getArray() {
return value;
}
/**
* INTERNAL
*/
@Override
public Object getArray(Map<String, Class<?>> map) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public Object getArray(long index, int count) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public Object getArray(long index, int count, Map<String, Class<?>> map)
throws SQLException {
throw getUnsupportedException();
}
/**
* Get the base type of this array.
*
* @return Types.NULL
*/
@Override
public int getBaseType() {
return Types.NULL;
}
/**
* Get the base type name of this array.
*
* @return "NULL"
*/
@Override
public String getBaseTypeName() {
return "NULL";
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet() throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(Map<String, Class<?>> map)
throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(long index, int count)
throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(long index, int count,
Map<String, Class<?>> map) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public void free() {
// nothing to do
}
}
/**
* This constructor is used if the result set is later populated with
* addRow.
......@@ -324,14 +181,18 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
}
/**
* Returns ResultSet.TYPE_FORWARD_ONLY.
* Returns the result set type. This is ResultSet.TYPE_FORWARD_ONLY for
* auto-close result sets, and ResultSet.TYPE_SCROLL_INSENSITIVE for others.
*
* @return TYPE_FORWARD_ONLY
* @return TYPE_FORWARD_ONLY or TYPE_SCROLL_INSENSITIVE
*/
@Override
public int getType() {
if (autoClose) {
return ResultSet.TYPE_FORWARD_ONLY;
}
return ResultSet.TYPE_SCROLL_INSENSITIVE;
}
/**
* Closes the result set and releases the resources.
......@@ -375,11 +236,14 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
}
/**
* Moves the current position to before the first row, that means resets the
* result set.
* Moves the current position to before the first row, that means the result
* set is reset.
*/
@Override
public void beforeFirst() throws SQLException {
if (autoClose) {
throw DbException.get(ErrorCode.RESULT_SET_NOT_SCROLLABLE);
}
rowId = -1;
if (source != null) {
source.reset();
......@@ -2337,7 +2201,8 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
* INTERNAL
*/
static SQLException getUnsupportedException() {
return DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1).getSQLException();
return DbException.get(ErrorCode.FEATURE_NOT_SUPPORTED_1).
getSQLException();
}
private void checkColumnIndex(int columnIndex) throws SQLException {
......@@ -2349,11 +2214,13 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
private Object get(int columnIndex) throws SQLException {
if (currentRow == null) {
throw DbException.get(ErrorCode.NO_DATA_AVAILABLE).getSQLException();
throw DbException.get(ErrorCode.NO_DATA_AVAILABLE).
getSQLException();
}
checkColumnIndex(columnIndex);
columnIndex--;
Object o = columnIndex < currentRow.length ? currentRow[columnIndex] : null;
Object o = columnIndex < currentRow.length ?
currentRow[columnIndex] : null;
wasNull = o == null;
return o;
}
......@@ -2418,4 +2285,147 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
return autoClose;
}
/**
* This class holds the data of a result column.
*/
static class Column {
/**
* The column label.
*/
String name;
/**
* The column type Name
*/
String sqlTypeName;
/**
* The SQL type.
*/
int sqlType;
/**
* The precision.
*/
int precision;
/**
* The scale.
*/
int scale;
}
/**
* A simple array implementation,
* backed by an object array
*/
public static class SimpleArray implements Array {
private final Object[] value;
SimpleArray(Object[] value) {
this.value = value;
}
/**
* Get the object array.
*
* @return the object array
*/
@Override
public Object getArray() {
return value;
}
/**
* INTERNAL
*/
@Override
public Object getArray(Map<String, Class<?>> map) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public Object getArray(long index, int count) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public Object getArray(long index, int count, Map<String, Class<?>> map)
throws SQLException {
throw getUnsupportedException();
}
/**
* Get the base type of this array.
*
* @return Types.NULL
*/
@Override
public int getBaseType() {
return Types.NULL;
}
/**
* Get the base type name of this array.
*
* @return "NULL"
*/
@Override
public String getBaseTypeName() {
return "NULL";
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet() throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(Map<String, Class<?>> map)
throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(long index, int count)
throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public ResultSet getResultSet(long index, int count,
Map<String, Class<?>> map) throws SQLException {
throw getUnsupportedException();
}
/**
* INTERNAL
*/
@Override
public void free() {
// nothing to do
}
}
}
......@@ -64,6 +64,7 @@ public class TestResultSet extends TestBase {
stat = conn.createStatement();
testReuseSimpleResult();
testUnsupportedOperations();
testAmbiguousColumnNames();
testInsertRowWithUpdatableResultSetDefault();
......@@ -102,6 +103,19 @@ public class TestResultSet extends TestBase {
}
private void testReuseSimpleResult() throws SQLException {
ResultSet rs = stat.executeQuery("select table(x array=((1)))");
while (rs.next()) {
rs.getString(1);
}
rs.close();
rs = stat.executeQuery("select table(x array=((1)))");
while (rs.next()) {
rs.getString(1);
}
rs.close();
}
@SuppressWarnings("deprecation")
private void testUnsupportedOperations() throws SQLException {
ResultSet rs = stat.executeQuery("select 1 as x from dual");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论