Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
1a82bf51
Unverified
提交
1a82bf51
authored
2月 07, 2018
作者:
ScaY
提交者:
GitHub
2月 07, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into scay-issue#832
上级
fc67a911
8678a122
显示空白字符变更
内嵌
并排
正在显示
26 个修改的文件
包含
1060 行增加
和
498 行删除
+1060
-498
mvnw
h2/mvnw
+1
-0
mvnw.cmd
h2/mvnw.cmd
+1
-1
pom.xml
h2/pom.xml
+2
-0
help.csv
h2/src/docsrc/help/help.csv
+2
-1
performance.html
h2/src/docsrc/html/performance.html
+1
-1
Parser.java
h2/src/main/org/h2/command/Parser.java
+57
-47
Select.java
h2/src/main/org/h2/command/dml/Select.java
+4
-0
ConditionInParameter.java
h2/src/main/org/h2/expression/ConditionInParameter.java
+164
-0
Function.java
h2/src/main/org/h2/expression/Function.java
+133
-133
FullText.java
h2/src/main/org/h2/fulltext/FullText.java
+6
-0
FullTextLucene.java
h2/src/main/org/h2/fulltext/FullTextLucene.java
+13
-0
JdbcResultSet.java
h2/src/main/org/h2/jdbc/JdbcResultSet.java
+8
-1
JdbcDataSource.java
h2/src/main/org/h2/jdbcx/JdbcDataSource.java
+2
-0
TransactionStore.java
h2/src/main/org/h2/mvstore/db/TransactionStore.java
+3
-0
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+60
-119
TableSynonym.java
h2/src/main/org/h2/table/TableSynonym.java
+5
-1
TableView.java
h2/src/main/org/h2/table/TableView.java
+36
-0
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+202
-88
LocalDateTimeUtils.java
h2/src/main/org/h2/util/LocalDateTimeUtils.java
+9
-2
CharsetCollator.java
h2/src/main/org/h2/value/CharsetCollator.java
+3
-0
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+94
-0
datediff.sql
...st/org/h2/test/scripts/functions/timeanddate/datediff.sql
+36
-0
TestKillRestart.java
h2/src/test/org/h2/test/synth/TestKillRestart.java
+58
-2
TestDateIso8601.java
h2/src/test/org/h2/test/unit/TestDateIso8601.java
+98
-99
TestDateTimeUtils.java
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
+56
-0
TestPgServer.java
h2/src/test/org/h2/test/unit/TestPgServer.java
+6
-3
没有找到文件。
h2/mvnw
浏览文件 @
1a82bf51
...
@@ -228,6 +228,7 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
...
@@ -228,6 +228,7 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec
"
$JAVACMD
"
\
exec
"
$JAVACMD
"
\
$MAVEN_OPTS
\
$MAVEN_OPTS
\
-Djava
.net.useSystemProxies
=
true
\
-classpath
"
$MAVEN_PROJECTBASEDIR
/.mvn/wrapper/maven-wrapper.jar"
\
-classpath
"
$MAVEN_PROJECTBASEDIR
/.mvn/wrapper/maven-wrapper.jar"
\
"-Dmaven.home=
${
M2_HOME
}
"
"-Dmaven.multiModuleProjectDirectory=
${
MAVEN_PROJECTBASEDIR
}
"
\
"-Dmaven.home=
${
M2_HOME
}
"
"-Dmaven.multiModuleProjectDirectory=
${
MAVEN_PROJECTBASEDIR
}
"
\
${
WRAPPER_LAUNCHER
}
$MAVEN_CMD_LINE_ARGS
${
WRAPPER_LAUNCHER
}
$MAVEN_CMD_LINE_ARGS
...
...
h2/mvnw.cmd
浏览文件 @
1a82bf51
...
@@ -121,7 +121,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
...
@@ -121,7 +121,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar""
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS%
-Djava.net.useSystemProxies=true
-classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
if ERRORLEVEL 1 goto error
if ERRORLEVEL 1 goto error
goto end
goto end
...
...
h2/pom.xml
浏览文件 @
1a82bf51
...
@@ -222,6 +222,7 @@
...
@@ -222,6 +222,7 @@
</executions>
</executions>
</plugin>
</plugin>
<!-- Make sure neither we nor one of our dependencies uses anything outside JDK 1.7 -->
<!-- Make sure neither we nor one of our dependencies uses anything outside JDK 1.7 -->
<!-- commented out for now because it fails to build under JDK1.8+ because we are manually adding the tools jar
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<artifactId>maven-enforcer-plugin</artifactId>
...
@@ -262,6 +263,7 @@
...
@@ -262,6 +263,7 @@
</dependency>
</dependency>
</dependencies>
</dependencies>
</plugin>
</plugin>
-->
<plugin>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<artifactId>
maven-surefire-plugin
</artifactId>
...
...
h2/src/docsrc/help/help.csv
浏览文件 @
1a82bf51
...
@@ -3685,6 +3685,7 @@ Returns the the number of crossed unit boundaries between two timestamps.
...
@@ -3685,6 +3685,7 @@ Returns the the number of crossed unit boundaries between two timestamps.
This method returns a long.
This method returns a long.
The string indicates the unit.
The string indicates the unit.
The same units as in the EXTRACT function are supported.
The same units as in the EXTRACT function are supported.
If timestamps have time zone offset component it is ignored.
","
","
DATEDIFF('YEAR', T1.CREATED, T2.CREATED)
DATEDIFF('YEAR', T1.CREATED, T2.CREATED)
"
"
...
@@ -3722,7 +3723,7 @@ DAY_OF_YEAR(CREATED)
...
@@ -3722,7 +3723,7 @@ DAY_OF_YEAR(CREATED)
"
"
"Functions (Time and Date)","EXTRACT","
"Functions (Time and Date)","EXTRACT","
EXTRACT ( { YEAR | YY | MONTH | MM | WEEK | DAY | DD | DAY_OF_YEAR
EXTRACT ( { YEAR | YY | MONTH | MM | WEEK |
ISO_WEEK |
DAY | DD | DAY_OF_YEAR
| DOY | HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS }
| DOY | HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS }
FROM timestamp )
FROM timestamp )
","
","
...
...
h2/src/docsrc/html/performance.html
浏览文件 @
1a82bf51
...
@@ -490,7 +490,7 @@ Instead, use a prepared statement with arrays as in the following example:
...
@@ -490,7 +490,7 @@ Instead, use a prepared statement with arrays as in the following example:
</p>
</p>
<pre>
<pre>
PreparedStatement prep = conn.prepareStatement(
PreparedStatement prep = conn.prepareStatement(
"SELECT *
FROM TABLE(X INT=?) T INNER JOIN TEST ON T.X=TEST.ID
");
"SELECT *
TEST.ID = ANY(?)
");
prep.setObject(1, new Object[] { "1", "2" });
prep.setObject(1, new Object[] { "1", "2" });
ResultSet rs = prep.executeQuery();
ResultSet rs = prep.executeQuery();
</pre>
</pre>
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
1a82bf51
...
@@ -112,6 +112,7 @@ import org.h2.expression.Comparison;
...
@@ -112,6 +112,7 @@ import org.h2.expression.Comparison;
import
org.h2.expression.ConditionAndOr
;
import
org.h2.expression.ConditionAndOr
;
import
org.h2.expression.ConditionExists
;
import
org.h2.expression.ConditionExists
;
import
org.h2.expression.ConditionIn
;
import
org.h2.expression.ConditionIn
;
import
org.h2.expression.ConditionInParameter
;
import
org.h2.expression.ConditionInSelect
;
import
org.h2.expression.ConditionInSelect
;
import
org.h2.expression.ConditionNot
;
import
org.h2.expression.ConditionNot
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
...
@@ -2504,9 +2505,14 @@ public class Parser {
...
@@ -2504,9 +2505,14 @@ public class Parser {
read
(
")"
);
read
(
")"
);
}
else
if
(
readIf
(
"ANY"
)
||
readIf
(
"SOME"
))
{
}
else
if
(
readIf
(
"ANY"
)
||
readIf
(
"SOME"
))
{
read
(
"("
);
read
(
"("
);
if
(
currentTokenType
==
PARAMETER
&&
compareType
==
0
)
{
Parameter
p
=
readParameter
();
r
=
new
ConditionInParameter
(
database
,
r
,
p
);
}
else
{
Query
query
=
parseSelect
();
Query
query
=
parseSelect
();
r
=
new
ConditionInSelect
(
database
,
r
,
query
,
false
,
r
=
new
ConditionInSelect
(
database
,
r
,
query
,
false
,
compareType
);
compareType
);
}
read
(
")"
);
read
(
")"
);
}
else
{
}
else
{
Expression
right
=
readConcat
();
Expression
right
=
readConcat
();
...
@@ -3001,21 +3007,7 @@ public class Parser {
...
@@ -3001,21 +3007,7 @@ public class Parser {
return
new
ExpressionColumn
(
database
,
null
,
objectName
,
name
);
return
new
ExpressionColumn
(
database
,
null
,
objectName
,
name
);
}
}
private
Expression
readTerm
()
{
private
Parameter
readParameter
()
{
Expression
r
;
switch
(
currentTokenType
)
{
case
AT:
read
();
r
=
new
Variable
(
session
,
readAliasIdentifier
());
if
(
readIf
(
":="
))
{
Expression
value
=
readExpression
();
Function
function
=
Function
.
getFunction
(
database
,
"SET"
);
function
.
setParameter
(
0
,
r
);
function
.
setParameter
(
1
,
value
);
r
=
function
;
}
break
;
case
PARAMETER:
// there must be no space between ? and the number
// there must be no space between ? and the number
boolean
indexed
=
Character
.
isDigit
(
sqlCommandChars
[
parseIndex
]);
boolean
indexed
=
Character
.
isDigit
(
sqlCommandChars
[
parseIndex
]);
...
@@ -3059,7 +3051,25 @@ public class Parser {
...
@@ -3059,7 +3051,25 @@ public class Parser {
p
=
new
Parameter
(
parameters
.
size
());
p
=
new
Parameter
(
parameters
.
size
());
}
}
parameters
.
add
(
p
);
parameters
.
add
(
p
);
r
=
p
;
return
p
;
}
private
Expression
readTerm
()
{
Expression
r
;
switch
(
currentTokenType
)
{
case
AT:
read
();
r
=
new
Variable
(
session
,
readAliasIdentifier
());
if
(
readIf
(
":="
))
{
Expression
value
=
readExpression
();
Function
function
=
Function
.
getFunction
(
database
,
"SET"
);
function
.
setParameter
(
0
,
r
);
function
.
setParameter
(
1
,
value
);
r
=
function
;
}
break
;
case
PARAMETER:
r
=
readParameter
();
break
;
break
;
case
KEYWORD:
case
KEYWORD:
if
(
isToken
(
"SELECT"
)
||
isToken
(
"FROM"
)
||
isToken
(
"WITH"
))
{
if
(
isToken
(
"SELECT"
)
||
isToken
(
"FROM"
)
||
isToken
(
"WITH"
))
{
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
1a82bf51
...
@@ -44,7 +44,11 @@ import java.util.HashSet;
...
@@ -44,7 +44,11 @@ import java.util.HashSet;
*/
*/
public
class
Select
extends
Query
{
public
class
Select
extends
Query
{
/**
* The main (top) table filter.
*/
TableFilter
topTableFilter
;
TableFilter
topTableFilter
;
private
final
ArrayList
<
TableFilter
>
filters
=
New
.
arrayList
();
private
final
ArrayList
<
TableFilter
>
filters
=
New
.
arrayList
();
private
final
ArrayList
<
TableFilter
>
topFilters
=
New
.
arrayList
();
private
final
ArrayList
<
TableFilter
>
topFilters
=
New
.
arrayList
();
...
...
h2/src/main/org/h2/expression/ConditionInParameter.java
0 → 100644
浏览文件 @
1a82bf51
/*
* 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
.
expression
;
import
java.util.AbstractList
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.index.IndexCondition
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueNull
;
/**
* A condition with parameter as {@code = ANY(?)}.
*/
public
class
ConditionInParameter
extends
Condition
{
private
static
final
class
ParameterList
extends
AbstractList
<
Expression
>
{
private
final
Parameter
parameter
;
ParameterList
(
Parameter
parameter
)
{
this
.
parameter
=
parameter
;
}
@Override
public
Expression
get
(
int
index
)
{
Value
value
=
parameter
.
getParamValue
();
if
(
value
instanceof
ValueArray
)
{
return
ValueExpression
.
get
(((
ValueArray
)
value
).
getList
()[
index
]);
}
if
(
index
!=
0
)
{
throw
new
IndexOutOfBoundsException
();
}
return
ValueExpression
.
get
(
value
);
}
@Override
public
int
size
()
{
if
(!
parameter
.
isValueSet
())
{
return
0
;
}
Value
value
=
parameter
.
getParamValue
();
if
(
value
instanceof
ValueArray
)
{
return
((
ValueArray
)
value
).
getList
().
length
;
}
return
1
;
}
}
private
final
Database
database
;
private
Expression
left
;
final
Parameter
parameter
;
/**
* Create a new {@code = ANY(?)} condition.
*
* @param database
* the database
* @param left
* the expression before {@code = ANY(?)}
* @param parameter
* parameter
*/
public
ConditionInParameter
(
Database
database
,
Expression
left
,
Parameter
parameter
)
{
this
.
database
=
database
;
this
.
left
=
left
;
this
.
parameter
=
parameter
;
}
@Override
public
Value
getValue
(
Session
session
)
{
Value
l
=
left
.
getValue
(
session
);
if
(
l
==
ValueNull
.
INSTANCE
)
{
return
l
;
}
boolean
result
=
false
;
boolean
hasNull
=
false
;
Value
value
=
parameter
.
getValue
(
session
);
if
(
value
instanceof
ValueArray
)
{
for
(
Value
r
:
((
ValueArray
)
value
).
getList
())
{
if
(
r
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
}
else
{
r
=
r
.
convertTo
(
l
.
getType
());
result
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
if
(
result
)
{
break
;
}
}
}
}
else
{
if
(
value
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
}
else
{
value
=
value
.
convertTo
(
l
.
getType
());
result
=
Comparison
.
compareNotNull
(
database
,
l
,
value
,
Comparison
.
EQUAL
);
}
}
if
(!
result
&&
hasNull
)
{
return
ValueNull
.
INSTANCE
;
}
return
ValueBoolean
.
get
(
result
);
}
@Override
public
void
mapColumns
(
ColumnResolver
resolver
,
int
level
)
{
left
.
mapColumns
(
resolver
,
level
);
}
@Override
public
Expression
optimize
(
Session
session
)
{
left
=
left
.
optimize
(
session
);
if
(
left
.
isConstant
()
&&
left
==
ValueExpression
.
getNull
())
{
return
left
;
}
return
this
;
}
@Override
public
void
createIndexConditions
(
Session
session
,
TableFilter
filter
)
{
if
(!(
left
instanceof
ExpressionColumn
))
{
return
;
}
ExpressionColumn
l
=
(
ExpressionColumn
)
left
;
if
(
filter
!=
l
.
getTableFilter
())
{
return
;
}
filter
.
addIndexCondition
(
IndexCondition
.
getInList
(
l
,
new
ParameterList
(
parameter
)));
}
@Override
public
void
setEvaluatable
(
TableFilter
tableFilter
,
boolean
b
)
{
left
.
setEvaluatable
(
tableFilter
,
b
);
}
@Override
public
String
getSQL
()
{
return
'('
+
left
.
getSQL
()
+
" = ANY("
+
parameter
.
getSQL
()
+
"))"
;
}
@Override
public
void
updateAggregate
(
Session
session
)
{
left
.
updateAggregate
(
session
);
}
@Override
public
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
return
left
.
isEverything
(
visitor
)
&&
parameter
.
isEverything
(
visitor
);
}
@Override
public
int
getCost
()
{
return
left
.
getCost
();
}
}
h2/src/main/org/h2/expression/Function.java
浏览文件 @
1a82bf51
...
@@ -20,7 +20,6 @@ import java.util.ArrayList;
...
@@ -20,7 +20,6 @@ import java.util.ArrayList;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
java.util.Locale
;
import
java.util.TimeZone
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
import
java.util.regex.PatternSyntaxException
;
import
java.util.regex.PatternSyntaxException
;
...
@@ -108,6 +107,11 @@ public class Function extends Expression implements FunctionCall {
...
@@ -108,6 +107,11 @@ public class Function extends Expression implements FunctionCall {
FORMATDATETIME
=
121
,
PARSEDATETIME
=
122
,
ISO_YEAR
=
123
,
FORMATDATETIME
=
121
,
PARSEDATETIME
=
122
,
ISO_YEAR
=
123
,
ISO_WEEK
=
124
,
ISO_DAY_OF_WEEK
=
125
,
EPOCH
=
126
;
ISO_WEEK
=
124
,
ISO_DAY_OF_WEEK
=
125
,
EPOCH
=
126
;
/**
* Pseudo function for {@code EXTRACT(MILLISECOND FROM ...)}.
*/
public
static
final
int
MILLISECOND
=
126
;
public
static
final
int
DATABASE
=
150
,
USER
=
151
,
CURRENT_USER
=
152
,
public
static
final
int
DATABASE
=
150
,
USER
=
151
,
CURRENT_USER
=
152
,
IDENTITY
=
153
,
SCOPE_IDENTITY
=
154
,
AUTOCOMMIT
=
155
,
IDENTITY
=
153
,
SCOPE_IDENTITY
=
154
,
AUTOCOMMIT
=
155
,
READONLY
=
156
,
DATABASE_PATH
=
157
,
LOCK_TIMEOUT
=
158
,
READONLY
=
156
,
DATABASE_PATH
=
157
,
LOCK_TIMEOUT
=
158
,
...
@@ -158,40 +162,40 @@ public class Function extends Expression implements FunctionCall {
...
@@ -158,40 +162,40 @@ public class Function extends Expression implements FunctionCall {
static
{
static
{
// DATE_PART
// DATE_PART
DATE_PART
.
put
(
"SQL_TSI_YEAR"
,
Calendar
.
YEAR
);
DATE_PART
.
put
(
"SQL_TSI_YEAR"
,
YEAR
);
DATE_PART
.
put
(
"YEAR"
,
Calendar
.
YEAR
);
DATE_PART
.
put
(
"YEAR"
,
YEAR
);
DATE_PART
.
put
(
"YYYY"
,
Calendar
.
YEAR
);
DATE_PART
.
put
(
"YYYY"
,
YEAR
);
DATE_PART
.
put
(
"YY"
,
Calendar
.
YEAR
);
DATE_PART
.
put
(
"YY"
,
YEAR
);
DATE_PART
.
put
(
"SQL_TSI_MONTH"
,
Calendar
.
MONTH
);
DATE_PART
.
put
(
"SQL_TSI_MONTH"
,
MONTH
);
DATE_PART
.
put
(
"MONTH"
,
Calendar
.
MONTH
);
DATE_PART
.
put
(
"MONTH"
,
MONTH
);
DATE_PART
.
put
(
"MM"
,
Calendar
.
MONTH
);
DATE_PART
.
put
(
"MM"
,
MONTH
);
DATE_PART
.
put
(
"M"
,
Calendar
.
MONTH
);
DATE_PART
.
put
(
"M"
,
MONTH
);
DATE_PART
.
put
(
"SQL_TSI_WEEK"
,
Calendar
.
WEEK_OF_YEAR
);
DATE_PART
.
put
(
"SQL_TSI_WEEK"
,
WEEK
);
DATE_PART
.
put
(
"WW"
,
Calendar
.
WEEK_OF_YEAR
);
DATE_PART
.
put
(
"WW"
,
WEEK
);
DATE_PART
.
put
(
"WK"
,
Calendar
.
WEEK_OF_YEAR
);
DATE_PART
.
put
(
"WK"
,
WEEK
);
DATE_PART
.
put
(
"WEEK"
,
Calendar
.
WEEK_OF_YEAR
);
DATE_PART
.
put
(
"WEEK"
,
WEEK
);
DATE_PART
.
put
(
"
DAY"
,
Calendar
.
DAY_OF_MONTH
);
DATE_PART
.
put
(
"
ISO_WEEK"
,
ISO_WEEK
);
DATE_PART
.
put
(
"D
D"
,
Calendar
.
DAY_OF_MONTH
);
DATE_PART
.
put
(
"D
AY"
,
DAY_OF_MONTH
);
DATE_PART
.
put
(
"D
"
,
Calendar
.
DAY_OF_MONTH
);
DATE_PART
.
put
(
"D
D"
,
DAY_OF_MONTH
);
DATE_PART
.
put
(
"
SQL_TSI_DAY"
,
Calendar
.
DAY_OF_MONTH
);
DATE_PART
.
put
(
"
D"
,
DAY_OF_MONTH
);
DATE_PART
.
put
(
"
DAYOFYEAR"
,
Calendar
.
DAY_OF_YEAR
);
DATE_PART
.
put
(
"
SQL_TSI_DAY"
,
DAY_OF_MONTH
);
DATE_PART
.
put
(
"DAY
_OF_YEAR"
,
Calendar
.
DAY_OF_YEAR
);
DATE_PART
.
put
(
"DAY
OFYEAR"
,
DAY_OF_YEAR
);
DATE_PART
.
put
(
"D
Y"
,
Calendar
.
DAY_OF_YEAR
);
DATE_PART
.
put
(
"D
AY_OF_YEAR"
,
DAY_OF_YEAR
);
DATE_PART
.
put
(
"D
OY"
,
Calendar
.
DAY_OF_YEAR
);
DATE_PART
.
put
(
"D
Y"
,
DAY_OF_YEAR
);
DATE_PART
.
put
(
"
SQL_TSI_HOUR"
,
Calendar
.
HOUR_OF_DAY
);
DATE_PART
.
put
(
"
DOY"
,
DAY_OF_YEAR
);
DATE_PART
.
put
(
"
HOUR"
,
Calendar
.
HOUR_OF_DAY
);
DATE_PART
.
put
(
"
SQL_TSI_HOUR"
,
HOUR
);
DATE_PART
.
put
(
"H
H"
,
Calendar
.
HOUR_OF_DAY
);
DATE_PART
.
put
(
"H
OUR"
,
HOUR
);
DATE_PART
.
put
(
"
SQL_TSI_MINUTE"
,
Calendar
.
MINUTE
);
DATE_PART
.
put
(
"
HH"
,
HOUR
);
DATE_PART
.
put
(
"
MINUTE"
,
Calendar
.
MINUTE
);
DATE_PART
.
put
(
"
SQL_TSI_MINUTE"
,
MINUTE
);
DATE_PART
.
put
(
"MI
"
,
Calendar
.
MINUTE
);
DATE_PART
.
put
(
"MI
NUTE"
,
MINUTE
);
DATE_PART
.
put
(
"
N"
,
Calendar
.
MINUTE
);
DATE_PART
.
put
(
"
MI"
,
MINUTE
);
DATE_PART
.
put
(
"
SQL_TSI_SECOND"
,
Calendar
.
SECOND
);
DATE_PART
.
put
(
"
N"
,
MINUTE
);
DATE_PART
.
put
(
"S
ECOND"
,
Calendar
.
SECOND
);
DATE_PART
.
put
(
"S
QL_TSI_SECOND"
,
SECOND
);
DATE_PART
.
put
(
"S
S"
,
Calendar
.
SECOND
);
DATE_PART
.
put
(
"S
ECOND"
,
SECOND
);
DATE_PART
.
put
(
"S
"
,
Calendar
.
SECOND
);
DATE_PART
.
put
(
"S
S"
,
SECOND
);
DATE_PART
.
put
(
"
MILLISECOND"
,
Calendar
.
MILLI
SECOND
);
DATE_PART
.
put
(
"
S"
,
SECOND
);
DATE_PART
.
put
(
"M
S"
,
Calendar
.
MILLISECOND
);
DATE_PART
.
put
(
"M
ILLISECOND"
,
MILLISECOND
);
DATE_PART
.
put
(
"
EPOCH"
,
EPOCH
);
DATE_PART
.
put
(
"
MS"
,
MILLISECOND
);
// SOUNDEX_INDEX
// SOUNDEX_INDEX
String
index
=
"7AEIOUY8HW1BFPV2CGJKQSXZ3DT4L5MN6R"
;
String
index
=
"7AEIOUY8HW1BFPV2CGJKQSXZ3DT4L5MN6R"
;
...
@@ -838,22 +842,19 @@ public class Function extends Expression implements FunctionCall {
...
@@ -838,22 +842,19 @@ public class Function extends Expression implements FunctionCall {
break
;
break
;
}
}
case
DAY_OF_MONTH:
case
DAY_OF_MONTH:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
DAY_OF_MONTH
));
break
;
case
DAY_OF_WEEK:
case
DAY_OF_WEEK:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
DAY_OF_WEEK
));
break
;
case
DAY_OF_YEAR:
case
DAY_OF_YEAR:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
DAY_OF_YEAR
));
break
;
case
HOUR:
case
HOUR:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
HOUR_OF_DAY
));
break
;
case
MINUTE:
case
MINUTE:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
MINUTE
));
break
;
case
MONTH:
case
MONTH:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
MONTH
));
case
QUARTER:
case
ISO_YEAR:
case
ISO_WEEK:
case
ISO_DAY_OF_WEEK:
case
SECOND:
case
WEEK:
case
YEAR:
result
=
ValueInt
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
info
.
type
));
break
;
break
;
case
MONTH_NAME:
{
case
MONTH_NAME:
{
SimpleDateFormat
monthName
=
new
SimpleDateFormat
(
"MMMM"
,
SimpleDateFormat
monthName
=
new
SimpleDateFormat
(
"MMMM"
,
...
@@ -862,27 +863,6 @@ public class Function extends Expression implements FunctionCall {
...
@@ -862,27 +863,6 @@ public class Function extends Expression implements FunctionCall {
database
.
getMode
().
treatEmptyStringsAsNull
);
database
.
getMode
().
treatEmptyStringsAsNull
);
break
;
break
;
}
}
case
QUARTER:
result
=
ValueLong
.
get
((
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
MONTH
)
-
1
)
/
3
+
1
);
break
;
case
SECOND:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
SECOND
));
break
;
case
WEEK:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
WEEK_OF_YEAR
));
break
;
case
YEAR:
result
=
ValueLong
.
get
(
DateTimeUtils
.
getDatePart
(
v0
,
Calendar
.
YEAR
));
break
;
case
ISO_YEAR:
result
=
ValueInt
.
get
(
DateTimeUtils
.
getIsoYear
(
v0
));
break
;
case
ISO_WEEK:
result
=
ValueInt
.
get
(
DateTimeUtils
.
getIsoWeek
(
v0
));
break
;
case
ISO_DAY_OF_WEEK:
result
=
ValueInt
.
get
(
DateTimeUtils
.
getIsoDayOfWeek
(
v0
));
break
;
case
CURDATE:
case
CURDATE:
case
CURRENT_DATE:
{
case
CURRENT_DATE:
{
long
now
=
session
.
getTransactionStart
();
long
now
=
session
.
getTransactionStart
();
...
@@ -1509,8 +1489,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -1509,8 +1489,7 @@ public class Function extends Expression implements FunctionCall {
v0
.
getString
(),
v1
.
getLong
(),
v2
.
getTimestamp
()));
v0
.
getString
(),
v1
.
getLong
(),
v2
.
getTimestamp
()));
break
;
break
;
case
DATE_DIFF:
case
DATE_DIFF:
result
=
ValueLong
.
get
(
datediff
(
result
=
ValueLong
.
get
(
datediff
(
v0
.
getString
(),
v1
,
v2
));
v0
.
getString
(),
v1
.
getTimestamp
(),
v2
.
getTimestamp
()));
break
;
break
;
case
EXTRACT:
{
case
EXTRACT:
{
int
field
=
getDatePart
(
v0
.
getString
());
int
field
=
getDatePart
(
v0
.
getString
());
...
@@ -1828,11 +1807,39 @@ public class Function extends Expression implements FunctionCall {
...
@@ -1828,11 +1807,39 @@ public class Function extends Expression implements FunctionCall {
private
static
Timestamp
dateadd
(
String
part
,
long
count
,
Timestamp
d
)
{
private
static
Timestamp
dateadd
(
String
part
,
long
count
,
Timestamp
d
)
{
int
field
=
getDatePart
(
part
);
int
field
=
getDatePart
(
part
);
if
(
field
==
Calendar
.
MILLISECOND
)
{
switch
(
field
)
{
case
YEAR:
field
=
Calendar
.
YEAR
;
break
;
case
MONTH:
field
=
Calendar
.
MONTH
;
break
;
case
DAY_OF_MONTH:
field
=
Calendar
.
DAY_OF_MONTH
;
break
;
case
DAY_OF_YEAR:
field
=
Calendar
.
DAY_OF_YEAR
;
break
;
case
WEEK:
field
=
Calendar
.
WEEK_OF_YEAR
;
break
;
case
HOUR:
field
=
Calendar
.
HOUR_OF_DAY
;
break
;
case
MINUTE:
field
=
Calendar
.
MINUTE
;
break
;
case
SECOND:
field
=
Calendar
.
SECOND
;
break
;
case
MILLISECOND:
{
Timestamp
ts
=
new
Timestamp
(
d
.
getTime
()
+
count
);
Timestamp
ts
=
new
Timestamp
(
d
.
getTime
()
+
count
);
ts
.
setNanos
(
ts
.
getNanos
()
+
(
d
.
getNanos
()
%
1000000
));
ts
.
setNanos
(
ts
.
getNanos
()
+
(
d
.
getNanos
()
%
1000000
));
return
ts
;
return
ts
;
}
}
default
:
throw
DbException
.
getUnsupportedException
(
"DATEADD "
+
part
);
}
// We allow long for manipulating the millisecond component,
// We allow long for manipulating the millisecond component,
// for the rest we only allow int.
// for the rest we only allow int.
if
(
count
>
Integer
.
MAX_VALUE
)
{
if
(
count
>
Integer
.
MAX_VALUE
)
{
...
@@ -1855,77 +1862,70 @@ public class Function extends Expression implements FunctionCall {
...
@@ -1855,77 +1862,70 @@ public class Function extends Expression implements FunctionCall {
* </pre>
* </pre>
*
*
* @param part the part
* @param part the part
* @param
d1 the first dat
e
* @param
v1 the first date-time valu
e
* @param
d2 the second dat
e
* @param
v2 the second date-time valu
e
* @return the number of crossed boundaries
* @return the number of crossed boundaries
*/
*/
private
static
long
datediff
(
String
part
,
Timestamp
d1
,
Timestamp
d
2
)
{
private
static
long
datediff
(
String
part
,
Value
v1
,
Value
v
2
)
{
int
field
=
getDatePart
(
part
);
int
field
=
getDatePart
(
part
);
Calendar
calendar
=
DateTimeUtils
.
createGregorianCalendar
();
long
[]
a1
=
DateTimeUtils
.
dateAndTimeFromValue
(
v1
);
long
t1
=
d1
.
getTime
(),
t2
=
d2
.
getTime
();
long
dateValue1
=
a1
[
0
];
// need to convert to UTC, otherwise we get inconsistent results with
long
absolute1
=
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue1
);
// certain time zones (those that are 30 minutes off)
long
[]
a2
=
DateTimeUtils
.
dateAndTimeFromValue
(
v2
);
TimeZone
zone
=
calendar
.
getTimeZone
();
long
dateValue2
=
a2
[
0
];
calendar
.
setTime
(
d1
);
long
absolute2
=
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue2
);
t1
+=
zone
.
getOffset
(
calendar
.
get
(
Calendar
.
ERA
),
calendar
.
get
(
Calendar
.
YEAR
),
calendar
.
get
(
Calendar
.
MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_WEEK
),
calendar
.
get
(
Calendar
.
MILLISECOND
));
calendar
.
setTime
(
d2
);
t2
+=
zone
.
getOffset
(
calendar
.
get
(
Calendar
.
ERA
),
calendar
.
get
(
Calendar
.
YEAR
),
calendar
.
get
(
Calendar
.
MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_MONTH
),
calendar
.
get
(
Calendar
.
DAY_OF_WEEK
),
calendar
.
get
(
Calendar
.
MILLISECOND
));
switch
(
field
)
{
switch
(
field
)
{
case
Calendar
.
MILLISECOND
:
case
MILLISECOND:
return
t2
-
t1
;
case
SECOND:
case
Calendar
.
SECOND
:
case
MINUTE:
case
Calendar
.
MINUTE
:
case
HOUR:
case
Calendar
.
HOUR_OF_DAY
:
long
timeNanos1
=
a1
[
1
];
case
Calendar
.
DAY_OF_YEAR
:
long
timeNanos2
=
a2
[
1
];
case
Calendar
.
WEEK_OF_YEAR
:
{
// first 'normalize' the numbers so both are not negative
long
hour
=
60
*
60
*
1000
;
long
add
=
Math
.
min
(
t1
/
hour
*
hour
,
t2
/
hour
*
hour
);
t1
-=
add
;
t2
-=
add
;
switch
(
field
)
{
switch
(
field
)
{
case
Calendar
.
SECOND
:
case
MILLISECOND:
return
t2
/
1000
-
t1
/
1000
;
return
(
absolute2
-
absolute1
)
*
DateTimeUtils
.
MILLIS_PER_DAY
case
Calendar
.
MINUTE
:
+
(
timeNanos2
/
1_000_000
-
timeNanos1
/
1_000_000
);
return
t2
/
(
60
*
1000
)
-
t1
/
(
60
*
1000
);
case
SECOND:
case
Calendar
.
HOUR_OF_DAY
:
return
(
absolute2
-
absolute1
)
*
86_400
return
t2
/
hour
-
t1
/
hour
;
+
(
timeNanos2
/
1_000_000_000
-
timeNanos1
/
1_000_000_000
);
case
Calendar
.
DAY_OF_YEAR
:
case
MINUTE:
return
t2
/
(
hour
*
24
)
-
t1
/
(
hour
*
24
);
return
(
absolute2
-
absolute1
)
*
1_440
case
Calendar
.
WEEK_OF_YEAR
:
+
(
timeNanos2
/
60_000_000_000L
-
timeNanos1
/
60_000_000_000L
);
return
t2
/
(
hour
*
24
*
7
)
-
t1
/
(
hour
*
24
*
7
);
case
HOUR:
return
(
absolute2
-
absolute1
)
*
24
+
(
timeNanos2
/
3_600_000_000_000L
-
timeNanos1
/
3_600_000_000_000L
);
}
// Fake fall-through
//$FALL-THROUGH$
case
DAY_OF_MONTH:
case
DAY_OF_YEAR:
return
absolute2
-
absolute1
;
case
WEEK:
return
weekdiff
(
absolute1
,
absolute2
,
0
);
case
ISO_WEEK:
return
weekdiff
(
absolute1
,
absolute2
,
1
);
case
MONTH:
return
(
DateTimeUtils
.
yearFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
yearFromDateValue
(
dateValue1
))
*
12
+
DateTimeUtils
.
monthFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
monthFromDateValue
(
dateValue1
);
case
YEAR:
return
DateTimeUtils
.
yearFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
yearFromDateValue
(
dateValue1
);
default
:
default
:
throw
DbException
.
throwInternalError
(
"field:"
+
field
);
throw
DbException
.
getUnsupportedException
(
"DATEDIFF "
+
part
);
}
}
}
}
case
Calendar
.
DATE
:
return
t2
/
(
24
*
60
*
60
*
1000
)
-
t1
/
(
24
*
60
*
60
*
1000
);
private
static
long
weekdiff
(
long
absolute1
,
long
absolute2
,
int
firstDayOfWeek
)
{
default
:
absolute1
+=
4
-
firstDayOfWeek
;
break
;
long
r1
=
absolute1
/
7
;
if
(
absolute1
<
0
&&
(
r1
*
7
!=
absolute1
))
{
r1
--;
}
}
calendar
=
DateTimeUtils
.
createGregorianCalendar
(
DateTimeUtils
.
UTC
);
absolute2
+=
4
-
firstDayOfWeek
;
calendar
.
setTimeInMillis
(
t1
);
long
r2
=
absolute2
/
7
;
int
year1
=
calendar
.
get
(
Calendar
.
YEAR
);
if
(
absolute2
<
0
&&
(
r2
*
7
!=
absolute2
))
{
int
month1
=
calendar
.
get
(
Calendar
.
MONTH
);
r2
--;
calendar
.
setTimeInMillis
(
t2
);
int
year2
=
calendar
.
get
(
Calendar
.
YEAR
);
int
month2
=
calendar
.
get
(
Calendar
.
MONTH
);
int
result
=
year2
-
year1
;
if
(
field
==
Calendar
.
MONTH
)
{
return
12
*
result
+
(
month2
-
month1
);
}
else
if
(
field
==
Calendar
.
YEAR
)
{
return
result
;
}
else
{
throw
DbException
.
getUnsupportedException
(
"DATEDIFF "
+
part
);
}
}
return
r2
-
r1
;
}
}
private
static
String
substring
(
String
s
,
int
start
,
int
length
)
{
private
static
String
substring
(
String
s
,
int
start
,
int
length
)
{
...
...
h2/src/main/org/h2/fulltext/FullText.java
浏览文件 @
1a82bf51
...
@@ -955,6 +955,12 @@ public class FullText {
...
@@ -955,6 +955,12 @@ public class FullText {
}
}
}
}
/**
* Check whether the database is in multi-threaded mode.
*
* @param conn the connection
* @return true if the multi-threaded mode is used
*/
static
boolean
isMultiThread
(
Connection
conn
)
static
boolean
isMultiThread
(
Connection
conn
)
throws
SQLException
{
throws
SQLException
{
try
(
Statement
stat
=
conn
.
createStatement
())
{
try
(
Statement
stat
=
conn
.
createStatement
())
{
...
...
h2/src/main/org/h2/fulltext/FullTextLucene.java
浏览文件 @
1a82bf51
...
@@ -703,11 +703,21 @@ public class FullTextLucene extends FullText {
...
@@ -703,11 +703,21 @@ public class FullTextLucene extends FullText {
searcher
=
new
IndexSearcher
(
reader
);
searcher
=
new
IndexSearcher
(
reader
);
}
}
/**
* Start using the searcher.
*
* @return the searcher
*/
synchronized
IndexSearcher
getSearcher
()
{
synchronized
IndexSearcher
getSearcher
()
{
++
counter
;
++
counter
;
return
searcher
;
return
searcher
;
}
}
/**
* Stop using the searcher.
*
* @param searcher the searcher
*/
synchronized
void
returnSearcher
(
IndexSearcher
searcher
)
{
synchronized
void
returnSearcher
(
IndexSearcher
searcher
)
{
if
(
this
.
searcher
==
searcher
)
{
if
(
this
.
searcher
==
searcher
)
{
--
counter
;
--
counter
;
...
@@ -738,6 +748,9 @@ public class FullTextLucene extends FullText {
...
@@ -738,6 +748,9 @@ public class FullTextLucene extends FullText {
searcher
=
new
IndexSearcher
(
IndexReader
.
open
(
writer
,
true
));
searcher
=
new
IndexSearcher
(
IndexReader
.
open
(
writer
,
true
));
}
}
/**
* Close the index.
*/
public
synchronized
void
close
()
throws
IOException
{
public
synchronized
void
close
()
throws
IOException
{
for
(
IndexSearcher
searcher
:
counters
.
keySet
())
{
for
(
IndexSearcher
searcher
:
counters
.
keySet
())
{
closeSearcher
(
searcher
);
closeSearcher
(
searcher
);
...
...
h2/src/main/org/h2/jdbc/JdbcResultSet.java
浏览文件 @
1a82bf51
...
@@ -3222,7 +3222,14 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
...
@@ -3222,7 +3222,14 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
}
}
}
}
private
Value
get
(
int
columnIndex
)
{
/**
* INTERNAL
*
* @param columnIndex
* index of a column
* @return internal representation of the value in the specified column
*/
public
Value
get
(
int
columnIndex
)
{
checkColumnIndex
(
columnIndex
);
checkColumnIndex
(
columnIndex
);
checkOnValidRow
();
checkOnValidRow
();
Value
[]
list
;
Value
[]
list
;
...
...
h2/src/main/org/h2/jdbcx/JdbcDataSource.java
浏览文件 @
1a82bf51
...
@@ -405,6 +405,7 @@ public class JdbcDataSource extends TraceObject implements XADataSource,
...
@@ -405,6 +405,7 @@ public class JdbcDataSource extends TraceObject implements XADataSource,
* Return an object of this class if possible.
* Return an object of this class if possible.
*
*
* @param iface the class
* @param iface the class
* @return this
*/
*/
@Override
@Override
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
...
@@ -423,6 +424,7 @@ public class JdbcDataSource extends TraceObject implements XADataSource,
...
@@ -423,6 +424,7 @@ public class JdbcDataSource extends TraceObject implements XADataSource,
* Checks if unwrap can return an object of this class.
* Checks if unwrap can return an object of this class.
*
*
* @param iface the class
* @param iface the class
* @return whether or not the interface is assignable from this class
*/
*/
@Override
@Override
public
boolean
isWrapperFor
(
Class
<?>
iface
)
throws
SQLException
{
public
boolean
isWrapperFor
(
Class
<?>
iface
)
throws
SQLException
{
...
...
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
1a82bf51
...
@@ -896,6 +896,9 @@ public class TransactionStore {
...
@@ -896,6 +896,9 @@ public class TransactionStore {
*/
*/
final
MVMap
<
K
,
VersionedValue
>
map
;
final
MVMap
<
K
,
VersionedValue
>
map
;
/**
* The transaction which is used for this map.
*/
final
Transaction
transaction
;
final
Transaction
transaction
;
TransactionMap
(
Transaction
transaction
,
MVMap
<
K
,
VersionedValue
>
map
,
TransactionMap
(
Transaction
transaction
,
MVMap
<
K
,
VersionedValue
>
map
,
...
...
h2/src/main/org/h2/server/pg/PgServerThread.java
浏览文件 @
1a82bf51
...
@@ -20,35 +20,38 @@ import java.net.Socket;
...
@@ -20,35 +20,38 @@ import java.net.Socket;
import
java.nio.charset.Charset
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.charset.StandardCharsets
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.Date
;
import
java.sql.ParameterMetaData
;
import
java.sql.ParameterMetaData
;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
java.sql.Time
;
import
java.sql.Timestamp
;
import
java.sql.Types
;
import
java.sql.Types
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Properties
;
import
java.util.Properties
;
import
java.util.TimeZone
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.CommandInterface
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.jdbc.JdbcPreparedStatement
;
import
org.h2.jdbc.JdbcPreparedStatement
;
import
org.h2.jdbc.JdbcResultSet
;
import
org.h2.jdbc.JdbcStatement
;
import
org.h2.jdbc.JdbcStatement
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.ScriptReader
;
import
org.h2.util.ScriptReader
;
import
org.h2.util.StringUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.h2.util.Utils
;
import
org.h2.value.CaseInsensitiveMap
;
import
org.h2.value.CaseInsensitiveMap
;
import
org.h2.value.Value
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueTime
;
import
org.h2.value.ValueTimestamp
;
/**
/**
* One server thread is opened for each client.
* One server thread is opened for each client.
...
@@ -527,153 +530,91 @@ public class PgServerThread implements Runnable {
...
@@ -527,153 +530,91 @@ public class PgServerThread implements Runnable {
sendMessage
();
sendMessage
();
}
}
private
static
long
toPostgreSeconds
(
long
millis
)
{
private
static
long
toPostgreDays
(
long
dateValue
)
{
// TODO handle Julian/Gregorian transitions
return
DateTimeUtils
.
prolepticGregorianAbsoluteDayFromDateValue
(
dateValue
)
-
10_957
;
return
millis
/
1000
-
946684800L
;
}
}
private
void
writeDataColumn
(
ResultSet
rs
,
int
column
,
int
pgType
,
boolean
text
)
private
void
writeDataColumn
(
ResultSet
rs
,
int
column
,
int
pgType
,
boolean
text
)
throws
Exception
{
throws
Exception
{
Value
v
=
((
JdbcResultSet
)
rs
).
get
(
column
);
if
(
v
==
ValueNull
.
INSTANCE
)
{
writeInt
(-
1
);
return
;
}
if
(
text
)
{
if
(
text
)
{
// plain text
// plain text
switch
(
pgType
)
{
switch
(
pgType
)
{
case
PgServer
.
PG_TYPE_BOOL
:
{
case
PgServer
.
PG_TYPE_BOOL
:
boolean
b
=
rs
.
getBoolean
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
1
);
writeInt
(
1
);
dataOut
.
writeByte
(
b
?
't'
:
'f'
);
dataOut
.
writeByte
(
v
.
getBoolean
()
?
't'
:
'f'
);
}
break
;
break
;
}
default
:
default
:
String
s
=
rs
.
getString
(
column
);
byte
[]
data
=
v
.
getString
().
getBytes
(
getEncoding
());
if
(
s
==
null
)
{
writeInt
(-
1
);
}
else
{
byte
[]
data
=
s
.
getBytes
(
getEncoding
());
writeInt
(
data
.
length
);
writeInt
(
data
.
length
);
write
(
data
);
write
(
data
);
}
}
}
}
else
{
}
else
{
// binary
// binary
switch
(
pgType
)
{
switch
(
pgType
)
{
case
PgServer
.
PG_TYPE_INT2
:
{
case
PgServer
.
PG_TYPE_INT2
:
short
s
=
rs
.
getShort
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
2
);
writeInt
(
2
);
writeShort
(
s
);
writeShort
(
v
.
getShort
());
}
break
;
break
;
}
case
PgServer
.
PG_TYPE_INT4
:
case
PgServer
.
PG_TYPE_INT4
:
{
int
i
=
rs
.
getInt
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
writeInt
(
4
);
writeInt
(
i
);
writeInt
(
v
.
getInt
());
}
break
;
break
;
}
case
PgServer
.
PG_TYPE_INT8
:
case
PgServer
.
PG_TYPE_INT8
:
{
long
l
=
rs
.
getLong
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
writeInt
(
8
);
dataOut
.
writeLong
(
l
);
dataOut
.
writeLong
(
v
.
getLong
());
}
break
;
break
;
}
case
PgServer
.
PG_TYPE_FLOAT4
:
case
PgServer
.
PG_TYPE_FLOAT4
:
{
float
f
=
rs
.
getFloat
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
writeInt
(
4
);
dataOut
.
writeFloat
(
f
);
dataOut
.
writeFloat
(
v
.
getFloat
());
}
break
;
break
;
}
case
PgServer
.
PG_TYPE_FLOAT8
:
case
PgServer
.
PG_TYPE_FLOAT8
:
{
double
d
=
rs
.
getDouble
(
column
);
if
(
rs
.
wasNull
())
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
writeInt
(
8
);
dataOut
.
writeDouble
(
d
);
dataOut
.
writeDouble
(
v
.
getDouble
());
}
break
;
break
;
}
case
PgServer
.
PG_TYPE_BYTEA
:
{
case
PgServer
.
PG_TYPE_BYTEA
:
{
byte
[]
data
=
rs
.
getBytes
(
column
);
byte
[]
data
=
v
.
getBytesNoCopy
();
if
(
data
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
data
.
length
);
writeInt
(
data
.
length
);
write
(
data
);
write
(
data
);
}
break
;
break
;
}
}
case
PgServer
.
PG_TYPE_DATE
:
{
case
PgServer
.
PG_TYPE_DATE
:
{
Date
d
=
rs
.
getDate
(
column
);
ValueDate
d
=
(
ValueDate
)
v
.
convertTo
(
Value
.
DATE
);
if
(
d
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
4
);
writeInt
(
4
);
long
millis
=
d
.
getTime
();
writeInt
((
int
)
(
toPostgreDays
(
d
.
getDateValue
())));
millis
+=
TimeZone
.
getDefault
().
getOffset
(
millis
);
writeInt
((
int
)
(
toPostgreSeconds
(
millis
)
/
86400
));
}
break
;
break
;
}
}
case
PgServer
.
PG_TYPE_TIME
:
{
case
PgServer
.
PG_TYPE_TIME
:
{
Time
t
=
rs
.
getTime
(
column
);
ValueTime
t
=
(
ValueTime
)
v
.
convertTo
(
Value
.
TIME
);
if
(
t
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
writeInt
(
8
);
long
m
=
t
.
getTime
();
long
m
=
t
.
getNanos
();
m
+=
TimeZone
.
getDefault
().
getOffset
(
m
);
if
(
INTEGER_DATE_TYPES
)
{
if
(
INTEGER_DATE_TYPES
)
{
// long format
// long format
m
*=
1
000
;
m
/=
1_
000
;
}
else
{
}
else
{
// double format
// double format
m
/=
1000
;
m
=
Double
.
doubleToLongBits
(
m
*
0.000_000_001
);
m
=
Double
.
doubleToLongBits
(
m
);
}
}
dataOut
.
writeLong
(
m
);
dataOut
.
writeLong
(
m
);
}
break
;
break
;
}
}
case
PgServer
.
PG_TYPE_TIMESTAMP_NO_TMZONE
:
{
case
PgServer
.
PG_TYPE_TIMESTAMP_NO_TMZONE
:
{
Timestamp
t
=
rs
.
getTimestamp
(
column
);
ValueTimestamp
t
=
(
ValueTimestamp
)
v
.
convertTo
(
Value
.
TIMESTAMP
);
if
(
t
==
null
)
{
writeInt
(-
1
);
}
else
{
writeInt
(
8
);
writeInt
(
8
);
long
m
=
t
.
getTime
();
long
m
=
toPostgreDays
(
t
.
getDateValue
())
*
86_400
;
m
+=
TimeZone
.
getDefault
().
getOffset
(
m
);
long
nanos
=
t
.
getTimeNanos
();
m
=
toPostgreSeconds
(
m
);
int
nanos
=
t
.
getNanos
();
if
(
m
<
0
&&
nanos
!=
0
)
{
m
--;
}
if
(
INTEGER_DATE_TYPES
)
{
if
(
INTEGER_DATE_TYPES
)
{
// long format
// long format
m
=
m
*
1000000
+
nanos
/
1
000
;
m
=
m
*
1_000_000
+
nanos
/
1_
000
;
}
else
{
}
else
{
// double format
// double format
m
=
Double
.
doubleToLongBits
(
m
+
nanos
*
0.000000
001
);
m
=
Double
.
doubleToLongBits
(
m
+
nanos
*
0.000_000_
001
);
}
}
dataOut
.
writeLong
(
m
);
dataOut
.
writeLong
(
m
);
}
break
;
break
;
}
}
default
:
throw
new
IllegalStateException
(
"output binary format is undefined"
);
default
:
throw
new
IllegalStateException
(
"output binary format is undefined"
);
...
...
h2/src/main/org/h2/table/TableSynonym.java
浏览文件 @
1a82bf51
...
@@ -37,6 +37,11 @@ public class TableSynonym extends SchemaObjectBase {
...
@@ -37,6 +37,11 @@ public class TableSynonym extends SchemaObjectBase {
return
synonymFor
;
return
synonymFor
;
}
}
/**
* Set (update) the data.
*
* @param data the new data
*/
public
void
updateData
(
CreateSynonymData
data
)
{
public
void
updateData
(
CreateSynonymData
data
)
{
this
.
data
=
data
;
this
.
data
=
data
;
}
}
...
@@ -46,7 +51,6 @@ public class TableSynonym extends SchemaObjectBase {
...
@@ -46,7 +51,6 @@ public class TableSynonym extends SchemaObjectBase {
return
SYNONYM
;
return
SYNONYM
;
}
}
@Override
@Override
public
String
getCreateSQLForCopy
(
Table
table
,
String
quotedName
)
{
public
String
getCreateSQLForCopy
(
Table
table
,
String
quotedName
)
{
return
synonymFor
.
getCreateSQLForCopy
(
table
,
quotedName
);
return
synonymFor
.
getCreateSQLForCopy
(
table
,
quotedName
);
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
1a82bf51
...
@@ -76,9 +76,11 @@ public class TableView extends Table {
...
@@ -76,9 +76,11 @@ public class TableView extends Table {
* dependent views.
* dependent views.
*
*
* @param querySQL the SQL statement
* @param querySQL the SQL statement
* @param newColumnTemplates the columns
* @param session the session
* @param session the session
* @param recursive whether this is a recursive view
* @param recursive whether this is a recursive view
* @param force if errors should be ignored
* @param force if errors should be ignored
* @param literalsChecked if literals have been checked
*/
*/
public
void
replace
(
String
querySQL
,
Column
[]
newColumnTemplates
,
Session
session
,
public
void
replace
(
String
querySQL
,
Column
[]
newColumnTemplates
,
Session
session
,
boolean
recursive
,
boolean
force
,
boolean
literalsChecked
)
{
boolean
recursive
,
boolean
force
,
boolean
literalsChecked
)
{
...
@@ -715,6 +717,22 @@ public class TableView extends Table {
...
@@ -715,6 +717,22 @@ public class TableView extends Table {
return
isPersistent
;
return
isPersistent
;
}
}
/**
* Create a view.
*
* @param schema the schema
* @param id the view id
* @param name the view name
* @param querySQL the query
* @param parameters the parameters
* @param columnTemplates the columns
* @param session the session
* @param literalsChecked whether literals in the query are checked
* @param isTableExpression if this is a table expression
* @param isPersistent whether the view is persisted
* @param db the database
* @return the view
*/
public
static
TableView
createTableViewMaybeRecursive
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
public
static
TableView
createTableViewMaybeRecursive
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
ArrayList
<
Parameter
>
parameters
,
Column
[]
columnTemplates
,
Session
session
,
ArrayList
<
Parameter
>
parameters
,
Column
[]
columnTemplates
,
Session
session
,
boolean
literalsChecked
,
boolean
isTableExpression
,
boolean
isPersistent
,
Database
db
)
{
boolean
literalsChecked
,
boolean
isTableExpression
,
boolean
isPersistent
,
Database
db
)
{
...
@@ -805,6 +823,17 @@ public class TableView extends Table {
...
@@ -805,6 +823,17 @@ public class TableView extends Table {
return
columnTemplateList
;
return
columnTemplateList
;
}
}
/**
* Create a table for a recursive query.
*
* @param isPersistent whether the table is persisted
* @param targetSession the session
* @param cteViewName the name
* @param schema the schema
* @param columns the columns
* @param db the database
* @return the table
*/
public
static
Table
createShadowTableForRecursiveTableExpression
(
boolean
isPersistent
,
Session
targetSession
,
public
static
Table
createShadowTableForRecursiveTableExpression
(
boolean
isPersistent
,
Session
targetSession
,
String
cteViewName
,
Schema
schema
,
List
<
Column
>
columns
,
Database
db
)
{
String
cteViewName
,
Schema
schema
,
List
<
Column
>
columns
,
Database
db
)
{
...
@@ -834,6 +863,13 @@ public class TableView extends Table {
...
@@ -834,6 +863,13 @@ public class TableView extends Table {
return
recursiveTable
;
return
recursiveTable
;
}
}
/**
* Remove a table for a recursive query.
*
* @param isPersistent whether the table is persisted
* @param targetSession the session
* @param recursiveTable the table
*/
public
static
void
destroyShadowTableForRecursiveExpression
(
boolean
isPersistent
,
Session
targetSession
,
public
static
void
destroyShadowTableForRecursiveExpression
(
boolean
isPersistent
,
Session
targetSession
,
Table
recursiveTable
)
{
Table
recursiveTable
)
{
if
(
recursiveTable
!=
null
)
{
if
(
recursiveTable
!=
null
)
{
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
1a82bf51
...
@@ -25,6 +25,7 @@ import org.h2.value.ValueTime;
...
@@ -25,6 +25,7 @@ import org.h2.value.ValueTime;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
import
org.h2.value.ValueTimestampTimeZone
;
/**
/**
* This utility class contains time conversion functions.
* This utility class contains time conversion functions.
* <p>
* <p>
...
@@ -299,30 +300,6 @@ public class DateTimeUtils {
...
@@ -299,30 +300,6 @@ public class DateTimeUtils {
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
nanos
);
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
nanos
);
}
}
private
static
Calendar
valueToCalendar
(
Value
value
)
{
Calendar
cal
;
if
(
value
instanceof
ValueTimestamp
)
{
cal
=
createGregorianCalendar
();
cal
.
setTime
(
value
.
getTimestamp
());
}
else
if
(
value
instanceof
ValueDate
)
{
cal
=
createGregorianCalendar
();
cal
.
setTime
(
value
.
getDate
());
}
else
if
(
value
instanceof
ValueTime
)
{
cal
=
createGregorianCalendar
();
cal
.
setTime
(
value
.
getTime
());
}
else
if
(
value
instanceof
ValueTimestampTimeZone
)
{
ValueTimestampTimeZone
v
=
(
ValueTimestampTimeZone
)
value
;
cal
=
createGregorianCalendar
(
v
.
getTimeZone
());
cal
.
setTimeInMillis
(
DateTimeUtils
.
convertDateValueToMillis
(
DateTimeUtils
.
UTC
,
v
.
getDateValue
())
+
v
.
getTimeNanos
()
/
1000000L
-
v
.
getTimeZoneOffsetMins
()
*
60000
);
}
else
{
cal
=
createGregorianCalendar
();
cal
.
setTime
(
value
.
getTimestamp
());
}
return
cal
;
}
/**
/**
* Parse a date string. The format is: [+|-]year-month-day
* Parse a date string. The format is: [+|-]year-month-day
*
*
...
@@ -585,52 +562,79 @@ public class DateTimeUtils {
...
@@ -585,52 +562,79 @@ public class DateTimeUtils {
}
}
/**
/**
* Get the specified field of a date, however with years normalized to
* Extracts date value and nanos of day from the specified value.
* positive or negative, and month starting with 1.
*
*
* @param
date the date
value
* @param value
*
@param field the field type
*
value to extract fields from
* @return
the value
* @return
array with date value and nanos of day
*/
*/
public
static
long
[]
dateAndTimeFromValue
(
Value
value
)
{
public
static
int
getDatePart
(
Value
date
,
int
field
)
{
long
dateValue
=
EPOCH_DATE_VALUE
;
long
dateValue
=
EPOCH_DATE_VALUE
;
long
timeNanos
=
0
;
long
timeNanos
=
0
;
if
(
dat
e
instanceof
ValueTimestamp
)
{
if
(
valu
e
instanceof
ValueTimestamp
)
{
ValueTimestamp
v
=
(
ValueTimestamp
)
dat
e
;
ValueTimestamp
v
=
(
ValueTimestamp
)
valu
e
;
dateValue
=
v
.
getDateValue
();
dateValue
=
v
.
getDateValue
();
timeNanos
=
v
.
getTimeNanos
();
timeNanos
=
v
.
getTimeNanos
();
}
else
if
(
dat
e
instanceof
ValueDate
)
{
}
else
if
(
valu
e
instanceof
ValueDate
)
{
dateValue
=
((
ValueDate
)
dat
e
).
getDateValue
();
dateValue
=
((
ValueDate
)
valu
e
).
getDateValue
();
}
else
if
(
dat
e
instanceof
ValueTime
)
{
}
else
if
(
valu
e
instanceof
ValueTime
)
{
timeNanos
=
((
ValueTime
)
dat
e
).
getNanos
();
timeNanos
=
((
ValueTime
)
valu
e
).
getNanos
();
}
else
if
(
dat
e
instanceof
ValueTimestampTimeZone
)
{
}
else
if
(
valu
e
instanceof
ValueTimestampTimeZone
)
{
ValueTimestampTimeZone
v
=
(
ValueTimestampTimeZone
)
dat
e
;
ValueTimestampTimeZone
v
=
(
ValueTimestampTimeZone
)
valu
e
;
dateValue
=
v
.
getDateValue
();
dateValue
=
v
.
getDateValue
();
timeNanos
=
v
.
getTimeNanos
();
timeNanos
=
v
.
getTimeNanos
();
}
else
{
}
else
{
ValueTimestamp
v
=
(
ValueTimestamp
)
date
.
convertTo
(
Value
.
TIMESTAMP
);
ValueTimestamp
v
=
(
ValueTimestamp
)
value
.
convertTo
(
Value
.
TIMESTAMP
);
date
=
v
;
// For valueToCalendar() to avoid second convertTo() call
dateValue
=
v
.
getDateValue
();
dateValue
=
v
.
getDateValue
();
timeNanos
=
v
.
getTimeNanos
();
timeNanos
=
v
.
getTimeNanos
();
}
}
return
new
long
[]
{
dateValue
,
timeNanos
};
}
/**
* Get the specified field of a date, however with years normalized to
* positive or negative, and month starting with 1.
*
* @param date the date value
* @param field the field type, see {@link Function} for constants
* @return the value
*/
public
static
int
getDatePart
(
Value
date
,
int
field
)
{
long
[]
a
=
dateAndTimeFromValue
(
date
);
long
dateValue
=
a
[
0
];
long
timeNanos
=
a
[
1
];
switch
(
field
)
{
switch
(
field
)
{
case
Calendar
.
YEAR
:
case
Function
.
YEAR
:
return
yearFromDateValue
(
dateValue
);
return
yearFromDateValue
(
dateValue
);
case
Calendar
.
MONTH
:
case
Function
.
MONTH
:
return
monthFromDateValue
(
dateValue
);
return
monthFromDateValue
(
dateValue
);
case
Calendar
.
DAY_OF_MONTH
:
case
Function
.
DAY_OF_MONTH
:
return
dayFromDateValue
(
dateValue
);
return
dayFromDateValue
(
dateValue
);
case
Calendar
.
HOUR_OF_DAY
:
case
Function
.
HOUR
:
return
(
int
)
(
timeNanos
/
3_600_000_000_000L
%
24
);
return
(
int
)
(
timeNanos
/
3_600_000_000_000L
%
24
);
case
Calendar
.
MINUTE
:
case
Function
.
MINUTE
:
return
(
int
)
(
timeNanos
/
60_000_000_000L
%
60
);
return
(
int
)
(
timeNanos
/
60_000_000_000L
%
60
);
case
Calendar
.
SECOND
:
case
Function
.
SECOND
:
return
(
int
)
(
timeNanos
/
1_000_000_000
%
60
);
return
(
int
)
(
timeNanos
/
1_000_000_000
%
60
);
case
Calendar
.
MILLISECOND
:
case
Function
.
MILLISECOND
:
return
(
int
)
(
timeNanos
/
1_000_000
%
1_000
);
return
(
int
)
(
timeNanos
/
1_000_000
%
1_000
);
}
case
Function
.
DAY_OF_YEAR
:
return
valueToCalendar
(
date
).
get
(
field
);
return
getDayOfYear
(
dateValue
);
case
Function
.
DAY_OF_WEEK
:
return
getSundayDayOfWeek
(
dateValue
);
case
Function
.
WEEK
:
GregorianCalendar
gc
=
getCalendar
();
return
getWeekOfYear
(
dateValue
,
gc
.
getFirstDayOfWeek
()
-
1
,
gc
.
getMinimalDaysInFirstWeek
());
case
Function
.
QUARTER
:
return
(
monthFromDateValue
(
dateValue
)
-
1
)
/
3
+
1
;
case
Function
.
ISO_YEAR
:
return
getIsoWeekYear
(
dateValue
);
case
Function
.
ISO_WEEK
:
return
getIsoWeekOfYear
(
dateValue
);
case
Function
.
ISO_DAY_OF_WEEK
:
return
getIsoDayOfWeek
(
dateValue
);
}
throw
DbException
.
getUnsupportedException
(
"getDatePart("
+
date
+
", "
+
field
+
')'
);
}
}
/**
/**
...
@@ -670,57 +674,144 @@ public class DateTimeUtils {
...
@@ -670,57 +674,144 @@ public class DateTimeUtils {
}
}
/**
/**
* Return the day of week according to the ISO 8601 specification. Week
* Returns day of week.
* starts at Monday. See also http://en.wikipedia.org/wiki/ISO_8601
*
*
* @author Robert Rathsack
* @param dateValue
* @param value the date object which day of week should be calculated
* the date value
* @return the day of the week, Monday as 1 to Sunday as 7
* @param firstDayOfWeek
* first day of week, Monday as 1, Sunday as 7 or 0
* @return day of week
* @see #getIsoDayOfWeek(long)
*/
*/
public
static
int
getIsoDayOfWeek
(
Value
value
)
{
public
static
int
getDayOfWeek
(
long
dateValue
,
int
firstDayOfWeek
)
{
int
val
=
valueToCalendar
(
value
).
get
(
Calendar
.
DAY_OF_WEEK
)
-
1
;
return
getDayOfWeekFromAbsolute
(
absoluteDayFromDateValue
(
dateValue
),
firstDayOfWeek
);
return
val
==
0
?
7
:
val
;
}
private
static
int
getDayOfWeekFromAbsolute
(
long
absoluteValue
,
int
firstDayOfWeek
)
{
return
absoluteValue
>=
0
?
(
int
)
((
absoluteValue
-
firstDayOfWeek
+
11
)
%
7
)
+
1
:
(
int
)
((
absoluteValue
-
firstDayOfWeek
-
2
)
%
7
)
+
7
;
}
}
/**
/**
* Returns the week of the year according to the ISO 8601 specification. The
* Returns number of day in year.
* spec defines the first week of the year as the week which contains at
* least 4 days of the new year. The week starts at Monday. Therefore
* December 29th - 31th could belong to the next year and January 1st - 3th
* could belong to the previous year. If January 1st is on Thursday (or
* earlier) it belongs to the first week, otherwise to the last week of the
* previous year. Hence January 4th always belongs to the first week while
* the December 28th always belongs to the last week.
*
*
* @
author Robert Rathsack
* @
param dateValue
*
@param value the date object which week of year should be calculated
*
the date value
* @return
the week of the
year
* @return
number of day in
year
*/
*/
public
static
int
getIsoWeek
(
Value
value
)
{
public
static
int
getDayOfYear
(
long
dateValue
)
{
Calendar
c
=
valueToCalendar
(
value
);
int
year
=
yearFromDateValue
(
dateValue
);
c
.
setFirstDayOfWeek
(
Calendar
.
MONDAY
);
return
(
int
)
(
absoluteDayFromDateValue
(
dateValue
)
-
absoluteDayFromDateValue
(
dateValue
(
year
,
1
,
1
)))
+
1
;
c
.
setMinimalDaysInFirstWeek
(
4
);
return
c
.
get
(
Calendar
.
WEEK_OF_YEAR
);
}
}
/**
/**
* Returns
the year according to the ISO week definition
.
* Returns
ISO day of week
.
*
*
* @author Robert Rathsack
* @param dateValue
* @param value the date object which year should be calculated
* the date value
* @return the year
* @return ISO day of week, Monday as 1 to Sunday as 7
* @see #getSundayDayOfWeek(long)
*/
public
static
int
getIsoDayOfWeek
(
long
dateValue
)
{
return
getDayOfWeek
(
dateValue
,
1
);
}
/**
* Returns ISO number of week in year.
*
* @param dateValue
* the date value
* @return number of week in year
* @see #getIsoWeekYear(long)
* @see #getWeekOfYear(long, int, int)
*/
*/
public
static
int
getIsoYear
(
Value
value
)
{
public
static
int
getIsoWeekOfYear
(
long
dateValue
)
{
Calendar
cal
=
valueToCalendar
(
value
);
return
getWeekOfYear
(
dateValue
,
1
,
4
);
cal
.
setFirstDayOfWeek
(
Calendar
.
MONDAY
);
}
cal
.
setMinimalDaysInFirstWeek
(
4
);
int
year
=
getYear
(
cal
);
/**
int
month
=
cal
.
get
(
Calendar
.
MONTH
);
* Returns ISO week year.
int
week
=
cal
.
get
(
Calendar
.
WEEK_OF_YEAR
);
*
if
(
month
==
0
&&
week
>
51
)
{
* @param dateValue
year
--;
* the date value
}
else
if
(
month
==
11
&&
week
==
1
)
{
* @return ISO week year
year
++;
* @see #getIsoWeekOfYear(long)
* @see #getWeekYear(long, int, int)
*/
public
static
int
getIsoWeekYear
(
long
dateValue
)
{
return
getWeekYear
(
dateValue
,
1
,
4
);
}
/**
* Returns day of week with Sunday as 1.
*
* @param dateValue
* the date value
* @return day of week, Sunday as 1 to Monday as 7
* @see #getIsoDayOfWeek(long)
*/
public
static
int
getSundayDayOfWeek
(
long
dateValue
)
{
return
getDayOfWeek
(
dateValue
,
0
);
}
/**
* Returns number of week in year.
*
* @param dateValue
* the date value
* @param firstDayOfWeek
* first day of week, Monday as 1, Sunday as 7 or 0
* @param minimalDaysInFirstWeek
* minimal days in first week of year
* @return number of week in year
* @see #getIsoWeekOfYear(long)
*/
public
static
int
getWeekOfYear
(
long
dateValue
,
int
firstDayOfWeek
,
int
minimalDaysInFirstWeek
)
{
long
abs
=
absoluteDayFromDateValue
(
dateValue
);
int
year
=
yearFromDateValue
(
dateValue
);
long
base
=
getWeekOfYearBase
(
year
,
firstDayOfWeek
,
minimalDaysInFirstWeek
);
if
(
abs
-
base
<
0
)
{
base
=
getWeekOfYearBase
(
year
-
1
,
firstDayOfWeek
,
minimalDaysInFirstWeek
);
}
else
if
(
monthFromDateValue
(
dateValue
)
==
12
&&
24
+
minimalDaysInFirstWeek
<
dayFromDateValue
(
dateValue
))
{
if
(
abs
>=
getWeekOfYearBase
(
year
+
1
,
firstDayOfWeek
,
minimalDaysInFirstWeek
))
{
return
1
;
}
}
return
(
int
)
((
abs
-
base
)
/
7
)
+
1
;
}
private
static
long
getWeekOfYearBase
(
int
year
,
int
firstDayOfWeek
,
int
minimalDaysInFirstWeek
)
{
long
first
=
absoluteDayFromDateValue
(
dateValue
(
year
,
1
,
1
));
int
daysInFirstWeek
=
8
-
getDayOfWeekFromAbsolute
(
first
,
firstDayOfWeek
);
long
base
=
first
+
daysInFirstWeek
;
if
(
daysInFirstWeek
>=
minimalDaysInFirstWeek
)
{
base
-=
7
;
}
return
base
;
}
/**
* Returns week year.
*
* @param dateValue
* the date value
* @param firstDayOfWeek
* first day of week, Monday as 1, Sunday as 7 or 0
* @param minimalDaysInFirstWeek
* minimal days in first week of year
* @return week year
* @see #getIsoWeekYear(long)
*/
public
static
int
getWeekYear
(
long
dateValue
,
int
firstDayOfWeek
,
int
minimalDaysInFirstWeek
)
{
long
abs
=
absoluteDayFromDateValue
(
dateValue
);
int
year
=
yearFromDateValue
(
dateValue
);
long
base
=
getWeekOfYearBase
(
year
,
firstDayOfWeek
,
minimalDaysInFirstWeek
);
if
(
abs
-
base
<
0
)
{
return
year
-
1
;
}
else
if
(
monthFromDateValue
(
dateValue
)
==
12
&&
24
+
minimalDaysInFirstWeek
<
dayFromDateValue
(
dateValue
))
{
if
(
abs
>=
getWeekOfYearBase
(
year
+
1
,
firstDayOfWeek
,
minimalDaysInFirstWeek
))
{
return
year
+
1
;
}
}
}
return
year
;
return
year
;
}
}
...
@@ -1043,6 +1134,29 @@ public class DateTimeUtils {
...
@@ -1043,6 +1134,29 @@ public class DateTimeUtils {
return
a
;
return
a
;
}
}
/**
* Calculate the absolute day from an encoded date value in proleptic Gregorian
* calendar.
*
* @param dateValue the date value
* @return the absolute day in proleptic Gregorian calendar
*/
public
static
long
prolepticGregorianAbsoluteDayFromDateValue
(
long
dateValue
)
{
long
y
=
yearFromDateValue
(
dateValue
);
int
m
=
monthFromDateValue
(
dateValue
);
int
d
=
dayFromDateValue
(
dateValue
);
if
(
m
<=
2
)
{
y
--;
m
+=
12
;
}
long
a
=
((
y
*
2922L
)
>>
3
)
+
DAYS_OFFSET
[
m
-
3
]
+
d
-
719484
;
if
(
y
<
1901
||
y
>
2099
)
{
// Slow mode
a
+=
(
y
/
400
)
-
(
y
/
100
)
+
15
;
}
return
a
;
}
/**
/**
* Calculate the encoded date value from an absolute day.
* Calculate the encoded date value from an absolute day.
*
*
...
...
h2/src/main/org/h2/util/LocalDateTimeUtils.java
浏览文件 @
1a82bf51
...
@@ -543,8 +543,15 @@ public class LocalDateTimeUtils {
...
@@ -543,8 +543,15 @@ public class LocalDateTimeUtils {
int
year
=
DateTimeUtils
.
yearFromDateValue
(
dateValue
);
int
year
=
DateTimeUtils
.
yearFromDateValue
(
dateValue
);
int
month
=
DateTimeUtils
.
monthFromDateValue
(
dateValue
);
int
month
=
DateTimeUtils
.
monthFromDateValue
(
dateValue
);
int
day
=
DateTimeUtils
.
dayFromDateValue
(
dateValue
);
int
day
=
DateTimeUtils
.
dayFromDateValue
(
dateValue
);
try
{
return
LOCAL_DATE_OF_YEAR_MONTH_DAY
.
invoke
(
null
,
year
,
month
,
day
);
return
LOCAL_DATE_OF_YEAR_MONTH_DAY
.
invoke
(
null
,
year
,
month
,
day
);
}
catch
(
InvocationTargetException
e
)
{
if
(
year
<=
1500
&&
(
year
&
3
)
==
0
&&
month
==
2
&&
day
==
29
)
{
// If proleptic Gregorian doesn't have such date use the next day
return
LOCAL_DATE_OF_YEAR_MONTH_DAY
.
invoke
(
null
,
year
,
3
,
1
);
}
throw
e
;
}
}
}
private
static
Object
localDateTimeFromDateNanos
(
long
dateValue
,
long
timeNanos
)
private
static
Object
localDateTimeFromDateNanos
(
long
dateValue
,
long
timeNanos
)
...
...
h2/src/main/org/h2/value/CharsetCollator.java
浏览文件 @
1a82bf51
...
@@ -15,6 +15,9 @@ import java.util.Comparator;
...
@@ -15,6 +15,9 @@ import java.util.Comparator;
*/
*/
public
class
CharsetCollator
extends
Collator
{
public
class
CharsetCollator
extends
Collator
{
/**
* The comparator used to compare byte arrays.
*/
static
final
Comparator
<
byte
[]>
COMPARATOR
=
new
Comparator
<
byte
[]>()
{
static
final
Comparator
<
byte
[]>
COMPARATOR
=
new
Comparator
<
byte
[]>()
{
@Override
@Override
public
int
compare
(
byte
[]
b1
,
byte
[]
b2
)
{
public
int
compare
(
byte
[]
b1
,
byte
[]
b2
)
{
...
...
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
1a82bf51
...
@@ -14,6 +14,7 @@ import java.math.BigDecimal;
...
@@ -14,6 +14,7 @@ import java.math.BigDecimal;
import
java.math.BigInteger
;
import
java.math.BigInteger
;
import
java.net.URL
;
import
java.net.URL
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.Date
;
import
java.sql.ParameterMetaData
;
import
java.sql.ParameterMetaData
;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
...
@@ -23,6 +24,8 @@ import java.sql.SQLException;
...
@@ -23,6 +24,8 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
import
java.sql.Types
;
import
java.sql.Types
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.UUID
;
import
java.util.UUID
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.Trigger
;
import
org.h2.api.Trigger
;
...
@@ -99,6 +102,7 @@ public class TestPreparedStatement extends TestBase {
...
@@ -99,6 +102,7 @@ public class TestPreparedStatement extends TestBase {
conn
.
close
();
conn
.
close
();
testPreparedStatementWithLiteralsNone
();
testPreparedStatementWithLiteralsNone
();
testPreparedStatementWithIndexedParameterAndLiteralsNone
();
testPreparedStatementWithIndexedParameterAndLiteralsNone
();
testPreparedStatementWithAnyParameter
();
deleteDb
(
"preparedStatement"
);
deleteDb
(
"preparedStatement"
);
}
}
...
@@ -644,6 +648,60 @@ public class TestPreparedStatement extends TestBase {
...
@@ -644,6 +648,60 @@ public class TestPreparedStatement extends TestBase {
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
localDate
,
localDate2
);
assertEquals
(
localDate
,
localDate2
);
rs
.
close
();
rs
.
close
();
/*
* Check that date that doesn't exist in proleptic Gregorian calendar can be
* read as a next date.
*/
prep
.
setString
(
1
,
"1500-02-29"
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
LocalDateTimeUtils
.
parseLocalDate
(
"1500-03-01"
),
localDate2
);
rs
.
close
();
prep
.
setString
(
1
,
"1400-02-29"
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
LocalDateTimeUtils
.
parseLocalDate
(
"1400-03-01"
),
localDate2
);
rs
.
close
();
prep
.
setString
(
1
,
"1300-02-29"
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
LocalDateTimeUtils
.
parseLocalDate
(
"1300-03-01"
),
localDate2
);
rs
.
close
();
prep
.
setString
(
1
,
"-0100-02-29"
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
LocalDateTimeUtils
.
parseLocalDate
(
"-0100-03-01"
),
localDate2
);
rs
.
close
();
/*
* Check that date that doesn't exist in traditional calendar can be set and
* read with LocalDate and can be read with getDate() as a next date.
*/
localDate
=
LocalDateTimeUtils
.
parseLocalDate
(
"1582-10-05"
);
prep
.
setObject
(
1
,
localDate
);
rs
=
prep
.
executeQuery
();
rs
.
next
();
localDate2
=
rs
.
getObject
(
1
,
LocalDateTimeUtils
.
LOCAL_DATE
);
assertEquals
(
localDate
,
localDate2
);
assertEquals
(
"1582-10-05"
,
rs
.
getString
(
1
));
assertEquals
(
Date
.
valueOf
(
"1582-10-15"
),
rs
.
getDate
(
1
));
/*
* Also check that date that doesn't exist in traditional calendar can be read
* with getDate() with custom Calendar properly.
*/
GregorianCalendar
gc
=
new
GregorianCalendar
();
gc
.
setGregorianChange
(
new
java
.
util
.
Date
(
Long
.
MIN_VALUE
));
gc
.
clear
();
gc
.
set
(
Calendar
.
YEAR
,
1582
);
gc
.
set
(
Calendar
.
MONTH
,
9
);
gc
.
set
(
Calendar
.
DAY_OF_MONTH
,
5
);
Date
expected
=
new
Date
(
gc
.
getTimeInMillis
());
gc
.
clear
();
assertEquals
(
expected
,
rs
.
getDate
(
1
,
gc
));
rs
.
close
();
}
}
private
void
testTime8
(
Connection
conn
)
throws
SQLException
{
private
void
testTime8
(
Connection
conn
)
throws
SQLException
{
...
@@ -1491,7 +1549,43 @@ public class TestPreparedStatement extends TestBase {
...
@@ -1491,7 +1549,43 @@ public class TestPreparedStatement extends TestBase {
deleteDb
(
"preparedStatement"
);
deleteDb
(
"preparedStatement"
);
}
}
private
void
testPreparedStatementWithAnyParameter
()
throws
SQLException
{
deleteDb
(
"preparedStatement"
);
Connection
conn
=
getConnection
(
"preparedStatement"
);
conn
.
prepareStatement
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE INT UNIQUE)"
).
execute
();
PreparedStatement
ps
=
conn
.
prepareStatement
(
"INSERT INTO TEST(ID, VALUE) VALUES (?, ?)"
);
for
(
int
i
=
0
;
i
<
10_000
;
i
++)
{
ps
.
setInt
(
1
,
i
);
ps
.
setInt
(
2
,
i
*
10
);
ps
.
executeUpdate
();
}
Object
[]
values
=
{-
100
,
10
,
200
,
3_000
,
40_000
,
500_000
};
int
[]
expected
=
{
1
,
20
,
300
,
4_000
};
// Ensure that other methods return the same results
ps
=
conn
.
prepareStatement
(
"SELECT ID FROM TEST WHERE VALUE IN (SELECT * FROM TABLE(X INT=?)) ORDER BY ID"
);
anyParameterCheck
(
ps
,
values
,
expected
);
ps
=
conn
.
prepareStatement
(
"SELECT ID FROM TEST INNER JOIN TABLE(X INT=?) T ON TEST.VALUE = T.X"
);
anyParameterCheck
(
ps
,
values
,
expected
);
// Test expression = ANY(?)
ps
=
conn
.
prepareStatement
(
"SELECT ID FROM TEST WHERE VALUE = ANY(?)"
);
assertThrows
(
ErrorCode
.
PARAMETER_NOT_SET_1
,
ps
).
executeQuery
();
anyParameterCheck
(
ps
,
values
,
expected
);
anyParameterCheck
(
ps
,
300
,
new
int
[]
{
30
});
anyParameterCheck
(
ps
,
-
5
,
new
int
[
0
]);
conn
.
close
();
deleteDb
(
"preparedStatement"
);
}
private
void
anyParameterCheck
(
PreparedStatement
ps
,
Object
values
,
int
[]
expected
)
throws
SQLException
{
ps
.
setObject
(
1
,
values
);
try
(
ResultSet
rs
=
ps
.
executeQuery
())
{
for
(
int
exp
:
expected
)
{
assertTrue
(
rs
.
next
());
assertEquals
(
exp
,
rs
.
getInt
(
1
));
}
assertFalse
(
rs
.
next
());
}
}
private
void
checkBigDecimal
(
ResultSet
rs
,
String
[]
value
)
throws
SQLException
{
private
void
checkBigDecimal
(
ResultSet
rs
,
String
[]
value
)
throws
SQLException
{
for
(
String
v
:
value
)
{
for
(
String
v
:
value
)
{
...
...
h2/src/test/org/h2/test/scripts/functions/timeanddate/datediff.sql
浏览文件 @
1a82bf51
...
@@ -158,3 +158,39 @@ call datediff('MS', TIMESTAMP '1900-01-01 00:00:01.000', TIMESTAMP '2008-01-01 0
...
@@ -158,3 +158,39 @@ call datediff('MS', TIMESTAMP '1900-01-01 00:00:01.000', TIMESTAMP '2008-01-01 0
>
-------------
>
-------------
>
3408134399000
>
3408134399000
>
rows
:
1
>
rows
:
1
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
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'2018-02-03'
,
DATE
'2018-02-04'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'2018-02-03'
,
DATE
'2018-02-04'
);
>
1
0
>
-
-
>
1
0
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'2018-02-04'
,
DATE
'2018-02-05'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'2018-02-04'
,
DATE
'2018-02-05'
);
>
0
1
>
-
-
>
0
1
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'2018-02-05'
,
DATE
'2018-02-06'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'2018-02-05'
,
DATE
'2018-02-06'
);
>
0
0
>
-
-
>
0
0
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'1969-12-27'
,
DATE
'1969-12-28'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'1969-12-27'
,
DATE
'1969-12-28'
);
>
1
0
>
-
-
>
1
0
>
rows
:
1
SELECT
DATEDIFF
(
'WEEK'
,
DATE
'1969-12-28'
,
DATE
'1969-12-29'
),
DATEDIFF
(
'ISO_WEEK'
,
DATE
'1969-12-28'
,
DATE
'1969-12-29'
);
>
0
1
>
-
-
>
0
1
>
rows
:
1
h2/src/test/org/h2/test/synth/TestKillRestart.java
浏览文件 @
1a82bf51
...
@@ -5,13 +5,17 @@
...
@@ -5,13 +5,17 @@
*/
*/
package
org
.
h2
.
test
.
synth
;
package
org
.
h2
.
test
.
synth
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.lang.reflect.Field
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.DriverManager
;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
java.util.Random
;
import
java.util.Random
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.TimeUnit
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.test.utils.SelfDestructor
;
import
org.h2.test.utils.SelfDestructor
;
...
@@ -58,7 +62,7 @@ public class TestKillRestart extends TestBase {
...
@@ -58,7 +62,7 @@ public class TestKillRestart extends TestBase {
Thread
.
sleep
(
100
);
Thread
.
sleep
(
100
);
printTime
(
"killing: "
+
i
);
printTime
(
"killing: "
+
i
);
p
.
destroy
();
p
.
destroy
();
p
.
waitFor
(
);
waitForTimeout
(
p
);
break
;
break
;
}
else
if
(
s
.
startsWith
(
"#Fail"
))
{
}
else
if
(
s
.
startsWith
(
"#Fail"
))
{
fail
(
"Failed: "
+
s
);
fail
(
"Failed: "
+
s
);
...
@@ -68,6 +72,58 @@ public class TestKillRestart extends TestBase {
...
@@ -68,6 +72,58 @@ public class TestKillRestart extends TestBase {
deleteDb
(
"killRestart"
);
deleteDb
(
"killRestart"
);
}
}
/**
* Wait for a subprocess with timeout.
*/
private
static
void
waitForTimeout
(
final
Process
p
)
throws
InterruptedException
,
IOException
{
final
long
pid
=
getPidOfProcess
(
p
);
if
(
pid
==
-
1
)
{
p
.
waitFor
();
}
// when we hit Java8 we can use the waitFor(1,TimeUnit.MINUTES) method
final
CountDownLatch
latch
=
new
CountDownLatch
(
1
);
new
Thread
(
"waitForTimeout"
)
{
@Override
public
void
run
()
{
try
{
p
.
waitFor
();
latch
.
countDown
();
}
catch
(
InterruptedException
ex
)
{
ex
.
printStackTrace
();
}
}
}.
start
();
if
(!
latch
.
await
(
2
,
TimeUnit
.
MINUTES
))
{
String
[]
procDef
=
{
"jstack"
,
"-F"
,
"-m"
,
"-l"
,
""
+
pid
};
new
ProcessBuilder
().
redirectErrorStream
(
true
).
command
(
procDef
)
.
start
();
OutputCatcher
catcher
=
new
OutputCatcher
(
p
.
getInputStream
());
catcher
.
start
();
Thread
.
sleep
(
500
);
throw
new
IOException
(
"timed out waiting for subprocess to die"
);
}
}
/**
* Get the PID of a subprocess. Only works on Linux and OSX.
*/
private
static
long
getPidOfProcess
(
Process
p
)
{
// When we hit Java9 we can call getPid() on Process.
long
pid
=
-
1
;
try
{
if
(
p
.
getClass
().
getName
().
equals
(
"java.lang.UNIXProcess"
))
{
Field
f
=
p
.
getClass
().
getDeclaredField
(
"pid"
);
f
.
setAccessible
(
true
);
pid
=
f
.
getLong
(
p
);
f
.
setAccessible
(
false
);
}
}
catch
(
Exception
e
)
{
pid
=
-
1
;
}
return
pid
;
}
/**
/**
* This method is called when executing this application from the command
* This method is called when executing this application from the command
* line.
* line.
...
@@ -77,7 +133,7 @@ public class TestKillRestart extends TestBase {
...
@@ -77,7 +133,7 @@ public class TestKillRestart extends TestBase {
public
static
void
main
(
String
...
args
)
{
public
static
void
main
(
String
...
args
)
{
SelfDestructor
.
startCountdown
(
60
);
SelfDestructor
.
startCountdown
(
60
);
String
driver
=
"org.h2.Driver"
;
String
driver
=
"org.h2.Driver"
;
String
url
=
"jdbc:h2:test"
,
user
=
"sa"
,
password
=
"sa"
;
String
url
=
"jdbc:h2:
mem:
test"
,
user
=
"sa"
,
password
=
"sa"
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
if
(
"-url"
.
equals
(
args
[
i
]))
{
if
(
"-url"
.
equals
(
args
[
i
]))
{
url
=
args
[++
i
];
url
=
args
[++
i
];
...
...
h2/src/test/org/h2/test/unit/TestDateIso8601.java
浏览文件 @
1a82bf51
...
@@ -6,11 +6,10 @@
...
@@ -6,11 +6,10 @@
package
org
.
h2
.
test
.
unit
;
package
org
.
h2
.
test
.
unit
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIsoDayOfWeek
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIsoDayOfWeek
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIsoWeek
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIsoWeek
OfYear
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIsoYear
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
getIso
Week
Year
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.value.Value
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
import
org.h2.value.ValueTimestampTimeZone
;
...
@@ -35,21 +34,21 @@ public class TestDateIso8601 extends TestBase {
...
@@ -35,21 +34,21 @@ public class TestDateIso8601 extends TestBase {
TestBase
.
createCaller
().
init
().
test
();
TestBase
.
createCaller
().
init
().
test
();
}
}
private
static
Value
parse
(
String
s
)
{
private
static
long
parse
(
String
s
)
{
if
(
type
==
null
)
{
if
(
type
==
null
)
{
throw
new
IllegalStateException
();
throw
new
IllegalStateException
();
}
}
switch
(
type
)
{
switch
(
type
)
{
case
DATE:
case
DATE:
return
ValueDate
.
parse
(
s
);
return
ValueDate
.
parse
(
s
)
.
getDateValue
()
;
case
TIMESTAMP:
case
TIMESTAMP:
return
ValueTimestamp
.
parse
(
s
);
return
ValueTimestamp
.
parse
(
s
)
.
getDateValue
()
;
case
TIMESTAMP_TIMEZONE_0:
case
TIMESTAMP_TIMEZONE_0:
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00.0Z"
);
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00.0Z"
)
.
getDateValue
()
;
case
TIMESTAMP_TIMEZONE_PLUS_18:
case
TIMESTAMP_TIMEZONE_PLUS_18:
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00+18:00"
);
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00+18:00"
)
.
getDateValue
()
;
case
TIMESTAMP_TIMEZONE_MINUS_18:
case
TIMESTAMP_TIMEZONE_MINUS_18:
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00-18:00"
);
return
ValueTimestampTimeZone
.
parse
(
s
+
" 00:00:00-18:00"
)
.
getDateValue
()
;
default
:
default
:
throw
new
IllegalStateException
();
throw
new
IllegalStateException
();
}
}
...
@@ -104,57 +103,57 @@ public class TestDateIso8601 extends TestBase {
...
@@ -104,57 +103,57 @@ public class TestDateIso8601 extends TestBase {
* January 1st is a Monday therefore the week belongs to the next year.
* January 1st is a Monday therefore the week belongs to the next year.
*/
*/
private
void
testIsoWeekJanuary1thMonday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thMonday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2006-12-31"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2006-12-31"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2007-01-01"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2007-01-01"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2007-01-07"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2007-01-07"
)));
assertEquals
(
2
,
getIsoWeek
(
parse
(
"2007-01-08"
)));
assertEquals
(
2
,
getIsoWeek
OfYear
(
parse
(
"2007-01-08"
)));
}
}
/**
/**
* January 1st is a Tuesday therefore the week belongs to the next year.
* January 1st is a Tuesday therefore the week belongs to the next year.
*/
*/
private
void
testIsoWeekJanuary1thTuesday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thTuesday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2007-12-30"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2007-12-30"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2007-12-31"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2007-12-31"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2008-01-01"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2008-01-01"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2008-01-06"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2008-01-06"
)));
assertEquals
(
2
,
getIsoWeek
(
parse
(
"2008-01-07"
)));
assertEquals
(
2
,
getIsoWeek
OfYear
(
parse
(
"2008-01-07"
)));
}
}
/**
/**
* January1th is a Wednesday therefore the week belongs to the next year.
* January1th is a Wednesday therefore the week belongs to the next year.
*/
*/
private
void
testIsoWeekJanuary1thWednesday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thWednesday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2002-12-28"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2002-12-28"
)));
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2002-12-29"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2002-12-29"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2002-12-30"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2002-12-30"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2002-12-31"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2002-12-31"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2003-01-01"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2003-01-01"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2003-01-05"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2003-01-05"
)));
assertEquals
(
2
,
getIsoWeek
(
parse
(
"2003-01-06"
)));
assertEquals
(
2
,
getIsoWeek
OfYear
(
parse
(
"2003-01-06"
)));
}
}
/**
/**
* January 1st is a Thursday therefore the week belongs to the next year.
* January 1st is a Thursday therefore the week belongs to the next year.
*/
*/
private
void
testIsoWeekJanuary1thThursday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thThursday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2008-12-28"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2008-12-28"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2008-12-29"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2008-12-29"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2008-12-30"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2008-12-30"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2008-12-31"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2008-12-31"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2009-01-01"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2009-01-01"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2009-01-04"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2009-01-04"
)));
assertEquals
(
2
,
getIsoWeek
(
parse
(
"2009-01-09"
)));
assertEquals
(
2
,
getIsoWeek
OfYear
(
parse
(
"2009-01-09"
)));
}
}
/**
/**
* January 1st is a Friday therefore the week belongs to the previous year.
* January 1st is a Friday therefore the week belongs to the previous year.
*/
*/
private
void
testIsoWeekJanuary1thFriday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thFriday
()
throws
Exception
{
assertEquals
(
53
,
getIsoWeek
(
parse
(
"2009-12-31"
)));
assertEquals
(
53
,
getIsoWeek
OfYear
(
parse
(
"2009-12-31"
)));
assertEquals
(
53
,
getIsoWeek
(
parse
(
"2010-01-01"
)));
assertEquals
(
53
,
getIsoWeek
OfYear
(
parse
(
"2010-01-01"
)));
assertEquals
(
53
,
getIsoWeek
(
parse
(
"2010-01-03"
)));
assertEquals
(
53
,
getIsoWeek
OfYear
(
parse
(
"2010-01-03"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2010-01-04"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2010-01-04"
)));
}
}
/**
/**
...
@@ -162,34 +161,34 @@ public class TestDateIso8601 extends TestBase {
...
@@ -162,34 +161,34 @@ public class TestDateIso8601 extends TestBase {
* year.
* year.
*/
*/
private
void
testIsoWeekJanuary1thSaturday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thSaturday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2010-12-31"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2010-12-31"
)));
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2011-01-01"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2011-01-01"
)));
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2011-01-02"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2011-01-02"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2011-01-03"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2011-01-03"
)));
}
}
/**
/**
* January 1st is a Sunday therefore the week belongs to the previous year.
* January 1st is a Sunday therefore the week belongs to the previous year.
*/
*/
private
void
testIsoWeekJanuary1thSunday
()
throws
Exception
{
private
void
testIsoWeekJanuary1thSunday
()
throws
Exception
{
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2011-12-31"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2011-12-31"
)));
assertEquals
(
52
,
getIsoWeek
(
parse
(
"2012-01-01"
)));
assertEquals
(
52
,
getIsoWeek
OfYear
(
parse
(
"2012-01-01"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2012-01-02"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2012-01-02"
)));
assertEquals
(
1
,
getIsoWeek
(
parse
(
"2012-01-08"
)));
assertEquals
(
1
,
getIsoWeek
OfYear
(
parse
(
"2012-01-08"
)));
assertEquals
(
2
,
getIsoWeek
(
parse
(
"2012-01-09"
)));
assertEquals
(
2
,
getIsoWeek
OfYear
(
parse
(
"2012-01-09"
)));
}
}
/**
/**
* January 1st is a Monday therefore year is equal to isoYear.
* January 1st is a Monday therefore year is equal to isoYear.
*/
*/
private
void
testIsoYearJanuary1thMonday
()
throws
Exception
{
private
void
testIsoYearJanuary1thMonday
()
throws
Exception
{
assertEquals
(
2006
,
getIsoYear
(
parse
(
"2006-12-28"
)));
assertEquals
(
2006
,
getIso
Week
Year
(
parse
(
"2006-12-28"
)));
assertEquals
(
2006
,
getIsoYear
(
parse
(
"2006-12-29"
)));
assertEquals
(
2006
,
getIso
Week
Year
(
parse
(
"2006-12-29"
)));
assertEquals
(
2006
,
getIsoYear
(
parse
(
"2006-12-30"
)));
assertEquals
(
2006
,
getIso
Week
Year
(
parse
(
"2006-12-30"
)));
assertEquals
(
2006
,
getIsoYear
(
parse
(
"2006-12-31"
)));
assertEquals
(
2006
,
getIso
Week
Year
(
parse
(
"2006-12-31"
)));
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-01-01"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-01-01"
)));
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-01-02"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-01-02"
)));
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-01-03"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-01-03"
)));
}
}
/**
/**
...
@@ -197,14 +196,14 @@ public class TestDateIso8601 extends TestBase {
...
@@ -197,14 +196,14 @@ public class TestDateIso8601 extends TestBase {
* year.
* year.
*/
*/
private
void
testIsoYearJanuary1thTuesday
()
throws
Exception
{
private
void
testIsoYearJanuary1thTuesday
()
throws
Exception
{
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-12-28"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-12-28"
)));
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-12-29"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-12-29"
)));
assertEquals
(
2007
,
getIsoYear
(
parse
(
"2007-12-30"
)));
assertEquals
(
2007
,
getIso
Week
Year
(
parse
(
"2007-12-30"
)));
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2007-12-31"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2007-12-31"
)));
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2008-01-01"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2008-01-01"
)));
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2008-01-02"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2008-01-02"
)));
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2008-01-03"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2008-01-03"
)));
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2008-01-04"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2008-01-04"
)));
}
}
/**
/**
...
@@ -212,13 +211,13 @@ public class TestDateIso8601 extends TestBase {
...
@@ -212,13 +211,13 @@ public class TestDateIso8601 extends TestBase {
* the next year.
* the next year.
*/
*/
private
void
testIsoYearJanuary1thWednesday
()
throws
Exception
{
private
void
testIsoYearJanuary1thWednesday
()
throws
Exception
{
assertEquals
(
2002
,
getIsoYear
(
parse
(
"2002-12-28"
)));
assertEquals
(
2002
,
getIso
Week
Year
(
parse
(
"2002-12-28"
)));
assertEquals
(
2002
,
getIsoYear
(
parse
(
"2002-12-29"
)));
assertEquals
(
2002
,
getIso
Week
Year
(
parse
(
"2002-12-29"
)));
assertEquals
(
2003
,
getIsoYear
(
parse
(
"2002-12-30"
)));
assertEquals
(
2003
,
getIso
Week
Year
(
parse
(
"2002-12-30"
)));
assertEquals
(
2003
,
getIsoYear
(
parse
(
"2002-12-31"
)));
assertEquals
(
2003
,
getIso
Week
Year
(
parse
(
"2002-12-31"
)));
assertEquals
(
2003
,
getIsoYear
(
parse
(
"2003-01-01"
)));
assertEquals
(
2003
,
getIso
Week
Year
(
parse
(
"2003-01-01"
)));
assertEquals
(
2003
,
getIsoYear
(
parse
(
"2003-01-02"
)));
assertEquals
(
2003
,
getIso
Week
Year
(
parse
(
"2003-01-02"
)));
assertEquals
(
2003
,
getIsoYear
(
parse
(
"2003-12-02"
)));
assertEquals
(
2003
,
getIso
Week
Year
(
parse
(
"2003-12-02"
)));
}
}
/**
/**
...
@@ -226,14 +225,14 @@ public class TestDateIso8601 extends TestBase {
...
@@ -226,14 +225,14 @@ public class TestDateIso8601 extends TestBase {
* next year.
* next year.
*/
*/
private
void
testIsoYearJanuary1thThursday
()
throws
Exception
{
private
void
testIsoYearJanuary1thThursday
()
throws
Exception
{
assertEquals
(
2008
,
getIsoYear
(
parse
(
"2008-12-28"
)));
assertEquals
(
2008
,
getIso
Week
Year
(
parse
(
"2008-12-28"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2008-12-29"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2008-12-29"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2008-12-30"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2008-12-30"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2008-12-31"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2008-12-31"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-01-01"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-01-01"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-01-02"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-01-02"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-01-03"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-01-03"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-01-04"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-01-04"
)));
}
}
/**
/**
...
@@ -241,14 +240,14 @@ public class TestDateIso8601 extends TestBase {
...
@@ -241,14 +240,14 @@ public class TestDateIso8601 extends TestBase {
* previous year.
* previous year.
*/
*/
private
void
testIsoYearJanuary1thFriday
()
throws
Exception
{
private
void
testIsoYearJanuary1thFriday
()
throws
Exception
{
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-12-28"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-12-28"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-12-29"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-12-29"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-12-30"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-12-30"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2009-12-31"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2009-12-31"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2010-01-01"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2010-01-01"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2010-01-02"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2010-01-02"
)));
assertEquals
(
2009
,
getIsoYear
(
parse
(
"2010-01-03"
)));
assertEquals
(
2009
,
getIso
Week
Year
(
parse
(
"2010-01-03"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2010-01-04"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2010-01-04"
)));
}
}
/**
/**
...
@@ -256,28 +255,28 @@ public class TestDateIso8601 extends TestBase {
...
@@ -256,28 +255,28 @@ public class TestDateIso8601 extends TestBase {
* previous year.
* previous year.
*/
*/
private
void
testIsoYearJanuary1thSaturday
()
throws
Exception
{
private
void
testIsoYearJanuary1thSaturday
()
throws
Exception
{
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2010-12-28"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2010-12-28"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2010-12-29"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2010-12-29"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2010-12-30"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2010-12-30"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2010-12-31"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2010-12-31"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2011-01-01"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2011-01-01"
)));
assertEquals
(
2010
,
getIsoYear
(
parse
(
"2011-01-02"
)));
assertEquals
(
2010
,
getIso
Week
Year
(
parse
(
"2011-01-02"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-01-03"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-01-03"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-01-04"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-01-04"
)));
}
}
/**
/**
* January 1st is a Sunday therefore this day belong to the previous year.
* January 1st is a Sunday therefore this day belong to the previous year.
*/
*/
private
void
testIsoYearJanuary1thSunday
()
throws
Exception
{
private
void
testIsoYearJanuary1thSunday
()
throws
Exception
{
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-12-28"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-12-28"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-12-29"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-12-29"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-12-30"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-12-30"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2011-12-31"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2011-12-31"
)));
assertEquals
(
2011
,
getIsoYear
(
parse
(
"2012-01-01"
)));
assertEquals
(
2011
,
getIso
Week
Year
(
parse
(
"2012-01-01"
)));
assertEquals
(
2012
,
getIsoYear
(
parse
(
"2012-01-02"
)));
assertEquals
(
2012
,
getIso
Week
Year
(
parse
(
"2012-01-02"
)));
assertEquals
(
2012
,
getIsoYear
(
parse
(
"2012-01-03"
)));
assertEquals
(
2012
,
getIso
Week
Year
(
parse
(
"2012-01-03"
)));
assertEquals
(
2012
,
getIsoYear
(
parse
(
"2012-01-04"
)));
assertEquals
(
2012
,
getIso
Week
Year
(
parse
(
"2012-01-04"
)));
}
}
}
}
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
浏览文件 @
1a82bf51
...
@@ -5,6 +5,9 @@
...
@@ -5,6 +5,9 @@
*/
*/
package
org
.
h2
.
test
.
unit
;
package
org
.
h2
.
test
.
unit
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.DateTimeUtils
;
...
@@ -25,6 +28,8 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -25,6 +28,8 @@ public class TestDateTimeUtils extends TestBase {
@Override
@Override
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
testParseTimeNanosDB2Format
();
testParseTimeNanosDB2Format
();
testDayOfWeek
();
testWeekOfYear
();
}
}
private
void
testParseTimeNanosDB2Format
()
{
private
void
testParseTimeNanosDB2Format
()
{
...
@@ -34,4 +39,55 @@ public class TestDateTimeUtils extends TestBase {
...
@@ -34,4 +39,55 @@ public class TestDateTimeUtils extends TestBase {
assertEquals
(
3723000000000L
,
DateTimeUtils
.
parseTimeNanos
(
"01:02:03"
,
0
,
8
,
true
));
assertEquals
(
3723000000000L
,
DateTimeUtils
.
parseTimeNanos
(
"01:02:03"
,
0
,
8
,
true
));
assertEquals
(
3723000000000L
,
DateTimeUtils
.
parseTimeNanos
(
"01.02.03"
,
0
,
8
,
true
));
assertEquals
(
3723000000000L
,
DateTimeUtils
.
parseTimeNanos
(
"01.02.03"
,
0
,
8
,
true
));
}
}
/**
* Test for {@link DateTimeUtils#getSundayDayOfWeek()} and
* {@link DateTimeUtils#getIsoDayOfWeek(long)}.
*/
private
void
testDayOfWeek
()
{
GregorianCalendar
gc
=
DateTimeUtils
.
createGregorianCalendar
();
for
(
int
i
=
-
1_000_000
;
i
<=
1_000_000
;
i
++)
{
gc
.
clear
();
gc
.
setTimeInMillis
(
i
*
86400000L
);
int
year
=
gc
.
get
(
Calendar
.
YEAR
);
if
(
gc
.
get
(
Calendar
.
ERA
)
==
GregorianCalendar
.
BC
)
{
year
=
1
-
year
;
}
long
expectedDateValue
=
DateTimeUtils
.
dateValue
(
year
,
gc
.
get
(
Calendar
.
MONTH
)
+
1
,
gc
.
get
(
Calendar
.
DAY_OF_MONTH
));
long
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
i
);
assertEquals
(
expectedDateValue
,
dateValue
);
assertEquals
(
i
,
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue
));
int
dow
=
gc
.
get
(
Calendar
.
DAY_OF_WEEK
);
assertEquals
(
dow
,
DateTimeUtils
.
getSundayDayOfWeek
(
dateValue
));
int
isoDow
=
(
dow
+
5
)
%
7
+
1
;
assertEquals
(
isoDow
,
DateTimeUtils
.
getIsoDayOfWeek
(
dateValue
));
assertEquals
(
gc
.
get
(
Calendar
.
WEEK_OF_YEAR
),
DateTimeUtils
.
getWeekOfYear
(
dateValue
,
gc
.
getFirstDayOfWeek
()
-
1
,
gc
.
getMinimalDaysInFirstWeek
()));
}
}
/**
* Test for {@link DateTimeUtils#getDayOfYear(long)},
* {@link DateTimeUtils#getWeekOfYear(long, int, int)} and
* {@link DateTimeUtils#getWeekYear(long, int, int)}.
*/
private
void
testWeekOfYear
()
{
GregorianCalendar
gc
=
new
GregorianCalendar
(
DateTimeUtils
.
UTC
);
for
(
int
firstDay
=
1
;
firstDay
<=
7
;
firstDay
++)
{
gc
.
setFirstDayOfWeek
(
firstDay
);
for
(
int
minimalDays
=
1
;
minimalDays
<=
7
;
minimalDays
++)
{
gc
.
setMinimalDaysInFirstWeek
(
minimalDays
);
for
(
int
i
=
0
;
i
<
150_000
;
i
++)
{
long
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
i
);
gc
.
clear
();
gc
.
setTimeInMillis
(
i
*
86400000L
);
assertEquals
(
gc
.
get
(
Calendar
.
DAY_OF_YEAR
),
DateTimeUtils
.
getDayOfYear
(
dateValue
));
assertEquals
(
gc
.
get
(
Calendar
.
WEEK_OF_YEAR
),
DateTimeUtils
.
getWeekOfYear
(
dateValue
,
firstDay
-
1
,
minimalDays
));
assertEquals
(
gc
.
getWeekYear
(),
DateTimeUtils
.
getWeekYear
(
dateValue
,
firstDay
-
1
,
minimalDays
));
}
}
}
}
}
}
h2/src/test/org/h2/test/unit/TestPgServer.java
浏览文件 @
1a82bf51
...
@@ -487,13 +487,16 @@ public class TestPgServer extends TestBase {
...
@@ -487,13 +487,16 @@ public class TestPgServer extends TestBase {
Date
[]
dates
=
{
null
,
Date
.
valueOf
(
"2017-02-20"
),
Date
[]
dates
=
{
null
,
Date
.
valueOf
(
"2017-02-20"
),
Date
.
valueOf
(
"1970-01-01"
),
Date
.
valueOf
(
"1969-12-31"
),
Date
.
valueOf
(
"1970-01-01"
),
Date
.
valueOf
(
"1969-12-31"
),
Date
.
valueOf
(
"1940-01-10"
),
Date
.
valueOf
(
"1950-11-10"
)
};
Date
.
valueOf
(
"1940-01-10"
),
Date
.
valueOf
(
"1950-11-10"
),
Date
.
valueOf
(
"1500-01-01"
)};
Time
[]
times
=
{
null
,
Time
.
valueOf
(
"14:15:16"
),
Time
[]
times
=
{
null
,
Time
.
valueOf
(
"14:15:16"
),
Time
.
valueOf
(
"00:00:00"
),
Time
.
valueOf
(
"23:59:59"
),
Time
.
valueOf
(
"00:00:00"
),
Time
.
valueOf
(
"23:59:59"
),
Time
.
valueOf
(
"00:10:59"
),
Time
.
valueOf
(
"08:30:42"
)
};
Time
.
valueOf
(
"00:10:59"
),
Time
.
valueOf
(
"08:30:42"
),
Time
.
valueOf
(
"10:00:00"
)};
Timestamp
[]
timestamps
=
{
null
,
Timestamp
.
valueOf
(
"2017-02-20 14:15:16.763"
),
Timestamp
[]
timestamps
=
{
null
,
Timestamp
.
valueOf
(
"2017-02-20 14:15:16.763"
),
Timestamp
.
valueOf
(
"1970-01-01 00:00:00"
),
Timestamp
.
valueOf
(
"1969-12-31 23:59:59"
),
Timestamp
.
valueOf
(
"1970-01-01 00:00:00"
),
Timestamp
.
valueOf
(
"1969-12-31 23:59:59"
),
Timestamp
.
valueOf
(
"1940-01-10 00:10:59"
),
Timestamp
.
valueOf
(
"1950-11-10 08:30:42.12"
)
};
Timestamp
.
valueOf
(
"1940-01-10 00:10:59"
),
Timestamp
.
valueOf
(
"1950-11-10 08:30:42.12"
),
Timestamp
.
valueOf
(
"1500-01-01 10:00:10"
)};
int
count
=
dates
.
length
;
int
count
=
dates
.
length
;
PreparedStatement
ps
=
conn
.
prepareStatement
(
PreparedStatement
ps
=
conn
.
prepareStatement
(
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论