Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
0707251f
提交
0707251f
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix prepared statements with multiple commands with parameters
上级
6666417b
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
85 行增加
和
35 行删除
+85
-35
changelog.html
h2/src/docsrc/html/changelog.html
+2
-0
CommandList.java
h2/src/main/org/h2/command/CommandList.java
+20
-17
Parser.java
h2/src/main/org/h2/command/Parser.java
+35
-18
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+28
-0
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
0707251f
...
@@ -21,6 +21,8 @@ Change Log
...
@@ -21,6 +21,8 @@ Change Log
<h2>
Next Version (unreleased)
</h2>
<h2>
Next Version (unreleased)
</h2>
<ul>
<ul>
<li>
Issue #1590: Error on executing "DELETE FROM table1 WHERE ID = ?; DELETE FROM table2 WHERE ID = ?;"
</li>
<li>
Issue #1727: Support ISODOW as identifier for the extract function additional to ISO_DAY_OF_WEEK
<li>
Issue #1727: Support ISODOW as identifier for the extract function additional to ISO_DAY_OF_WEEK
</li>
</li>
<li>
PR #1580, #1726: Disable remote database creation by default
<li>
PR #1580, #1726: Disable remote database creation by default
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/CommandList.java
浏览文件 @
0707251f
...
@@ -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.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.expression.ParameterInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
...
@@ -16,51 +17,53 @@ import org.h2.result.ResultInterface;
...
@@ -16,51 +17,53 @@ import org.h2.result.ResultInterface;
*/
*/
class
CommandList
extends
Command
{
class
CommandList
extends
Command
{
private
final
Command
command
;
private
final
ArrayList
<
Command
>
commands
;
private
final
String
remaining
;
private
final
ArrayList
<
Parameter
>
parameters
;
CommandList
(
Session
session
,
String
sql
,
Command
c
,
String
remaining
)
{
CommandList
(
Session
session
,
String
sql
,
ArrayList
<
Command
>
commands
,
ArrayList
<
Parameter
>
parameters
)
{
super
(
session
,
sql
);
super
(
session
,
sql
);
this
.
command
=
c
;
this
.
command
s
=
commands
;
this
.
remaining
=
remaining
;
this
.
parameters
=
parameters
;
}
}
@Override
@Override
public
ArrayList
<?
extends
ParameterInterface
>
getParameters
()
{
public
ArrayList
<?
extends
ParameterInterface
>
getParameters
()
{
return
command
.
getParameters
()
;
return
parameters
;
}
}
private
void
executeRemaining
()
{
private
void
executeRemaining
()
{
Command
remainingCommand
=
session
.
prepareLocal
(
remaining
);
for
(
int
i
=
1
,
l
=
commands
.
size
();
i
<
l
;
i
++)
{
if
(
remainingCommand
.
isQuery
())
{
Command
command
=
commands
.
get
(
i
);
remainingCommand
.
query
(
0
);
if
(
command
.
isQuery
())
{
}
else
{
command
.
query
(
0
);
remainingCommand
.
update
();
}
else
{
command
.
update
();
}
}
}
}
}
@Override
@Override
public
int
update
()
{
public
int
update
()
{
int
updateCount
=
command
.
executeUpdate
(
false
).
getUpdateCount
();
int
updateCount
=
command
s
.
get
(
0
)
.
executeUpdate
(
false
).
getUpdateCount
();
executeRemaining
();
executeRemaining
();
return
updateCount
;
return
updateCount
;
}
}
@Override
@Override
public
void
prepareJoinBatch
()
{
public
void
prepareJoinBatch
()
{
command
.
prepareJoinBatch
();
command
s
.
get
(
0
)
.
prepareJoinBatch
();
}
}
@Override
@Override
public
ResultInterface
query
(
int
maxrows
)
{
public
ResultInterface
query
(
int
maxrows
)
{
ResultInterface
result
=
command
.
query
(
maxrows
);
ResultInterface
result
=
command
s
.
get
(
0
)
.
query
(
maxrows
);
executeRemaining
();
executeRemaining
();
return
result
;
return
result
;
}
}
@Override
@Override
public
boolean
isQuery
()
{
public
boolean
isQuery
()
{
return
command
.
isQuery
();
return
command
s
.
get
(
0
)
.
isQuery
();
}
}
@Override
@Override
...
@@ -75,12 +78,12 @@ class CommandList extends Command {
...
@@ -75,12 +78,12 @@ class CommandList extends Command {
@Override
@Override
public
ResultInterface
queryMeta
()
{
public
ResultInterface
queryMeta
()
{
return
command
.
queryMeta
();
return
command
s
.
get
(
0
)
.
queryMeta
();
}
}
@Override
@Override
public
int
getCommandType
()
{
public
int
getCommandType
()
{
return
command
.
getCommandType
();
return
command
s
.
get
(
0
)
.
getCommandType
();
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/Parser.java
浏览文件 @
0707251f
...
@@ -634,14 +634,15 @@ public class Parser {
...
@@ -634,14 +634,15 @@ public class Parser {
private
Prepared
currentPrepared
;
private
Prepared
currentPrepared
;
private
Select
currentSelect
;
private
Select
currentSelect
;
private
ArrayList
<
Parameter
>
parameters
;
private
ArrayList
<
Parameter
>
parameters
;
private
ArrayList
<
Parameter
>
indexedParameterList
;
private
ArrayList
<
Parameter
>
suppliedParameters
;
private
ArrayList
<
Parameter
>
suppliedParameterList
;
private
String
schemaName
;
private
String
schemaName
;
private
ArrayList
<
String
>
expectedList
;
private
ArrayList
<
String
>
expectedList
;
private
boolean
rightsChecked
;
private
boolean
rightsChecked
;
private
boolean
recompileAlways
;
private
boolean
recompileAlways
;
private
boolean
literalsChecked
;
private
boolean
literalsChecked
;
private
ArrayList
<
Parameter
>
indexedParameterList
;
private
int
orderInFrom
;
private
int
orderInFrom
;
private
ArrayList
<
Parameter
>
suppliedParameterList
;
public
Parser
(
Session
session
)
{
public
Parser
(
Session
session
)
{
this
.
database
=
session
.
getDatabase
();
this
.
database
=
session
.
getDatabase
();
...
@@ -672,22 +673,11 @@ public class Parser {
...
@@ -672,22 +673,11 @@ public class Parser {
*/
*/
public
Command
prepareCommand
(
String
sql
)
{
public
Command
prepareCommand
(
String
sql
)
{
try
{
try
{
Prepared
p
=
parse
(
sql
);
Command
c
=
prepareSingleCommand
(
sql
);
boolean
hasMore
=
isToken
(
SEMICOLON
);
if
(
currentTokenType
==
SEMICOLON
)
{
if
(!
hasMore
&&
currentTokenType
!=
END
)
{
throw
getSyntaxError
();
}
try
{
p
.
prepare
();
}
catch
(
Throwable
t
)
{
CommandContainer
.
clearCTE
(
session
,
p
);
throw
t
;
}
Command
c
=
new
CommandContainer
(
session
,
sql
,
p
);
if
(
hasMore
)
{
String
remaining
=
originalSQL
.
substring
(
parseIndex
);
String
remaining
=
originalSQL
.
substring
(
parseIndex
);
if
(!
StringUtils
.
isWhitespaceOrEmpty
(
remaining
))
{
if
(!
StringUtils
.
isWhitespaceOrEmpty
(
remaining
))
{
c
=
new
CommandList
(
session
,
sql
,
c
,
remaining
);
c
=
prepareCommandList
(
c
,
sql
,
remaining
);
}
}
}
}
return
c
;
return
c
;
...
@@ -696,6 +686,33 @@ public class Parser {
...
@@ -696,6 +686,33 @@ public class Parser {
}
}
}
}
private
Command
prepareCommandList
(
Command
c
,
String
sql
,
String
remaining
)
{
ArrayList
<
Command
>
list
=
Utils
.
newSmallArrayList
();
list
.
add
(
c
);
do
{
suppliedParameters
=
parameters
;
suppliedParameterList
=
indexedParameterList
;
list
.
add
(
prepareSingleCommand
(
remaining
));
}
while
(
currentTokenType
==
SEMICOLON
&&
!
StringUtils
.
isWhitespaceOrEmpty
(
remaining
=
originalSQL
.
substring
(
parseIndex
)));
return
new
CommandList
(
session
,
sql
,
list
,
parameters
);
}
private
Command
prepareSingleCommand
(
String
sql
)
{
Prepared
p
=
parse
(
sql
);
if
(
currentTokenType
!=
SEMICOLON
&&
currentTokenType
!=
END
)
{
addExpected
(
SEMICOLON
);
throw
getSyntaxError
();
}
try
{
p
.
prepare
();
}
catch
(
Throwable
t
)
{
CommandContainer
.
clearCTE
(
session
,
p
);
throw
t
;
}
return
new
CommandContainer
(
session
,
sql
,
p
);
}
/**
/**
* Parse the statement, but don't prepare it for execution.
* Parse the statement, but don't prepare it for execution.
*
*
...
@@ -727,12 +744,12 @@ public class Parser {
...
@@ -727,12 +744,12 @@ public class Parser {
}
else
{
}
else
{
expectedList
=
null
;
expectedList
=
null
;
}
}
parameters
=
Utils
.
newSmallArrayList
();
parameters
=
suppliedParameters
!=
null
?
suppliedParameters
:
Utils
.<
Parameter
>
newSmallArrayList
();
indexedParameterList
=
suppliedParameterList
;
currentSelect
=
null
;
currentSelect
=
null
;
currentPrepared
=
null
;
currentPrepared
=
null
;
createView
=
null
;
createView
=
null
;
recompileAlways
=
false
;
recompileAlways
=
false
;
indexedParameterList
=
suppliedParameterList
;
read
();
read
();
return
parsePrepared
();
return
parsePrepared
();
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
0707251f
...
@@ -199,6 +199,7 @@ public class TestPreparedStatement extends TestDb {
...
@@ -199,6 +199,7 @@ public class TestPreparedStatement extends TestDb {
testColumnMetaDataWithEquals
(
conn
);
testColumnMetaDataWithEquals
(
conn
);
testColumnMetaDataWithIn
(
conn
);
testColumnMetaDataWithIn
(
conn
);
testValueResultSet
(
conn
);
testValueResultSet
(
conn
);
testMultipleStatements
(
conn
);
conn
.
close
();
conn
.
close
();
testPreparedStatementWithLiteralsNone
();
testPreparedStatementWithLiteralsNone
();
testPreparedStatementWithIndexedParameterAndLiteralsNone
();
testPreparedStatementWithIndexedParameterAndLiteralsNone
();
...
@@ -1758,4 +1759,31 @@ public class TestPreparedStatement extends TestDb {
...
@@ -1758,4 +1759,31 @@ public class TestPreparedStatement extends TestDb {
}
}
}
}
private
void
testMultipleStatements
(
Connection
conn
)
throws
SQLException
{
assertThrows
(
ErrorCode
.
CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS
,
conn
).
prepareStatement
(
"SELECT ?; SELECT ?1"
);
assertThrows
(
ErrorCode
.
CANNOT_MIX_INDEXED_AND_UNINDEXED_PARAMS
,
conn
).
prepareStatement
(
"SELECT ?1; SELECT ?"
);
Statement
stmt
=
conn
.
createStatement
();
stmt
.
execute
(
"CREATE TABLE TEST (ID IDENTITY, V INT)"
);
PreparedStatement
ps
=
conn
.
prepareStatement
(
"INSERT INTO TEST(V) VALUES ?; INSERT INTO TEST(V) VALUES ?"
);
ps
.
setInt
(
1
,
1
);
ps
.
setInt
(
2
,
2
);
ps
.
executeUpdate
();
ps
=
conn
.
prepareStatement
(
"INSERT INTO TEST(V) VALUES ?2; INSERT INTO TEST(V) VALUES ?1;"
);
ps
.
setInt
(
1
,
3
);
ps
.
setInt
(
2
,
4
);
ps
.
executeUpdate
();
try
(
ResultSet
rs
=
stmt
.
executeQuery
(
"SELECT V FROM TEST ORDER BY ID"
))
{
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
4
,
rs
.
getInt
(
1
));
assertTrue
(
rs
.
next
());
assertEquals
(
3
,
rs
.
getInt
(
1
));
assertFalse
(
rs
.
next
());
}
stmt
.
execute
(
"DROP TABLE TEST"
);
}
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论