提交 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 ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <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>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, </li><li>Spatial index: a few bugs have been fixed (using spatial constraints in views,
transferring geometry objects over TCP/IP). transferring geometry objects over TCP/IP).
......
...@@ -135,6 +135,7 @@ public class TableFunction extends Function { ...@@ -135,6 +135,7 @@ public class TableFunction extends Function {
int maxrows) { int maxrows) {
int columnCount = rs.getVisibleColumnCount(); int columnCount = rs.getVisibleColumnCount();
SimpleResultSet simple = new SimpleResultSet(); SimpleResultSet simple = new SimpleResultSet();
simple.setAutoClose(false);
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
String name = rs.getColumnName(i); String name = rs.getColumnName(i);
int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i)); int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i));
......
...@@ -64,149 +64,6 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -64,149 +64,6 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
private ArrayList<Column> columns = New.arrayList(); private ArrayList<Column> columns = New.arrayList();
private boolean autoClose = true; 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 * This constructor is used if the result set is later populated with
* addRow. * addRow.
...@@ -324,14 +181,18 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -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 @Override
public int getType() { public int getType() {
if (autoClose) {
return ResultSet.TYPE_FORWARD_ONLY; return ResultSet.TYPE_FORWARD_ONLY;
} }
return ResultSet.TYPE_SCROLL_INSENSITIVE;
}
/** /**
* Closes the result set and releases the resources. * Closes the result set and releases the resources.
...@@ -375,11 +236,14 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -375,11 +236,14 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
} }
/** /**
* Moves the current position to before the first row, that means resets the * Moves the current position to before the first row, that means the result
* result set. * set is reset.
*/ */
@Override @Override
public void beforeFirst() throws SQLException { public void beforeFirst() throws SQLException {
if (autoClose) {
throw DbException.get(ErrorCode.RESULT_SET_NOT_SCROLLABLE);
}
rowId = -1; rowId = -1;
if (source != null) { if (source != null) {
source.reset(); source.reset();
...@@ -2337,7 +2201,8 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -2337,7 +2201,8 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
* INTERNAL * INTERNAL
*/ */
static SQLException getUnsupportedException() { 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 { private void checkColumnIndex(int columnIndex) throws SQLException {
...@@ -2349,11 +2214,13 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -2349,11 +2214,13 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
private Object get(int columnIndex) throws SQLException { private Object get(int columnIndex) throws SQLException {
if (currentRow == null) { if (currentRow == null) {
throw DbException.get(ErrorCode.NO_DATA_AVAILABLE).getSQLException(); throw DbException.get(ErrorCode.NO_DATA_AVAILABLE).
getSQLException();
} }
checkColumnIndex(columnIndex); checkColumnIndex(columnIndex);
columnIndex--; columnIndex--;
Object o = columnIndex < currentRow.length ? currentRow[columnIndex] : null; Object o = columnIndex < currentRow.length ?
currentRow[columnIndex] : null;
wasNull = o == null; wasNull = o == null;
return o; return o;
} }
...@@ -2418,4 +2285,147 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -2418,4 +2285,147 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
return autoClose; 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 { ...@@ -64,6 +64,7 @@ public class TestResultSet extends TestBase {
stat = conn.createStatement(); stat = conn.createStatement();
testReuseSimpleResult();
testUnsupportedOperations(); testUnsupportedOperations();
testAmbiguousColumnNames(); testAmbiguousColumnNames();
testInsertRowWithUpdatableResultSetDefault(); testInsertRowWithUpdatableResultSetDefault();
...@@ -102,6 +103,19 @@ public class TestResultSet extends TestBase { ...@@ -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") @SuppressWarnings("deprecation")
private void testUnsupportedOperations() throws SQLException { private void testUnsupportedOperations() throws SQLException {
ResultSet rs = stat.executeQuery("select 1 as x from dual"); ResultSet rs = stat.executeQuery("select 1 as x from dual");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论