Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
9e5d9644
提交
9e5d9644
authored
2月 18, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into generated_keys
上级
0581dbd0
8556fd23
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
30 个修改的文件
包含
1116 行增加
和
644 行删除
+1116
-644
help.csv
h2/src/docsrc/help/help.csv
+39
-5
Constraint.java
h2/src/main/org/h2/constraint/Constraint.java
+0
-1
AggregateDataMedian.java
h2/src/main/org/h2/expression/AggregateDataMedian.java
+2
-1
Function.java
h2/src/main/org/h2/expression/Function.java
+96
-74
IndexCursor.java
h2/src/main/org/h2/index/IndexCursor.java
+3
-4
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+22
-20
DataReader.java
h2/src/main/org/h2/store/DataReader.java
+1
-1
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+1
-1
ChangeFileEncryption.java
h2/src/main/org/h2/tools/ChangeFileEncryption.java
+2
-1
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+41
-39
ToChar.java
h2/src/main/org/h2/util/ToChar.java
+180
-106
ToDateParser.java
h2/src/main/org/h2/util/ToDateParser.java
+202
-42
ToDateTokenizer.java
h2/src/main/org/h2/util/ToDateTokenizer.java
+82
-111
Transfer.java
h2/src/main/org/h2/value/Transfer.java
+1
-17
ValueLobDb.java
h2/src/main/org/h2/value/ValueLobDb.java
+10
-0
ValueTimestampTimeZone.java
h2/src/main/org/h2/value/ValueTimestampTimeZone.java
+24
-42
TestBase.java
h2/src/test/org/h2/test/TestBase.java
+66
-10
TestFunctions.java
h2/src/test/org/h2/test/db/TestFunctions.java
+92
-70
TestOutOfMemory.java
h2/src/test/org/h2/test/db/TestOutOfMemory.java
+88
-60
TestLobApi.java
h2/src/test/org/h2/test/jdbc/TestLobApi.java
+27
-4
TestScript.java
h2/src/test/org/h2/test/scripts/TestScript.java
+1
-1
dateadd.sql
...est/org/h2/test/scripts/functions/timeanddate/dateadd.sql
+12
-0
datediff.sql
...st/org/h2/test/scripts/functions/timeanddate/datediff.sql
+16
-0
extract.sql
...est/org/h2/test/scripts/functions/timeanddate/extract.sql
+14
-0
TestMVStoreBenchmark.java
h2/src/test/org/h2/test/store/TestMVStoreBenchmark.java
+0
-8
TestFuzzOptimizations.java
h2/src/test/org/h2/test/synth/TestFuzzOptimizations.java
+22
-17
TestClearReferences.java
h2/src/test/org/h2/test/unit/TestClearReferences.java
+3
-0
TestDateTimeUtils.java
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
+58
-4
TestTimeStampWithTimeZone.java
h2/src/test/org/h2/test/unit/TestTimeStampWithTimeZone.java
+9
-3
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+2
-2
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
9e5d9644
...
@@ -2300,9 +2300,9 @@ Each table has a pseudo-column named ""_ROWID_"" that contains the unique row id
...
@@ -2300,9 +2300,9 @@ Each table has a pseudo-column named ""_ROWID_"" that contains the unique row id
"
"
"Other Grammar","Time","
"Other Grammar","Time","
TIME 'hh:mm:ss'
TIME 'hh:mm:ss
[.nnnnnnnnn]
'
","
","
A time literal. A value is between
plus and minus 2 million hours
A time literal. A value is between
0:00:00 and 23:59:59.999999999
and has nanosecond resolution.
and has nanosecond resolution.
","
","
TIME '23:59:59'
TIME '23:59:59'
...
@@ -2318,6 +2318,19 @@ minimum and maximum years are 0001 and 9999.
...
@@ -2318,6 +2318,19 @@ minimum and maximum years are 0001 and 9999.
TIMESTAMP '2005-12-31 23:59:59'
TIMESTAMP '2005-12-31 23:59:59'
"
"
"Other Grammar","Timestamp with time zone","
TIMESTAMP 'yyyy-MM-dd hh:mm:ss[.nnnnnnnnn]
[Z | { - | + } timeZoneOffsetString | timeZoneNameString ]'
","
A timestamp with time zone literal.
If name of time zone is specified it will be converted to time zone offset.
","
TIMESTAMP WITH TIME ZONE '2005-12-31 23:59:59Z'
TIMESTAMP WITH TIME ZONE '2005-12-31 23:59:59-10:00'
TIMESTAMP WITH TIME ZONE '2005-12-31 23:59:59.123+05'
TIMESTAMP WITH TIME ZONE '2005-12-31 23:59:59.123456789 Europe/London'
"
"Other Grammar","Value","
"Other Grammar","Value","
string | dollarQuotedString | numeric | date | time | timestamp | boolean | bytes | array | null
string | dollarQuotedString | numeric | date | time | timestamp | boolean | bytes | array | null
","
","
...
@@ -3671,7 +3684,7 @@ CURRENT_TIMESTAMP()
...
@@ -3671,7 +3684,7 @@ CURRENT_TIMESTAMP()
Adds units to a date-time value. The string indicates the unit.
Adds units to a date-time value. The string indicates the unit.
Use negative values to subtract units.
Use negative values to subtract units.
addIntLong may be a long value when manipulating milliseconds,
addIntLong may be a long value when manipulating milliseconds,
otherwise it'
s range is restricted to int.
microseconds, or nanoseconds otherwise it
s range is restricted to int.
The same units as in the EXTRACT function are supported.
The same units as in the EXTRACT function are supported.
This method returns a value with the same type as specified value if unit is compatible with this value.
This method returns a value with the same type as specified value if unit is compatible with this value.
If specified unit is a HOUR, MINUTE, SECOND, MILLISECOND, etc and value is a DATE value DATEADD returns combined TIMESTAMP.
If specified unit is a HOUR, MINUTE, SECOND, MILLISECOND, etc and value is a DATE value DATEADD returns combined TIMESTAMP.
...
@@ -3727,11 +3740,13 @@ DAY_OF_YEAR(CREATED)
...
@@ -3727,11 +3740,13 @@ DAY_OF_YEAR(CREATED)
"Functions (Time and Date)","EXTRACT","
"Functions (Time and Date)","EXTRACT","
EXTRACT ( { YEAR | YY | MONTH | MM | QUARTER | WEEK | ISO_WEEK
EXTRACT ( { YEAR | YY | MONTH | MM | QUARTER | WEEK | ISO_WEEK
| DAY | DD | DAY_OF_YEAR | DOY
| DAY | DD | DAY_OF_YEAR | DOY
| HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS }
| HOUR | HH | MINUTE | MI | SECOND | SS | EPOCH
| MILLISECOND | MS | MICROSECOND | MCS | NANOSECOND | NS }
FROM timestamp )
FROM timestamp )
","
","
Returns a specific value from a timestamps.
Returns a specific value from a timestamps.
This method returns an int.
This method returns a numeric value with EPOCH unit and
an int for all other time units.
","
","
EXTRACT(SECOND FROM CURRENT_TIMESTAMP)
EXTRACT(SECOND FROM CURRENT_TIMESTAMP)
"
"
...
@@ -3820,6 +3835,17 @@ This method uses the current system locale.
...
@@ -3820,6 +3835,17 @@ This method uses the current system locale.
WEEK(CREATED)
WEEK(CREATED)
"
"
"Functions (Time and Date)","ISO_WEEK","
ISO_WEEK(timestamp)
","
Returns the week (1-53) from a timestamp.
This method uses the ISO definition when
first week of year should have at least four days
and week is started with Monday.
","
ISO_WEEK(CREATED)
"
"Functions (Time and Date)","YEAR","
"Functions (Time and Date)","YEAR","
YEAR(timestamp)
YEAR(timestamp)
","
","
...
@@ -3828,6 +3854,14 @@ Returns the year from a timestamp.
...
@@ -3828,6 +3854,14 @@ Returns the year from a timestamp.
YEAR(CREATED)
YEAR(CREATED)
"
"
"Functions (Time and Date)","ISO_YEAR","
ISO_YEAR(timestamp)
","
Returns the ISO week year from a timestamp.
","
ISO_YEAR(CREATED)
"
"Functions (System)","ARRAY_GET","
"Functions (System)","ARRAY_GET","
ARRAY_GET(arrayExpression, indexExpression)
ARRAY_GET(arrayExpression, indexExpression)
","
","
...
...
h2/src/main/org/h2/constraint/Constraint.java
浏览文件 @
9e5d9644
...
@@ -10,7 +10,6 @@ import org.h2.engine.DbObject;
...
@@ -10,7 +10,6 @@ import org.h2.engine.DbObject;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.index.Index
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Schema
;
...
...
h2/src/main/org/h2/expression/AggregateDataMedian.java
浏览文件 @
9e5d9644
...
@@ -224,7 +224,8 @@ class AggregateDataMedian extends AggregateData {
...
@@ -224,7 +224,8 @@ class AggregateDataMedian extends AggregateData {
case
Value
.
DOUBLE
:
case
Value
.
DOUBLE
:
return
ValueDouble
.
get
((
v0
.
getFloat
()
+
v1
.
getDouble
())
/
2
);
return
ValueDouble
.
get
((
v0
.
getFloat
()
+
v1
.
getDouble
())
/
2
);
case
Value
.
TIME
:
{
case
Value
.
TIME
:
{
return
ValueTime
.
fromMillis
((
v0
.
getTime
().
getTime
()
+
v1
.
getTime
().
getTime
())
/
2
);
ValueTime
t0
=
(
ValueTime
)
v0
.
convertTo
(
Value
.
TIME
),
t1
=
(
ValueTime
)
v1
.
convertTo
(
Value
.
TIME
);
return
ValueTime
.
fromNanos
((
t0
.
getNanos
()
+
t1
.
getNanos
())
/
2
);
}
}
case
Value
.
DATE
:
{
case
Value
.
DATE
:
{
ValueDate
d0
=
(
ValueDate
)
v0
.
convertTo
(
Value
.
DATE
),
d1
=
(
ValueDate
)
v1
.
convertTo
(
Value
.
DATE
);
ValueDate
d0
=
(
ValueDate
)
v0
.
convertTo
(
Value
.
DATE
),
d1
=
(
ValueDate
)
v1
.
convertTo
(
Value
.
DATE
);
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
9e5d9644
差异被折叠。
点击展开。
h2/src/main/org/h2/index/IndexCursor.java
浏览文件 @
9e5d9644
...
@@ -148,6 +148,9 @@ public class IndexCursor implements Cursor {
...
@@ -148,6 +148,9 @@ public class IndexCursor implements Cursor {
}
}
}
}
}
}
if
(
inColumn
!=
null
)
{
start
=
table
.
getTemplateRow
();
}
}
}
/**
/**
...
@@ -326,7 +329,6 @@ public class IndexCursor implements Cursor {
...
@@ -326,7 +329,6 @@ public class IndexCursor implements Cursor {
while
(
inResult
.
next
())
{
while
(
inResult
.
next
())
{
Value
v
=
inResult
.
currentRow
()[
0
];
Value
v
=
inResult
.
currentRow
()[
0
];
if
(
v
!=
ValueNull
.
INSTANCE
)
{
if
(
v
!=
ValueNull
.
INSTANCE
)
{
v
=
inColumn
.
convert
(
v
);
if
(
inResultTested
==
null
)
{
if
(
inResultTested
==
null
)
{
inResultTested
=
new
HashSet
<>();
inResultTested
=
new
HashSet
<>();
}
}
...
@@ -342,9 +344,6 @@ public class IndexCursor implements Cursor {
...
@@ -342,9 +344,6 @@ public class IndexCursor implements Cursor {
private
void
find
(
Value
v
)
{
private
void
find
(
Value
v
)
{
v
=
inColumn
.
convert
(
v
);
v
=
inColumn
.
convert
(
v
);
int
id
=
inColumn
.
getColumnId
();
int
id
=
inColumn
.
getColumnId
();
if
(
start
==
null
)
{
start
=
table
.
getTemplateRow
();
}
start
.
setValue
(
id
,
v
);
start
.
setValue
(
id
,
v
);
cursor
=
index
.
find
(
tableFilter
,
start
,
start
);
cursor
=
index
.
find
(
tableFilter
,
start
,
start
);
}
}
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
9e5d9644
...
@@ -2450,27 +2450,27 @@ public final class MVStore {
...
@@ -2450,27 +2450,27 @@ public final class MVStore {
* needed.
* needed.
*/
*/
void
writeInBackground
()
{
void
writeInBackground
()
{
if
(
closed
)
{
try
{
return
;
if
(
closed
)
{
}
return
;
}
// could also commit when there are many unsaved pages,
// could also commit when there are many unsaved pages,
// but according to a test it doesn't really help
// but according to a test it doesn't really help
long
time
=
getTimeSinceCreation
();
long
time
=
getTimeSinceCreation
();
if
(
time
<=
lastCommitTime
+
autoCommitDelay
)
{
if
(
time
<=
lastCommitTime
+
autoCommitDelay
)
{
return
;
}
if
(
hasUnsavedChanges
())
{
try
{
commitAndSave
();
}
catch
(
Throwable
e
)
{
handleException
(
e
);
return
;
return
;
}
}
}
if
(
hasUnsavedChanges
())
{
if
(
autoCompactFillRate
>
0
)
{
try
{
try
{
commitAndSave
();
}
catch
(
Throwable
e
)
{
handleException
(
e
);
return
;
}
}
if
(
autoCompactFillRate
>
0
)
{
// whether there were file read or write operations since
// whether there were file read or write operations since
// the last time
// the last time
boolean
fileOps
;
boolean
fileOps
;
...
@@ -2486,9 +2486,9 @@ public final class MVStore {
...
@@ -2486,9 +2486,9 @@ public final class MVStore {
// in the bookkeeping?
// in the bookkeeping?
compact
(
fillRate
,
autoCommitMemory
);
compact
(
fillRate
,
autoCommitMemory
);
autoCompactLastFileOpCount
=
fileStore
.
getWriteCount
()
+
fileStore
.
getReadCount
();
autoCompactLastFileOpCount
=
fileStore
.
getWriteCount
()
+
fileStore
.
getReadCount
();
}
catch
(
Throwable
e
)
{
handleException
(
e
);
}
}
}
catch
(
Throwable
e
)
{
handleException
(
e
);
}
}
}
}
...
@@ -2497,7 +2497,9 @@ public final class MVStore {
...
@@ -2497,7 +2497,9 @@ public final class MVStore {
try
{
try
{
backgroundExceptionHandler
.
uncaughtException
(
null
,
ex
);
backgroundExceptionHandler
.
uncaughtException
(
null
,
ex
);
}
catch
(
Throwable
ignore
)
{
}
catch
(
Throwable
ignore
)
{
ex
.
addSuppressed
(
ignore
);
if
(
ex
!=
ignore
)
{
// OOME may be the same
ex
.
addSuppressed
(
ignore
);
}
}
}
}
}
}
}
...
...
h2/src/main/org/h2/store/DataReader.java
浏览文件 @
9e5d9644
...
@@ -171,7 +171,7 @@ public class DataReader extends Reader {
...
@@ -171,7 +171,7 @@ public class DataReader extends Reader {
int
i
=
0
;
int
i
=
0
;
try
{
try
{
for
(;
i
<
len
;
i
++)
{
for
(;
i
<
len
;
i
++)
{
buff
[
i
]
=
readChar
();
buff
[
off
+
i
]
=
readChar
();
}
}
return
len
;
return
len
;
}
catch
(
EOFException
e
)
{
}
catch
(
EOFException
e
)
{
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
9e5d9644
...
@@ -1615,7 +1615,7 @@ public class MetaTable extends Table {
...
@@ -1615,7 +1615,7 @@ public class MetaTable extends Table {
if
(
constraintType
==
Constraint
.
Type
.
CHECK
)
{
if
(
constraintType
==
Constraint
.
Type
.
CHECK
)
{
checkExpression
=
((
ConstraintCheck
)
constraint
).
getExpression
().
getSQL
();
checkExpression
=
((
ConstraintCheck
)
constraint
).
getExpression
().
getSQL
();
}
else
if
(
constraintType
==
Constraint
.
Type
.
UNIQUE
||
}
else
if
(
constraintType
==
Constraint
.
Type
.
UNIQUE
||
constraintType
==
Constraint
.
Type
.
PRIMARY_KEY
)
{
constraintType
==
Constraint
.
Type
.
PRIMARY_KEY
)
{
indexColumns
=
((
ConstraintUnique
)
constraint
).
getColumns
();
indexColumns
=
((
ConstraintUnique
)
constraint
).
getColumns
();
}
else
if
(
constraintType
==
Constraint
.
Type
.
REFERENTIAL
)
{
}
else
if
(
constraintType
==
Constraint
.
Type
.
REFERENTIAL
)
{
indexColumns
=
((
ConstraintReferential
)
constraint
).
getColumns
();
indexColumns
=
((
ConstraintReferential
)
constraint
).
getColumns
();
...
...
h2/src/main/org/h2/tools/ChangeFileEncryption.java
浏览文件 @
9e5d9644
...
@@ -224,7 +224,8 @@ public class ChangeFileEncryption extends Tool {
...
@@ -224,7 +224,8 @@ public class ChangeFileEncryption extends Tool {
try
(
FileChannel
fileIn
=
getFileChannel
(
fileName
,
"r"
,
decryptKey
)){
try
(
FileChannel
fileIn
=
getFileChannel
(
fileName
,
"r"
,
decryptKey
)){
try
(
InputStream
inStream
=
new
FileChannelInputStream
(
fileIn
,
true
))
{
try
(
InputStream
inStream
=
new
FileChannelInputStream
(
fileIn
,
true
))
{
FileUtils
.
delete
(
temp
);
FileUtils
.
delete
(
temp
);
try
(
OutputStream
outStream
=
new
FileChannelOutputStream
(
getFileChannel
(
temp
,
"rw"
,
encryptKey
),
true
))
{
try
(
OutputStream
outStream
=
new
FileChannelOutputStream
(
getFileChannel
(
temp
,
"rw"
,
encryptKey
),
true
))
{
byte
[]
buffer
=
new
byte
[
4
*
1024
];
byte
[]
buffer
=
new
byte
[
4
*
1024
];
long
remaining
=
fileIn
.
size
();
long
remaining
=
fileIn
.
size
();
long
total
=
remaining
;
long
total
=
remaining
;
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
9e5d9644
...
@@ -36,7 +36,7 @@ public class DateTimeUtils {
...
@@ -36,7 +36,7 @@ public class DateTimeUtils {
* The number of milliseconds per day.
* The number of milliseconds per day.
*/
*/
public
static
final
long
MILLIS_PER_DAY
=
24
*
60
*
60
*
1000L
;
public
static
final
long
MILLIS_PER_DAY
=
24
*
60
*
60
*
1000L
;
/**
/**
* The number of seconds per day.
* The number of seconds per day.
*/
*/
...
@@ -85,6 +85,11 @@ public class DateTimeUtils {
...
@@ -85,6 +85,11 @@ public class DateTimeUtils {
private
static
final
ThreadLocal
<
GregorianCalendar
>
CACHED_CALENDAR_NON_DEFAULT_TIMEZONE
=
private
static
final
ThreadLocal
<
GregorianCalendar
>
CACHED_CALENDAR_NON_DEFAULT_TIMEZONE
=
new
ThreadLocal
<>();
new
ThreadLocal
<>();
/**
* Cached local time zone.
*/
private
static
volatile
TimeZone
timeZone
;
/**
/**
* Observed JVM behaviour is that if the timezone of the host computer is
* Observed JVM behaviour is that if the timezone of the host computer is
* changed while the JVM is running, the zone offset does not change but
* changed while the JVM is running, the zone offset does not change but
...
@@ -100,12 +105,26 @@ public class DateTimeUtils {
...
@@ -100,12 +105,26 @@ public class DateTimeUtils {
// utility class
// utility class
}
}
/**
* Returns local time zone.
*
* @return local time zone
*/
private
static
TimeZone
getTimeZone
()
{
TimeZone
tz
=
timeZone
;
if
(
tz
==
null
)
{
timeZone
=
tz
=
TimeZone
.
getDefault
();
}
return
tz
;
}
/**
/**
* Reset the cached calendar for default timezone, for example after
* Reset the cached calendar for default timezone, for example after
* changing the default timezone.
* changing the default timezone.
*/
*/
public
static
void
resetCalendar
()
{
public
static
void
resetCalendar
()
{
CACHED_CALENDAR
.
remove
();
CACHED_CALENDAR
.
remove
();
timeZone
=
null
;
zoneOffsetMillis
=
DateTimeUtils
.
createGregorianCalendar
().
get
(
Calendar
.
ZONE_OFFSET
);
zoneOffsetMillis
=
DateTimeUtils
.
createGregorianCalendar
().
get
(
Calendar
.
ZONE_OFFSET
);
}
}
...
@@ -628,20 +647,6 @@ public class DateTimeUtils {
...
@@ -628,20 +647,6 @@ public class DateTimeUtils {
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
);
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
);
}
}
/**
* Get the year (positive or negative) from a calendar.
*
* @param calendar the calendar
* @return the year
*/
private
static
int
getYear
(
Calendar
calendar
)
{
int
year
=
calendar
.
get
(
Calendar
.
YEAR
);
if
(
calendar
.
get
(
Calendar
.
ERA
)
==
GregorianCalendar
.
BC
)
{
year
=
1
-
year
;
}
return
year
;
}
/**
/**
* Get the number of milliseconds since 1970-01-01 in the local timezone,
* Get the number of milliseconds since 1970-01-01 in the local timezone,
* but without daylight saving time into account.
* but without daylight saving time into account.
...
@@ -921,19 +926,6 @@ public class DateTimeUtils {
...
@@ -921,19 +926,6 @@ public class DateTimeUtils {
return
new
Date
(
millis
);
return
new
Date
(
millis
);
}
}
/**
* Convert an encoded date value to millis, using the supplied timezone.
*
* @param tz the timezone
* @param dateValue the date value
* @return the date
*/
public
static
long
convertDateValueToMillis
(
TimeZone
tz
,
long
dateValue
)
{
return
getMillis
(
tz
,
yearFromDateValue
(
dateValue
),
monthFromDateValue
(
dateValue
),
dayFromDateValue
(
dateValue
),
0
,
0
,
0
,
0
);
}
/**
/**
* Convert an encoded date-time value to millis, using the supplied timezone.
* Convert an encoded date-time value to millis, using the supplied timezone.
*
*
...
@@ -1070,9 +1062,13 @@ public class DateTimeUtils {
...
@@ -1070,9 +1062,13 @@ public class DateTimeUtils {
* @return the date value
* @return the date value
*/
*/
public
static
long
dateValueFromDate
(
long
ms
)
{
public
static
long
dateValueFromDate
(
long
ms
)
{
Calendar
cal
=
getCalendar
();
ms
+=
getTimeZone
().
getOffset
(
ms
);
cal
.
setTimeInMillis
(
ms
);
long
absoluteDay
=
ms
/
MILLIS_PER_DAY
;
return
dateValueFromCalendar
(
cal
);
// Round toward negative infinity
if
(
ms
<
0
&&
(
absoluteDay
*
MILLIS_PER_DAY
!=
ms
))
{
absoluteDay
--;
}
return
dateValueFromAbsoluteDay
(
absoluteDay
);
}
}
/**
/**
...
@@ -1082,10 +1078,12 @@ public class DateTimeUtils {
...
@@ -1082,10 +1078,12 @@ public class DateTimeUtils {
* @return the date value
* @return the date value
*/
*/
private
static
long
dateValueFromCalendar
(
Calendar
cal
)
{
private
static
long
dateValueFromCalendar
(
Calendar
cal
)
{
int
year
,
month
,
day
;
int
year
=
cal
.
get
(
Calendar
.
YEAR
);
year
=
getYear
(
cal
);
if
(
cal
.
get
(
Calendar
.
ERA
)
==
GregorianCalendar
.
BC
)
{
month
=
cal
.
get
(
Calendar
.
MONTH
)
+
1
;
year
=
1
-
year
;
day
=
cal
.
get
(
Calendar
.
DAY_OF_MONTH
);
}
int
month
=
cal
.
get
(
Calendar
.
MONTH
)
+
1
;
int
day
=
cal
.
get
(
Calendar
.
DAY_OF_MONTH
);
return
((
long
)
year
<<
SHIFT_YEAR
)
|
(
month
<<
SHIFT_MONTH
)
|
day
;
return
((
long
)
year
<<
SHIFT_YEAR
)
|
(
month
<<
SHIFT_MONTH
)
|
day
;
}
}
...
@@ -1097,9 +1095,13 @@ public class DateTimeUtils {
...
@@ -1097,9 +1095,13 @@ public class DateTimeUtils {
* @return the nanoseconds
* @return the nanoseconds
*/
*/
public
static
long
nanosFromDate
(
long
ms
)
{
public
static
long
nanosFromDate
(
long
ms
)
{
Calendar
cal
=
getCalendar
();
ms
+=
getTimeZone
().
getOffset
(
ms
);
cal
.
setTimeInMillis
(
ms
);
long
absoluteDay
=
ms
/
MILLIS_PER_DAY
;
return
nanosFromCalendar
(
cal
);
// Round toward negative infinity
if
(
ms
<
0
&&
(
absoluteDay
*
MILLIS_PER_DAY
!=
ms
))
{
absoluteDay
--;
}
return
(
ms
-
absoluteDay
*
MILLIS_PER_DAY
)
*
1_000_000
;
}
}
/**
/**
...
@@ -1154,7 +1156,7 @@ public class DateTimeUtils {
...
@@ -1154,7 +1156,7 @@ public class DateTimeUtils {
m
+=
12
;
m
+=
12
;
}
}
long
a
=
((
y
*
2922L
)
>>
3
)
+
DAYS_OFFSET
[
m
-
3
]
+
d
-
719484
;
long
a
=
((
y
*
2922L
)
>>
3
)
+
DAYS_OFFSET
[
m
-
3
]
+
d
-
719484
;
if
(
y
<=
1582
&&
((
y
<
1582
)
||
(
m
*
100
+
d
<
10
0
5
)))
{
if
(
y
<=
1582
&&
((
y
<
1582
)
||
(
m
*
100
+
d
<
10
1
5
)))
{
// Julian calendar (cutover at 1582-10-04 / 1582-10-15)
// Julian calendar (cutover at 1582-10-04 / 1582-10-15)
a
+=
13
;
a
+=
13
;
}
else
if
(
y
<
1901
||
y
>
2099
)
{
}
else
if
(
y
<
1901
||
y
>
2099
)
{
...
...
h2/src/main/org/h2/util/ToChar.java
浏览文件 @
9e5d9644
差异被折叠。
点击展开。
h2/src/main/org/h2/util/ToDateParser.java
浏览文件 @
9e5d9644
...
@@ -7,9 +7,13 @@ package org.h2.util;
...
@@ -7,9 +7,13 @@ package org.h2.util;
import
static
java
.
lang
.
String
.
format
;
import
static
java
.
lang
.
String
.
format
;
import
java.sql.Timestamp
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.List
;
import
java.util.List
;
import
java.util.TimeZone
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
/**
/**
* Emulates Oracle's TO_DATE function.<br>
* Emulates Oracle's TO_DATE function.<br>
...
@@ -21,8 +25,29 @@ public class ToDateParser {
...
@@ -21,8 +25,29 @@ public class ToDateParser {
private
final
ConfigParam
functionName
;
private
final
ConfigParam
functionName
;
private
String
inputStr
;
private
String
inputStr
;
private
String
formatStr
;
private
String
formatStr
;
private
final
Calendar
resultCalendar
=
DateTimeUtils
.
createGregorianCalendar
();
private
Integer
nanos
;
private
boolean
doyValid
=
false
,
absoluteDayValid
=
false
,
hour12Valid
=
false
,
timeZoneHMValid
=
false
;
private
boolean
bc
;
private
long
absoluteDay
;
private
int
year
,
month
,
day
=
1
;
private
int
dayOfYear
;
private
int
hour
,
minute
,
second
,
nanos
;
private
int
hour12
;
boolean
isAM
=
true
;
private
TimeZone
timeZone
;
private
int
timeZoneHour
,
timeZoneMinute
;
private
int
currentYear
,
currentMonth
;
/**
/**
* @param input the input date with the date-time info
* @param input the input date with the date-time info
...
@@ -31,20 +56,6 @@ public class ToDateParser {
...
@@ -31,20 +56,6 @@ public class ToDateParser {
* code)
* code)
*/
*/
private
ToDateParser
(
ConfigParam
functionName
,
String
input
,
String
format
)
{
private
ToDateParser
(
ConfigParam
functionName
,
String
input
,
String
format
)
{
// reset calendar - default oracle behaviour
resultCalendar
.
set
(
Calendar
.
YEAR
,
1970
);
resultCalendar
.
set
(
Calendar
.
MONTH
,
DateTimeUtils
.
createGregorianCalendar
().
get
(
Calendar
.
MONTH
));
resultCalendar
.
clear
(
Calendar
.
DAY_OF_YEAR
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK_IN_MONTH
);
resultCalendar
.
set
(
Calendar
.
DAY_OF_MONTH
,
1
);
resultCalendar
.
set
(
Calendar
.
HOUR
,
0
);
resultCalendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
resultCalendar
.
set
(
Calendar
.
MINUTE
,
0
);
resultCalendar
.
set
(
Calendar
.
SECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
MILLISECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
AM_PM
,
Calendar
.
AM
);
this
.
functionName
=
functionName
;
this
.
functionName
=
functionName
;
inputStr
=
input
.
trim
();
inputStr
=
input
.
trim
();
// Keep a copy
// Keep a copy
...
@@ -59,30 +70,65 @@ public class ToDateParser {
...
@@ -59,30 +70,65 @@ public class ToDateParser {
unmodifiedFormatStr
=
formatStr
;
unmodifiedFormatStr
=
formatStr
;
}
}
private
static
ToDateParser
get
DateParser
(
String
input
,
String
format
)
{
private
static
ToDateParser
get
TimestampParser
(
ConfigParam
param
,
String
input
,
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
ToDateParser
result
=
new
ToDateParser
(
param
,
input
,
format
);
parse
(
result
);
parse
(
result
);
return
result
;
return
result
;
}
}
private
static
ToDateParser
getTimestampParser
(
String
input
,
String
format
)
{
private
ValueTimestamp
getResultingValue
()
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
long
dateValue
;
parse
(
result
);
if
(
absoluteDayValid
)
{
return
result
;
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
absoluteDay
);
}
}
else
{
int
year
=
this
.
year
;
private
Timestamp
getResultingTimestamp
()
{
if
(
year
==
0
)
{
Calendar
cal
=
(
Calendar
)
getResultCalendar
().
clone
();
year
=
getCurrentYear
();
int
nanosToSet
=
nanos
==
null
?
}
cal
.
get
(
Calendar
.
MILLISECOND
)
*
1000000
:
nanos
.
intValue
();
if
(
bc
)
{
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
year
=
1
-
year
;
Timestamp
ts
=
new
Timestamp
(
cal
.
getTimeInMillis
());
}
ts
.
setNanos
(
nanosToSet
);
if
(
doyValid
)
{
return
ts
;
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
DateTimeUtils
.
absoluteDayFromDateValue
(
DateTimeUtils
.
dateValue
(
year
,
1
,
1
))
+
dayOfYear
-
1
);
}
else
{
int
month
=
this
.
month
;
if
(
month
==
0
)
{
// Oracle uses current month as default
month
=
getCurrentMonth
();
}
dateValue
=
DateTimeUtils
.
dateValue
(
year
,
month
,
day
);
}
}
int
hour
;
if
(
hour12Valid
)
{
hour
=
hour12
%
12
;
if
(!
isAM
)
{
hour
+=
12
;
}
}
else
{
hour
=
this
.
hour
;
}
long
timeNanos
=
((((
hour
*
60
)
+
minute
)
*
60
)
+
second
)
*
1_000_000_000L
+
nanos
;
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
);
}
}
Calendar
getResultCalendar
()
{
private
ValueTimestampTimeZone
getResultingValueWithTimeZone
()
{
return
resultCalendar
;
ValueTimestamp
ts
=
getResultingValue
();
long
dateValue
=
ts
.
getDateValue
();
short
offset
;
if
(
timeZoneHMValid
)
{
offset
=
(
short
)
(
timeZoneHour
*
60
+
((
timeZoneHour
>=
0
)
?
timeZoneMinute
:
-
timeZoneMinute
));
}
else
{
TimeZone
timeZone
=
this
.
timeZone
;
if
(
timeZone
==
null
)
{
timeZone
=
TimeZone
.
getDefault
();
}
long
millis
=
DateTimeUtils
.
convertDateTimeValueToMillis
(
timeZone
,
dateValue
,
nanos
/
1000000
);
offset
=
(
short
)
(
timeZone
.
getOffset
(
millis
)
/
1000
/
60
);
}
return
ValueTimestampTimeZone
.
fromDateValueAndNanos
(
dateValue
,
ts
.
getTimeNanos
(),
offset
);
}
}
String
getInputStr
()
{
String
getInputStr
()
{
...
@@ -97,10 +143,111 @@ public class ToDateParser {
...
@@ -97,10 +143,111 @@ public class ToDateParser {
return
functionName
.
name
();
return
functionName
.
name
();
}
}
private
void
queryCurrentYearAndMonth
()
{
GregorianCalendar
gc
=
DateTimeUtils
.
getCalendar
();
gc
.
setTimeInMillis
(
System
.
currentTimeMillis
());
currentYear
=
gc
.
get
(
Calendar
.
YEAR
);
currentMonth
=
gc
.
get
(
Calendar
.
MONTH
)
+
1
;
}
int
getCurrentYear
()
{
if
(
currentYear
==
0
)
{
queryCurrentYearAndMonth
();
}
return
currentYear
;
}
int
getCurrentMonth
()
{
if
(
currentMonth
==
0
)
{
queryCurrentYearAndMonth
();
}
return
currentMonth
;
}
void
setAbsoluteDay
(
int
absoluteDay
)
{
doyValid
=
false
;
absoluteDayValid
=
true
;
this
.
absoluteDay
=
absoluteDay
;
}
void
setBC
(
boolean
bc
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
bc
=
bc
;
}
void
setYear
(
int
year
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
year
=
year
;
}
void
setMonth
(
int
month
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
month
=
month
;
if
(
year
==
0
)
{
year
=
1970
;
}
}
void
setDay
(
int
day
)
{
doyValid
=
false
;
absoluteDayValid
=
false
;
this
.
day
=
day
;
if
(
year
==
0
)
{
year
=
1970
;
}
}
void
setDayOfYear
(
int
dayOfYear
)
{
doyValid
=
true
;
absoluteDayValid
=
false
;
this
.
dayOfYear
=
dayOfYear
;
}
void
setHour
(
int
hour
)
{
hour12Valid
=
false
;
this
.
hour
=
hour
;
}
void
setMinute
(
int
minute
)
{
this
.
minute
=
minute
;
}
void
setSecord
(
int
second
)
{
this
.
second
=
second
;
}
void
setNanos
(
int
nanos
)
{
void
setNanos
(
int
nanos
)
{
this
.
nanos
=
nanos
;
this
.
nanos
=
nanos
;
}
}
void
setAmPm
(
boolean
isAM
)
{
hour12Valid
=
true
;
this
.
isAM
=
isAM
;
}
void
setHour12
(
int
hour12
)
{
hour12Valid
=
true
;
this
.
hour12
=
hour12
;
}
void
setTimeZone
(
TimeZone
timeZone
)
{
timeZoneHMValid
=
false
;
this
.
timeZone
=
timeZone
;
}
void
setTimeZoneHour
(
int
timeZoneHour
)
{
timeZoneHMValid
=
true
;
this
.
timeZoneHour
=
timeZoneHour
;
}
void
setTimeZoneMinute
(
int
timeZoneMinute
)
{
timeZoneHMValid
=
true
;
this
.
timeZoneMinute
=
timeZoneMinute
;
}
private
boolean
hasToParseData
()
{
private
boolean
hasToParseData
()
{
return
formatStr
.
length
()
>
0
;
return
formatStr
.
length
()
>
0
;
}
}
...
@@ -180,9 +327,21 @@ public class ToDateParser {
...
@@ -180,9 +327,21 @@ public class ToDateParser {
* @param format the format
* @param format the format
* @return the timestamp
* @return the timestamp
*/
*/
public
static
Timestamp
toTimestamp
(
String
input
,
String
format
)
{
public
static
ValueTimestamp
toTimestamp
(
String
input
,
String
format
)
{
ToDateParser
parser
=
getTimestampParser
(
input
,
format
);
ToDateParser
parser
=
getTimestampParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
return
parser
.
getResultingTimestamp
();
return
parser
.
getResultingValue
();
}
/**
* Parse a string as a timestamp with the given format.
*
* @param input the input
* @param format the format
* @return the timestamp
*/
public
static
ValueTimestampTimeZone
toTimestampTz
(
String
input
,
String
format
)
{
ToDateParser
parser
=
getTimestampParser
(
ConfigParam
.
TO_TIMESTAMP_TZ
,
input
,
format
);
return
parser
.
getResultingValueWithTimeZone
();
}
}
/**
/**
...
@@ -192,9 +351,9 @@ public class ToDateParser {
...
@@ -192,9 +351,9 @@ public class ToDateParser {
* @param format the format
* @param format the format
* @return the date as a timestamp
* @return the date as a timestamp
*/
*/
public
static
Timestamp
toDate
(
String
input
,
String
format
)
{
public
static
Value
Timestamp
toDate
(
String
input
,
String
format
)
{
ToDateParser
parser
=
get
DateParser
(
input
,
format
);
ToDateParser
parser
=
get
TimestampParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
return
parser
.
getResulting
Timestamp
();
return
parser
.
getResulting
Value
();
}
}
/**
/**
...
@@ -202,7 +361,8 @@ public class ToDateParser {
...
@@ -202,7 +361,8 @@ public class ToDateParser {
*/
*/
private
enum
ConfigParam
{
private
enum
ConfigParam
{
TO_DATE
(
"DD MON YYYY"
),
TO_DATE
(
"DD MON YYYY"
),
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
);
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
),
TO_TIMESTAMP_TZ
(
"DD MON YYYY HH:MI:SS TZR"
);
private
final
String
defaultFormatStr
;
private
final
String
defaultFormatStr
;
ConfigParam
(
String
defaultFormatStr
)
{
ConfigParam
(
String
defaultFormatStr
)
{
...
...
h2/src/main/org/h2/util/ToDateTokenizer.java
浏览文件 @
9e5d9644
差异被折叠。
点击展开。
h2/src/main/org/h2/value/Transfer.java
浏览文件 @
9e5d9644
...
@@ -14,7 +14,6 @@ import java.io.Reader;
...
@@ -14,7 +14,6 @@ import java.io.Reader;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.net.InetAddress
;
import
java.net.InetAddress
;
import
java.net.Socket
;
import
java.net.Socket
;
import
java.nio.charset.StandardCharsets
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
...
@@ -463,10 +462,6 @@ public class Transfer {
...
@@ -463,10 +462,6 @@ public class Transfer {
throw
DbException
.
get
(
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"length="
+
length
);
ErrorCode
.
CONNECTION_BROKEN_1
,
"length="
+
length
);
}
}
if
(
length
>
Integer
.
MAX_VALUE
)
{
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"length="
+
length
);
}
writeLong
(
length
);
writeLong
(
length
);
Reader
reader
=
v
.
getReader
();
Reader
reader
=
v
.
getReader
();
Data
.
copyString
(
reader
,
out
);
Data
.
copyString
(
reader
,
out
);
...
@@ -652,21 +647,10 @@ public class Transfer {
...
@@ -652,21 +647,10 @@ public class Transfer {
return
ValueLobDb
.
create
(
return
ValueLobDb
.
create
(
Value
.
CLOB
,
session
.
getDataHandler
(),
tableId
,
id
,
hmac
,
precision
);
Value
.
CLOB
,
session
.
getDataHandler
(),
tableId
,
id
,
hmac
,
precision
);
}
}
if
(
length
<
0
||
length
>
Integer
.
MAX_VALUE
)
{
if
(
length
<
0
)
{
throw
DbException
.
get
(
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"length="
+
length
);
ErrorCode
.
CONNECTION_BROKEN_1
,
"length="
+
length
);
}
}
DataReader
reader
=
new
DataReader
(
in
);
int
len
=
(
int
)
length
;
char
[]
buff
=
new
char
[
len
];
IOUtils
.
readFully
(
reader
,
buff
,
len
);
int
magic
=
readInt
();
if
(
magic
!=
LOB_MAGIC
)
{
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"magic="
+
magic
);
}
byte
[]
small
=
new
String
(
buff
).
getBytes
(
StandardCharsets
.
UTF_8
);
return
ValueLobDb
.
createSmallLob
(
Value
.
CLOB
,
small
,
length
);
}
}
Value
v
=
session
.
getDataHandler
().
getLobStorage
().
Value
v
=
session
.
getDataHandler
().
getLobStorage
().
createClob
(
new
DataReader
(
in
),
length
);
createClob
(
new
DataReader
(
in
),
length
);
...
...
h2/src/main/org/h2/value/ValueLobDb.java
浏览文件 @
9e5d9644
...
@@ -26,6 +26,7 @@ import org.h2.store.FileStoreInputStream;
...
@@ -26,6 +26,7 @@ import org.h2.store.FileStoreInputStream;
import
org.h2.store.FileStoreOutputStream
;
import
org.h2.store.FileStoreOutputStream
;
import
org.h2.store.LobStorageFrontend
;
import
org.h2.store.LobStorageFrontend
;
import
org.h2.store.LobStorageInterface
;
import
org.h2.store.LobStorageInterface
;
import
org.h2.store.RangeReader
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
...
@@ -544,6 +545,15 @@ public class ValueLobDb extends Value implements Value.ValueClob,
...
@@ -544,6 +545,15 @@ public class ValueLobDb extends Value implements Value.ValueClob,
*/
*/
public
static
ValueLobDb
createTempClob
(
Reader
in
,
long
length
,
public
static
ValueLobDb
createTempClob
(
Reader
in
,
long
length
,
DataHandler
handler
)
{
DataHandler
handler
)
{
if
(
length
>=
0
)
{
// Otherwise BufferedReader may try to read more data than needed and that
// blocks the network level
try
{
in
=
new
RangeReader
(
in
,
0
,
length
);
}
catch
(
IOException
e
)
{
throw
DbException
.
convert
(
e
);
}
}
BufferedReader
reader
;
BufferedReader
reader
;
if
(
in
instanceof
BufferedReader
)
{
if
(
in
instanceof
BufferedReader
)
{
reader
=
(
BufferedReader
)
in
;
reader
=
(
BufferedReader
)
in
;
...
...
h2/src/main/org/h2/value/ValueTimestampTimeZone.java
浏览文件 @
9e5d9644
...
@@ -9,8 +9,6 @@ import java.math.BigDecimal;
...
@@ -9,8 +9,6 @@ import java.math.BigDecimal;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
import
java.util.SimpleTimeZone
;
import
java.util.TimeZone
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.TimestampWithTimeZone
;
import
org.h2.api.TimestampWithTimeZone
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
...
@@ -148,19 +146,6 @@ public class ValueTimestampTimeZone extends Value {
...
@@ -148,19 +146,6 @@ public class ValueTimestampTimeZone extends Value {
return
timeZoneOffsetMins
;
return
timeZoneOffsetMins
;
}
}
/**
* Returns compatible offset-based time zone with no DST schedule.
*
* @return compatible offset-based time zone
*/
public
TimeZone
getTimeZone
()
{
int
offset
=
timeZoneOffsetMins
;
if
(
offset
==
0
)
{
return
DateTimeUtils
.
UTC
;
}
return
new
SimpleTimeZone
(
offset
*
60000
,
Integer
.
toString
(
offset
));
}
@Override
@Override
public
Timestamp
getTimestamp
()
{
public
Timestamp
getTimestamp
()
{
throw
new
UnsupportedOperationException
(
"unimplemented"
);
throw
new
UnsupportedOperationException
(
"unimplemented"
);
...
@@ -219,34 +204,31 @@ public class ValueTimestampTimeZone extends Value {
...
@@ -219,34 +204,31 @@ public class ValueTimestampTimeZone extends Value {
@Override
@Override
protected
int
compareSecure
(
Value
o
,
CompareMode
mode
)
{
protected
int
compareSecure
(
Value
o
,
CompareMode
mode
)
{
ValueTimestampTimeZone
t
=
(
ValueTimestampTimeZone
)
o
;
ValueTimestampTimeZone
t
=
(
ValueTimestampTimeZone
)
o
;
//
We are pretending that the dateValue is in UTC because that gives us
//
Maximum time zone offset is +/-18 hours so difference in days between local
// a
stable sort even if the DST database changes.
// a
nd UTC cannot be more than one day
long
daysA
=
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue
);
// convert to minutes and add timezone offset
long
timeA
=
timeNanos
-
timeZoneOffsetMins
*
60_000_000_000L
;
long
a
=
DateTimeUtils
.
convertDateValueToMillis
(
if
(
timeA
<
0
)
{
DateTimeUtils
.
UTC
,
dateValue
)
/
timeA
+=
DateTimeUtils
.
NANOS_PER_DAY
;
(
1000L
*
60L
)
;
daysA
--
;
long
ma
=
timeNanos
/
(
1000L
*
1000L
*
1000L
*
60L
);
}
else
if
(
timeA
>=
DateTimeUtils
.
NANOS_PER_DAY
)
{
a
+=
ma
;
timeA
-=
DateTimeUtils
.
NANOS_PER_DAY
;
a
-=
timeZoneOffsetMins
;
daysA
++
;
}
// convert to minutes and add timezone offset
long
daysB
=
DateTimeUtils
.
absoluteDayFromDateValue
(
t
.
dateValue
);
long
b
=
DateTimeUtils
.
convertDateValueToMillis
(
long
timeB
=
t
.
timeNanos
-
t
.
timeZoneOffsetMins
*
60_000_000_000L
;
DateTimeUtils
.
UTC
,
t
.
dateValue
)
/
if
(
timeB
<
0
)
{
(
1000L
*
60L
)
;
timeB
+=
DateTimeUtils
.
NANOS_PER_DAY
;
long
mb
=
t
.
timeNanos
/
(
1000L
*
1000L
*
1000L
*
60L
)
;
daysB
--
;
b
+=
mb
;
}
else
if
(
timeB
>=
DateTimeUtils
.
NANOS_PER_DAY
)
{
b
-=
t
.
timeZoneOffsetMins
;
timeB
-=
DateTimeUtils
.
NANOS_PER_DAY
;
daysB
++;
// compare date
}
int
c
=
Long
.
compare
(
a
,
b
);
int
c
mp
=
Long
.
compare
(
daysA
,
daysB
);
if
(
c
!=
0
)
{
if
(
c
mp
!=
0
)
{
return
c
;
return
c
mp
;
}
}
// compare time
return
Long
.
compare
(
timeA
,
timeB
);
long
na
=
timeNanos
-
(
ma
*
1000L
*
1000L
*
1000L
*
60L
);
long
nb
=
t
.
timeNanos
-
(
mb
*
1000L
*
1000L
*
1000L
*
60L
);
return
Long
.
compare
(
na
,
nb
);
}
}
@Override
@Override
...
...
h2/src/test/org/h2/test/TestBase.java
浏览文件 @
9e5d9644
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
package
org
.
h2
.
test
;
package
org
.
h2
.
test
;
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayInputStream
;
import
java.io.File
;
import
java.io.FileWriter
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
...
@@ -30,7 +31,9 @@ import java.sql.Types;
...
@@ -30,7 +31,9 @@ import java.sql.Types;
import
java.text.DateFormat
;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Objects
;
import
java.util.SimpleTimeZone
;
import
java.util.SimpleTimeZone
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
...
@@ -40,6 +43,7 @@ import org.h2.store.fs.FilePath;
...
@@ -40,6 +43,7 @@ import org.h2.store.fs.FilePath;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.utils.ProxyCodeGenerator
;
import
org.h2.test.utils.ProxyCodeGenerator
;
import
org.h2.test.utils.ResultVerifier
;
import
org.h2.test.utils.ResultVerifier
;
import
org.h2.test.utils.SelfDestructor
;
import
org.h2.tools.DeleteDbFiles
;
import
org.h2.tools.DeleteDbFiles
;
/**
/**
...
@@ -466,16 +470,16 @@ public abstract class TestBase {
...
@@ -466,16 +470,16 @@ public abstract class TestBase {
throw
new
AssertionError
(
string
);
throw
new
AssertionError
(
string
);
}
}
/**
/**
* Log an error message.
* Log an error message.
*
*
* @param s the message
* @param s the message
*/
*/
public
static
void
logErrorMessage
(
String
s
)
{
public
static
void
logErrorMessage
(
String
s
)
{
System
.
out
.
flush
();
System
.
out
.
flush
();
System
.
err
.
println
(
"ERROR: "
+
s
+
"------------------------------"
);
System
.
err
.
println
(
"ERROR: "
+
s
+
"------------------------------"
);
logThrowable
(
s
,
null
);
logThrowable
(
s
,
null
);
}
}
/**
/**
* Log an error message.
* Log an error message.
...
@@ -1444,6 +1448,16 @@ public abstract class TestBase {
...
@@ -1444,6 +1448,16 @@ public abstract class TestBase {
return
System
.
getProperty
(
"java.class.path"
);
return
System
.
getProperty
(
"java.class.path"
);
}
}
/**
* Get the path to a java executable of the current process
*
* @return the path to java
*/
private
String
getJVM
()
{
return
System
.
getProperty
(
"java.home"
)
+
File
.
separatorChar
+
"bin"
+
File
.
separator
+
"java"
;
}
/**
/**
* Use up almost all memory.
* Use up almost all memory.
*
*
...
@@ -1687,4 +1701,46 @@ public abstract class TestBase {
...
@@ -1687,4 +1701,46 @@ public abstract class TestBase {
return
getClass
().
getSimpleName
();
return
getClass
().
getSimpleName
();
}
}
public
ProcessBuilder
buildChild
(
String
name
,
Class
<?
extends
TestBase
>
childClass
,
String
...
jvmArgs
)
{
List
<
String
>
args
=
new
ArrayList
<>(
16
);
args
.
add
(
getJVM
());
Collections
.
addAll
(
args
,
jvmArgs
);
Collections
.
addAll
(
args
,
"-cp"
,
getClassPath
(),
SelfDestructor
.
getPropertyString
(
1
),
childClass
.
getName
(),
"-url"
,
getURL
(
name
,
true
),
"-user"
,
getUser
(),
"-password"
,
getPassword
());
ProcessBuilder
processBuilder
=
new
ProcessBuilder
()
// .redirectError(ProcessBuilder.Redirect.INHERIT)
.
redirectErrorStream
(
true
)
.
redirectOutput
(
ProcessBuilder
.
Redirect
.
INHERIT
)
.
command
(
args
);
return
processBuilder
;
}
public
abstract
static
class
Child
extends
TestBase
{
private
String
url
;
private
String
user
;
private
String
password
;
public
Child
(
String
...
args
)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
if
(
"-url"
.
equals
(
args
[
i
]))
{
url
=
args
[++
i
];
}
else
if
(
"-user"
.
equals
(
args
[
i
]))
{
user
=
args
[++
i
];
}
else
if
(
"-password"
.
equals
(
args
[
i
]))
{
password
=
args
[++
i
];
}
SelfDestructor
.
startCountdown
(
60
);
}
}
public
Connection
getConnection
()
throws
SQLException
{
return
getConnection
(
url
,
user
,
password
);
}
}
}
}
h2/src/test/org/h2/test/db/TestFunctions.java
浏览文件 @
9e5d9644
差异被折叠。
点击展开。
h2/src/test/org/h2/test/db/TestOutOfMemory.java
浏览文件 @
9e5d9644
...
@@ -15,7 +15,6 @@ import java.util.Map;
...
@@ -15,7 +15,6 @@ import java.util.Map;
import
java.util.Random
;
import
java.util.Random
;
import
java.util.concurrent.atomic.AtomicReference
;
import
java.util.concurrent.atomic.AtomicReference
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStore
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePath
;
import
org.h2.store.fs.FilePathMem
;
import
org.h2.store.fs.FilePathMem
;
...
@@ -28,6 +27,8 @@ import org.h2.test.TestBase;
...
@@ -28,6 +27,8 @@ import org.h2.test.TestBase;
*/
*/
public
class
TestOutOfMemory
extends
TestBase
{
public
class
TestOutOfMemory
extends
TestBase
{
private
static
final
String
DB_NAME
=
"outOfMemory"
;
/**
/**
* Run just this test.
* Run just this test.
*
*
...
@@ -38,16 +39,18 @@ public class TestOutOfMemory extends TestBase {
...
@@ -38,16 +39,18 @@ public class TestOutOfMemory extends TestBase {
}
}
@Override
@Override
public
void
test
()
throws
SQLException
,
Interrupted
Exception
{
public
void
test
()
throws
Exception
{
if
(
config
.
vmlens
)
{
if
(
config
.
vmlens
)
{
// running out of memory will cause the vmlens agent to stop working
// running out of memory will cause the vmlens agent to stop working
return
;
return
;
}
}
try
{
try
{
System
.
gc
();
if
(!
config
.
travis
)
{
testMVStoreUsingInMemoryFileSystem
();
System
.
gc
();
System
.
gc
();
testMVStoreUsingInMemoryFileSystem
();
testDatabaseUsingInMemoryFileSystem
();
System
.
gc
();
testDatabaseUsingInMemoryFileSystem
();
}
System
.
gc
();
System
.
gc
();
testUpdateWhenNearlyOutOfMemory
();
testUpdateWhenNearlyOutOfMemory
();
}
finally
{
}
finally
{
...
@@ -147,67 +150,92 @@ public class TestOutOfMemory extends TestBase {
...
@@ -147,67 +150,92 @@ public class TestOutOfMemory extends TestBase {
}
}
}
}
private
void
testUpdateWhenNearlyOutOfMemory
()
throws
SQLException
,
Interrupted
Exception
{
private
void
testUpdateWhenNearlyOutOfMemory
()
throws
Exception
{
if
(
config
.
memory
)
{
if
(
config
.
memory
)
{
return
;
return
;
}
}
recoverAfterOOM
();
deleteDb
(
DB_NAME
);
deleteDb
(
"outOfMemory"
);
Connection
conn
=
getConnection
(
"outOfMemory;MAX_OPERATION_MEMORY=1000000"
);
ProcessBuilder
processBuilder
=
buildChild
(
Statement
stat
=
conn
.
createStatement
();
DB_NAME
+
";MAX_OPERATION_MEMORY=1000000"
,
stat
.
execute
(
"drop all objects"
);
MyChild
.
class
,
stat
.
execute
(
"create table stuff (id int, text varchar as space(100) || id)"
);
"-XX:+UseParallelGC"
,
stat
.
execute
(
"insert into stuff(id) select x from system_range(1, 3000)"
);
// "-XX:+UseG1GC",
PreparedStatement
prep
=
conn
.
prepareStatement
(
"-Xmx128m"
);
"update stuff set text = text || space(1000) || id"
);
//*
prep
.
execute
();
processBuilder
.
start
().
waitFor
();
stat
.
execute
(
"checkpoint"
);
/*/
eatMemory
(
80
);
List<String> args = processBuilder.command();
try
{
for (Iterator<String> iter = args.iterator(); iter.hasNext(); ) {
try
{
String arg = iter.next();
prep
.
execute
();
if(arg.equals(MyChild.class.getName())) {
fail
();
iter.remove();
}
catch
(
DbException
ex
)
{
break;
freeMemory
();
assertTrue
(
ErrorCode
.
OUT_OF_MEMORY
==
ex
.
getErrorCode
()
||
ErrorCode
.
GENERAL_ERROR_1
==
ex
.
getErrorCode
());
}
catch
(
SQLException
ex
)
{
freeMemory
();
assertTrue
(
ErrorCode
.
OUT_OF_MEMORY
==
ex
.
getErrorCode
()
||
ErrorCode
.
GENERAL_ERROR_1
==
ex
.
getErrorCode
());
}
recoverAfterOOM
();
try
{
conn
.
close
();
fail
();
}
catch
(
DbException
ex
)
{
freeMemory
();
assertEquals
(
ErrorCode
.
DATABASE_IS_CLOSED
,
ex
.
getErrorCode
());
}
catch
(
SQLException
ex
)
{
freeMemory
();
assertEquals
(
ErrorCode
.
DATABASE_IS_CLOSED
,
ex
.
getErrorCode
());
}
}
freeMemory
();
iter.remove();
conn
=
null
;
}
conn
=
getConnection
(
"outOfMemory"
);
MyChild.main(args.toArray(new String[0]));
stat
=
conn
.
createStatement
();
//*/
ResultSet
rs
=
stat
.
executeQuery
(
"select count(*) from stuff"
);
try
(
Connection
conn
=
getConnection
(
DB_NAME
))
{
rs
.
next
();
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT count(*) FROM stuff"
);
assertTrue
(
rs
.
next
());
assertEquals
(
3000
,
rs
.
getInt
(
1
));
assertEquals
(
3000
,
rs
.
getInt
(
1
));
}
catch
(
OutOfMemoryError
e
)
{
freeMemory
();
rs
=
stat
.
executeQuery
(
"SELECT * FROM stuff WHERE id = 3000"
);
// out of memory not detected
assertTrue
(
rs
.
next
());
throw
new
AssertionError
(
"Out of memory not detected"
,
e
);
String
text
=
rs
.
getString
(
2
);
}
finally
{
assertFalse
(
rs
.
wasNull
());
freeMemory
();
assertEquals
(
1004
,
text
.
length
());
if
(
conn
!=
null
)
{
try
{
// TODO: there are intermittent failures here
conn
.
close
();
// where number is about 1000 short of expected value.
}
catch
(
SQLException
e
)
{
// This indicates a real problem - durability failure
// out of memory will / may close the database
// and need to be looked at.
assertKnownException
(
e
);
rs
=
stat
.
executeQuery
(
"SELECT sum(length(text)) FROM stuff"
);
}
assertTrue
(
rs
.
next
());
int
totalSize
=
rs
.
getInt
(
1
);
if
(
3010893
>
totalSize
)
{
TestBase
.
logErrorMessage
(
"Durability failure - expected: 3010893, actual: "
+
totalSize
);
}
}
}
finally
{
deleteDb
(
DB_NAME
);
}
}
deleteDb
(
"outOfMemory"
);
}
}
public
static
final
class
MyChild
extends
TestBase
.
Child
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
new
MyChild
(
args
).
init
().
test
();
}
private
MyChild
(
String
...
args
)
{
super
(
args
);
}
@Override
public
void
test
()
{
try
(
Connection
conn
=
getConnection
())
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"DROP ALL OBJECTS"
);
stat
.
execute
(
"CREATE TABLE stuff (id INT, text VARCHAR)"
);
stat
.
execute
(
"INSERT INTO stuff(id) SELECT x FROM system_range(1, 3000)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"UPDATE stuff SET text = IFNULL(text,'') || space(1000) || id"
);
prep
.
execute
();
stat
.
execute
(
"CHECKPOINT"
);
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT sum(length(text)) FROM stuff"
);
assertTrue
(
rs
.
next
());
assertEquals
(
3010893
,
rs
.
getInt
(
1
));
eatMemory
(
80
);
prep
.
execute
();
fail
();
}
catch
(
SQLException
ignore
)
{
}
finally
{
freeMemory
();
}
}
}
}
}
h2/src/test/org/h2/test/jdbc/TestLobApi.java
浏览文件 @
9e5d9644
...
@@ -119,7 +119,20 @@ public class TestLobApi extends TestBase {
...
@@ -119,7 +119,20 @@ public class TestLobApi extends TestBase {
prep
.
setString
(
1
,
""
);
prep
.
setString
(
1
,
""
);
prep
.
setBytes
(
2
,
new
byte
[
0
]);
prep
.
setBytes
(
2
,
new
byte
[
0
]);
prep
.
execute
();
prep
.
execute
();
Random
r
=
new
Random
(
1
);
Random
r
=
new
Random
(
1
);
char
[]
charsSmall
=
new
char
[
20
];
for
(
int
i
=
0
;
i
<
charsSmall
.
length
;
i
++)
{
charsSmall
[
i
]
=
(
char
)
r
.
nextInt
(
10000
);
}
String
dSmall
=
new
String
(
charsSmall
);
prep
.
setCharacterStream
(
1
,
new
StringReader
(
dSmall
),
-
1
);
byte
[]
bytesSmall
=
new
byte
[
20
];
r
.
nextBytes
(
bytesSmall
);
prep
.
setBinaryStream
(
2
,
new
ByteArrayInputStream
(
bytesSmall
),
-
1
);
prep
.
execute
();
char
[]
chars
=
new
char
[
100000
];
char
[]
chars
=
new
char
[
100000
];
for
(
int
i
=
0
;
i
<
chars
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
chars
.
length
;
i
++)
{
chars
[
i
]
=
(
char
)
r
.
nextInt
(
10000
);
chars
[
i
]
=
(
char
)
r
.
nextInt
(
10000
);
...
@@ -130,6 +143,7 @@ public class TestLobApi extends TestBase {
...
@@ -130,6 +143,7 @@ public class TestLobApi extends TestBase {
r
.
nextBytes
(
bytes
);
r
.
nextBytes
(
bytes
);
prep
.
setBinaryStream
(
2
,
new
ByteArrayInputStream
(
bytes
),
-
1
);
prep
.
setBinaryStream
(
2
,
new
ByteArrayInputStream
(
bytes
),
-
1
);
prep
.
execute
();
prep
.
execute
();
conn
.
setAutoCommit
(
false
);
conn
.
setAutoCommit
(
false
);
ResultSet
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
ResultSet
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
rs
.
next
();
rs
.
next
();
...
@@ -138,18 +152,27 @@ public class TestLobApi extends TestBase {
...
@@ -138,18 +152,27 @@ public class TestLobApi extends TestBase {
rs
.
next
();
rs
.
next
();
Clob
c2
=
rs
.
getClob
(
2
);
Clob
c2
=
rs
.
getClob
(
2
);
Blob
b2
=
rs
.
getBlob
(
3
);
Blob
b2
=
rs
.
getBlob
(
3
);
rs
.
next
();
Clob
c3
=
rs
.
getClob
(
2
);
Blob
b3
=
rs
.
getBlob
(
3
);
assertFalse
(
rs
.
next
());
assertFalse
(
rs
.
next
());
// now close
// now close
rs
.
close
();
rs
.
close
();
// but the LOBs must stay open
// but the LOBs must stay open
assertEquals
(
0
,
c1
.
length
());
assertEquals
(
0
,
c1
.
length
());
assertEquals
(
0
,
b1
.
length
());
assertEquals
(
0
,
b1
.
length
());
assertEquals
(
chars
.
length
,
c2
.
length
());
assertEquals
(
bytes
.
length
,
b2
.
length
());
assertEquals
(
""
,
c1
.
getSubString
(
1
,
0
));
assertEquals
(
""
,
c1
.
getSubString
(
1
,
0
));
assertEquals
(
new
byte
[
0
],
b1
.
getBytes
(
1
,
0
));
assertEquals
(
new
byte
[
0
],
b1
.
getBytes
(
1
,
0
));
assertEquals
(
d
,
c2
.
getSubString
(
1
,
(
int
)
c2
.
length
()));
assertEquals
(
bytes
,
b2
.
getBytes
(
1
,
(
int
)
b2
.
length
()));
assertEquals
(
charsSmall
.
length
,
c2
.
length
());
assertEquals
(
bytesSmall
.
length
,
b2
.
length
());
assertEquals
(
dSmall
,
c2
.
getSubString
(
1
,
(
int
)
c2
.
length
()));
assertEquals
(
bytesSmall
,
b2
.
getBytes
(
1
,
(
int
)
b2
.
length
()));
assertEquals
(
chars
.
length
,
c3
.
length
());
assertEquals
(
bytes
.
length
,
b3
.
length
());
assertEquals
(
d
,
c3
.
getSubString
(
1
,
(
int
)
c3
.
length
()));
assertEquals
(
bytes
,
b3
.
getBytes
(
1
,
(
int
)
b3
.
length
()));
stat
.
execute
(
"drop table test"
);
stat
.
execute
(
"drop table test"
);
conn
.
close
();
conn
.
close
();
}
}
...
...
h2/src/test/org/h2/test/scripts/TestScript.java
浏览文件 @
9e5d9644
...
@@ -92,7 +92,7 @@ public class TestScript extends TestBase {
...
@@ -92,7 +92,7 @@ public class TestScript extends TestBase {
}
else
{
}
else
{
decimal2
=
"decimal_numeric"
;
decimal2
=
"decimal_numeric"
;
}
}
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"
,
"other"
,
"real"
,
"smallint"
,
...
...
h2/src/test/org/h2/test/scripts/functions/timeanddate/dateadd.sql
浏览文件 @
9e5d9644
...
@@ -105,6 +105,18 @@ call dateadd('MS', 1, TIMESTAMP '2001-02-03 04:05:06.789001');
...
@@ -105,6 +105,18 @@ call dateadd('MS', 1, TIMESTAMP '2001-02-03 04:05:06.789001');
>
2001
-
02
-
03
04
:
05
:
06
.
790001
>
2001
-
02
-
03
04
:
05
:
06
.
790001
>
rows
:
1
>
rows
:
1
SELECT
DATEADD
(
'MICROSECOND'
,
1
,
TIME
'10:00:01'
),
DATEADD
(
'MCS'
,
1
,
TIMESTAMP
'2010-10-20 10:00:01.1'
);
>
TIME
'10:00:01.000001'
TIMESTAMP
'2010-10-20 10:00:01.100001'
>
---------------------- --------------------------------------
>
10
:
00
:
01
.
000001
2010
-
10
-
20
10
:
00
:
01
.
100001
>
rows
:
1
SELECT
DATEADD
(
'NANOSECOND'
,
1
,
TIME
'10:00:01'
),
DATEADD
(
'NS'
,
1
,
TIMESTAMP
'2010-10-20 10:00:01.1'
);
>
TIME
'10:00:01.000000001'
TIMESTAMP
'2010-10-20 10:00:01.100000001'
>
------------------------- -----------------------------------------
>
10
:
00
:
01
.
000000001
2010
-
10
-
20
10
:
00
:
01
.
100000001
>
rows
:
1
SELECT
DATEADD
(
'HOUR'
,
1
,
DATE
'2010-01-20'
);
SELECT
DATEADD
(
'HOUR'
,
1
,
DATE
'2010-01-20'
);
>
TIMESTAMP
'2010-01-20 01:00:00.0'
>
TIMESTAMP
'2010-01-20 01:00:00.0'
>
---------------------------------
>
---------------------------------
...
...
h2/src/test/org/h2/test/scripts/functions/timeanddate/datediff.sql
浏览文件 @
9e5d9644
...
@@ -159,6 +159,22 @@ call datediff('MS', TIMESTAMP '1900-01-01 00:00:01.000', TIMESTAMP '2008-01-01 0
...
@@ -159,6 +159,22 @@ call datediff('MS', TIMESTAMP '1900-01-01 00:00:01.000', TIMESTAMP '2008-01-01 0
>
3408134399000
>
3408134399000
>
rows
:
1
>
rows
:
1
SELECT
DATEDIFF
(
'MICROSECOND'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-01 00:00:00.123456789'
),
DATEDIFF
(
'MCS'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-01 00:00:00.123456789'
),
DATEDIFF
(
'MCS'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-02 00:00:00.123456789'
);
>
123456
123456
86400123456
>
------ ------ -----------
>
123456
123456
86400123456
>
rows
:
1
SELECT
DATEDIFF
(
'NANOSECOND'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-01 00:00:00.123456789'
),
DATEDIFF
(
'NS'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-01 00:00:00.123456789'
),
DATEDIFF
(
'NS'
,
'2006-01-01 00:00:00.0000000'
,
'2006-01-02 00:00:00.123456789'
);
>
123456789
123456789
86400123456789
>
--------- --------- --------------
>
123456789
123456789
86400123456789
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'2018-02-02'
,
DATE
'2018-02-03'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'2018-02-02'
,
DATE
'2018-02-03'
);
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'2018-02-02'
,
DATE
'2018-02-03'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'2018-02-02'
,
DATE
'2018-02-03'
);
>
0
0
>
0
0
>
-
-
>
-
-
...
...
h2/src/test/org/h2/test/scripts/functions/timeanddate/extract.sql
浏览文件 @
9e5d9644
...
@@ -3,6 +3,20 @@
...
@@ -3,6 +3,20 @@
-- Initial Developer: H2 Group
-- Initial Developer: H2 Group
--
--
SELECT
EXTRACT
(
MICROSECOND
FROM
TIME
'10:00:00.123456789'
),
EXTRACT
(
MCS
FROM
TIMESTAMP
'2015-01-01 11:22:33.987654321'
);
>
123456
987654
>
------ ------
>
123456
987654
>
rows
:
1
SELECT
EXTRACT
(
NANOSECOND
FROM
TIME
'10:00:00.123456789'
),
EXTRACT
(
NS
FROM
TIMESTAMP
'2015-01-01 11:22:33.987654321'
);
>
123456789
987654321
>
--------- ---------
>
123456789
987654321
>
rows
:
1
select
EXTRACT
(
EPOCH
from
time
'00:00:00'
);
select
EXTRACT
(
EPOCH
from
time
'00:00:00'
);
>
0
>
0
...
...
h2/src/test/org/h2/test/store/TestMVStoreBenchmark.java
浏览文件 @
9e5d9644
...
@@ -124,14 +124,6 @@ public class TestMVStoreBenchmark extends TestBase {
...
@@ -124,14 +124,6 @@ public class TestMVStoreBenchmark extends TestBase {
}
}
static
long
getMemory
()
{
static
long
getMemory
()
{
try
{
LinkedList
<
byte
[]>
list
=
new
LinkedList
<>();
while
(
true
)
{
list
.
add
(
new
byte
[
1024
]);
}
}
catch
(
OutOfMemoryError
e
)
{
// ok
}
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
for
(
int
i
=
0
;
i
<
16
;
i
++)
{
System
.
gc
();
System
.
gc
();
try
{
try
{
...
...
h2/src/test/org/h2/test/synth/TestFuzzOptimizations.java
浏览文件 @
9e5d9644
...
@@ -10,6 +10,7 @@ import java.sql.PreparedStatement;
...
@@ -10,6 +10,7 @@ import java.sql.PreparedStatement;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Random
;
import
java.util.Random
;
...
@@ -107,33 +108,37 @@ public class TestFuzzOptimizations extends TestBase {
...
@@ -107,33 +108,37 @@ public class TestFuzzOptimizations extends TestBase {
ArrayList
<
String
>
params
=
New
.
arrayList
();
ArrayList
<
String
>
params
=
New
.
arrayList
();
String
condition
=
getRandomCondition
(
random
,
params
,
columns
,
String
condition
=
getRandomCondition
(
random
,
params
,
columns
,
compares
,
values
);
compares
,
values
);
// System.out.println(condition + " " + params);
String
message
=
"seed: "
+
seed
+
" "
+
condition
;
PreparedStatement
prep0
=
conn
.
prepareStatement
(
executeAndCompare
(
condition
,
params
,
message
);
"select * from test0 where "
+
condition
+
" order by 1, 2, 3"
);
PreparedStatement
prep1
=
conn
.
prepareStatement
(
"select * from test1 where "
+
condition
+
" order by 1, 2, 3"
);
for
(
int
j
=
0
;
j
<
params
.
size
();
j
++)
{
prep0
.
setString
(
j
+
1
,
params
.
get
(
j
));
prep1
.
setString
(
j
+
1
,
params
.
get
(
j
));
}
ResultSet
rs0
=
prep0
.
executeQuery
();
ResultSet
rs1
=
prep1
.
executeQuery
();
assertEquals
(
"seed: "
+
seed
+
" "
+
condition
,
rs0
,
rs1
);
if
(
params
.
size
()
>
0
)
{
if
(
params
.
size
()
>
0
)
{
for
(
int
j
=
0
;
j
<
params
.
size
();
j
++)
{
for
(
int
j
=
0
;
j
<
params
.
size
();
j
++)
{
String
value
=
values
[
random
.
nextInt
(
values
.
length
-
2
)];
String
value
=
values
[
random
.
nextInt
(
values
.
length
-
2
)];
params
.
set
(
j
,
value
);
params
.
set
(
j
,
value
);
prep0
.
setString
(
j
+
1
,
value
);
prep1
.
setString
(
j
+
1
,
value
);
}
}
assertEquals
(
"seed: "
+
seed
+
" "
+
condition
,
rs0
,
rs1
);
executeAndCompare
(
condition
,
params
,
message
);
}
}
}
}
executeAndCompare
(
"a >=0 and b in(?, 2) and a in(1, ?, null)"
,
Arrays
.
asList
(
"10"
,
"2"
),
"seed=-6191135606105920350L"
);
db
.
execute
(
"drop table test0, test1"
);
db
.
execute
(
"drop table test0, test1"
);
}
}
private
void
executeAndCompare
(
String
condition
,
List
<
String
>
params
,
String
message
)
throws
SQLException
{
PreparedStatement
prep0
=
conn
.
prepareStatement
(
"select * from test0 where "
+
condition
+
" order by 1, 2, 3"
);
PreparedStatement
prep1
=
conn
.
prepareStatement
(
"select * from test1 where "
+
condition
+
" order by 1, 2, 3"
);
for
(
int
j
=
0
;
j
<
params
.
size
();
j
++)
{
prep0
.
setString
(
j
+
1
,
params
.
get
(
j
));
prep1
.
setString
(
j
+
1
,
params
.
get
(
j
));
}
ResultSet
rs0
=
prep0
.
executeQuery
();
ResultSet
rs1
=
prep1
.
executeQuery
();
assertEquals
(
message
,
rs0
,
rs1
);
}
private
String
getRandomCondition
(
Random
random
,
ArrayList
<
String
>
params
,
private
String
getRandomCondition
(
Random
random
,
ArrayList
<
String
>
params
,
String
[]
columns
,
String
[]
compares
,
String
[]
values
)
{
String
[]
columns
,
String
[]
compares
,
String
[]
values
)
{
int
comp
=
1
+
random
.
nextInt
(
4
);
int
comp
=
1
+
random
.
nextInt
(
4
);
...
...
h2/src/test/org/h2/test/unit/TestClearReferences.java
浏览文件 @
9e5d9644
...
@@ -26,6 +26,7 @@ public class TestClearReferences extends TestBase {
...
@@ -26,6 +26,7 @@ public class TestClearReferences extends TestBase {
"org.h2.compress.CompressLZF.cachedHashTable"
,
"org.h2.compress.CompressLZF.cachedHashTable"
,
"org.h2.engine.DbSettings.defaultSettings"
,
"org.h2.engine.DbSettings.defaultSettings"
,
"org.h2.engine.SessionRemote.sessionFactory"
,
"org.h2.engine.SessionRemote.sessionFactory"
,
"org.h2.expression.Function.MONTHS_AND_WEEKS"
,
"org.h2.jdbcx.JdbcDataSourceFactory.cachedTraceSystem"
,
"org.h2.jdbcx.JdbcDataSourceFactory.cachedTraceSystem"
,
"org.h2.store.RecoverTester.instance"
,
"org.h2.store.RecoverTester.instance"
,
"org.h2.store.fs.FilePath.defaultProvider"
,
"org.h2.store.fs.FilePath.defaultProvider"
,
...
@@ -36,6 +37,7 @@ public class TestClearReferences extends TestBase {
...
@@ -36,6 +37,7 @@ public class TestClearReferences extends TestBase {
"org.h2.tools.CompressTool.cachedBuffer"
,
"org.h2.tools.CompressTool.cachedBuffer"
,
"org.h2.util.CloseWatcher.queue"
,
"org.h2.util.CloseWatcher.queue"
,
"org.h2.util.CloseWatcher.refs"
,
"org.h2.util.CloseWatcher.refs"
,
"org.h2.util.DateTimeUtils.timeZone"
,
"org.h2.util.MathUtils.cachedSecureRandom"
,
"org.h2.util.MathUtils.cachedSecureRandom"
,
"org.h2.util.NetUtils.cachedLocalAddress"
,
"org.h2.util.NetUtils.cachedLocalAddress"
,
"org.h2.util.StringUtils.softCache"
,
"org.h2.util.StringUtils.softCache"
,
...
@@ -43,6 +45,7 @@ public class TestClearReferences extends TestBase {
...
@@ -43,6 +45,7 @@ public class TestClearReferences extends TestBase {
"org.h2.util.JdbcUtils.allowedClassNamePrefixes"
,
"org.h2.util.JdbcUtils.allowedClassNamePrefixes"
,
"org.h2.util.JdbcUtils.userClassFactories"
,
"org.h2.util.JdbcUtils.userClassFactories"
,
"org.h2.util.Task.counter"
,
"org.h2.util.Task.counter"
,
"org.h2.util.ToChar.NAMES"
,
"org.h2.value.CompareMode.lastUsed"
,
"org.h2.value.CompareMode.lastUsed"
,
"org.h2.value.Value.softCache"
,
"org.h2.value.Value.softCache"
,
};
};
...
...
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
浏览文件 @
9e5d9644
...
@@ -5,13 +5,16 @@
...
@@ -5,13 +5,16 @@
*/
*/
package
org
.
h2
.
test
.
unit
;
package
org
.
h2
.
test
.
unit
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
dateValue
;
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
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.value.ValueTimestamp
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
dateValue
;
/**
/**
* Unit tests for the DateTimeUtils class
* Unit tests for the DateTimeUtils class
...
@@ -21,9 +24,18 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -21,9 +24,18 @@ public class TestDateTimeUtils extends TestBase {
/**
/**
* Run just this test.
* Run just this test.
*
*
* @param a ignored
* @param a
* if {@code "testUtc2Value"} only {@link #testUTC2Value(boolean)}
* will be executed with all time zones (slow). Otherwise all tests
* in this test unit will be executed with local time zone.
*/
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
public
static
void
main
(
String
...
a
)
throws
Exception
{
if
(
a
.
length
==
1
)
{
if
(
"testUtc2Value"
.
equals
(
a
[
0
]))
{
new
TestDateTimeUtils
().
testUTC2Value
(
true
);
return
;
}
}
TestBase
.
createCaller
().
init
().
test
();
TestBase
.
createCaller
().
init
().
test
();
}
}
...
@@ -33,6 +45,7 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -33,6 +45,7 @@ public class TestDateTimeUtils extends TestBase {
testDayOfWeek
();
testDayOfWeek
();
testWeekOfYear
();
testWeekOfYear
();
testDateValueFromDenormalizedDate
();
testDateValueFromDenormalizedDate
();
testUTC2Value
(
false
);
}
}
private
void
testParseTimeNanosDB2Format
()
{
private
void
testParseTimeNanosDB2Format
()
{
...
@@ -44,7 +57,7 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -44,7 +57,7 @@ public class TestDateTimeUtils extends TestBase {
}
}
/**
/**
* Test for {@link DateTimeUtils#getSundayDayOfWeek()} and
* Test for {@link DateTimeUtils#getSundayDayOfWeek(
long
)} and
* {@link DateTimeUtils#getIsoDayOfWeek(long)}.
* {@link DateTimeUtils#getIsoDayOfWeek(long)}.
*/
*/
private
void
testDayOfWeek
()
{
private
void
testDayOfWeek
()
{
...
@@ -106,4 +119,45 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -106,4 +119,45 @@ public class TestDateTimeUtils extends TestBase {
assertEquals
(
dateValue
(-
100
,
2
,
29
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(-
100
,
2
,
30
));
assertEquals
(
dateValue
(-
100
,
2
,
29
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(-
100
,
2
,
30
));
}
}
private
void
testUTC2Value
(
boolean
allTimeZones
)
{
TimeZone
def
=
TimeZone
.
getDefault
();
GregorianCalendar
gc
=
new
GregorianCalendar
();
if
(
allTimeZones
)
{
try
{
for
(
String
id
:
TimeZone
.
getAvailableIDs
())
{
System
.
out
.
println
(
id
);
TimeZone
tz
=
TimeZone
.
getTimeZone
(
id
);
TimeZone
.
setDefault
(
tz
);
DateTimeUtils
.
resetCalendar
();
testUTC2ValueImpl
(
tz
,
gc
);
}
}
finally
{
TimeZone
.
setDefault
(
def
);
DateTimeUtils
.
resetCalendar
();
}
}
else
{
testUTC2ValueImpl
(
def
,
gc
);
}
}
private
void
testUTC2ValueImpl
(
TimeZone
tz
,
GregorianCalendar
gc
)
{
gc
.
setTimeZone
(
tz
);
gc
.
set
(
Calendar
.
MILLISECOND
,
0
);
long
absoluteStart
=
DateTimeUtils
.
absoluteDayFromDateValue
(
DateTimeUtils
.
dateValue
(
1950
,
01
,
01
));
long
absoluteEnd
=
DateTimeUtils
.
absoluteDayFromDateValue
(
DateTimeUtils
.
dateValue
(
2050
,
01
,
01
));
for
(
long
i
=
absoluteStart
;
i
<
absoluteEnd
;
i
++)
{
long
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
i
);
int
year
=
DateTimeUtils
.
yearFromDateValue
(
dateValue
);
int
month
=
DateTimeUtils
.
monthFromDateValue
(
dateValue
);
int
day
=
DateTimeUtils
.
dayFromDateValue
(
dateValue
);
for
(
int
j
=
0
;
j
<
48
;
j
++)
{
gc
.
set
(
year
,
month
-
1
,
day
,
j
/
2
,
(
j
&
1
)
*
30
,
0
);
long
timeMillis
=
gc
.
getTimeInMillis
();
ValueTimestamp
ts
=
DateTimeUtils
.
convertTimestamp
(
new
Timestamp
(
timeMillis
),
gc
);
assertEquals
(
ts
.
getDateValue
(),
DateTimeUtils
.
dateValueFromDate
(
timeMillis
));
assertEquals
(
ts
.
getTimeNanos
(),
DateTimeUtils
.
nanosFromDate
(
timeMillis
));
}
}
}
}
}
h2/src/test/org/h2/test/unit/TestTimeStampWithTimeZone.java
浏览文件 @
9e5d9644
...
@@ -126,21 +126,27 @@ public class TestTimeStampWithTimeZone extends TestBase {
...
@@ -126,21 +126,27 @@ public class TestTimeStampWithTimeZone extends TestBase {
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 12:00:00.00+00:15"
);
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 12:00:00.00+00:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 12:00:01.00+01:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 12:00:01.00+01:15"
);
int
c
=
a
.
compareTo
(
b
,
null
);
int
c
=
a
.
compareTo
(
b
,
null
);
assertEquals
(
c
,
1
);
assertEquals
(
1
,
c
);
c
=
b
.
compareTo
(
a
,
null
);
assertEquals
(-
1
,
c
);
}
}
private
void
test3
()
{
private
void
test3
()
{
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-02 00:00:02.00+01:15"
);
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-02 00:00:02.00+01:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 23:00:01.00+00:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 23:00:01.00+00:15"
);
int
c
=
a
.
compareTo
(
b
,
null
);
int
c
=
a
.
compareTo
(
b
,
null
);
assertEquals
(
c
,
1
);
assertEquals
(
1
,
c
);
c
=
b
.
compareTo
(
a
,
null
);
assertEquals
(-
1
,
c
);
}
}
private
void
test4
()
{
private
void
test4
()
{
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-02 00:00:01.00+01:15"
);
ValueTimestampTimeZone
a
=
ValueTimestampTimeZone
.
parse
(
"1970-01-02 00:00:01.00+01:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 23:00:01.00+00:15"
);
ValueTimestampTimeZone
b
=
ValueTimestampTimeZone
.
parse
(
"1970-01-01 23:00:01.00+00:15"
);
int
c
=
a
.
compareTo
(
b
,
null
);
int
c
=
a
.
compareTo
(
b
,
null
);
assertEquals
(
c
,
0
);
assertEquals
(
0
,
c
);
c
=
b
.
compareTo
(
a
,
null
);
assertEquals
(
0
,
c
);
}
}
private
void
test5
()
throws
SQLException
{
private
void
test5
()
throws
SQLException
{
...
...
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
9e5d9644
...
@@ -764,5 +764,5 @@ mdy destfile hclf forbids spellchecking selfdestruct expects accident jacocoagen
...
@@ -764,5 +764,5 @@ mdy destfile hclf forbids spellchecking selfdestruct expects accident jacocoagen
jacoco xdata invokes sourcefiles classfiles duplication crypto stacktraces prt directions handled overly asm hardcoded
jacoco xdata invokes sourcefiles classfiles duplication crypto stacktraces prt directions handled overly asm hardcoded
interpolated thead
interpolated thead
die weekdiff osx subprocess dow proleptic
die weekdiff osx subprocess dow proleptic
microsecond microseconds divisible cmp denormalized suppressed saturated mcs
london
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论