Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
5b21a636
提交
5b21a636
authored
8 年前
作者:
Thomas Mueller
提交者:
GitHub
8 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #488 from svladykin/lazyQuery
Lazy query execution support
上级
676c9f13
6049065a
全部展开
显示空白字符变更
内嵌
并排
正在显示
44 个修改的文件
包含
928 行增加
和
231 行删除
+928
-231
Command.java
h2/src/main/org/h2/command/Command.java
+5
-3
CommandContainer.java
h2/src/main/org/h2/command/CommandContainer.java
+1
-1
CommandInterface.java
h2/src/main/org/h2/command/CommandInterface.java
+5
-0
CommandRemote.java
h2/src/main/org/h2/command/CommandRemote.java
+6
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+11
-2
Query.java
h2/src/main/org/h2/command/dml/Query.java
+38
-9
Select.java
h2/src/main/org/h2/command/dml/Select.java
+188
-76
SelectUnion.java
h2/src/main/org/h2/command/dml/SelectUnion.java
+94
-10
Set.java
h2/src/main/org/h2/command/dml/Set.java
+10
-1
SetTypes.java
h2/src/main/org/h2/command/dml/SetTypes.java
+7
-1
Session.java
h2/src/main/org/h2/engine/Session.java
+13
-4
ConditionExists.java
h2/src/main/org/h2/expression/ConditionExists.java
+3
-3
ConditionInSelect.java
h2/src/main/org/h2/expression/ConditionInSelect.java
+4
-4
Subquery.java
h2/src/main/org/h2/expression/Subquery.java
+4
-6
TableFunction.java
h2/src/main/org/h2/expression/TableFunction.java
+1
-2
ViewCursor.java
h2/src/main/org/h2/index/ViewCursor.java
+3
-3
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+6
-4
JdbcConnection.java
h2/src/main/org/h2/jdbc/JdbcConnection.java
+1
-1
JdbcPreparedStatement.java
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
+13
-5
JdbcResultSet.java
h2/src/main/org/h2/jdbc/JdbcResultSet.java
+48
-33
JdbcStatement.java
h2/src/main/org/h2/jdbc/JdbcStatement.java
+29
-8
LazyResult.java
h2/src/main/org/h2/result/LazyResult.java
+195
-0
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+19
-0
ResultInterface.java
h2/src/main/org/h2/result/ResultInterface.java
+45
-0
ResultRemote.java
h2/src/main/org/h2/result/ResultRemote.java
+32
-0
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+2
-2
JoinBatch.java
h2/src/main/org/h2/table/JoinBatch.java
+43
-12
TableView.java
h2/src/main/org/h2/table/TableView.java
+5
-5
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+13
-0
TestBase.java
h2/src/test/org/h2/test/TestBase.java
+25
-3
TestLob.java
h2/src/test/org/h2/test/db/TestLob.java
+6
-0
TestOptimizations.java
h2/src/test/org/h2/test/db/TestOptimizations.java
+3
-0
TestOutOfMemory.java
h2/src/test/org/h2/test/db/TestOutOfMemory.java
+10
-3
TestQueryCache.java
h2/src/test/org/h2/test/db/TestQueryCache.java
+2
-1
TestRecursiveQueries.java
h2/src/test/org/h2/test/db/TestRecursiveQueries.java
+2
-2
TestScript.java
h2/src/test/org/h2/test/db/TestScript.java
+8
-6
TestTableEngines.java
h2/src/test/org/h2/test/db/TestTableEngines.java
+4
-4
TestTempTables.java
h2/src/test/org/h2/test/db/TestTempTables.java
+7
-4
TestCancel.java
h2/src/test/org/h2/test/jdbc/TestCancel.java
+2
-3
TestMetaData.java
h2/src/test/org/h2/test/jdbc/TestMetaData.java
+2
-2
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+3
-3
TestUpdatableResultSet.java
h2/src/test/org/h2/test/jdbc/TestUpdatableResultSet.java
+7
-2
TestHaltApp.java
h2/src/test/org/h2/test/synth/TestHaltApp.java
+2
-2
H2Cursor.java
h2/src/tools/org/h2/android/H2Cursor.java
+1
-1
没有找到文件。
h2/src/main/org/h2/command/Command.java
浏览文件 @
5b21a636
...
...
@@ -21,7 +21,6 @@ import org.h2.util.MathUtils;
* Represents a SQL statement. This object is only used on the server side.
*/
public
abstract
class
Command
implements
CommandInterface
{
/**
* The session.
*/
...
...
@@ -147,7 +146,8 @@ public abstract class Command implements CommandInterface {
}
}
private
void
stop
()
{
@Override
public
void
stop
()
{
session
.
endStatement
();
session
.
setCurrentCommand
(
null
);
if
(!
isTransactional
())
{
...
...
@@ -198,7 +198,9 @@ public abstract class Command implements CommandInterface {
while
(
true
)
{
database
.
checkPowerOff
();
try
{
return
query
(
maxrows
);
ResultInterface
result
=
query
(
maxrows
);
callStop
=
!
result
.
isLazy
();
return
result
;
}
catch
(
DbException
e
)
{
start
=
filterConcurrentUpdate
(
e
,
start
);
}
catch
(
OutOfMemoryError
e
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/CommandContainer.java
浏览文件 @
5b21a636
...
...
@@ -111,7 +111,7 @@ public class CommandContainer extends Command {
start
();
prepared
.
checkParameters
();
ResultInterface
result
=
prepared
.
query
(
maxrows
);
prepared
.
trace
(
startTimeNanos
,
result
.
getRowCount
());
prepared
.
trace
(
startTimeNanos
,
result
.
isLazy
()
?
0
:
result
.
getRowCount
());
setProgress
(
DatabaseEventListener
.
STATE_STATEMENT_END
);
return
result
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/CommandInterface.java
浏览文件 @
5b21a636
...
...
@@ -503,6 +503,11 @@ public interface CommandInterface {
*/
int
executeUpdate
();
/**
* Stop the command execution, release all locks and resources
*/
void
stop
();
/**
* Close the statement.
*/
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/CommandRemote.java
浏览文件 @
5b21a636
...
...
@@ -54,6 +54,12 @@ public class CommandRemote implements CommandInterface {
created
=
session
.
getLastReconnect
();
}
@Override
public
void
stop
()
{
// Must never be called, because remote result is not lazy.
throw
DbException
.
throwInternalError
();
}
private
void
prepare
(
SessionRemote
s
,
boolean
createParams
)
{
id
=
s
.
getNextId
();
for
(
int
i
=
0
,
count
=
0
;
i
<
transferList
.
size
();
i
++)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/Parser.java
浏览文件 @
5b21a636
...
...
@@ -1715,7 +1715,9 @@ public class Parser {
}
}
if
(
isToken
(
"SELECT"
)
||
isToken
(
"FROM"
)
||
isToken
(
"("
)
||
isToken
(
"WITH"
))
{
command
.
setCommand
(
parseSelect
());
Query
query
=
parseSelect
();
query
.
setNeverLazy
(
true
);
command
.
setCommand
(
query
);
}
else
if
(
readIf
(
"DELETE"
))
{
command
.
setCommand
(
parseDelete
());
}
else
if
(
readIf
(
"UPDATE"
))
{
...
...
@@ -1924,7 +1926,10 @@ public class Parser {
return
command
;
}
if
(
readIf
(
"WITH"
))
{
return
parseWith
();
Query
query
=
parseWith
();
// recursive can not be lazy
query
.
setNeverLazy
(
true
);
return
query
;
}
Select
select
=
parseSelectSimple
();
return
select
;
...
...
@@ -2235,6 +2240,10 @@ public class Parser {
}
else
{
if
(
isSelect
())
{
Query
query
=
parseSelect
();
// can not be lazy because we have to call
// method ResultInterface.containsDistinct
// which is not supported for lazy execution
query
.
setNeverLazy
(
true
);
r
=
new
ConditionInSelect
(
database
,
r
,
query
,
false
,
Comparison
.
EQUAL
);
}
else
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/Query.java
浏览文件 @
5b21a636
...
...
@@ -19,7 +19,7 @@ import org.h2.expression.ExpressionVisitor;
import
org.h2.expression.Parameter
;
import
org.h2.expression.ValueExpression
;
import
org.h2.message.DbException
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.result.ResultTarget
;
import
org.h2.result.SortOrder
;
import
org.h2.table.ColumnResolver
;
...
...
@@ -63,14 +63,23 @@ public abstract class Query extends Prepared {
private
boolean
noCache
;
private
int
lastLimit
;
private
long
lastEvaluated
;
private
LocalResult
lastResult
;
private
ResultInterface
lastResult
;
private
Value
[]
lastParameters
;
private
boolean
cacheableChecked
;
private
boolean
neverLazy
;
Query
(
Session
session
)
{
super
(
session
);
}
public
void
setNeverLazy
(
boolean
b
)
{
this
.
neverLazy
=
b
;
}
public
boolean
isNeverLazy
()
{
return
neverLazy
;
}
/**
* Check if this is a UNION query.
*
...
...
@@ -92,9 +101,24 @@ public abstract class Query extends Prepared {
* @param target the target to write results to
* @return the result
*/
protected
abstract
LocalResult
queryWithoutCache
(
int
limit
,
protected
abstract
ResultInterface
queryWithoutCache
(
int
limit
,
ResultTarget
target
);
private
ResultInterface
queryWithoutCacheLazyCheck
(
int
limit
,
ResultTarget
target
)
{
boolean
disableLazy
=
neverLazy
&&
session
.
isLazyQueryExecution
();
if
(
disableLazy
)
{
session
.
setLazyQueryExecution
(
false
);
}
try
{
return
queryWithoutCache
(
limit
,
target
);
}
finally
{
if
(
disableLazy
)
{
session
.
setLazyQueryExecution
(
true
);
}
}
}
/**
* Initialize the query.
*/
...
...
@@ -305,7 +329,7 @@ public abstract class Query extends Prepared {
}
@Override
public
LocalResult
query
(
int
maxrows
)
{
public
final
ResultInterface
query
(
int
maxrows
)
{
return
query
(
maxrows
,
null
);
}
...
...
@@ -316,10 +340,16 @@ public abstract class Query extends Prepared {
* @param target the target result (null will return the result)
* @return the result set (if the target is not set).
*/
LocalResult
query
(
int
limit
,
ResultTarget
target
)
{
public
final
ResultInterface
query
(
int
limit
,
ResultTarget
target
)
{
if
(
isUnion
())
{
// union doesn't always know the parameter list of the left and right
// queries
return
queryWithoutCacheLazyCheck
(
limit
,
target
);
}
fireBeforeSelectTriggers
();
if
(
noCache
||
!
session
.
getDatabase
().
getOptimizeReuseResults
())
{
return
queryWithoutCache
(
limit
,
target
);
if
(
noCache
||
!
session
.
getDatabase
().
getOptimizeReuseResults
()
||
session
.
isLazyQueryExecution
())
{
return
queryWithoutCacheLazyCheck
(
limit
,
target
);
}
Value
[]
params
=
getParameterValues
();
long
now
=
session
.
getDatabase
().
getModificationDataId
();
...
...
@@ -338,7 +368,7 @@ public abstract class Query extends Prepared {
}
lastParameters
=
params
;
closeLastResult
();
LocalResult
r
=
queryWithoutCache
(
limit
,
target
);
ResultInterface
r
=
queryWithoutCacheLazyCheck
(
limit
,
target
);
lastResult
=
r
;
this
.
lastEvaluated
=
now
;
lastLimit
=
limit
;
...
...
@@ -565,5 +595,4 @@ public abstract class Query extends Prepared {
isEverything
(
visitor
);
return
visitor
.
getMaxDataModificationId
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
5b21a636
差异被折叠。
点击展开。
h2/src/main/org/h2/command/dml/SelectUnion.java
浏览文件 @
5b21a636
...
...
@@ -17,6 +17,7 @@ import org.h2.expression.ExpressionVisitor;
import
org.h2.expression.Parameter
;
import
org.h2.expression.ValueExpression
;
import
org.h2.message.DbException
;
import
org.h2.result.LazyResult
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultTarget
;
...
...
@@ -148,7 +149,7 @@ public class SelectUnion extends Query {
}
@Override
protected
LocalResult
queryWithoutCache
(
int
maxRows
,
ResultTarget
target
)
{
protected
ResultInterface
queryWithoutCache
(
int
maxRows
,
ResultTarget
target
)
{
if
(
maxRows
!=
0
)
{
// maxRows is set (maxRows 0 means no limit)
int
l
;
...
...
@@ -177,6 +178,25 @@ public class SelectUnion extends Query {
}
}
int
columnCount
=
left
.
getColumnCount
();
if
(
session
.
isLazyQueryExecution
()
&&
unionType
==
UNION_ALL
&&
!
distinct
&&
sort
==
null
&&
!
randomAccessResult
&&
!
isForUpdate
&&
offsetExpr
==
null
&&
isReadOnly
())
{
int
limit
=
-
1
;
if
(
limitExpr
!=
null
)
{
Value
v
=
limitExpr
.
getValue
(
session
);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
limit
=
v
.
getInt
();
}
}
// limit 0 means no rows
if
(
limit
!=
0
)
{
LazyResultUnion
lazyResult
=
new
LazyResultUnion
(
expressionArray
,
columnCount
);
if
(
limit
>
0
)
{
lazyResult
.
setLimit
(
limit
);
}
return
lazyResult
;
}
}
LocalResult
result
=
new
LocalResult
(
session
,
expressionArray
,
columnCount
);
if
(
sort
!=
null
)
{
result
.
setSortOrder
(
sort
);
...
...
@@ -205,8 +225,8 @@ public class SelectUnion extends Query {
default
:
DbException
.
throwInternalError
(
"type="
+
unionType
);
}
LocalResult
l
=
left
.
query
(
0
);
LocalResult
r
=
right
.
query
(
0
);
ResultInterface
l
=
left
.
query
(
0
);
ResultInterface
r
=
right
.
query
(
0
);
l
.
reset
();
r
.
reset
();
switch
(
unionType
)
{
...
...
@@ -434,13 +454,6 @@ public class SelectUnion extends Query {
return
buff
.
toString
();
}
@Override
public
LocalResult
query
(
int
limit
,
ResultTarget
target
)
{
// union doesn't always know the parameter list of the left and right
// queries
return
queryWithoutCache
(
limit
,
target
);
}
@Override
public
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
return
left
.
isEverything
(
visitor
)
&&
right
.
isEverything
(
visitor
);
...
...
@@ -473,4 +486,75 @@ public class SelectUnion extends Query {
return
left
.
allowGlobalConditions
()
&&
right
.
allowGlobalConditions
();
}
/**
* Lazy execution for this union.
*/
private
final
class
LazyResultUnion
extends
LazyResult
{
int
columnCount
;
ResultInterface
l
;
ResultInterface
r
;
boolean
leftDone
;
boolean
rightDone
;
LazyResultUnion
(
Expression
[]
expressions
,
int
columnCount
)
{
super
(
expressions
);
this
.
columnCount
=
columnCount
;
}
@Override
public
int
getVisibleColumnCount
()
{
return
columnCount
;
}
@Override
protected
Value
[]
fetchNextRow
()
{
if
(
rightDone
)
{
return
null
;
}
if
(!
leftDone
)
{
if
(
l
==
null
)
{
l
=
left
.
query
(
0
);
l
.
reset
();
}
if
(
l
.
next
())
{
return
l
.
currentRow
();
}
leftDone
=
true
;
}
if
(
r
==
null
)
{
r
=
right
.
query
(
0
);
r
.
reset
();
}
if
(
r
.
next
())
{
return
r
.
currentRow
();
}
rightDone
=
true
;
return
null
;
}
@Override
public
void
close
()
{
super
.
close
();
if
(
l
!=
null
)
{
l
.
close
();
}
if
(
r
!=
null
)
{
r
.
close
();
}
}
@Override
public
void
reset
()
{
super
.
reset
();
if
(
l
!=
null
)
{
l
.
reset
();
}
if
(
r
!=
null
)
{
r
.
reset
();
}
leftDone
=
false
;
rightDone
=
false
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/Set.java
浏览文件 @
5b21a636
...
...
@@ -510,11 +510,20 @@ public class Set extends Prepared {
int
value
=
getIntValue
();
if
(
value
!=
0
&&
value
!=
1
)
{
throw
DbException
.
getInvalidValueException
(
"FORCE_JOIN_ORDER"
,
getIntValue
()
);
value
);
}
session
.
setForceJoinOrder
(
value
==
1
);
break
;
}
case
SetTypes
.
LAZY_QUERY_EXECUTION
:
{
int
value
=
getIntValue
();
if
(
value
!=
0
&&
value
!=
1
)
{
throw
DbException
.
getInvalidValueException
(
"LAZY_QUERY_EXECUTION"
,
value
);
}
session
.
setLazyQueryExecution
(
value
==
1
);
break
;
}
default
:
DbException
.
throwInternalError
(
"type="
+
type
);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/command/dml/SetTypes.java
浏览文件 @
5b21a636
...
...
@@ -214,7 +214,7 @@ public class SetTypes {
public
static
final
int
RETENTION_TIME
=
40
;
/**
* The type of a SET QUERY_STATISTICS
_ACTIVE
statement.
* The type of a SET QUERY_STATISTICS statement.
*/
public
static
final
int
QUERY_STATISTICS
=
41
;
...
...
@@ -238,6 +238,11 @@ public class SetTypes {
*/
public
static
final
int
FORCE_JOIN_ORDER
=
45
;
/**
* The type of SET LAZY_QUERY_EXECUTION statement.
*/
public
static
final
int
LAZY_QUERY_EXECUTION
=
46
;
private
static
final
ArrayList
<
String
>
TYPES
=
New
.
arrayList
();
private
SetTypes
()
{
...
...
@@ -292,6 +297,7 @@ public class SetTypes {
list
.
add
(
ROW_FACTORY
,
"ROW_FACTORY"
);
list
.
add
(
BATCH_JOINS
,
"BATCH_JOINS"
);
list
.
add
(
FORCE_JOIN_ORDER
,
"FORCE_JOIN_ORDER"
);
list
.
add
(
LAZY_QUERY_EXECUTION
,
"LAZY_QUERY_EXECUTION"
);
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/engine/Session.java
浏览文件 @
5b21a636
...
...
@@ -31,7 +31,7 @@ import org.h2.message.TraceSystem;
import
org.h2.mvstore.db.MVTable
;
import
org.h2.mvstore.db.TransactionStore.Change
;
import
org.h2.mvstore.db.TransactionStore.Transaction
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
...
...
@@ -108,7 +108,7 @@ public class Session extends SessionWithState {
private
long
transactionStart
;
private
long
currentCommandStart
;
private
HashMap
<
String
,
Value
>
variables
;
private
HashSet
<
LocalResult
>
temporaryResults
;
private
HashSet
<
ResultInterface
>
temporaryResults
;
private
int
queryTimeout
;
private
boolean
commitOrRollbackDisabled
;
private
Table
waitForLock
;
...
...
@@ -125,6 +125,7 @@ public class Session extends SessionWithState {
private
HashMap
<
Object
,
ViewIndex
>
subQueryIndexCache
;
private
boolean
joinBatchEnabled
;
private
boolean
forceJoinOrder
;
private
boolean
lazyQueryExecution
;
/**
* Temporary LOBs from result sets. Those are kept for some time. The
...
...
@@ -158,6 +159,14 @@ public class Session extends SessionWithState {
this
.
currentSchemaName
=
Constants
.
SCHEMA_MAIN
;
}
public
void
setLazyQueryExecution
(
boolean
lazyQueryExecution
)
{
this
.
lazyQueryExecution
=
lazyQueryExecution
;
}
public
boolean
isLazyQueryExecution
()
{
return
lazyQueryExecution
;
}
public
void
setForceJoinOrder
(
boolean
forceJoinOrder
)
{
this
.
forceJoinOrder
=
forceJoinOrder
;
}
...
...
@@ -1469,7 +1478,7 @@ public class Session extends SessionWithState {
*
* @param result the temporary result set
*/
public
void
addTemporaryResult
(
LocalResult
result
)
{
public
void
addTemporaryResult
(
ResultInterface
result
)
{
if
(!
result
.
needToClose
())
{
return
;
}
...
...
@@ -1484,7 +1493,7 @@ public class Session extends SessionWithState {
private
void
closeTemporaryResults
()
{
if
(
temporaryResults
!=
null
)
{
for
(
LocalResult
result
:
temporaryResults
)
{
for
(
ResultInterface
result
:
temporaryResults
)
{
result
.
close
();
}
temporaryResults
=
null
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/ConditionExists.java
浏览文件 @
5b21a636
...
...
@@ -7,7 +7,7 @@ package org.h2.expression;
import
org.h2.command.dml.Query
;
import
org.h2.engine.Session
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.util.StringUtils
;
...
...
@@ -28,9 +28,9 @@ public class ConditionExists extends Condition {
@Override
public
Value
getValue
(
Session
session
)
{
query
.
setSession
(
session
);
LocalResult
result
=
query
.
query
(
1
);
ResultInterface
result
=
query
.
query
(
1
);
session
.
addTemporaryResult
(
result
);
boolean
r
=
result
.
getRowCount
()
>
0
;
boolean
r
=
result
.
hasNext
()
;
return
ValueBoolean
.
get
(
r
);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/ConditionInSelect.java
浏览文件 @
5b21a636
...
...
@@ -11,7 +11,7 @@ import org.h2.engine.Database;
import
org.h2.engine.Session
;
import
org.h2.index.IndexCondition
;
import
org.h2.message.DbException
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.util.StringUtils
;
...
...
@@ -46,9 +46,9 @@ public class ConditionInSelect extends Condition {
if
(!
query
.
hasOrder
())
{
query
.
setDistinct
(
true
);
}
LocalResult
rows
=
query
.
query
(
0
);
ResultInterface
rows
=
query
.
query
(
0
);
Value
l
=
left
.
getValue
(
session
);
if
(
rows
.
getRowCount
()
==
0
)
{
if
(
!
rows
.
hasNext
()
)
{
return
ValueBoolean
.
get
(
all
);
}
else
if
(
l
==
ValueNull
.
INSTANCE
)
{
return
l
;
...
...
@@ -74,7 +74,7 @@ public class ConditionInSelect extends Condition {
return
ValueBoolean
.
get
(
false
);
}
private
Value
getValueSlow
(
LocalResult
rows
,
Value
l
)
{
private
Value
getValueSlow
(
ResultInterface
rows
,
Value
l
)
{
// this only returns the correct result if the result has at least one
// row, and if l is not null
boolean
hasNull
=
false
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Subquery.java
浏览文件 @
5b21a636
...
...
@@ -34,21 +34,19 @@ public class Subquery extends Expression {
public
Value
getValue
(
Session
session
)
{
query
.
setSession
(
session
);
try
(
ResultInterface
result
=
query
.
query
(
2
))
{
int
rowcount
=
result
.
getRowCount
();
if
(
rowcount
>
1
)
{
throw
DbException
.
get
(
ErrorCode
.
SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW
);
}
Value
v
;
if
(
rowcount
<=
0
)
{
if
(
!
result
.
next
()
)
{
v
=
ValueNull
.
INSTANCE
;
}
else
{
result
.
next
();
Value
[]
values
=
result
.
currentRow
();
if
(
result
.
getVisibleColumnCount
()
==
1
)
{
v
=
values
[
0
];
}
else
{
v
=
ValueArray
.
get
(
values
);
}
if
(
result
.
hasNext
())
{
throw
DbException
.
get
(
ErrorCode
.
SCALAR_SUBQUERY_CONTAINS_MORE_THAN_ONE_ROW
);
}
}
return
v
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/TableFunction.java
浏览文件 @
5b21a636
...
...
@@ -12,7 +12,6 @@ import org.h2.engine.Database;
import
org.h2.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.table.Column
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.util.MathUtils
;
...
...
@@ -131,7 +130,7 @@ public class TableFunction extends Function {
return
vr
;
}
private
static
SimpleResultSet
getSimpleResultSet
(
ResultInterface
rs
,
private
static
SimpleResultSet
getSimpleResultSet
(
LocalResult
rs
,
int
maxrows
)
{
int
columnCount
=
rs
.
getVisibleColumnCount
();
SimpleResultSet
simple
=
new
SimpleResultSet
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/ViewCursor.java
浏览文件 @
5b21a636
...
...
@@ -6,7 +6,7 @@
package
org
.
h2
.
index
;
import
org.h2.message.DbException
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.table.Table
;
...
...
@@ -20,11 +20,11 @@ public class ViewCursor implements Cursor {
private
final
Table
table
;
private
final
ViewIndex
index
;
private
final
LocalResult
result
;
private
final
ResultInterface
result
;
private
final
SearchRow
first
,
last
;
private
Row
current
;
public
ViewCursor
(
ViewIndex
index
,
LocalResult
result
,
SearchRow
first
,
public
ViewCursor
(
ViewIndex
index
,
ResultInterface
result
,
SearchRow
first
,
SearchRow
last
)
{
this
.
table
=
index
.
getTable
();
this
.
index
=
index
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
5b21a636
...
...
@@ -20,6 +20,7 @@ import org.h2.expression.Comparison;
import
org.h2.expression.Parameter
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
...
...
@@ -181,7 +182,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
private
Cursor
findRecursive
(
SearchRow
first
,
SearchRow
last
)
{
assert
recursive
;
LocalResult
recResult
=
view
.
getRecursiveResult
();
ResultInterface
recResult
=
view
.
getRecursiveResult
();
if
(
recResult
!=
null
)
{
recResult
.
reset
();
return
new
ViewCursor
(
this
,
recResult
,
first
,
last
);
...
...
@@ -191,6 +192,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
parser
.
setRightsChecked
(
true
);
parser
.
setSuppliedParameterList
(
originalParameters
);
query
=
(
Query
)
parser
.
prepare
(
querySQL
);
query
.
setNeverLazy
(
true
);
}
if
(!
query
.
isUnion
())
{
throw
DbException
.
get
(
ErrorCode
.
SYNTAX_ERROR_2
,
...
...
@@ -204,7 +206,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
Query
left
=
union
.
getLeft
();
// to ensure the last result is not closed
left
.
disableCache
();
LocalResult
r
=
left
.
query
(
0
);
ResultInterface
r
=
left
.
query
(
0
);
LocalResult
result
=
union
.
getEmptyResult
();
// ensure it is not written to disk,
// because it is not closed normally
...
...
@@ -219,7 +221,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
right
.
disableCache
();
while
(
true
)
{
r
=
right
.
query
(
0
);
if
(
r
.
getRowCount
()
==
0
)
{
if
(
!
r
.
hasNext
()
)
{
break
;
}
while
(
r
.
next
())
{
...
...
@@ -286,7 +288,7 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
return
findRecursive
(
first
,
last
);
}
setupQueryParameters
(
session
,
first
,
last
,
intersection
);
LocalResult
result
=
query
.
query
(
0
);
ResultInterface
result
=
query
.
query
(
0
);
return
new
ViewCursor
(
this
,
result
,
first
,
last
);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/jdbc/JdbcConnection.java
浏览文件 @
5b21a636
...
...
@@ -1548,7 +1548,7 @@ public class JdbcConnection extends TraceObject implements Connection,
"SELECT SCOPE_IDENTITY() "
+
"WHERE SCOPE_IDENTITY() IS NOT NULL"
,
getGeneratedKeys
);
ResultInterface
result
=
getGeneratedKeys
.
executeQuery
(
0
,
false
);
ResultSet
rs
=
new
JdbcResultSet
(
this
,
stat
,
result
,
id
,
false
,
true
,
false
);
ResultSet
rs
=
new
JdbcResultSet
(
this
,
stat
,
getGeneratedKeys
,
result
,
id
,
false
,
true
,
false
);
return
rs
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/jdbc/JdbcPreparedStatement.java
浏览文件 @
5b21a636
...
...
@@ -103,15 +103,19 @@ public class JdbcPreparedStatement extends JdbcStatement implements
checkClosed
();
closeOldResultSet
();
ResultInterface
result
;
boolean
lazy
=
false
;
boolean
scrollable
=
resultSetType
!=
ResultSet
.
TYPE_FORWARD_ONLY
;
boolean
updatable
=
resultSetConcurrency
==
ResultSet
.
CONCUR_UPDATABLE
;
try
{
setExecutingStatement
(
command
);
result
=
command
.
executeQuery
(
maxRows
,
scrollable
);
lazy
=
result
.
isLazy
();
}
finally
{
if
(!
lazy
)
{
setExecutingStatement
(
null
);
}
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
result
,
id
,
}
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
command
,
result
,
id
,
closedByResultSet
,
scrollable
,
updatable
,
cachedColumnLabelMap
);
}
return
resultSet
;
...
...
@@ -186,6 +190,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
boolean
returnsResultSet
;
synchronized
(
conn
.
getSession
())
{
closeOldResultSet
();
boolean
lazy
=
false
;
try
{
setExecutingStatement
(
command
);
if
(
command
.
isQuery
())
{
...
...
@@ -193,17 +198,20 @@ public class JdbcPreparedStatement extends JdbcStatement implements
boolean
scrollable
=
resultSetType
!=
ResultSet
.
TYPE_FORWARD_ONLY
;
boolean
updatable
=
resultSetConcurrency
==
ResultSet
.
CONCUR_UPDATABLE
;
ResultInterface
result
=
command
.
executeQuery
(
maxRows
,
scrollable
);
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
result
,
lazy
=
result
.
isLazy
();
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
command
,
result
,
id
,
closedByResultSet
,
scrollable
,
updatable
);
updatable
,
cachedColumnLabelMap
);
}
else
{
returnsResultSet
=
false
;
updateCount
=
command
.
executeUpdate
();
}
}
finally
{
if
(!
lazy
)
{
setExecutingStatement
(
null
);
}
}
}
return
returnsResultSet
;
}
finally
{
afterWriting
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/jdbc/JdbcResultSet.java
浏览文件 @
5b21a636
...
...
@@ -31,6 +31,7 @@ import java.util.UUID;
import
org.h2.api.ErrorCode
;
import
org.h2.api.TimestampWithTimeZone
;
import
org.h2.command.CommandInterface
;
import
org.h2.engine.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.message.TraceObject
;
...
...
@@ -91,13 +92,15 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
private
HashMap
<
String
,
Integer
>
columnLabelMap
;
private
HashMap
<
Integer
,
Value
[]>
patchedRows
;
private
JdbcPreparedStatement
preparedStatement
;
private
CommandInterface
command
;
JdbcResultSet
(
JdbcConnection
conn
,
JdbcStatement
stat
,
JdbcResultSet
(
JdbcConnection
conn
,
JdbcStatement
stat
,
CommandInterface
command
,
ResultInterface
result
,
int
id
,
boolean
closeStatement
,
boolean
scrollable
,
boolean
updatable
)
{
setTrace
(
conn
.
getSession
().
getTrace
(),
TraceObject
.
RESULT_SET
,
id
);
this
.
conn
=
conn
;
this
.
stat
=
stat
;
this
.
command
=
command
;
this
.
result
=
result
;
columnCount
=
result
.
getVisibleColumnCount
();
this
.
closeStatement
=
closeStatement
;
...
...
@@ -106,10 +109,10 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
}
JdbcResultSet
(
JdbcConnection
conn
,
JdbcPreparedStatement
preparedStatement
,
ResultInterface
result
,
int
id
,
boolean
closeStatement
,
CommandInterface
command
,
ResultInterface
result
,
int
id
,
boolean
closeStatement
,
boolean
scrollable
,
boolean
updatable
,
HashMap
<
String
,
Integer
>
columnLabelMap
)
{
this
(
conn
,
preparedStatement
,
result
,
id
,
closeStatement
,
scrollable
,
this
(
conn
,
preparedStatement
,
command
,
result
,
id
,
closeStatement
,
scrollable
,
updatable
);
this
.
columnLabelMap
=
columnLabelMap
;
this
.
preparedStatement
=
preparedStatement
;
...
...
@@ -208,6 +211,9 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
void
closeInternal
()
throws
SQLException
{
if
(
result
!=
null
)
{
try
{
if
(
result
.
isLazy
())
{
stat
.
onLazyResultSetClose
(
command
,
preparedStatement
==
null
);
}
result
.
close
();
if
(
closeStatement
&&
stat
!=
null
)
{
stat
.
close
();
...
...
@@ -2525,10 +2531,10 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"getRow"
);
checkClosed
();
int
rowId
=
result
.
getRowId
();
if
(
rowId
>=
result
.
getRowCount
())
{
if
(
result
.
isAfterLast
())
{
return
0
;
}
int
rowId
=
result
.
getRowId
();
return
rowId
+
1
;
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
...
...
@@ -2674,9 +2680,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"isBeforeFirst"
);
checkClosed
();
int
row
=
result
.
getRowId
();
int
count
=
result
.
getRowCount
();
return
count
>
0
&&
row
<
0
;
return
result
.
getRowId
()
<
0
&&
result
.
hasNext
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2695,9 +2699,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"isAfterLast"
);
checkClosed
();
int
row
=
result
.
getRowId
();
int
count
=
result
.
getRowCount
();
return
count
>
0
&&
row
>=
count
;
return
result
.
getRowId
()
>
0
&&
result
.
isAfterLast
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2715,8 +2717,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"isFirst"
);
checkClosed
();
int
row
=
result
.
getRowId
();
return
row
==
0
&&
row
<
result
.
getRowCount
();
return
result
.
getRowId
()
==
0
&&
!
result
.
isAfterLast
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2734,8 +2735,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"isLast"
);
checkClosed
();
int
row
=
result
.
getRowId
();
return
row
>=
0
&&
row
==
result
.
getRowCount
()
-
1
;
int
row
Id
=
result
.
getRowId
();
return
row
Id
>=
0
&&
!
result
.
isAfterLast
()
&&
!
result
.
hasNext
()
;
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2791,10 +2792,9 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"first"
);
checkClosed
();
if
(
result
.
getRowId
()
<
0
)
{
return
nextRow
();
}
if
(
result
.
getRowId
()
>=
0
)
{
resetResult
();
}
return
nextRow
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
...
...
@@ -2812,7 +2812,13 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"last"
);
checkClosed
();
return
absolute
(-
1
);
if
(
result
.
isAfterLast
())
{
resetResult
();
}
while
(
result
.
hasNext
())
{
nextRow
();
}
return
isOnValidRow
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2836,17 +2842,16 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
checkClosed
();
if
(
rowNumber
<
0
)
{
rowNumber
=
result
.
getRowCount
()
+
rowNumber
+
1
;
}
else
if
(
rowNumber
>
result
.
getRowCount
()
+
1
)
{
rowNumber
=
result
.
getRowCount
()
+
1
;
}
if
(
rowNumber
<=
result
.
getRowId
())
{
if
(
--
rowNumber
<
result
.
getRowId
())
{
resetResult
();
}
while
(
result
.
getRowId
()
+
1
<
rowNumber
)
{
nextRow
();
while
(
result
.
getRowId
()
<
rowNumber
)
{
if
(!
nextRow
())
{
return
false
;
}
int
row
=
result
.
getRowId
();
return
row
>=
0
&&
row
<
result
.
getRowCount
();
}
return
isOnValidRow
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -2867,13 +2872,16 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
try
{
debugCodeCall
(
"relative"
,
rowCount
);
checkClosed
();
int
row
=
result
.
getRowId
()
+
1
+
rowCount
;
if
(
row
<
0
)
{
row
=
0
;
}
else
if
(
row
>
result
.
getRowCount
())
{
row
=
result
.
getRowCount
()
+
1
;
if
(
rowCount
<
0
)
{
rowCount
=
result
.
getRowId
()
+
rowCount
+
1
;
resetResult
();
}
return
absolute
(
row
);
for
(
int
i
=
0
;
i
<
rowCount
;
i
++)
{
if
(!
nextRow
())
{
return
false
;
}
}
return
isOnValidRow
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
}
...
...
@@ -3207,8 +3215,12 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
}
}
private
boolean
isOnValidRow
()
{
return
result
.
getRowId
()
>=
0
&&
!
result
.
isAfterLast
();
}
private
void
checkOnValidRow
()
{
if
(
result
.
getRowId
()
<
0
||
result
.
getRowId
()
>=
result
.
getRowCount
())
{
if
(
!
isOnValidRow
())
{
throw
DbException
.
get
(
ErrorCode
.
NO_DATA_AVAILABLE
);
}
}
...
...
@@ -3254,6 +3266,9 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
}
private
boolean
nextRow
()
{
if
(
result
.
isLazy
()
&&
stat
.
isCancelled
())
{
throw
DbException
.
get
(
ErrorCode
.
STATEMENT_WAS_CANCELED
);
}
boolean
next
=
result
.
next
();
if
(!
next
&&
!
scrollable
)
{
result
.
close
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/jdbc/JdbcStatement.java
浏览文件 @
5b21a636
...
...
@@ -12,6 +12,7 @@ import java.sql.SQLWarning;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Command
;
import
org.h2.command.CommandInterface
;
import
org.h2.engine.SessionInterface
;
import
org.h2.engine.SysProperties
;
...
...
@@ -38,7 +39,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
private
int
lastExecutedCommandType
;
private
ArrayList
<
String
>
batchCommands
;
private
boolean
escapeProcessing
=
true
;
private
boolean
cancelled
;
private
volatile
boolean
cancelled
;
JdbcStatement
(
JdbcConnection
conn
,
int
id
,
int
resultSetType
,
int
resultSetConcurrency
,
boolean
closeWithResultSet
)
{
...
...
@@ -72,16 +73,22 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
sql
=
JdbcConnection
.
translateSQL
(
sql
,
escapeProcessing
);
CommandInterface
command
=
conn
.
prepareCommand
(
sql
,
fetchSize
);
ResultInterface
result
;
boolean
lazy
=
false
;
boolean
scrollable
=
resultSetType
!=
ResultSet
.
TYPE_FORWARD_ONLY
;
boolean
updatable
=
resultSetConcurrency
==
ResultSet
.
CONCUR_UPDATABLE
;
setExecutingStatement
(
command
);
try
{
result
=
command
.
executeQuery
(
maxRows
,
scrollable
);
lazy
=
result
.
isLazy
();
}
finally
{
if
(!
lazy
)
{
setExecutingStatement
(
null
);
}
}
if
(!
lazy
)
{
command
.
close
();
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
result
,
id
,
}
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
command
,
result
,
id
,
closedByResultSet
,
scrollable
,
updatable
);
}
return
resultSet
;
...
...
@@ -168,6 +175,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
closeOldResultSet
();
sql
=
JdbcConnection
.
translateSQL
(
sql
,
escapeProcessing
);
CommandInterface
command
=
conn
.
prepareCommand
(
sql
,
fetchSize
);
boolean
lazy
=
false
;
boolean
returnsResultSet
;
synchronized
(
session
)
{
setExecutingStatement
(
command
);
...
...
@@ -177,17 +185,22 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
boolean
scrollable
=
resultSetType
!=
ResultSet
.
TYPE_FORWARD_ONLY
;
boolean
updatable
=
resultSetConcurrency
==
ResultSet
.
CONCUR_UPDATABLE
;
ResultInterface
result
=
command
.
executeQuery
(
maxRows
,
scrollable
);
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
result
,
id
,
lazy
=
result
.
isLazy
();
resultSet
=
new
JdbcResultSet
(
conn
,
this
,
command
,
result
,
id
,
closedByResultSet
,
scrollable
,
updatable
);
}
else
{
returnsResultSet
=
false
;
updateCount
=
command
.
executeUpdate
();
}
}
finally
{
if
(!
lazy
)
{
setExecutingStatement
(
null
);
}
}
}
if
(!
lazy
)
{
command
.
close
();
}
return
returnsResultSet
;
}
finally
{
afterWriting
();
...
...
@@ -549,7 +562,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
*
* @return true if yes
*/
public
boolean
wa
sCancelled
()
{
public
boolean
i
sCancelled
()
{
return
cancelled
;
}
...
...
@@ -1031,6 +1044,14 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
executingCommand
=
c
;
}
void
onLazyResultSetClose
(
CommandInterface
command
,
boolean
closeCommand
)
{
setExecutingStatement
(
null
);
command
.
stop
();
if
(
closeCommand
)
{
command
.
close
();
}
}
/**
* INTERNAL.
* Get the command type of the last executed command.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LazyResult.java
0 → 100644
浏览文件 @
5b21a636
/*
* Copyright 2004-2014 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
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.value.Value
;
/**
* Lazy execution support for queries.
*
* @author Sergi Vladykin
*/
public
abstract
class
LazyResult
implements
ResultInterface
{
private
Expression
[]
expressions
;
private
int
rowId
=
-
1
;
private
Value
[]
currentRow
;
private
Value
[]
nextRow
;
private
boolean
closed
;
private
boolean
afterLast
;
private
int
limit
;
public
LazyResult
(
Expression
[]
expressions
)
{
this
.
expressions
=
expressions
;
}
public
void
setLimit
(
int
limit
)
{
this
.
limit
=
limit
;
}
@Override
public
boolean
isLazy
()
{
return
true
;
}
@Override
public
void
reset
()
{
if
(
closed
)
{
throw
DbException
.
throwInternalError
();
}
rowId
=
-
1
;
afterLast
=
false
;
currentRow
=
null
;
nextRow
=
null
;
}
@Override
public
Value
[]
currentRow
()
{
return
currentRow
;
}
@Override
public
boolean
next
()
{
if
(
hasNext
())
{
rowId
++;
currentRow
=
nextRow
;
nextRow
=
null
;
return
true
;
}
if
(!
afterLast
)
{
rowId
++;
currentRow
=
null
;
afterLast
=
true
;
}
return
false
;
}
@Override
public
boolean
hasNext
()
{
if
(
closed
||
afterLast
)
{
return
false
;
}
if
(
nextRow
==
null
&&
(
limit
<=
0
||
rowId
+
1
<
limit
))
{
nextRow
=
fetchNextRow
();
}
return
nextRow
!=
null
;
}
/**
* Fetch next row or null if none available.
*
* @return next row or null
*/
protected
abstract
Value
[]
fetchNextRow
();
@Override
public
boolean
isAfterLast
()
{
return
afterLast
;
}
@Override
public
int
getRowId
()
{
return
rowId
;
}
@Override
public
int
getRowCount
()
{
throw
DbException
.
getUnsupportedException
(
"Row count is unknown for lazy result."
);
}
@Override
public
boolean
needToClose
()
{
return
true
;
}
@Override
public
boolean
isClosed
()
{
return
closed
;
}
@Override
public
void
close
()
{
closed
=
true
;
}
@Override
public
String
getAlias
(
int
i
)
{
return
expressions
[
i
].
getAlias
();
}
@Override
public
String
getSchemaName
(
int
i
)
{
return
expressions
[
i
].
getSchemaName
();
}
@Override
public
String
getTableName
(
int
i
)
{
return
expressions
[
i
].
getTableName
();
}
@Override
public
String
getColumnName
(
int
i
)
{
return
expressions
[
i
].
getColumnName
();
}
@Override
public
int
getColumnType
(
int
i
)
{
return
expressions
[
i
].
getType
();
}
@Override
public
long
getColumnPrecision
(
int
i
)
{
return
expressions
[
i
].
getPrecision
();
}
@Override
public
int
getColumnScale
(
int
i
)
{
return
expressions
[
i
].
getScale
();
}
@Override
public
int
getDisplaySize
(
int
i
)
{
return
expressions
[
i
].
getDisplaySize
();
}
@Override
public
boolean
isAutoIncrement
(
int
i
)
{
return
expressions
[
i
].
isAutoIncrement
();
}
@Override
public
int
getNullable
(
int
i
)
{
return
expressions
[
i
].
getNullable
();
}
@Override
public
void
setFetchSize
(
int
fetchSize
)
{
// ignore
}
@Override
public
int
getFetchSize
()
{
// We always fetch rows one by one.
return
1
;
}
@Override
public
ResultInterface
createShallowCopy
(
Session
targetSession
)
{
// Copying is impossible with lazy result.
return
null
;
}
@Override
public
boolean
containsDistinct
(
Value
[]
values
)
{
// We have to make sure that we do not allow lazy
// evaluation when this call is needed:
// WHERE x IN (SELECT ...).
throw
DbException
.
throwInternalError
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
5b21a636
...
...
@@ -77,6 +77,11 @@ public class LocalResult implements ResultInterface, ResultTarget {
this
.
expressions
=
expressions
;
}
@Override
public
boolean
isLazy
()
{
return
false
;
}
public
void
setMaxMemoryRows
(
int
maxValue
)
{
this
.
maxMemoryRows
=
maxValue
;
}
...
...
@@ -117,6 +122,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
* @param targetSession the session of the copy
* @return the copy if possible, or null if copying is not possible
*/
@Override
public
LocalResult
createShallowCopy
(
Session
targetSession
)
{
if
(
external
==
null
&&
(
rows
==
null
||
rows
.
size
()
<
rowCount
))
{
return
null
;
...
...
@@ -199,6 +205,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
* @param values the row
* @return true if the row exists
*/
@Override
public
boolean
containsDistinct
(
Value
[]
values
)
{
if
(
external
!=
null
)
{
return
external
.
contains
(
values
);
...
...
@@ -217,6 +224,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
@Override
public
void
reset
()
{
rowId
=
-
1
;
currentRow
=
null
;
if
(
external
!=
null
)
{
external
.
reset
();
if
(
diskOffset
>
0
)
{
...
...
@@ -254,6 +262,11 @@ public class LocalResult implements ResultInterface, ResultTarget {
return
rowId
;
}
@Override
public
boolean
isAfterLast
()
{
return
rowId
>=
rowCount
;
}
private
void
cloneLobs
(
Value
[]
values
)
{
for
(
int
i
=
0
;
i
<
values
.
length
;
i
++)
{
Value
v
=
values
[
i
];
...
...
@@ -375,6 +388,11 @@ public class LocalResult implements ResultInterface, ResultTarget {
return
rowCount
;
}
@Override
public
boolean
hasNext
()
{
return
!
closed
&&
rowId
<
rowCount
-
1
;
}
/**
* Set the number of rows that this result will return at the maximum.
*
...
...
@@ -508,6 +526,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
*
* @return true if it is
*/
@Override
public
boolean
isClosed
()
{
return
closed
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/ResultInterface.java
浏览文件 @
5b21a636
...
...
@@ -5,6 +5,7 @@
*/
package
org
.
h2
.
result
;
import
org.h2.engine.Session
;
import
org.h2.value.Value
;
/**
...
...
@@ -41,6 +42,13 @@ public interface ResultInterface extends AutoCloseable {
*/
int
getRowId
();
/**
* Check if the current position is after last row.
*
* @return true if after last
*/
boolean
isAfterLast
();
/**
* Get the number of visible columns.
* More columns may exist internally for sorting or grouping.
...
...
@@ -56,6 +64,13 @@ public interface ResultInterface extends AutoCloseable {
*/
int
getRowCount
();
/**
* Check if this result has more rows to fetch.
*
* @return true if it has
*/
boolean
hasNext
();
/**
* Check if this result set should be closed, for example because it is
* buffered using a temporary file.
...
...
@@ -164,4 +179,34 @@ public interface ResultInterface extends AutoCloseable {
*/
int
getFetchSize
();
/**
* Check if this a lazy execution result.
*
* @return true if it is a lazy result
*/
boolean
isLazy
();
/**
* Check if this result set is closed.
*
* @return true if it is
*/
boolean
isClosed
();
/**
* Create a shallow copy of the result set. The data and a temporary table
* (if there is any) is not copied.
*
* @param targetSession the session of the copy
* @return the copy if possible, or null if copying is not possible
*/
ResultInterface
createShallowCopy
(
Session
targetSession
);
/**
* Check if this result set contains the given row.
*
* @param values the row
* @return true if the row exists
*/
boolean
containsDistinct
(
Value
[]
values
);
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/ResultRemote.java
浏览文件 @
5b21a636
...
...
@@ -7,6 +7,7 @@ package org.h2.result;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
org.h2.engine.Session
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
import
org.h2.message.DbException
;
...
...
@@ -50,6 +51,11 @@ public class ResultRemote implements ResultInterface {
fetchRows
(
false
);
}
@Override
public
boolean
isLazy
()
{
return
false
;
}
@Override
public
String
getAlias
(
int
i
)
{
return
columns
[
i
].
alias
;
...
...
@@ -145,6 +151,11 @@ public class ResultRemote implements ResultInterface {
return
rowId
;
}
@Override
public
boolean
isAfterLast
()
{
return
rowId
>=
rowCount
;
}
@Override
public
int
getVisibleColumnCount
()
{
return
columns
.
length
;
...
...
@@ -155,6 +166,11 @@ public class ResultRemote implements ResultInterface {
return
rowCount
;
}
@Override
public
boolean
hasNext
()
{
return
rowId
<
rowCount
-
1
;
}
private
void
sendClose
()
{
if
(
session
==
null
)
{
return
;
...
...
@@ -254,4 +270,20 @@ public class ResultRemote implements ResultInterface {
return
true
;
}
@Override
public
ResultInterface
createShallowCopy
(
Session
targetSession
)
{
// The operation is not supported on remote result.
return
null
;
}
@Override
public
boolean
isClosed
()
{
return
result
==
null
;
}
@Override
public
boolean
containsDistinct
(
Value
[]
values
)
{
// We should never do this on remote result.
throw
DbException
.
throwInternalError
();
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/server/pg/PgServerThread.java
浏览文件 @
5b21a636
...
...
@@ -376,7 +376,7 @@ public class PgServerThread implements Runnable {
sendCommandComplete
(
prep
,
prep
.
getUpdateCount
());
}
}
catch
(
Exception
e
)
{
if
(
prep
.
wa
sCancelled
())
{
if
(
prep
.
i
sCancelled
())
{
sendCancelQueryResponse
();
}
else
{
sendErrorResponse
(
e
);
...
...
@@ -423,7 +423,7 @@ public class PgServerThread implements Runnable {
sendCommandComplete
(
stat
,
stat
.
getUpdateCount
());
}
}
catch
(
SQLException
e
)
{
if
(
stat
!=
null
&&
stat
.
wa
sCancelled
())
{
if
(
stat
!=
null
&&
stat
.
i
sCancelled
())
{
sendCancelQueryResponse
();
}
else
{
sendErrorResponse
(
e
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/JoinBatch.java
浏览文件 @
5b21a636
...
...
@@ -21,7 +21,7 @@ import org.h2.index.IndexLookupBatch;
import
org.h2.index.ViewCursor
;
import
org.h2.index.ViewIndex
;
import
org.h2.message.DbException
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.util.DoneFuture
;
...
...
@@ -738,6 +738,7 @@ public final class JoinBatch {
/**
* Simple singleton list.
* @param <E> Element type.
*/
static
final
class
SingletonList
<
E
>
extends
AbstractList
<
E
>
{
private
E
element
;
...
...
@@ -763,6 +764,7 @@ public final class JoinBatch {
/**
* Base class for SELECT and SELECT UNION view index lookup batches.
* @param <R> Runner type.
*/
private
abstract
static
class
ViewIndexLookupBatchBase
<
R
extends
QueryRunnerBase
>
implements
IndexLookupBatch
{
...
...
@@ -850,14 +852,15 @@ public final class JoinBatch {
}
/**
* Lazy query runner base.
* Lazy query runner base
for subqueries and views
.
*/
private
abstract
static
class
QueryRunnerBase
extends
LazyFuture
<
Cursor
>
{
protected
final
ViewIndex
viewIndex
;
protected
SearchRow
first
;
protected
SearchRow
last
;
private
boolean
isLazyResult
;
public
QueryRunnerBase
(
ViewIndex
viewIndex
)
{
QueryRunnerBase
(
ViewIndex
viewIndex
)
{
this
.
viewIndex
=
viewIndex
;
}
...
...
@@ -867,6 +870,9 @@ public final class JoinBatch {
@Override
public
final
boolean
reset
()
{
if
(
isLazyResult
)
{
resetViewTopFutureCursorAfterQuery
();
}
if
(
super
.
reset
())
{
return
true
;
}
...
...
@@ -875,11 +881,14 @@ public final class JoinBatch {
return
false
;
}
protected
final
ViewCursor
newCursor
(
LocalResult
localResult
)
{
protected
final
ViewCursor
newCursor
(
ResultInterface
localResult
)
{
isLazyResult
=
localResult
.
isLazy
();
ViewCursor
cursor
=
new
ViewCursor
(
viewIndex
,
localResult
,
first
,
last
);
clear
();
return
cursor
;
}
protected
abstract
void
resetViewTopFutureCursorAfterQuery
();
}
/**
...
...
@@ -924,12 +933,12 @@ public final class JoinBatch {
}
/**
* Query runner.
* Query runner
for SELECT
.
*/
private
final
class
QueryRunner
extends
QueryRunnerBase
{
Future
<
Cursor
>
topFutureCursor
;
public
QueryRunner
(
ViewIndex
viewIndex
)
{
QueryRunner
(
ViewIndex
viewIndex
)
{
super
(
viewIndex
);
}
...
...
@@ -948,14 +957,23 @@ public final class JoinBatch {
}
viewIndex
.
setupQueryParameters
(
viewIndex
.
getSession
(),
first
,
last
,
null
);
JoinBatch
.
this
.
viewTopFutureCursor
=
topFutureCursor
;
LocalResult
localResult
;
ResultInterface
localResult
;
boolean
lazy
=
false
;
try
{
localResult
=
viewIndex
.
getQuery
().
query
(
0
);
lazy
=
localResult
.
isLazy
();
}
finally
{
JoinBatch
.
this
.
viewTopFutureCursor
=
null
;
if
(!
lazy
)
{
resetViewTopFutureCursorAfterQuery
();
}
}
return
newCursor
(
localResult
);
}
@Override
protected
void
resetViewTopFutureCursorAfterQuery
()
{
JoinBatch
.
this
.
viewTopFutureCursor
=
null
;
}
}
/**
...
...
@@ -1056,7 +1074,7 @@ public final class JoinBatch {
private
ViewIndexLookupBatchUnion
batchUnion
;
@SuppressWarnings
(
"unchecked"
)
public
QueryRunnerUnion
(
ViewIndexLookupBatchUnion
batchUnion
)
{
QueryRunnerUnion
(
ViewIndexLookupBatchUnion
batchUnion
)
{
super
(
batchUnion
.
viewIndex
);
this
.
batchUnion
=
batchUnion
;
topFutureCursors
=
new
Future
[
batchUnion
.
filters
.
size
()];
...
...
@@ -1078,16 +1096,29 @@ public final class JoinBatch {
assert
topFutureCursors
[
i
]
!=
null
;
joinBatches
.
get
(
i
).
viewTopFutureCursor
=
topFutureCursors
[
i
];
}
LocalResult
localResult
;
ResultInterface
localResult
;
boolean
lazy
=
false
;
try
{
localResult
=
viewIndex
.
getQuery
().
query
(
0
);
lazy
=
localResult
.
isLazy
();
}
finally
{
for
(
int
i
=
0
,
size
=
joinBatches
.
size
();
i
<
size
;
i
++
)
{
joinBatches
.
get
(
i
).
viewTopFutureCursor
=
null
;
if
(!
lazy
)
{
resetViewTopFutureCursorAfterQuery
()
;
}
}
return
newCursor
(
localResult
);
}
@Override
protected
void
resetViewTopFutureCursorAfterQuery
()
{
ArrayList
<
JoinBatch
>
joinBatches
=
batchUnion
.
joinBatches
;
if
(
joinBatches
==
null
)
{
return
;
}
for
(
int
i
=
0
,
size
=
joinBatches
.
size
();
i
<
size
;
i
++)
{
joinBatches
.
get
(
i
).
viewTopFutureCursor
=
null
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/table/TableView.java
浏览文件 @
5b21a636
...
...
@@ -26,7 +26,7 @@ import org.h2.index.Index;
import
org.h2.index.IndexType
;
import
org.h2.index.ViewIndex
;
import
org.h2.message.DbException
;
import
org.h2.result.
LocalResult
;
import
org.h2.result.
ResultInterface
;
import
org.h2.result.Row
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
...
...
@@ -55,7 +55,7 @@ public class TableView extends Table {
private
long
maxDataModificationId
;
private
User
owner
;
private
Query
topQuery
;
private
LocalResult
recursiveResult
;
private
ResultInterface
recursiveResult
;
private
boolean
tableExpression
;
public
TableView
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
...
...
@@ -591,14 +591,14 @@ public class TableView extends Table {
return
viewQuery
.
isEverything
(
ExpressionVisitor
.
DETERMINISTIC_VISITOR
);
}
public
void
setRecursiveResult
(
LocalResult
value
)
{
public
void
setRecursiveResult
(
ResultInterface
value
)
{
if
(
recursiveResult
!=
null
)
{
recursiveResult
.
close
();
}
this
.
recursiveResult
=
value
;
}
public
LocalResult
getRecursiveResult
()
{
public
ResultInterface
getRecursiveResult
()
{
return
recursiveResult
;
}
...
...
@@ -630,7 +630,7 @@ public class TableView extends Table {
private
final
int
[]
masks
;
private
final
TableView
view
;
public
CacheKey
(
int
[]
masks
,
TableView
view
)
{
CacheKey
(
int
[]
masks
,
TableView
view
)
{
this
.
masks
=
masks
;
this
.
view
=
view
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
5b21a636
...
...
@@ -315,6 +315,11 @@ java org.h2.test.TestAll timer
*/
public
boolean
multiThreaded
;
/**
* If lazy queries should be used.
*/
public
boolean
lazy
;
/**
* The cipher to use (null for unencrypted).
*/
...
...
@@ -603,6 +608,13 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
test
();
testUnit
();
// lazy
lazy
=
true
;
memory
=
true
;
multiThreaded
=
true
;
test
();
lazy
=
false
;
// but sometimes race conditions need bigger windows
memory
=
false
;
multiThreaded
=
true
;
...
...
@@ -1063,6 +1075,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
public
String
toString
()
{
StringBuilder
buff
=
new
StringBuilder
();
appendIf
(
buff
,
fast
,
"fast"
);
appendIf
(
buff
,
lazy
,
"lazy"
);
appendIf
(
buff
,
mvStore
,
"mvStore"
);
appendIf
(
buff
,
big
,
"big"
);
appendIf
(
buff
,
networked
,
"net"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestBase.java
浏览文件 @
5b21a636
...
...
@@ -22,6 +22,7 @@ import java.nio.channels.FileChannel;
import
java.nio.channels.FileLock
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
...
...
@@ -318,6 +319,9 @@ public abstract class TestBase {
if
(
config
.
multiThreaded
)
{
url
=
addOption
(
url
,
"MULTI_THREADED"
,
"TRUE"
);
}
if
(
config
.
lazy
)
{
url
=
addOption
(
url
,
"LAZY_QUERY_EXECUTION"
,
"1"
);
}
if
(
config
.
cacheType
!=
null
&&
admin
)
{
url
=
addOption
(
url
,
"CACHE_TYPE"
,
config
.
cacheType
);
}
...
...
@@ -1056,13 +1060,30 @@ public abstract class TestBase {
protected
void
assertThrows
(
int
expectedErrorCode
,
Statement
stat
,
String
sql
)
{
try
{
stat
.
execute
(
sql
);
execute
(
stat
,
sql
);
fail
(
"Expected error: "
+
expectedErrorCode
);
}
catch
(
SQLException
ex
)
{
assertEquals
(
expectedErrorCode
,
ex
.
getErrorCode
());
}
}
protected
void
execute
(
PreparedStatement
stat
)
throws
SQLException
{
execute
(
stat
,
null
);
}
protected
void
execute
(
Statement
stat
,
String
sql
)
throws
SQLException
{
boolean
query
=
sql
==
null
?
((
PreparedStatement
)
stat
).
execute
()
:
stat
.
execute
(
sql
);
if
(
query
&&
config
.
lazy
)
{
try
(
ResultSet
rs
=
stat
.
getResultSet
())
{
while
(
rs
.
next
())
{
// just loop
}
}
}
}
/**
* Check if the result set meta data is correct.
*
...
...
@@ -1497,8 +1518,9 @@ public abstract class TestBase {
AssertionError
ae
=
new
AssertionError
(
"Expected an SQLException or DbException with error code "
+
expectedErrorCode
+
", but got a "
+
t
.
getClass
().
getName
()
+
" exception "
+
" with error code "
+
errorCode
);
+
", but got a "
+
(
t
==
null
?
"null"
:
t
.
getClass
().
getName
()
+
" exception "
+
" with error code "
+
errorCode
));
ae
.
initCause
(
t
);
throw
ae
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestLob.java
浏览文件 @
5b21a636
...
...
@@ -163,6 +163,9 @@ public class TestLob extends TestBase {
}
private
void
testRemovedAfterTimeout
()
throws
Exception
{
if
(
config
.
lazy
)
{
return
;
}
deleteDb
(
"lob"
);
final
String
url
=
getURL
(
"lob;lob_timeout=50"
,
true
);
Connection
conn
=
getConnection
(
url
);
...
...
@@ -199,6 +202,9 @@ public class TestLob extends TestBase {
}
private
void
testConcurrentRemoveRead
()
throws
Exception
{
if
(
config
.
lazy
)
{
return
;
}
deleteDb
(
"lob"
);
final
String
url
=
getURL
(
"lob"
,
true
);
Connection
conn
=
getConnection
(
url
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestOptimizations.java
浏览文件 @
5b21a636
...
...
@@ -220,6 +220,9 @@ public class TestOptimizations extends TestBase {
}
private
void
testQueryCacheConcurrentUse
()
throws
Exception
{
if
(
config
.
lazy
)
{
return
;
}
final
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table test(id int primary key, data clob)"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestOutOfMemory.java
浏览文件 @
5b21a636
...
...
@@ -37,9 +37,16 @@ public class TestOutOfMemory extends TestBase {
@Override
public
void
test
()
throws
SQLException
{
try
{
System
.
gc
();
testMVStoreUsingInMemoryFileSystem
();
System
.
gc
();
testDatabaseUsingInMemoryFileSystem
();
System
.
gc
();
testUpdateWhenNearlyOutOfMemory
();
}
finally
{
System
.
gc
();
}
}
private
void
testMVStoreUsingInMemoryFileSystem
()
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestQueryCache.java
浏览文件 @
5b21a636
...
...
@@ -52,10 +52,11 @@ public class TestQueryCache extends TestBase {
// stat.execute("drop table x");
time
=
System
.
nanoTime
();
prep
=
conn
.
prepareStatement
(
"select count(*) from test t1, test t2"
);
prep
.
executeQuery
(
);
execute
(
prep
);
rs
=
stat
.
executeQuery
(
"select count(*) from test t1, test t2"
);
rs
.
next
();
int
c
=
rs
.
getInt
(
1
);
rs
.
close
();
assertEquals
(
1000000
,
c
);
time
=
System
.
nanoTime
()
-
time
;
if
(
first
==
0
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestRecursiveQueries.java
浏览文件 @
5b21a636
...
...
@@ -103,7 +103,7 @@ public class TestRecursiveQueries extends TestBase {
prep2
.
setInt
(
1
,
10
);
prep2
.
setInt
(
2
,
2
);
prep2
.
setInt
(
3
,
14
);
prep2
.
execute
(
);
assertTrue
(
prep2
.
executeQuery
().
next
()
);
rs
=
prep
.
executeQuery
();
assertTrue
(
rs
.
next
());
assertEquals
(
10
,
rs
.
getInt
(
1
));
...
...
@@ -116,7 +116,7 @@ public class TestRecursiveQueries extends TestBase {
prep2
.
setInt
(
1
,
100
);
prep2
.
setInt
(
2
,
3
);
prep2
.
setInt
(
3
,
103
);
prep2
.
execute
(
);
assertTrue
(
prep2
.
executeQuery
().
next
()
);
rs
=
prep
.
executeQuery
();
assertTrue
(
rs
.
next
());
assertEquals
(
100
,
rs
.
getInt
(
1
));
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestScript.java
浏览文件 @
5b21a636
...
...
@@ -284,12 +284,6 @@ public class TestScript extends TestBase {
ResultSetMetaData
meta
=
rs
.
getMetaData
();
int
len
=
meta
.
getColumnCount
();
int
[]
max
=
new
int
[
len
];
String
[]
head
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
String
label
=
formatString
(
meta
.
getColumnLabel
(
i
+
1
));
max
[
i
]
=
label
.
length
();
head
[
i
]
=
label
;
}
result
.
clear
();
while
(
rs
.
next
())
{
String
[]
row
=
new
String
[
len
];
...
...
@@ -302,6 +296,14 @@ public class TestScript extends TestBase {
}
result
.
add
(
row
);
}
String
[]
head
=
new
String
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
String
label
=
formatString
(
meta
.
getColumnLabel
(
i
+
1
));
if
(
max
[
i
]
<
label
.
length
())
{
max
[
i
]
=
label
.
length
();
}
head
[
i
]
=
label
;
}
rs
.
close
();
writeResult
(
sql
,
format
(
head
,
max
),
null
);
writeResult
(
sql
,
format
(
null
,
max
),
null
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestTableEngines.java
浏览文件 @
5b21a636
...
...
@@ -1200,7 +1200,7 @@ public class TestTableEngines extends TestBase {
}
};
public
TreeSetTable
(
CreateTableData
data
)
{
TreeSetTable
(
CreateTableData
data
)
{
super
(
data
);
}
...
...
@@ -1602,7 +1602,7 @@ public class TestTableEngines extends TestBase {
Iterator
<
SearchRow
>
it
;
private
Row
current
;
public
IteratorCursor
(
Iterator
<
SearchRow
>
it
)
{
IteratorCursor
(
Iterator
<
SearchRow
>
it
)
{
this
.
it
=
it
;
}
...
...
@@ -1644,12 +1644,12 @@ public class TestTableEngines extends TestBase {
private
int
[]
cols
;
private
boolean
descending
;
public
RowComparator
(
int
...
cols
)
{
RowComparator
(
int
...
cols
)
{
this
.
descending
=
false
;
this
.
cols
=
cols
;
}
public
RowComparator
(
boolean
descending
,
int
...
cols
)
{
RowComparator
(
boolean
descending
,
int
...
cols
)
{
this
.
descending
=
descending
;
this
.
cols
=
cols
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestTempTables.java
浏览文件 @
5b21a636
...
...
@@ -90,6 +90,9 @@ public class TestTempTables extends TestBase {
}
private
void
testTempFileResultSet
()
throws
SQLException
{
if
(
config
.
lazy
)
{
return
;
}
deleteDb
(
"tempTables"
);
Connection
conn
=
getConnection
(
"tempTables;MAX_MEMORY_ROWS=10"
);
ResultSet
rs1
,
rs2
;
...
...
@@ -100,10 +103,10 @@ public class TestTempTables extends TestBase {
rs1
=
stat1
.
executeQuery
(
"select * from system_range(1, 20)"
);
rs2
=
stat2
.
executeQuery
(
"select * from system_range(1, 20)"
);
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
rs1
.
next
(
);
rs2
.
next
(
);
rs1
.
getInt
(
1
);
rs2
.
getInt
(
1
);
assertTrue
(
rs1
.
next
()
);
assertTrue
(
rs2
.
next
()
);
assertEquals
(
i
+
1
,
rs1
.
getInt
(
1
)
);
assertEquals
(
i
+
1
,
rs2
.
getInt
(
1
)
);
}
rs2
.
close
();
// verify the temp table is not deleted yet
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jdbc/TestCancel.java
浏览文件 @
5b21a636
...
...
@@ -189,8 +189,7 @@ public class TestCancel extends TestBase {
cancel
.
start
();
try
{
Thread
.
yield
();
assertThrows
(
ErrorCode
.
STATEMENT_WAS_CANCELED
,
query
).
executeQuery
(
"SELECT VISIT(ID), (SELECT SUM(X) "
+
assertThrows
(
ErrorCode
.
STATEMENT_WAS_CANCELED
,
query
,
"SELECT VISIT(ID), (SELECT SUM(X) "
+
"FROM SYSTEM_RANGE(1, 100000) WHERE X<>ID) FROM TEST ORDER BY ID"
);
}
finally
{
cancel
.
stopNow
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jdbc/TestMetaData.java
浏览文件 @
5b21a636
...
...
@@ -1256,7 +1256,7 @@ public class TestMetaData extends TestBase {
stat
.
execute
(
"SET QUERY_STATISTICS TRUE"
);
int
count
=
100
;
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
stat
.
execute
(
"select * from test limit 10"
);
execute
(
stat
,
"select * from test limit 10"
);
}
// The "order by" makes the result set more stable on windows, where the
// timer resolution is not that great
...
...
@@ -1266,7 +1266,7 @@ public class TestMetaData extends TestBase {
assertTrue
(
rs
.
next
());
assertEquals
(
"select * from test limit 10"
,
rs
.
getString
(
"SQL_STATEMENT"
));
assertEquals
(
count
,
rs
.
getInt
(
"EXECUTION_COUNT"
));
assertEquals
(
10
*
count
,
rs
.
getInt
(
"CUMULATIVE_ROW_COUNT"
));
assertEquals
(
config
.
lazy
?
0
:
10
*
count
,
rs
.
getInt
(
"CUMULATIVE_ROW_COUNT"
));
rs
.
close
();
conn
.
close
();
deleteDb
(
"metaData"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
5b21a636
...
...
@@ -372,11 +372,11 @@ public class TestPreparedStatement extends TestBase {
prepareStatement
(
"SELECT * FROM (SELECT ? FROM DUAL)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"SELECT -?"
);
prep
.
setInt
(
1
,
1
);
prep
.
execute
(
);
execute
(
prep
);
prep
=
conn
.
prepareStatement
(
"SELECT ?-?"
);
prep
.
setInt
(
1
,
1
);
prep
.
setInt
(
2
,
2
);
prep
.
execute
(
);
execute
(
prep
);
}
private
void
testCancelReuse
(
Connection
conn
)
throws
Exception
{
...
...
@@ -390,7 +390,7 @@ public class TestPreparedStatement extends TestBase {
Task
t
=
new
Task
()
{
@Override
public
void
call
()
throws
SQLException
{
prep
.
execute
(
);
TestPreparedStatement
.
this
.
execute
(
prep
);
}
};
t
.
execute
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jdbc/TestUpdatableResultSet.java
浏览文件 @
5b21a636
...
...
@@ -266,9 +266,14 @@ public class TestUpdatableResultSet extends TestBase {
assertTrue
(
rs
.
absolute
(
3
));
assertEquals
(
3
,
rs
.
getRow
());
if
(!
config
.
lazy
)
{
assertTrue
(
rs
.
absolute
(-
1
));
assertEquals
(
3
,
rs
.
getRow
());
assertTrue
(
rs
.
absolute
(-
2
));
assertEquals
(
2
,
rs
.
getRow
());
}
assertFalse
(
rs
.
absolute
(
4
));
assertTrue
(
rs
.
isAfterLast
());
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/synth/TestHaltApp.java
浏览文件 @
5b21a636
...
...
@@ -38,9 +38,9 @@ public class TestHaltApp extends TestHalt {
}
}
pr
ivate
void
execute
(
Statement
stat
,
String
sql
)
throws
SQLException
{
pr
otected
void
execute
(
Statement
stat
,
String
sql
)
throws
SQLException
{
traceOperation
(
"execute: "
+
sql
);
s
tat
.
execute
(
sql
);
s
uper
.
execute
(
stat
,
sql
);
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/android/H2Cursor.java
浏览文件 @
5b21a636
...
...
@@ -56,7 +56,7 @@ public class H2Cursor extends AbstractWindowedCursor {
@Override
public
int
getCount
()
{
return
result
.
getRowCount
();
return
result
.
isLazy
()
?
-
1
:
result
.
getRowCount
();
}
/**
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论