提交 428f1f59 authored 作者: Thomas Mueller's avatar Thomas Mueller

The GEOMETRY data type now works for user defined functions that return a result set.

上级 bb47d6be
......@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>PostgreSQL compatibility: the PgServer was not working properly when the setting
<ul><li>The GEOMETRY data type now works for user defined functions that return a result set.
</li><li>PostgreSQL compatibility: the PgServer was not working properly when the setting
database_to_upper was set to false.
</li><li>JdbcDataSource: the methods setUrl and getUrl where added as aliases for setURL and getURL.
This should solve problems with the HikariCP (Hikari connection pool).
......
......@@ -331,7 +331,7 @@ public abstract class Expression {
Database db = session == null ? null : session.getDatabase();
for (int i = 0; i < columnCount; i++) {
String name = meta.getColumnLabel(i + 1);
int type = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
int type = DataType.getValueTypeFromResultSet(meta, i + 1);
int precision = meta.getPrecision(i + 1);
int scale = meta.getScale(i + 1);
int displaySize = meta.getColumnDisplaySize(i + 1);
......
......@@ -61,8 +61,8 @@ public class FunctionCursorResultSet implements Cursor {
int columnCount = meta.getColumnCount();
values = new Value[columnCount];
for (int i = 0; i < columnCount; i++) {
int type = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
values[i] = DataType.readValue(session, result, i+1, type);
int type = DataType.getValueTypeFromResultSet(meta, i + 1);
values[i] = DataType.readValue(session, result, i + 1, type);
}
} else {
values = null;
......
......@@ -392,7 +392,7 @@ public class ValueDataType implements DataType {
while (rs.next()) {
buff.put((byte) 1);
for (int i = 0; i < columnCount; i++) {
int t = org.h2.value.DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
int t = org.h2.value.DataType.getValueTypeFromResultSet(meta, i + 1);
Value val = org.h2.value.DataType.readValue(null, rs, i + 1, t);
writeValue(buff, val);
}
......
......@@ -665,7 +665,7 @@ public class Data {
while (rs.next()) {
writeByte((byte) 1);
for (int i = 0; i < columnCount; i++) {
int t = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
int t = DataType.getValueTypeFromResultSet(meta, i + 1);
Value val = DataType.readValue(null, rs, i + 1, t);
writeValue(val);
}
......@@ -1075,7 +1075,7 @@ public class Data {
while (rs.next()) {
len++;
for (int i = 0; i < columnCount; i++) {
int t = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
int t = DataType.getValueTypeFromResultSet(meta, i + 1);
Value val = DataType.readValue(null, rs, i + 1, t);
len += getValueLen(val, handler);
}
......
......@@ -70,8 +70,10 @@ public class FunctionTable extends Table {
int columnCount = meta.getColumnCount();
Column[] cols = new Column[columnCount];
for (int i = 0; i < columnCount; i++) {
cols[i] = new Column(meta.getColumnName(i + 1), DataType.convertSQLTypeToValueType(meta
.getColumnType(i + 1)), meta.getPrecision(i + 1), meta.getScale(i + 1), meta.getColumnDisplaySize(i + 1));
cols[i] = new Column(meta.getColumnName(i + 1),
DataType.getValueTypeFromResultSet(meta, i + 1),
meta.getPrecision(i + 1),
meta.getScale(i + 1), meta.getColumnDisplaySize(i + 1));
}
setColumns(cols);
} catch (SQLException e) {
......
......@@ -180,7 +180,7 @@ public class TableLink extends Table {
int scale = rsMeta.getScale(i + 1);
scale = convertScale(sqlType, scale);
int displaySize = rsMeta.getColumnDisplaySize(i + 1);
int type = DataType.convertSQLTypeToValueType(sqlType);
int type = DataType.getValueTypeFromResultSet(rsMeta, i + 1);
Column col = new Column(n, type, precision, scale, displaySize);
col.setTable(this, i++);
columnList.add(col);
......
......@@ -74,6 +74,11 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/
String name;
/**
* The column type Name
*/
String sqlTypeName;
/**
* The SQL type.
*/
......@@ -218,13 +223,29 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
/**
* Adds a column to the result set.
* All columns must be added before adding rows.
* This method uses the default SQL type names.
*
* @param name null is replaced with C1, C2,...
* @param sqlType the value returned in getColumnType(..) (ignored internally)
* @param sqlType the value returned in getColumnType(..)
* @param precision the precision
* @param scale the scale
*/
public void addColumn(String name, int sqlType, int precision, int scale) {
int valueType = DataType.convertSQLTypeToValueType(sqlType);
addColumn(name, sqlType, DataType.getDataType(valueType).name, precision, scale);
}
/**
* Adds a column to the result set.
* All columns must be added before adding rows.
*
* @param name null is replaced with C1, C2,...
* @param sqlType the value returned in getColumnType(..)
* @param sqlTypeName the type name return in getColumnTypeName(..)
* @param precision the precision
* @param scale the scale
*/
public void addColumn(String name, int sqlType, String sqlTypeName, int precision, int scale) {
if (rows != null && rows.size() > 0) {
throw new IllegalStateException("Cannot add a column after adding rows");
}
......@@ -236,6 +257,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
column.sqlType = sqlType;
column.precision = precision;
column.scale = scale;
column.sqlTypeName = sqlTypeName;
columns.add(column);
}
......@@ -2025,8 +2047,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/
@Override
public String getColumnClassName(int columnIndex) throws SQLException {
int sqlType = getColumn(columnIndex - 1).sqlType;
int type = DataType.convertSQLTypeToValueType(sqlType);
int type = DataType.getValueTypeFromResultSet(this, columnIndex);
return DataType.getTypeClassName(type);
}
......@@ -2060,9 +2081,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/
@Override
public String getColumnTypeName(int columnIndex) throws SQLException {
int sqlType = getColumn(columnIndex - 1).sqlType;
int type = DataType.convertSQLTypeToValueType(sqlType);
return DataType.getDataType(type).name;
return getColumn(columnIndex - 1).sqlTypeName;
}
/**
......
......@@ -15,6 +15,7 @@ import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
......@@ -735,6 +736,40 @@ public class DataType {
return getDataType(type).sqlType;
}
/**
* Convert a SQL type to a value type using SQL type name, in order to
* manage SQL type extension mechanism.
*
* @param sqlType the SQL type
* @param sqlTypeName the SQL type name
* @return the value type
*/
private static int convertSQLTypeToValueType(int sqlType, String sqlTypeName) {
switch(sqlType) {
case Types.OTHER:
case Types.JAVA_OBJECT:
if (sqlTypeName.equalsIgnoreCase("geometry")) {
return Value.GEOMETRY;
}
}
return convertSQLTypeToValueType(sqlType);
}
/**
* Get the SQL type from the result set meta data for the given column. This
* method uses the SQL type and type name.
*
* @param meta the meta data
* @param columnIndex the column index (1, 2,...)
* @return the value type
*/
public static int getValueTypeFromResultSet(ResultSetMetaData meta, int columnIndex)
throws SQLException {
return convertSQLTypeToValueType(
meta.getColumnType(columnIndex),
meta.getColumnTypeName(columnIndex));
}
/**
* Convert a SQL type to a value type.
*
......
......@@ -495,7 +495,7 @@ public class Transfer {
while (rs.next()) {
writeBoolean(true);
for (int i = 0; i < columnCount; i++) {
int t = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1));
int t = DataType.getValueTypeFromResultSet(meta, i + 1);
Value val = DataType.readValue(session, rs, i + 1, t);
writeValue(val);
}
......
......@@ -104,7 +104,7 @@ public class ValueResultSet extends Value {
buff.resetCount();
for (int j = 0; j < columnCount; j++) {
buff.appendExceptFirst(", ");
int t = DataType.convertSQLTypeToValueType(meta.getColumnType(j + 1));
int t = DataType.getValueTypeFromResultSet(meta, j + 1);
Value v = DataType.readValue(null, result, j+1, t);
buff.append(v.getString());
}
......
......@@ -63,6 +63,7 @@ public class TestSpatial extends TestBase {
testWKB();
testValueConversion();
testEquals();
testTableFunctionGeometry();
testHashCode();
deleteDb("spatial");
}
......@@ -499,7 +500,7 @@ public class TestSpatial extends TestBase {
random.setSeed(seed);
}
});
rs.addColumn("the_geom", Types.OTHER, Integer.MAX_VALUE, 0);
rs.addColumn("the_geom", Types.OTHER, "GEOMETRY", Integer.MAX_VALUE, 0);
return rs;
}
......@@ -594,4 +595,34 @@ public class TestSpatial extends TestBase {
}
}
/**
* Check that geometry column type is kept with a table function
*/
private void testTableFunctionGeometry() throws SQLException {
deleteDb("spatialIndex");
Connection conn = getConnection("spatialIndex");
try {
Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS POINT_TABLE FOR \"" +
TestSpatial.class.getName() + ".pointTable\"");
stat.execute("create table test as select * from point_table(1, 1)");
// Read column type
ResultSet columnMeta = conn.getMetaData().getColumns(null, null, "TEST", "THE_GEOM");
assertTrue(columnMeta.next());
assertEquals("geometry", columnMeta.getString("TYPE_NAME").toLowerCase());
assertFalse(columnMeta.next());
} finally {
conn.close();
}
deleteDb("spatialIndex");
}
public static ResultSet pointTable(double x, double y) {
GeometryFactory factory = new GeometryFactory();
SimpleResultSet srs = new SimpleResultSet();
srs.addColumn("THE_GEOM", Types.JAVA_OBJECT, "GEOMETRY", 0, 0);
srs.addRow(factory.createPoint(new Coordinate(x, y)));
return srs;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论