Unverified 提交 621cd6e5 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1004 from katzyn/misc

Preserve type names in more places especially for UUID
...@@ -21,6 +21,18 @@ Change Log ...@@ -21,6 +21,18 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>PR #1004: Preserve type names in more places especially for UUID
</li>
<li>Issue #1000: Regression in INFORMATION_SCHEMA.CONSTRAINTS.CONSTRAINT_TYPE content
</li>
<li>Issue #997: Can not delete from tables with enums
</li>
<li>Issue #994: Too much column in result set for GENERATED_KEYS on table with DEFAULT
</li>
<li>PR #993: Fix some compiler warnings and improve assert*() methods
</li>
<li>PR #991: Generate shorter queries in JdbcDatabaseMetaData.getTables() and remove some dead code
</li>
<li>PR #989: Fix more issues with range table and improve its documentation <li>PR #989: Fix more issues with range table and improve its documentation
</li> </li>
</ul> </ul>
......
...@@ -3027,7 +3027,7 @@ public class Parser { ...@@ -3027,7 +3027,7 @@ public class Parser {
int index = currentValue.getInt() - 1; int index = currentValue.getInt() - 1;
if (index < 0 || index >= Constants.MAX_PARAMETER_INDEX) { if (index < 0 || index >= Constants.MAX_PARAMETER_INDEX) {
throw DbException.getInvalidValueException( throw DbException.getInvalidValueException(
"parameter index", index); "parameter index", index + 1);
} }
if (indexedParameterList.size() <= index) { if (indexedParameterList.size() <= index) {
indexedParameterList.ensureCapacity(index + 1); indexedParameterList.ensureCapacity(index + 1);
......
...@@ -135,14 +135,12 @@ public class TableFunction extends Function { ...@@ -135,14 +135,12 @@ public class TableFunction extends Function {
simple.setAutoClose(false); 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);
/* DataType dataType = DataType.getDataType(rs.getColumnType(i));
* TODO Some types, such as Value.BYTES and Value.UUID are mapped to the same int sqlType = dataType.sqlType;
* SQL type and we can lose real type here. String sqlTypeName = dataType.name;
*/
int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i));
int precision = MathUtils.convertLongToInt(rs.getColumnPrecision(i)); int precision = MathUtils.convertLongToInt(rs.getColumnPrecision(i));
int scale = rs.getColumnScale(i); int scale = rs.getColumnScale(i);
simple.addColumn(name, sqlType, precision, scale); simple.addColumn(name, sqlType, sqlTypeName, precision, scale);
} }
rs.reset(); rs.reset();
for (int i = 0; i < maxrows && rs.next(); i++) { for (int i = 0; i < maxrows && rs.next(); i++) {
......
...@@ -38,6 +38,7 @@ import org.h2.util.Bits; ...@@ -38,6 +38,7 @@ import org.h2.util.Bits;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.SimpleColumnInfo;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.DataType; import org.h2.value.DataType;
...@@ -67,7 +68,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -67,7 +68,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
private int rowId = -1; private int rowId = -1;
private boolean wasNull; private boolean wasNull;
private SimpleRowSource source; private SimpleRowSource source;
private ArrayList<Column> columns = New.arrayList(); private ArrayList<SimpleColumnInfo> columns = New.arrayList();
private boolean autoClose = true; private boolean autoClose = true;
/** /**
...@@ -123,13 +124,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -123,13 +124,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
if (name == null) { if (name == null) {
name = "C" + (columns.size() + 1); name = "C" + (columns.size() + 1);
} }
Column column = new Column(); columns.add(new SimpleColumnInfo(name, sqlType, sqlTypeName, precision, scale));
column.name = name;
column.sqlType = sqlType;
column.precision = precision;
column.scale = scale;
column.sqlTypeName = sqlTypeName;
columns.add(column);
} }
/** /**
...@@ -1012,7 +1007,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -1012,7 +1007,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
if (o == null) { if (o == null) {
return null; return null;
} }
switch (columns.get(columnIndex - 1).sqlType) { switch (columns.get(columnIndex - 1).type) {
case Types.CLOB: case Types.CLOB:
Clob c = (Clob) o; Clob c = (Clob) o;
return c.getSubString(1, MathUtils.convertLongToInt(c.length())); return c.getSubString(1, MathUtils.convertLongToInt(c.length()));
...@@ -1868,7 +1863,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -1868,7 +1863,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
*/ */
@Override @Override
public int getColumnType(int columnIndex) throws SQLException { public int getColumnType(int columnIndex) throws SQLException {
return getColumn(columnIndex - 1).sqlType; return getColumn(columnIndex - 1).type;
} }
/** /**
...@@ -2045,7 +2040,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -2045,7 +2040,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
*/ */
@Override @Override
public String getColumnTypeName(int columnIndex) throws SQLException { public String getColumnTypeName(int columnIndex) throws SQLException {
return getColumn(columnIndex - 1).sqlTypeName; return getColumn(columnIndex - 1).typeName;
} }
/** /**
...@@ -2295,7 +2290,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -2295,7 +2290,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
return o; return o;
} }
private Column getColumn(int i) throws SQLException { private SimpleColumnInfo getColumn(int i) throws SQLException {
checkColumnIndex(i + 1); checkColumnIndex(i + 1);
return columns.get(i); return columns.get(i);
} }
...@@ -2355,37 +2350,6 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -2355,37 +2350,6 @@ 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, * A simple array implementation,
* backed by an object array * backed by an object array
......
...@@ -24,59 +24,9 @@ import org.h2.tools.SimpleResultSet; ...@@ -24,59 +24,9 @@ import org.h2.tools.SimpleResultSet;
* that have {@code NAME} column should also define it with the same type. * that have {@code NAME} column should also define it with the same type.
*/ */
public final class MergedResultSet { public final class MergedResultSet {
/** private final ArrayList<Map<SimpleColumnInfo, Object>> data = New.arrayList();
* Metadata of a column.
*/
private static final class ColumnInfo {
final String name;
final int type;
final int precision;
final int scale;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
ColumnInfo(String name, int type, int precision, int scale) {
this.name = name;
this.type = type;
this.precision = precision;
this.scale = scale;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
ColumnInfo other = (ColumnInfo) obj;
return name.equals(other.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
private final ArrayList<Map<ColumnInfo, Object>> data = New.arrayList();
private final ArrayList<ColumnInfo> columns = New.arrayList(); private final ArrayList<SimpleColumnInfo> columns = New.arrayList();
/** /**
* Appends a result set. * Appends a result set.
...@@ -92,10 +42,10 @@ public final class MergedResultSet { ...@@ -92,10 +42,10 @@ public final class MergedResultSet {
if (cols == 0) { if (cols == 0) {
return; return;
} }
ColumnInfo[] info = new ColumnInfo[cols]; SimpleColumnInfo[] info = new SimpleColumnInfo[cols];
for (int i = 1; i <= cols; i++) { for (int i = 1; i <= cols; i++) {
ColumnInfo ci = new ColumnInfo(meta.getColumnName(i), meta.getColumnType(i), meta.getPrecision(i), SimpleColumnInfo ci = new SimpleColumnInfo(meta.getColumnName(i), meta.getColumnType(i),
meta.getScale(i)); meta.getColumnTypeName(i), meta.getPrecision(i), meta.getScale(i));
info[i - 1] = ci; info[i - 1] = ci;
if (!columns.contains(ci)) { if (!columns.contains(ci)) {
columns.add(ci); columns.add(ci);
...@@ -105,9 +55,9 @@ public final class MergedResultSet { ...@@ -105,9 +55,9 @@ public final class MergedResultSet {
if (cols == 1) { if (cols == 1) {
data.add(Collections.singletonMap(info[0], rs.getObject(1))); data.add(Collections.singletonMap(info[0], rs.getObject(1)));
} else { } else {
HashMap<ColumnInfo, Object> map = new HashMap<>(); HashMap<SimpleColumnInfo, Object> map = new HashMap<>();
for (int i = 1; i <= cols; i++) { for (int i = 1; i <= cols; i++) {
ColumnInfo ci = info[i - 1]; SimpleColumnInfo ci = info[i - 1];
map.put(ci, rs.getObject(i)); map.put(ci, rs.getObject(i));
} }
data.add(map); data.add(map);
...@@ -122,12 +72,12 @@ public final class MergedResultSet { ...@@ -122,12 +72,12 @@ public final class MergedResultSet {
*/ */
public SimpleResultSet getResult() { public SimpleResultSet getResult() {
SimpleResultSet rs = new SimpleResultSet(); SimpleResultSet rs = new SimpleResultSet();
for (ColumnInfo ci : columns) { for (SimpleColumnInfo ci : columns) {
rs.addColumn(ci.name, ci.type, ci.precision, ci.scale); rs.addColumn(ci.name, ci.type, ci.typeName, ci.precision, ci.scale);
} }
for (Map<ColumnInfo, Object> map : data) { for (Map<SimpleColumnInfo, Object> map : data) {
Object[] row = new Object[columns.size()]; Object[] row = new Object[columns.size()];
for (Map.Entry<ColumnInfo, Object> entry : map.entrySet()) { for (Map.Entry<SimpleColumnInfo, Object> entry : map.entrySet()) {
row[columns.indexOf(entry.getKey())] = entry.getValue(); row[columns.indexOf(entry.getKey())] = entry.getValue();
} }
rs.addRow(row); rs.addRow(row);
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
/**
* Metadata of a column.
*
* <p>
* Notice: {@linkplain #equals(Object)} and {@linkplain #hashCode()} use only
* {@linkplain #name} field.
* </p>
*/
public final class SimpleColumnInfo {
/**
* Name of the column.
*/
public final String name;
/**
* Type of the column, see {@link java.sql.Types}.
*/
public final int type;
/**
* Type name of the column.
*/
public final String typeName;
/**
* Precision of the column
*/
public final int precision;
/**
* Scale of the column.
*/
public final int scale;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param typeName
* type name of the column
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
public SimpleColumnInfo(String name, int type, String typeName, int precision, int scale) {
this.name = name;
this.type = type;
this.typeName = typeName;
this.precision = precision;
this.scale = scale;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
SimpleColumnInfo other = (SimpleColumnInfo) obj;
return name.equals(other.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
...@@ -856,6 +856,11 @@ public class DataType { ...@@ -856,6 +856,11 @@ public class DataType {
*/ */
public static int convertSQLTypeToValueType(int sqlType, String sqlTypeName) { public static int convertSQLTypeToValueType(int sqlType, String sqlTypeName) {
switch (sqlType) { switch (sqlType) {
case Types.BINARY:
if (sqlTypeName.equalsIgnoreCase("UUID")) {
return Value.UUID;
}
break;
case Types.OTHER: case Types.OTHER:
case Types.JAVA_OBJECT: case Types.JAVA_OBJECT:
if (sqlTypeName.equalsIgnoreCase("geometry")) { if (sqlTypeName.equalsIgnoreCase("geometry")) {
......
...@@ -8,6 +8,7 @@ package org.h2.test.jdbc; ...@@ -8,6 +8,7 @@ package org.h2.test.jdbc;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.UUID; import java.util.UUID;
...@@ -127,6 +128,9 @@ public class TestGetGeneratedKeys extends TestBase { ...@@ -127,6 +128,9 @@ public class TestGetGeneratedKeys extends TestBase {
prep.addBatch(); prep.addBatch();
prep.executeBatch(); prep.executeBatch();
ResultSet rs = prep.getGeneratedKeys(); ResultSet rs = prep.getGeneratedKeys();
ResultSetMetaData meta = rs.getMetaData();
assertEquals("BIGINT", meta.getColumnTypeName(1));
assertEquals("UUID", meta.getColumnTypeName(2));
rs.next(); rs.next();
assertEquals(1L, rs.getLong(1)); assertEquals(1L, rs.getLong(1));
UUID u1 = (UUID) rs.getObject(2); UUID u1 = (UUID) rs.getObject(2);
......
...@@ -8,11 +8,14 @@ package org.h2.test.jdbc; ...@@ -8,11 +8,14 @@ package org.h2.test.jdbc;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DatabaseMetaData; import java.sql.DatabaseMetaData;
import java.sql.Driver; import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Types; import java.sql.Types;
import java.util.UUID;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
...@@ -135,6 +138,13 @@ public class TestMetaData extends TestBase { ...@@ -135,6 +138,13 @@ public class TestMetaData extends TestBase {
assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability()); assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability()); assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, rs.getHoldability());
stat.executeUpdate("drop table test"); stat.executeUpdate("drop table test");
PreparedStatement prep = conn.prepareStatement("SELECT X FROM TABLE (X UUID = ?)");
prep.setObject(1, UUID.randomUUID());
rs = prep.executeQuery();
rsMeta = rs.getMetaData();
assertEquals("UUID", rsMeta.getColumnTypeName(1));
conn.close(); conn.close();
} }
......
...@@ -770,5 +770,5 @@ openoffice organize libre systemtables gmane sea borders announced millennium al ...@@ -770,5 +770,5 @@ openoffice organize libre systemtables gmane sea borders announced millennium al
opti excessively opti excessively
iterators tech enums incompatibilities loses reimplement readme reorganize milli subdirectory iterators tech enums incompatibilities loses reimplement readme reorganize milli subdirectory linkplain inspections
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论