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

Merge pull request #898 from katzyn/datetime

Parse TIME WITHOUT TIME ZONE and fix TIMESTAMP as column name
...@@ -2298,7 +2298,7 @@ Each table has a pseudo-column named ""_ROWID_"" that contains the unique row id ...@@ -2298,7 +2298,7 @@ Each table has a pseudo-column named ""_ROWID_"" that contains the unique row id
" "
"Other Grammar","Time"," "Other Grammar","Time","
TIME 'hh:mm:ss[.nnnnnnnnn]' TIME [ WITHOUT TIME ZONE ] 'hh:mm:ss[.nnnnnnnnn]'
"," ","
A time literal. A value is between 0:00:00 and 23:59:59.999999999 A time literal. A value is between 0:00:00 and 23:59:59.999999999
and has nanosecond resolution. and has nanosecond resolution.
...@@ -2433,7 +2433,7 @@ REAL ...@@ -2433,7 +2433,7 @@ REAL
" "
"Data Types","TIME Type"," "Data Types","TIME Type","
TIME TIME [ WITHOUT TIME ZONE ]
"," ","
The time data type. The format is hh:mm:ss[.nnnnnnnnn]. The time data type. The format is hh:mm:ss[.nnnnnnnnn].
......
...@@ -3137,6 +3137,23 @@ public class Parser { ...@@ -3137,6 +3137,23 @@ public class Parser {
read("FOR"); read("FOR");
Sequence sequence = readSequence(); Sequence sequence = readSequence();
r = new SequenceValue(sequence); r = new SequenceValue(sequence);
} else if (equalsToken("TIME", name)) {
boolean without = readIf("WITHOUT");
if (without) {
read("TIME");
read("ZONE");
}
if (currentTokenType != VALUE
|| currentValue.getType() != Value.STRING) {
if (without) {
throw getSyntaxError();
}
r = new ExpressionColumn(database, null, null, name);
} else {
String time = currentValue.getString();
read();
r = ValueExpression.get(ValueTime.parse(time));
}
} else if (equalsToken("TIMESTAMP", name)) { } else if (equalsToken("TIMESTAMP", name)) {
if (readIf("WITH")) { if (readIf("WITH")) {
read("TIME"); read("TIME");
...@@ -3149,17 +3166,22 @@ public class Parser { ...@@ -3149,17 +3166,22 @@ public class Parser {
read(); read();
r = ValueExpression.get(ValueTimestampTimeZone.parse(timestamp)); r = ValueExpression.get(ValueTimestampTimeZone.parse(timestamp));
} else { } else {
if (readIf("WITHOUT")) { boolean without = readIf("WITHOUT");
if (without) {
read("TIME"); read("TIME");
read("ZONE"); read("ZONE");
} }
if (currentTokenType != VALUE if (currentTokenType != VALUE
|| currentValue.getType() != Value.STRING) { || currentValue.getType() != Value.STRING) {
throw getSyntaxError(); if (without) {
throw getSyntaxError();
}
r = new ExpressionColumn(database, null, null, name);
} else {
String timestamp = currentValue.getString();
read();
r = ValueExpression.get(ValueTimestamp.parse(timestamp, database.getMode()));
} }
String timestamp = currentValue.getString();
read();
r = ValueExpression.get(ValueTimestamp.parse(timestamp, database.getMode()));
} }
} else if (currentTokenType == VALUE && } else if (currentTokenType == VALUE &&
currentValue.getType() == Value.STRING) { currentValue.getType() == Value.STRING) {
...@@ -3168,8 +3190,7 @@ public class Parser { ...@@ -3168,8 +3190,7 @@ public class Parser {
String date = currentValue.getString(); String date = currentValue.getString();
read(); read();
r = ValueExpression.get(ValueDate.parse(date)); r = ValueExpression.get(ValueDate.parse(date));
} else if (equalsToken("TIME", name) || } else if (equalsToken("T", name)) {
equalsToken("T", name)) {
String time = currentValue.getString(); String time = currentValue.getString();
read(); read();
r = ValueExpression.get(ValueTime.parse(time)); r = ValueExpression.get(ValueTime.parse(time));
...@@ -4340,6 +4361,12 @@ public class Parser { ...@@ -4340,6 +4361,12 @@ public class Parser {
if (readIf("VARYING")) { if (readIf("VARYING")) {
original += " VARYING"; original += " VARYING";
} }
} else if (readIf("TIME")) {
if (readIf("WITHOUT")) {
read("TIME");
read("ZONE");
original += " WITHOUT TIME ZONE";
}
} else if (readIf("TIMESTAMP")) { } else if (readIf("TIMESTAMP")) {
if (readIf("WITH")) { if (readIf("WITH")) {
read("TIME"); read("TIME");
......
...@@ -66,9 +66,9 @@ public class DataType { ...@@ -66,9 +66,9 @@ public class DataType {
* The list of types. An ArrayList so that Tomcat doesn't set it to null * The list of types. An ArrayList so that Tomcat doesn't set it to null
* when clearing references. * when clearing references.
*/ */
private static final ArrayList<DataType> TYPES = New.arrayList(); private static final ArrayList<DataType> TYPES = new ArrayList<>(96);
private static final HashMap<String, DataType> TYPES_BY_NAME = new HashMap<>(); private static final HashMap<String, DataType> TYPES_BY_NAME = new HashMap<>(96);
private static final HashMap<Integer, DataType> TYPES_BY_VALUE_TYPE = new HashMap<>(); private static final HashMap<Integer, DataType> TYPES_BY_VALUE_TYPE = new HashMap<>(48);
/** /**
* The value type of this data type. * The value type of this data type.
...@@ -289,7 +289,7 @@ public class DataType { ...@@ -289,7 +289,7 @@ public class DataType {
); );
add(Value.TIME, Types.TIME, "Time", add(Value.TIME, Types.TIME, "Time",
createDate(ValueTime.PRECISION, "TIME", 0, ValueTime.DISPLAY_SIZE), createDate(ValueTime.PRECISION, "TIME", 0, ValueTime.DISPLAY_SIZE),
new String[]{"TIME"}, new String[]{"TIME", "TIME WITHOUT TIME ZONE"},
// 24 for ValueTime, 32 for java.sql.Time // 24 for ValueTime, 32 for java.sql.Time
56 56
); );
......
...@@ -2,3 +2,42 @@ ...@@ -2,3 +2,42 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html). -- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
CREATE TABLE TEST(T1 TIME, T2 TIME WITHOUT TIME ZONE);
> ok
INSERT INTO TEST(T1, T2) VALUES (TIME '10:00:00', TIME WITHOUT TIME ZONE '10:00:00');
> update count: 1
SELECT T1, T2, T1 = T2 FROM TEST;
> T1 T2 T1 = T2
> -------- -------- -------
> 10:00:00 10:00:00 TRUE
> rows: 1
SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TEST' ORDER BY ORDINAL_POSITION;
> COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_TYPE
> ----------- --------- --------- ----------------------
> T1 92 TIME TIME
> T2 92 TIME TIME WITHOUT TIME ZONE
> rows (ordered): 2
DROP TABLE TEST;
> ok
-- Check that TIME is allowed as a column name
CREATE TABLE TEST(TIME TIME);
> ok
INSERT INTO TEST VALUES (TIME '08:00:00');
> update count: 1
SELECT TIME FROM TEST;
> TIME
> --------
> 08:00:00
> rows: 1
DROP TABLE TEST;
> ok
...@@ -25,3 +25,19 @@ SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.CO ...@@ -25,3 +25,19 @@ SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.CO
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
-- Check that TIMESTAMP is allowed as a column name
CREATE TABLE TEST(TIMESTAMP TIMESTAMP);
> ok
INSERT INTO TEST VALUES (TIMESTAMP '1999-12-31 08:00:00');
> update count: 1
SELECT TIMESTAMP FROM TEST;
> TIMESTAMP
> ---------------------
> 1999-12-31 08:00:00.0
> rows: 1
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论