提交 5a481f85 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Align precision and display size of date-time columns with JDBC specification

上级 a64c34d1
......@@ -4433,7 +4433,6 @@ public class Parser {
if (t == Value.TIME || t == Value.TIMESTAMP || t == Value.TIMESTAMP_TZ) {
if (originalScale >= 0) {
scale = originalScale;
precision = dataType.defaultPrecision;
switch (t) {
case Value.TIME:
if (original.equals("TIME WITHOUT TIME ZONE")) {
......@@ -4441,7 +4440,7 @@ public class Parser {
} else {
original = original + '(' + originalScale + ')';
}
displaySize = ValueTime.getDisplaySize(originalScale);
precision = displaySize = ValueTime.getDisplaySize(originalScale);
break;
case Value.TIMESTAMP:
if (original.equals("TIMESTAMP WITHOUT TIME ZONE")) {
......@@ -4449,11 +4448,11 @@ public class Parser {
} else {
original = original + '(' + originalScale + ')';
}
displaySize = ValueTimestamp.getDisplaySize(originalScale);
precision = displaySize = ValueTimestamp.getDisplaySize(originalScale);
break;
case Value.TIMESTAMP_TZ:
original = "TIMESTAMP(" + originalScale + ") WITH TIME ZONE";
displaySize = ValueTimestampTimeZone.getDisplaySize(originalScale);
precision = displaySize = ValueTimestampTimeZone.getDisplaySize(originalScale);
break;
}
}
......
......@@ -2590,7 +2590,7 @@ public class Function extends Expression implements FunctionCall {
t = Value.DATE;
p = ValueDate.PRECISION;
s = 0;
d = ValueDate.DISPLAY_SIZE;
d = ValueDate.PRECISION;
}
break;
case ABS:
......
......@@ -295,10 +295,10 @@ public class TableLink extends Table {
precision = Math.max(ValueDate.PRECISION, precision);
break;
case Types.TIMESTAMP:
precision = Math.max(ValueTimestamp.PRECISION, precision);
precision = Math.max(ValueTimestamp.MAXIMUM_PRECISION, precision);
break;
case Types.TIME:
precision = Math.max(ValueTime.PRECISION, precision);
precision = Math.max(ValueTime.MAXIMUM_PRECISION, precision);
break;
}
return precision;
......
......@@ -1421,7 +1421,7 @@ public class DateTimeUtils {
* @return formatted string
*/
public static String timestampTimeZoneToString(long dateValue, long timeNanos, short timeZoneOffsetMins) {
StringBuilder buff = new StringBuilder(ValueTimestampTimeZone.DISPLAY_SIZE);
StringBuilder buff = new StringBuilder(ValueTimestampTimeZone.MAXIMUM_PRECISION);
appendDate(buff, dateValue);
buff.append(' ');
appendTime(buff, timeNanos, true);
......
......@@ -282,24 +282,22 @@ public class DataType {
24
);
add(Value.TIME, Types.TIME,
createDate(ValueTime.PRECISION, "TIME",
true, ValueTime.DEFAULT_SCALE, ValueTime.MAXIMUM_SCALE,
ValueTime.DISPLAY_SIZE),
createDate(ValueTime.MAXIMUM_PRECISION, ValueTime.DEFAULT_PRECISION,
"TIME", true, ValueTime.DEFAULT_SCALE, ValueTime.MAXIMUM_SCALE),
new String[]{"TIME", "TIME WITHOUT TIME ZONE"},
// 24 for ValueTime, 32 for java.sql.Time
56
);
add(Value.DATE, Types.DATE,
createDate(ValueDate.PRECISION, "DATE",
false, 0, 0, ValueDate.DISPLAY_SIZE),
createDate(ValueDate.PRECISION, ValueDate.PRECISION,
"DATE", false, 0, 0),
new String[]{"DATE"},
// 24 for ValueDate, 32 for java.sql.Data
56
);
add(Value.TIMESTAMP, Types.TIMESTAMP,
createDate(ValueTimestamp.PRECISION, "TIMESTAMP",
true, ValueTimestamp.DEFAULT_SCALE, ValueTimestamp.MAXIMUM_SCALE,
ValueTimestamp.DISPLAY_SIZE),
createDate(ValueTimestamp.MAXIMUM_PRECISION, ValueTimestamp.DEFAULT_PRECISION,
"TIMESTAMP", true, ValueTimestamp.DEFAULT_SCALE, ValueTimestamp.MAXIMUM_SCALE),
new String[]{"TIMESTAMP", "TIMESTAMP WITHOUT TIME ZONE",
"DATETIME", "DATETIME2", "SMALLDATETIME"},
// 24 for ValueTimestamp, 32 for java.sql.Timestamp
......@@ -310,9 +308,9 @@ public class DataType {
// compile (on Java 1.7). Can be replaced with
// Types.TIMESTAMP_WITH_TIMEZONE once Java 1.8 is required.
add(Value.TIMESTAMP_TZ, 2014,
createDate(ValueTimestampTimeZone.PRECISION, "TIMESTAMP_TZ",
true, ValueTimestampTimeZone.DEFAULT_SCALE, ValueTimestampTimeZone.MAXIMUM_SCALE,
ValueTimestampTimeZone.DISPLAY_SIZE),
createDate(ValueTimestampTimeZone.MAXIMUM_PRECISION, ValueTimestampTimeZone.DEFAULT_PRECISION,
"TIMESTAMP_TZ", true, ValueTimestampTimeZone.DEFAULT_SCALE,
ValueTimestampTimeZone.MAXIMUM_SCALE),
new String[]{"TIMESTAMP WITH TIME ZONE"},
// 26 for ValueTimestampUtc, 32 for java.sql.Timestamp
58
......@@ -466,17 +464,17 @@ public class DataType {
return dataType;
}
private static DataType createDate(int precision, String prefix, boolean supportsScale, int scale, int maxScale,
int displaySize) {
private static DataType createDate(int maxPrecision, int precision, String prefix, boolean supportsScale, int scale,
int maxScale) {
DataType dataType = new DataType();
dataType.prefix = prefix + " '";
dataType.suffix = "'";
dataType.maxPrecision = precision;
dataType.maxPrecision = maxPrecision;
dataType.supportsScale = supportsScale;
dataType.maxScale = maxScale;
dataType.defaultPrecision = precision;
dataType.defaultScale = scale;
dataType.defaultDisplaySize = displaySize;
dataType.defaultDisplaySize = precision;
return dataType;
}
......
......@@ -19,15 +19,10 @@ import org.h2.util.DateTimeUtils;
public class ValueDate extends Value {
/**
* The precision in digits.
*/
public static final int PRECISION = 8;
/**
* The display size of the textual representation of a date.
* The default precision and display size of the textual representation of a date.
* Example: 2000-01-02
*/
public static final int DISPLAY_SIZE = 10;
public static final int PRECISION = 10;
private final long dateValue;
......@@ -97,7 +92,7 @@ public class ValueDate extends Value {
@Override
public String getString() {
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
StringBuilder buff = new StringBuilder(PRECISION);
DateTimeUtils.appendDate(buff, dateValue);
return buff.toString();
}
......@@ -114,7 +109,7 @@ public class ValueDate extends Value {
@Override
public int getDisplaySize() {
return DISPLAY_SIZE;
return PRECISION;
}
@Override
......
......@@ -19,15 +19,16 @@ import org.h2.util.DateTimeUtils;
public class ValueTime extends Value {
/**
* The precision in digits.
* The default precision and display size of the textual representation of a time.
* Example: 10:00:00
*/
public static final int PRECISION = 9;
public static final int DEFAULT_PRECISION = 8;
/**
* The display size of the textual representation of a time.
* Example: 10:00:00
* The maximum precision and display size of the textual representation of a time.
* Example: 10:00:00.123456789
*/
static final int DISPLAY_SIZE = 8;
public static final int MAXIMUM_PRECISION = 18;
/**
* The default scale for time.
......@@ -134,7 +135,7 @@ public class ValueTime extends Value {
@Override
public String getString() {
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
StringBuilder buff = new StringBuilder(MAXIMUM_PRECISION);
DateTimeUtils.appendTime(buff, nanos, false);
return buff.toString();
}
......@@ -146,12 +147,18 @@ public class ValueTime extends Value {
@Override
public long getPrecision() {
return PRECISION;
return MAXIMUM_PRECISION;
}
@Override
public int getDisplaySize() {
return DISPLAY_SIZE;
return MAXIMUM_PRECISION;
}
@Override
public boolean checkPrecision(long precision) {
// TIME data type does not have precision parameter
return true;
}
@Override
......
......@@ -19,15 +19,16 @@ import org.h2.util.DateTimeUtils;
public class ValueTimestamp extends Value {
/**
* The precision in digits.
* The default precision and display size of the textual representation of a timestamp.
* Example: 2001-01-01 23:59:59.123456
*/
public static final int PRECISION = 23;
public static final int DEFAULT_PRECISION = 26;
/**
* The display size of the textual representation of a timestamp.
* Example: 2001-01-01 23:59:59.000
* The maximum precision and display size of the textual representation of a timestamp.
* Example: 2001-01-01 23:59:59.123456789
*/
static final int DISPLAY_SIZE = 23;
public static final int MAXIMUM_PRECISION = 29;
/**
* The default scale for timestamps.
......@@ -179,7 +180,7 @@ public class ValueTimestamp extends Value {
@Override
public String getString() {
StringBuilder buff = new StringBuilder(DISPLAY_SIZE);
StringBuilder buff = new StringBuilder(MAXIMUM_PRECISION);
DateTimeUtils.appendDate(buff, dateValue);
buff.append(' ');
DateTimeUtils.appendTime(buff, timeNanos, true);
......@@ -193,7 +194,7 @@ public class ValueTimestamp extends Value {
@Override
public long getPrecision() {
return PRECISION;
return MAXIMUM_PRECISION;
}
@Override
......@@ -203,7 +204,13 @@ public class ValueTimestamp extends Value {
@Override
public int getDisplaySize() {
return DISPLAY_SIZE;
return MAXIMUM_PRECISION;
}
@Override
public boolean checkPrecision(long precision) {
// TIMESTAMP data type does not have precision parameter
return true;
}
@Override
......
......@@ -22,15 +22,16 @@ import org.h2.util.DateTimeUtils;
public class ValueTimestampTimeZone extends Value {
/**
* The precision in digits.
* The default precision and display size of the textual representation of a timestamp.
* Example: 2001-01-01 23:59:59.123456+10:00
*/
public static final int PRECISION = 30;
public static final int DEFAULT_PRECISION = 32;
/**
* The display size of the textual representation of a timestamp. Example:
* 2001-01-01 23:59:59.000 +10:00
* The maximum precision and display size of the textual representation of a timestamp.
* Example: 2001-01-01 23:59:59.123456789+10:00
*/
public static final int DISPLAY_SIZE = 30;
public static final int MAXIMUM_PRECISION = 35;
/**
* The default scale for timestamps.
......@@ -182,7 +183,7 @@ public class ValueTimestampTimeZone extends Value {
@Override
public long getPrecision() {
return PRECISION;
return MAXIMUM_PRECISION;
}
@Override
......@@ -192,7 +193,13 @@ public class ValueTimestampTimeZone extends Value {
@Override
public int getDisplaySize() {
return DISPLAY_SIZE;
return MAXIMUM_PRECISION;
}
@Override
public boolean checkPrecision(long precision) {
// TIMESTAMP WITH TIME ZONE data type does not have precision parameter
return true;
}
@Override
......
......@@ -723,9 +723,9 @@ public class TestMetaData extends TestBase {
"" + DatabaseMetaData.columnNullable, "", null,
"" + numericType, "0", "12", "3", "YES" },
{ CATALOG, Constants.SCHEMA_MAIN, "TEST", "DATE_V",
"" + Types.TIMESTAMP, "TIMESTAMP", "23", "23", "6",
"" + Types.TIMESTAMP, "TIMESTAMP", "26", "26", "6",
"10", "" + DatabaseMetaData.columnNullable, "", null,
"" + Types.TIMESTAMP, "0", "23", "4", "YES" },
"" + Types.TIMESTAMP, "0", "26", "4", "YES" },
{ CATALOG, Constants.SCHEMA_MAIN, "TEST", "BLOB_V",
"" + Types.BLOB, "BLOB", "" + Integer.MAX_VALUE,
"" + Integer.MAX_VALUE, "0", "10",
......
......@@ -1280,11 +1280,11 @@ public class TestResultSet extends TestBase {
"TIMESTAMP '9999-12-31 23:59:59' VALUE FROM TEST ORDER BY ID");
assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" },
new int[] { Types.INTEGER, Types.TIMESTAMP },
new int[] { 10, 23 }, new int[] { 0, 9 });
new int[] { 10, 29 }, new int[] { 0, 9 });
rs = stat.executeQuery("SELECT * FROM TEST ORDER BY ID");
assertResultSetMeta(rs, 2, new String[] { "ID", "VALUE" },
new int[] { Types.INTEGER, Types.TIMESTAMP },
new int[] { 10, 23 }, new int[] { 0, 6 });
new int[] { 10, 26 }, new int[] { 0, 6 });
rs.next();
java.sql.Date date;
java.sql.Time time;
......@@ -1494,7 +1494,7 @@ public class TestResultSet extends TestBase {
new String[] { "ID", "D", "T", "TS" },
new int[] { Types.INTEGER, Types.DATE,
Types.TIME, Types.TIMESTAMP },
new int[] { 10, 8, 9, 23 }, new int[] { 0, 0, 0, 9 });
new int[] { 10, 10, 8, 29 }, new int[] { 0, 0, 0, 9 });
rs.next();
assertEquals(0, rs.getInt(1));
......
......@@ -163,8 +163,9 @@ public class TestDate extends TestBase {
assertEquals(Value.TIME, t1.getType());
long nanos = t1.getNanos();
assertEquals((int) ((nanos >>> 32) ^ nanos), t1.hashCode());
assertEquals(t1.getString().length(), t1.getDisplaySize());
assertEquals(ValueTime.PRECISION, t1.getPrecision());
// Literals return maximum precision
assertEquals(ValueTime.MAXIMUM_PRECISION, t1.getDisplaySize());
assertEquals(ValueTime.MAXIMUM_PRECISION, t1.getPrecision());
assertEquals("java.sql.Time", t1.getObject().getClass().getName());
ValueTime t1b = ValueTime.parse("11:11:11");
assertTrue(t1 == t1b);
......@@ -257,8 +258,9 @@ public class TestDate extends TestBase {
assertEquals((int) ((dateValue >>> 32) ^ dateValue ^
(nanos >>> 32) ^ nanos),
t1.hashCode());
assertEquals(t1.getString().length(), t1.getDisplaySize());
assertEquals(ValueTimestamp.PRECISION, t1.getPrecision());
// Literals return maximum precision
assertEquals(ValueTimestamp.MAXIMUM_PRECISION, t1.getDisplaySize());
assertEquals(ValueTimestamp.MAXIMUM_PRECISION, t1.getPrecision());
assertEquals(9, t1.getScale());
assertEquals("java.sql.Timestamp", t1.getObject().getClass().getName());
ValueTimestamp t1b = ValueTimestamp.parse("2001-01-01 01:01:01.111");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论