Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
e403cc08
提交
e403cc08
authored
8月 13, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Initial partial implementation of INTERVAL data type
上级
217abf45
显示空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
1241 行增加
和
40 行删除
+1241
-40
Interval.java
h2/src/main/org/h2/api/Interval.java
+74
-0
IntervalQualifier.java
h2/src/main/org/h2/api/IntervalQualifier.java
+337
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+106
-2
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+27
-3
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+254
-8
DataType.java
h2/src/main/org/h2/value/DataType.java
+63
-4
Value.java
h2/src/main/org/h2/value/Value.java
+92
-1
ValueInterval.java
h2/src/main/org/h2/value/ValueInterval.java
+142
-0
TestScript.java
h2/src/test/org/h2/test/scripts/TestScript.java
+1
-1
decimal_decimal.sql
...rc/test/org/h2/test/scripts/datatypes/decimal_decimal.sql
+7
-7
decimal_numeric.sql
...rc/test/org/h2/test/scripts/datatypes/decimal_numeric.sql
+7
-7
enum.sql
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
+7
-7
interval.sql
h2/src/test/org/h2/test/scripts/datatypes/interval.sql
+51
-0
TestDateTimeUtils.java
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
+73
-0
没有找到文件。
h2/src/main/org/h2/api/Interval.java
0 → 100644
浏览文件 @
e403cc08
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
api
;
import
org.h2.util.DateTimeUtils
;
/**
* {@code INTERVAL} representation for result sets.
*/
public
final
class
Interval
{
private
final
IntervalQualifier
qualifier
;
private
final
long
leading
;
private
final
long
remaining
;
/**
* @param qualifier
* qualifier
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
*/
public
Interval
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
)
{
if
(
qualifier
==
null
)
{
throw
new
NullPointerException
();
}
this
.
qualifier
=
qualifier
;
this
.
leading
=
leading
;
this
.
remaining
=
remaining
;
}
/**
* Return qualifier of this interval.
*
* @return qualifier
*/
public
IntervalQualifier
getQualifier
()
{
return
qualifier
;
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
qualifier
.
hashCode
();
result
=
prime
*
result
+
(
int
)
(
leading
^
(
leading
>>>
32
));
result
=
prime
*
result
+
(
int
)
(
remaining
^
(
remaining
>>>
32
));
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(!(
obj
instanceof
Interval
))
{
return
false
;
}
Interval
other
=
(
Interval
)
obj
;
return
qualifier
==
other
.
qualifier
&&
leading
==
other
.
leading
||
remaining
==
other
.
remaining
;
}
@Override
public
String
toString
()
{
return
DateTimeUtils
.
intervalToString
(
qualifier
,
leading
,
remaining
);
}
}
h2/src/main/org/h2/api/IntervalQualifier.java
0 → 100644
浏览文件 @
e403cc08
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
api
;
/**
* Interval qualifier.
*/
public
enum
IntervalQualifier
{
/**
* {@code YEAR}
*/
YEAR
,
/**
* {@code MONTH}
*/
MONTH
,
/**
* {@code DAY}
*/
DAY
,
/**
* {@code HOUR}
*/
HOUR
,
/**
* {@code MINUTE}
*/
MINUTE
,
/**
* {@code SECOND}
*/
SECOND
,
/**
* {@code YEAR TO MONTH}
*/
YEAR_TO_MONTH
,
/**
* {@code DAY TO HOUR}
*/
DAY_TO_HOUR
,
/**
* {@code DAY TO MINUTE}
*/
DAY_TO_MINUTE
,
/**
* {@code DAY TO SECOND}
*/
DAY_TO_SECOND
,
/**
* {@code HOUR TO MINUTE}
*/
HOUR_TO_MINUTE
,
/**
* {@code HOUR TO SECOND}
*/
HOUR_TO_SECOND
,
/**
* {@code MINUTE TO SECOND}
*/
MINUTE_TO_SECOND
;
private
final
String
string
;
/**
* Returns the interval qualifier with the specified ordinal value.
*
* @param ordinal
* Java ordinal value (0-based)
* @return interval qualifier with the specified ordinal value
*/
public
static
IntervalQualifier
valueOf
(
int
ordinal
)
{
switch
(
ordinal
)
{
case
0
:
return
YEAR
;
case
1
:
return
MONTH
;
case
2
:
return
DAY
;
case
3
:
return
HOUR
;
case
4
:
return
MINUTE
;
case
5
:
return
SECOND
;
case
6
:
return
YEAR_TO_MONTH
;
case
7
:
return
DAY_TO_HOUR
;
case
8
:
return
DAY_TO_MINUTE
;
case
9
:
return
DAY_TO_SECOND
;
case
10
:
return
HOUR_TO_MINUTE
;
case
11
:
return
HOUR_TO_SECOND
;
case
12
:
return
MINUTE_TO_SECOND
;
default
:
throw
new
IllegalArgumentException
();
}
}
private
IntervalQualifier
()
{
string
=
name
().
replace
(
'_'
,
' '
).
intern
();
}
/**
* Returns whether interval with this qualifier is a year-month interval.
*
* @return whether interval with this qualifier is a year-month interval
*/
public
boolean
isYearMonth
()
{
return
this
==
YEAR
||
this
==
MONTH
||
this
==
YEAR_TO_MONTH
;
}
/**
* Returns whether interval with this qualifier is a day-time interval.
*
* @return whether interval with this qualifier is a day-time interval
*/
public
boolean
isDayTime
()
{
return
!
isYearMonth
();
}
/**
* Returns whether interval with this qualifier has years.
*
* @return whether interval with this qualifier has years
*/
public
boolean
hasYears
()
{
return
this
==
YEAR
||
this
==
YEAR_TO_MONTH
;
}
/**
* Returns whether interval with this qualifier has months.
*
* @return whether interval with this qualifier has months
*/
public
boolean
hasMonths
()
{
return
this
==
MONTH
||
this
==
YEAR_TO_MONTH
;
}
/**
* Returns whether interval with this qualifier has days.
*
* @return whether interval with this qualifier has days
*/
public
boolean
hasDays
()
{
switch
(
this
)
{
case
DAY:
case
DAY_TO_HOUR:
case
DAY_TO_MINUTE:
case
DAY_TO_SECOND:
return
true
;
default
:
return
false
;
}
}
/**
* Returns whether interval with this qualifier has hours.
*
* @return whether interval with this qualifier has hours
*/
public
boolean
hasHours
()
{
switch
(
this
)
{
case
HOUR:
case
DAY_TO_HOUR:
case
DAY_TO_MINUTE:
case
DAY_TO_SECOND:
case
HOUR_TO_MINUTE:
case
HOUR_TO_SECOND:
return
true
;
default
:
return
false
;
}
}
/**
* Returns whether interval with this qualifier has minutes.
*
* @return whether interval with this qualifier has minutes
*/
public
boolean
hasMinutes
()
{
switch
(
this
)
{
case
MINUTE:
case
DAY_TO_MINUTE:
case
DAY_TO_SECOND:
case
HOUR_TO_MINUTE:
case
HOUR_TO_SECOND:
case
MINUTE_TO_SECOND:
return
true
;
default
:
return
false
;
}
}
/**
* Returns whether interval with this qualifier has seconds.
*
* @return whether interval with this qualifier has seconds
*/
public
boolean
hasSeconds
()
{
switch
(
this
)
{
case
SECOND:
case
DAY_TO_SECOND:
case
HOUR_TO_SECOND:
case
MINUTE_TO_SECOND:
return
true
;
default
:
return
false
;
}
}
/**
* Returns whether interval with this qualifier has multiple fields.
*
* @return whether interval with this qualifier has multiple fields
*/
public
boolean
hasMultipleFields
()
{
return
ordinal
()
>
5
;
}
@Override
public
String
toString
()
{
return
string
;
}
/**
* Returns full type name.
*
* @param precision precision, or {@code -1}
* @param scale fractional seconds precision, or {@code -1}
* @return full type name
*/
public
String
getTypeName
(
int
precision
,
int
scale
)
{
StringBuilder
b
=
new
StringBuilder
(
"INTERVAL "
);
switch
(
this
)
{
case
YEAR:
case
MONTH:
case
DAY:
case
HOUR:
case
MINUTE:
b
.
append
(
string
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
break
;
case
SECOND:
b
.
append
(
string
);
if
(
precision
>
0
||
scale
>=
0
)
{
b
.
append
(
'('
).
append
(
precision
>
0
?
precision
:
2
);
if
(
scale
>=
0
)
{
b
.
append
(
", "
).
append
(
scale
);
}
b
.
append
(
')'
);
}
break
;
case
YEAR_TO_MONTH:
b
.
append
(
"YEAR"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO MONTH"
);
break
;
case
DAY_TO_HOUR:
b
.
append
(
"DAY"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO HOUR"
);
break
;
case
DAY_TO_MINUTE:
b
.
append
(
"DAY"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO MINUTE"
);
break
;
case
DAY_TO_SECOND:
b
.
append
(
"DAY"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO SECOND"
);
if
(
scale
>=
0
)
{
b
.
append
(
'('
).
append
(
scale
).
append
(
')'
);
}
break
;
case
HOUR_TO_MINUTE:
b
.
append
(
"HOUR"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO MINUTE"
);
break
;
case
HOUR_TO_SECOND:
b
.
append
(
"HOUR"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO SECOND"
);
if
(
scale
>=
0
)
{
b
.
append
(
'('
).
append
(
scale
).
append
(
')'
);
}
break
;
case
MINUTE_TO_SECOND:
b
.
append
(
"MINUTE"
);
if
(
precision
>
0
)
{
b
.
append
(
'('
).
append
(
precision
).
append
(
')'
);
}
b
.
append
(
" TO SECOND"
);
if
(
scale
>=
0
)
{
b
.
append
(
'('
).
append
(
scale
).
append
(
')'
);
}
}
return
b
.
toString
();
}
}
h2/src/main/org/h2/command/Parser.java
浏览文件 @
e403cc08
...
@@ -60,6 +60,7 @@ import java.util.LinkedHashSet;
...
@@ -60,6 +60,7 @@ import java.util.LinkedHashSet;
import
java.util.List
;
import
java.util.List
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.IntervalQualifier
;
import
org.h2.api.Trigger
;
import
org.h2.api.Trigger
;
import
org.h2.command.ddl.AlterIndexRename
;
import
org.h2.command.ddl.AlterIndexRename
;
import
org.h2.command.ddl.AlterSchemaRename
;
import
org.h2.command.ddl.AlterSchemaRename
;
...
@@ -201,6 +202,7 @@ import org.h2.value.ValueDate;
...
@@ -201,6 +202,7 @@ import org.h2.value.ValueDate;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInterval
;
import
org.h2.value.ValueLong
;
import
org.h2.value.ValueLong
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueString
;
import
org.h2.value.ValueString
;
...
@@ -4685,7 +4687,7 @@ public class Parser {
...
@@ -4685,7 +4687,7 @@ public class Parser {
private
Column
parseColumnWithType
(
String
columnName
,
boolean
forTable
)
{
private
Column
parseColumnWithType
(
String
columnName
,
boolean
forTable
)
{
String
original
=
currentToken
;
String
original
=
currentToken
;
boolean
regular
=
false
;
boolean
regular
=
false
;
int
originalScale
=
-
1
;
int
original
Precision
=
-
1
,
original
Scale
=
-
1
;
if
(
readIf
(
"LONG"
))
{
if
(
readIf
(
"LONG"
))
{
if
(
readIf
(
"RAW"
))
{
if
(
readIf
(
"RAW"
))
{
original
=
"LONG RAW"
;
original
=
"LONG RAW"
;
...
@@ -4742,6 +4744,90 @@ public class Parser {
...
@@ -4742,6 +4744,90 @@ public class Parser {
read
(
"ZONE"
);
read
(
"ZONE"
);
original
=
"TIMESTAMP WITHOUT TIME ZONE"
;
original
=
"TIMESTAMP WITHOUT TIME ZONE"
;
}
}
}
else
if
(
readIf
(
"INTERVAL"
))
{
if
(
readIf
(
"YEAR"
))
{
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
if
(
readIf
(
"TO"
))
{
read
(
"MONTH"
);
original
=
"INTERVAL YEAR TO MONTH"
;
}
else
{
original
=
"INTERVAL YEAR"
;
}
}
else
if
(
readIf
(
"MONTH"
))
{
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
original
=
"INTERVAL MONTH"
;
}
else
if
(
readIf
(
"DAY"
))
{
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
if
(
readIf
(
"TO"
))
{
if
(
readIf
(
"HOUR"
))
{
original
=
"INTERVAL DAY TO HOUR"
;
}
else
if
(
readIf
(
"MINUTE"
))
{
original
=
"INTERVAL DAY TO MINUTE"
;
}
else
{
read
(
"SECOND"
);
if
(
readIf
(
OPEN_PAREN
))
{
originalScale
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
original
=
"INTERVAL DAY TO SECOND"
;
}
}
else
{
original
=
"INTERVAL DAY"
;
}
}
else
if
(
readIf
(
"HOUR"
))
{
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
if
(
readIf
(
"TO"
))
{
if
(
readIf
(
"MINUTE"
))
{
original
=
"INTERVAL HOUR TO MINUTE"
;
}
else
{
read
(
"SECOND"
);
if
(
readIf
(
OPEN_PAREN
))
{
originalScale
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
original
=
"INTERVAL HOUR TO SECOND"
;
}
}
else
{
original
=
"INTERVAL HOUR"
;
}
}
else
if
(
readIf
(
"MINUTE"
))
{
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
if
(
readIf
(
"TO"
))
{
read
(
"SECOND"
);
if
(
readIf
(
OPEN_PAREN
))
{
originalScale
=
readNonNegativeInt
();
read
(
CLOSE_PAREN
);
}
original
=
"INTERVAL MINUTE TO SECOND"
;
}
else
{
original
=
"INTERVAL MINUTE"
;
}
}
else
{
read
(
"SECOND"
);
if
(
readIf
(
OPEN_PAREN
))
{
originalPrecision
=
readNonNegativeInt
();
if
(
readIf
(
COMMA
))
{
originalScale
=
readNonNegativeInt
();
}
read
(
CLOSE_PAREN
);
}
original
=
"INTERVAL SECOND"
;
}
}
else
{
}
else
{
regular
=
true
;
regular
=
true
;
}
}
...
@@ -4828,6 +4914,24 @@ public class Parser {
...
@@ -4828,6 +4914,24 @@ public class Parser {
scale
=
0
;
scale
=
0
;
precision
=
displaySize
=
ValueTimestamp
.
getDisplaySize
(
0
);
precision
=
displaySize
=
ValueTimestamp
.
getDisplaySize
(
0
);
}
}
}
else
if
(
DataType
.
isIntervalType
(
t
))
{
if
(
originalPrecision
>=
0
||
originalScale
>=
0
)
{
IntervalQualifier
qualifier
=
IntervalQualifier
.
valueOf
(
t
-
Value
.
INTERVAL_YEAR
);
original
=
qualifier
.
getTypeName
(
originalPrecision
,
originalScale
);
if
(
originalPrecision
>=
0
)
{
if
(
originalPrecision
<=
0
||
originalPrecision
>
ValueInterval
.
MAXIMUM_PRECISION
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_SCALE_PRECISION
,
Integer
.
toString
(
originalPrecision
));
}
precision
=
originalPrecision
;
}
if
(
originalScale
>=
0
)
{
if
(
originalScale
>
ValueInterval
.
MAXIMUM_SCALE
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_SCALE_PRECISION
,
Integer
.
toString
(
originalScale
));
}
}
}
}
else
if
(
readIf
(
OPEN_PAREN
))
{
}
else
if
(
readIf
(
OPEN_PAREN
))
{
if
(!
readIf
(
"MAX"
))
{
if
(!
readIf
(
"MAX"
))
{
long
p
=
readLong
();
long
p
=
readLong
();
...
@@ -4909,7 +5013,7 @@ public class Parser {
...
@@ -4909,7 +5013,7 @@ public class Parser {
// MySQL compatibility
// MySQL compatibility
readIf
(
"UNSIGNED"
);
readIf
(
"UNSIGNED"
);
int
type
=
dataType
.
type
;
int
type
=
dataType
.
type
;
if
(
scale
>
precision
)
{
if
(
scale
>
precision
&&
!
DataType
.
isIntervalType
(
type
)
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_SCALE_PRECISION
,
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_SCALE_PRECISION
,
Integer
.
toString
(
scale
),
Long
.
toString
(
precision
));
Integer
.
toString
(
scale
),
Long
.
toString
(
precision
));
}
}
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
e403cc08
...
@@ -175,6 +175,8 @@ public class MetaTable extends Table {
...
@@ -175,6 +175,8 @@ public class MetaTable extends Table {
"NUMERIC_PRECISION_RADIX INT"
,
"NUMERIC_PRECISION_RADIX INT"
,
"NUMERIC_SCALE INT"
,
"NUMERIC_SCALE INT"
,
"DATETIME_PRECISION INT"
,
"DATETIME_PRECISION INT"
,
"INTERVAL_TYPE"
,
"INTERVAL_PRECISION INT"
,
"CHARACTER_SET_NAME"
,
"CHARACTER_SET_NAME"
,
"COLLATION_NAME"
,
"COLLATION_NAME"
,
// extensions
// extensions
...
@@ -845,6 +847,24 @@ public class MetaTable extends Table {
...
@@ -845,6 +847,24 @@ public class MetaTable extends Table {
ValueInt
precision
=
ValueInt
.
get
(
c
.
getPrecisionAsInt
());
ValueInt
precision
=
ValueInt
.
get
(
c
.
getPrecisionAsInt
());
ValueInt
scale
=
ValueInt
.
get
(
c
.
getScale
());
ValueInt
scale
=
ValueInt
.
get
(
c
.
getScale
());
Sequence
sequence
=
c
.
getSequence
();
Sequence
sequence
=
c
.
getSequence
();
boolean
hasDateTimePrecision
;
int
type
=
dataType
.
type
;
switch
(
type
)
{
case
Value
.
TIME
:
case
Value
.
DATE
:
case
Value
.
TIMESTAMP
:
case
Value
.
TIMESTAMP_TZ
:
case
Value
.
INTERVAL_SECOND
:
case
Value
.
INTERVAL_DAY_TO_SECOND
:
case
Value
.
INTERVAL_HOUR_TO_SECOND
:
case
Value
.
INTERVAL_MINUTE_TO_SECOND
:
hasDateTimePrecision
=
true
;
break
;
default
:
hasDateTimePrecision
=
false
;
}
boolean
isInterval
=
DataType
.
isIntervalType
(
type
);
String
createSQLWithoutName
=
c
.
getCreateSQLWithoutName
();
add
(
rows
,
add
(
rows
,
// TABLE_CATALOG
// TABLE_CATALOG
catalog
,
catalog
,
...
@@ -873,13 +893,17 @@ public class MetaTable extends Table {
...
@@ -873,13 +893,17 @@ public class MetaTable extends Table {
// NUMERIC_SCALE
// NUMERIC_SCALE
scale
,
scale
,
// DATETIME_PRECISION
// DATETIME_PRECISION
DataType
.
isDateTimeType
(
dataType
.
type
)
?
scale
:
null
,
hasDateTimePrecision
?
scale
:
null
,
// INTERVAL_TYPE
isInterval
?
createSQLWithoutName
.
substring
(
9
)
:
null
,
// INTERVAL_PRECISION
isInterval
?
precision
:
null
,
// CHARACTER_SET_NAME
// CHARACTER_SET_NAME
CHARACTER_SET_NAME
,
CHARACTER_SET_NAME
,
// COLLATION_NAME
// COLLATION_NAME
collation
,
collation
,
// TYPE_NAME
// TYPE_NAME
identifier
(
dataType
.
name
),
identifier
(
isInterval
?
"INTERVAL"
:
dataType
.
name
),
// NULLABLE
// NULLABLE
ValueInt
.
get
(
c
.
isNullable
()
ValueInt
.
get
(
c
.
isNullable
()
?
DatabaseMetaData
.
columnNullable
:
DatabaseMetaData
.
columnNoNulls
),
?
DatabaseMetaData
.
columnNullable
:
DatabaseMetaData
.
columnNoNulls
),
...
@@ -897,7 +921,7 @@ public class MetaTable extends Table {
...
@@ -897,7 +921,7 @@ public class MetaTable extends Table {
// SMALLINT
// SMALLINT
null
,
null
,
// COLUMN_TYPE
// COLUMN_TYPE
c
.
getCreateSQLWithoutName
()
,
c
reateSQLWithoutName
,
// COLUMN_ON_UPDATE
// COLUMN_ON_UPDATE
c
.
getOnUpdateSQL
()
c
.
getOnUpdateSQL
()
);
);
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
e403cc08
...
@@ -12,9 +12,11 @@ import java.sql.Timestamp;
...
@@ -12,9 +12,11 @@ import java.sql.Timestamp;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.GregorianCalendar
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
org.h2.api.IntervalQualifier
;
import
org.h2.engine.Mode
;
import
org.h2.engine.Mode
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueInterval
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueTime
;
import
org.h2.value.ValueTime
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestamp
;
...
@@ -392,8 +394,7 @@ public class DateTimeUtils {
...
@@ -392,8 +394,7 @@ public class DateTimeUtils {
second
=
Integer
.
parseInt
(
s
.
substring
(
s2
+
1
,
end
));
second
=
Integer
.
parseInt
(
s
.
substring
(
s2
+
1
,
end
));
}
else
{
}
else
{
second
=
Integer
.
parseInt
(
s
.
substring
(
s2
+
1
,
s3
));
second
=
Integer
.
parseInt
(
s
.
substring
(
s2
+
1
,
s3
));
String
n
=
(
s
.
substring
(
s3
+
1
,
end
)
+
"000000000"
).
substring
(
0
,
9
);
nanos
=
parseNanos
(
s
,
s3
+
1
,
end
);
nanos
=
Integer
.
parseInt
(
n
);
}
}
if
(
hour
>=
2_000_000
||
minute
<
0
||
minute
>=
60
||
second
<
0
if
(
hour
>=
2_000_000
||
minute
<
0
||
minute
>=
60
||
second
<
0
||
second
>=
60
)
{
||
second
>=
60
)
{
...
@@ -406,6 +407,10 @@ public class DateTimeUtils {
...
@@ -406,6 +407,10 @@ public class DateTimeUtils {
return
negative
?
-
nanos
:
nanos
;
return
negative
?
-
nanos
:
nanos
;
}
}
private
static
int
parseNanos
(
String
s
,
int
start
,
int
end
)
{
return
Integer
.
parseInt
((
s
.
substring
(
start
,
end
)
+
"000000000"
).
substring
(
0
,
9
));
}
/**
/**
* See:
* See:
* https://stackoverflow.com/questions/3976616/how-to-find-nth-occurrence-of-character-in-a-string#answer-3976656
* https://stackoverflow.com/questions/3976616/how-to-find-nth-occurrence-of-character-in-a-string#answer-3976656
...
@@ -1399,17 +1404,21 @@ public class DateTimeUtils {
...
@@ -1399,17 +1404,21 @@ public class DateTimeUtils {
StringUtils
.
appendZeroPadded
(
buff
,
2
,
s
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
s
);
if
(
ms
>
0
||
nanos
>
0
)
{
if
(
ms
>
0
||
nanos
>
0
)
{
buff
.
append
(
'.'
);
buff
.
append
(
'.'
);
int
start
=
buff
.
length
();
StringUtils
.
appendZeroPadded
(
buff
,
3
,
ms
);
StringUtils
.
appendZeroPadded
(
buff
,
3
,
ms
);
if
(
nanos
>
0
)
{
if
(
nanos
>
0
)
{
StringUtils
.
appendZeroPadded
(
buff
,
6
,
nanos
);
StringUtils
.
appendZeroPadded
(
buff
,
6
,
nanos
);
}
}
for
(
int
i
=
buff
.
length
()
-
1
;
i
>
start
;
i
--)
{
stripTrailingZeroes
(
buff
);
if
(
buff
.
charAt
(
i
)
!=
'0'
)
{
break
;
}
}
buff
.
deleteCharAt
(
i
);
}
}
private
static
void
stripTrailingZeroes
(
StringBuilder
buff
)
{
int
i
=
buff
.
length
()
-
1
;
if
(
buff
.
charAt
(
i
)
==
'0'
)
{
while
(
buff
.
charAt
(--
i
)
==
'0'
)
{
// do nothing
}
buff
.
setLength
(
i
+
1
);
}
}
}
}
...
@@ -1478,6 +1487,243 @@ public class DateTimeUtils {
...
@@ -1478,6 +1487,243 @@ public class DateTimeUtils {
return
b
.
toString
();
return
b
.
toString
();
}
}
/**
* Parses the specified string as {@code INTERVAL} value.
*
* @param qualifier the qualifier of interval
* @param negative whether the interval is negative
* @param s the string to parse
* @return the interval value
*/
public
static
ValueInterval
parseInterval
(
IntervalQualifier
qualifier
,
boolean
negative
,
String
s
)
{
long
leading
,
remaining
;
switch
(
qualifier
)
{
case
YEAR:
case
MONTH:
case
DAY:
case
HOUR:
case
MINUTE:
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
break
;
case
SECOND:
{
int
dot
=
s
.
indexOf
(
'.'
);
if
(
dot
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
dot
);
remaining
=
parseNanos
(
s
,
dot
+
1
,
s
.
length
());
}
break
;
}
case
YEAR_TO_MONTH:
return
parseInterval2
(
qualifier
,
s
,
'-'
,
11
);
case
DAY_TO_HOUR:
return
parseInterval2
(
qualifier
,
s
,
' '
,
23
);
case
DAY_TO_MINUTE:
{
int
space
=
s
.
indexOf
(
' '
);
if
(
space
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
space
);
int
colon
=
s
.
indexOf
(
':'
,
space
+
1
);
if
(
colon
<
0
)
{
remaining
=
parseIntervalRemaining
(
s
,
space
+
1
,
s
.
length
(),
23
)
*
60
;
}
else
{
remaining
=
parseIntervalRemaining
(
s
,
space
+
1
,
colon
,
23
)
*
60
+
parseIntervalRemaining
(
s
,
colon
+
1
,
s
.
length
(),
59
);
}
}
break
;
}
case
DAY_TO_SECOND:
{
int
space
=
s
.
indexOf
(
' '
);
if
(
space
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
space
);
int
colon
=
s
.
indexOf
(
':'
,
space
+
1
);
if
(
colon
<
0
)
{
remaining
=
parseIntervalRemaining
(
s
,
space
+
1
,
s
.
length
(),
23
)
*
3_600_000_000_000L
;
}
else
{
int
colon2
=
s
.
indexOf
(
':'
,
colon
+
1
);
if
(
colon2
<
0
)
{
remaining
=
parseIntervalRemaining
(
s
,
space
+
1
,
colon
,
23
)
*
3_600_000_000_000L
+
parseIntervalRemaining
(
s
,
colon
+
1
,
s
.
length
(),
59
)
*
60_000_000_000L
;
}
else
{
remaining
=
parseIntervalRemaining
(
s
,
space
+
1
,
colon
,
23
)
*
3_600_000_000_000L
+
parseIntervalRemaining
(
s
,
colon
+
1
,
colon2
,
59
)
*
60_000_000_000L
+
parseIntervalRemainingSeconds
(
s
,
colon2
+
1
);
}
}
}
break
;
}
case
HOUR_TO_MINUTE:
return
parseInterval2
(
qualifier
,
s
,
':'
,
59
);
case
HOUR_TO_SECOND:
{
int
colon
=
s
.
indexOf
(
':'
);
if
(
colon
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
colon
);
int
colon2
=
s
.
indexOf
(
':'
,
colon
+
1
);
if
(
colon2
<
0
)
{
remaining
=
parseIntervalRemaining
(
s
,
colon
+
1
,
s
.
length
(),
59
)
*
60_000_000_000L
;
}
else
{
remaining
=
parseIntervalRemaining
(
s
,
colon
+
1
,
colon2
,
59
)
*
60_000_000_000L
+
parseIntervalRemainingSeconds
(
s
,
colon2
+
1
);
}
}
break
;
}
case
MINUTE_TO_SECOND:
{
int
dash
=
s
.
indexOf
(
':'
);
if
(
dash
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
dash
);
remaining
=
parseIntervalRemainingSeconds
(
s
,
dash
+
1
);
}
return
ValueInterval
.
from
(
qualifier
,
leading
,
remaining
);
}
default
:
throw
new
IllegalArgumentException
();
}
return
ValueInterval
.
from
(
qualifier
,
leading
,
remaining
);
}
static
ValueInterval
parseInterval2
(
IntervalQualifier
qualifier
,
String
s
,
char
ch
,
int
max
)
{
long
leading
;
long
remaining
;
int
dash
=
s
.
indexOf
(
ch
);
if
(
dash
<
0
)
{
leading
=
parseIntervalLeading
(
s
,
0
,
s
.
length
());
remaining
=
0
;
}
else
{
leading
=
parseIntervalLeading
(
s
,
0
,
dash
);
remaining
=
parseIntervalRemaining
(
s
,
dash
+
1
,
s
.
length
(),
max
);
}
return
ValueInterval
.
from
(
qualifier
,
leading
,
remaining
);
}
private
static
long
parseIntervalLeading
(
String
s
,
int
start
,
int
end
)
{
return
Long
.
parseLong
(
s
.
substring
(
start
,
end
));
}
private
static
long
parseIntervalRemaining
(
String
s
,
int
start
,
int
end
,
int
max
)
{
long
v
=
Integer
.
parseInt
(
s
.
substring
(
start
,
end
));
if
(
v
<
0
||
v
>
max
)
{
throw
new
IllegalArgumentException
(
s
);
}
return
v
;
}
private
static
long
parseIntervalRemainingSeconds
(
String
s
,
int
start
)
{
int
seconds
,
nanos
;
int
dot
=
s
.
indexOf
(
'.'
,
start
+
1
);
if
(
dot
<
0
)
{
seconds
=
Integer
.
parseInt
(
s
.
substring
(
start
));
nanos
=
0
;
}
else
{
seconds
=
Integer
.
parseInt
(
s
.
substring
(
start
,
dot
));
nanos
=
parseNanos
(
s
,
dot
+
1
,
s
.
length
());
}
if
(
seconds
<
0
||
seconds
>
59
)
{
throw
new
IllegalArgumentException
(
s
);
}
return
seconds
*
1_000_000_000L
+
nanos
;
}
/**
* Formats interval as a string.
*
* @param qualifier qualifier of the interval
* @param leading the value of leading field
* @param remaining the value of all remaining fields
* @return string representation of the specified interval
*/
public
static
String
intervalToString
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
)
{
StringBuilder
buff
=
new
StringBuilder
().
append
(
"INTERVAL "
);
boolean
negative
=
leading
<
0
;
if
(
negative
)
{
leading
=
-
leading
;
buff
.
append
(
'-'
);
}
buff
.
append
(
'\''
);
switch
(
qualifier
)
{
case
YEAR:
case
MONTH:
case
DAY:
case
HOUR:
case
MINUTE:
buff
.
append
(
leading
);
break
;
case
SECOND:
buff
.
append
(
leading
);
appendNanos
(
buff
,
remaining
);
break
;
case
YEAR_TO_MONTH:
buff
.
append
(
leading
).
append
(
'-'
).
append
(
remaining
);
break
;
case
DAY_TO_HOUR:
buff
.
append
(
leading
).
append
(
' '
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
);
break
;
case
DAY_TO_MINUTE:
buff
.
append
(
leading
).
append
(
' '
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
/
60
);
buff
.
append
(
':'
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
%
60
);
break
;
case
DAY_TO_SECOND:
{
long
nanos
=
remaining
%
60_000_000_000L
;
remaining
/=
60_000_000_000L
;
buff
.
append
(
leading
).
append
(
' '
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
/
60
);
buff
.
append
(
':'
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
%
60
);
buff
.
append
(
':'
);
appendSecondsWithNanos
(
buff
,
nanos
);
break
;
}
case
HOUR_TO_MINUTE:
buff
.
append
(
leading
).
append
(
':'
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
);
break
;
case
HOUR_TO_SECOND:
buff
.
append
(
leading
).
append
(
':'
);
StringUtils
.
appendZeroPadded
(
buff
,
2
,
remaining
/
60_000_000_000L
);
buff
.
append
(
':'
);
appendSecondsWithNanos
(
buff
,
remaining
%
60_000_000_000L
);
break
;
case
MINUTE_TO_SECOND:
buff
.
append
(
leading
).
append
(
':'
);
appendSecondsWithNanos
(
buff
,
remaining
);
break
;
}
buff
.
append
(
"' "
).
append
(
qualifier
);
return
buff
.
toString
();
}
private
static
void
appendSecondsWithNanos
(
StringBuilder
buff
,
long
nanos
)
{
StringUtils
.
appendZeroPadded
(
buff
,
2
,
nanos
/
1_000_000_000
);
appendNanos
(
buff
,
nanos
%
1_000_000_000
);
}
private
static
void
appendNanos
(
StringBuilder
buff
,
long
nanos
)
{
if
(
nanos
>
0
)
{
buff
.
append
(
'.'
);
StringUtils
.
appendZeroPadded
(
buff
,
9
,
nanos
);
stripTrailingZeroes
(
buff
);
}
}
/**
/**
* Converts scale of nanoseconds.
* Converts scale of nanoseconds.
*
*
...
...
h2/src/main/org/h2/value/DataType.java
浏览文件 @
e403cc08
...
@@ -26,6 +26,7 @@ import java.util.HashMap;
...
@@ -26,6 +26,7 @@ import java.util.HashMap;
import
java.util.UUID
;
import
java.util.UUID
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.IntervalQualifier
;
import
org.h2.api.TimestampWithTimeZone
;
import
org.h2.api.TimestampWithTimeZone
;
import
org.h2.engine.Mode
;
import
org.h2.engine.Mode
;
import
org.h2.engine.SessionInterface
;
import
org.h2.engine.SessionInterface
;
...
@@ -181,9 +182,7 @@ public class DataType {
...
@@ -181,9 +182,7 @@ public class DataType {
g
=
null
;
g
=
null
;
}
}
GEOMETRY_CLASS
=
g
;
GEOMETRY_CLASS
=
g
;
}
static
{
add
(
Value
.
NULL
,
Types
.
NULL
,
add
(
Value
.
NULL
,
Types
.
NULL
,
new
DataType
(),
new
DataType
(),
new
String
[]{
"NULL"
},
new
String
[]{
"NULL"
},
...
@@ -294,7 +293,7 @@ public class DataType {
...
@@ -294,7 +293,7 @@ public class DataType {
createDate
(
ValueDate
.
PRECISION
,
ValueDate
.
PRECISION
,
createDate
(
ValueDate
.
PRECISION
,
ValueDate
.
PRECISION
,
"DATE"
,
false
,
0
,
0
),
"DATE"
,
false
,
0
,
0
),
new
String
[]{
"DATE"
},
new
String
[]{
"DATE"
},
// 24 for ValueDate, 32 for java.sql.Dat
a
// 24 for ValueDate, 32 for java.sql.Dat
e
56
56
);
);
add
(
Value
.
TIMESTAMP
,
Types
.
TIMESTAMP
,
add
(
Value
.
TIMESTAMP
,
Types
.
TIMESTAMP
,
...
@@ -314,7 +313,7 @@ public class DataType {
...
@@ -314,7 +313,7 @@ public class DataType {
"TIMESTAMP_TZ"
,
true
,
ValueTimestampTimeZone
.
DEFAULT_SCALE
,
"TIMESTAMP_TZ"
,
true
,
ValueTimestampTimeZone
.
DEFAULT_SCALE
,
ValueTimestampTimeZone
.
MAXIMUM_SCALE
),
ValueTimestampTimeZone
.
MAXIMUM_SCALE
),
new
String
[]{
"TIMESTAMP WITH TIME ZONE"
},
new
String
[]{
"TIMESTAMP WITH TIME ZONE"
},
// 26 for ValueTimestamp
Utc
, 32 for java.sql.Timestamp
// 26 for ValueTimestamp
TimeZone
, 32 for java.sql.Timestamp
58
58
);
);
add
(
Value
.
BYTES
,
Types
.
VARBINARY
,
add
(
Value
.
BYTES
,
Types
.
VARBINARY
,
...
@@ -384,6 +383,9 @@ public class DataType {
...
@@ -384,6 +383,9 @@ public class DataType {
new
String
[]{
"ENUM"
},
new
String
[]{
"ENUM"
},
48
48
);
);
for
(
int
i
=
Value
.
INTERVAL_YEAR
;
i
<=
Value
.
INTERVAL_MINUTE_TO_SECOND
;
i
++)
{
addInterval
(
i
);
}
for
(
Integer
i
:
TYPES_BY_VALUE_TYPE
.
keySet
())
{
for
(
Integer
i
:
TYPES_BY_VALUE_TYPE
.
keySet
())
{
Value
.
getOrder
(
i
);
Value
.
getOrder
(
i
);
}
}
...
@@ -412,6 +414,27 @@ public class DataType {
...
@@ -412,6 +414,27 @@ public class DataType {
);
);
}
}
private
static
void
addInterval
(
int
type
)
{
IntervalQualifier
qualifier
=
IntervalQualifier
.
valueOf
(
type
-
Value
.
INTERVAL_YEAR
);
String
name
=
qualifier
.
toString
();
DataType
dataType
=
new
DataType
();
dataType
.
prefix
=
"INTERVAL "
;
dataType
.
suffix
=
' '
+
name
;
dataType
.
supportsPrecision
=
true
;
dataType
.
defaultPrecision
=
ValueInterval
.
DEFAULT_PRECISION
;
dataType
.
maxPrecision
=
ValueInterval
.
MAXIMUM_PRECISION
;
if
(
qualifier
.
hasSeconds
())
{
dataType
.
supportsScale
=
true
;
dataType
.
defaultScale
=
ValueInterval
.
DEFAULT_SCALE
;
dataType
.
maxScale
=
ValueInterval
.
MAXIMUM_SCALE
;
}
dataType
.
defaultDisplaySize
=
Integer
.
MAX_VALUE
;
add
(
type
,
Types
.
OTHER
,
dataType
,
new
String
[]{(
"INTERVAL "
+
name
).
intern
()},
36
);
}
private
static
void
add
(
int
type
,
int
sqlType
,
private
static
void
add
(
int
type
,
int
sqlType
,
DataType
dataType
,
String
[]
names
,
int
memory
)
{
DataType
dataType
,
String
[]
names
,
int
memory
)
{
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
...
@@ -1286,6 +1309,16 @@ public class DataType {
...
@@ -1286,6 +1309,16 @@ public class DataType {
}
}
}
}
/**
* Check if the given value type is an interval type.
*
* @param type the value type
* @return true if the value type is an interval type
*/
public
static
boolean
isIntervalType
(
int
type
)
{
return
type
>=
Value
.
INTERVAL_YEAR
&&
type
<=
Value
.
INTERVAL_MINUTE_TO_SECOND
;
}
/**
/**
* Check if the given value type is a large object (BLOB or CLOB).
* Check if the given value type is a large object (BLOB or CLOB).
*
*
...
@@ -1321,6 +1354,19 @@ public class DataType {
...
@@ -1321,6 +1354,19 @@ public class DataType {
case
Value
.
INT
:
case
Value
.
INT
:
case
Value
.
LONG
:
case
Value
.
LONG
:
case
Value
.
SHORT
:
case
Value
.
SHORT
:
case
Value
.
INTERVAL_YEAR
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_DAY
:
case
Value
.
INTERVAL_HOUR
:
case
Value
.
INTERVAL_MINUTE
:
case
Value
.
INTERVAL_SECOND
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
case
Value
.
INTERVAL_DAY_TO_HOUR
:
case
Value
.
INTERVAL_DAY_TO_MINUTE
:
case
Value
.
INTERVAL_DAY_TO_SECOND
:
case
Value
.
INTERVAL_HOUR_TO_MINUTE
:
case
Value
.
INTERVAL_HOUR_TO_SECOND
:
case
Value
.
INTERVAL_MINUTE_TO_SECOND
:
return
true
;
return
true
;
case
Value
.
BOOLEAN
:
case
Value
.
BOOLEAN
:
case
Value
.
TIME
:
case
Value
.
TIME
:
...
@@ -1388,6 +1434,19 @@ public class DataType {
...
@@ -1388,6 +1434,19 @@ public class DataType {
case
Value
.
ARRAY
:
case
Value
.
ARRAY
:
case
Value
.
RESULT_SET
:
case
Value
.
RESULT_SET
:
case
Value
.
GEOMETRY
:
case
Value
.
GEOMETRY
:
case
Value
.
INTERVAL_YEAR
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_DAY
:
case
Value
.
INTERVAL_HOUR
:
case
Value
.
INTERVAL_MINUTE
:
case
Value
.
INTERVAL_SECOND
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
case
Value
.
INTERVAL_DAY_TO_HOUR
:
case
Value
.
INTERVAL_DAY_TO_MINUTE
:
case
Value
.
INTERVAL_DAY_TO_SECOND
:
case
Value
.
INTERVAL_HOUR_TO_MINUTE
:
case
Value
.
INTERVAL_HOUR_TO_SECOND
:
case
Value
.
INTERVAL_MINUTE_TO_SECOND
:
return
type
;
return
type
;
default
:
default
:
if
(
JdbcUtils
.
customDataTypesHandler
!=
null
)
{
if
(
JdbcUtils
.
customDataTypesHandler
!=
null
)
{
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
e403cc08
...
@@ -174,10 +174,75 @@ public abstract class Value {
...
@@ -174,10 +174,75 @@ public abstract class Value {
*/
*/
public
static
final
int
ENUM
=
25
;
public
static
final
int
ENUM
=
25
;
/**
* The value type for {@code INTERVAL YEAR} values.
*/
public
static
final
int
INTERVAL_YEAR
=
26
;
/**
* The value type for {@code INTERVAL MONTH} values.
*/
public
static
final
int
INTERVAL_MONTH
=
27
;
/**
* The value type for {@code INTERVAL DAY} values.
*/
public
static
final
int
INTERVAL_DAY
=
28
;
/**
* The value type for {@code INTERVAL HOUR} values.
*/
public
static
final
int
INTERVAL_HOUR
=
29
;
/**
* The value type for {@code INTERVAL MINUTE} values.
*/
public
static
final
int
INTERVAL_MINUTE
=
30
;
/**
* The value type for {@code INTERVAL SECOND} values.
*/
public
static
final
int
INTERVAL_SECOND
=
31
;
/**
* The value type for {@code INTERVAL YEAR TO MONTH} values.
*/
public
static
final
int
INTERVAL_YEAR_TO_MONTH
=
32
;
/**
* The value type for {@code INTERVAL DAY TO HOUR} values.
*/
public
static
final
int
INTERVAL_DAY_TO_HOUR
=
33
;
/**
* The value type for {@code INTERVAL DAY TO MINUTE} values.
*/
public
static
final
int
INTERVAL_DAY_TO_MINUTE
=
34
;
/**
* The value type for {@code INTERVAL DAY TO SECOND} values.
*/
public
static
final
int
INTERVAL_DAY_TO_SECOND
=
35
;
/**
* The value type for {@code INTERVAL HOUR TO MINUTE} values.
*/
public
static
final
int
INTERVAL_HOUR_TO_MINUTE
=
36
;
/**
* The value type for {@code INTERVAL HOUR TO SECOND} values.
*/
public
static
final
int
INTERVAL_HOUR_TO_SECOND
=
37
;
/**
* The value type for {@code INTERVAL MINUTE TO SECOND} values.
*/
public
static
final
int
INTERVAL_MINUTE_TO_SECOND
=
38
;
/**
/**
* The number of value types.
* The number of value types.
*/
*/
public
static
final
int
TYPE_COUNT
=
ENUM
;
public
static
final
int
TYPE_COUNT
=
INTERVAL_MINUTE_TO_SECOND
;
private
static
SoftReference
<
Value
[]>
softCache
;
private
static
SoftReference
<
Value
[]>
softCache
;
private
static
final
BigDecimal
MAX_LONG_DECIMAL
=
private
static
final
BigDecimal
MAX_LONG_DECIMAL
=
...
@@ -316,6 +381,32 @@ public abstract class Value {
...
@@ -316,6 +381,32 @@ public abstract class Value {
return
26_000
;
return
26_000
;
case
DOUBLE:
case
DOUBLE:
return
27_000
;
return
27_000
;
case
INTERVAL_YEAR:
return
28_000
;
case
INTERVAL_MONTH:
return
28_100
;
case
INTERVAL_YEAR_TO_MONTH:
return
28_200
;
case
INTERVAL_DAY:
return
29_000
;
case
INTERVAL_HOUR:
return
29_100
;
case
INTERVAL_DAY_TO_HOUR:
return
29_200
;
case
INTERVAL_MINUTE:
return
29_300
;
case
INTERVAL_HOUR_TO_MINUTE:
return
29_400
;
case
INTERVAL_DAY_TO_MINUTE:
return
29_500
;
case
INTERVAL_SECOND:
return
29_600
;
case
INTERVAL_MINUTE_TO_SECOND:
return
29_700
;
case
INTERVAL_HOUR_TO_SECOND:
return
29_800
;
case
INTERVAL_DAY_TO_SECOND:
return
29_900
;
case
TIME:
case
TIME:
return
30_000
;
return
30_000
;
case
DATE:
case
DATE:
...
...
h2/src/main/org/h2/value/ValueInterval.java
0 → 100644
浏览文件 @
e403cc08
package
org
.
h2
.
value
;
import
java.sql.PreparedStatement
;
import
java.sql.SQLException
;
import
org.h2.api.Interval
;
import
org.h2.api.IntervalQualifier
;
import
org.h2.util.DateTimeUtils
;
/**
* Implementation of the INTERVAL data type.
*/
public
class
ValueInterval
extends
Value
{
/**
* The default leading field precision for intervals.
*/
public
static
final
int
DEFAULT_PRECISION
=
2
;
/**
* The maximum leading field precision for intervals.
*/
public
static
final
int
MAXIMUM_PRECISION
=
18
;
/**
* The default scale for intervals with seconds.
*/
static
final
int
DEFAULT_SCALE
=
6
;
/**
* The maximum scale for intervals with seconds.
*/
public
static
final
int
MAXIMUM_SCALE
=
9
;
private
final
int
type
;
private
final
long
leading
;
private
final
long
remaining
;
/**
* @param qualifier
* qualifier
* @param leading
* value of leading field
* @param remaining
* values of all remaining fields
* @return interval value
*/
public
static
ValueInterval
from
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
)
{
return
(
ValueInterval
)
Value
.
cache
(
new
ValueInterval
(
qualifier
.
ordinal
()
+
INTERVAL_YEAR
,
leading
,
remaining
));
}
private
ValueInterval
(
int
type
,
long
leading
,
long
remaining
)
{
this
.
type
=
type
;
this
.
leading
=
leading
;
this
.
remaining
=
remaining
;
}
@Override
public
String
getSQL
()
{
return
getString
();
}
@Override
public
int
getType
()
{
return
type
;
}
@Override
public
long
getPrecision
()
{
return
MAXIMUM_PRECISION
;
}
@Override
public
int
getDisplaySize
()
{
// TODO Auto-generated method stub
return
0
;
}
@Override
public
String
getString
()
{
return
DateTimeUtils
.
intervalToString
(
getQualifier
(),
leading
,
remaining
);
}
@Override
public
Object
getObject
()
{
return
new
Interval
(
getQualifier
(),
leading
,
remaining
);
}
/**
* Returns the interval qualifier.
*
* @return the interval qualifier
*/
public
IntervalQualifier
getQualifier
()
{
return
IntervalQualifier
.
valueOf
(
type
-
INTERVAL_YEAR
);
}
@Override
public
void
set
(
PreparedStatement
prep
,
int
parameterIndex
)
throws
SQLException
{
prep
.
setString
(
parameterIndex
,
getString
());
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
result
=
prime
*
result
+
type
;
result
=
prime
*
result
+
(
int
)
(
leading
^
(
leading
>>>
32
));
result
=
prime
*
result
+
(
int
)
(
remaining
^
(
remaining
>>>
32
));
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(!(
obj
instanceof
ValueInterval
))
{
return
false
;
}
ValueInterval
other
=
(
ValueInterval
)
obj
;
return
type
==
other
.
type
&&
leading
==
other
.
leading
||
remaining
==
other
.
remaining
;
}
@Override
public
int
compareTypeSafe
(
Value
v
,
CompareMode
mode
)
{
ValueInterval
other
=
(
ValueInterval
)
v
;
int
cmp
=
Long
.
compare
(
leading
,
other
.
leading
);
if
(
cmp
==
0
)
{
cmp
=
Long
.
compare
(
remaining
,
other
.
remaining
);
}
return
cmp
;
}
@Override
public
Value
negate
()
{
return
from
(
getQualifier
(),
-
leading
,
remaining
);
}
}
h2/src/test/org/h2/test/scripts/TestScript.java
浏览文件 @
e403cc08
...
@@ -118,7 +118,7 @@ public class TestScript extends TestDb {
...
@@ -118,7 +118,7 @@ public class TestScript extends TestDb {
for
(
String
s
:
new
String
[]
{
"array"
,
"bigint"
,
"binary"
,
"blob"
,
for
(
String
s
:
new
String
[]
{
"array"
,
"bigint"
,
"binary"
,
"blob"
,
"boolean"
,
"char"
,
"clob"
,
"date"
,
"decimal"
,
decimal2
,
"double"
,
"enum"
,
"boolean"
,
"char"
,
"clob"
,
"date"
,
"decimal"
,
decimal2
,
"double"
,
"enum"
,
"geometry"
,
"identity"
,
"int"
,
"other"
,
"real"
,
"smallint"
,
"geometry"
,
"identity"
,
"int"
,
"
interval"
,
"
other"
,
"real"
,
"smallint"
,
"time"
,
"timestamp-with-timezone"
,
"timestamp"
,
"tinyint"
,
"time"
,
"timestamp-with-timezone"
,
"timestamp"
,
"tinyint"
,
"uuid"
,
"varchar"
,
"varchar-ignorecase"
})
{
"uuid"
,
"varchar"
,
"varchar-ignorecase"
})
{
testScript
(
"datatypes/"
+
s
+
".sql"
);
testScript
(
"datatypes/"
+
s
+
".sql"
);
...
...
h2/src/test/org/h2/test/scripts/datatypes/decimal_decimal.sql
浏览文件 @
e403cc08
...
@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
...
@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
>
ok
>
ok
select
*
from
information_schema
.
columns
where
table_name
=
'ORDERS'
;
select
*
from
information_schema
.
columns
where
table_name
=
'ORDERS'
;
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------
------------------ -------------
----- -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
>
SCRIPT
PUBLIC
ORDERS
COMPLETED
4
null
NO
3
1
1
1
10
0
null
Unicode
OFF
DECIMAL
0
FALSE
50
null
null
NUMERIC
(
1
)
NOT
NULL
null
>
SCRIPT
PUBLIC
ORDERS
COMPLETED
4
null
NO
3
1
1
1
10
0
null
null
null
Unicode
OFF
DECIMAL
0
FALSE
50
null
null
NUMERIC
(
1
)
NOT
NULL
null
>
SCRIPT
PUBLIC
ORDERS
CUSTOMER_ID
3
null
YES
12
10
10
10
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
CUSTOMER_ID
3
null
YES
12
10
10
10
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
NAME
2
null
YES
12
20
20
20
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
20
)
null
>
SCRIPT
PUBLIC
ORDERS
NAME
2
null
YES
12
20
20
20
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
20
)
null
>
SCRIPT
PUBLIC
ORDERS
ORDERID
1
null
YES
12
10
10
10
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
ORDERID
1
null
YES
12
10
10
10
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
VERIFIED
5
null
YES
3
1
1
1
10
0
null
Unicode
OFF
DECIMAL
1
FALSE
50
null
null
NUMERIC
(
1
)
null
>
SCRIPT
PUBLIC
ORDERS
VERIFIED
5
null
YES
3
1
1
1
10
0
null
null
null
Unicode
OFF
DECIMAL
1
FALSE
50
null
null
NUMERIC
(
1
)
null
>
rows
:
5
>
rows
:
5
drop
table
orders
;
drop
table
orders
;
...
...
h2/src/test/org/h2/test/scripts/datatypes/decimal_numeric.sql
浏览文件 @
e403cc08
...
@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
...
@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
>
ok
>
ok
select
*
from
information_schema
.
columns
where
table_name
=
'ORDERS'
;
select
*
from
information_schema
.
columns
where
table_name
=
'ORDERS'
;
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------
------------------ -------------
----- -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
>
SCRIPT
PUBLIC
ORDERS
COMPLETED
4
null
NO
2
1
1
1
10
0
null
Unicode
OFF
NUMERIC
0
FALSE
50
null
null
NUMERIC
(
1
)
NOT
NULL
null
>
SCRIPT
PUBLIC
ORDERS
COMPLETED
4
null
NO
2
1
1
1
10
0
null
null
null
Unicode
OFF
NUMERIC
0
FALSE
50
null
null
NUMERIC
(
1
)
NOT
NULL
null
>
SCRIPT
PUBLIC
ORDERS
CUSTOMER_ID
3
null
YES
12
10
10
10
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
CUSTOMER_ID
3
null
YES
12
10
10
10
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
NAME
2
null
YES
12
20
20
20
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
20
)
null
>
SCRIPT
PUBLIC
ORDERS
NAME
2
null
YES
12
20
20
20
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
20
)
null
>
SCRIPT
PUBLIC
ORDERS
ORDERID
1
null
YES
12
10
10
10
10
0
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
ORDERID
1
null
YES
12
10
10
10
10
0
null
null
null
Unicode
OFF
VARCHAR
1
FALSE
50
null
null
VARCHAR
(
10
)
null
>
SCRIPT
PUBLIC
ORDERS
VERIFIED
5
null
YES
2
1
1
1
10
0
null
Unicode
OFF
NUMERIC
1
FALSE
50
null
null
NUMERIC
(
1
)
null
>
SCRIPT
PUBLIC
ORDERS
VERIFIED
5
null
YES
2
1
1
1
10
0
null
null
null
Unicode
OFF
NUMERIC
1
FALSE
50
null
null
NUMERIC
(
1
)
null
>
rows
:
5
>
rows
:
5
drop
table
orders
;
drop
table
orders
;
...
...
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
浏览文件 @
e403cc08
...
@@ -242,13 +242,13 @@ SELECT * FROM V3;
...
@@ -242,13 +242,13 @@ SELECT * FROM V3;
>>
-
1
>>
-
1
SELECT
*
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
COLUMN_NAME
=
'E'
ORDER
BY
TABLE_NAME
;
SELECT
*
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
COLUMN_NAME
=
'E'
ORDER
BY
TABLE_NAME
;
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------- ----------------
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------
------------------ -------------
----- -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------- ----------------
>
SCRIPT
PUBLIC
TEST
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
TEST
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
V
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
V
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
V1
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V1
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V2
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V2
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V3
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V3
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
rows
(
ordered
):
5
>
rows
(
ordered
):
5
DROP
VIEW
V
;
DROP
VIEW
V
;
...
...
h2/src/test/org/h2/test/scripts/datatypes/interval.sql
0 → 100644
浏览文件 @
e403cc08
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE
TABLE
TEST
(
I01
INTERVAL
YEAR
,
I02
INTERVAL
MONTH
,
I03
INTERVAL
DAY
,
I04
INTERVAL
HOUR
,
I05
INTERVAL
MINUTE
,
I06
INTERVAL
SECOND
,
I07
INTERVAL
YEAR
TO
MONTH
,
I08
INTERVAL
DAY
TO
HOUR
,
I09
INTERVAL
DAY
TO
MINUTE
,
I10
INTERVAL
DAY
TO
SECOND
,
I11
INTERVAL
HOUR
TO
MINUTE
,
I12
INTERVAL
HOUR
TO
SECOND
,
I13
INTERVAL
MINUTE
TO
SECOND
,
J01
INTERVAL
YEAR
(
5
),
J02
INTERVAL
MONTH
(
5
),
J03
INTERVAL
DAY
(
5
),
J04
INTERVAL
HOUR
(
5
),
J05
INTERVAL
MINUTE
(
5
),
J06
INTERVAL
SECOND
(
5
,
9
),
J07
INTERVAL
YEAR
(
5
)
TO
MONTH
,
J08
INTERVAL
DAY
(
5
)
TO
HOUR
,
J09
INTERVAL
DAY
(
5
)
TO
MINUTE
,
J10
INTERVAL
DAY
(
5
)
TO
SECOND
(
9
),
J11
INTERVAL
HOUR
(
5
)
TO
MINUTE
,
J12
INTERVAL
HOUR
(
5
)
TO
SECOND
(
9
),
J13
INTERVAL
MINUTE
(
5
)
TO
SECOND
(
9
));
>
ok
SELECT
COLUMN_NAME
,
DATA_TYPE
,
TYPE_NAME
,
COLUMN_TYPE
,
NUMERIC_PRECISION
,
NUMERIC_SCALE
,
DATETIME_PRECISION
,
INTERVAL_TYPE
,
INTERVAL_PRECISION
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
TABLE_NAME
=
'TEST'
ORDER
BY
ORDINAL_POSITION
;
>
COLUMN_NAME
DATA_TYPE
TYPE_NAME
COLUMN_TYPE
NUMERIC_PRECISION
NUMERIC_SCALE
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
>
----------- --------- --------- ------------------------------- ----------------- ------------- ------------------ ---------------------- ------------------
>
I01
1111
INTERVAL
INTERVAL
YEAR
2
0
null
YEAR
2
>
I02
1111
INTERVAL
INTERVAL
MONTH
2
0
null
MONTH
2
>
I03
1111
INTERVAL
INTERVAL
DAY
2
0
null
DAY
2
>
I04
1111
INTERVAL
INTERVAL
HOUR
2
0
null
HOUR
2
>
I05
1111
INTERVAL
INTERVAL
MINUTE
2
0
null
MINUTE
2
>
I06
1111
INTERVAL
INTERVAL
SECOND
2
6
6
SECOND
2
>
I07
1111
INTERVAL
INTERVAL
YEAR
TO
MONTH
2
0
null
YEAR
TO
MONTH
2
>
I08
1111
INTERVAL
INTERVAL
DAY
TO
HOUR
2
0
null
DAY
TO
HOUR
2
>
I09
1111
INTERVAL
INTERVAL
DAY
TO
MINUTE
2
0
null
DAY
TO
MINUTE
2
>
I10
1111
INTERVAL
INTERVAL
DAY
TO
SECOND
2
6
6
DAY
TO
SECOND
2
>
I11
1111
INTERVAL
INTERVAL
HOUR
TO
MINUTE
2
0
null
HOUR
TO
MINUTE
2
>
I12
1111
INTERVAL
INTERVAL
HOUR
TO
SECOND
2
6
6
HOUR
TO
SECOND
2
>
I13
1111
INTERVAL
INTERVAL
MINUTE
TO
SECOND
2
6
6
MINUTE
TO
SECOND
2
>
J01
1111
INTERVAL
INTERVAL
YEAR
(
5
)
5
0
null
YEAR
(
5
)
5
>
J02
1111
INTERVAL
INTERVAL
MONTH
(
5
)
5
0
null
MONTH
(
5
)
5
>
J03
1111
INTERVAL
INTERVAL
DAY
(
5
)
5
0
null
DAY
(
5
)
5
>
J04
1111
INTERVAL
INTERVAL
HOUR
(
5
)
5
0
null
HOUR
(
5
)
5
>
J05
1111
INTERVAL
INTERVAL
MINUTE
(
5
)
5
0
null
MINUTE
(
5
)
5
>
J06
1111
INTERVAL
INTERVAL
SECOND
(
5
,
9
)
5
6
6
SECOND
(
5
,
9
)
5
>
J07
1111
INTERVAL
INTERVAL
YEAR
(
5
)
TO
MONTH
5
0
null
YEAR
(
5
)
TO
MONTH
5
>
J08
1111
INTERVAL
INTERVAL
DAY
(
5
)
TO
HOUR
5
0
null
DAY
(
5
)
TO
HOUR
5
>
J09
1111
INTERVAL
INTERVAL
DAY
(
5
)
TO
MINUTE
5
0
null
DAY
(
5
)
TO
MINUTE
5
>
J10
1111
INTERVAL
INTERVAL
DAY
(
5
)
TO
SECOND
(
9
)
5
6
6
DAY
(
5
)
TO
SECOND
(
9
)
5
>
J11
1111
INTERVAL
INTERVAL
HOUR
(
5
)
TO
MINUTE
5
0
null
HOUR
(
5
)
TO
MINUTE
5
>
J12
1111
INTERVAL
INTERVAL
HOUR
(
5
)
TO
SECOND
(
9
)
5
6
6
HOUR
(
5
)
TO
SECOND
(
9
)
5
>
J13
1111
INTERVAL
INTERVAL
MINUTE
(
5
)
TO
SECOND
(
9
)
5
6
6
MINUTE
(
5
)
TO
SECOND
(
9
)
5
>
rows
(
ordered
):
26
DROP
TABLE
TEST
;
>
ok
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
浏览文件 @
e403cc08
...
@@ -12,8 +12,10 @@ import java.util.Calendar;
...
@@ -12,8 +12,10 @@ import java.util.Calendar;
import
java.util.GregorianCalendar
;
import
java.util.GregorianCalendar
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
org.h2.api.IntervalQualifier
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.value.ValueInterval
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestamp
;
/**
/**
...
@@ -47,6 +49,7 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -47,6 +49,7 @@ public class TestDateTimeUtils extends TestBase {
testDateValueFromDenormalizedDate
();
testDateValueFromDenormalizedDate
();
testUTC2Value
(
false
);
testUTC2Value
(
false
);
testConvertScale
();
testConvertScale
();
testParseInterval
();
}
}
private
void
testParseTimeNanosDB2Format
()
{
private
void
testParseTimeNanosDB2Format
()
{
...
@@ -194,4 +197,74 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -194,4 +197,74 @@ public class TestDateTimeUtils extends TestBase {
assertEquals
(
101_000_000_000L
,
DateTimeUtils
.
convertScale
(
100_999_999_999L
,
0
));
assertEquals
(
101_000_000_000L
,
DateTimeUtils
.
convertScale
(
100_999_999_999L
,
0
));
}
}
private
void
testParseInterval
()
{
testParseIntervalSimple
(
IntervalQualifier
.
YEAR
);
testParseIntervalSimple
(
IntervalQualifier
.
MONTH
);
testParseIntervalSimple
(
IntervalQualifier
.
DAY
);
testParseIntervalSimple
(
IntervalQualifier
.
HOUR
);
testParseIntervalSimple
(
IntervalQualifier
.
MINUTE
);
testParseIntervalSimple
(
IntervalQualifier
.
SECOND
);
testParseInterval
(
IntervalQualifier
.
YEAR_TO_MONTH
,
10
,
0
,
"10"
,
"10-0"
);
testParseInterval
(
IntervalQualifier
.
YEAR_TO_MONTH
,
10
,
11
,
"10-11"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_HOUR
,
10
,
0
,
"10"
,
"10 00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_HOUR
,
10
,
11
,
"10 11"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_MINUTE
,
10
,
0
,
"10"
,
"10 00:00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_MINUTE
,
10
,
11
*
60
,
"10 11"
,
"10 11:00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_MINUTE
,
10
,
11
*
60
+
12
,
"10 11:12"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
10
,
0
,
"10 00:00:00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
10
,
11
*
3_600_000_000_000L
,
"10 11"
,
"10 11:00:00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
10
,
11
*
3_600_000_000_000L
+
12
*
60_000_000_000L
,
"10 11:12"
,
"10 11:12:00"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
10
,
11
*
3_600_000_000_000L
+
12
*
60_000_000_000L
+
13_000_000_000L
,
"10 11:12:13"
);
testParseInterval
(
IntervalQualifier
.
DAY_TO_SECOND
,
10
,
11
*
3_600_000_000_000L
+
12
*
60_000_000_000L
+
13_123_456_789L
,
"10 11:12:13.123456789"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_MINUTE
,
10
,
0
,
"10"
,
"10:00"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_MINUTE
,
10
,
11
,
"10:11"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_SECOND
,
10
,
0
,
"10"
,
"10:00:00"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_SECOND
,
10
,
11
*
60_000_000_000L
,
"10:11"
,
"10:11:00"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_SECOND
,
10
,
11
*
60_000_000_000L
+
12_000_000_000L
,
"10:11:12"
);
testParseInterval
(
IntervalQualifier
.
HOUR_TO_SECOND
,
10
,
11
*
60_000_000_000L
+
12_123_456_789L
,
"10:11:12.123456789"
);
testParseInterval
(
IntervalQualifier
.
MINUTE_TO_SECOND
,
10
,
0
,
"10"
,
"10:00"
);
testParseInterval
(
IntervalQualifier
.
MINUTE_TO_SECOND
,
10
,
11_000_000_000L
,
"10:11"
,
"10:11"
);
testParseInterval
(
IntervalQualifier
.
MINUTE_TO_SECOND
,
10
,
11_123_456_789L
,
"10:11.123456789"
);
}
private
void
testParseIntervalSimple
(
IntervalQualifier
qualifier
)
{
testParseInterval
(
qualifier
,
10
,
0
,
"10"
);
}
private
void
testParseInterval
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
,
String
s
)
{
testParseInterval
(
qualifier
,
leading
,
remaining
,
s
,
s
);
}
private
void
testParseInterval
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
,
String
s
,
String
full
)
{
testParseIntervalImpl
(
qualifier
,
leading
,
remaining
,
false
,
s
,
full
);
testParseIntervalImpl
(
qualifier
,
-
leading
,
remaining
,
true
,
s
,
full
);
}
private
void
testParseIntervalImpl
(
IntervalQualifier
qualifier
,
long
leading
,
long
remaining
,
boolean
negative
,
String
s
,
String
full
)
{
ValueInterval
expected
=
ValueInterval
.
from
(
qualifier
,
leading
,
remaining
);
assertEquals
(
expected
,
DateTimeUtils
.
parseInterval
(
qualifier
,
negative
,
s
));
StringBuilder
b
=
new
StringBuilder
();
b
.
append
(
"INTERVAL "
);
if
(
negative
)
{
b
.
append
(
'-'
);
}
b
.
append
(
'\''
).
append
(
full
).
append
(
"' "
).
append
(
qualifier
);
assertEquals
(
b
.
toString
(),
expected
.
getString
());
}
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论