提交 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 ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <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. database_to_upper was set to false.
</li><li>JdbcDataSource: the methods setUrl and getUrl where added as aliases for setURL and getURL. </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). This should solve problems with the HikariCP (Hikari connection pool).
......
...@@ -331,7 +331,7 @@ public abstract class Expression { ...@@ -331,7 +331,7 @@ public abstract class Expression {
Database db = session == null ? null : session.getDatabase(); Database db = session == null ? null : session.getDatabase();
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
String name = meta.getColumnLabel(i + 1); 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 precision = meta.getPrecision(i + 1);
int scale = meta.getScale(i + 1); int scale = meta.getScale(i + 1);
int displaySize = meta.getColumnDisplaySize(i + 1); int displaySize = meta.getColumnDisplaySize(i + 1);
......
...@@ -61,8 +61,8 @@ public class FunctionCursorResultSet implements Cursor { ...@@ -61,8 +61,8 @@ public class FunctionCursorResultSet implements Cursor {
int columnCount = meta.getColumnCount(); int columnCount = meta.getColumnCount();
values = new Value[columnCount]; values = new Value[columnCount];
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
int type = DataType.convertSQLTypeToValueType(meta.getColumnType(i + 1)); int type = DataType.getValueTypeFromResultSet(meta, i + 1);
values[i] = DataType.readValue(session, result, i+1, type); values[i] = DataType.readValue(session, result, i + 1, type);
} }
} else { } else {
values = null; values = null;
......
...@@ -392,7 +392,7 @@ public class ValueDataType implements DataType { ...@@ -392,7 +392,7 @@ public class ValueDataType implements DataType {
while (rs.next()) { while (rs.next()) {
buff.put((byte) 1); buff.put((byte) 1);
for (int i = 0; i < columnCount; i++) { 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); Value val = org.h2.value.DataType.readValue(null, rs, i + 1, t);
writeValue(buff, val); writeValue(buff, val);
} }
......
...@@ -665,7 +665,7 @@ public class Data { ...@@ -665,7 +665,7 @@ public class Data {
while (rs.next()) { while (rs.next()) {
writeByte((byte) 1); writeByte((byte) 1);
for (int i = 0; i < columnCount; i++) { 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); Value val = DataType.readValue(null, rs, i + 1, t);
writeValue(val); writeValue(val);
} }
...@@ -1075,7 +1075,7 @@ public class Data { ...@@ -1075,7 +1075,7 @@ public class Data {
while (rs.next()) { while (rs.next()) {
len++; len++;
for (int i = 0; i < columnCount; i++) { 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); Value val = DataType.readValue(null, rs, i + 1, t);
len += getValueLen(val, handler); len += getValueLen(val, handler);
} }
......
...@@ -70,8 +70,10 @@ public class FunctionTable extends Table { ...@@ -70,8 +70,10 @@ public class FunctionTable extends Table {
int columnCount = meta.getColumnCount(); int columnCount = meta.getColumnCount();
Column[] cols = new Column[columnCount]; Column[] cols = new Column[columnCount];
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
cols[i] = new Column(meta.getColumnName(i + 1), DataType.convertSQLTypeToValueType(meta cols[i] = new Column(meta.getColumnName(i + 1),
.getColumnType(i + 1)), meta.getPrecision(i + 1), meta.getScale(i + 1), meta.getColumnDisplaySize(i + 1)); DataType.getValueTypeFromResultSet(meta, i + 1),
meta.getPrecision(i + 1),
meta.getScale(i + 1), meta.getColumnDisplaySize(i + 1));
} }
setColumns(cols); setColumns(cols);
} catch (SQLException e) { } catch (SQLException e) {
......
...@@ -180,7 +180,7 @@ public class TableLink extends Table { ...@@ -180,7 +180,7 @@ public class TableLink extends Table {
int scale = rsMeta.getScale(i + 1); int scale = rsMeta.getScale(i + 1);
scale = convertScale(sqlType, scale); scale = convertScale(sqlType, scale);
int displaySize = rsMeta.getColumnDisplaySize(i + 1); 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); Column col = new Column(n, type, precision, scale, displaySize);
col.setTable(this, i++); col.setTable(this, i++);
columnList.add(col); columnList.add(col);
......
...@@ -74,6 +74,11 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -74,6 +74,11 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/ */
String name; String name;
/**
* The column type Name
*/
String sqlTypeName;
/** /**
* The SQL type. * The SQL type.
*/ */
...@@ -218,13 +223,29 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -218,13 +223,29 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
/** /**
* Adds a column to the result set. * Adds a column to the result set.
* All columns must be added before adding rows. * 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 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 precision the precision
* @param scale the scale * @param scale the scale
*/ */
public void addColumn(String name, int sqlType, int precision, int 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) { if (rows != null && rows.size() > 0) {
throw new IllegalStateException("Cannot add a column after adding rows"); throw new IllegalStateException("Cannot add a column after adding rows");
} }
...@@ -236,6 +257,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -236,6 +257,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
column.sqlType = sqlType; column.sqlType = sqlType;
column.precision = precision; column.precision = precision;
column.scale = scale; column.scale = scale;
column.sqlTypeName = sqlTypeName;
columns.add(column); columns.add(column);
} }
...@@ -2025,8 +2047,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -2025,8 +2047,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/ */
@Override @Override
public String getColumnClassName(int columnIndex) throws SQLException { public String getColumnClassName(int columnIndex) throws SQLException {
int sqlType = getColumn(columnIndex - 1).sqlType; int type = DataType.getValueTypeFromResultSet(this, columnIndex);
int type = DataType.convertSQLTypeToValueType(sqlType);
return DataType.getTypeClassName(type); return DataType.getTypeClassName(type);
} }
...@@ -2060,9 +2081,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData { ...@@ -2060,9 +2081,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData {
*/ */
@Override @Override
public String getColumnTypeName(int columnIndex) throws SQLException { public String getColumnTypeName(int columnIndex) throws SQLException {
int sqlType = getColumn(columnIndex - 1).sqlType; return getColumn(columnIndex - 1).sqlTypeName;
int type = DataType.convertSQLTypeToValueType(sqlType);
return DataType.getDataType(type).name;
} }
/** /**
......
...@@ -15,6 +15,7 @@ import java.sql.Blob; ...@@ -15,6 +15,7 @@ import java.sql.Blob;
import java.sql.Clob; import java.sql.Clob;
import java.sql.Date; import java.sql.Date;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
...@@ -735,6 +736,40 @@ public class DataType { ...@@ -735,6 +736,40 @@ public class DataType {
return getDataType(type).sqlType; 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. * Convert a SQL type to a value type.
* *
......
...@@ -495,7 +495,7 @@ public class Transfer { ...@@ -495,7 +495,7 @@ public class Transfer {
while (rs.next()) { while (rs.next()) {
writeBoolean(true); writeBoolean(true);
for (int i = 0; i < columnCount; i++) { 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); Value val = DataType.readValue(session, rs, i + 1, t);
writeValue(val); writeValue(val);
} }
......
...@@ -104,7 +104,7 @@ public class ValueResultSet extends Value { ...@@ -104,7 +104,7 @@ public class ValueResultSet extends Value {
buff.resetCount(); buff.resetCount();
for (int j = 0; j < columnCount; j++) { for (int j = 0; j < columnCount; j++) {
buff.appendExceptFirst(", "); 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); Value v = DataType.readValue(null, result, j+1, t);
buff.append(v.getString()); buff.append(v.getString());
} }
......
...@@ -63,6 +63,7 @@ public class TestSpatial extends TestBase { ...@@ -63,6 +63,7 @@ public class TestSpatial extends TestBase {
testWKB(); testWKB();
testValueConversion(); testValueConversion();
testEquals(); testEquals();
testTableFunctionGeometry();
testHashCode(); testHashCode();
deleteDb("spatial"); deleteDb("spatial");
} }
...@@ -499,7 +500,7 @@ public class TestSpatial extends TestBase { ...@@ -499,7 +500,7 @@ public class TestSpatial extends TestBase {
random.setSeed(seed); 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; return rs;
} }
...@@ -594,4 +595,34 @@ public class TestSpatial extends TestBase { ...@@ -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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论