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

Parse more date-time literals for compatibility with other databases

上级 c6f12e1c
...@@ -336,6 +336,7 @@ public class DateTimeUtils { ...@@ -336,6 +336,7 @@ public class DateTimeUtils {
/** /**
* Parse a date string. The format is: [+|-]year-month-day * Parse a date string. The format is: [+|-]year-month-day
* or [+|-]yyyyMMdd.
* *
* @param s the string to parse * @param s the string to parse
* @param start the parse index start * @param start the parse index start
...@@ -349,14 +350,27 @@ public class DateTimeUtils { ...@@ -349,14 +350,27 @@ public class DateTimeUtils {
start++; start++;
} }
// start at position 1 to support "-year" // start at position 1 to support "-year"
int s1 = s.indexOf('-', start + 1); int yEnd = s.indexOf('-', start + 1);
int s2 = s.indexOf('-', s1 + 1); int mStart, mEnd, dStart;
if (s1 <= 0 || s2 <= s1) { if (yEnd > 0) {
// Standard [+|-]year-month-day format
mStart = yEnd + 1;
mEnd = s.indexOf('-', mStart);
if (mEnd <= mStart) {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
} }
int year = Integer.parseInt(s.substring(start, s1)); dStart = mEnd + 1;
int month = Integer.parseInt(s.substring(s1 + 1, s2)); } else {
int day = Integer.parseInt(s.substring(s2 + 1, end)); // Additional [+|-]yyyyMMdd format for compatibility
mEnd = dStart = end - 2;
yEnd = mStart = mEnd - 2;
if (yEnd <= start) {
throw new IllegalArgumentException(s);
}
}
int year = Integer.parseInt(s.substring(start, yEnd));
int month = Integer.parseInt(s.substring(mStart, mEnd));
int day = Integer.parseInt(s.substring(dStart, end));
if (!isValidDate(year, month, day)) { if (!isValidDate(year, month, day)) {
throw new IllegalArgumentException(year + "-" + month + "-" + day); throw new IllegalArgumentException(year + "-" + month + "-" + day);
} }
...@@ -364,8 +378,8 @@ public class DateTimeUtils { ...@@ -364,8 +378,8 @@ public class DateTimeUtils {
} }
/** /**
* Parse a time string. The format is: hour:minute:second[.nanos] or * Parse a time string. The format is: hour:minute[:second[.nanos]],
* alternatively hour.minute.second[.nanos]. * hhmm[ss[.nanos]], or hour.minute.second[.nanos].
* *
* @param s the string to parse * @param s the string to parse
* @param start the parse index start * @param start the parse index start
...@@ -375,30 +389,70 @@ public class DateTimeUtils { ...@@ -375,30 +389,70 @@ public class DateTimeUtils {
*/ */
public static long parseTimeNanos(String s, int start, int end) { public static long parseTimeNanos(String s, int start, int end) {
int hour, minute, second, nanos; int hour, minute, second, nanos;
int s1 = s.indexOf(':', start); int hEnd = s.indexOf(':', start);
int s2 = s.indexOf(':', s1 + 1); int mStart, mEnd, sStart, sEnd;
int s3 = s.indexOf('.', s2 + 1); if (hEnd > 0) {
if (s1 <= 0 || s2 <= s1) { mStart = hEnd + 1;
// if first try fails try to use IBM DB2 time format mEnd = s.indexOf(':', mStart);
// [-]hour.minute.second[.nanos] if (mEnd >= mStart) {
s1 = s.indexOf('.', start); // Standard hour:minute:second[.nanos] format
s2 = s.indexOf('.', s1 + 1); sStart = mEnd + 1;
s3 = s.indexOf('.', s2 + 1); sEnd = s.indexOf('.', sStart);
if (s1 <= 0 || s2 <= s1) { } else {
// Additional hour:minute format for compatibility
mEnd = end;
sStart = sEnd = -1;
}
} else {
int t = s.indexOf('.', start);
if (t < 0) {
// Additional hhmm[ss] format for compatibility
hEnd = mStart = start + 2;
mEnd = mStart + 2;
int len = end - start;
if (len == 6) {
sStart = mEnd;
sEnd = -1;
} else if (len == 4) {
sStart = sEnd = -1;
} else {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
} }
} else if (t >= start + 6) {
// Additional hhmmss.nanos format for compatibility
if (t - start != 6) {
throw new IllegalArgumentException(s);
}
hEnd = mStart = start + 2;
mEnd = sStart = mStart + 2;
sEnd = t;
} else {
// Additional hour.minute.second[.nanos] IBM DB2 time format
hEnd = t;
mStart = hEnd + 1;
mEnd = s.indexOf('.', mStart);
if (mEnd <= mStart) {
throw new IllegalArgumentException(s);
} }
hour = Integer.parseInt(s.substring(start, s1)); sStart = mEnd + 1;
if (hour < 0 || hour == 0 && s.charAt(0) == '-' || hour >= 24) { sEnd = s.indexOf('.', sStart);
}
}
hour = Integer.parseInt(s.substring(start, hEnd));
if (hour < 0 || hour == 0 && s.charAt(start) == '-' || hour >= 24) {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
} }
minute = Integer.parseInt(s.substring(s1 + 1, s2)); minute = Integer.parseInt(s.substring(mStart, mEnd));
if (s3 < 0) { if (sStart > 0) {
second = Integer.parseInt(s.substring(s2 + 1, end)); if (sEnd < 0) {
second = Integer.parseInt(s.substring(sStart, end));
nanos = 0; nanos = 0;
} else { } else {
second = Integer.parseInt(s.substring(s2 + 1, s3)); second = Integer.parseInt(s.substring(sStart, sEnd));
nanos = parseNanos(s, s3 + 1, end); nanos = parseNanos(s, sEnd + 1, end);
}
} else {
second = nanos = 0;
} }
if (minute < 0 || minute >= 60 || second < 0 || second >= 60) { if (minute < 0 || minute >= 60 || second < 0 || second >= 60) {
throw new IllegalArgumentException(s); throw new IllegalArgumentException(s);
......
...@@ -15,3 +15,12 @@ SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE, NUMERIC_SCALE, DATETIME_P ...@@ -15,3 +15,12 @@ SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE, NUMERIC_SCALE, DATETIME_P
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
SELECT DATE '2000-01-02';
>> 2000-01-02
SELECT DATE '20000102';
>> 2000-01-02
SELECT DATE '-1000102';
>> -100-01-02
...@@ -81,3 +81,33 @@ SELECT T0 FROM TEST; ...@@ -81,3 +81,33 @@ SELECT T0 FROM TEST;
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
SELECT TIME '11:22:33';
>> 11:22:33
SELECT TIME '11:22';
>> 11:22:00
SELECT TIME '112233';
>> 11:22:33
SELECT TIME '1122';
>> 11:22:00
SELECT TIME '12233';
> exception INVALID_DATETIME_CONSTANT_2
SELECT TIME '122';
> exception INVALID_DATETIME_CONSTANT_2
SELECT TIME '11:22:33.1';
>> 11:22:33.1
SELECT TIME '112233.1';
>> 11:22:33.1
SELECT TIME '12233.1';
> exception INVALID_DATETIME_CONSTANT_2
SELECT TIME '1122.1';
> exception INVALID_DATETIME_CONSTANT_2
...@@ -129,3 +129,27 @@ select * from test where d= timestamp '2006-01-01 12:00:00.000'; ...@@ -129,3 +129,27 @@ select * from test where d= timestamp '2006-01-01 12:00:00.000';
drop table test; drop table test;
> ok > ok
SELECT TIMESTAMP '2000-01-02 11:22:33';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '2000-01-02T11:22:33';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '20000102 11:22:33';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '20000102T11:22:33';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '2000-01-02 112233';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '2000-01-02T112233';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '20000102 112233';
>> 2000-01-02 11:22:33
SELECT TIMESTAMP '20000102T112233';
>> 2000-01-02 11:22:33
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论