Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6ecfc2ce
提交
6ecfc2ce
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use FunctionsMySQL in MySQL mode
上级
394ac43a
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
146 行增加
和
54 行删除
+146
-54
Function.java
h2/src/main/org/h2/expression/Function.java
+12
-7
FunctionInfo.java
h2/src/main/org/h2/expression/FunctionInfo.java
+5
-5
FunctionsBase.java
h2/src/main/org/h2/mode/FunctionsBase.java
+6
-1
FunctionsMSSQLServer.java
h2/src/main/org/h2/mode/FunctionsMSSQLServer.java
+2
-1
FunctionsMySQL.java
h2/src/main/org/h2/mode/FunctionsMySQL.java
+121
-39
TestCompatibility.java
h2/src/test/org/h2/test/db/TestCompatibility.java
+0
-1
没有找到文件。
h2/src/main/org/h2/expression/Function.java
浏览文件 @
6ecfc2ce
...
...
@@ -29,6 +29,7 @@ import org.h2.engine.Mode;
import
org.h2.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.mode.FunctionsMSSQLServer
;
import
org.h2.mode.FunctionsMySQL
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Sequence
;
import
org.h2.security.BlockCipher
;
...
...
@@ -144,7 +145,7 @@ public class Function extends Expression implements FunctionCall {
public
static
final
int
ROW_NUMBER
=
300
;
pr
ivate
static
final
int
VAR_ARGS
=
-
1
;
pr
otected
static
final
int
VAR_ARGS
=
-
1
;
private
static
final
long
PRECISION_UNKNOWN
=
-
1
;
private
static
final
HashMap
<
String
,
FunctionInfo
>
FUNCTIONS
=
new
HashMap
<>(
256
);
...
...
@@ -152,11 +153,13 @@ public class Function extends Expression implements FunctionCall {
protected
Expression
[]
args
;
pr
ivate
final
FunctionInfo
info
;
pr
otected
final
FunctionInfo
info
;
private
ArrayList
<
Expression
>
varArgs
;
private
int
dataType
,
scale
;
private
long
precision
=
PRECISION_UNKNOWN
;
private
int
displaySize
;
protected
int
dataType
;
protected
int
scale
;
protected
long
precision
=
PRECISION_UNKNOWN
;
protected
int
displaySize
;
private
final
Database
database
;
static
{
...
...
@@ -524,6 +527,8 @@ public class Function extends Expression implements FunctionCall {
switch
(
database
.
getMode
().
getEnum
())
{
case
MSSQLServer:
return
FunctionsMSSQLServer
.
getFunction
(
database
,
name
);
case
MySQL:
return
FunctionsMySQL
.
getFunction
(
database
,
name
);
default
:
return
null
;
}
...
...
@@ -1098,7 +1103,7 @@ public class Function extends Expression implements FunctionCall {
return
table
.
getDiskSpaceUsed
();
}
pr
ivate
static
Value
getNullOrValue
(
Session
session
,
Expression
[]
args
,
pr
otected
static
Value
getNullOrValue
(
Session
session
,
Expression
[]
args
,
Value
[]
values
,
int
i
)
{
if
(
i
>=
args
.
length
)
{
return
null
;
...
...
@@ -1114,7 +1119,7 @@ public class Function extends Expression implements FunctionCall {
return
v
;
}
pr
ivate
Value
getValueWithArgs
(
Session
session
,
Expression
[]
args
)
{
pr
otected
Value
getValueWithArgs
(
Session
session
,
Expression
[]
args
)
{
Value
[]
values
=
new
Value
[
args
.
length
];
if
(
info
.
nullIfParameterIsNull
)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/FunctionInfo.java
浏览文件 @
6ecfc2ce
...
...
@@ -13,12 +13,12 @@ public final class FunctionInfo {
/**
* The name of the function.
*/
final
String
name
;
public
final
String
name
;
/**
* The function type.
*/
final
int
type
;
public
final
int
type
;
/**
* The number of parameters.
...
...
@@ -28,7 +28,7 @@ public final class FunctionInfo {
/**
* The data type of the return value.
*/
final
int
returnDataType
;
public
final
int
returnDataType
;
/**
* If the result of the function is NULL if any of the parameters is NULL.
...
...
@@ -38,7 +38,7 @@ public final class FunctionInfo {
/**
* If this function always returns the same value for the same parameters.
*/
final
boolean
deterministic
;
public
final
boolean
deterministic
;
/**
* Should the return value ResultSet be buffered in a local temporary file?
...
...
@@ -66,7 +66,7 @@ public final class FunctionInfo {
* should the return value ResultSet be buffered in a local
* temporary file?
*/
FunctionInfo
(
String
name
,
int
type
,
int
parameterCount
,
int
returnDataType
,
boolean
nullIfParameterIsNull
,
public
FunctionInfo
(
String
name
,
int
type
,
int
parameterCount
,
int
returnDataType
,
boolean
nullIfParameterIsNull
,
boolean
deterministic
,
boolean
bufferResultSetToLocalTemp
)
{
this
.
name
=
name
;
this
.
type
=
type
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mode/FunctionsBase.java
浏览文件 @
6ecfc2ce
...
...
@@ -7,13 +7,18 @@ package org.h2.mode;
import
java.util.HashMap
;
import
org.h2.engine.Database
;
import
org.h2.expression.Function
;
import
org.h2.expression.FunctionInfo
;
/**
* Base class for mode-specific functions.
*/
abstract
class
FunctionsBase
{
abstract
class
FunctionsBase
extends
Function
{
FunctionsBase
(
Database
database
,
FunctionInfo
info
)
{
super
(
database
,
info
);
}
/**
* Copy a standard function to a mode functions with a different name.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mode/FunctionsMSSQLServer.java
浏览文件 @
6ecfc2ce
...
...
@@ -39,6 +39,7 @@ public final class FunctionsMSSQLServer extends FunctionsBase {
return
info
!=
null
?
new
Function
(
database
,
info
)
:
null
;
}
private
FunctionsMSSQLServer
()
{
private
FunctionsMSSQLServer
(
Database
database
,
FunctionInfo
info
)
{
super
(
database
,
info
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mode/FunctionsMySQL.java
浏览文件 @
6ecfc2ce
...
...
@@ -5,14 +5,24 @@
*/
package
org
.
h2
.
mode
;
import
java.sql.Connection
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Function
;
import
org.h2.expression.FunctionInfo
;
import
org.h2.expression.ValueExpression
;
import
org.h2.message.DbException
;
import
org.h2.util.StringUtils
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueString
;
/**
* This class implements some MySQL-specific functions.
...
...
@@ -20,7 +30,20 @@ import org.h2.util.StringUtils;
* @author Jason Brittain
* @author Thomas Mueller
*/
public
class
FunctionsMySQL
{
public
class
FunctionsMySQL
extends
FunctionsBase
{
private
static
final
int
UNIX_TIMESTAMP
=
1001
,
FROM_UNIXTIME
=
1002
,
DATE
=
1003
;
private
static
final
HashMap
<
String
,
FunctionInfo
>
FUNCTIONS
=
new
HashMap
<>();
static
{
FUNCTIONS
.
put
(
"UNIX_TIMESTAMP"
,
new
FunctionInfo
(
"UNIX_TIMESTAMP"
,
UNIX_TIMESTAMP
,
VAR_ARGS
,
Value
.
INT
,
false
,
false
,
false
));
FUNCTIONS
.
put
(
"FROM_UNIXTIME"
,
new
FunctionInfo
(
"FROM_UNIXTIME"
,
FROM_UNIXTIME
,
VAR_ARGS
,
Value
.
STRING
,
false
,
true
,
false
));
FUNCTIONS
.
put
(
"DATE"
,
new
FunctionInfo
(
"DATE"
,
DATE
,
1
,
Value
.
DATE
,
false
,
true
,
false
));
}
/**
* The date format of a MySQL formatted date/time.
...
...
@@ -60,27 +83,6 @@ public class FunctionsMySQL {
"%%"
,
"%"
,
};
/**
* Register the functionality in the database.
* Nothing happens if the functions are already registered.
*
* @param conn the connection
*/
public
static
void
register
(
Connection
conn
)
throws
SQLException
{
String
[]
init
=
{
"UNIX_TIMESTAMP"
,
"unixTimestamp"
,
"FROM_UNIXTIME"
,
"fromUnixTime"
,
"DATE"
,
"date"
,
};
Statement
stat
=
conn
.
createStatement
();
for
(
int
i
=
0
;
i
<
init
.
length
;
i
+=
2
)
{
String
alias
=
init
[
i
],
method
=
init
[
i
+
1
];
stat
.
execute
(
"CREATE ALIAS IF NOT EXISTS "
+
alias
+
" FOR \""
+
FunctionsMySQL
.
class
.
getName
()
+
"."
+
method
+
"\""
);
}
}
/**
* Get the seconds since 1970-01-01 00:00:00 UTC.
* See
...
...
@@ -140,24 +142,104 @@ public class FunctionsMySQL {
}
/**
* See
* http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date
* This function is dependent on the exact formatting of the MySQL date/time
* string.
* Returns mode-specific function for a given name, or {@code null}.
*
* @param dateTime The date/time String from which to extract just the date
* part.
* @return the date part of the given date/time String argument.
* @param database
* the database
* @param upperName
* the upper-case name of a function
* @return the function with specified name or {@code null}
*/
public
static
String
date
(
String
dateTime
)
{
if
(
dateTime
==
null
)
{
return
null
;
public
static
Function
getFunction
(
Database
database
,
String
upperName
)
{
FunctionInfo
info
=
FUNCTIONS
.
get
(
upperName
);
return
info
!=
null
?
new
FunctionsMySQL
(
database
,
info
)
:
null
;
}
FunctionsMySQL
(
Database
database
,
FunctionInfo
info
)
{
super
(
database
,
info
);
}
@Override
protected
void
checkParameterCount
(
int
len
)
{
int
min
,
max
;
switch
(
info
.
type
)
{
case
UNIX_TIMESTAMP:
min
=
0
;
max
=
2
;
break
;
case
FROM_UNIXTIME:
min
=
1
;
max
=
2
;
break
;
case
DATE:
min
=
1
;
max
=
1
;
break
;
default
:
DbException
.
throwInternalError
(
"type="
+
info
.
type
);
return
;
}
if
(
len
<
min
||
len
>
max
)
{
throw
DbException
.
get
(
ErrorCode
.
INVALID_PARAMETER_COUNT_2
,
info
.
name
,
min
+
".."
+
max
);
}
int
index
=
dateTime
.
indexOf
(
' '
);
if
(
index
!=
-
1
)
{
return
dateTime
.
substring
(
0
,
index
);
}
@Override
public
Expression
optimize
(
Session
session
)
{
boolean
allConst
=
info
.
deterministic
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Expression
e
=
args
[
i
];
if
(
e
==
null
)
{
continue
;
}
e
=
e
.
optimize
(
session
);
args
[
i
]
=
e
;
if
(!
e
.
isConstant
())
{
allConst
=
false
;
}
}
if
(
allConst
)
{
return
ValueExpression
.
get
(
getValue
(
session
));
}
dataType
=
info
.
returnDataType
;
DataType
dt
=
DataType
.
getDataType
(
dataType
);
precision
=
dt
.
defaultPrecision
;
scale
=
dt
.
defaultScale
;
displaySize
=
dt
.
defaultDisplaySize
;
return
this
;
}
@Override
protected
Value
getValueWithArgs
(
Session
session
,
Expression
[]
args
)
{
Value
[]
values
=
new
Value
[
args
.
length
];
Value
v0
=
getNullOrValue
(
session
,
args
,
values
,
0
);
Value
v1
=
getNullOrValue
(
session
,
args
,
values
,
1
);
Value
result
;
switch
(
info
.
type
)
{
case
UNIX_TIMESTAMP:
result
=
ValueInt
.
get
(
v0
==
null
?
unixTimestamp
()
:
unixTimestamp
(
v0
.
getTimestamp
()));
break
;
case
FROM_UNIXTIME:
result
=
ValueString
.
get
(
v1
==
null
?
fromUnixTime
(
v0
.
getInt
())
:
fromUnixTime
(
v0
.
getInt
(),
v1
.
getString
()));
break
;
case
DATE:
switch
(
v0
.
getType
())
{
case
Value
.
DATE
:
result
=
v0
;
break
;
default
:
v0
=
v0
.
convertTo
(
Value
.
TIMESTAMP
);
//$FALL-THROUGH$
case
Value
.
TIMESTAMP
:
case
Value
.
TIMESTAMP_TZ
:
result
=
v0
.
convertTo
(
Value
.
DATE
);
}
break
;
default
:
throw
DbException
.
throwInternalError
(
"type="
+
info
.
type
);
}
return
dateTime
;
return
result
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestCompatibility.java
浏览文件 @
6ecfc2ce
...
...
@@ -307,7 +307,6 @@ public class TestCompatibility extends TestDb {
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')"
);
org
.
h2
.
mode
.
FunctionsMySQL
.
register
(
conn
);
assertResult
(
"0"
,
stat
,
"SELECT UNIX_TIMESTAMP('1970-01-01 00:00:00Z')"
);
assertResult
(
"1196418619"
,
stat
,
"SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')"
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论