Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
e0e2869b
提交
e0e2869b
authored
12月 16, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
488ecc5e
隐藏空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
895 行增加
和
368 行删除
+895
-368
Command.java
h2/src/main/org/h2/command/Command.java
+5
-3
Parser.java
h2/src/main/org/h2/command/Parser.java
+6
-0
SelectUnion.java
h2/src/main/org/h2/command/dml/SelectUnion.java
+2
-5
Set.java
h2/src/main/org/h2/command/dml/Set.java
+6
-0
SetTypes.java
h2/src/main/org/h2/command/dml/SetTypes.java
+3
-2
ErrorCode.java
h2/src/main/org/h2/constant/ErrorCode.java
+1
-0
Database.java
h2/src/main/org/h2/engine/Database.java
+20
-3
Session.java
h2/src/main/org/h2/engine/Session.java
+26
-7
Function.java
h2/src/main/org/h2/expression/Function.java
+464
-303
BtreeIndex.java
h2/src/main/org/h2/index/BtreeIndex.java
+0
-2
_messages_en.properties
h2/src/main/org/h2/res/_messages_en.properties
+1
-0
help.csv
h2/src/main/org/h2/res/help.csv
+25
-0
FtpControl.java
h2/src/main/org/h2/server/ftp/FtpControl.java
+1
-0
WebServer.java
h2/src/main/org/h2/server/web/WebServer.java
+7
-0
WebThread.java
h2/src/main/org/h2/server/web/WebThread.java
+130
-5
table.js
h2/src/main/org/h2/server/web/res/table.js
+34
-5
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+9
-4
Server.java
h2/src/main/org/h2/tools/Server.java
+29
-27
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+11
-2
TestSessionsLocks.java
h2/src/test/org/h2/test/db/TestSessionsLocks.java
+115
-0
没有找到文件。
h2/src/main/org/h2/command/Command.java
浏览文件 @
e0e2869b
...
@@ -64,10 +64,11 @@ public abstract class Command implements CommandInterface {
...
@@ -64,10 +64,11 @@ public abstract class Command implements CommandInterface {
startTime
=
System
.
currentTimeMillis
();
startTime
=
System
.
currentTimeMillis
();
Database
database
=
session
.
getDatabase
();
Database
database
=
session
.
getDatabase
();
Object
sync
=
database
.
getMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
Object
sync
=
database
.
getMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
session
.
waitIfExclusiveModeEnabled
();
synchronized
(
sync
)
{
synchronized
(
sync
)
{
try
{
try
{
database
.
checkPowerOff
();
database
.
checkPowerOff
();
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
startTime
);
return
query
(
maxrows
);
return
query
(
maxrows
);
}
catch
(
Throwable
e
)
{
}
catch
(
Throwable
e
)
{
SQLException
s
=
Message
.
convert
(
e
);
SQLException
s
=
Message
.
convert
(
e
);
...
@@ -92,7 +93,7 @@ public abstract class Command implements CommandInterface {
...
@@ -92,7 +93,7 @@ public abstract class Command implements CommandInterface {
}
}
private
void
stop
()
throws
SQLException
{
private
void
stop
()
throws
SQLException
{
session
.
setCurrentCommand
(
null
);
session
.
setCurrentCommand
(
null
,
0
);
if
(!
isTransactional
())
{
if
(!
isTransactional
())
{
session
.
commit
(
true
);
session
.
commit
(
true
);
}
else
if
(
session
.
getAutoCommit
())
{
}
else
if
(
session
.
getAutoCommit
())
{
...
@@ -115,9 +116,10 @@ public abstract class Command implements CommandInterface {
...
@@ -115,9 +116,10 @@ public abstract class Command implements CommandInterface {
startTime
=
System
.
currentTimeMillis
();
startTime
=
System
.
currentTimeMillis
();
Database
database
=
session
.
getDatabase
();
Database
database
=
session
.
getDatabase
();
Object
sync
=
database
.
getMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
Object
sync
=
database
.
getMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
session
.
waitIfExclusiveModeEnabled
();
synchronized
(
sync
)
{
synchronized
(
sync
)
{
int
rollback
=
session
.
getLogId
();
int
rollback
=
session
.
getLogId
();
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
startTime
);
try
{
try
{
database
.
checkPowerOff
();
database
.
checkPowerOff
();
return
update
();
return
update
();
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
e0e2869b
...
@@ -3656,6 +3656,12 @@ public class Parser {
...
@@ -3656,6 +3656,12 @@ public class Parser {
Set
command
=
new
Set
(
session
,
SetTypes
.
MVCC
);
Set
command
=
new
Set
(
session
,
SetTypes
.
MVCC
);
command
.
setInt
(
value
?
1
:
0
);
command
.
setInt
(
value
?
1
:
0
);
return
command
;
return
command
;
}
else
if
(
readIf
(
"EXCLUSIVE"
))
{
readIfEqualOrTo
();
boolean
value
=
readBooleanSetting
();
Set
command
=
new
Set
(
session
,
SetTypes
.
EXCLUSIVE
);
command
.
setInt
(
value
?
1
:
0
);
return
command
;
}
else
if
(
readIf
(
"IGNORECASE"
))
{
}
else
if
(
readIf
(
"IGNORECASE"
))
{
readIfEqualOrTo
();
readIfEqualOrTo
();
boolean
value
=
readBooleanSetting
();
boolean
value
=
readBooleanSetting
();
...
...
h2/src/main/org/h2/command/dml/SelectUnion.java
浏览文件 @
e0e2869b
...
@@ -94,20 +94,17 @@ public class SelectUnion extends Query {
...
@@ -94,20 +94,17 @@ public class SelectUnion extends Query {
}
}
switch
(
unionType
)
{
switch
(
unionType
)
{
case
UNION:
case
UNION:
case
EXCEPT:
left
.
setDistinct
(
true
);
left
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
result
.
setDistinct
();
result
.
setDistinct
();
break
;
break
;
case
UNION_ALL:
case
UNION_ALL:
break
;
break
;
case
EXCEPT:
case
INTERSECT:
result
.
setDistinct
();
// fall through
case
INTERSECT:
{
left
.
setDistinct
(
true
);
left
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
break
;
break
;
}
default
:
default
:
throw
Message
.
getInternalError
(
"type="
+
unionType
);
throw
Message
.
getInternalError
(
"type="
+
unionType
);
}
}
...
...
h2/src/main/org/h2/command/dml/Set.java
浏览文件 @
e0e2869b
...
@@ -274,6 +274,12 @@ public class Set extends Prepared {
...
@@ -274,6 +274,12 @@ public class Set extends Prepared {
database
.
setMaxOperationMemory
(
value
);
database
.
setMaxOperationMemory
(
value
);
break
;
break
;
}
}
case
SetTypes
.
EXCLUSIVE
:
{
session
.
getUser
().
checkAdmin
();
int
value
=
getIntValue
();
database
.
setExclusiveSession
(
value
==
1
?
session
:
null
);
break
;
}
default
:
default
:
throw
Message
.
getInternalError
(
"type="
+
type
);
throw
Message
.
getInternalError
(
"type="
+
type
);
}
}
...
...
h2/src/main/org/h2/command/dml/SetTypes.java
浏览文件 @
e0e2869b
...
@@ -20,10 +20,10 @@ public class SetTypes {
...
@@ -20,10 +20,10 @@ public class SetTypes {
public
static
final
int
LOG
=
19
,
THROTTLE
=
20
,
MAX_MEMORY_UNDO
=
21
,
MAX_LENGTH_INPLACE_LOB
=
22
;
public
static
final
int
LOG
=
19
,
THROTTLE
=
20
,
MAX_MEMORY_UNDO
=
21
,
MAX_LENGTH_INPLACE_LOB
=
22
;
public
static
final
int
COMPRESS_LOB
=
23
,
ALLOW_LITERALS
=
24
,
MULTI_THREADED
=
25
,
SCHEMA
=
26
;
public
static
final
int
COMPRESS_LOB
=
23
,
ALLOW_LITERALS
=
24
,
MULTI_THREADED
=
25
,
SCHEMA
=
26
;
public
static
final
int
OPTIMIZE_REUSE_RESULTS
=
27
,
SCHEMA_SEARCH_PATH
=
28
,
UNDO_LOG
=
29
;
public
static
final
int
OPTIMIZE_REUSE_RESULTS
=
27
,
SCHEMA_SEARCH_PATH
=
28
,
UNDO_LOG
=
29
;
public
static
final
int
REFERENTIAL_INTEGRITY
=
30
,
MVCC
=
31
,
MAX_OPERATION_MEMORY
=
32
;
public
static
final
int
REFERENTIAL_INTEGRITY
=
30
,
MVCC
=
31
,
MAX_OPERATION_MEMORY
=
32
,
EXCLUSIVE
=
33
;
private
static
ObjectArray
types
=
new
ObjectArray
();
private
static
ObjectArray
types
=
new
ObjectArray
();
static
{
static
{
setType
(
IGNORECASE
,
"IGNORECASE"
);
setType
(
IGNORECASE
,
"IGNORECASE"
);
setType
(
MAX_LOG_SIZE
,
"MAX_LOG_SIZE"
);
setType
(
MAX_LOG_SIZE
,
"MAX_LOG_SIZE"
);
...
@@ -57,6 +57,7 @@ public class SetTypes {
...
@@ -57,6 +57,7 @@ public class SetTypes {
setType
(
REFERENTIAL_INTEGRITY
,
"REFERENTIAL_INTEGRITY"
);
setType
(
REFERENTIAL_INTEGRITY
,
"REFERENTIAL_INTEGRITY"
);
setType
(
MVCC
,
"MVCC"
);
setType
(
MVCC
,
"MVCC"
);
setType
(
MAX_OPERATION_MEMORY
,
"MAX_OPERATION_MEMORY"
);
setType
(
MAX_OPERATION_MEMORY
,
"MAX_OPERATION_MEMORY"
);
setType
(
EXCLUSIVE
,
"EXCLUSIVE"
);
}
}
private
static
void
setType
(
int
type
,
String
name
)
{
private
static
void
setType
(
int
type
,
String
name
)
{
...
...
h2/src/main/org/h2/constant/ErrorCode.java
浏览文件 @
e0e2869b
...
@@ -315,6 +315,7 @@ public class ErrorCode {
...
@@ -315,6 +315,7 @@ public class ErrorCode {
public
static
final
int
AGGREGATE_NOT_FOUND_1
=
90132
;
public
static
final
int
AGGREGATE_NOT_FOUND_1
=
90132
;
public
static
final
int
CANNOT_CHANGE_SETTING_WHEN_OPEN_1
=
90133
;
public
static
final
int
CANNOT_CHANGE_SETTING_WHEN_OPEN_1
=
90133
;
public
static
final
int
ACCESS_DENIED_TO_CLASS_1
=
90134
;
public
static
final
int
ACCESS_DENIED_TO_CLASS_1
=
90134
;
public
static
final
int
DATABASE_IS_IN_EXCLUSIVE_MODE
=
90135
;
/**
/**
* INTERNAL
* INTERNAL
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
e0e2869b
...
@@ -7,9 +7,11 @@ package org.h2.engine;
...
@@ -7,9 +7,11 @@ package org.h2.engine;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
java.util.Set
;
import
java.util.StringTokenizer
;
import
java.util.StringTokenizer
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.api.DatabaseEventListener
;
...
@@ -85,7 +87,8 @@ public class Database implements DataHandler {
...
@@ -85,7 +87,8 @@ public class Database implements DataHandler {
private
final
HashMap
userDataTypes
=
new
HashMap
();
private
final
HashMap
userDataTypes
=
new
HashMap
();
private
final
HashMap
aggregates
=
new
HashMap
();
private
final
HashMap
aggregates
=
new
HashMap
();
private
final
HashMap
comments
=
new
HashMap
();
private
final
HashMap
comments
=
new
HashMap
();
private
final
HashSet
sessions
=
new
HashSet
();
private
final
Set
sessions
=
Collections
.
synchronizedSet
(
new
HashSet
());
private
Session
exclusiveSession
;
private
final
BitField
objectIds
=
new
BitField
();
private
final
BitField
objectIds
=
new
BitField
();
private
final
Object
lobSyncObject
=
new
Object
();
private
final
Object
lobSyncObject
=
new
Object
();
...
@@ -772,7 +775,10 @@ public class Database implements DataHandler {
...
@@ -772,7 +775,10 @@ public class Database implements DataHandler {
return
getUser
(
name
,
Message
.
getSQLException
(
ErrorCode
.
USER_NOT_FOUND_1
,
name
));
return
getUser
(
name
,
Message
.
getSQLException
(
ErrorCode
.
USER_NOT_FOUND_1
,
name
));
}
}
public
synchronized
Session
createSession
(
User
user
)
{
public
synchronized
Session
createSession
(
User
user
)
throws
SQLException
{
if
(
exclusiveSession
!=
null
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
DATABASE_IS_IN_EXCLUSIVE_MODE
);
}
Session
session
=
new
Session
(
this
,
user
,
++
nextSessionId
);
Session
session
=
new
Session
(
this
,
user
,
++
nextSessionId
);
sessions
.
add
(
session
);
sessions
.
add
(
session
);
traceSystem
.
getTrace
(
Trace
.
SESSION
).
info
(
"connecting #"
+
session
.
getId
()
+
" to "
+
databaseName
);
traceSystem
.
getTrace
(
Trace
.
SESSION
).
info
(
"connecting #"
+
session
.
getId
()
+
" to "
+
databaseName
);
...
@@ -785,6 +791,9 @@ public class Database implements DataHandler {
...
@@ -785,6 +791,9 @@ public class Database implements DataHandler {
public
synchronized
void
removeSession
(
Session
session
)
throws
SQLException
{
public
synchronized
void
removeSession
(
Session
session
)
throws
SQLException
{
if
(
session
!=
null
)
{
if
(
session
!=
null
)
{
if
(
exclusiveSession
==
session
)
{
exclusiveSession
=
null
;
}
sessions
.
remove
(
session
);
sessions
.
remove
(
session
);
if
(
session
!=
systemSession
)
{
if
(
session
!=
systemSession
)
{
traceSystem
.
getTrace
(
Trace
.
SESSION
).
info
(
"disconnecting #"
+
session
.
getId
());
traceSystem
.
getTrace
(
Trace
.
SESSION
).
info
(
"disconnecting #"
+
session
.
getId
());
...
@@ -1032,7 +1041,7 @@ public class Database implements DataHandler {
...
@@ -1032,7 +1041,7 @@ public class Database implements DataHandler {
return
log
;
return
log
;
}
}
public
synchronized
Session
[]
getSessions
()
{
public
Session
[]
getSessions
()
{
Session
[]
list
=
new
Session
[
sessions
.
size
()];
Session
[]
list
=
new
Session
[
sessions
.
size
()];
sessions
.
toArray
(
list
);
sessions
.
toArray
(
list
);
return
list
;
return
list
;
...
@@ -1624,4 +1633,12 @@ public class Database implements DataHandler {
...
@@ -1624,4 +1633,12 @@ public class Database implements DataHandler {
return
maxOperationMemory
;
return
maxOperationMemory
;
}
}
public
Session
getExclusiveSession
()
{
return
exclusiveSession
;
}
public
void
setExclusiveSession
(
Session
session
)
{
this
.
exclusiveSession
=
session
;
}
}
}
h2/src/main/org/h2/engine/Session.java
浏览文件 @
e0e2869b
...
@@ -73,7 +73,8 @@ public class Session implements SessionInterface {
...
@@ -73,7 +73,8 @@ public class Session implements SessionInterface {
private
String
currentTransactionName
;
private
String
currentTransactionName
;
private
boolean
isClosed
;
private
boolean
isClosed
;
private
boolean
rollbackMode
;
private
boolean
rollbackMode
;
private
long
loginTime
=
System
.
currentTimeMillis
();
private
long
sessionStart
=
System
.
currentTimeMillis
();
private
long
currentCommandStart
;
public
Session
()
{
public
Session
()
{
}
}
...
@@ -498,8 +499,9 @@ public class Session implements SessionInterface {
...
@@ -498,8 +499,9 @@ public class Session implements SessionInterface {
}
}
}
}
public
void
setCurrentCommand
(
Command
command
)
{
public
void
setCurrentCommand
(
Command
command
,
long
startTime
)
{
this
.
currentCommand
=
command
;
this
.
currentCommand
=
command
;
this
.
currentCommandStart
=
startTime
;
}
}
public
void
checkCancelled
()
throws
SQLException
{
public
void
checkCancelled
()
throws
SQLException
{
...
@@ -508,9 +510,12 @@ public class Session implements SessionInterface {
...
@@ -508,9 +510,12 @@ public class Session implements SessionInterface {
}
}
}
}
public
String
getCurrentCommand
()
{
public
Command
getCurrentCommand
()
{
Command
c
=
currentCommand
;
return
currentCommand
;
return
c
==
null
?
null
:
c
.
toString
();
}
public
long
getCurrentCommandStart
()
{
return
currentCommandStart
;
}
}
public
boolean
getAllowLiterals
()
{
public
boolean
getAllowLiterals
()
{
...
@@ -609,8 +614,8 @@ public class Session implements SessionInterface {
...
@@ -609,8 +614,8 @@ public class Session implements SessionInterface {
return
rollbackMode
;
return
rollbackMode
;
}
}
public
long
get
LoginTime
()
{
public
long
get
SessionStart
()
{
return
loginTime
;
return
sessionStart
;
}
}
public
Table
[]
getLocks
()
{
public
Table
[]
getLocks
()
{
...
@@ -621,4 +626,18 @@ public class Session implements SessionInterface {
...
@@ -621,4 +626,18 @@ public class Session implements SessionInterface {
}
}
}
}
public
void
waitIfExclusiveModeEnabled
()
{
while
(
true
)
{
Session
exclusive
=
database
.
getExclusiveSession
();
if
(
exclusive
==
null
||
exclusive
==
this
)
{
break
;
}
try
{
Thread
.
sleep
(
100
);
}
catch
(
InterruptedException
e
)
{
// ignore
}
}
}
}
}
h2/src/main/org/h2/expression/Function.java
浏览文件 @
e0e2869b
...
@@ -16,6 +16,7 @@ import java.util.HashMap;
...
@@ -16,6 +16,7 @@ import java.util.HashMap;
import
java.util.Locale
;
import
java.util.Locale
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
org.h2.command.Command
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Mode
;
import
org.h2.engine.Mode
;
...
@@ -85,7 +86,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -85,7 +86,7 @@ public class Function extends Expression implements FunctionCall {
public
static
final
int
IFNULL
=
200
,
CASEWHEN
=
201
,
CONVERT
=
202
,
CAST
=
203
,
COALESCE
=
204
,
NULLIF
=
205
,
public
static
final
int
IFNULL
=
200
,
CASEWHEN
=
201
,
CONVERT
=
202
,
CAST
=
203
,
COALESCE
=
204
,
NULLIF
=
205
,
CASE
=
206
,
NEXTVAL
=
207
,
CURRVAL
=
208
,
ARRAY_GET
=
209
,
CSVREAD
=
210
,
CSVWRITE
=
211
,
CASE
=
206
,
NEXTVAL
=
207
,
CURRVAL
=
208
,
ARRAY_GET
=
209
,
CSVREAD
=
210
,
CSVWRITE
=
211
,
MEMORY_FREE
=
212
,
MEMORY_USED
=
213
,
LOCK_MODE
=
214
,
SCHEMA
=
215
,
SESSION_ID
=
216
,
ARRAY_LENGTH
=
217
,
MEMORY_FREE
=
212
,
MEMORY_USED
=
213
,
LOCK_MODE
=
214
,
SCHEMA
=
215
,
SESSION_ID
=
216
,
ARRAY_LENGTH
=
217
,
LINK_SCHEMA
=
218
,
TABLE
=
219
,
LEAST
=
220
,
GREATEST
=
221
,
TABLE_DISTINCT
=
222
;
LINK_SCHEMA
=
218
,
TABLE
=
219
,
LEAST
=
220
,
GREATEST
=
221
,
TABLE_DISTINCT
=
222
,
CANCEL_SESSION
=
223
;
private
static
final
int
VAR_ARGS
=
-
1
;
private
static
final
int
VAR_ARGS
=
-
1
;
...
@@ -287,6 +288,7 @@ public class Function extends Expression implements FunctionCall {
...
@@ -287,6 +288,7 @@ public class Function extends Expression implements FunctionCall {
addFunctionWithNull
(
"TABLE_DISTINCT"
,
TABLE_DISTINCT
,
VAR_ARGS
,
Value
.
RESULT_SET
);
addFunctionWithNull
(
"TABLE_DISTINCT"
,
TABLE_DISTINCT
,
VAR_ARGS
,
Value
.
RESULT_SET
);
addFunctionWithNull
(
"LEAST"
,
LEAST
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"LEAST"
,
LEAST
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"GREATEST"
,
GREATEST
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"GREATEST"
,
GREATEST
,
VAR_ARGS
,
Value
.
NULL
);
addFunction
(
"CANCEL_SESSION"
,
CANCEL_SESSION
,
1
,
Value
.
BOOLEAN
);
}
}
private
static
void
addFunction
(
String
name
,
int
type
,
int
parameterCount
,
int
dataType
,
private
static
void
addFunction
(
String
name
,
int
type
,
int
parameterCount
,
int
dataType
,
...
@@ -361,41 +363,332 @@ public class Function extends Expression implements FunctionCall {
...
@@ -361,41 +363,332 @@ public class Function extends Expression implements FunctionCall {
return
null
;
return
null
;
}
}
public
Value
getValueWithArgs
(
Session
session
,
Expression
[]
args
)
throws
SQLException
{
public
Value
getSimpleValue
(
Session
session
,
Value
v0
,
Expression
[]
args
)
throws
SQLException
{
if
(
info
.
nullIfParameterIsNull
)
{
Value
result
;
switch
(
info
.
type
)
{
case
ABS:
result
=
v0
.
getSignum
()
>
0
?
v0
:
v0
.
negate
();
break
;
case
ACOS:
result
=
ValueDouble
.
get
(
Math
.
acos
(
v0
.
getDouble
()));
break
;
case
ASIN:
result
=
ValueDouble
.
get
(
Math
.
asin
(
v0
.
getDouble
()));
break
;
case
ATAN:
result
=
ValueDouble
.
get
(
Math
.
atan
(
v0
.
getDouble
()));
break
;
case
CEILING:
result
=
ValueDouble
.
get
(
Math
.
ceil
(
v0
.
getDouble
()));
break
;
case
COS:
result
=
ValueDouble
.
get
(
Math
.
cos
(
v0
.
getDouble
()));
break
;
case
COT:
{
double
d
=
Math
.
tan
(
v0
.
getDouble
());
if
(
d
==
0.0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
DIVISION_BY_ZERO_1
,
getSQL
());
}
result
=
ValueDouble
.
get
(
1
.
/
d
);
break
;
}
case
DEGREES:
result
=
ValueDouble
.
get
(
Math
.
toDegrees
(
v0
.
getDouble
()));
break
;
case
EXP:
result
=
ValueDouble
.
get
(
Math
.
exp
(
v0
.
getDouble
()));
break
;
case
FLOOR:
result
=
ValueDouble
.
get
(
Math
.
floor
(
v0
.
getDouble
()));
break
;
case
LOG:
result
=
ValueDouble
.
get
(
Math
.
log
(
v0
.
getDouble
()));
break
;
case
LOG10:
result
=
ValueDouble
.
get
(
log10
(
v0
.
getDouble
()));
break
;
case
PI:
result
=
ValueDouble
.
get
(
Math
.
PI
);
break
;
case
RADIANS:
result
=
ValueDouble
.
get
(
Math
.
toRadians
(
v0
.
getDouble
()));
break
;
case
RAND:
{
if
(
v0
!=
null
)
{
session
.
getRandom
().
setSeed
(
v0
.
getInt
());
}
// TODO function rand: if seed value is set,
// return a random value? probably yes
result
=
ValueDouble
.
get
(
session
.
getRandom
().
nextDouble
());
break
;
}
case
ROUNDMAGIC:
result
=
ValueDouble
.
get
(
roundmagic
(
v0
.
getDouble
()));
break
;
case
SIGN:
result
=
ValueInt
.
get
(
v0
.
getSignum
());
break
;
case
SIN:
result
=
ValueDouble
.
get
(
Math
.
sin
(
v0
.
getDouble
()));
break
;
case
SQRT:
result
=
ValueDouble
.
get
(
Math
.
sqrt
(
v0
.
getDouble
()));
break
;
case
TAN:
result
=
ValueDouble
.
get
(
Math
.
tan
(
v0
.
getDouble
()));
break
;
case
SECURE_RAND:
result
=
ValueBytes
.
getNoCopy
(
RandomUtils
.
getSecureBytes
(
v0
.
getInt
()));
break
;
case
EXPAND:
result
=
ValueBytes
.
getNoCopy
(
CompressTool
.
getInstance
().
expand
(
v0
.
getBytesNoCopy
()));
break
;
case
ZERO:
result
=
ValueInt
.
get
(
0
);
break
;
case
RANDOM_UUID:
result
=
ValueUuid
.
getNewRandom
();
break
;
// string
case
ASCII:
{
String
s
=
v0
.
getString
();
if
(
s
.
length
()
==
0
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueInt
.
get
(
s
.
charAt
(
0
));
}
break
;
}
case
BIT_LENGTH:
result
=
ValueInt
.
get
(
16
*
length
(
v0
));
break
;
case
CHAR:
result
=
ValueString
.
get
(
String
.
valueOf
((
char
)
v0
.
getInt
()));
break
;
case
CHAR_LENGTH:
case
LENGTH:
result
=
ValueInt
.
get
(
length
(
v0
));
break
;
case
OCTET_LENGTH:
result
=
ValueInt
.
get
(
2
*
length
(
v0
));
break
;
case
CONCAT:
{
result
=
ValueNull
.
INSTANCE
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
if
(
getNullOrValue
(
session
,
args
,
i
)
==
ValueNull
.
INSTANCE
)
{
Value
v
=
args
[
i
].
getValue
(
session
);
return
ValueNull
.
INSTANCE
;
if
(
v
==
ValueNull
.
INSTANCE
)
{
continue
;
}
if
(
result
==
ValueNull
.
INSTANCE
)
{
result
=
v
;
}
else
{
result
=
ValueString
.
get
(
result
.
getString
().
concat
(
v
.
getString
()));
}
}
}
}
break
;
}
case
HEXTORAW:
result
=
ValueString
.
get
(
hexToRaw
(
v0
.
getString
()));
break
;
case
LOWER:
case
LCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
result
=
ValueString
.
get
(
v0
.
getString
().
toLowerCase
());
break
;
case
RAWTOHEX:
result
=
ValueString
.
get
(
rawToHex
(
v0
.
getString
()));
break
;
case
SOUNDEX:
result
=
ValueString
.
get
(
getSoundex
(
v0
.
getString
()));
break
;
case
SPACE:
{
// TODO DOS attacks: limit len?
int
len
=
Math
.
max
(
0
,
v0
.
getInt
());
char
[]
chars
=
new
char
[
len
];
for
(
int
i
=
len
-
1
;
i
>=
0
;
i
--)
{
chars
[
i
]
=
' '
;
}
result
=
ValueString
.
get
(
new
String
(
chars
));
break
;
}
case
UPPER:
case
UCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
result
=
ValueString
.
get
(
v0
.
getString
().
toUpperCase
());
break
;
case
STRINGENCODE:
result
=
ValueString
.
get
(
StringUtils
.
javaEncode
(
v0
.
getString
()));
break
;
case
STRINGDECODE:
result
=
ValueString
.
get
(
StringUtils
.
javaDecode
(
v0
.
getString
()));
break
;
case
STRINGTOUTF8:
result
=
ValueBytes
.
getNoCopy
(
StringUtils
.
utf8Encode
(
v0
.
getString
()));
break
;
case
UTF8TOSTRING:
result
=
ValueString
.
get
(
StringUtils
.
utf8Decode
(
v0
.
getBytesNoCopy
()));
break
;
case
XMLCOMMENT:
result
=
ValueString
.
get
(
StringUtils
.
xmlComment
(
v0
.
getString
()));
break
;
case
XMLCDATA:
result
=
ValueString
.
get
(
StringUtils
.
xmlCData
(
v0
.
getString
()));
break
;
case
XMLSTARTDOC:
result
=
ValueString
.
get
(
StringUtils
.
xmlStartDoc
());
break
;
case
XMLTEXT:
result
=
ValueString
.
get
(
StringUtils
.
xmlText
(
v0
.
getString
()));
break
;
case
DAYNAME:
{
synchronized
(
FORMAT_DAYNAME
)
{
result
=
ValueString
.
get
(
FORMAT_DAYNAME
.
format
(
v0
.
getDateNoCopy
()));
}
break
;
}
case
DAYOFMONTH:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_MONTH
));
break
;
case
DAYOFWEEK:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_WEEK
));
break
;
case
DAYOFYEAR:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_YEAR
));
break
;
case
HOUR:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
HOUR_OF_DAY
));
break
;
case
MINUTE:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
MINUTE
));
break
;
case
MONTH:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
MONTH
));
break
;
case
MONTHNAME:
{
synchronized
(
FORMAT_MONTHNAME
)
{
result
=
ValueString
.
get
(
FORMAT_MONTHNAME
.
format
(
v0
.
getDateNoCopy
()));
}
break
;
}
case
QUARTER:
result
=
ValueInt
.
get
((
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
MONTH
)
-
1
)
/
3
+
1
);
break
;
case
SECOND:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
SECOND
));
break
;
case
WEEK:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
WEEK_OF_YEAR
));
break
;
case
YEAR:
result
=
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
YEAR
));
break
;
case
CURDATE:
case
CURRENT_DATE:
// need to normalize
result
=
ValueDate
.
get
(
new
Date
(
System
.
currentTimeMillis
()));
break
;
case
CURTIME:
case
CURRENT_TIME:
// need to normalize
result
=
ValueTime
.
get
(
new
Time
(
System
.
currentTimeMillis
()));
break
;
case
NOW:
case
CURRENT_TIMESTAMP:
{
ValueTimestamp
vt
=
ValueTimestamp
.
getNoCopy
(
new
Timestamp
(
System
.
currentTimeMillis
()));
if
(
v0
!=
null
)
{
Mode
mode
=
database
.
getMode
();
vt
=
(
ValueTimestamp
)
vt
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
v0
.
getInt
());
}
result
=
vt
;
break
;
}
case
DATABASE:
result
=
ValueString
.
get
(
database
.
getShortName
());
break
;
case
USER:
case
CURRENT_USER:
result
=
ValueString
.
get
(
session
.
getUser
().
getName
());
break
;
case
IDENTITY:
result
=
session
.
getLastIdentity
();
break
;
case
AUTOCOMMIT:
result
=
ValueBoolean
.
get
(
session
.
getAutoCommit
());
break
;
case
READONLY:
result
=
ValueBoolean
.
get
(
database
.
getReadOnly
());
break
;
case
DATABASE_PATH:
{
String
path
=
database
.
getDatabasePath
();
result
=
path
==
null
?
(
Value
)
ValueNull
.
INSTANCE
:
ValueString
.
get
(
path
);
break
;
}
case
LOCK_TIMEOUT:
result
=
ValueInt
.
get
(
session
.
getLockTimeout
());
break
;
case
CAST:
case
CONVERT:
{
v0
=
v0
.
convertTo
(
dataType
);
Mode
mode
=
database
.
getMode
();
v0
=
v0
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
scale
);
v0
=
v0
.
convertPrecision
(
getPrecision
());
result
=
v0
;
break
;
}
case
TABLE:
result
=
getTable
(
session
,
args
,
false
,
false
);
break
;
case
TABLE_DISTINCT:
result
=
getTable
(
session
,
args
,
false
,
true
);
break
;
case
MEMORY_FREE:
session
.
getUser
().
checkAdmin
();
result
=
ValueInt
.
get
(
MemoryUtils
.
getMemoryFree
());
break
;
case
MEMORY_USED:
session
.
getUser
().
checkAdmin
();
result
=
ValueInt
.
get
(
MemoryUtils
.
getMemoryUsed
());
break
;
case
LOCK_MODE:
result
=
ValueInt
.
get
(
database
.
getLockMode
());
break
;
case
SCHEMA:
result
=
ValueString
.
get
(
session
.
getCurrentSchemaName
());
break
;
case
SESSION_ID:
result
=
ValueInt
.
get
(
session
.
getId
());
break
;
case
IFNULL:
{
result
=
v0
==
ValueNull
.
INSTANCE
?
args
[
1
].
getValue
(
session
)
:
v0
;
break
;
}
}
Value
v0
=
getNullOrValue
(
session
,
args
,
0
);
switch
(
info
.
type
)
{
case
IFNULL:
return
v0
==
ValueNull
.
INSTANCE
?
args
[
1
].
getValue
(
session
)
:
v0
;
case
CASEWHEN:
{
case
CASEWHEN:
{
Expression
result
;
Expression
expr
;
if
(
v0
==
ValueNull
.
INSTANCE
||
!
v0
.
getBoolean
().
booleanValue
())
{
if
(
v0
==
ValueNull
.
INSTANCE
||
!
v0
.
getBoolean
().
booleanValue
())
{
result
=
args
[
2
];
expr
=
args
[
2
];
}
else
{
}
else
{
result
=
args
[
1
];
expr
=
args
[
1
];
}
}
Value
v
=
result
.
getValue
(
session
);
Value
v
=
expr
.
getValue
(
session
);
v
=
v
.
convertTo
(
dataType
);
result
=
v
.
convertTo
(
dataType
);
return
v
;
break
;
}
}
case
COALESCE:
{
case
COALESCE:
{
result
=
v0
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Value
v
=
i
==
0
?
v0
:
args
[
i
].
getValue
(
session
);
Value
v
=
i
==
0
?
v0
:
args
[
i
].
getValue
(
session
);
if
(!(
v
==
ValueNull
.
INSTANCE
))
{
if
(!(
v
==
ValueNull
.
INSTANCE
))
{
return
v
.
convertTo
(
dataType
);
result
=
v
.
convertTo
(
dataType
);
break
;
}
}
}
}
return
v0
;
break
;
}
}
case
GREATEST:
case
GREATEST:
case
LEAST:
{
case
LEAST:
{
Value
result
=
ValueNull
.
INSTANCE
;
result
=
ValueNull
.
INSTANCE
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Value
v
=
i
==
0
?
v0
:
args
[
i
].
getValue
(
session
);
Value
v
=
i
==
0
?
v0
:
args
[
i
].
getValue
(
session
);
if
(!(
v
==
ValueNull
.
INSTANCE
))
{
if
(!(
v
==
ValueNull
.
INSTANCE
))
{
...
@@ -412,18 +705,22 @@ public class Function extends Expression implements FunctionCall {
...
@@ -412,18 +705,22 @@ public class Function extends Expression implements FunctionCall {
}
}
}
}
}
}
return
result
;
break
;
}
}
case
CASE:
{
case
CASE:
{
// TODO function CASE: document & implement functionality
result
=
null
;
int
i
=
0
;
int
i
=
0
;
for
(;
i
<
args
.
length
;
i
++)
{
for
(;
i
<
args
.
length
;
i
++)
{
Value
when
=
args
[
i
++].
getValue
(
session
);
Value
when
=
args
[
i
++].
getValue
(
session
);
if
(
Boolean
.
TRUE
.
equals
(
when
))
{
if
(
Boolean
.
TRUE
.
equals
(
when
))
{
return
args
[
i
].
getValue
(
session
);
result
=
args
[
i
].
getValue
(
session
);
break
;
}
}
}
}
return
i
<
args
.
length
?
args
[
i
].
getValue
(
session
)
:
ValueNull
.
INSTANCE
;
if
(
result
==
null
)
{
result
=
i
<
args
.
length
?
args
[
i
].
getValue
(
session
)
:
ValueNull
.
INSTANCE
;
}
break
;
}
}
case
ARRAY_GET:
{
case
ARRAY_GET:
{
if
(
v0
.
getType
()
==
Value
.
ARRAY
)
{
if
(
v0
.
getType
()
==
Value
.
ARRAY
)
{
...
@@ -431,372 +728,248 @@ public class Function extends Expression implements FunctionCall {
...
@@ -431,372 +728,248 @@ public class Function extends Expression implements FunctionCall {
int
element
=
v1
.
getInt
();
int
element
=
v1
.
getInt
();
Value
[]
list
=
((
ValueArray
)
v0
).
getList
();
Value
[]
list
=
((
ValueArray
)
v0
).
getList
();
if
(
element
<
1
||
element
>
list
.
length
)
{
if
(
element
<
1
||
element
>
list
.
length
)
{
return
ValueNull
.
INSTANCE
;
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
list
[
element
-
1
];
}
}
return
list
[
element
-
1
];
}
else
{
result
=
ValueNull
.
INSTANCE
;
}
}
return
ValueNull
.
INSTANCE
;
break
;
}
}
case
ARRAY_LENGTH:
{
case
ARRAY_LENGTH:
{
if
(
v0
.
getType
()
==
Value
.
ARRAY
)
{
if
(
v0
.
getType
()
==
Value
.
ARRAY
)
{
Value
[]
list
=
((
ValueArray
)
v0
).
getList
();
Value
[]
list
=
((
ValueArray
)
v0
).
getList
();
return
ValueInt
.
get
(
list
.
length
);
result
=
ValueInt
.
get
(
list
.
length
);
}
else
{
result
=
ValueNull
.
INSTANCE
;
}
}
return
ValueNull
.
INSTANCE
;
break
;
}
case
CANCEL_SESSION:
{
result
=
ValueBoolean
.
get
(
cancelStatement
(
session
,
v0
.
getInt
()));
break
;
}
}
default
:
default
:
// ok
result
=
null
;
}
return
result
;
}
private
boolean
cancelStatement
(
Session
session
,
int
targetSessionId
)
throws
SQLException
{
session
.
getUser
().
checkAdmin
();
Session
[]
sessions
=
session
.
getDatabase
().
getSessions
();
for
(
int
i
=
0
;
i
<
sessions
.
length
;
i
++)
{
Session
s
=
sessions
[
i
];
if
(
s
.
getId
()
==
targetSessionId
)
{
Command
c
=
s
.
getCurrentCommand
();
if
(
c
==
null
)
{
return
false
;
}
else
{
c
.
cancel
();
return
true
;
}
}
}
return
false
;
}
public
Value
getValueWithArgs
(
Session
session
,
Expression
[]
args
)
throws
SQLException
{
if
(
info
.
nullIfParameterIsNull
)
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
if
(
getNullOrValue
(
session
,
args
,
i
)
==
ValueNull
.
INSTANCE
)
{
return
ValueNull
.
INSTANCE
;
}
}
}
Value
v0
=
getNullOrValue
(
session
,
args
,
0
);
Value
resultSimple
=
getSimpleValue
(
session
,
v0
,
args
);
if
(
resultSimple
!=
null
)
{
return
resultSimple
;
}
}
Value
v1
=
getNullOrValue
(
session
,
args
,
1
);
Value
v1
=
getNullOrValue
(
session
,
args
,
1
);
Value
v2
=
getNullOrValue
(
session
,
args
,
2
);
Value
v2
=
getNullOrValue
(
session
,
args
,
2
);
Value
v3
=
getNullOrValue
(
session
,
args
,
3
);
Value
v3
=
getNullOrValue
(
session
,
args
,
3
);
Value
v4
=
getNullOrValue
(
session
,
args
,
4
);
Value
v4
=
getNullOrValue
(
session
,
args
,
4
);
Value
v5
=
getNullOrValue
(
session
,
args
,
5
);
Value
v5
=
getNullOrValue
(
session
,
args
,
5
);
Value
result
;
switch
(
info
.
type
)
{
switch
(
info
.
type
)
{
case
ABS:
return
v0
.
getSignum
()
>
0
?
v0
:
v0
.
negate
();
case
ACOS:
return
ValueDouble
.
get
(
Math
.
acos
(
v0
.
getDouble
()));
case
ASIN:
return
ValueDouble
.
get
(
Math
.
asin
(
v0
.
getDouble
()));
case
ATAN:
return
ValueDouble
.
get
(
Math
.
atan
(
v0
.
getDouble
()));
case
ATAN2:
case
ATAN2:
return
ValueDouble
.
get
(
Math
.
atan2
(
v0
.
getDouble
(),
v1
.
getDouble
()));
result
=
ValueDouble
.
get
(
Math
.
atan2
(
v0
.
getDouble
(),
v1
.
getDouble
()));
break
;
case
BITAND:
case
BITAND:
return
ValueInt
.
get
(
v0
.
getInt
()
&
v1
.
getInt
());
result
=
ValueInt
.
get
(
v0
.
getInt
()
&
v1
.
getInt
());
break
;
case
BITOR:
case
BITOR:
return
ValueInt
.
get
(
v0
.
getInt
()
|
v1
.
getInt
());
result
=
ValueInt
.
get
(
v0
.
getInt
()
|
v1
.
getInt
());
break
;
case
BITXOR:
case
BITXOR:
return
ValueInt
.
get
(
v0
.
getInt
()
^
v1
.
getInt
());
result
=
ValueInt
.
get
(
v0
.
getInt
()
^
v1
.
getInt
());
case
CEILING:
break
;
return
ValueDouble
.
get
(
Math
.
ceil
(
v0
.
getDouble
()));
case
COS:
return
ValueDouble
.
get
(
Math
.
cos
(
v0
.
getDouble
()));
case
COT:
{
double
d
=
Math
.
tan
(
v0
.
getDouble
());
if
(
d
==
0.0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
DIVISION_BY_ZERO_1
,
getSQL
());
}
return
ValueDouble
.
get
(
1
.
/
d
);
}
case
DEGREES:
return
ValueDouble
.
get
(
Math
.
toDegrees
(
v0
.
getDouble
()));
case
EXP:
return
ValueDouble
.
get
(
Math
.
exp
(
v0
.
getDouble
()));
case
FLOOR:
return
ValueDouble
.
get
(
Math
.
floor
(
v0
.
getDouble
()));
case
LOG:
return
ValueDouble
.
get
(
Math
.
log
(
v0
.
getDouble
()));
case
LOG10:
return
ValueDouble
.
get
(
log10
(
v0
.
getDouble
()));
case
MOD:
{
case
MOD:
{
int
x
=
v1
.
getInt
();
int
x
=
v1
.
getInt
();
if
(
x
==
0.0
)
{
if
(
x
==
0.0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
DIVISION_BY_ZERO_1
,
getSQL
());
throw
Message
.
getSQLException
(
ErrorCode
.
DIVISION_BY_ZERO_1
,
getSQL
());
}
}
return
ValueInt
.
get
(
v0
.
getInt
()
%
x
);
result
=
ValueInt
.
get
(
v0
.
getInt
()
%
x
);
break
;
}
}
case
PI:
return
ValueDouble
.
get
(
Math
.
PI
);
case
POWER:
case
POWER:
return
ValueDouble
.
get
(
Math
.
pow
(
v0
.
getDouble
(),
v1
.
getDouble
()));
result
=
ValueDouble
.
get
(
Math
.
pow
(
v0
.
getDouble
(),
v1
.
getDouble
()));
case
RADIANS:
break
;
return
ValueDouble
.
get
(
Math
.
toRadians
(
v0
.
getDouble
()));
case
RAND:
{
if
(
v0
!=
null
)
{
session
.
getRandom
().
setSeed
(
v0
.
getInt
());
}
// TODO function rand: if seed value is set, return a random value?
// probably yes
return
ValueDouble
.
get
(
session
.
getRandom
().
nextDouble
());
}
case
ROUND:
{
case
ROUND:
{
double
f
=
Math
.
pow
(
10
.,
v1
.
getDouble
());
double
f
=
Math
.
pow
(
10
.,
v1
.
getDouble
());
return
ValueDouble
.
get
(
Math
.
round
(
v0
.
getDouble
()
*
f
)
/
f
);
result
=
ValueDouble
.
get
(
Math
.
round
(
v0
.
getDouble
()
*
f
)
/
f
);
break
;
}
}
case
ROUNDMAGIC:
return
ValueDouble
.
get
(
roundmagic
(
v0
.
getDouble
()));
case
SIGN:
return
ValueInt
.
get
(
v0
.
getSignum
());
case
SIN:
return
ValueDouble
.
get
(
Math
.
sin
(
v0
.
getDouble
()));
case
SQRT:
return
ValueDouble
.
get
(
Math
.
sqrt
(
v0
.
getDouble
()));
case
TAN:
return
ValueDouble
.
get
(
Math
.
tan
(
v0
.
getDouble
()));
case
TRUNCATE:
{
case
TRUNCATE:
{
double
d
=
v0
.
getDouble
();
double
d
=
v0
.
getDouble
();
int
p
=
v1
.
getInt
();
int
p
=
v1
.
getInt
();
double
f
=
Math
.
pow
(
10
.,
p
);
double
f
=
Math
.
pow
(
10
.,
p
);
double
g
=
d
*
f
;
double
g
=
d
*
f
;
return
ValueDouble
.
get
(((
d
<
0
)
?
Math
.
ceil
(
g
)
:
Math
.
floor
(
g
))
/
f
);
result
=
ValueDouble
.
get
(((
d
<
0
)
?
Math
.
ceil
(
g
)
:
Math
.
floor
(
g
))
/
f
);
break
;
}
}
case
SECURE_RAND:
return
ValueBytes
.
getNoCopy
(
RandomUtils
.
getSecureBytes
(
v0
.
getInt
()));
case
HASH:
case
HASH:
return
ValueBytes
.
getNoCopy
(
getHash
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getInt
()));
result
=
ValueBytes
.
getNoCopy
(
getHash
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getInt
()));
break
;
case
ENCRYPT:
case
ENCRYPT:
return
ValueBytes
.
getNoCopy
(
encrypt
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getBytesNoCopy
()));
result
=
ValueBytes
.
getNoCopy
(
encrypt
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getBytesNoCopy
()));
break
;
case
DECRYPT:
case
DECRYPT:
return
ValueBytes
.
getNoCopy
(
decrypt
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getBytesNoCopy
()));
result
=
ValueBytes
.
getNoCopy
(
decrypt
(
v0
.
getString
(),
v1
.
getBytesNoCopy
(),
v2
.
getBytesNoCopy
()));
break
;
case
COMPRESS:
{
case
COMPRESS:
{
String
algorithm
=
null
;
String
algorithm
=
null
;
if
(
v1
!=
null
)
{
if
(
v1
!=
null
)
{
algorithm
=
v1
.
getString
();
algorithm
=
v1
.
getString
();
}
}
return
ValueBytes
.
getNoCopy
(
CompressTool
.
getInstance
().
compress
(
v0
.
getBytesNoCopy
(),
algorithm
));
result
=
ValueBytes
.
getNoCopy
(
CompressTool
.
getInstance
().
compress
(
v0
.
getBytesNoCopy
(),
algorithm
));
}
break
;
case
EXPAND:
return
ValueBytes
.
getNoCopy
(
CompressTool
.
getInstance
().
expand
(
v0
.
getBytesNoCopy
()));
case
ZERO:
return
ValueInt
.
get
(
0
);
case
RANDOM_UUID:
return
ValueUuid
.
getNewRandom
();
// string
case
ASCII:
{
String
s
=
v0
.
getString
();
if
(
s
.
length
()
==
0
)
{
return
ValueNull
.
INSTANCE
;
}
return
ValueInt
.
get
(
s
.
charAt
(
0
));
}
case
BIT_LENGTH:
return
ValueInt
.
get
(
16
*
length
(
v0
));
case
CHAR:
return
ValueString
.
get
(
String
.
valueOf
((
char
)
v0
.
getInt
()));
case
CHAR_LENGTH:
case
LENGTH:
return
ValueInt
.
get
(
length
(
v0
));
case
OCTET_LENGTH:
return
ValueInt
.
get
(
2
*
length
(
v0
));
case
CONCAT:
{
Value
concat
=
ValueNull
.
INSTANCE
;
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Value
v
=
args
[
i
].
getValue
(
session
);
if
(
v
==
ValueNull
.
INSTANCE
)
{
continue
;
}
if
(
concat
==
ValueNull
.
INSTANCE
)
{
concat
=
v
;
}
else
{
concat
=
ValueString
.
get
(
concat
.
getString
().
concat
(
v
.
getString
()));
}
}
return
concat
;
}
}
case
DIFFERENCE:
case
DIFFERENCE:
return
ValueInt
.
get
(
getDifference
(
v0
.
getString
(),
v1
.
getString
()));
result
=
ValueInt
.
get
(
getDifference
(
v0
.
getString
(),
v1
.
getString
()));
case
HEXTORAW:
break
;
return
ValueString
.
get
(
hexToRaw
(
v0
.
getString
()));
case
INSERT:
{
case
INSERT:
{
if
(
v1
==
ValueNull
.
INSTANCE
||
v2
==
ValueNull
.
INSTANCE
)
{
if
(
v1
==
ValueNull
.
INSTANCE
||
v2
==
ValueNull
.
INSTANCE
)
{
return
v1
;
result
=
v1
;
}
else
{
result
=
ValueString
.
get
(
insert
(
v0
.
getString
(),
v1
.
getInt
(),
v2
.
getInt
(),
v3
.
getString
()));
}
}
return
ValueString
.
get
(
insert
(
v0
.
getString
(),
v1
.
getInt
(),
v2
.
getInt
(),
v3
.
getString
()))
;
break
;
}
}
case
LOWER:
case
LCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
return
ValueString
.
get
(
v0
.
getString
().
toLowerCase
());
case
LEFT:
case
LEFT:
return
ValueString
.
get
(
left
(
v0
.
getString
(),
v1
.
getInt
()));
result
=
ValueString
.
get
(
left
(
v0
.
getString
(),
v1
.
getInt
()));
break
;
case
LOCATE:
{
case
LOCATE:
{
int
start
=
v2
==
null
?
0
:
v2
.
getInt
();
int
start
=
v2
==
null
?
0
:
v2
.
getInt
();
return
ValueInt
.
get
(
locate
(
v0
.
getString
(),
v1
.
getString
(),
start
));
result
=
ValueInt
.
get
(
locate
(
v0
.
getString
(),
v1
.
getString
(),
start
));
break
;
}
}
case
INSTR:
{
case
INSTR:
{
int
start
=
v2
==
null
?
0
:
v2
.
getInt
();
int
start
=
v2
==
null
?
0
:
v2
.
getInt
();
return
ValueInt
.
get
(
locate
(
v1
.
getString
(),
v0
.
getString
(),
start
));
result
=
ValueInt
.
get
(
locate
(
v1
.
getString
(),
v0
.
getString
(),
start
));
break
;
}
}
case
RAWTOHEX:
return
ValueString
.
get
(
rawToHex
(
v0
.
getString
()));
case
REPEAT:
{
case
REPEAT:
{
// TODO DOS attacks: limit len?
int
count
=
Math
.
max
(
0
,
v1
.
getInt
());
int
count
=
Math
.
max
(
0
,
v1
.
getInt
());
return
ValueString
.
get
(
repeat
(
v0
.
getString
(),
count
));
result
=
ValueString
.
get
(
repeat
(
v0
.
getString
(),
count
));
break
;
}
}
case
REPLACE:
{
case
REPLACE:
{
String
s0
=
v0
==
ValueNull
.
INSTANCE
?
""
:
v0
.
getString
();
String
s0
=
v0
==
ValueNull
.
INSTANCE
?
""
:
v0
.
getString
();
String
s1
=
v1
==
ValueNull
.
INSTANCE
?
""
:
v1
.
getString
();
String
s1
=
v1
==
ValueNull
.
INSTANCE
?
""
:
v1
.
getString
();
String
s2
=
(
v2
==
null
||
v2
==
ValueNull
.
INSTANCE
)
?
""
:
v2
.
getString
();
String
s2
=
(
v2
==
null
||
v2
==
ValueNull
.
INSTANCE
)
?
""
:
v2
.
getString
();
return
ValueString
.
get
(
replace
(
s0
,
s1
,
s2
));
result
=
ValueString
.
get
(
replace
(
s0
,
s1
,
s2
));
break
;
}
}
case
RIGHT:
case
RIGHT:
return
ValueString
.
get
(
right
(
v0
.
getString
(),
v1
.
getInt
()));
result
=
ValueString
.
get
(
right
(
v0
.
getString
(),
v1
.
getInt
()));
break
;
case
LTRIM:
case
LTRIM:
return
ValueString
.
get
(
trim
(
v0
.
getString
(),
true
,
false
,
v1
==
null
?
" "
:
v1
.
getString
()));
result
=
ValueString
.
get
(
trim
(
v0
.
getString
(),
true
,
false
,
v1
==
null
?
" "
:
v1
.
getString
()));
break
;
case
TRIM:
case
TRIM:
return
ValueString
.
get
(
trim
(
v0
.
getString
(),
true
,
true
,
v1
==
null
?
" "
:
v1
.
getString
()));
result
=
ValueString
.
get
(
trim
(
v0
.
getString
(),
true
,
true
,
v1
==
null
?
" "
:
v1
.
getString
()));
break
;
case
RTRIM:
case
RTRIM:
return
ValueString
.
get
(
trim
(
v0
.
getString
(),
false
,
true
,
v1
==
null
?
" "
:
v1
.
getString
()));
result
=
ValueString
.
get
(
trim
(
v0
.
getString
(),
false
,
true
,
v1
==
null
?
" "
:
v1
.
getString
()));
case
SOUNDEX:
break
;
return
ValueString
.
get
(
getSoundex
(
v0
.
getString
()));
case
SPACE:
{
// TODO DOS attacks: limit len?
int
len
=
Math
.
max
(
0
,
v0
.
getInt
());
char
[]
chars
=
new
char
[
len
];
for
(
int
i
=
len
-
1
;
i
>=
0
;
i
--)
{
chars
[
i
]
=
' '
;
}
return
ValueString
.
get
(
new
String
(
chars
));
}
case
SUBSTR:
case
SUBSTR:
case
SUBSTRING:
{
case
SUBSTRING:
{
String
s
=
v0
.
getString
();
String
s
=
v0
.
getString
();
int
length
=
v2
==
null
?
s
.
length
()
:
v2
.
getInt
();
int
length
=
v2
==
null
?
s
.
length
()
:
v2
.
getInt
();
return
ValueString
.
get
(
substring
(
s
,
v1
.
getInt
(),
length
));
result
=
ValueString
.
get
(
substring
(
s
,
v1
.
getInt
(),
length
));
break
;
}
}
case
POSITION:
case
POSITION:
return
ValueInt
.
get
(
locate
(
v0
.
getString
(),
v1
.
getString
(),
0
));
result
=
ValueInt
.
get
(
locate
(
v0
.
getString
(),
v1
.
getString
(),
0
));
case
UPPER:
break
;
case
UCASE:
// TODO this is locale specific, need to document or provide a way
// to set the locale
return
ValueString
.
get
(
v0
.
getString
().
toUpperCase
());
case
STRINGENCODE:
return
ValueString
.
get
(
StringUtils
.
javaEncode
(
v0
.
getString
()));
case
STRINGDECODE:
return
ValueString
.
get
(
StringUtils
.
javaDecode
(
v0
.
getString
()));
case
STRINGTOUTF8:
return
ValueBytes
.
getNoCopy
(
StringUtils
.
utf8Encode
(
v0
.
getString
()));
case
UTF8TOSTRING:
return
ValueString
.
get
(
StringUtils
.
utf8Decode
(
v0
.
getBytesNoCopy
()));
case
XMLATTR:
case
XMLATTR:
return
ValueString
.
get
(
StringUtils
.
xmlAttr
(
v0
.
getString
(),
v1
.
getString
()));
result
=
ValueString
.
get
(
StringUtils
.
xmlAttr
(
v0
.
getString
(),
v1
.
getString
()));
break
;
case
XMLNODE:
{
case
XMLNODE:
{
String
attr
=
v1
==
null
?
null
:
v1
==
ValueNull
.
INSTANCE
?
null
:
v1
.
getString
();
String
attr
=
v1
==
null
?
null
:
v1
==
ValueNull
.
INSTANCE
?
null
:
v1
.
getString
();
String
content
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
String
content
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
return
ValueString
.
get
(
StringUtils
.
xmlNode
(
v0
.
getString
(),
attr
,
content
));
result
=
ValueString
.
get
(
StringUtils
.
xmlNode
(
v0
.
getString
(),
attr
,
content
));
break
;
}
}
case
XMLCOMMENT:
return
ValueString
.
get
(
StringUtils
.
xmlComment
(
v0
.
getString
()));
case
XMLCDATA:
return
ValueString
.
get
(
StringUtils
.
xmlCData
(
v0
.
getString
()));
case
XMLSTARTDOC:
return
ValueString
.
get
(
StringUtils
.
xmlStartDoc
());
case
XMLTEXT:
return
ValueString
.
get
(
StringUtils
.
xmlText
(
v0
.
getString
()));
case
REGEXP_REPLACE:
case
REGEXP_REPLACE:
return
ValueString
.
get
(
v0
.
getString
().
replaceAll
(
v1
.
getString
(),
v2
.
getString
()));
result
=
ValueString
.
get
(
v0
.
getString
().
replaceAll
(
v1
.
getString
(),
v2
.
getString
()));
break
;
case
RPAD:
case
RPAD:
return
ValueString
.
get
(
StringUtils
.
pad
(
v0
.
getString
(),
v1
.
getInt
(),
v2
==
null
?
null
:
v2
.
getString
(),
true
));
result
=
ValueString
.
get
(
StringUtils
.
pad
(
v0
.
getString
(),
v1
.
getInt
(),
v2
==
null
?
null
:
v2
.
getString
(),
true
));
break
;
case
LPAD:
case
LPAD:
return
ValueString
.
get
(
StringUtils
.
pad
(
v0
.
getString
(),
v1
.
getInt
(),
v2
==
null
?
null
:
v2
.
getString
(),
false
));
result
=
ValueString
.
get
(
StringUtils
.
pad
(
v0
.
getString
(),
v1
.
getInt
(),
v2
==
null
?
null
:
v2
.
getString
(),
false
));
break
;
// date
// date
case
DATEADD:
case
DATEADD:
return
ValueTimestamp
.
getNoCopy
(
dateadd
(
v0
.
getString
(),
v1
.
getInt
(),
v2
.
getTimestampNoCopy
()));
result
=
ValueTimestamp
.
getNoCopy
(
dateadd
(
v0
.
getString
(),
v1
.
getInt
(),
v2
.
getTimestampNoCopy
()));
break
;
case
DATEDIFF:
case
DATEDIFF:
return
ValueLong
.
get
(
datediff
(
v0
.
getString
(),
v1
.
getTimestampNoCopy
(),
v2
.
getTimestampNoCopy
()));
result
=
ValueLong
.
get
(
datediff
(
v0
.
getString
(),
v1
.
getTimestampNoCopy
(),
v2
.
getTimestampNoCopy
()));
case
DAYNAME:
{
break
;
Value
result
;
synchronized
(
FORMAT_DAYNAME
)
{
result
=
ValueString
.
get
(
FORMAT_DAYNAME
.
format
(
v0
.
getDateNoCopy
()));
}
return
result
;
}
case
DAYOFMONTH:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_MONTH
));
case
DAYOFWEEK:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_WEEK
));
case
DAYOFYEAR:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
DAY_OF_YEAR
));
case
HOUR:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
HOUR_OF_DAY
));
case
MINUTE:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
MINUTE
));
case
MONTH:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestampNoCopy
(),
Calendar
.
MONTH
));
case
MONTHNAME:
{
Value
v
;
synchronized
(
FORMAT_MONTHNAME
)
{
v
=
ValueString
.
get
(
FORMAT_MONTHNAME
.
format
(
v0
.
getDateNoCopy
()));
}
return
v
;
}
case
QUARTER:
return
ValueInt
.
get
((
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
MONTH
)
-
1
)
/
3
+
1
);
case
SECOND:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
SECOND
));
case
WEEK:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
WEEK_OF_YEAR
));
case
YEAR:
return
ValueInt
.
get
(
getDatePart
(
v0
.
getTimestamp
(),
Calendar
.
YEAR
));
case
CURDATE:
case
CURRENT_DATE:
// need to normalize
return
ValueDate
.
get
(
new
Date
(
System
.
currentTimeMillis
()));
case
CURTIME:
case
CURRENT_TIME:
// need to normalize
return
ValueTime
.
get
(
new
Time
(
System
.
currentTimeMillis
()));
case
NOW:
case
CURRENT_TIMESTAMP:
{
ValueTimestamp
vt
=
ValueTimestamp
.
getNoCopy
(
new
Timestamp
(
System
.
currentTimeMillis
()));
if
(
v0
!=
null
)
{
Mode
mode
=
database
.
getMode
();
vt
=
(
ValueTimestamp
)
vt
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
v0
.
getInt
());
}
return
vt
;
}
case
EXTRACT:
{
case
EXTRACT:
{
int
field
=
getDatePart
(
v0
.
getString
());
int
field
=
getDatePart
(
v0
.
getString
());
return
ValueInt
.
get
(
getDatePart
(
v1
.
getTimestamp
(),
field
));
result
=
ValueInt
.
get
(
getDatePart
(
v1
.
getTimestamp
(),
field
));
break
;
}
}
case
FORMATDATETIME:
{
case
FORMATDATETIME:
{
if
(
v0
==
ValueNull
.
INSTANCE
||
v1
==
ValueNull
.
INSTANCE
)
{
if
(
v0
==
ValueNull
.
INSTANCE
||
v1
==
ValueNull
.
INSTANCE
)
{
return
ValueNull
.
INSTANCE
;
result
=
ValueNull
.
INSTANCE
;
}
else
{
String
locale
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
String
tz
=
v3
==
null
?
null
:
v3
==
ValueNull
.
INSTANCE
?
null
:
v3
.
getString
();
result
=
ValueString
.
get
(
StringUtils
.
formatDateTime
(
v0
.
getTimestamp
(),
v1
.
getString
(),
locale
,
tz
));
}
}
String
locale
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
break
;
String
tz
=
v3
==
null
?
null
:
v3
==
ValueNull
.
INSTANCE
?
null
:
v3
.
getString
();
return
ValueString
.
get
(
StringUtils
.
formatDateTime
(
v0
.
getTimestamp
(),
v1
.
getString
(),
locale
,
tz
));
}
}
case
PARSEDATETIME:
{
case
PARSEDATETIME:
{
if
(
v0
==
ValueNull
.
INSTANCE
||
v1
==
ValueNull
.
INSTANCE
)
{
if
(
v0
==
ValueNull
.
INSTANCE
||
v1
==
ValueNull
.
INSTANCE
)
{
return
ValueNull
.
INSTANCE
;
result
=
ValueNull
.
INSTANCE
;
}
else
{
String
locale
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
String
tz
=
v3
==
null
?
null
:
v3
==
ValueNull
.
INSTANCE
?
null
:
v3
.
getString
();
java
.
util
.
Date
d
=
StringUtils
.
parseDateTime
(
v0
.
getString
(),
v1
.
getString
(),
locale
,
tz
);
result
=
ValueTimestamp
.
getNoCopy
(
new
Timestamp
(
d
.
getTime
()));
}
}
String
locale
=
v2
==
null
?
null
:
v2
==
ValueNull
.
INSTANCE
?
null
:
v2
.
getString
();
break
;
String
tz
=
v3
==
null
?
null
:
v3
==
ValueNull
.
INSTANCE
?
null
:
v3
.
getString
();
java
.
util
.
Date
d
=
StringUtils
.
parseDateTime
(
v0
.
getString
(),
v1
.
getString
(),
locale
,
tz
);
return
ValueTimestamp
.
getNoCopy
(
new
Timestamp
(
d
.
getTime
()));
}
// system
case
DATABASE:
return
ValueString
.
get
(
database
.
getShortName
());
case
USER:
case
CURRENT_USER:
return
ValueString
.
get
(
session
.
getUser
().
getName
());
case
IDENTITY:
return
session
.
getLastIdentity
();
case
AUTOCOMMIT:
return
ValueBoolean
.
get
(
session
.
getAutoCommit
());
case
READONLY:
return
ValueBoolean
.
get
(
database
.
getReadOnly
());
case
DATABASE_PATH:
{
String
path
=
database
.
getDatabasePath
();
return
path
==
null
?
(
Value
)
ValueNull
.
INSTANCE
:
ValueString
.
get
(
path
);
}
}
case
LOCK_TIMEOUT:
return
ValueInt
.
get
(
session
.
getLockTimeout
());
case
NULLIF:
case
NULLIF:
return
database
.
areEqual
(
v0
,
v1
)
?
ValueNull
.
INSTANCE
:
v0
;
result
=
database
.
areEqual
(
v0
,
v1
)
?
ValueNull
.
INSTANCE
:
v0
;
case
CAST:
break
;
case
CONVERT:
{
// system
v0
=
v0
.
convertTo
(
dataType
);
Mode
mode
=
database
.
getMode
();
v0
=
v0
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
scale
);
v0
=
v0
.
convertPrecision
(
getPrecision
());
return
v0
;
}
case
NEXTVAL:
{
case
NEXTVAL:
{
Sequence
sequence
=
getSequence
(
session
,
v0
,
v1
);
Sequence
sequence
=
getSequence
(
session
,
v0
,
v1
);
SequenceValue
value
=
new
SequenceValue
(
sequence
);
SequenceValue
value
=
new
SequenceValue
(
sequence
);
return
value
.
getValue
(
session
);
result
=
value
.
getValue
(
session
);
break
;
}
}
case
CURRVAL:
{
case
CURRVAL:
{
Sequence
sequence
=
getSequence
(
session
,
v0
,
v1
);
Sequence
sequence
=
getSequence
(
session
,
v0
,
v1
);
return
ValueLong
.
get
(
sequence
.
getCurrentValue
());
result
=
ValueLong
.
get
(
sequence
.
getCurrentValue
());
break
;
}
}
case
CSVREAD:
{
case
CSVREAD:
{
String
fileName
=
v0
.
getString
();
String
fileName
=
v0
.
getString
();
...
@@ -810,19 +983,17 @@ public class Function extends Expression implements FunctionCall {
...
@@ -810,19 +983,17 @@ public class Function extends Expression implements FunctionCall {
char
fieldSeparator
=
csv
.
getFieldSeparatorRead
();
char
fieldSeparator
=
csv
.
getFieldSeparatorRead
();
String
[]
columns
=
StringUtils
.
arraySplit
(
columnList
,
fieldSeparator
,
true
);
String
[]
columns
=
StringUtils
.
arraySplit
(
columnList
,
fieldSeparator
,
true
);
ValueResultSet
vr
=
ValueResultSet
.
get
(
csv
.
read
(
fileName
,
columns
,
charset
));
ValueResultSet
vr
=
ValueResultSet
.
get
(
csv
.
read
(
fileName
,
columns
,
charset
));
return
vr
;
result
=
vr
;
break
;
}
}
case
LINK_SCHEMA:
{
case
LINK_SCHEMA:
{
session
.
getUser
().
checkAdmin
();
session
.
getUser
().
checkAdmin
();
Connection
conn
=
session
.
createConnection
(
false
);
Connection
conn
=
session
.
createConnection
(
false
);
ResultSet
rs
=
LinkSchema
.
linkSchema
(
conn
,
v0
.
getString
(),
v1
.
getString
(),
v2
.
getString
(),
v3
.
getString
(),
ResultSet
rs
=
LinkSchema
.
linkSchema
(
conn
,
v0
.
getString
(),
v1
.
getString
(),
v2
.
getString
(),
v3
.
getString
(),
v4
.
getString
(),
v5
.
getString
());
v4
.
getString
(),
v5
.
getString
());
return
ValueResultSet
.
get
(
rs
);
result
=
ValueResultSet
.
get
(
rs
);
break
;
}
}
case
TABLE:
return
getTable
(
session
,
args
,
false
,
false
);
case
TABLE_DISTINCT:
return
getTable
(
session
,
args
,
false
,
true
);
case
CSVWRITE:
{
case
CSVWRITE:
{
session
.
getUser
().
checkAdmin
();
session
.
getUser
().
checkAdmin
();
Connection
conn
=
session
.
createConnection
(
false
);
Connection
conn
=
session
.
createConnection
(
false
);
...
@@ -833,23 +1004,13 @@ public class Function extends Expression implements FunctionCall {
...
@@ -833,23 +1004,13 @@ public class Function extends Expression implements FunctionCall {
Csv
csv
=
Csv
.
getInstance
();
Csv
csv
=
Csv
.
getInstance
();
setCsvDelimiterEscape
(
csv
,
fieldSeparatorWrite
,
fieldDelimiter
,
escapeCharacter
);
setCsvDelimiterEscape
(
csv
,
fieldSeparatorWrite
,
fieldDelimiter
,
escapeCharacter
);
int
rows
=
csv
.
write
(
conn
,
v0
.
getString
(),
v1
.
getString
(),
charset
);
int
rows
=
csv
.
write
(
conn
,
v0
.
getString
(),
v1
.
getString
(),
charset
);
return
ValueInt
.
get
(
rows
);
result
=
ValueInt
.
get
(
rows
);
break
;
}
}
case
MEMORY_FREE:
session
.
getUser
().
checkAdmin
();
return
ValueInt
.
get
(
MemoryUtils
.
getMemoryFree
());
case
MEMORY_USED:
session
.
getUser
().
checkAdmin
();
return
ValueInt
.
get
(
MemoryUtils
.
getMemoryUsed
());
case
LOCK_MODE:
return
ValueInt
.
get
(
database
.
getLockMode
());
case
SCHEMA:
return
ValueString
.
get
(
session
.
getCurrentSchemaName
());
case
SESSION_ID:
return
ValueInt
.
get
(
session
.
getId
());
default
:
default
:
throw
Message
.
getInternalError
(
"type="
+
info
.
type
);
throw
Message
.
getInternalError
(
"type="
+
info
.
type
);
}
}
return
result
;
}
}
private
Sequence
getSequence
(
Session
session
,
Value
v0
,
Value
v1
)
throws
SQLException
{
private
Sequence
getSequence
(
Session
session
,
Value
v0
,
Value
v1
)
throws
SQLException
{
...
...
h2/src/main/org/h2/index/BtreeIndex.java
浏览文件 @
e0e2869b
...
@@ -57,8 +57,6 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
...
@@ -57,8 +57,6 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
head
=
(
BtreeHead
)
rec
;
head
=
(
BtreeHead
)
rec
;
}
}
if
(
head
!=
null
&&
head
.
getConsistent
())
{
if
(
head
!=
null
&&
head
.
getConsistent
())
{
int
testing
;
// setRoot((BtreePage) storage.getRecord(session, head.getRootPosition()));
needRebuild
=
false
;
needRebuild
=
false
;
rowCount
=
table
.
getRowCount
(
session
);
rowCount
=
table
.
getRowCount
(
session
);
}
else
{
}
else
{
...
...
h2/src/main/org/h2/res/_messages_en.properties
浏览文件 @
e0e2869b
...
@@ -155,6 +155,7 @@
...
@@ -155,6 +155,7 @@
90132
=
Aggregate {0} not found
90132
=
Aggregate {0} not found
90133
=
Cannot change the setting {0} when the database is already open
90133
=
Cannot change the setting {0} when the database is already open
90134
=
Access to the class {0} is denied
90134
=
Access to the class {0} is denied
90135
=
The database is open in exclusive mode; can not open additional connections
HY000
=
General error
\:
{0}
HY000
=
General error
\:
{0}
HY004
=
Unknown data type
\:
{0}
HY004
=
Unknown data type
\:
{0}
HYC00
=
Feature not supported
HYC00
=
Feature not supported
...
...
h2/src/main/org/h2/res/help.csv
浏览文件 @
e0e2869b
...
@@ -856,6 +856,19 @@ Admin rights are required to execute this command.
...
@@ -856,6 +856,19 @@ Admin rights are required to execute this command.
SET DEFAULT_TABLE_TYPE MEMORY
SET DEFAULT_TABLE_TYPE MEMORY
"
"
"Commands (Other)","SET EXCLUSIVE","
SET EXCLUSIVE {TRUE | FALSE}
","
Switched the database to exclusive mode and back. In exclusive mode, new connections are rejected,
and operations by other connections are paused until the exclusive mode is disabled.
Only the connection that set the exclusive mode can disable it. When the connection is closed,
it is automatically disabled.
This setting is not persistent.
Admin rights are required to execute this command.
","
SET EXCLUSIVE TRUE
"
"Commands (Other)","SET IGNORECASE","
"Commands (Other)","SET IGNORECASE","
SET IGNORECASE {TRUE|FALSE}
SET IGNORECASE {TRUE|FALSE}
","
","
...
@@ -2559,6 +2572,18 @@ Returns true if auto commit is switched on for this session.
...
@@ -2559,6 +2572,18 @@ Returns true if auto commit is switched on for this session.
AUTOCOMMIT()
AUTOCOMMIT()
"
"
"Functions (System)","CANCEL_SESSION","
CANCEL_SESSION(sessionInt): boolean
","
Cancels the currently executing statement of another session.
The method only works if the multithreaded kernel is enabled (see SET MULTI_THREADED).
Returns true if the statement was cancelled, false if the session is closed
or no statement is currently executing.
Admin rights are required to execute this command.
","
CANCEL_STATEMENT(3)
"
"Functions (System)","CASEWHEN Function","
"Functions (System)","CASEWHEN Function","
CASEWHEN(boolean, aValue, bValue): value
CASEWHEN(boolean, aValue, bValue): value
","
","
...
...
h2/src/main/org/h2/server/ftp/FtpControl.java
浏览文件 @
e0e2869b
...
@@ -333,6 +333,7 @@ public class FtpControl extends Thread {
...
@@ -333,6 +333,7 @@ public class FtpControl extends Thread {
}
else
if
(
"XRMD"
.
equals
(
command
))
{
}
else
if
(
"XRMD"
.
equals
(
command
))
{
processRemoveDir
(
param
);
processRemoveDir
(
param
);
}
}
break
;
default
:
default
:
break
;
break
;
}
}
...
...
h2/src/main/org/h2/server/web/WebServer.java
浏览文件 @
e0e2869b
...
@@ -114,6 +114,7 @@ public class WebServer implements Service {
...
@@ -114,6 +114,7 @@ public class WebServer implements Service {
private
ShutdownHandler
shutdownHandler
;
private
ShutdownHandler
shutdownHandler
;
private
Thread
listenerThread
;
private
Thread
listenerThread
;
private
boolean
ifExists
;
private
boolean
ifExists
;
private
boolean
allowScript
;
byte
[]
getFile
(
String
file
)
throws
IOException
{
byte
[]
getFile
(
String
file
)
throws
IOException
{
trace
(
"getFile <"
+
file
+
">"
);
trace
(
"getFile <"
+
file
+
">"
);
...
@@ -196,6 +197,8 @@ public class WebServer implements Service {
...
@@ -196,6 +197,8 @@ public class WebServer implements Service {
ssl
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
ssl
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
"-webAllowOthers"
.
equals
(
a
))
{
}
else
if
(
"-webAllowOthers"
.
equals
(
a
))
{
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
allowOthers
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
"-webScript"
.
equals
(
a
))
{
allowScript
=
Boolean
.
valueOf
(
args
[++
i
]).
booleanValue
();
}
else
if
(
"-baseDir"
.
equals
(
a
))
{
}
else
if
(
"-baseDir"
.
equals
(
a
))
{
String
baseDir
=
args
[++
i
];
String
baseDir
=
args
[++
i
];
SysProperties
.
setBaseDir
(
baseDir
);
SysProperties
.
setBaseDir
(
baseDir
);
...
@@ -508,4 +511,8 @@ public class WebServer implements Service {
...
@@ -508,4 +511,8 @@ public class WebServer implements Service {
this
.
shutdownHandler
=
shutdownHandler
;
this
.
shutdownHandler
=
shutdownHandler
;
}
}
public
boolean
getAllowScript
()
{
return
allowScript
;
}
}
}
h2/src/main/org/h2/server/web/WebThread.java
浏览文件 @
e0e2869b
...
@@ -5,13 +5,20 @@
...
@@ -5,13 +5,20 @@
package
org
.
h2
.
server
.
web
;
package
org
.
h2
.
server
.
web
;
import
java.io.BufferedOutputStream
;
import
java.io.BufferedOutputStream
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.DataOutputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.PrintWriter
;
import
java.io.PrintWriter
;
import
java.io.StringReader
;
import
java.io.StringReader
;
import
java.io.StringWriter
;
import
java.io.StringWriter
;
import
java.lang.reflect.Method
;
import
java.net.MalformedURLException
;
import
java.net.Socket
;
import
java.net.Socket
;
import
java.security.SecureClassLoader
;
import
java.sql.Connection
;
import
java.sql.Connection
;
import
java.sql.DatabaseMetaData
;
import
java.sql.DatabaseMetaData
;
import
java.sql.PreparedStatement
;
import
java.sql.PreparedStatement
;
...
@@ -40,12 +47,12 @@ import org.h2.engine.Constants;
...
@@ -40,12 +47,12 @@ import org.h2.engine.Constants;
import
org.h2.jdbc.JdbcSQLException
;
import
org.h2.jdbc.JdbcSQLException
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MemoryUtils
;
import
org.h2.util.MemoryUtils
;
import
org.h2.util.NetUtils
;
import
org.h2.util.NetUtils
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
import
org.h2.util.ScriptReader
;
import
org.h2.util.ScriptReader
;
import
org.h2.util.StringUtils
;
import
org.h2.util.StringUtils
;
...
@@ -1018,7 +1025,17 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1018,7 +1025,17 @@ class WebThread extends Thread implements DatabaseEventListener {
try
{
try
{
Connection
conn
=
session
.
getConnection
();
Connection
conn
=
session
.
getConnection
();
String
result
;
String
result
;
if
(
"@AUTOCOMMIT TRUE"
.
equals
(
sql
))
{
if
(
sql
.
startsWith
(
"@JAVA"
))
{
if
(
server
.
getAllowScript
())
{
try
{
result
=
executeJava
(
sql
.
substring
(
"@JAVA"
.
length
()));
}
catch
(
Throwable
t
)
{
result
=
getStackTrace
(
0
,
t
);
}
}
else
{
result
=
"Executing Java code is not allowed, use command line parameters -webScript true"
;
}
}
else
if
(
"@AUTOCOMMIT TRUE"
.
equals
(
sql
))
{
conn
.
setAutoCommit
(
true
);
conn
.
setAutoCommit
(
true
);
result
=
"${text.result.autoCommitOn}"
;
result
=
"${text.result.autoCommitOn}"
;
}
else
if
(
"@AUTOCOMMIT FALSE"
.
equals
(
sql
))
{
}
else
if
(
"@AUTOCOMMIT FALSE"
.
equals
(
sql
))
{
...
@@ -1068,6 +1085,94 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1068,6 +1085,94 @@ class WebThread extends Thread implements DatabaseEventListener {
return
"result.jsp"
;
return
"result.jsp"
;
}
}
static
class
DynamicClassLoader
extends
SecureClassLoader
{
private
String
name
;
private
byte
[]
data
;
private
Class
clazz
;
DynamicClassLoader
(
String
name
,
byte
[]
data
)
throws
MalformedURLException
{
super
(
DynamicClassLoader
.
class
.
getClassLoader
());
this
.
name
=
name
;
this
.
data
=
data
;
}
public
Class
loadClass
(
String
className
)
throws
ClassNotFoundException
{
return
findClass
(
className
);
}
public
Class
findClass
(
String
className
)
throws
ClassNotFoundException
{
if
(
className
.
equals
(
name
))
{
if
(
clazz
==
null
)
{
clazz
=
defineClass
(
className
,
data
,
0
,
data
.
length
);
}
return
clazz
;
}
try
{
return
findSystemClass
(
className
);
}
catch
(
Exception
e
)
{
}
return
super
.
findClass
(
className
);
}
}
private
String
executeJava
(
String
code
)
throws
Exception
{
File
javaFile
=
new
File
(
"Java.java"
);
File
classFile
=
new
File
(
"Java.class"
);
try
{
PrintWriter
out
=
new
PrintWriter
(
new
FileWriter
(
javaFile
));
classFile
.
delete
();
int
endImport
=
code
.
indexOf
(
"@CODE"
);
String
importCode
=
"import java.util.*; import java.math.*; import java.sql.*;"
;
if
(
endImport
>=
0
)
{
importCode
=
code
.
substring
(
0
,
endImport
);
code
=
code
.
substring
(
"@CODE"
.
length
()
+
endImport
);
}
out
.
println
(
importCode
);
out
.
println
(
"public class Java { public static Object run() throws Throwable {"
+
code
+
"}}"
);
out
.
close
();
Process
p
=
Runtime
.
getRuntime
().
exec
(
"javac Java.java"
);
InputStream
processIn
=
p
.
getInputStream
();
InputStream
processErrorIn
=
p
.
getErrorStream
();
StringBuffer
buff
=
new
StringBuffer
();
while
(
true
)
{
int
c
=
processIn
.
read
();
if
(
c
==
-
1
)
{
break
;
}
buff
.
append
((
char
)
c
);
}
while
(
true
)
{
int
c
=
processErrorIn
.
read
();
if
(
c
==
-
1
)
{
break
;
}
buff
.
append
((
char
)
c
);
}
String
error
=
buff
.
toString
().
trim
();
if
(
error
.
length
()
>
0
)
{
throw
new
Exception
(
"Error compiling: "
+
error
.
toString
());
}
byte
[]
data
=
new
byte
[(
int
)
classFile
.
length
()];
DataInputStream
in
=
new
DataInputStream
(
new
FileInputStream
(
classFile
));
in
.
readFully
(
data
);
in
.
close
();
DynamicClassLoader
cl
=
new
DynamicClassLoader
(
"Java"
,
data
);
Class
clazz
=
cl
.
loadClass
(
"Java"
);
Method
[]
methods
=
clazz
.
getMethods
();
for
(
int
i
=
0
;
i
<
methods
.
length
;
i
++)
{
Method
m
=
methods
[
i
];
if
(
m
.
getName
().
equals
(
"run"
))
{
return
""
+
m
.
invoke
(
null
,
new
Object
[
0
]);
}
}
return
null
;
}
finally
{
javaFile
.
delete
();
classFile
.
delete
();
}
}
private
String
editResult
()
{
private
String
editResult
()
{
ResultSet
rs
=
session
.
result
;
ResultSet
rs
=
session
.
result
;
int
row
=
Integer
.
parseInt
(
attributes
.
getProperty
(
"row"
));
int
row
=
Integer
.
parseInt
(
attributes
.
getProperty
(
"row"
));
...
@@ -1083,7 +1188,7 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1083,7 +1188,7 @@ class WebThread extends Thread implements DatabaseEventListener {
}
}
for
(
int
i
=
0
;
i
<
rs
.
getMetaData
().
getColumnCount
();
i
++)
{
for
(
int
i
=
0
;
i
<
rs
.
getMetaData
().
getColumnCount
();
i
++)
{
String
x
=
attributes
.
getProperty
(
"r"
+
row
+
"c"
+
(
i
+
1
));
String
x
=
attributes
.
getProperty
(
"r"
+
row
+
"c"
+
(
i
+
1
));
rs
.
updateString
(
i
+
1
,
x
);
rs
.
updateString
(
i
+
1
,
unescapeData
(
x
)
);
}
}
if
(
insert
)
{
if
(
insert
)
{
rs
.
insertRow
();
rs
.
insertRow
();
...
@@ -1611,7 +1716,7 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1611,7 +1716,7 @@ class WebThread extends Thread implements DatabaseEventListener {
buff
.
append
(
PageParser
.
escapeHtml
(
meta
.
getColumnLabel
(
i
+
1
)));
buff
.
append
(
PageParser
.
escapeHtml
(
meta
.
getColumnLabel
(
i
+
1
)));
buff
.
append
(
"</td>"
);
buff
.
append
(
"</td>"
);
buff
.
append
(
"<td>"
);
buff
.
append
(
"<td>"
);
buff
.
append
(
PageParser
.
escapeHtml
(
rs
.
getString
(
i
+
1
)));
buff
.
append
(
escapeData
(
rs
.
getString
(
i
+
1
)));
buff
.
append
(
"</td></tr>"
);
buff
.
append
(
"</td></tr>"
);
}
}
}
}
...
@@ -1645,7 +1750,7 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1645,7 +1750,7 @@ class WebThread extends Thread implements DatabaseEventListener {
}
}
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
for
(
int
i
=
0
;
i
<
columns
;
i
++)
{
buff
.
append
(
"<td>"
);
buff
.
append
(
"<td>"
);
buff
.
append
(
PageParser
.
escapeHtml
(
rs
.
getString
(
i
+
1
)));
buff
.
append
(
escapeData
(
rs
.
getString
(
i
+
1
)));
buff
.
append
(
"</td>"
);
buff
.
append
(
"</td>"
);
}
}
buff
.
append
(
"</tr>"
);
buff
.
append
(
"</tr>"
);
...
@@ -1713,6 +1818,26 @@ class WebThread extends Thread implements DatabaseEventListener {
...
@@ -1713,6 +1818,26 @@ class WebThread extends Thread implements DatabaseEventListener {
return
"index.do"
;
return
"index.do"
;
}
}
private
String
escapeData
(
String
d
)
{
if
(
d
==
null
)
{
return
"<i>null</i>"
;
}
else
if
(
d
.
startsWith
(
"null"
))
{
return
"<div style='display: none'>=</div>"
+
PageParser
.
escapeHtml
(
d
);
}
return
PageParser
.
escapeHtml
(
d
);
}
private
String
unescapeData
(
String
d
)
{
if
(
d
.
endsWith
(
"null"
))
{
if
(
d
.
equals
(
"null"
))
{
return
null
;
}
else
if
(
d
.
startsWith
(
"="
))
{
return
d
.
substring
(
1
);
}
}
return
d
;
}
private
String
settingRemove
()
{
private
String
settingRemove
()
{
String
setting
=
attributes
.
getProperty
(
"name"
,
""
);
String
setting
=
attributes
.
getProperty
(
"name"
,
""
);
server
.
removeSetting
(
setting
);
server
.
removeSetting
(
setting
);
...
...
h2/src/main/org/h2/server/web/res/table.js
浏览文件 @
e0e2869b
/*
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
*/
*/
addEvent
(
window
,
"load"
,
initSort
);
addEvent
(
window
,
"load"
,
initSort
);
function
addEvent
(
elm
,
evType
,
fn
,
useCapture
)
{
function
addEvent
(
elm
,
evType
,
fn
,
useCapture
)
{
...
@@ -26,7 +26,7 @@ function initSort() {
...
@@ -26,7 +26,7 @@ function initSort() {
}
}
var
tables
=
document
.
getElementsByTagName
(
"table"
);
var
tables
=
document
.
getElementsByTagName
(
"table"
);
for
(
var
i
=
0
;
i
<
tables
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
tables
.
length
;
i
++
)
{
table
=
tables
[
i
];
table
=
tables
[
i
];
if
(
table
.
rows
&&
table
.
rows
.
length
>
0
)
{
if
(
table
.
rows
&&
table
.
rows
.
length
>
0
)
{
var
header
=
table
.
rows
[
0
];
var
header
=
table
.
rows
[
0
];
for
(
var
j
=
0
;
j
<
header
.
cells
.
length
;
j
++
)
{
for
(
var
j
=
0
;
j
<
header
.
cells
.
length
;
j
++
)
{
...
@@ -45,8 +45,8 @@ function editRow(row, session, write, undo) {
...
@@ -45,8 +45,8 @@ function editRow(row, session, write, undo) {
for
(
i
=
1
;
i
<
table
.
rows
.
length
;
i
++
)
{
for
(
i
=
1
;
i
<
table
.
rows
.
length
;
i
++
)
{
var
cell
=
table
.
rows
[
i
].
cells
[
0
];
var
cell
=
table
.
rows
[
i
].
cells
[
0
];
if
(
i
==
y
)
{
if
(
i
==
y
)
{
var
edit
=
'<img width=16 height=16 src="ico_ok.gif" onclick="
javascript:editing.op.value=
\'
1
\'
;editing.row.value=
\'
'
+
row
+
'
\'
;editing.submit(
)" onmouseover = "this.className =
\'
icon_hover
\'
" onmouseout = "this.className=
\'
icon
\'
" class="icon" alt="'
+
write
+
'" title="'
+
write
+
'" border="1"/>'
;
var
edit
=
'<img width=16 height=16 src="ico_ok.gif" onclick="
editOk('
+
row
+
'
)" onmouseover = "this.className =
\'
icon_hover
\'
" onmouseout = "this.className=
\'
icon
\'
" class="icon" alt="'
+
write
+
'" title="'
+
write
+
'" border="1"/>'
;
var
undo
=
'<img width=16 height=16 src="ico_undo.gif" onclick="
javascript:editing.op.value=
\'
3
\'
;editing.row.value=
\'
'
+
row
+
'
\'
;editing.submit(
)" onmouseover = "this.className =
\'
icon_hover
\'
" onmouseout = "this.className=
\'
icon
\'
" class="icon" alt="'
+
undo
+
'" title="'
+
undo
+
'" border="1"/>'
;
var
undo
=
'<img width=16 height=16 src="ico_undo.gif" onclick="
editCancel('
+
row
+
'
)" onmouseover = "this.className =
\'
icon_hover
\'
" onmouseout = "this.className=
\'
icon
\'
" class="icon" alt="'
+
undo
+
'" title="'
+
undo
+
'" border="1"/>'
;
cell
.
innerHTML
=
edit
+
undo
;
cell
.
innerHTML
=
edit
+
undo
;
}
else
{
}
else
{
cell
.
innerHTML
=
''
;
cell
.
innerHTML
=
''
;
...
@@ -56,10 +56,39 @@ function editRow(row, session, write, undo) {
...
@@ -56,10 +56,39 @@ function editRow(row, session, write, undo) {
for
(
i
=
1
;
i
<
cells
.
length
;
i
++
)
{
for
(
i
=
1
;
i
<
cells
.
length
;
i
++
)
{
var
cell
=
cells
[
i
];
var
cell
=
cells
[
i
];
var
text
=
getInnerText
(
cell
);
var
text
=
getInnerText
(
cell
);
cell
.
innerHTML
=
'<input type="text" name="r'
+
row
+
'c'
+
i
+
'" value="'
+
text
+
'" size="'
+
(
text
.
length
+
5
)
+
'"/>'
;
cell
.
innerHTML
=
'<input type="text" name="r'
+
row
+
'c'
+
i
+
'" value="'
+
text
+
'" size="'
+
(
text
.
length
+
5
)
+
'"
onkeydown="return editKeyDown('
+
row
+
', this, event)"
/>'
;
}
}
}
}
function
editCancel
(
row
)
{
var
editing
=
document
.
getElementById
(
'editing'
);
editing
.
row
.
value
=
row
;
editing
.
op
.
value
=
'3'
;
editing
.
submit
();
}
function
editOk
(
row
)
{
var
editing
=
document
.
getElementById
(
'editing'
);
editing
.
row
.
value
=
row
;
editing
.
op
.
value
=
'1'
;
editing
.
submit
();
}
function
editKeyDown
(
row
,
object
,
event
)
{
var
key
=
event
.
keyCode
?
event
.
keyCode
:
event
.
charCode
;
if
(
key
==
46
&&
event
.
ctrlKey
)
{
// ctrl + delete
object
.
value
=
'null'
;
return
false
;
}
else
if
(
key
==
13
)
{
editOk
(
row
);
return
false
;
}
else
if
(
key
==
27
)
{
editCancel
(
row
);
return
false
;
}
}
function
getInnerText
(
el
)
{
function
getInnerText
(
el
)
{
if
(
typeof
el
==
"string"
)
return
el
;
if
(
typeof
el
==
"string"
)
return
el
;
if
(
typeof
el
==
"undefined"
)
{
return
el
};
if
(
typeof
el
==
"undefined"
)
{
return
el
};
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
e0e2869b
...
@@ -16,6 +16,7 @@ import java.sql.Timestamp;
...
@@ -16,6 +16,7 @@ import java.sql.Timestamp;
import
java.text.Collator
;
import
java.text.Collator
;
import
java.util.Locale
;
import
java.util.Locale
;
import
org.h2.command.Command
;
import
org.h2.constant.SysProperties
;
import
org.h2.constant.SysProperties
;
import
org.h2.constraint.Constraint
;
import
org.h2.constraint.Constraint
;
import
org.h2.constraint.ConstraintCheck
;
import
org.h2.constraint.ConstraintCheck
;
...
@@ -434,8 +435,9 @@ public class MetaTable extends Table {
...
@@ -434,8 +435,9 @@ public class MetaTable extends Table {
cols
=
createColumns
(
new
String
[]{
cols
=
createColumns
(
new
String
[]{
"ID INT"
,
"ID INT"
,
"USER_NAME"
,
"USER_NAME"
,
"CURRENT_STATEMENT"
,
"SESSION_START"
,
"LOGIN_TIME"
,
"STATEMENT"
,
"STATEMENT_START"
});
});
break
;
break
;
}
}
...
@@ -707,6 +709,7 @@ public class MetaTable extends Table {
...
@@ -707,6 +709,7 @@ public class MetaTable extends Table {
}
}
}
}
add
(
rows
,
new
String
[]
{
"MVCC"
,
database
.
isMultiVersion
()
?
"TRUE"
:
"FALSE"
});
add
(
rows
,
new
String
[]
{
"MVCC"
,
database
.
isMultiVersion
()
?
"TRUE"
:
"FALSE"
});
add
(
rows
,
new
String
[]
{
"EXCLUSIVE"
,
database
.
getExclusiveSession
()
==
null
?
"FALSE"
:
"TRUE"
});
add
(
rows
,
new
String
[]
{
"MODE"
,
database
.
getMode
().
getName
()
});
add
(
rows
,
new
String
[]
{
"MODE"
,
database
.
getMode
().
getName
()
});
add
(
rows
,
new
String
[]
{
"MULTI_THREADED"
,
database
.
getMultiThreaded
()
?
"1"
:
"0"
});
add
(
rows
,
new
String
[]
{
"MULTI_THREADED"
,
database
.
getMultiThreaded
()
?
"1"
:
"0"
});
DiskFile
dataFile
=
database
.
getDataFile
();
DiskFile
dataFile
=
database
.
getDataFile
();
...
@@ -1205,11 +1208,13 @@ public class MetaTable extends Table {
...
@@ -1205,11 +1208,13 @@ public class MetaTable extends Table {
for
(
int
i
=
0
;
i
<
sessions
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
sessions
.
length
;
i
++)
{
Session
s
=
sessions
[
i
];
Session
s
=
sessions
[
i
];
if
(
admin
||
s
==
session
)
{
if
(
admin
||
s
==
session
)
{
Command
command
=
s
.
getCurrentCommand
();
add
(
rows
,
new
String
[]
{
add
(
rows
,
new
String
[]
{
""
+
s
.
getId
(),
// ID
""
+
s
.
getId
(),
// ID
s
.
getUser
().
getName
(),
// USER_NAME
s
.
getUser
().
getName
(),
// USER_NAME
s
.
getCurrentCommand
(),
// CURRENT_COMMAND
new
Timestamp
(
s
.
getSessionStart
()).
toString
(),
// SESSION_START
new
Timestamp
(
s
.
getLoginTime
()).
toString
(),
// LOGIN_TIME
command
==
null
?
null
:
command
.
toString
(),
// STATEMENT
new
Timestamp
(
s
.
getCurrentCommandStart
()).
toString
()
// STATEMENT_START
});
});
}
}
}
}
...
...
h2/src/main/org/h2/tools/Server.java
浏览文件 @
e0e2869b
...
@@ -28,12 +28,12 @@ import org.h2.util.StartBrowser;
...
@@ -28,12 +28,12 @@ import org.h2.util.StartBrowser;
* This tool can be used to start various database servers (listeners).
* This tool can be used to start various database servers (listeners).
*/
*/
public
class
Server
implements
Runnable
,
ShutdownHandler
{
public
class
Server
implements
Runnable
,
ShutdownHandler
{
private
Service
service
;
private
Service
service
;
private
static
final
int
EXIT_ERROR
=
1
;
private
static
final
int
EXIT_ERROR
=
1
;
private
Server
web
,
tcp
,
pg
,
ftp
;
private
Server
web
,
tcp
,
pg
,
ftp
;
private
ShutdownHandler
shutdownHandler
;
private
ShutdownHandler
shutdownHandler
;
private
void
showUsage
(
String
a
,
PrintStream
out
)
{
private
void
showUsage
(
String
a
,
PrintStream
out
)
{
if
(
a
!=
null
)
{
if
(
a
!=
null
)
{
out
.
println
(
"Unknown option: "
+
a
);
out
.
println
(
"Unknown option: "
+
a
);
...
@@ -53,30 +53,30 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -53,30 +53,30 @@ public class Server implements Runnable, ShutdownHandler {
out
.
println
(
"-tcp (start the TCP Server)"
);
out
.
println
(
"-tcp (start the TCP Server)"
);
out
.
println
(
"-tcpAllowOthers {true|false}"
);
out
.
println
(
"-tcpAllowOthers {true|false}"
);
out
.
println
(
"-tcpPort <port> (default: "
+
TcpServer
.
DEFAULT_PORT
+
")"
);
out
.
println
(
"-tcpPort <port> (default: "
+
TcpServer
.
DEFAULT_PORT
+
")"
);
out
.
println
(
"-tcpSSL {true|false}"
);
out
.
println
(
"-tcpSSL {true|false}"
);
out
.
println
(
"-tcpPassword {password} (the password for shutting down a TCP Server)"
);
out
.
println
(
"-tcpPassword {password} (the password for shutting down a TCP Server)"
);
out
.
println
(
"-tcpShutdown {url} (shutdown the TCP Server, URL example: tcp://localhost:9094)"
);
out
.
println
(
"-tcpShutdown {url} (shutdown the TCP Server, URL example: tcp://localhost:9094)"
);
out
.
println
(
"-tcpShutdownForce {true|false} (don't wait for other connections to close)"
);
out
.
println
(
"-tcpShutdownForce {true|false} (don't wait for other connections to close)"
);
out
.
println
();
out
.
println
();
out
.
println
(
"-pg (start the PG Server)"
);
out
.
println
(
"-pg (start the PG Server)"
);
out
.
println
(
"-pgAllowOthers {true|false}"
);
out
.
println
(
"-pgAllowOthers {true|false}"
);
out
.
println
(
"-pgPort <port> (default: "
+
PgServer
.
DEFAULT_PORT
+
")"
);
out
.
println
(
"-pgPort <port> (default: "
+
PgServer
.
DEFAULT_PORT
+
")"
);
out
.
println
();
out
.
println
();
out
.
println
(
"-ftp (start the FTP Server)"
);
out
.
println
(
"-ftp (start the FTP Server)"
);
out
.
println
(
"-ftpPort <port> (default: "
+
Constants
.
DEFAULT_FTP_PORT
+
")"
);
out
.
println
(
"-ftpPort <port> (default: "
+
Constants
.
DEFAULT_FTP_PORT
+
")"
);
out
.
println
(
"-ftpDir <directory> (default: "
+
FtpServer
.
DEFAULT_ROOT
+
", use jdbc:... to access a database)"
);
out
.
println
(
"-ftpDir <directory> (default: "
+
FtpServer
.
DEFAULT_ROOT
+
", use jdbc:... to access a database)"
);
out
.
println
(
"-ftpRead <readUserName> (default: "
+
FtpServer
.
DEFAULT_READ
+
")"
);
out
.
println
(
"-ftpRead <readUserName> (default: "
+
FtpServer
.
DEFAULT_READ
+
")"
);
out
.
println
(
"-ftpWrite <writeUserName> (default: "
+
FtpServer
.
DEFAULT_WRITE
+
")"
);
out
.
println
(
"-ftpWrite <writeUserName> (default: "
+
FtpServer
.
DEFAULT_WRITE
+
")"
);
out
.
println
(
"-ftpWritePassword <password> (default: "
+
FtpServer
.
DEFAULT_WRITE_PASSWORD
+
")"
);
out
.
println
(
"-ftpWritePassword <password> (default: "
+
FtpServer
.
DEFAULT_WRITE_PASSWORD
+
")"
);
out
.
println
();
out
.
println
();
out
.
println
(
"-log {true|false} (enable or disable logging, for all servers)"
);
out
.
println
(
"-log {true|false} (enable or disable logging, for all servers)"
);
out
.
println
(
"-baseDir <directory> (sets the base directory for H2 databases, for all servers)"
);
out
.
println
(
"-baseDir <directory> (sets the base directory for H2 databases, for all servers)"
);
out
.
println
(
"-ifExists {true|false} (only existing databases may be opened, for all servers)"
);
out
.
println
(
"-ifExists {true|false} (only existing databases may be opened, for all servers)"
);
}
}
public
Server
()
{
public
Server
()
{
}
}
/**
/**
* The command line interface for this tool.
* The command line interface for this tool.
* The options must be split into strings like this: "-baseDir", "/temp/data",...
* The options must be split into strings like this: "-baseDir", "/temp/data",...
...
@@ -114,7 +114,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -114,7 +114,7 @@ public class Server implements Runnable, ShutdownHandler {
* </li><li>-ftpWrite {writeUserName}
* </li><li>-ftpWrite {writeUserName}
* </li><li>-ftpWritePassword {password}
* </li><li>-ftpWritePassword {password}
* </li></ul>
* </li></ul>
*
*
* @param args the command line arguments
* @param args the command line arguments
* @throws SQLException
* @throws SQLException
*/
*/
...
@@ -150,6 +150,8 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -150,6 +150,8 @@ public class Server implements Runnable, ShutdownHandler {
i
++;
i
++;
}
else
if
(
"-webPort"
.
equals
(
a
))
{
}
else
if
(
"-webPort"
.
equals
(
a
))
{
i
++;
i
++;
}
else
if
(
"-webScript"
.
equals
(
a
))
{
i
++;
}
else
if
(
"-webSSL"
.
equals
(
a
))
{
}
else
if
(
"-webSSL"
.
equals
(
a
))
{
i
++;
i
++;
}
else
{
}
else
{
...
@@ -267,10 +269,10 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -267,10 +269,10 @@ public class Server implements Runnable, ShutdownHandler {
// ignore (status is displayed)
// ignore (status is displayed)
e
.
printStackTrace
();
e
.
printStackTrace
();
exitCode
=
EXIT_ERROR
;
exitCode
=
EXIT_ERROR
;
}
}
out
.
println
(
web
.
getStatus
());
out
.
println
(
web
.
getStatus
());
// start browser anyway (even if the server is already running)
// start browser anyway (even if the server is already running)
// because some people don't look at the output,
// because some people don't look at the output,
// but are wondering why nothing happens
// but are wondering why nothing happens
if
(
browserStart
)
{
if
(
browserStart
)
{
StartBrowser
.
openURL
(
web
.
getURL
());
StartBrowser
.
openURL
(
web
.
getURL
());
...
@@ -289,22 +291,22 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -289,22 +291,22 @@ public class Server implements Runnable, ShutdownHandler {
}
}
return
exitCode
;
return
exitCode
;
}
}
/**
/**
* Shutdown a TCP server. If force is set to false, the server will not allow new connections,
* Shutdown a TCP server. If force is set to false, the server will not allow new connections,
* but not kill existing connections, instead it will stop if the last connection is closed.
* but not kill existing connections, instead it will stop if the last connection is closed.
* If force is set to true, existing connections are killed.
* If force is set to true, existing connections are killed.
* After calling the method with force=false, it is not possible to call it again with
* After calling the method with force=false, it is not possible to call it again with
* force=true because new connections are not allowed.
* force=true because new connections are not allowed.
* Example:
* Example:
* <pre>Server.shutdownTcpServer("tcp://localhost:9094", password, true);</pre>
* <pre>Server.shutdownTcpServer("tcp://localhost:9094", password, true);</pre>
*
*
* @param url example: tcp://localhost:9094
* @param url example: tcp://localhost:9094
* @param password the password to use ("" for no password)
* @param password the password to use ("" for no password)
* @param force the shutdown (don't wait)
* @param force the shutdown (don't wait)
* @throws ClassNotFoundException
* @throws ClassNotFoundException
* @throws SQLException
* @throws SQLException
*/
*/
public
static
void
shutdownTcpServer
(
String
url
,
String
password
,
boolean
force
)
throws
SQLException
{
public
static
void
shutdownTcpServer
(
String
url
,
String
password
,
boolean
force
)
throws
SQLException
{
int
port
=
Constants
.
DEFAULT_SERVER_PORT
;
int
port
=
Constants
.
DEFAULT_SERVER_PORT
;
int
idx
=
url
.
indexOf
(
':'
,
"jdbc:h2:"
.
length
());
int
idx
=
url
.
indexOf
(
':'
,
"jdbc:h2:"
.
length
());
...
@@ -376,7 +378,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -376,7 +378,7 @@ public class Server implements Runnable, ShutdownHandler {
* Create a new web server, but does not start it yet.
* Create a new web server, but does not start it yet.
* Example:
* Example:
* <pre>Server server = Server.createWebServer(new String[]{"-log", "true"}).start();</pre>
* <pre>Server server = Server.createWebServer(new String[]{"-log", "true"}).start();</pre>
*
*
* @param args
* @param args
* @return the server
* @return the server
*/
*/
...
@@ -391,7 +393,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -391,7 +393,7 @@ public class Server implements Runnable, ShutdownHandler {
* Create a new ftp server, but does not start it yet.
* Create a new ftp server, but does not start it yet.
* Example:
* Example:
* <pre>Server server = Server.createFtpServer(new String[]{"-log", "true"}).start();</pre>
* <pre>Server server = Server.createFtpServer(new String[]{"-log", "true"}).start();</pre>
*
*
* @param args
* @param args
* @return the server
* @return the server
*/
*/
...
@@ -403,26 +405,26 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -403,26 +405,26 @@ public class Server implements Runnable, ShutdownHandler {
* Create a new TCP server, but does not start it yet.
* Create a new TCP server, but does not start it yet.
* Example:
* Example:
* <pre>Server server = Server.createTcpServer(new String[]{"-tcpAllowOthers", "true"}).start();</pre>
* <pre>Server server = Server.createTcpServer(new String[]{"-tcpAllowOthers", "true"}).start();</pre>
*
*
* @param args
* @param args
* @return the server
* @return the server
*/
*/
public
static
Server
createTcpServer
(
String
[]
args
)
throws
SQLException
{
public
static
Server
createTcpServer
(
String
[]
args
)
throws
SQLException
{
return
new
Server
(
new
TcpServer
(),
args
);
return
new
Server
(
new
TcpServer
(),
args
);
}
}
/**
/**
* Create a new PG server, but does not start it yet.
* Create a new PG server, but does not start it yet.
* Example:
* Example:
* <pre>Server server = Server.createPgServer(new String[]{"-pgAllowOthers", "true"}).start();</pre>
* <pre>Server server = Server.createPgServer(new String[]{"-pgAllowOthers", "true"}).start();</pre>
*
*
* @param args
* @param args
* @return the server
* @return the server
*/
*/
public
static
Server
createPgServer
(
String
[]
args
)
throws
SQLException
{
public
static
Server
createPgServer
(
String
[]
args
)
throws
SQLException
{
return
new
Server
(
new
PgServer
(),
args
);
return
new
Server
(
new
PgServer
(),
args
);
}
}
/**
/**
* Tries to start the server.
* Tries to start the server.
* @return the server if successful
* @return the server if successful
...
@@ -473,7 +475,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -473,7 +475,7 @@ public class Server implements Runnable, ShutdownHandler {
/**
/**
* Checks if the server is running.
* Checks if the server is running.
*
*
* @return if the server is running
* @return if the server is running
*/
*/
public
boolean
isRunning
()
{
public
boolean
isRunning
()
{
...
@@ -486,7 +488,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -486,7 +488,7 @@ public class Server implements Runnable, ShutdownHandler {
public
void
stop
()
{
public
void
stop
()
{
service
.
stop
();
service
.
stop
();
}
}
/**
/**
* Gets the URL of this server.
* Gets the URL of this server.
* @return the url
* @return the url
...
@@ -514,7 +516,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -514,7 +516,7 @@ public class Server implements Runnable, ShutdownHandler {
TraceSystem
.
traceThrowable
(
e
);
TraceSystem
.
traceThrowable
(
e
);
}
}
}
}
/**
/**
* INTERNAL
* INTERNAL
*/
*/
...
@@ -524,7 +526,7 @@ public class Server implements Runnable, ShutdownHandler {
...
@@ -524,7 +526,7 @@ public class Server implements Runnable, ShutdownHandler {
/**
/**
* INTERNAL
* INTERNAL
*/
*/
public
void
shutdown
()
{
public
void
shutdown
()
{
if
(
shutdownHandler
!=
null
)
{
if
(
shutdownHandler
!=
null
)
{
shutdownHandler
.
shutdown
();
shutdownHandler
.
shutdown
();
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
e0e2869b
...
@@ -40,6 +40,7 @@ import org.h2.test.db.TestSQLInjection;
...
@@ -40,6 +40,7 @@ import org.h2.test.db.TestSQLInjection;
import
org.h2.test.db.TestScript
;
import
org.h2.test.db.TestScript
;
import
org.h2.test.db.TestScriptSimple
;
import
org.h2.test.db.TestScriptSimple
;
import
org.h2.test.db.TestSequence
;
import
org.h2.test.db.TestSequence
;
import
org.h2.test.db.TestSessionsLocks
;
import
org.h2.test.db.TestSpaceReuse
;
import
org.h2.test.db.TestSpaceReuse
;
import
org.h2.test.db.TestSpeed
;
import
org.h2.test.db.TestSpeed
;
import
org.h2.test.db.TestTempTables
;
import
org.h2.test.db.TestTempTables
;
...
@@ -151,8 +152,15 @@ java org.h2.test.TestAll timer
...
@@ -151,8 +152,15 @@ java org.h2.test.TestAll timer
/*
/*
write simple test for
test & document exclusive mode
NFORMATION_SCHEMA.SESSIONS and LOCKS
test exlclusive mode (inform_sch.settings table, disallow new connections, delay operations by other,
disable when close session, disable
translate error code 90135
C:\temp\test\db
C:\temp\test\db
...
@@ -576,6 +584,7 @@ Features of H2
...
@@ -576,6 +584,7 @@ Features of H2
new
TestRights
().
runTest
(
this
);
new
TestRights
().
runTest
(
this
);
new
TestRunscript
().
runTest
(
this
);
new
TestRunscript
().
runTest
(
this
);
new
TestSQLInjection
().
runTest
(
this
);
new
TestSQLInjection
().
runTest
(
this
);
new
TestSessionsLocks
().
runTest
(
this
);
new
TestSequence
().
runTest
(
this
);
new
TestSequence
().
runTest
(
this
);
new
TestSpaceReuse
().
runTest
(
this
);
new
TestSpaceReuse
().
runTest
(
this
);
new
TestSpeed
().
runTest
(
this
);
new
TestSpeed
().
runTest
(
this
);
...
...
h2/src/test/org/h2/test/db/TestSessionsLocks.java
0 → 100644
浏览文件 @
e0e2869b
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.test.TestBase
;
public
class
TestSessionsLocks
extends
TestBase
{
public
void
test
()
throws
Exception
{
testCancelStatement
();
testLocks
();
}
private
void
testLocks
()
throws
Exception
{
deleteDb
(
"sessionsLocks"
);
Connection
conn
=
getConnection
(
"sessionsLocks;MULTI_THREADED=1"
);
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"select * from information_schema.locks order by session_id"
);
checkFalse
(
rs
.
next
());
Connection
conn2
=
getConnection
(
"sessionsLocks"
);
Statement
stat2
=
conn2
.
createStatement
();
stat2
.
execute
(
"create table test(id int primary key, name varchar)"
);
conn2
.
setAutoCommit
(
false
);
stat2
.
execute
(
"insert into test values(1, 'Hello')"
);
rs
=
stat
.
executeQuery
(
"select * from information_schema.locks order by session_id"
);
rs
.
next
();
check
(
"PUBLIC"
,
rs
.
getString
(
"TABLE_SCHEMA"
));
check
(
"TEST"
,
rs
.
getString
(
"TABLE_NAME"
));
rs
.
getString
(
"SESSION_ID"
);
if
(
config
.
mvcc
)
{
check
(
"READ"
,
rs
.
getString
(
"LOCK_TYPE"
));
}
else
{
check
(
"WRITE"
,
rs
.
getString
(
"LOCK_TYPE"
));
}
checkFalse
(
rs
.
next
());
conn2
.
commit
();
conn2
.
setTransactionIsolation
(
Connection
.
TRANSACTION_SERIALIZABLE
);
stat2
.
execute
(
"SELECT * FROM TEST"
);
rs
=
stat
.
executeQuery
(
"select * from information_schema.locks order by session_id"
);
if
(!
config
.
mvcc
)
{
rs
.
next
();
check
(
"PUBLIC"
,
rs
.
getString
(
"TABLE_SCHEMA"
));
check
(
"TEST"
,
rs
.
getString
(
"TABLE_NAME"
));
rs
.
getString
(
"SESSION_ID"
);
check
(
"READ"
,
rs
.
getString
(
"LOCK_TYPE"
));
}
checkFalse
(
rs
.
next
());
conn2
.
commit
();
rs
=
stat
.
executeQuery
(
"select * from information_schema.locks order by session_id"
);
checkFalse
(
rs
.
next
());
conn
.
close
();
conn2
.
close
();
}
public
void
testCancelStatement
()
throws
Exception
{
deleteDb
(
"sessionsLocks"
);
Connection
conn
=
getConnection
(
"sessionsLocks;MULTI_THREADED=1"
);
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
;
rs
=
stat
.
executeQuery
(
"select * from information_schema.sessions order by SESSION_START, ID"
);
rs
.
next
();
int
sessionId
=
rs
.
getInt
(
"ID"
);
rs
.
getString
(
"USER_NAME"
);
rs
.
getTimestamp
(
"SESSION_START"
);
rs
.
getString
(
"STATEMENT"
);
rs
.
getTimestamp
(
"STATEMENT_START"
);
checkFalse
(
rs
.
next
());
Connection
conn2
=
getConnection
(
"sessionsLocks"
);
final
Statement
stat2
=
conn2
.
createStatement
();
rs
=
stat
.
executeQuery
(
"select * from information_schema.sessions order by SESSION_START, ID"
);
check
(
rs
.
next
());
check
(
sessionId
,
rs
.
getInt
(
"ID"
));
check
(
rs
.
next
());
int
otherId
=
rs
.
getInt
(
"ID"
);
check
(
otherId
!=
sessionId
);
checkFalse
(
rs
.
next
());
stat2
.
execute
(
"set throttle 1"
);
final
boolean
[]
done
=
new
boolean
[
1
];
Runnable
runnable
=
new
Runnable
()
{
public
void
run
()
{
try
{
stat2
.
execute
(
"select count(*) from system_range(1, 10000000) t1, system_range(1, 10000000) t2"
);
new
Error
(
"Unexpected success"
).
printStackTrace
();
}
catch
(
SQLException
e
)
{
done
[
0
]
=
true
;
}
}
};
new
Thread
(
runnable
).
start
();
while
(
true
)
{
Thread
.
sleep
(
1000
);
rs
=
stat
.
executeQuery
(
"CALL CANCEL_SESSION("
+
otherId
+
")"
);
rs
.
next
();
if
(
rs
.
getBoolean
(
1
))
{
Thread
.
sleep
(
100
);
check
(
done
[
0
]);
break
;
}
else
{
System
.
out
.
println
(
"no statement is executing yet"
);
}
}
conn2
.
close
();
conn
.
close
();
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论