Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
47ed036f
Unverified
提交
47ed036f
authored
2月 18, 2018
作者:
Noel Grandin
提交者:
GitHub
2月 18, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #858 from katzyn/generated_keys
Return all generated rows and columns from getGeneratedKeys()
上级
8556fd23
7108c22b
全部展开
显示空白字符变更
内嵌
并排
正在显示
37 个修改的文件
包含
2719 行增加
和
242 行删除
+2719
-242
Command.java
h2/src/main/org/h2/command/Command.java
+11
-5
CommandInterface.java
h2/src/main/org/h2/command/CommandInterface.java
+9
-1
CommandList.java
h2/src/main/org/h2/command/CommandList.java
+1
-1
CommandRemote.java
h2/src/main/org/h2/command/CommandRemote.java
+41
-2
Parser.java
h2/src/main/org/h2/command/Parser.java
+4
-0
Insert.java
h2/src/main/org/h2/command/dml/Insert.java
+20
-1
Merge.java
h2/src/main/org/h2/command/dml/Merge.java
+10
-0
ConnectionInfo.java
h2/src/main/org/h2/engine/ConnectionInfo.java
+2
-1
Constants.java
h2/src/main/org/h2/engine/Constants.java
+15
-0
Engine.java
h2/src/main/org/h2/engine/Engine.java
+2
-2
GeneratedKeys.java
h2/src/main/org/h2/engine/GeneratedKeys.java
+239
-0
GeneratedKeysMode.java
h2/src/main/org/h2/engine/GeneratedKeysMode.java
+67
-0
Session.java
h2/src/main/org/h2/engine/Session.java
+27
-2
SessionInterface.java
h2/src/main/org/h2/engine/SessionInterface.java
+9
-0
SessionRemote.java
h2/src/main/org/h2/engine/SessionRemote.java
+12
-6
SessionWithState.java
h2/src/main/org/h2/engine/SessionWithState.java
+1
-1
FullText.java
h2/src/main/org/h2/fulltext/FullText.java
+5
-2
JdbcCallableStatement.java
h2/src/main/org/h2/jdbc/JdbcCallableStatement.java
+1
-1
JdbcConnection.java
h2/src/main/org/h2/jdbc/JdbcConnection.java
+65
-31
JdbcPreparedStatement.java
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
+27
-18
JdbcSavepoint.java
h2/src/main/org/h2/jdbc/JdbcSavepoint.java
+1
-1
JdbcStatement.java
h2/src/main/org/h2/jdbc/JdbcStatement.java
+78
-44
ResultWithGeneratedKeys.java
h2/src/main/org/h2/result/ResultWithGeneratedKeys.java
+71
-0
TriggerObject.java
h2/src/main/org/h2/schema/TriggerObject.java
+3
-1
TcpServerThread.java
h2/src/main/org/h2/server/TcpServerThread.java
+65
-11
WebApp.java
h2/src/main/org/h2/server/web/WebApp.java
+4
-4
FileLock.java
h2/src/main/org/h2/store/FileLock.java
+2
-2
Column.java
h2/src/main/org/h2/table/Column.java
+2
-0
Table.java
h2/src/main/org/h2/table/Table.java
+1
-1
MergedResultSet.java
h2/src/main/org/h2/util/MergedResultSet.java
+141
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-0
TestTriggersConstraints.java
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
+1
-1
TestGetGeneratedKeys.java
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
+1760
-0
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+7
-96
TestResultSet.java
h2/src/test/org/h2/test/jdbc/TestResultSet.java
+4
-2
TestStatement.java
h2/src/test/org/h2/test/jdbc/TestStatement.java
+8
-4
TestWeb.java
h2/src/test/org/h2/test/server/TestWeb.java
+1
-1
没有找到文件。
h2/src/main/org/h2/command/Command.java
浏览文件 @
47ed036f
...
@@ -15,6 +15,7 @@ import org.h2.expression.ParameterInterface;
...
@@ -15,6 +15,7 @@ import org.h2.expression.ParameterInterface;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
/**
/**
...
@@ -149,7 +150,7 @@ public abstract class Command implements CommandInterface {
...
@@ -149,7 +150,7 @@ public abstract class Command implements CommandInterface {
@Override
@Override
public
void
stop
()
{
public
void
stop
()
{
session
.
endStatement
();
session
.
endStatement
();
session
.
setCurrentCommand
(
null
);
session
.
setCurrentCommand
(
null
,
false
);
if
(!
isTransactional
())
{
if
(!
isTransactional
())
{
session
.
commit
(
true
);
session
.
commit
(
true
);
}
else
if
(
session
.
getAutoCommit
())
{
}
else
if
(
session
.
getAutoCommit
())
{
...
@@ -193,7 +194,7 @@ public abstract class Command implements CommandInterface {
...
@@ -193,7 +194,7 @@ public abstract class Command implements CommandInterface {
}
}
}
}
synchronized
(
sync
)
{
synchronized
(
sync
)
{
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
false
);
try
{
try
{
while
(
true
)
{
while
(
true
)
{
database
.
checkPowerOff
();
database
.
checkPowerOff
();
...
@@ -238,7 +239,7 @@ public abstract class Command implements CommandInterface {
...
@@ -238,7 +239,7 @@ public abstract class Command implements CommandInterface {
}
}
@Override
@Override
public
int
executeUpdate
(
)
{
public
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
)
{
long
start
=
0
;
long
start
=
0
;
Database
database
=
session
.
getDatabase
();
Database
database
=
session
.
getDatabase
();
Object
sync
=
database
.
isMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
Object
sync
=
database
.
isMultiThreaded
()
?
(
Object
)
session
:
(
Object
)
database
;
...
@@ -252,12 +253,17 @@ public abstract class Command implements CommandInterface {
...
@@ -252,12 +253,17 @@ public abstract class Command implements CommandInterface {
}
}
synchronized
(
sync
)
{
synchronized
(
sync
)
{
Session
.
Savepoint
rollback
=
session
.
setSavepoint
();
Session
.
Savepoint
rollback
=
session
.
setSavepoint
();
session
.
setCurrentCommand
(
this
);
session
.
setCurrentCommand
(
this
,
generatedKeysRequest
);
try
{
try
{
while
(
true
)
{
while
(
true
)
{
database
.
checkPowerOff
();
database
.
checkPowerOff
();
try
{
try
{
return
update
();
int
updateCount
=
update
();
if
(!
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
new
ResultWithGeneratedKeys
.
WithKeys
(
updateCount
,
session
.
getGeneratedKeys
().
getKeys
(
session
));
}
return
ResultWithGeneratedKeys
.
of
(
updateCount
);
}
catch
(
DbException
e
)
{
}
catch
(
DbException
e
)
{
start
=
filterConcurrentUpdate
(
e
,
start
);
start
=
filterConcurrentUpdate
(
e
,
start
);
}
catch
(
OutOfMemoryError
e
)
{
}
catch
(
OutOfMemoryError
e
)
{
...
...
h2/src/main/org/h2/command/CommandInterface.java
浏览文件 @
47ed036f
...
@@ -8,6 +8,7 @@ package org.h2.command;
...
@@ -8,6 +8,7 @@ package org.h2.command;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
/**
/**
* Represents a SQL statement.
* Represents a SQL statement.
...
@@ -510,9 +511,16 @@ public interface CommandInterface {
...
@@ -510,9 +511,16 @@ public interface CommandInterface {
/**
/**
* Execute the statement
* Execute the statement
*
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*
* @return the update count
* @return the update count
*/
*/
int
executeUpdate
(
);
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
);
/**
/**
* Stop the command execution, release all locks and resources
* Stop the command execution, release all locks and resources
...
...
h2/src/main/org/h2/command/CommandList.java
浏览文件 @
47ed036f
...
@@ -39,7 +39,7 @@ class CommandList extends Command {
...
@@ -39,7 +39,7 @@ class CommandList extends Command {
@Override
@Override
public
int
update
()
{
public
int
update
()
{
int
updateCount
=
command
.
executeUpdate
();
int
updateCount
=
command
.
executeUpdate
(
false
).
getUpdateCount
(
);
executeRemaining
();
executeRemaining
();
return
updateCount
;
return
updateCount
;
}
}
...
...
h2/src/main/org/h2/command/CommandRemote.java
浏览文件 @
47ed036f
...
@@ -9,6 +9,7 @@ import java.io.IOException;
...
@@ -9,6 +9,7 @@ import java.io.IOException;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.engine.GeneratedKeysMode
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.expression.ParameterInterface
;
...
@@ -17,6 +18,7 @@ import org.h2.message.DbException;
...
@@ -17,6 +18,7 @@ import org.h2.message.DbException;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultRemote
;
import
org.h2.result.ResultRemote
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.util.New
;
import
org.h2.util.New
;
import
org.h2.value.Transfer
;
import
org.h2.value.Transfer
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
...
@@ -194,10 +196,14 @@ public class CommandRemote implements CommandInterface {
...
@@ -194,10 +196,14 @@ public class CommandRemote implements CommandInterface {
}
}
@Override
@Override
public
int
executeUpdate
(
)
{
public
ResultWithGeneratedKeys
executeUpdate
(
Object
generatedKeysRequest
)
{
checkParameters
();
checkParameters
();
boolean
supportsGeneratedKeys
=
session
.
isSupportsGeneratedKeys
();
boolean
readGeneratedKeys
=
supportsGeneratedKeys
&&
!
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
);
int
objectId
=
readGeneratedKeys
?
session
.
getNextId
()
:
0
;
synchronized
(
session
)
{
synchronized
(
session
)
{
int
updateCount
=
0
;
int
updateCount
=
0
;
ResultRemote
generatedKeys
=
null
;
boolean
autoCommit
=
false
;
boolean
autoCommit
=
false
;
for
(
int
i
=
0
,
count
=
0
;
i
<
transferList
.
size
();
i
++)
{
for
(
int
i
=
0
,
count
=
0
;
i
<
transferList
.
size
();
i
++)
{
prepareIfRequired
();
prepareIfRequired
();
...
@@ -206,9 +212,39 @@ public class CommandRemote implements CommandInterface {
...
@@ -206,9 +212,39 @@ public class CommandRemote implements CommandInterface {
session
.
traceOperation
(
"COMMAND_EXECUTE_UPDATE"
,
id
);
session
.
traceOperation
(
"COMMAND_EXECUTE_UPDATE"
,
id
);
transfer
.
writeInt
(
SessionRemote
.
COMMAND_EXECUTE_UPDATE
).
writeInt
(
id
);
transfer
.
writeInt
(
SessionRemote
.
COMMAND_EXECUTE_UPDATE
).
writeInt
(
id
);
sendParameters
(
transfer
);
sendParameters
(
transfer
);
if
(
supportsGeneratedKeys
)
{
int
mode
=
GeneratedKeysMode
.
valueOf
(
generatedKeysRequest
);
transfer
.
writeInt
(
mode
);
switch
(
mode
)
{
case
GeneratedKeysMode
.
COLUMN_NUMBERS
:
{
int
[]
keys
=
(
int
[])
generatedKeysRequest
;
transfer
.
writeInt
(
keys
.
length
);
for
(
int
key
:
keys
)
{
transfer
.
writeInt
(
key
);
}
break
;
}
case
GeneratedKeysMode
.
COLUMN_NAMES
:
{
String
[]
keys
=
(
String
[])
generatedKeysRequest
;
transfer
.
writeInt
(
keys
.
length
);
for
(
String
key
:
keys
)
{
transfer
.
writeString
(
key
);
}
break
;
}
}
}
session
.
done
(
transfer
);
session
.
done
(
transfer
);
updateCount
=
transfer
.
readInt
();
updateCount
=
transfer
.
readInt
();
autoCommit
=
transfer
.
readBoolean
();
autoCommit
=
transfer
.
readBoolean
();
if
(
readGeneratedKeys
)
{
int
columnCount
=
transfer
.
readInt
();
if
(
generatedKeys
!=
null
)
{
generatedKeys
.
close
();
generatedKeys
=
null
;
}
generatedKeys
=
new
ResultRemote
(
session
,
transfer
,
objectId
,
columnCount
,
Integer
.
MAX_VALUE
);
}
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
session
.
removeServer
(
e
,
i
--,
++
count
);
session
.
removeServer
(
e
,
i
--,
++
count
);
}
}
...
@@ -216,7 +252,10 @@ public class CommandRemote implements CommandInterface {
...
@@ -216,7 +252,10 @@ public class CommandRemote implements CommandInterface {
session
.
setAutoCommitFromServer
(
autoCommit
);
session
.
setAutoCommitFromServer
(
autoCommit
);
session
.
autoCommitIfCluster
();
session
.
autoCommitIfCluster
();
session
.
readSessionState
();
session
.
readSessionState
();
return
updateCount
;
if
(
generatedKeys
!=
null
)
{
return
new
ResultWithGeneratedKeys
.
WithKeys
(
updateCount
,
generatedKeys
);
}
return
ResultWithGeneratedKeys
.
of
(
updateCount
);
}
}
}
}
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
47ed036f
...
@@ -5667,6 +5667,10 @@ public class Parser {
...
@@ -5667,6 +5667,10 @@ public class Parser {
readIfEqualOrTo
();
readIfEqualOrTo
();
read
();
read
();
return
new
NoOperation
(
session
);
return
new
NoOperation
(
session
);
}
else
if
(
readIf
(
"SCOPE_GENERATED_KEYS"
))
{
readIfEqualOrTo
();
read
();
return
new
NoOperation
(
session
);
}
else
if
(
readIf
(
"SCHEMA"
))
{
}
else
if
(
readIf
(
"SCHEMA"
))
{
readIfEqualOrTo
();
readIfEqualOrTo
();
Set
command
=
new
Set
(
session
,
SetTypes
.
SCHEMA
);
Set
command
=
new
Set
(
session
,
SetTypes
.
SCHEMA
);
...
...
h2/src/main/org/h2/command/dml/Insert.java
浏览文件 @
47ed036f
...
@@ -12,6 +12,7 @@ import org.h2.api.Trigger;
...
@@ -12,6 +12,7 @@ import org.h2.api.Trigger;
import
org.h2.command.Command
;
import
org.h2.command.Command
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.Prepared
;
import
org.h2.command.Prepared
;
import
org.h2.engine.GeneratedKeys
;
import
org.h2.engine.Right
;
import
org.h2.engine.Right
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.engine.UndoLogRecord
;
import
org.h2.engine.UndoLogRecord
;
...
@@ -20,6 +21,7 @@ import org.h2.expression.ConditionAndOr;
...
@@ -20,6 +21,7 @@ import org.h2.expression.ConditionAndOr;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.SequenceValue
;
import
org.h2.index.Index
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.db.MVPrimaryIndex
;
import
org.h2.mvstore.db.MVPrimaryIndex
;
...
@@ -142,11 +144,14 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -142,11 +144,14 @@ public class Insert extends Prepared implements ResultTarget {
setCurrentRowNumber
(
0
);
setCurrentRowNumber
(
0
);
table
.
fire
(
session
,
Trigger
.
INSERT
,
true
);
table
.
fire
(
session
,
Trigger
.
INSERT
,
true
);
rowNumber
=
0
;
rowNumber
=
0
;
GeneratedKeys
generatedKeys
=
session
.
getGeneratedKeys
();
generatedKeys
.
initialize
(
table
);
int
listSize
=
list
.
size
();
int
listSize
=
list
.
size
();
if
(
listSize
>
0
)
{
if
(
listSize
>
0
)
{
int
columnLen
=
columns
.
length
;
int
columnLen
=
columns
.
length
;
for
(
int
x
=
0
;
x
<
listSize
;
x
++)
{
for
(
int
x
=
0
;
x
<
listSize
;
x
++)
{
session
.
startStatementWithinTransaction
();
session
.
startStatementWithinTransaction
();
generatedKeys
.
nextRow
();
Row
newRow
=
table
.
getTemplateRow
();
Row
newRow
=
table
.
getTemplateRow
();
Expression
[]
expr
=
list
.
get
(
x
);
Expression
[]
expr
=
list
.
get
(
x
);
setCurrentRowNumber
(
x
+
1
);
setCurrentRowNumber
(
x
+
1
);
...
@@ -160,6 +165,9 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -160,6 +165,9 @@ public class Insert extends Prepared implements ResultTarget {
try
{
try
{
Value
v
=
c
.
convert
(
e
.
getValue
(
session
),
session
.
getDatabase
().
getMode
());
Value
v
=
c
.
convert
(
e
.
getValue
(
session
),
session
.
getDatabase
().
getMode
());
newRow
.
setValue
(
index
,
v
);
newRow
.
setValue
(
index
,
v
);
if
(
e
instanceof
SequenceValue
)
{
generatedKeys
.
add
(
c
);
}
}
catch
(
DbException
ex
)
{
}
catch
(
DbException
ex
)
{
throw
setRow
(
ex
,
x
,
getSQL
(
expr
));
throw
setRow
(
ex
,
x
,
getSQL
(
expr
));
}
}
...
@@ -179,6 +187,7 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -179,6 +187,7 @@ public class Insert extends Prepared implements ResultTarget {
continue
;
continue
;
}
}
}
}
generatedKeys
.
confirmRow
(
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
}
}
...
@@ -190,8 +199,12 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -190,8 +199,12 @@ public class Insert extends Prepared implements ResultTarget {
}
else
{
}
else
{
ResultInterface
rows
=
query
.
query
(
0
);
ResultInterface
rows
=
query
.
query
(
0
);
while
(
rows
.
next
())
{
while
(
rows
.
next
())
{
generatedKeys
.
nextRow
();
Value
[]
r
=
rows
.
currentRow
();
Value
[]
r
=
rows
.
currentRow
();
addRow
(
r
);
Row
newRow
=
addRowImpl
(
r
);
if
(
newRow
!=
null
)
{
generatedKeys
.
confirmRow
(
newRow
);
}
}
}
rows
.
close
();
rows
.
close
();
}
}
...
@@ -202,6 +215,10 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -202,6 +215,10 @@ public class Insert extends Prepared implements ResultTarget {
@Override
@Override
public
void
addRow
(
Value
[]
values
)
{
public
void
addRow
(
Value
[]
values
)
{
addRowImpl
(
values
);
}
private
Row
addRowImpl
(
Value
[]
values
)
{
Row
newRow
=
table
.
getTemplateRow
();
Row
newRow
=
table
.
getTemplateRow
();
setCurrentRowNumber
(++
rowNumber
);
setCurrentRowNumber
(++
rowNumber
);
for
(
int
j
=
0
,
len
=
columns
.
length
;
j
<
len
;
j
++)
{
for
(
int
j
=
0
,
len
=
columns
.
length
;
j
<
len
;
j
++)
{
...
@@ -220,7 +237,9 @@ public class Insert extends Prepared implements ResultTarget {
...
@@ -220,7 +237,9 @@ public class Insert extends Prepared implements ResultTarget {
table
.
addRow
(
session
,
newRow
);
table
.
addRow
(
session
,
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
return
newRow
;
}
}
return
null
;
}
}
@Override
@Override
...
...
h2/src/main/org/h2/command/dml/Merge.java
浏览文件 @
47ed036f
...
@@ -11,11 +11,13 @@ import org.h2.api.Trigger;
...
@@ -11,11 +11,13 @@ import org.h2.api.Trigger;
import
org.h2.command.Command
;
import
org.h2.command.Command
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.CommandInterface
;
import
org.h2.command.Prepared
;
import
org.h2.command.Prepared
;
import
org.h2.engine.GeneratedKeys
;
import
org.h2.engine.Right
;
import
org.h2.engine.Right
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.engine.UndoLogRecord
;
import
org.h2.engine.UndoLogRecord
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.SequenceValue
;
import
org.h2.index.Index
;
import
org.h2.index.Index
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
...
@@ -84,11 +86,14 @@ public class Merge extends Prepared {
...
@@ -84,11 +86,14 @@ public class Merge extends Prepared {
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
INSERT
);
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
INSERT
);
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
UPDATE
);
session
.
getUser
().
checkRight
(
targetTable
,
Right
.
UPDATE
);
setCurrentRowNumber
(
0
);
setCurrentRowNumber
(
0
);
GeneratedKeys
generatedKeys
=
session
.
getGeneratedKeys
();
if
(!
valuesExpressionList
.
isEmpty
())
{
if
(!
valuesExpressionList
.
isEmpty
())
{
// process values in list
// process values in list
count
=
0
;
count
=
0
;
generatedKeys
.
initialize
(
targetTable
);
for
(
int
x
=
0
,
size
=
valuesExpressionList
.
size
();
x
<
size
;
x
++)
{
for
(
int
x
=
0
,
size
=
valuesExpressionList
.
size
();
x
<
size
;
x
++)
{
setCurrentRowNumber
(
x
+
1
);
setCurrentRowNumber
(
x
+
1
);
generatedKeys
.
nextRow
();
Expression
[]
expr
=
valuesExpressionList
.
get
(
x
);
Expression
[]
expr
=
valuesExpressionList
.
get
(
x
);
Row
newRow
=
targetTable
.
getTemplateRow
();
Row
newRow
=
targetTable
.
getTemplateRow
();
for
(
int
i
=
0
,
len
=
columns
.
length
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
,
len
=
columns
.
length
;
i
<
len
;
i
++)
{
...
@@ -100,6 +105,9 @@ public class Merge extends Prepared {
...
@@ -100,6 +105,9 @@ public class Merge extends Prepared {
try
{
try
{
Value
v
=
c
.
convert
(
e
.
getValue
(
session
));
Value
v
=
c
.
convert
(
e
.
getValue
(
session
));
newRow
.
setValue
(
index
,
v
);
newRow
.
setValue
(
index
,
v
);
if
(
e
instanceof
SequenceValue
)
{
generatedKeys
.
add
(
c
);
}
}
catch
(
DbException
ex
)
{
}
catch
(
DbException
ex
)
{
throw
setRow
(
ex
,
count
,
getSQL
(
expr
));
throw
setRow
(
ex
,
count
,
getSQL
(
expr
));
}
}
...
@@ -116,6 +124,7 @@ public class Merge extends Prepared {
...
@@ -116,6 +124,7 @@ public class Merge extends Prepared {
targetTable
.
lock
(
session
,
true
,
false
);
targetTable
.
lock
(
session
,
true
,
false
);
while
(
rows
.
next
())
{
while
(
rows
.
next
())
{
count
++;
count
++;
generatedKeys
.
nextRow
();
Value
[]
r
=
rows
.
currentRow
();
Value
[]
r
=
rows
.
currentRow
();
Row
newRow
=
targetTable
.
getTemplateRow
();
Row
newRow
=
targetTable
.
getTemplateRow
();
setCurrentRowNumber
(
count
);
setCurrentRowNumber
(
count
);
...
@@ -171,6 +180,7 @@ public class Merge extends Prepared {
...
@@ -171,6 +180,7 @@ public class Merge extends Prepared {
if
(!
done
)
{
if
(!
done
)
{
targetTable
.
lock
(
session
,
true
,
false
);
targetTable
.
lock
(
session
,
true
,
false
);
targetTable
.
addRow
(
session
,
row
);
targetTable
.
addRow
(
session
,
row
);
session
.
getGeneratedKeys
().
confirmRow
(
row
);
session
.
log
(
targetTable
,
UndoLogRecord
.
INSERT
,
row
);
session
.
log
(
targetTable
,
UndoLogRecord
.
INSERT
,
row
);
targetTable
.
fireAfterRow
(
session
,
null
,
row
,
false
);
targetTable
.
fireAfterRow
(
session
,
null
,
row
,
false
);
}
}
...
...
h2/src/main/org/h2/engine/ConnectionInfo.java
浏览文件 @
47ed036f
...
@@ -96,7 +96,8 @@ public class ConnectionInfo implements Cloneable {
...
@@ -96,7 +96,8 @@ public class ConnectionInfo implements Cloneable {
"CREATE"
,
"CACHE_TYPE"
,
"FILE_LOCK"
,
"IGNORE_UNKNOWN_SETTINGS"
,
"CREATE"
,
"CACHE_TYPE"
,
"FILE_LOCK"
,
"IGNORE_UNKNOWN_SETTINGS"
,
"IFEXISTS"
,
"INIT"
,
"PASSWORD"
,
"RECOVER"
,
"RECOVER_TEST"
,
"IFEXISTS"
,
"INIT"
,
"PASSWORD"
,
"RECOVER"
,
"RECOVER_TEST"
,
"USER"
,
"AUTO_SERVER"
,
"AUTO_SERVER_PORT"
,
"NO_UPGRADE"
,
"USER"
,
"AUTO_SERVER"
,
"AUTO_SERVER_PORT"
,
"NO_UPGRADE"
,
"AUTO_RECONNECT"
,
"OPEN_NEW"
,
"PAGE_SIZE"
,
"PASSWORD_HASH"
,
"JMX"
};
"AUTO_RECONNECT"
,
"OPEN_NEW"
,
"PAGE_SIZE"
,
"PASSWORD_HASH"
,
"JMX"
,
"SCOPE_GENERATED_KEYS"
};
HashSet
<
String
>
set
=
new
HashSet
<>(
list
.
size
()
+
connectionTime
.
length
);
HashSet
<
String
>
set
=
new
HashSet
<>(
list
.
size
()
+
connectionTime
.
length
);
set
.
addAll
(
list
);
set
.
addAll
(
list
);
for
(
String
key
:
connectionTime
)
{
for
(
String
key
:
connectionTime
)
{
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
47ed036f
...
@@ -100,6 +100,21 @@ public class Constants {
...
@@ -100,6 +100,21 @@ public class Constants {
*/
*/
public
static
final
int
TCP_PROTOCOL_VERSION_16
=
16
;
public
static
final
int
TCP_PROTOCOL_VERSION_16
=
16
;
/**
* The TCP protocol version number 17.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_17
=
17
;
/**
* Minimum supported version of TCP protocol.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_MIN_SUPPORTED
=
TCP_PROTOCOL_VERSION_6
;
/**
* Maximum supported version of TCP protocol.
*/
public
static
final
int
TCP_PROTOCOL_VERSION_MAX_SUPPORTED
=
TCP_PROTOCOL_VERSION_17
;
/**
/**
* The major version of this database.
* The major version of this database.
*/
*/
...
...
h2/src/main/org/h2/engine/Engine.java
浏览文件 @
47ed036f
...
@@ -206,7 +206,7 @@ public class Engine implements SessionFactory {
...
@@ -206,7 +206,7 @@ public class Engine implements SessionFactory {
CommandInterface
command
=
session
.
prepareCommand
(
CommandInterface
command
=
session
.
prepareCommand
(
"SET "
+
Parser
.
quoteIdentifier
(
setting
)
+
" "
+
value
,
"SET "
+
Parser
.
quoteIdentifier
(
setting
)
+
" "
+
value
,
Integer
.
MAX_VALUE
);
Integer
.
MAX_VALUE
);
command
.
executeUpdate
();
command
.
executeUpdate
(
false
);
}
catch
(
DbException
e
)
{
}
catch
(
DbException
e
)
{
if
(
e
.
getErrorCode
()
==
ErrorCode
.
ADMIN_RIGHTS_REQUIRED
)
{
if
(
e
.
getErrorCode
()
==
ErrorCode
.
ADMIN_RIGHTS_REQUIRED
)
{
session
.
getTrace
().
error
(
e
,
"admin rights required; user: \""
+
session
.
getTrace
().
error
(
e
,
"admin rights required; user: \""
+
...
@@ -224,7 +224,7 @@ public class Engine implements SessionFactory {
...
@@ -224,7 +224,7 @@ public class Engine implements SessionFactory {
try
{
try
{
CommandInterface
command
=
session
.
prepareCommand
(
init
,
CommandInterface
command
=
session
.
prepareCommand
(
init
,
Integer
.
MAX_VALUE
);
Integer
.
MAX_VALUE
);
command
.
executeUpdate
();
command
.
executeUpdate
(
false
);
}
catch
(
DbException
e
)
{
}
catch
(
DbException
e
)
{
if
(!
ignoreUnknownSetting
)
{
if
(!
ignoreUnknownSetting
)
{
session
.
close
();
session
.
close
();
...
...
h2/src/main/org/h2/engine/GeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
engine
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.result.LocalResult
;
import
org.h2.result.Row
;
import
org.h2.table.Column
;
import
org.h2.table.Table
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* Class for gathering and processing of generated keys.
*/
public
final
class
GeneratedKeys
{
/**
* Data for result set with generated keys.
*/
private
final
ArrayList
<
Map
<
Column
,
Value
>>
data
=
New
.
arrayList
();
/**
* Columns with generated keys in the current row.
*/
private
final
ArrayList
<
Column
>
row
=
New
.
arrayList
();
/**
* All columns with generated keys.
*/
private
final
ArrayList
<
Column
>
allColumns
=
New
.
arrayList
();
/**
* Request for keys gathering. {@code false} if generated keys are not needed,
* {@code true} if generated keys should be configured automatically,
* {@code int[]} to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys from.
*/
private
Object
generatedKeysRequest
;
/**
* Processed table.
*/
private
Table
table
;
/**
* Remembers columns with generated keys.
*
* @param column
* table column
*/
public
void
add
(
Column
column
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
;
}
row
.
add
(
column
);
}
/**
* Clears all information from previous runs and sets a new request for
* gathering of generated keys.
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*/
public
void
clear
(
Object
generatedKeysRequest
)
{
this
.
generatedKeysRequest
=
generatedKeysRequest
;
data
.
clear
();
row
.
clear
();
allColumns
.
clear
();
table
=
null
;
}
/**
* Saves row with generated keys if any.
*
* @param tableRow
* table row that was inserted
*/
public
void
confirmRow
(
Row
tableRow
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
;
}
int
size
=
row
.
size
();
if
(
size
>
0
)
{
if
(
size
==
1
)
{
Column
column
=
row
.
get
(
0
);
data
.
add
(
Collections
.
singletonMap
(
column
,
tableRow
.
getValue
(
column
.
getColumnId
())));
if
(!
allColumns
.
contains
(
column
))
{
allColumns
.
add
(
column
);
}
}
else
{
HashMap
<
Column
,
Value
>
map
=
new
HashMap
<>();
for
(
Column
column
:
row
)
{
map
.
put
(
column
,
tableRow
.
getValue
(
column
.
getColumnId
()));
if
(!
allColumns
.
contains
(
column
))
{
allColumns
.
add
(
column
);
}
}
data
.
add
(
map
);
}
row
.
clear
();
}
}
/**
* Returns generated keys.
*
* @return local result with generated keys
*/
public
LocalResult
getKeys
(
Session
session
)
{
Database
db
=
session
==
null
?
null
:
session
.
getDatabase
();
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
clear
(
null
);
return
new
LocalResult
();
}
ArrayList
<
ExpressionColumn
>
expressionColumns
;
if
(
Boolean
.
TRUE
.
equals
(
generatedKeysRequest
))
{
expressionColumns
=
new
ArrayList
<>(
allColumns
.
size
());
for
(
Column
column
:
allColumns
)
{
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
}
}
else
if
(
generatedKeysRequest
instanceof
int
[])
{
if
(
table
!=
null
)
{
int
[]
indices
=
(
int
[])
generatedKeysRequest
;
Column
[]
columns
=
table
.
getColumns
();
int
cnt
=
columns
.
length
;
allColumns
.
clear
();
expressionColumns
=
new
ArrayList
<>(
indices
.
length
);
for
(
int
idx
:
indices
)
{
if
(
idx
>=
1
&&
idx
<=
cnt
)
{
Column
column
=
columns
[
idx
-
1
];
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
allColumns
.
add
(
column
);
}
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
}
else
if
(
generatedKeysRequest
instanceof
String
[])
{
if
(
table
!=
null
)
{
String
[]
names
=
(
String
[])
generatedKeysRequest
;
allColumns
.
clear
();
expressionColumns
=
new
ArrayList
<>(
names
.
length
);
for
(
String
name
:
names
)
{
Column
column
;
search:
if
(
table
.
doesColumnExist
(
name
))
{
column
=
table
.
getColumn
(
name
);
}
else
{
name
=
StringUtils
.
toUpperEnglish
(
name
);
if
(
table
.
doesColumnExist
(
name
))
{
column
=
table
.
getColumn
(
name
);
}
else
{
for
(
Column
c
:
table
.
getColumns
())
{
if
(
c
.
getName
().
equalsIgnoreCase
(
name
))
{
column
=
c
;
break
search
;
}
}
continue
;
}
}
expressionColumns
.
add
(
new
ExpressionColumn
(
db
,
column
));
allColumns
.
add
(
column
);
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
}
else
{
clear
(
null
);
return
new
LocalResult
();
}
int
columnCount
=
expressionColumns
.
size
();
if
(
columnCount
==
0
)
{
clear
(
null
);
return
new
LocalResult
();
}
LocalResult
result
=
new
LocalResult
(
session
,
expressionColumns
.
toArray
(
new
Expression
[
0
]),
columnCount
);
for
(
Map
<
Column
,
Value
>
map
:
data
)
{
Value
[]
row
=
new
Value
[
columnCount
];
for
(
Map
.
Entry
<
Column
,
Value
>
entry
:
map
.
entrySet
())
{
int
idx
=
allColumns
.
indexOf
(
entry
.
getKey
());
if
(
idx
>=
0
)
{
row
[
idx
]
=
entry
.
getValue
();
}
}
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
if
(
row
[
i
]
==
null
)
{
row
[
i
]
=
ValueNull
.
INSTANCE
;
}
}
result
.
addRow
(
row
);
}
clear
(
null
);
return
result
;
}
/**
* Initializes processing of the specified table. Should be called after
* {@code clear()}, but before other methods.
*
* @param table
* table
*/
public
void
initialize
(
Table
table
)
{
this
.
table
=
table
;
}
/**
* Clears unsaved information about previous row, if any. Should be called
* before processing of a new row if previous row was not confirmed or simply
* always before each row.
*/
public
void
nextRow
()
{
row
.
clear
();
}
@Override
public
String
toString
()
{
return
allColumns
+
": "
+
data
.
size
();
}
}
h2/src/main/org/h2/engine/GeneratedKeysMode.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
engine
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
/**
* Modes of generated keys' gathering.
*/
public
final
class
GeneratedKeysMode
{
/**
* Generated keys are not needed.
*/
public
static
final
int
NONE
=
0
;
/**
* Generated keys should be configured automatically.
*/
public
static
final
int
AUTO
=
1
;
/**
* Use specified column indices to return generated keys from.
*/
public
static
final
int
COLUMN_NUMBERS
=
2
;
/**
* Use specified column names to return generated keys from.
*/
public
static
final
int
COLUMN_NAMES
=
3
;
/**
* Determines mode of generated keys' gathering.
*
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
* @return mode for the specified generated keys request
*/
public
static
int
valueOf
(
Object
generatedKeysRequest
)
{
if
(
Boolean
.
FALSE
.
equals
(
generatedKeysRequest
))
{
return
NONE
;
}
if
(
Boolean
.
TRUE
.
equals
(
generatedKeysRequest
))
{
return
AUTO
;
}
if
(
generatedKeysRequest
instanceof
int
[])
{
return
COLUMN_NUMBERS
;
}
if
(
generatedKeysRequest
instanceof
String
[])
{
return
COLUMN_NAMES
;
}
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_2
,
generatedKeysRequest
==
null
?
"null"
:
generatedKeysRequest
.
toString
());
}
private
GeneratedKeysMode
()
{
}
}
h2/src/main/org/h2/engine/Session.java
浏览文件 @
47ed036f
...
@@ -85,6 +85,7 @@ public class Session extends SessionWithState {
...
@@ -85,6 +85,7 @@ public class Session extends SessionWithState {
private
Value
lastIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastScopeIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastScopeIdentity
=
ValueLong
.
get
(
0
);
private
Value
lastTriggerIdentity
;
private
Value
lastTriggerIdentity
;
private
GeneratedKeys
generatedKeys
;
private
int
firstUncommittedLog
=
Session
.
LOG_WRITTEN
;
private
int
firstUncommittedLog
=
Session
.
LOG_WRITTEN
;
private
int
firstUncommittedPos
=
Session
.
LOG_WRITTEN
;
private
int
firstUncommittedPos
=
Session
.
LOG_WRITTEN
;
private
HashMap
<
String
,
Savepoint
>
savepoints
;
private
HashMap
<
String
,
Savepoint
>
savepoints
;
...
@@ -1075,6 +1076,13 @@ public class Session extends SessionWithState {
...
@@ -1075,6 +1076,13 @@ public class Session extends SessionWithState {
return
lastTriggerIdentity
;
return
lastTriggerIdentity
;
}
}
public
GeneratedKeys
getGeneratedKeys
()
{
if
(
generatedKeys
==
null
)
{
generatedKeys
=
new
GeneratedKeys
();
}
return
generatedKeys
;
}
/**
/**
* Called when a log entry for this session is added. The session keeps
* Called when a log entry for this session is added. The session keeps
* track of the first entry in the transaction log that is not yet
* track of the first entry in the transaction log that is not yet
...
@@ -1237,9 +1245,20 @@ public class Session extends SessionWithState {
...
@@ -1237,9 +1245,20 @@ public class Session extends SessionWithState {
* executing the statement.
* executing the statement.
*
*
* @param command the command
* @param command the command
*/
* @param generatedKeysRequest
public
void
setCurrentCommand
(
Command
command
)
{
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*/
public
void
setCurrentCommand
(
Command
command
,
Object
generatedKeysRequest
)
{
this
.
currentCommand
=
command
;
this
.
currentCommand
=
command
;
// Preserve generated keys in case of a new query due to possible nested
// queries in update
if
(
command
!=
null
&&
!
command
.
isQuery
())
{
getGeneratedKeys
().
clear
(
generatedKeysRequest
);
}
if
(
queryTimeout
>
0
&&
command
!=
null
)
{
if
(
queryTimeout
>
0
&&
command
!=
null
)
{
currentCommandStart
=
System
.
currentTimeMillis
();
currentCommandStart
=
System
.
currentTimeMillis
();
long
now
=
System
.
nanoTime
();
long
now
=
System
.
nanoTime
();
...
@@ -1790,4 +1809,10 @@ public class Session extends SessionWithState {
...
@@ -1790,4 +1809,10 @@ public class Session extends SessionWithState {
public
void
setColumnNamerConfiguration
(
ColumnNamerConfiguration
columnNamerConfiguration
)
{
public
void
setColumnNamerConfiguration
(
ColumnNamerConfiguration
columnNamerConfiguration
)
{
this
.
columnNamerConfiguration
=
columnNamerConfiguration
;
this
.
columnNamerConfiguration
=
columnNamerConfiguration
;
}
}
@Override
public
boolean
isSupportsGeneratedKeys
()
{
return
true
;
}
}
}
h2/src/main/org/h2/engine/SessionInterface.java
浏览文件 @
47ed036f
...
@@ -153,4 +153,13 @@ public interface SessionInterface extends Closeable {
...
@@ -153,4 +153,13 @@ public interface SessionInterface extends Closeable {
* @return the current schema name
* @return the current schema name
*/
*/
String
getCurrentSchemaName
();
String
getCurrentSchemaName
();
/**
* Returns is this session supports generated keys.
*
* @return {@code true} if generated keys are supported, {@code false} if only
* {@code SCOPE_IDENTITY()} is supported
*/
boolean
isSupportsGeneratedKeys
();
}
}
h2/src/main/org/h2/engine/SessionRemote.java
浏览文件 @
47ed036f
...
@@ -117,8 +117,8 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -117,8 +117,8 @@ public class SessionRemote extends SessionWithState implements DataHandler {
Transfer
trans
=
new
Transfer
(
this
,
socket
);
Transfer
trans
=
new
Transfer
(
this
,
socket
);
trans
.
setSSL
(
ci
.
isSSL
());
trans
.
setSSL
(
ci
.
isSSL
());
trans
.
init
();
trans
.
init
();
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
6
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
16
);
trans
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
trans
.
writeString
(
db
);
trans
.
writeString
(
db
);
trans
.
writeString
(
ci
.
getOriginalURL
());
trans
.
writeString
(
ci
.
getOriginalURL
());
trans
.
writeString
(
ci
.
getUserName
());
trans
.
writeString
(
ci
.
getUserName
());
...
@@ -210,7 +210,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -210,7 +210,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
CommandInterface
c
=
prepareCommand
(
CommandInterface
c
=
prepareCommand
(
"SET CLUSTER "
+
serverList
,
Integer
.
MAX_VALUE
);
"SET CLUSTER "
+
serverList
,
Integer
.
MAX_VALUE
);
// this will set autoCommit to false
// this will set autoCommit to false
c
.
executeUpdate
();
c
.
executeUpdate
(
false
);
// so we need to switch it on
// so we need to switch it on
autoCommit
=
true
;
autoCommit
=
true
;
cluster
=
true
;
cluster
=
true
;
...
@@ -265,13 +265,13 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -265,13 +265,13 @@ public class SessionRemote extends SessionWithState implements DataHandler {
autoCommitTrue
=
prepareCommand
(
autoCommitTrue
=
prepareCommand
(
"SET AUTOCOMMIT TRUE"
,
Integer
.
MAX_VALUE
);
"SET AUTOCOMMIT TRUE"
,
Integer
.
MAX_VALUE
);
}
}
autoCommitTrue
.
executeUpdate
();
autoCommitTrue
.
executeUpdate
(
false
);
}
else
{
}
else
{
if
(
autoCommitFalse
==
null
)
{
if
(
autoCommitFalse
==
null
)
{
autoCommitFalse
=
prepareCommand
(
autoCommitFalse
=
prepareCommand
(
"SET AUTOCOMMIT FALSE"
,
Integer
.
MAX_VALUE
);
"SET AUTOCOMMIT FALSE"
,
Integer
.
MAX_VALUE
);
}
}
autoCommitFalse
.
executeUpdate
();
autoCommitFalse
.
executeUpdate
(
false
);
}
}
}
}
}
}
...
@@ -468,7 +468,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -468,7 +468,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
private
void
switchOffCluster
()
{
private
void
switchOffCluster
()
{
CommandInterface
ci
=
prepareCommand
(
"SET CLUSTER ''"
,
Integer
.
MAX_VALUE
);
CommandInterface
ci
=
prepareCommand
(
"SET CLUSTER ''"
,
Integer
.
MAX_VALUE
);
ci
.
executeUpdate
();
ci
.
executeUpdate
(
false
);
}
}
/**
/**
...
@@ -869,4 +869,10 @@ public class SessionRemote extends SessionWithState implements DataHandler {
...
@@ -869,4 +869,10 @@ public class SessionRemote extends SessionWithState implements DataHandler {
public
void
setCurrentSchemaName
(
String
schema
)
{
public
void
setCurrentSchemaName
(
String
schema
)
{
throw
DbException
.
getUnsupportedException
(
"setSchema && remote session"
);
throw
DbException
.
getUnsupportedException
(
"setSchema && remote session"
);
}
}
@Override
public
boolean
isSupportsGeneratedKeys
()
{
return
getClientVersion
()
>=
Constants
.
TCP_PROTOCOL_VERSION_17
;
}
}
}
h2/src/main/org/h2/engine/SessionWithState.java
浏览文件 @
47ed036f
...
@@ -29,7 +29,7 @@ abstract class SessionWithState implements SessionInterface {
...
@@ -29,7 +29,7 @@ abstract class SessionWithState implements SessionInterface {
try
{
try
{
for
(
String
sql
:
sessionState
)
{
for
(
String
sql
:
sessionState
)
{
CommandInterface
ci
=
prepareCommand
(
sql
,
Integer
.
MAX_VALUE
);
CommandInterface
ci
=
prepareCommand
(
sql
,
Integer
.
MAX_VALUE
);
ci
.
executeUpdate
();
ci
.
executeUpdate
(
false
);
}
}
}
finally
{
}
finally
{
sessionStateUpdating
=
false
;
sessionStateUpdating
=
false
;
...
...
h2/src/main/org/h2/fulltext/FullText.java
浏览文件 @
47ed036f
...
@@ -950,7 +950,8 @@ public class FullText {
...
@@ -950,7 +950,8 @@ public class FullText {
useOwnConnection
=
isMultiThread
(
conn
);
useOwnConnection
=
isMultiThread
(
conn
);
if
(!
useOwnConnection
)
{
if
(!
useOwnConnection
)
{
for
(
int
i
=
0
;
i
<
SQL
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
SQL
.
length
;
i
++)
{
prepStatements
[
i
]
=
conn
.
prepareStatement
(
SQL
[
i
]);
prepStatements
[
i
]
=
conn
.
prepareStatement
(
SQL
[
i
],
Statement
.
RETURN_GENERATED_KEYS
);
}
}
}
}
}
}
...
@@ -1154,7 +1155,9 @@ public class FullText {
...
@@ -1154,7 +1155,9 @@ public class FullText {
}
}
private
PreparedStatement
getStatement
(
Connection
conn
,
int
index
)
throws
SQLException
{
private
PreparedStatement
getStatement
(
Connection
conn
,
int
index
)
throws
SQLException
{
return
useOwnConnection
?
conn
.
prepareStatement
(
SQL
[
index
])
:
prepStatements
[
index
];
return
useOwnConnection
?
conn
.
prepareStatement
(
SQL
[
index
],
Statement
.
RETURN_GENERATED_KEYS
)
:
prepStatements
[
index
];
}
}
}
}
...
...
h2/src/main/org/h2/jdbc/JdbcCallableStatement.java
浏览文件 @
47ed036f
...
@@ -47,7 +47,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
...
@@ -47,7 +47,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
JdbcCallableStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
JdbcCallableStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
int
resultSetType
,
int
resultSetConcurrency
)
{
int
resultSetType
,
int
resultSetConcurrency
)
{
super
(
conn
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
);
super
(
conn
,
sql
,
id
,
resultSetType
,
resultSetConcurrency
,
false
,
false
);
setTrace
(
session
.
getTrace
(),
TraceObject
.
CALLABLE_STATEMENT
,
id
);
setTrace
(
session
.
getTrace
(),
TraceObject
.
CALLABLE_STATEMENT
,
id
);
}
}
...
...
h2/src/main/org/h2/jdbc/JdbcConnection.java
浏览文件 @
47ed036f
差异被折叠。
点击展开。
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
浏览文件 @
47ed036f
...
@@ -31,9 +31,10 @@ import org.h2.expression.ParameterInterface;
...
@@ -31,9 +31,10 @@ import org.h2.expression.ParameterInterface;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.message.TraceObject
;
import
org.h2.message.TraceObject
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.
tools.SimpleResultSet
;
import
org.h2.
result.ResultWithGeneratedKeys
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.MergedResultSet
;
import
org.h2.util.New
;
import
org.h2.util.New
;
import
org.h2.value.DataType
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
...
@@ -61,13 +62,15 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -61,13 +62,15 @@ public class JdbcPreparedStatement extends JdbcStatement implements
protected
CommandInterface
command
;
protected
CommandInterface
command
;
private
final
String
sqlStatement
;
private
final
String
sqlStatement
;
private
ArrayList
<
Value
[]>
batchParameters
;
private
ArrayList
<
Value
[]>
batchParameters
;
private
ArrayList
<
Object
>
batchIdentities
;
private
MergedResultSet
batchIdentities
;
private
HashMap
<
String
,
Integer
>
cachedColumnLabelMap
;
private
HashMap
<
String
,
Integer
>
cachedColumnLabelMap
;
private
final
Object
generatedKeysRequest
;
JdbcPreparedStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
JdbcPreparedStatement
(
JdbcConnection
conn
,
String
sql
,
int
id
,
int
resultSetType
,
int
resultSetConcurrency
,
int
resultSetType
,
int
resultSetConcurrency
,
boolean
closeWithResultSet
)
{
boolean
closeWithResultSet
,
Object
generatedKeysRequest
)
{
super
(
conn
,
id
,
resultSetType
,
resultSetConcurrency
,
closeWithResultSet
);
super
(
conn
,
id
,
resultSetType
,
resultSetConcurrency
,
closeWithResultSet
);
this
.
generatedKeysRequest
=
conn
.
scopeGeneratedKeys
()
?
false
:
generatedKeysRequest
;
setTrace
(
session
.
getTrace
(),
TraceObject
.
PREPARED_STATEMENT
,
id
);
setTrace
(
session
.
getTrace
(),
TraceObject
.
PREPARED_STATEMENT
,
id
);
this
.
sqlStatement
=
sql
;
this
.
sqlStatement
=
sql
;
command
=
conn
.
prepareCommand
(
sql
,
fetchSize
);
command
=
conn
.
prepareCommand
(
sql
,
fetchSize
);
...
@@ -193,7 +196,14 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -193,7 +196,14 @@ public class JdbcPreparedStatement extends JdbcStatement implements
synchronized
(
session
)
{
synchronized
(
session
)
{
try
{
try
{
setExecutingStatement
(
command
);
setExecutingStatement
(
command
);
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
int
id
=
getNextId
(
TraceObject
.
RESULT_SET
);
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
finally
{
}
finally
{
setExecutingStatement
(
null
);
setExecutingStatement
(
null
);
}
}
...
@@ -236,7 +246,13 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -236,7 +246,13 @@ public class JdbcPreparedStatement extends JdbcStatement implements
updatable
,
cachedColumnLabelMap
);
updatable
,
cachedColumnLabelMap
);
}
else
{
}
else
{
returnsResultSet
=
false
;
returnsResultSet
=
false
;
updateCount
=
command
.
executeUpdate
();
ResultWithGeneratedKeys
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
updateCount
=
result
.
getUpdateCount
();
ResultInterface
gk
=
result
.
getGeneratedKeys
();
if
(
gk
!=
null
)
{
generatedKeys
=
new
JdbcResultSet
(
conn
,
this
,
command
,
gk
,
id
,
false
,
true
,
false
);
}
}
}
}
finally
{
}
finally
{
if
(!
lazy
)
{
if
(!
lazy
)
{
...
@@ -1243,7 +1259,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -1243,7 +1259,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
// set
// set
batchParameters
=
New
.
arrayList
();
batchParameters
=
New
.
arrayList
();
}
}
batchIdentities
=
New
.
arrayLis
t
();
batchIdentities
=
new
MergedResultSe
t
();
int
size
=
batchParameters
.
size
();
int
size
=
batchParameters
.
size
();
int
[]
result
=
new
int
[
size
];
int
[]
result
=
new
int
[
size
];
boolean
error
=
false
;
boolean
error
=
false
;
...
@@ -1261,10 +1277,9 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -1261,10 +1277,9 @@ public class JdbcPreparedStatement extends JdbcStatement implements
}
}
try
{
try
{
result
[
i
]
=
executeUpdateInternal
();
result
[
i
]
=
executeUpdateInternal
();
ResultSet
rs
=
conn
.
getGeneratedKeys
(
this
,
id
);
// Cannot use own implementation, it returns batch identities
while
(
rs
.
next
())
{
ResultSet
rs
=
super
.
getGeneratedKeys
();
batchIdentities
.
add
(
rs
.
getObject
(
1
));
batchIdentities
.
add
(
rs
);
}
}
catch
(
Exception
re
)
{
}
catch
(
Exception
re
)
{
SQLException
e
=
logAndConvert
(
re
);
SQLException
e
=
logAndConvert
(
re
);
if
(
next
==
null
)
{
if
(
next
==
null
)
{
...
@@ -1293,14 +1308,8 @@ public class JdbcPreparedStatement extends JdbcStatement implements
...
@@ -1293,14 +1308,8 @@ public class JdbcPreparedStatement extends JdbcStatement implements
@Override
@Override
public
ResultSet
getGeneratedKeys
()
throws
SQLException
{
public
ResultSet
getGeneratedKeys
()
throws
SQLException
{
if
(
batchIdentities
!=
null
&&
!
batchIdentities
.
isEmpty
())
{
if
(
batchIdentities
!=
null
)
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
return
batchIdentities
.
getResult
();
rs
.
addColumn
(
"identity"
,
java
.
sql
.
Types
.
INTEGER
,
10
,
0
);
for
(
Object
o
:
batchIdentities
)
{
rs
.
addRow
(
o
);
}
return
rs
;
}
}
return
super
.
getGeneratedKeys
();
return
super
.
getGeneratedKeys
();
}
}
...
...
h2/src/main/org/h2/jdbc/JdbcSavepoint.java
浏览文件 @
47ed036f
...
@@ -65,7 +65,7 @@ public class JdbcSavepoint extends TraceObject implements Savepoint {
...
@@ -65,7 +65,7 @@ public class JdbcSavepoint extends TraceObject implements Savepoint {
checkValid
();
checkValid
();
conn
.
prepareCommand
(
conn
.
prepareCommand
(
"ROLLBACK TO SAVEPOINT "
+
getName
(
name
,
savepointId
),
"ROLLBACK TO SAVEPOINT "
+
getName
(
name
,
savepointId
),
Integer
.
MAX_VALUE
).
executeUpdate
();
Integer
.
MAX_VALUE
).
executeUpdate
(
false
);
}
}
private
void
checkValid
()
{
private
void
checkValid
()
{
...
...
h2/src/main/org/h2/jdbc/JdbcStatement.java
浏览文件 @
47ed036f
差异被折叠。
点击展开。
h2/src/main/org/h2/result/ResultWithGeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
result
;
/**
* Result of update command with optional generated keys.
*/
public
class
ResultWithGeneratedKeys
{
/**
* Result of update command with generated keys;
*/
public
static
final
class
WithKeys
extends
ResultWithGeneratedKeys
{
private
final
ResultInterface
generatedKeys
;
/**
* Creates a result with update count and generated keys.
*
* @param updateCount
* update count
* @param generatedKeys
* generated keys
*/
public
WithKeys
(
int
updateCount
,
ResultInterface
generatedKeys
)
{
super
(
updateCount
);
this
.
generatedKeys
=
generatedKeys
;
}
@Override
public
ResultInterface
getGeneratedKeys
()
{
return
generatedKeys
;
}
}
/**
* Returns a result with only update count.
*
* @param updateCount
* update count
*/
public
static
ResultWithGeneratedKeys
of
(
int
updateCount
)
{
return
new
ResultWithGeneratedKeys
(
updateCount
);
}
private
final
int
updateCount
;
ResultWithGeneratedKeys
(
int
updateCount
)
{
this
.
updateCount
=
updateCount
;
}
/**
* Returns generated keys, or {@code null}.
*
* @return generated keys, or {@code null}
*/
public
ResultInterface
getGeneratedKeys
()
{
return
null
;
}
/**
* Returns update count.
*
* @return update count
*/
public
int
getUpdateCount
()
{
return
updateCount
;
}
}
h2/src/main/org/h2/schema/TriggerObject.java
浏览文件 @
47ed036f
...
@@ -203,6 +203,7 @@ public class TriggerObject extends SchemaObjectBase {
...
@@ -203,6 +203,7 @@ public class TriggerObject extends SchemaObjectBase {
* times for each statement.
* times for each statement.
*
*
* @param session the session
* @param session the session
* @param table the table
* @param oldRow the old row
* @param oldRow the old row
* @param newRow the new row
* @param newRow the new row
* @param beforeAction true if this method is called before the operation is
* @param beforeAction true if this method is called before the operation is
...
@@ -210,7 +211,7 @@ public class TriggerObject extends SchemaObjectBase {
...
@@ -210,7 +211,7 @@ public class TriggerObject extends SchemaObjectBase {
* @param rollback when the operation occurred within a rollback
* @param rollback when the operation occurred within a rollback
* @return true if no further action is required (for 'instead of' triggers)
* @return true if no further action is required (for 'instead of' triggers)
*/
*/
public
boolean
fireRow
(
Session
session
,
Row
oldRow
,
Row
newRow
,
public
boolean
fireRow
(
Session
session
,
Table
table
,
Row
oldRow
,
Row
newRow
,
boolean
beforeAction
,
boolean
rollback
)
{
boolean
beforeAction
,
boolean
rollback
)
{
if
(!
rowBased
||
before
!=
beforeAction
)
{
if
(!
rowBased
||
before
!=
beforeAction
)
{
return
false
;
return
false
;
...
@@ -260,6 +261,7 @@ public class TriggerObject extends SchemaObjectBase {
...
@@ -260,6 +261,7 @@ public class TriggerObject extends SchemaObjectBase {
Object
o
=
newList
[
i
];
Object
o
=
newList
[
i
];
if
(
o
!=
newListBackup
[
i
])
{
if
(
o
!=
newListBackup
[
i
])
{
Value
v
=
DataType
.
convertToValue
(
session
,
o
,
Value
.
UNKNOWN
);
Value
v
=
DataType
.
convertToValue
(
session
,
o
,
Value
.
UNKNOWN
);
session
.
getGeneratedKeys
().
add
(
table
.
getColumn
(
i
));
newRow
.
setValue
(
i
,
v
);
newRow
.
setValue
(
i
,
v
);
}
}
}
}
...
...
h2/src/main/org/h2/server/TcpServerThread.java
浏览文件 @
47ed036f
...
@@ -21,6 +21,7 @@ import org.h2.command.Command;
...
@@ -21,6 +21,7 @@ import org.h2.command.Command;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.ConnectionInfo
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Engine
;
import
org.h2.engine.Engine
;
import
org.h2.engine.GeneratedKeysMode
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
...
@@ -31,6 +32,7 @@ import org.h2.jdbc.JdbcSQLException;
...
@@ -31,6 +32,7 @@ import org.h2.jdbc.JdbcSQLException;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.ResultColumn
;
import
org.h2.result.ResultColumn
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.store.LobStorageInterface
;
import
org.h2.store.LobStorageInterface
;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.SmallLRUCache
;
import
org.h2.util.SmallLRUCache
;
...
@@ -88,15 +90,15 @@ public class TcpServerThread implements Runnable {
...
@@ -88,15 +90,15 @@ public class TcpServerThread implements Runnable {
}
}
int
minClientVersion
=
transfer
.
readInt
();
int
minClientVersion
=
transfer
.
readInt
();
int
maxClientVersion
=
transfer
.
readInt
();
int
maxClientVersion
=
transfer
.
readInt
();
if
(
maxClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_
6
)
{
if
(
maxClientVersion
<
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
6
);
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_
16
)
{
}
else
if
(
minClientVersion
>
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
)
{
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
throw
DbException
.
get
(
ErrorCode
.
DRIVER_VERSION_ERROR_2
,
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
16
);
""
+
clientVersion
,
""
+
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
}
}
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_
16
)
{
if
(
maxClientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
)
{
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_
16
;
clientVersion
=
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
;
}
else
{
}
else
{
clientVersion
=
maxClientVersion
;
clientVersion
=
maxClientVersion
;
}
}
...
@@ -178,7 +180,7 @@ public class TcpServerThread implements Runnable {
...
@@ -178,7 +180,7 @@ public class TcpServerThread implements Runnable {
RuntimeException
closeError
=
null
;
RuntimeException
closeError
=
null
;
try
{
try
{
Command
rollback
=
session
.
prepareLocal
(
"ROLLBACK"
);
Command
rollback
=
session
.
prepareLocal
(
"ROLLBACK"
);
rollback
.
executeUpdate
();
rollback
.
executeUpdate
(
false
);
}
catch
(
RuntimeException
e
)
{
}
catch
(
RuntimeException
e
)
{
closeError
=
e
;
closeError
=
e
;
server
.
traceError
(
e
);
server
.
traceError
(
e
);
...
@@ -302,7 +304,7 @@ public class TcpServerThread implements Runnable {
...
@@ -302,7 +304,7 @@ public class TcpServerThread implements Runnable {
commit
=
session
.
prepareLocal
(
"COMMIT"
);
commit
=
session
.
prepareLocal
(
"COMMIT"
);
}
}
int
old
=
session
.
getModificationId
();
int
old
=
session
.
getModificationId
();
commit
.
executeUpdate
();
commit
.
executeUpdate
(
false
);
transfer
.
writeInt
(
getState
(
old
)).
flush
();
transfer
.
writeInt
(
getState
(
old
)).
flush
();
break
;
break
;
}
}
...
@@ -353,10 +355,48 @@ public class TcpServerThread implements Runnable {
...
@@ -353,10 +355,48 @@ public class TcpServerThread implements Runnable {
int
id
=
transfer
.
readInt
();
int
id
=
transfer
.
readInt
();
Command
command
=
(
Command
)
cache
.
getObject
(
id
,
false
);
Command
command
=
(
Command
)
cache
.
getObject
(
id
,
false
);
setParameters
(
command
);
setParameters
(
command
);
boolean
supportsGeneratedKeys
=
clientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_17
;
boolean
writeGeneratedKeys
=
supportsGeneratedKeys
;
Object
generatedKeysRequest
;
if
(
supportsGeneratedKeys
)
{
int
mode
=
transfer
.
readInt
();
switch
(
mode
)
{
case
GeneratedKeysMode
.
NONE
:
generatedKeysRequest
=
false
;
writeGeneratedKeys
=
false
;
break
;
case
GeneratedKeysMode
.
AUTO
:
generatedKeysRequest
=
true
;
break
;
case
GeneratedKeysMode
.
COLUMN_NUMBERS
:
{
int
len
=
transfer
.
readInt
();
int
[]
keys
=
new
int
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
keys
[
i
]
=
transfer
.
readInt
();
}
generatedKeysRequest
=
keys
;
break
;
}
case
GeneratedKeysMode
.
COLUMN_NAMES
:
{
int
len
=
transfer
.
readInt
();
String
[]
keys
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
keys
[
i
]
=
transfer
.
readString
();
}
generatedKeysRequest
=
keys
;
break
;
}
default
:
throw
DbException
.
get
(
ErrorCode
.
CONNECTION_BROKEN_1
,
"Unsupported generated keys' mode "
+
mode
);
}
}
else
{
generatedKeysRequest
=
false
;
}
int
old
=
session
.
getModificationId
();
int
old
=
session
.
getModificationId
();
int
updateCoun
t
;
ResultWithGeneratedKeys
resul
t
;
synchronized
(
session
)
{
synchronized
(
session
)
{
updateCount
=
command
.
executeUpdate
(
);
result
=
command
.
executeUpdate
(
generatedKeysRequest
);
}
}
int
status
;
int
status
;
if
(
session
.
isClosed
())
{
if
(
session
.
isClosed
())
{
...
@@ -365,8 +405,22 @@ public class TcpServerThread implements Runnable {
...
@@ -365,8 +405,22 @@ public class TcpServerThread implements Runnable {
}
else
{
}
else
{
status
=
getState
(
old
);
status
=
getState
(
old
);
}
}
transfer
.
writeInt
(
status
).
writeInt
(
updateCount
).
transfer
.
writeInt
(
status
).
writeInt
(
result
.
getUpdateCount
()
).
writeBoolean
(
session
.
getAutoCommit
());
writeBoolean
(
session
.
getAutoCommit
());
if
(
writeGeneratedKeys
)
{
ResultInterface
generatedKeys
=
result
.
getGeneratedKeys
();
int
columnCount
=
generatedKeys
.
getVisibleColumnCount
();
transfer
.
writeInt
(
columnCount
);
int
rowCount
=
generatedKeys
.
getRowCount
();
transfer
.
writeInt
(
rowCount
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
ResultColumn
.
writeColumn
(
transfer
,
generatedKeys
,
i
);
}
for
(
int
i
=
0
;
i
<
rowCount
;
i
++)
{
sendRow
(
generatedKeys
);
}
generatedKeys
.
close
();
}
transfer
.
flush
();
transfer
.
flush
();
break
;
break
;
}
}
...
...
h2/src/main/org/h2/server/web/WebApp.java
浏览文件 @
47ed036f
...
@@ -1284,7 +1284,7 @@ public class WebApp {
...
@@ -1284,7 +1284,7 @@ public class WebApp {
ResultSet
rs
;
ResultSet
rs
;
long
time
=
System
.
currentTimeMillis
();
long
time
=
System
.
currentTimeMillis
();
boolean
metadata
=
false
;
boolean
metadata
=
false
;
boolean
generatedKeys
=
false
;
int
generatedKeys
=
Statement
.
NO_GENERATED_KEYS
;
boolean
edit
=
false
;
boolean
edit
=
false
;
boolean
list
=
false
;
boolean
list
=
false
;
if
(
isBuiltIn
(
sql
,
"@autocommit_true"
))
{
if
(
isBuiltIn
(
sql
,
"@autocommit_true"
))
{
...
@@ -1316,7 +1316,7 @@ public class WebApp {
...
@@ -1316,7 +1316,7 @@ public class WebApp {
sql
=
sql
.
substring
(
"@meta"
.
length
()).
trim
();
sql
=
sql
.
substring
(
"@meta"
.
length
()).
trim
();
}
}
if
(
isBuiltIn
(
sql
,
"@generated"
))
{
if
(
isBuiltIn
(
sql
,
"@generated"
))
{
generatedKeys
=
true
;
generatedKeys
=
Statement
.
RETURN_GENERATED_KEYS
;
sql
=
sql
.
substring
(
"@generated"
.
length
()).
trim
();
sql
=
sql
.
substring
(
"@generated"
.
length
()).
trim
();
}
else
if
(
isBuiltIn
(
sql
,
"@history"
))
{
}
else
if
(
isBuiltIn
(
sql
,
"@history"
))
{
buff
.
append
(
getCommandHistoryString
());
buff
.
append
(
getCommandHistoryString
());
...
@@ -1385,9 +1385,9 @@ public class WebApp {
...
@@ -1385,9 +1385,9 @@ public class WebApp {
int
maxrows
=
getMaxrows
();
int
maxrows
=
getMaxrows
();
stat
.
setMaxRows
(
maxrows
);
stat
.
setMaxRows
(
maxrows
);
session
.
executingStatement
=
stat
;
session
.
executingStatement
=
stat
;
boolean
isResultSet
=
stat
.
execute
(
sql
);
boolean
isResultSet
=
stat
.
execute
(
sql
,
generatedKeys
);
session
.
addCommand
(
sql
);
session
.
addCommand
(
sql
);
if
(
generatedKeys
)
{
if
(
generatedKeys
==
Statement
.
RETURN_GENERATED_KEYS
)
{
rs
=
null
;
rs
=
null
;
rs
=
stat
.
getGeneratedKeys
();
rs
=
stat
.
getGeneratedKeys
();
}
else
{
}
else
{
...
...
h2/src/main/org/h2/store/FileLock.java
浏览文件 @
47ed036f
...
@@ -210,8 +210,8 @@ public class FileLock implements Runnable {
...
@@ -210,8 +210,8 @@ public class FileLock implements Runnable {
Constants
.
DEFAULT_TCP_PORT
,
false
);
Constants
.
DEFAULT_TCP_PORT
,
false
);
Transfer
transfer
=
new
Transfer
(
null
,
socket
);
Transfer
transfer
=
new
Transfer
(
null
,
socket
);
transfer
.
init
();
transfer
.
init
();
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
6
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MIN_SUPPORTED
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
16
);
transfer
.
writeInt
(
Constants
.
TCP_PROTOCOL_VERSION_
MAX_SUPPORTED
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
null
);
transfer
.
writeString
(
id
);
transfer
.
writeString
(
id
);
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
47ed036f
...
@@ -321,6 +321,7 @@ public class Column {
...
@@ -321,6 +321,7 @@ public class Column {
value
=
ValueNull
.
INSTANCE
;
value
=
ValueNull
.
INSTANCE
;
}
else
{
}
else
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
session
.
getGeneratedKeys
().
add
(
this
);
if
(
primaryKey
)
{
if
(
primaryKey
)
{
session
.
setLastIdentity
(
value
);
session
.
setLastIdentity
(
value
);
}
}
...
@@ -330,6 +331,7 @@ public class Column {
...
@@ -330,6 +331,7 @@ public class Column {
if
(
value
==
ValueNull
.
INSTANCE
)
{
if
(
value
==
ValueNull
.
INSTANCE
)
{
if
(
convertNullToDefault
)
{
if
(
convertNullToDefault
)
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
type
);
session
.
getGeneratedKeys
().
add
(
this
);
}
}
if
(
value
==
ValueNull
.
INSTANCE
&&
!
nullable
)
{
if
(
value
==
ValueNull
.
INSTANCE
&&
!
nullable
)
{
if
(
mode
.
convertInsertNullToZero
)
{
if
(
mode
.
convertInsertNullToZero
)
{
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
47ed036f
...
@@ -1026,7 +1026,7 @@ public abstract class Table extends SchemaObjectBase {
...
@@ -1026,7 +1026,7 @@ public abstract class Table extends SchemaObjectBase {
boolean
beforeAction
,
boolean
rollback
)
{
boolean
beforeAction
,
boolean
rollback
)
{
if
(
triggers
!=
null
)
{
if
(
triggers
!=
null
)
{
for
(
TriggerObject
trigger
:
triggers
)
{
for
(
TriggerObject
trigger
:
triggers
)
{
boolean
done
=
trigger
.
fireRow
(
session
,
oldRow
,
newRow
,
beforeAction
,
rollback
);
boolean
done
=
trigger
.
fireRow
(
session
,
this
,
oldRow
,
newRow
,
beforeAction
,
rollback
);
if
(
done
)
{
if
(
done
)
{
return
true
;
return
true
;
}
}
...
...
h2/src/main/org/h2/util/MergedResultSet.java
0 → 100644
浏览文件 @
47ed036f
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
util
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.h2.tools.SimpleResultSet
;
/**
* Merged result set. Used to combine several result sets into one. Merged
* result set will contain rows from all appended result sets. Result sets are
* not required to have the same lists of columns, but required to have
* compatible column definitions, for example, if one result set has a
* {@link java.sql.Types#VARCHAR} column {@code NAME} then another results sets
* that have {@code NAME} column should also define it with the same type.
*/
public
final
class
MergedResultSet
{
/**
* Metadata of a column.
*/
private
static
final
class
ColumnInfo
{
final
String
name
;
final
int
type
;
final
int
precision
;
final
int
scale
;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
ColumnInfo
(
String
name
,
int
type
,
int
precision
,
int
scale
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
precision
=
precision
;
this
.
scale
=
scale
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
ColumnInfo
other
=
(
ColumnInfo
)
obj
;
return
name
.
equals
(
other
.
name
);
}
@Override
public
int
hashCode
()
{
return
name
.
hashCode
();
}
}
private
final
ArrayList
<
Map
<
ColumnInfo
,
Object
>>
data
=
New
.
arrayList
();
private
final
ArrayList
<
ColumnInfo
>
columns
=
New
.
arrayList
();
/**
* Appends a result set.
*
* @param rs
* result set to append
* @throws SQLException
* on SQL exception
*/
public
void
add
(
ResultSet
rs
)
throws
SQLException
{
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
cols
=
meta
.
getColumnCount
();
if
(
cols
==
0
)
{
return
;
}
ColumnInfo
[]
info
=
new
ColumnInfo
[
cols
];
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
new
ColumnInfo
(
meta
.
getColumnName
(
i
),
meta
.
getColumnType
(
i
),
meta
.
getPrecision
(
i
),
meta
.
getScale
(
i
));
info
[
i
-
1
]
=
ci
;
if
(!
columns
.
contains
(
ci
))
{
columns
.
add
(
ci
);
}
}
while
(
rs
.
next
())
{
if
(
cols
==
1
)
{
data
.
add
(
Collections
.
singletonMap
(
info
[
0
],
rs
.
getObject
(
1
)));
}
else
{
HashMap
<
ColumnInfo
,
Object
>
map
=
new
HashMap
<>();
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
info
[
i
-
1
];
map
.
put
(
ci
,
rs
.
getObject
(
i
));
}
data
.
add
(
map
);
}
}
}
/**
* Returns merged results set.
*
* @return result set with rows from all appended result sets
*/
public
SimpleResultSet
getResult
()
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
for
(
ColumnInfo
ci
:
columns
)
{
rs
.
addColumn
(
ci
.
name
,
ci
.
type
,
ci
.
precision
,
ci
.
scale
);
}
for
(
Map
<
ColumnInfo
,
Object
>
map
:
data
)
{
Object
[]
row
=
new
Object
[
columns
.
size
()];
for
(
Map
.
Entry
<
ColumnInfo
,
Object
>
entry
:
map
.
entrySet
())
{
row
[
columns
.
indexOf
(
entry
.
getKey
())]
=
entry
.
getValue
();
}
rs
.
addRow
(
row
);
}
return
rs
;
}
@Override
public
String
toString
()
{
return
columns
+
": "
+
data
.
size
();
}
}
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
47ed036f
...
@@ -97,6 +97,7 @@ import org.h2.test.jdbc.TestConnection;
...
@@ -97,6 +97,7 @@ import org.h2.test.jdbc.TestConnection;
import
org.h2.test.jdbc.TestCustomDataTypesHandler
;
import
org.h2.test.jdbc.TestCustomDataTypesHandler
;
import
org.h2.test.jdbc.TestDatabaseEventListener
;
import
org.h2.test.jdbc.TestDatabaseEventListener
;
import
org.h2.test.jdbc.TestDriver
;
import
org.h2.test.jdbc.TestDriver
;
import
org.h2.test.jdbc.TestGetGeneratedKeys
;
import
org.h2.test.jdbc.TestJavaObject
;
import
org.h2.test.jdbc.TestJavaObject
;
import
org.h2.test.jdbc.TestJavaObjectSerializer
;
import
org.h2.test.jdbc.TestJavaObjectSerializer
;
import
org.h2.test.jdbc.TestLimitUpdates
;
import
org.h2.test.jdbc.TestLimitUpdates
;
...
@@ -814,6 +815,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -814,6 +815,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest
(
new
TestPreparedStatement
());
addTest
(
new
TestPreparedStatement
());
addTest
(
new
TestResultSet
());
addTest
(
new
TestResultSet
());
addTest
(
new
TestStatement
());
addTest
(
new
TestStatement
());
addTest
(
new
TestGetGeneratedKeys
());
addTest
(
new
TestTransactionIsolation
());
addTest
(
new
TestTransactionIsolation
());
addTest
(
new
TestUpdatableResultSet
());
addTest
(
new
TestUpdatableResultSet
());
addTest
(
new
TestZloty
());
addTest
(
new
TestZloty
());
...
...
h2/src/test/org/h2/test/db/TestTriggersConstraints.java
浏览文件 @
47ed036f
...
@@ -227,7 +227,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
...
@@ -227,7 +227,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
assertEquals
(
1
,
count
);
assertEquals
(
1
,
count
);
ResultSet
gkRs
;
ResultSet
gkRs
;
gkRs
=
pstat
.
getGeneratedKeys
(
);
gkRs
=
stat
.
executeQuery
(
"select scope_identity()"
);
assertTrue
(
gkRs
.
next
());
assertTrue
(
gkRs
.
next
());
assertEquals
(
1
,
gkRs
.
getInt
(
1
));
assertEquals
(
1
,
gkRs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
0 → 100644
浏览文件 @
47ed036f
差异被折叠。
点击展开。
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
47ed036f
...
@@ -27,6 +27,7 @@ import java.sql.Types;
...
@@ -27,6 +27,7 @@ import java.sql.Types;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.GregorianCalendar
;
import
java.util.UUID
;
import
java.util.UUID
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.Trigger
;
import
org.h2.api.Trigger
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
...
@@ -83,15 +84,12 @@ public class TestPreparedStatement extends TestBase {
...
@@ -83,15 +84,12 @@ public class TestPreparedStatement extends TestBase {
testOffsetDateTime8
(
conn
);
testOffsetDateTime8
(
conn
);
testInstant8
(
conn
);
testInstant8
(
conn
);
testArray
(
conn
);
testArray
(
conn
);
testUUIDGeneratedKeys
(
conn
);
testSetObject
(
conn
);
testSetObject
(
conn
);
testPreparedSubquery
(
conn
);
testPreparedSubquery
(
conn
);
testLikeIndex
(
conn
);
testLikeIndex
(
conn
);
testCasewhen
(
conn
);
testCasewhen
(
conn
);
testSubquery
(
conn
);
testSubquery
(
conn
);
testObject
(
conn
);
testObject
(
conn
);
testIdentity
(
conn
);
testBatchGeneratedKeys
(
conn
);
testDataTypes
(
conn
);
testDataTypes
(
conn
);
testGetMoreResults
(
conn
);
testGetMoreResults
(
conn
);
testBlob
(
conn
);
testBlob
(
conn
);
...
@@ -521,21 +519,6 @@ public class TestPreparedStatement extends TestBase {
...
@@ -521,21 +519,6 @@ public class TestPreparedStatement extends TestBase {
stat
.
execute
(
"drop table test_uuid"
);
stat
.
execute
(
"drop table test_uuid"
);
}
}
private
void
testUUIDGeneratedKeys
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST_UUID(id UUID DEFAULT "
+
"random_UUID() PRIMARY KEY)"
);
stat
.
execute
(
"INSERT INTO TEST_UUID() VALUES()"
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
byte
[]
data
=
rs
.
getBytes
(
1
);
assertEquals
(
16
,
data
.
length
);
stat
.
execute
(
"INSERT INTO TEST_UUID VALUES(random_UUID())"
);
rs
=
stat
.
getGeneratedKeys
();
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST_UUID"
);
}
/**
/**
* A trigger that creates a sequence value.
* A trigger that creates a sequence value.
*/
*/
...
@@ -572,12 +555,17 @@ public class TestPreparedStatement extends TestBase {
...
@@ -572,12 +555,17 @@ public class TestPreparedStatement extends TestBase {
stat
.
execute
(
"create sequence seq start with 1000"
);
stat
.
execute
(
"create sequence seq start with 1000"
);
stat
.
execute
(
"create trigger test_ins after insert on test call \""
+
stat
.
execute
(
"create trigger test_ins after insert on test call \""
+
SequenceTrigger
.
class
.
getName
()
+
"\""
);
SequenceTrigger
.
class
.
getName
()
+
"\""
);
stat
.
execute
(
"insert into test values(null)"
);
stat
.
execute
(
"insert into test values(null)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
rs
.
next
();
// Generated key
assertEquals
(
1
,
rs
.
getLong
(
1
));
assertEquals
(
1
,
rs
.
getLong
(
1
));
stat
.
execute
(
"insert into test values(100)"
);
stat
.
execute
(
"insert into test values(100)"
);
rs
=
stat
.
getGeneratedKeys
();
rs
=
stat
.
getGeneratedKeys
();
// No generated keys
assertFalse
(
rs
.
next
());
// Value from sequence from trigger
rs
=
stat
.
executeQuery
(
"select scope_identity()"
);
rs
.
next
();
rs
.
next
();
assertEquals
(
100
,
rs
.
getLong
(
1
));
assertEquals
(
100
,
rs
.
getLong
(
1
));
stat
.
execute
(
"drop sequence seq"
);
stat
.
execute
(
"drop sequence seq"
);
...
@@ -1263,83 +1251,6 @@ public class TestPreparedStatement extends TestBase {
...
@@ -1263,83 +1251,6 @@ public class TestPreparedStatement extends TestBase {
}
}
private
void
testIdentity
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
PreparedStatement
prep
;
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
prep
.
execute
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
int
[]
{
1
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
3
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
new
String
[]
{
"ID"
});
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
4
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
ResultSet
.
TYPE_FORWARD_ONLY
,
ResultSet
.
CONCUR_READ_ONLY
,
ResultSet
.
HOLD_CURSORS_OVER_COMMIT
);
prep
.
execute
();
rs
=
prep
.
getGeneratedKeys
();
rs
.
next
();
assertEquals
(
5
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
}
private
void
testBatchGeneratedKeys
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
keys
=
prep
.
getGeneratedKeys
();
keys
.
next
();
assertEquals
(
1
,
keys
.
getLong
(
1
));
keys
.
next
();
assertEquals
(
2
,
keys
.
getLong
(
1
));
keys
.
next
();
assertEquals
(
3
,
keys
.
getLong
(
1
));
assertFalse
(
keys
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"DROP SEQUENCE SEQ"
);
}
private
int
getLength
()
{
private
int
getLength
()
{
return
getSize
(
LOB_SIZE
,
LOB_SIZE_BIG
);
return
getSize
(
LOB_SIZE
,
LOB_SIZE_BIG
);
}
}
...
...
h2/src/test/org/h2/test/jdbc/TestResultSet.java
浏览文件 @
47ed036f
...
@@ -573,12 +573,14 @@ public class TestResultSet extends TestBase {
...
@@ -573,12 +573,14 @@ public class TestResultSet extends TestBase {
ResultSet
rs
;
ResultSet
rs
;
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)"
);
stat
.
execute
(
"CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello')"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello')"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
rs
=
stat
.
getGeneratedKeys
();
assertTrue
(
rs
.
next
());
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
1
,
rs
.
getInt
(
1
));
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('World')"
);
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('World')"
,
Statement
.
RETURN_GENERATED_KEYS
);
rs
=
stat
.
getGeneratedKeys
();
rs
=
stat
.
getGeneratedKeys
();
assertTrue
(
rs
.
next
());
assertTrue
(
rs
.
next
());
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertEquals
(
2
,
rs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/jdbc/TestStatement.java
浏览文件 @
47ed036f
...
@@ -351,16 +351,19 @@ public class TestStatement extends TestBase {
...
@@ -351,16 +351,19 @@ public class TestStatement extends TestBase {
stat
.
execute
(
"create table test1(id identity, x int)"
);
stat
.
execute
(
"create table test1(id identity, x int)"
);
stat
.
execute
(
"drop table if exists test2"
);
stat
.
execute
(
"drop table if exists test2"
);
stat
.
execute
(
"create table test2(id identity, x int)"
);
stat
.
execute
(
"create table test2(id identity, x int)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
keys
;
ResultSet
keys
;
keys
=
stat
.
getGeneratedKeys
();
keys
=
stat
.
getGeneratedKeys
();
keys
.
next
();
keys
.
next
();
assertEquals
(
1
,
keys
.
getInt
(
1
));
assertEquals
(
1
,
keys
.
getInt
(
1
));
stat
.
execute
(
"insert into test2(x) values(10), (11), (12)"
);
stat
.
execute
(
"insert into test2(x) values(10), (11), (12)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(5)"
,
Statement
.
RETURN_GENERATED_KEYS
);
keys
=
stat
.
getGeneratedKeys
();
keys
=
stat
.
getGeneratedKeys
();
assertFalse
(
keys
.
next
());
assertFalse
(
keys
.
next
());
stat
.
execute
(
"merge into test1(x) key(x) values(6)"
);
stat
.
execute
(
"merge into test1(x) key(x) values(6)"
,
Statement
.
RETURN_GENERATED_KEYS
);
keys
=
stat
.
getGeneratedKeys
();
keys
=
stat
.
getGeneratedKeys
();
keys
.
next
();
keys
.
next
();
assertEquals
(
2
,
keys
.
getInt
(
1
));
assertEquals
(
2
,
keys
.
getInt
(
1
));
...
@@ -371,7 +374,8 @@ public class TestStatement extends TestBase {
...
@@ -371,7 +374,8 @@ public class TestStatement extends TestBase {
Statement
stat
=
conn
.
createStatement
();
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE SEQUENCE SEQ"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"
,
Statement
.
RETURN_GENERATED_KEYS
);
ResultSet
rs
=
stat
.
getGeneratedKeys
();
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
rs
.
next
();
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
1
,
rs
.
getInt
(
1
));
...
...
h2/src/test/org/h2/test/server/TestWeb.java
浏览文件 @
47ed036f
...
@@ -447,7 +447,7 @@ public class TestWeb extends TestBase {
...
@@ -447,7 +447,7 @@ public class TestWeb extends TestBase {
assertContains
(
result
,
"There is currently no running statement"
);
assertContains
(
result
,
"There is currently no running statement"
);
result
=
client
.
get
(
url
,
result
=
client
.
get
(
url
,
"query.do?sql=@generated insert into test(id) values(test_sequence.nextval)"
);
"query.do?sql=@generated insert into test(id) values(test_sequence.nextval)"
);
assertContains
(
result
,
"
SCOPE_IDENTITY()
"
);
assertContains
(
result
,
"
<tr><th>ID</th></tr><tr><td>1</td></tr>
"
);
result
=
client
.
get
(
url
,
"query.do?sql=@maxrows 2000"
);
result
=
client
.
get
(
url
,
"query.do?sql=@maxrows 2000"
);
assertContains
(
result
,
"Max rowcount is set"
);
assertContains
(
result
,
"Max rowcount is set"
);
result
=
client
.
get
(
url
,
"query.do?sql=@password_hash user password"
);
result
=
client
.
get
(
url
,
"query.do?sql=@password_hash user password"
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论