Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
7ae35403
提交
7ae35403
authored
8月 14, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement casts between INTERVAL and VARCHAR
上级
326b51e6
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
317 行增加
和
0 行删除
+317
-0
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+151
-0
Value.java
h2/src/main/org/h2/value/Value.java
+24
-0
interval.sql
h2/src/test/org/h2/test/scripts/datatypes/interval.sql
+142
-0
没有找到文件。
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
7ae35403
...
@@ -1490,6 +1490,157 @@ public class DateTimeUtils {
...
@@ -1490,6 +1490,157 @@ public class DateTimeUtils {
return
b
.
toString
();
return
b
.
toString
();
}
}
/**
* Parses the specified string as {@code INTERVAL} value.
*
* @param qualifier the default qualifier to use if string does not have one
* @param s the string with type information to parse
* @return the interval value.
* Type of value can be different from the specified qualifier.
*/
public
static
ValueInterval
parseFormattedInterval
(
IntervalQualifier
qualifier
,
String
s
)
{
int
i
=
0
;
i
=
skipWS
(
s
,
i
);
if
(!
s
.
regionMatches
(
true
,
i
,
"INTERVAL"
,
0
,
8
))
{
return
parseInterval
(
qualifier
,
false
,
s
);
}
i
=
skipWS
(
s
,
i
+
8
);
boolean
negative
=
false
;
char
ch
=
s
.
charAt
(
i
);
if
(
ch
==
'-'
)
{
negative
=
true
;
i
=
skipWS
(
s
,
i
+
1
);
ch
=
s
.
charAt
(
i
);
}
else
if
(
ch
==
'+'
)
{
i
=
skipWS
(
s
,
i
+
1
);
ch
=
s
.
charAt
(
i
);
}
if
(
ch
!=
'\''
)
{
throw
new
IllegalArgumentException
(
s
);
}
int
start
=
++
i
;
int
l
=
s
.
length
();
for
(;;)
{
if
(
i
==
l
)
{
throw
new
IllegalArgumentException
(
s
);
}
if
(
s
.
charAt
(
i
)
==
'\''
)
{
break
;
}
i
++;
}
String
v
=
s
.
substring
(
start
,
i
);
i
=
skipWS
(
s
,
i
+
1
);
if
(
s
.
regionMatches
(
true
,
i
,
"YEAR"
,
0
,
4
))
{
i
+=
4
;
int
j
=
skipWSEnd
(
s
,
i
);
if
(
j
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
YEAR
,
negative
,
v
);
}
if
(
j
>
i
&&
s
.
regionMatches
(
true
,
j
,
"TO"
,
0
,
2
))
{
j
+=
2
;
i
=
skipWS
(
s
,
j
);
if
(
i
>
j
&&
s
.
regionMatches
(
true
,
i
,
"MONTH"
,
0
,
5
))
{
if
(
skipWSEnd
(
s
,
i
+
5
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
YEAR_TO_MONTH
,
negative
,
v
);
}
}
}
}
else
if
(
s
.
regionMatches
(
true
,
i
,
"MONTH"
,
0
,
5
))
{
if
(
skipWSEnd
(
s
,
i
+
5
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
MONTH
,
negative
,
v
);
}
}
if
(
s
.
regionMatches
(
true
,
i
,
"DAY"
,
0
,
3
))
{
i
+=
3
;
int
j
=
skipWSEnd
(
s
,
i
);
if
(
j
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
DAY
,
negative
,
v
);
}
if
(
j
>
i
&&
s
.
regionMatches
(
true
,
j
,
"TO"
,
0
,
2
))
{
j
+=
2
;
i
=
skipWS
(
s
,
j
);
if
(
i
>
j
)
{
if
(
s
.
regionMatches
(
true
,
i
,
"HOUR"
,
0
,
4
))
{
if
(
skipWSEnd
(
s
,
i
+
4
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
DAY_TO_HOUR
,
negative
,
v
);
}
}
else
if
(
s
.
regionMatches
(
true
,
i
,
"MINUTE"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
DAY_TO_MINUTE
,
negative
,
v
);
}
}
else
if
(
s
.
regionMatches
(
true
,
i
,
"SECOND"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
negative
,
v
);
}
}
}
}
}
if
(
s
.
regionMatches
(
true
,
i
,
"HOUR"
,
0
,
4
))
{
i
+=
4
;
int
j
=
skipWSEnd
(
s
,
i
);
if
(
j
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
HOUR
,
negative
,
v
);
}
if
(
j
>
i
&&
s
.
regionMatches
(
true
,
j
,
"TO"
,
0
,
2
))
{
j
+=
2
;
i
=
skipWS
(
s
,
j
);
if
(
i
>
j
)
{
if
(
s
.
regionMatches
(
true
,
i
,
"MINUTE"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
HOUR_TO_MINUTE
,
negative
,
v
);
}
}
else
if
(
s
.
regionMatches
(
true
,
i
,
"SECOND"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
HOUR_TO_SECOND
,
negative
,
v
);
}
}
}
}
}
if
(
s
.
regionMatches
(
true
,
i
,
"MINUTE"
,
0
,
6
))
{
i
+=
6
;
int
j
=
skipWSEnd
(
s
,
i
);
if
(
j
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
MINUTE
,
negative
,
v
);
}
if
(
j
>
i
&&
s
.
regionMatches
(
true
,
j
,
"TO"
,
0
,
2
))
{
j
+=
2
;
i
=
skipWS
(
s
,
j
);
if
(
i
>
j
&&
s
.
regionMatches
(
true
,
i
,
"SECOND"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
MINUTE_TO_SECOND
,
negative
,
v
);
}
}
}
}
if
(
s
.
regionMatches
(
true
,
i
,
"SECOND"
,
0
,
6
))
{
if
(
skipWSEnd
(
s
,
i
+
6
)
==
l
)
{
return
parseInterval
(
IntervalQualifier
.
SECOND
,
negative
,
v
);
}
}
throw
new
IllegalArgumentException
(
s
);
}
private
static
int
skipWS
(
String
s
,
int
i
)
{
for
(
int
l
=
s
.
length
();
;
i
++)
{
if
(
i
==
l
)
{
throw
new
IllegalArgumentException
(
s
);
}
if
(!
Character
.
isWhitespace
(
s
.
charAt
(
i
)))
{
return
i
;
}
}
}
private
static
int
skipWSEnd
(
String
s
,
int
i
)
{
for
(
int
l
=
s
.
length
();
;
i
++)
{
if
(
i
==
l
)
{
return
i
;
}
if
(!
Character
.
isWhitespace
(
s
.
charAt
(
i
)))
{
return
i
;
}
}
}
/**
/**
* Parses the specified string as {@code INTERVAL} value.
* Parses the specified string as {@code INTERVAL} value.
*
*
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
7ae35403
...
@@ -1153,6 +1153,18 @@ public abstract class Value {
...
@@ -1153,6 +1153,18 @@ public abstract class Value {
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
switch
(
getType
())
{
switch
(
getType
())
{
case
Value
.
STRING
:
case
Value
.
STRING_IGNORECASE
:
case
Value
.
STRING_FIXED
:
{
String
s
=
getString
();
try
{
return
DateTimeUtils
.
parseFormattedInterval
(
IntervalQualifier
.
valueOf
(
targetType
-
Value
.
INTERVAL_YEAR
),
s
)
.
convertTo
(
targetType
);
}
catch
(
Exception
e
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_DATETIME_CONSTANT_2
,
e
,
"INTERVAL"
,
s
);
}
}
case
Value
.
INTERVAL_YEAR
:
case
Value
.
INTERVAL_YEAR
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
...
@@ -1172,6 +1184,18 @@ public abstract class Value {
...
@@ -1172,6 +1184,18 @@ public abstract class Value {
case
Value
.
INTERVAL_HOUR_TO_SECOND
:
case
Value
.
INTERVAL_HOUR_TO_SECOND
:
case
Value
.
INTERVAL_MINUTE_TO_SECOND
:
case
Value
.
INTERVAL_MINUTE_TO_SECOND
:
switch
(
getType
())
{
switch
(
getType
())
{
case
Value
.
STRING
:
case
Value
.
STRING_IGNORECASE
:
case
Value
.
STRING_FIXED
:
{
String
s
=
getString
();
try
{
return
DateTimeUtils
.
parseFormattedInterval
(
IntervalQualifier
.
valueOf
(
targetType
-
Value
.
INTERVAL_YEAR
),
s
)
.
convertTo
(
targetType
);
}
catch
(
Exception
e
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_DATETIME_CONSTANT_2
,
e
,
"INTERVAL"
,
s
);
}
}
case
Value
.
INTERVAL_DAY
:
case
Value
.
INTERVAL_DAY
:
case
Value
.
INTERVAL_HOUR
:
case
Value
.
INTERVAL_HOUR
:
case
Value
.
INTERVAL_MINUTE
:
case
Value
.
INTERVAL_MINUTE
:
...
...
h2/src/test/org/h2/test/scripts/datatypes/interval.sql
浏览文件 @
7ae35403
...
@@ -433,6 +433,148 @@ SELECT CAST(INTERVAL '-1803:4.123456789' MINUTE TO SECOND AS INTERVAL HOUR TO SE
...
@@ -433,6 +433,148 @@ SELECT CAST(INTERVAL '-1803:4.123456789' MINUTE TO SECOND AS INTERVAL HOUR TO SE
SELECT
CAST
(
INTERVAL
'10:11.123456789'
MINUTE
TO
SECOND
AS
INTERVAL
SECOND
(
3
,
9
));
SELECT
CAST
(
INTERVAL
'10:11.123456789'
MINUTE
TO
SECOND
AS
INTERVAL
SECOND
(
3
,
9
));
>>
INTERVAL
'611.123456789'
SECOND
>>
INTERVAL
'611.123456789'
SECOND
-- Casts with strings
SELECT
CAST
(
INTERVAL
'10'
YEAR
AS
VARCHAR
);
>>
INTERVAL
'10'
YEAR
SELECT
CAST
(
'INTERVAL
''
10
''
YEAR'
AS
INTERVAL
YEAR
);
>>
INTERVAL
'10'
YEAR
SELECT
CAST
(
'10'
AS
INTERVAL
YEAR
);
>>
INTERVAL
'10'
YEAR
SELECT
CAST
(
INTERVAL
'10'
MONTH
AS
VARCHAR
);
>>
INTERVAL
'10'
MONTH
SELECT
CAST
(
'INTERVAL
''
10
''
MONTH'
AS
INTERVAL
MONTH
);
>>
INTERVAL
'10'
MONTH
SELECT
CAST
(
'10'
AS
INTERVAL
MONTH
);
>>
INTERVAL
'10'
MONTH
SELECT
CAST
(
INTERVAL
'10'
DAY
AS
VARCHAR
);
>>
INTERVAL
'10'
DAY
SELECT
CAST
(
'INTERVAL
''
10
''
DAY'
AS
INTERVAL
DAY
);
>>
INTERVAL
'10'
DAY
SELECT
CAST
(
'10'
AS
INTERVAL
DAY
);
>>
INTERVAL
'10'
DAY
SELECT
CAST
(
INTERVAL
'10'
HOUR
AS
VARCHAR
);
>>
INTERVAL
'10'
HOUR
SELECT
CAST
(
'INTERVAL
''
10
''
HOUR'
AS
INTERVAL
HOUR
);
>>
INTERVAL
'10'
HOUR
SELECT
CAST
(
'10'
AS
INTERVAL
HOUR
);
>>
INTERVAL
'10'
HOUR
SELECT
CAST
(
INTERVAL
'10'
MINUTE
AS
VARCHAR
);
>>
INTERVAL
'10'
MINUTE
SELECT
CAST
(
'INTERVAL
''
10
''
MINUTE'
AS
INTERVAL
MINUTE
);
>>
INTERVAL
'10'
MINUTE
SELECT
CAST
(
'10'
AS
INTERVAL
MINUTE
);
>>
INTERVAL
'10'
MINUTE
SELECT
CAST
(
INTERVAL
'10.123456789'
SECOND
AS
VARCHAR
);
>>
INTERVAL
'10.123456789'
SECOND
SELECT
CAST
(
'INTERVAL
''
10.123456789
''
SECOND'
AS
INTERVAL
SECOND
(
2
,
9
));
>>
INTERVAL
'10.123456789'
SECOND
SELECT
CAST
(
'10.123456789'
AS
INTERVAL
SECOND
(
2
,
9
));
>>
INTERVAL
'10.123456789'
SECOND
SELECT
CAST
(
INTERVAL
'10-11'
YEAR
TO
MONTH
AS
VARCHAR
);
>>
INTERVAL
'10-11'
YEAR
TO
MONTH
SELECT
CAST
(
'INTERVAL
''
10-11
''
YEAR TO MONTH'
AS
INTERVAL
YEAR
TO
MONTH
);
>>
INTERVAL
'10-11'
YEAR
TO
MONTH
SELECT
CAST
(
'10-11'
AS
INTERVAL
YEAR
TO
MONTH
);
>>
INTERVAL
'10-11'
YEAR
TO
MONTH
SELECT
CAST
(
INTERVAL
'10 11'
DAY
TO
HOUR
AS
VARCHAR
);
>>
INTERVAL
'10 11'
DAY
TO
HOUR
SELECT
CAST
(
'INTERVAL
''
10 11
''
DAY TO HOUR'
AS
INTERVAL
DAY
TO
HOUR
);
>>
INTERVAL
'10 11'
DAY
TO
HOUR
SELECT
CAST
(
'10 11'
AS
INTERVAL
DAY
TO
HOUR
);
>>
INTERVAL
'10 11'
DAY
TO
HOUR
SELECT
CAST
(
INTERVAL
'10 11:12'
DAY
TO
MINUTE
AS
VARCHAR
);
>>
INTERVAL
'10 11:12'
DAY
TO
MINUTE
SELECT
CAST
(
'INTERVAL
''
10 11:12
''
DAY TO MINUTE'
AS
INTERVAL
DAY
TO
MINUTE
);
>>
INTERVAL
'10 11:12'
DAY
TO
MINUTE
SELECT
CAST
(
'10 11:12'
AS
INTERVAL
DAY
TO
MINUTE
);
>>
INTERVAL
'10 11:12'
DAY
TO
MINUTE
SELECT
CAST
(
INTERVAL
'10 11:12:13.123456789'
DAY
TO
SECOND
AS
VARCHAR
);
>>
INTERVAL
'10 11:12:13.123456789'
DAY
TO
SECOND
SELECT
CAST
(
'INTERVAL
''
10 11:12:13.123456789
''
DAY TO SECOND'
AS
INTERVAL
DAY
TO
SECOND
(
9
));
>>
INTERVAL
'10 11:12:13.123456789'
DAY
TO
SECOND
SELECT
CAST
(
'10 11:12:13.123456789'
AS
INTERVAL
DAY
TO
SECOND
(
9
));
>>
INTERVAL
'10 11:12:13.123456789'
DAY
TO
SECOND
SELECT
CAST
(
INTERVAL
'11:12'
HOUR
TO
MINUTE
AS
VARCHAR
);
>>
INTERVAL
'11:12'
HOUR
TO
MINUTE
SELECT
CAST
(
'INTERVAL
''
11:12
''
HOUR TO MINUTE'
AS
INTERVAL
HOUR
TO
MINUTE
);
>>
INTERVAL
'11:12'
HOUR
TO
MINUTE
SELECT
CAST
(
'11:12'
AS
INTERVAL
HOUR
TO
MINUTE
);
>>
INTERVAL
'11:12'
HOUR
TO
MINUTE
SELECT
CAST
(
INTERVAL
'11:12:13.123456789'
HOUR
TO
SECOND
AS
VARCHAR
);
>>
INTERVAL
'11:12:13.123456789'
HOUR
TO
SECOND
SELECT
CAST
(
'INTERVAL
''
11:12:13.123456789
''
HOUR TO SECOND'
AS
INTERVAL
HOUR
TO
SECOND
(
9
));
>>
INTERVAL
'11:12:13.123456789'
HOUR
TO
SECOND
SELECT
CAST
(
'11:12:13.123456789'
AS
INTERVAL
HOUR
TO
SECOND
(
9
));
>>
INTERVAL
'11:12:13.123456789'
HOUR
TO
SECOND
SELECT
CAST
(
INTERVAL
'12:13.123456789'
MINUTE
TO
SECOND
AS
VARCHAR
);
>>
INTERVAL
'12:13.123456789'
MINUTE
TO
SECOND
SELECT
CAST
(
'INTERVAL
''
12:13.123456789
''
MINUTE TO SECOND'
AS
INTERVAL
MINUTE
TO
SECOND
(
9
));
>>
INTERVAL
'12:13.123456789'
MINUTE
TO
SECOND
SELECT
CAST
(
'12:13.123456789'
AS
INTERVAL
MINUTE
TO
SECOND
(
9
));
>>
INTERVAL
'12:13.123456789'
MINUTE
TO
SECOND
-- More formats
SELECT
INTERVAL
+
'+10'
SECOND
;
>>
INTERVAL
'10'
SECOND
SELECT
CAST
(
'INTERVAL +
''
+10
''
SECOND'
AS
INTERVAL
SECOND
);
>>
INTERVAL
'10'
SECOND
SELECT
INTERVAL
-
'-10'
HOUR
;
>>
INTERVAL
'10'
HOUR
SELECT
CAST
(
'INTERVAL -
''
-10
''
HOUR'
AS
INTERVAL
HOUR
);
>>
INTERVAL
'10'
HOUR
SELECT
CAST
(
'INTERVAL
''
1
''
MINUTE'
AS
INTERVAL
SECOND
);
>>
INTERVAL
'60'
SECOND
SELECT
CAST
(
' interval +
''
12-2
''
Year To Month '
AS
INTERVAL
YEAR
TO
MONTH
);
>>
INTERVAL
'12-2'
YEAR
TO
MONTH
SELECT
CAST
(
'INTERVAL
''
11:12
''
HOUR TO MINUTE'
AS
INTERVAL
HOUR
TO
MINUTE
);
>>
INTERVAL
'11:12'
HOUR
TO
MINUTE
-- Arithmetic
-- Arithmetic
SELECT
INTERVAL
'1000'
SECOND
+
INTERVAL
'10'
MINUTE
;
SELECT
INTERVAL
'1000'
SECOND
+
INTERVAL
'10'
MINUTE
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论