Unverified 提交 7dc0d946 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1362 from katzyn/mode

Add limited support for MONEY and SMALLMONEY in compatibility modes
......@@ -1096,6 +1096,8 @@ or the SQL statement <code>SET MODE MSSQLServer</code>.
</li><li>Concatenating <code>NULL</code> with another value
results in the other value.
</li><li>Text can be concatenated using '+'.
</li><li>MONEY data type is treated like NUMERIC(19, 4) data type. SMALLMONEY data type is treated like NUMERIC(10, 4)
data type.
</li></ul>
<h3>MySQL Compatibility Mode</h3>
......@@ -1141,7 +1143,7 @@ or the SQL statement <code>SET MODE Oracle</code>.
results in the other value.
</li><li>Empty strings are treated like <code>NULL</code> values.
</li><li>REGEXP_REPLACE() uses \ for back-references.
</li><li>DATE data type is treated like TIMESTAMP data type.
</li><li>DATE data type is treated like TIMESTAMP(0) data type.
</li></ul>
<h3>PostgreSQL Compatibility Mode</h3>
......@@ -1159,6 +1161,7 @@ or the SQL statement <code>SET MODE PostgreSQL</code>.
</li><li>LOG(x) is base 10 in this mode.
</li><li>REGEXP_REPLACE() uses \ for back-references.
</li><li>Fixed-width strings are padded with spaces.
</li><li>MONEY data type is treated like NUMERIC(19, 2) data type.
</li></ul>
<h3>Ignite Compatibility Mode</h3>
......
......@@ -5,6 +5,7 @@
*/
package org.h2.engine;
import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
......@@ -258,6 +259,16 @@ public class Mode {
// MS SQL Server does not support client info properties. See
// https://msdn.microsoft.com/en-Us/library/dd571296%28v=sql.110%29.aspx
mode.supportedClientInfoPropertiesRegEx = null;
DataType dt = DataType.createDecimal(19, 19, 4, 21, false, false);
dt.type = Value.DECIMAL;
dt.sqlType = Types.NUMERIC;
dt.name = "MONEY";
mode.typeByNameMap.put("MONEY", dt);
dt = DataType.createDecimal(10, 10, 4, 12, false, false);
dt.type = Value.DECIMAL;
dt.sqlType = Types.NUMERIC;
dt.name = "SMALLMONEY";
mode.typeByNameMap.put("SMALLMONEY", dt);
add(mode);
mode = new Mode(ModeEnum.MySQL);
......@@ -289,7 +300,11 @@ public class Mode {
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile(".*\\..*");
mode.prohibitEmptyInPredicate = true;
mode.typeByNameMap.put("DATE", DataType.getDataType(Value.TIMESTAMP));
dt = DataType.createDate(/* 2001-01-01 23:59:59 */ 19, 19, "DATE", false, 0, 0);
dt.type = Value.TIMESTAMP;
dt.sqlType = Types.TIMESTAMP;
dt.name = "DATE";
mode.typeByNameMap.put("DATE", dt);
add(mode);
mode = new Mode(ModeEnum.PostgreSQL);
......@@ -313,6 +328,11 @@ public class Mode {
disallowedTypes.add("TINYINT");
disallowedTypes.add("BLOB");
mode.disallowedTypes = disallowedTypes;
dt = DataType.createDecimal(19, 19, 2, 21, false, false);
dt.type = Value.DECIMAL;
dt.sqlType = Types.NUMERIC;
dt.name = "MONEY";
mode.typeByNameMap.put("MONEY", dt);
add(mode);
mode = new Mode(ModeEnum.Ignite);
......
......@@ -448,7 +448,18 @@ public class DataType {
}
}
private static DataType createDecimal(int maxPrecision,
/**
* Create a numeric data type.
*
* @param maxPrecision maximum supported precision
* @param defaultPrecision default precision
* @param defaultScale default scale
* @param defaultDisplaySize default display size
* @param needsPrecisionAndScale where precision and scale are supported
* @param autoInc whether the data type is an auto-increment type
* @return data type
*/
public static DataType createDecimal(int maxPrecision,
int defaultPrecision, int defaultScale, int defaultDisplaySize,
boolean needsPrecisionAndScale, boolean autoInc) {
DataType dataType = new DataType();
......@@ -466,7 +477,18 @@ public class DataType {
return dataType;
}
private static DataType createDate(int maxPrecision, int precision, String prefix,
/**
* Create a date-time data type.
*
* @param maxPrecision maximum supported precision
* @param precision default precision
* @param prefix the prefix for SQL literal representation
* @param supportsScale whether the scale parameter is supported
* @param scale default scale
* @param maxScale highest possible scale
* @return data type
*/
public static DataType createDate(int maxPrecision, int precision, String prefix,
boolean supportsScale, int scale, int maxScale) {
DataType dataType = new DataType();
dataType.prefix = prefix + " '";
......
......@@ -5,6 +5,7 @@
*/
package org.h2.test.db;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
......@@ -276,6 +277,21 @@ public class TestCompatibility extends TestDb {
/* Expected! */
}
}
/* Test MONEY data type */
stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(M MONEY)");
stat.execute("INSERT INTO TEST(M) VALUES (-92233720368547758.08)");
stat.execute("INSERT INTO TEST(M) VALUES (0.11111)");
stat.execute("INSERT INTO TEST(M) VALUES (92233720368547758.07)");
ResultSet rs = stat.executeQuery("SELECT M FROM TEST ORDER BY M");
assertTrue(rs.next());
assertEquals(new BigDecimal("-92233720368547758.08"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("0.11"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("92233720368547758.07"), rs.getBigDecimal(1));
assertFalse(rs.next());
}
private void testMySQL() throws SQLException {
......@@ -496,6 +512,36 @@ public class TestCompatibility extends TestDb {
// UNIQUEIDENTIFIER is MSSQL's equivalent of UUID
stat.execute("create table test3 (id UNIQUEIDENTIFIER)");
/* Test MONEY data type */
stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(M MONEY)");
stat.execute("INSERT INTO TEST(M) VALUES (-922337203685477.5808)");
stat.execute("INSERT INTO TEST(M) VALUES (0.11111)");
stat.execute("INSERT INTO TEST(M) VALUES (922337203685477.5807)");
rs = stat.executeQuery("SELECT M FROM TEST ORDER BY M");
assertTrue(rs.next());
assertEquals(new BigDecimal("-922337203685477.5808"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("0.1111"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("922337203685477.5807"), rs.getBigDecimal(1));
assertFalse(rs.next());
/* Test SMALLMONEY data type */
stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(M SMALLMONEY)");
stat.execute("INSERT INTO TEST(M) VALUES (-214748.3648)");
stat.execute("INSERT INTO TEST(M) VALUES (0.11111)");
stat.execute("INSERT INTO TEST(M) VALUES (214748.3647)");
rs = stat.executeQuery("SELECT M FROM TEST ORDER BY M");
assertTrue(rs.next());
assertEquals(new BigDecimal("-214748.3648"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("0.1111"), rs.getBigDecimal(1));
assertTrue(rs.next());
assertEquals(new BigDecimal("214748.3647"), rs.getBigDecimal(1));
assertFalse(rs.next());
}
private void testDB2() throws SQLException {
......
......@@ -263,12 +263,12 @@ public class TestCompatibilityOracle extends TestDb {
Timestamp t4 = Timestamp.valueOf("2018-01-10 22:10:01");
stat.execute("CREATE TABLE TEST (ID INT PRIMARY KEY, D DATE)");
stat.executeUpdate("INSERT INTO TEST VALUES(1, TIMESTAMP '2011-02-03 12:11:10')");
stat.executeUpdate("INSERT INTO TEST VALUES(2, CAST ('1999-10-15 13:14:15' AS DATE))");
stat.executeUpdate("INSERT INTO TEST VALUES(3, '2030-11-22 11:22:33')");
stat.executeUpdate("INSERT INTO TEST VALUES(1, TIMESTAMP '2011-02-03 12:11:10.1')");
stat.executeUpdate("INSERT INTO TEST VALUES(2, CAST ('1999-10-15 13:14:15.1' AS DATE))");
stat.executeUpdate("INSERT INTO TEST VALUES(3, '2030-11-22 11:22:33.1')");
PreparedStatement ps = conn.prepareStatement("INSERT INTO TEST VALUES (?, ?)");
ps.setInt(1, 4);
ps.setTimestamp(2, t4);
ps.setTimestamp(2, Timestamp.valueOf("2018-01-10 22:10:01.1"));
ps.executeUpdate();
ResultSet rs = stat.executeQuery("SELECT D FROM TEST ORDER BY ID");
rs.next();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论