Unverified 提交 a9728a14 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #770 from katzyn/JDBC

Fix issue #754: Make NUMERIC type read as NUMERIC
......@@ -355,6 +355,15 @@ public class SysProperties {
public static final boolean OLD_RESULT_SET_GET_OBJECT =
Utils.getProperty("h2.oldResultSetGetObject", true);
/**
* System property {@code h2.bigDecimalIsDecimal}, {@code true} by default. If
* {@code true} map {@code BigDecimal} to {@code DECIMAL} type, if {@code false}
* map it to {@code NUMERIC} as specified in JDBC specification (see Mapping
* from Java Object Types to JDBC Types).
*/
public static final boolean BIG_DECIMAL_IS_DECIMAL =
Utils.getProperty("h2.bigDecimalIsDecimal", true);
/**
* System property <code>h2.pgClientEncoding</code> (default: UTF-8).<br />
* Default client encoding for PG server. It is used if the client does not
......
......@@ -261,23 +261,13 @@ public class DataType {
new String[]{"IDENTITY", "BIGSERIAL"},
24
);
add(Value.DECIMAL, Types.DECIMAL, "BigDecimal",
createDecimal(Integer.MAX_VALUE,
ValueDecimal.DEFAULT_PRECISION,
ValueDecimal.DEFAULT_SCALE,
ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false),
new String[]{"DECIMAL", "DEC"},
// 40 for ValueDecimal,
64
);
add(Value.DECIMAL, Types.NUMERIC, "BigDecimal",
createDecimal(Integer.MAX_VALUE,
ValueDecimal.DEFAULT_PRECISION,
ValueDecimal.DEFAULT_SCALE,
ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false),
new String[]{"NUMERIC", "NUMBER"},
64
);
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
addDecimal();
addNumeric();
} else {
addNumeric();
addDecimal();
}
add(Value.FLOAT, Types.REAL, "Float",
createDecimal(ValueFloat.PRECISION, ValueFloat.PRECISION,
0, ValueFloat.DISPLAY_SIZE, false, false),
......@@ -398,6 +388,29 @@ public class DataType {
}
}
static void addDecimal() {
add(Value.DECIMAL, Types.DECIMAL, "BigDecimal",
createDecimal(Integer.MAX_VALUE,
ValueDecimal.DEFAULT_PRECISION,
ValueDecimal.DEFAULT_SCALE,
ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false),
new String[]{"DECIMAL", "DEC"},
// 40 for ValueDecimal,
64
);
}
static void addNumeric() {
add(Value.DECIMAL, Types.NUMERIC, "BigDecimal",
createDecimal(Integer.MAX_VALUE,
ValueDecimal.DEFAULT_PRECISION,
ValueDecimal.DEFAULT_SCALE,
ValueDecimal.DEFAULT_DISPLAY_SIZE, true, false),
new String[]{"NUMERIC", "NUMBER"},
64
);
}
private static void add(int type, int sqlType, String jdbc,
DataType dataType, String[] names, int memory) {
for (int i = 0; i < names.length; i++) {
......
......@@ -15,6 +15,7 @@ import java.sql.Statement;
import java.sql.Types;
import org.h2.api.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.SysProperties;
import org.h2.test.TestBase;
import org.h2.value.DataType;
......@@ -177,6 +178,12 @@ public class TestMetaData extends TestBase {
}
private void testColumnPrecision() throws SQLException {
int numericType;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
numericType = Types.DECIMAL;
} else {
numericType = Types.NUMERIC;
}
Connection conn = getConnection("metaData");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE ONE(X NUMBER(12,2), Y FLOAT)");
......@@ -187,13 +194,13 @@ public class TestMetaData extends TestBase {
rsMeta = rs.getMetaData();
assertEquals(12, rsMeta.getPrecision(1));
assertEquals(17, rsMeta.getPrecision(2));
assertEquals(Types.DECIMAL, rsMeta.getColumnType(1));
assertEquals(numericType, rsMeta.getColumnType(1));
assertEquals(Types.DOUBLE, rsMeta.getColumnType(2));
rs = stat.executeQuery("SELECT * FROM TWO");
rsMeta = rs.getMetaData();
assertEquals(12, rsMeta.getPrecision(1));
assertEquals(17, rsMeta.getPrecision(2));
assertEquals(Types.DECIMAL, rsMeta.getColumnType(1));
assertEquals(numericType, rsMeta.getColumnType(1));
assertEquals(Types.DOUBLE, rsMeta.getColumnType(2));
stat.execute("DROP TABLE ONE, TWO");
conn.close();
......@@ -597,6 +604,15 @@ public class TestMetaData extends TestBase {
}
private void testMore() throws SQLException {
int numericType;
String numericName;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
numericType = Types.DECIMAL;
numericName = "DECIMAL";
} else {
numericType = Types.NUMERIC;
numericName = "NUMERIC";
}
Connection conn = getConnection("metaData");
DatabaseMetaData meta = conn.getMetaData();
Statement stat = conn.createStatement();
......@@ -703,9 +719,9 @@ public class TestMetaData extends TestBase {
"" + DatabaseMetaData.columnNullable, "", null,
"" + Types.VARCHAR, "0", "120", "2", "YES" },
{ CATALOG, Constants.SCHEMA_MAIN, "TEST", "DEC_V",
"" + Types.DECIMAL, "DECIMAL", "12", "12", "3", "10",
"" + numericType, numericName, "12", "12", "3", "10",
"" + DatabaseMetaData.columnNullable, "", null,
"" + Types.DECIMAL, "0", "12", "3", "YES" },
"" + numericType, "0", "12", "3", "YES" },
{ CATALOG, Constants.SCHEMA_MAIN, "TEST", "DATE_V",
"" + Types.TIMESTAMP, "TIMESTAMP", "23", "23", "10",
"10", "" + DatabaseMetaData.columnNullable, "", null,
......
......@@ -769,6 +769,15 @@ public class TestPreparedStatement extends TestBase {
}
private void testParameterMetaData(Connection conn) throws SQLException {
int numericType;
String numericName;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
numericType = Types.DECIMAL;
numericName = "DECIMAL";
} else {
numericType = Types.NUMERIC;
numericName = "NUMERIC";
}
PreparedStatement prep = conn.prepareStatement("SELECT ?, ?, ? FROM DUAL");
ParameterMetaData pm = prep.getParameterMetaData();
assertEquals("java.lang.String", pm.getParameterClassName(1));
......@@ -794,15 +803,15 @@ public class TestPreparedStatement extends TestBase {
"INSERT INTO TEST3 VALUES(?, ?, ?)");
checkParameter(prep1, 1, "java.lang.Integer", 4, "INTEGER", 10, 0);
checkParameter(prep1, 2, "java.lang.String", 12, "VARCHAR", 255, 0);
checkParameter(prep1, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2);
checkParameter(prep1, 3, "java.math.BigDecimal", numericType, numericName, 10, 2);
checkParameter(prep2, 1, "java.lang.Integer", 4, "INTEGER", 10, 0);
checkParameter(prep2, 2, "java.lang.String", 12, "VARCHAR", 255, 0);
checkParameter(prep2, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2);
checkParameter(prep2, 3, "java.math.BigDecimal", numericType, numericName, 10, 2);
PreparedStatement prep3 = conn.prepareStatement(
"SELECT * FROM TEST3 WHERE ID=? AND NAME LIKE ? AND ?>DATA");
checkParameter(prep3, 1, "java.lang.Integer", 4, "INTEGER", 10, 0);
checkParameter(prep3, 2, "java.lang.String", 12, "VARCHAR", 0, 0);
checkParameter(prep3, 3, "java.math.BigDecimal", 3, "DECIMAL", 10, 2);
checkParameter(prep3, 3, "java.math.BigDecimal", numericType, numericName, 10, 2);
stat.execute("DROP TABLE TEST3");
}
......
......@@ -1091,6 +1091,12 @@ public class TestResultSet extends TestBase {
}
private void testDecimal() throws SQLException {
int numericType;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
numericType = Types.DECIMAL;
} else {
numericType = Types.NUMERIC;
}
trace("Test DECIMAL");
ResultSet rs;
Object o;
......@@ -1105,7 +1111,7 @@ public class TestResultSet extends TestBase {
stat.execute("INSERT INTO TEST VALUES(8,NULL)");
rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID");
assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" },
new int[] { Types.INTEGER, Types.DECIMAL }, new int[] {
new int[] { Types.INTEGER, numericType }, new int[] {
10, 10 }, new int[] { 0, 2 });
BigDecimal bd;
......
......@@ -19,6 +19,8 @@ import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
import org.h2.engine.SysProperties;
import org.h2.test.TestAll;
import org.h2.test.TestBase;
import org.h2.util.New;
......@@ -83,8 +85,14 @@ public class TestScript extends TestBase {
testScript("query-optimisations.sql");
testScript("commands-dml-script.sql");
testScript("commands-dml-create-view.sql");
String decimal2;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
decimal2 = "decimal_decimal";
} else {
decimal2 = "decimal_numeric";
}
for (String s : new String[] { "array", "bigint", "binary", "blob",
"boolean", "char", "clob", "date", "decimal", "double", "enum",
"boolean", "char", "clob", "date", "decimal", decimal2, "double", "enum",
"geometry", "identity", "int", "other", "real", "smallint",
"time", "timestamp-with-timezone", "timestamp", "tinyint",
"uuid", "varchar", "varchar-ignorecase" }) {
......
-- 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
--
-- h2.bigDecimalIsDecimal=true
--
create memory table orders ( orderid varchar(10), name varchar(20), customer_id varchar(10), completed numeric(1) not null, verified numeric(1) );
> ok
select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- -------------------
> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50 null null NUMERIC(1) NOT NULL
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20)
> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50 null null NUMERIC(1)
> rows: 5
drop table orders;
> ok
CREATE TABLE TEST(ID INT, X1 BIT, XT TINYINT, X_SM SMALLINT, XB BIGINT, XD DECIMAL(10,2), XD2 DOUBLE PRECISION, XR REAL);
> ok
INSERT INTO TEST VALUES(?, ?, ?, ?, ?, ?, ?, ?);
{
0,FALSE,0,0,0,0.0,0.0,0.0
1,TRUE,1,1,1,1.0,1.0,1.0
4,TRUE,4,4,4,4.0,4.0,4.0
-1,FALSE,-1,-1,-1,-1.0,-1.0,-1.0
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
> update count: 5
SELECT ID, CAST(XT AS NUMBER(10,1)),
CAST(X_SM AS NUMBER(10,1)), CAST(XB AS NUMBER(10,1)), CAST(XD AS NUMBER(10,1)),
CAST(XD2 AS NUMBER(10,1)), CAST(XR AS NUMBER(10,1)) FROM TEST;
> ID CAST(XT AS DECIMAL(10, 1)) CAST(X_SM AS DECIMAL(10, 1)) CAST(XB AS DECIMAL(10, 1)) CAST(XD AS DECIMAL(10, 1)) CAST(XD2 AS DECIMAL(10, 1)) CAST(XR AS DECIMAL(10, 1))
> ---- -------------------------- ---------------------------- -------------------------- -------------------------- --------------------------- --------------------------
> -1 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0
> 0 0.0 0.0 0.0 0.0 0.0 0.0
> 1 1.0 1.0 1.0 1.0 1.0 1.0
> 4 4.0 4.0 4.0 4.0 4.0 4.0
> null null null null null null null
> rows: 5
-- 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
--
-- h2.bigDecimalIsDecimal=false
--
create memory table orders ( orderid varchar(10), name varchar(20), customer_id varchar(10), completed numeric(1) not null, verified numeric(1) );
> ok
select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- -------------------
> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 2 1 1 1 10 0 Unicode OFF NUMERIC 0 FALSE 50 null null NUMERIC(1) NOT NULL
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20)
> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 2 1 1 1 10 0 Unicode OFF NUMERIC 1 FALSE 50 null null NUMERIC(1)
> rows: 5
drop table orders;
> ok
CREATE TABLE TEST(ID INT, X1 BIT, XT TINYINT, X_SM SMALLINT, XB BIGINT, XD DECIMAL(10,2), XD2 DOUBLE PRECISION, XR REAL);
> ok
INSERT INTO TEST VALUES(?, ?, ?, ?, ?, ?, ?, ?);
{
0,FALSE,0,0,0,0.0,0.0,0.0
1,TRUE,1,1,1,1.0,1.0,1.0
4,TRUE,4,4,4,4.0,4.0,4.0
-1,FALSE,-1,-1,-1,-1.0,-1.0,-1.0
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
> update count: 5
SELECT ID, CAST(XT AS NUMBER(10,1)),
CAST(X_SM AS NUMBER(10,1)), CAST(XB AS NUMBER(10,1)), CAST(XD AS NUMBER(10,1)),
CAST(XD2 AS NUMBER(10,1)), CAST(XR AS NUMBER(10,1)) FROM TEST;
> ID CAST(XT AS NUMERIC(10, 1)) CAST(X_SM AS NUMERIC(10, 1)) CAST(XB AS NUMERIC(10, 1)) CAST(XD AS NUMERIC(10, 1)) CAST(XD2 AS NUMERIC(10, 1)) CAST(XR AS NUMERIC(10, 1))
> ---- -------------------------- ---------------------------- -------------------------- -------------------------- --------------------------- --------------------------
> -1 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0
> 0 0.0 0.0 0.0 0.0 0.0 0.0
> 1 1.0 1.0 1.0 1.0 1.0 1.0
> 4 4.0 4.0 4.0 4.0 4.0 4.0
> null null null null null null null
> rows: 5
......@@ -2672,22 +2672,6 @@ select * from Foo where A like 'abc%' escape '\' AND B=1;
drop table Foo;
> ok
create memory table orders ( orderid varchar(10), name varchar(20), customer_id varchar(10), completed numeric(1) not null, verified numeric(1) );
> ok
select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- -------------------
> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50 null null NUMERIC(1) NOT NULL
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20)
> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10)
> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50 null null NUMERIC(1)
> rows: 5
drop table orders;
> ok
create table test(id int, d timestamp);
> ok
......@@ -7954,18 +7938,6 @@ SELECT ID, 10*X1, 10*XT, 10*X_SM, 10*XB, 10*XD, 10*XD2, 10*XR FROM TEST;
> null null null null null null null null
> rows: 5
SELECT ID, CAST(XT AS NUMBER(10,1)),
CAST(X_SM AS NUMBER(10,1)), CAST(XB AS NUMBER(10,1)), CAST(XD AS NUMBER(10,1)),
CAST(XD2 AS NUMBER(10,1)), CAST(XR AS NUMBER(10,1)) FROM TEST;
> ID CAST(XT AS DECIMAL(10, 1)) CAST(X_SM AS DECIMAL(10, 1)) CAST(XB AS DECIMAL(10, 1)) CAST(XD AS DECIMAL(10, 1)) CAST(XD2 AS DECIMAL(10, 1)) CAST(XR AS DECIMAL(10, 1))
> ---- -------------------------- ---------------------------- -------------------------- -------------------------- --------------------------- --------------------------
> -1 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0
> 0 0.0 0.0 0.0 0.0 0.0 0.0
> 1 1.0 1.0 1.0 1.0 1.0 1.0
> 4 4.0 4.0 4.0 4.0 4.0 4.0
> null null null null null null null
> rows: 5
SELECT ID, SIGN(XT), SIGN(X_SM), SIGN(XB), SIGN(XD), SIGN(XD2), SIGN(XR) FROM TEST;
> ID SIGN(XT) SIGN(X_SM) SIGN(XB) SIGN(XD) SIGN(XD2) SIGN(XR)
> ---- -------- ---------- -------- -------- --------- --------
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论