Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
8cd9dc21
提交
8cd9dc21
authored
10月 10, 2010
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New experimental feature to speed up CREATE TABLE ... AS SELECT.
上级
36c23898
显示空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
240 行增加
和
65 行删除
+240
-65
CreateTable.java
h2/src/main/org/h2/command/ddl/CreateTable.java
+1
-0
Insert.java
h2/src/main/org/h2/command/dml/Insert.java
+48
-34
Query.java
h2/src/main/org/h2/command/dml/Query.java
+20
-5
Select.java
h2/src/main/org/h2/command/dml/Select.java
+43
-16
SelectUnion.java
h2/src/main/org/h2/command/dml/SelectUnion.java
+23
-4
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+8
-0
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+6
-6
ResultTarget.java
h2/src/main/org/h2/result/ResultTarget.java
+23
-0
DirectInsert.java
h2/src/test/org/h2/samples/DirectInsert.java
+68
-0
没有找到文件。
h2/src/main/org/h2/command/ddl/CreateTable.java
浏览文件 @
8cd9dc21
...
@@ -171,6 +171,7 @@ public class CreateTable extends SchemaCommand {
...
@@ -171,6 +171,7 @@ public class CreateTable extends SchemaCommand {
insert
.
setSortedInsertMode
(
sortedInsertMode
);
insert
.
setSortedInsertMode
(
sortedInsertMode
);
insert
.
setQuery
(
asQuery
);
insert
.
setQuery
(
asQuery
);
insert
.
setTable
(
table
);
insert
.
setTable
(
table
);
insert
.
setInsertFromSelect
(
true
);
insert
.
prepare
();
insert
.
prepare
();
insert
.
update
();
insert
.
update
();
}
finally
{
}
finally
{
...
...
h2/src/main/org/h2/command/dml/Insert.java
浏览文件 @
8cd9dc21
...
@@ -21,6 +21,7 @@ import org.h2.expression.Parameter;
...
@@ -21,6 +21,7 @@ import org.h2.expression.Parameter;
import
org.h2.index.PageIndex
;
import
org.h2.index.PageIndex
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultTarget
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.table.Column
;
import
org.h2.table.Column
;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
...
@@ -32,13 +33,15 @@ import org.h2.value.Value;
...
@@ -32,13 +33,15 @@ import org.h2.value.Value;
* This class represents the statement
* This class represents the statement
* INSERT
* INSERT
*/
*/
public
class
Insert
extends
Prepared
{
public
class
Insert
extends
Prepared
implements
ResultTarget
{
private
Table
table
;
private
Table
table
;
private
Column
[]
columns
;
private
Column
[]
columns
;
private
ArrayList
<
Expression
[]>
list
=
New
.
arrayList
();
private
ArrayList
<
Expression
[]>
list
=
New
.
arrayList
();
private
Query
query
;
private
Query
query
;
private
boolean
sortedInsertMode
;
private
boolean
sortedInsertMode
;
private
int
rowNumber
;
private
boolean
insertFromSelect
;
public
Insert
(
Session
session
)
{
public
Insert
(
Session
session
)
{
super
(
session
);
super
(
session
);
...
@@ -89,17 +92,18 @@ public class Insert extends Prepared {
...
@@ -89,17 +92,18 @@ public class Insert extends Prepared {
}
}
private
int
insertRows
()
{
private
int
insertRows
()
{
int
count
;
session
.
getUser
().
checkRight
(
table
,
Right
.
INSERT
);
session
.
getUser
().
checkRight
(
table
,
Right
.
INSERT
);
setCurrentRowNumber
(
0
);
setCurrentRowNumber
(
0
);
table
.
fire
(
session
,
Trigger
.
INSERT
,
true
);
table
.
fire
(
session
,
Trigger
.
INSERT
,
true
);
if
(
list
.
size
()
>
0
)
{
rowNumber
=
0
;
count
=
0
;
int
listSize
=
list
.
size
();
for
(
int
x
=
0
;
x
<
list
.
size
();
x
++)
{
if
(
listSize
>
0
)
{
Expression
[]
expr
=
list
.
get
(
x
);
int
columnLen
=
columns
.
length
;
for
(
int
x
=
0
;
x
<
listSize
;
x
++)
{
Row
newRow
=
table
.
getTemplateRow
();
Row
newRow
=
table
.
getTemplateRow
();
Expression
[]
expr
=
list
.
get
(
x
);
setCurrentRowNumber
(
x
+
1
);
setCurrentRowNumber
(
x
+
1
);
for
(
int
i
=
0
;
i
<
column
s
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
column
Len
;
i
++)
{
Column
c
=
columns
[
i
];
Column
c
=
columns
[
i
];
int
index
=
c
.
getColumnId
();
int
index
=
c
.
getColumnId
();
Expression
e
=
expr
[
i
];
Expression
e
=
expr
[
i
];
...
@@ -114,6 +118,7 @@ public class Insert extends Prepared {
...
@@ -114,6 +118,7 @@ public class Insert extends Prepared {
}
}
}
}
}
}
rowNumber
++;
table
.
validateConvertUpdateSequence
(
session
,
newRow
);
table
.
validateConvertUpdateSequence
(
session
,
newRow
);
boolean
done
=
table
.
fireBeforeRow
(
session
,
null
,
newRow
);
boolean
done
=
table
.
fireBeforeRow
(
session
,
null
,
newRow
);
if
(!
done
)
{
if
(!
done
)
{
...
@@ -122,25 +127,35 @@ public class Insert extends Prepared {
...
@@ -122,25 +127,35 @@ public class Insert extends Prepared {
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
session
.
log
(
table
,
UndoLogRecord
.
INSERT
,
newRow
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
}
}
count
++;
}
}
}
else
{
}
else
{
ResultInterface
rows
=
query
.
query
(
0
);
count
=
0
;
table
.
lock
(
session
,
true
,
false
);
table
.
lock
(
session
,
true
,
false
);
if
(
insertFromSelect
)
{
query
.
query
(
0
,
this
);
}
else
{
ResultInterface
rows
=
query
.
query
(
0
);
while
(
rows
.
next
())
{
while
(
rows
.
next
())
{
count
++;
Value
[]
r
=
rows
.
currentRow
();
Value
[]
r
=
rows
.
currentRow
();
addRow
(
r
);
}
rows
.
close
();
}
}
table
.
fire
(
session
,
Trigger
.
INSERT
,
false
);
return
rowNumber
;
}
public
void
addRow
(
Value
[]
values
)
{
Row
newRow
=
table
.
getTemplateRow
();
Row
newRow
=
table
.
getTemplateRow
();
setCurrentRowNumber
(
count
);
setCurrentRowNumber
(++
rowNumber
);
for
(
int
j
=
0
;
j
<
columns
.
length
;
j
++)
{
for
(
int
j
=
0
,
len
=
columns
.
length
;
j
<
len
;
j
++)
{
Column
c
=
columns
[
j
];
Column
c
=
columns
[
j
];
int
index
=
c
.
getColumnId
();
int
index
=
c
.
getColumnId
();
try
{
try
{
Value
v
=
c
.
convert
(
r
[
j
]);
Value
v
=
c
.
convert
(
values
[
j
]);
newRow
.
setValue
(
index
,
v
);
newRow
.
setValue
(
index
,
v
);
}
catch
(
DbException
ex
)
{
}
catch
(
DbException
ex
)
{
throw
setRow
(
ex
,
count
,
getSQL
(
r
));
throw
setRow
(
ex
,
rowNumber
,
getSQL
(
values
));
}
}
}
}
table
.
validateConvertUpdateSequence
(
session
,
newRow
);
table
.
validateConvertUpdateSequence
(
session
,
newRow
);
...
@@ -151,11 +166,6 @@ public class Insert extends Prepared {
...
@@ -151,11 +166,6 @@ public class Insert extends Prepared {
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
table
.
fireAfterRow
(
session
,
null
,
newRow
,
false
);
}
}
}
}
rows
.
close
();
}
table
.
fire
(
session
,
Trigger
.
INSERT
,
false
);
return
count
;
}
public
String
getPlanSQL
()
{
public
String
getPlanSQL
()
{
StatementBuilder
buff
=
new
StatementBuilder
(
"INSERT INTO "
);
StatementBuilder
buff
=
new
StatementBuilder
(
"INSERT INTO "
);
...
@@ -204,7 +214,7 @@ public class Insert extends Prepared {
...
@@ -204,7 +214,7 @@ public class Insert extends Prepared {
if
(
expr
.
length
!=
columns
.
length
)
{
if
(
expr
.
length
!=
columns
.
length
)
{
throw
DbException
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
throw
DbException
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
}
}
for
(
int
i
=
0
;
i
<
expr
.
length
;
i
++)
{
for
(
int
i
=
0
,
len
=
expr
.
length
;
i
<
len
;
i
++)
{
Expression
e
=
expr
[
i
];
Expression
e
=
expr
[
i
];
if
(
e
!=
null
)
{
if
(
e
!=
null
)
{
e
=
e
.
optimize
(
session
);
e
=
e
.
optimize
(
session
);
...
@@ -240,4 +250,8 @@ public class Insert extends Prepared {
...
@@ -240,4 +250,8 @@ public class Insert extends Prepared {
return
CommandInterface
.
INSERT
;
return
CommandInterface
.
INSERT
;
}
}
public
void
setInsertFromSelect
(
boolean
value
)
{
this
.
insertFromSelect
=
value
;
}
}
}
h2/src/main/org/h2/command/dml/Query.java
浏览文件 @
8cd9dc21
...
@@ -21,6 +21,7 @@ import org.h2.expression.ValueExpression;
...
@@ -21,6 +21,7 @@ import org.h2.expression.ValueExpression;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultTarget
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
...
@@ -62,12 +63,15 @@ public abstract class Query extends Prepared {
...
@@ -62,12 +63,15 @@ public abstract class Query extends Prepared {
}
}
/**
/**
* Execute the query without checking the cache.
* Execute the query without checking the cache. If a target is specified,
* the results are written to it, and the method returns null. If no target
* is specified, a new LocalResult is created and returned.
*
*
* @param limit the limit as specified in the JDBC method call
* @param limit the limit as specified in the JDBC method call
* @param target the target to write results to
* @return the result
* @return the result
*/
*/
protected
abstract
LocalResult
queryWithoutCache
(
int
limit
);
protected
abstract
LocalResult
queryWithoutCache
(
int
limit
,
ResultTarget
target
);
/**
/**
* Initialize the query.
* Initialize the query.
...
@@ -218,10 +222,21 @@ public abstract class Query extends Prepared {
...
@@ -218,10 +222,21 @@ public abstract class Query extends Prepared {
return
params
;
return
params
;
}
}
public
ResultInterface
query
(
int
limit
)
{
public
ResultInterface
query
(
int
maxrows
)
{
return
query
(
maxrows
,
null
);
}
/**
* Execute the query, writing the result to the target result.
*
* @param maxrows the maximum number of rows to return
* @param target the target result (null will return the result)
* @return the result set (if the target is not set).
*/
ResultInterface
query
(
int
limit
,
ResultTarget
target
)
{
fireBeforeSelectTriggers
();
fireBeforeSelectTriggers
();
if
(!
session
.
getDatabase
().
getOptimizeReuseResults
())
{
if
(!
session
.
getDatabase
().
getOptimizeReuseResults
())
{
return
queryWithoutCache
(
limit
);
return
queryWithoutCache
(
limit
,
target
);
}
}
Value
[]
params
=
getParameterValues
();
Value
[]
params
=
getParameterValues
();
long
now
=
session
.
getDatabase
().
getModificationDataId
();
long
now
=
session
.
getDatabase
().
getModificationDataId
();
...
@@ -238,7 +253,7 @@ public abstract class Query extends Prepared {
...
@@ -238,7 +253,7 @@ public abstract class Query extends Prepared {
}
}
lastParameters
=
params
;
lastParameters
=
params
;
closeLastResult
();
closeLastResult
();
lastResult
=
queryWithoutCache
(
limit
);
lastResult
=
queryWithoutCache
(
limit
,
target
);
this
.
lastEvaluated
=
now
;
this
.
lastEvaluated
=
now
;
lastLimit
=
limit
;
lastLimit
=
limit
;
return
lastResult
;
return
lastResult
;
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
8cd9dc21
...
@@ -29,6 +29,7 @@ import org.h2.index.IndexType;
...
@@ -29,6 +29,7 @@ import org.h2.index.IndexType;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultTarget
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
...
@@ -151,7 +152,7 @@ public class Select extends Query {
...
@@ -151,7 +152,7 @@ public class Select extends Query {
}
}
}
}
private
void
queryGroupSorted
(
int
columnCount
,
LocalResul
t
result
)
{
private
void
queryGroupSorted
(
int
columnCount
,
ResultTarge
t
result
)
{
int
rowNumber
=
0
;
int
rowNumber
=
0
;
setCurrentRowNumber
(
0
);
setCurrentRowNumber
(
0
);
Value
[]
previousKeyValues
=
null
;
Value
[]
previousKeyValues
=
null
;
...
@@ -190,7 +191,7 @@ public class Select extends Query {
...
@@ -190,7 +191,7 @@ public class Select extends Query {
}
}
}
}
private
void
addGroupSortedRow
(
Value
[]
keyValues
,
int
columnCount
,
LocalResul
t
result
)
{
private
void
addGroupSortedRow
(
Value
[]
keyValues
,
int
columnCount
,
ResultTarge
t
result
)
{
Value
[]
row
=
new
Value
[
columnCount
];
Value
[]
row
=
new
Value
[
columnCount
];
for
(
int
j
=
0
;
groupIndex
!=
null
&&
j
<
groupIndex
.
length
;
j
++)
{
for
(
int
j
=
0
;
groupIndex
!=
null
&&
j
<
groupIndex
.
length
;
j
++)
{
row
[
groupIndex
[
j
]]
=
keyValues
[
j
];
row
[
groupIndex
[
j
]]
=
keyValues
[
j
];
...
@@ -443,7 +444,7 @@ public class Select extends Query {
...
@@ -443,7 +444,7 @@ public class Select extends Query {
return
null
;
return
null
;
}
}
private
void
queryDistinct
(
LocalResul
t
result
,
long
limitRows
)
{
private
void
queryDistinct
(
ResultTarge
t
result
,
long
limitRows
)
{
if
(
limitRows
!=
0
&&
offsetExpr
!=
null
)
{
if
(
limitRows
!=
0
&&
offsetExpr
!=
null
)
{
// limitRows must be long, otherwise we get an int overflow
// limitRows must be long, otherwise we get an int overflow
// if limitRows is at or near Integer.MAX_VALUE
// if limitRows is at or near Integer.MAX_VALUE
...
@@ -469,7 +470,7 @@ public class Select extends Query {
...
@@ -469,7 +470,7 @@ public class Select extends Query {
Value
[]
row
=
{
value
};
Value
[]
row
=
{
value
};
result
.
addRow
(
row
);
result
.
addRow
(
row
);
rowNumber
++;
rowNumber
++;
if
((
sort
==
null
||
sortUsingIndex
)
&&
limitRows
!=
0
&&
r
esult
.
getRowCount
()
>=
limitRows
)
{
if
((
sort
==
null
||
sortUsingIndex
)
&&
limitRows
!=
0
&&
r
owNumber
>=
limitRows
)
{
break
;
break
;
}
}
if
(
sampleSize
>
0
&&
rowNumber
>=
sampleSize
)
{
if
(
sampleSize
>
0
&&
rowNumber
>=
sampleSize
)
{
...
@@ -478,7 +479,7 @@ public class Select extends Query {
...
@@ -478,7 +479,7 @@ public class Select extends Query {
}
}
}
}
private
void
queryFlat
(
int
columnCount
,
LocalResul
t
result
,
long
limitRows
)
{
private
void
queryFlat
(
int
columnCount
,
ResultTarge
t
result
,
long
limitRows
)
{
if
(
limitRows
!=
0
&&
offsetExpr
!=
null
)
{
if
(
limitRows
!=
0
&&
offsetExpr
!=
null
)
{
// limitRows must be long, otherwise we get an int overflow
// limitRows must be long, otherwise we get an int overflow
// if limitRows is at or near Integer.MAX_VALUE
// if limitRows is at or near Integer.MAX_VALUE
...
@@ -503,7 +504,7 @@ public class Select extends Query {
...
@@ -503,7 +504,7 @@ public class Select extends Query {
}
}
result
.
addRow
(
row
);
result
.
addRow
(
row
);
rowNumber
++;
rowNumber
++;
if
((
sort
==
null
||
sortUsingIndex
)
&&
limitRows
!=
0
&&
r
esult
.
getRowCount
()
>=
limitRows
)
{
if
((
sort
==
null
||
sortUsingIndex
)
&&
limitRows
!=
0
&&
r
owNumber
>=
limitRows
)
{
break
;
break
;
}
}
if
(
sampleSize
>
0
&&
rowNumber
>=
sampleSize
)
{
if
(
sampleSize
>
0
&&
rowNumber
>=
sampleSize
)
{
...
@@ -516,7 +517,7 @@ public class Select extends Query {
...
@@ -516,7 +517,7 @@ public class Select extends Query {
}
}
}
}
private
void
queryQuick
(
int
columnCount
,
LocalResul
t
result
)
{
private
void
queryQuick
(
int
columnCount
,
ResultTarge
t
result
)
{
Value
[]
row
=
new
Value
[
columnCount
];
Value
[]
row
=
new
Value
[
columnCount
];
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
Expression
expr
=
expressions
.
get
(
i
);
Expression
expr
=
expressions
.
get
(
i
);
...
@@ -531,7 +532,7 @@ public class Select extends Query {
...
@@ -531,7 +532,7 @@ public class Select extends Query {
return
result
;
return
result
;
}
}
protected
LocalResult
queryWithoutCache
(
int
maxRows
)
{
protected
LocalResult
queryWithoutCache
(
int
maxRows
,
ResultTarget
target
)
{
int
limitRows
=
maxRows
;
int
limitRows
=
maxRows
;
if
(
limitExpr
!=
null
)
{
if
(
limitExpr
!=
null
)
{
int
l
=
limitExpr
.
getValue
(
session
).
getInt
();
int
l
=
limitExpr
.
getValue
(
session
).
getInt
();
...
@@ -542,13 +543,24 @@ public class Select extends Query {
...
@@ -542,13 +543,24 @@ public class Select extends Query {
}
}
}
}
int
columnCount
=
expressions
.
size
();
int
columnCount
=
expressions
.
size
();
LocalResult
result
=
new
LocalResult
(
session
,
expressionArray
,
visibleColumnCount
);
LocalResult
result
=
null
;
if
(!
sortUsingIndex
||
distinct
)
{
if
(!
SysProperties
.
optimizeInsertFromSelect
||
target
==
null
)
{
result
=
createLocalResult
(
result
);
}
if
(
sort
!=
null
&&
(!
sortUsingIndex
||
distinct
))
{
result
=
createLocalResult
(
result
);
result
.
setSortOrder
(
sort
);
result
.
setSortOrder
(
sort
);
}
}
if
(
distinct
&&
!
isDistinctQuery
)
{
if
(
distinct
&&
!
isDistinctQuery
)
{
result
=
createLocalResult
(
result
);
result
.
setDistinct
();
result
.
setDistinct
();
}
}
if
(
isGroupQuery
&&
!
isGroupSortedQuery
)
{
result
=
createLocalResult
(
result
);
}
if
(
limitRows
!=
0
||
offsetExpr
!=
null
)
{
result
=
createLocalResult
(
result
);
}
topTableFilter
.
startQuery
(
session
);
topTableFilter
.
startQuery
(
session
);
topTableFilter
.
reset
();
topTableFilter
.
reset
();
boolean
exclusive
=
isForUpdate
&&
!
isForUpdateMvcc
;
boolean
exclusive
=
isForUpdate
&&
!
isForUpdateMvcc
;
...
@@ -566,18 +578,19 @@ public class Select extends Query {
...
@@ -566,18 +578,19 @@ public class Select extends Query {
throw
DbException
.
getUnsupportedException
(
"FOR UPDATE && JOIN"
);
throw
DbException
.
getUnsupportedException
(
"FOR UPDATE && JOIN"
);
}
}
}
}
ResultTarget
to
=
result
!=
null
?
result
:
target
;
if
(
isQuickAggregateQuery
)
{
if
(
isQuickAggregateQuery
)
{
queryQuick
(
columnCount
,
result
);
queryQuick
(
columnCount
,
to
);
}
else
if
(
isGroupQuery
)
{
}
else
if
(
isGroupQuery
)
{
if
(
isGroupSortedQuery
)
{
if
(
isGroupSortedQuery
)
{
queryGroupSorted
(
columnCount
,
result
);
queryGroupSorted
(
columnCount
,
to
);
}
else
{
}
else
{
queryGroup
(
columnCount
,
result
);
queryGroup
(
columnCount
,
result
);
}
}
}
else
if
(
isDistinctQuery
)
{
}
else
if
(
isDistinctQuery
)
{
queryDistinct
(
result
,
limitRows
);
queryDistinct
(
to
,
limitRows
);
}
else
{
}
else
{
queryFlat
(
columnCount
,
result
,
limitRows
);
queryFlat
(
columnCount
,
to
,
limitRows
);
}
}
if
(
offsetExpr
!=
null
)
{
if
(
offsetExpr
!=
null
)
{
result
.
setOffset
(
offsetExpr
.
getValue
(
session
).
getInt
());
result
.
setOffset
(
offsetExpr
.
getValue
(
session
).
getInt
());
...
@@ -585,9 +598,23 @@ public class Select extends Query {
...
@@ -585,9 +598,23 @@ public class Select extends Query {
if
(
limitRows
!=
0
)
{
if
(
limitRows
!=
0
)
{
result
.
setLimit
(
limitRows
);
result
.
setLimit
(
limitRows
);
}
}
if
(
result
!=
null
)
{
result
.
done
();
result
.
done
();
if
(
target
!=
null
)
{
while
(
result
.
next
())
{
target
.
addRow
(
result
.
currentRow
());
}
result
.
close
();
return
null
;
}
return
result
;
return
result
;
}
}
return
null
;
}
private
LocalResult
createLocalResult
(
LocalResult
old
)
{
return
old
!=
null
?
old
:
new
LocalResult
(
session
,
expressionArray
,
visibleColumnCount
);
}
private
void
expandColumnList
()
{
private
void
expandColumnList
()
{
for
(
int
i
=
0
;
i
<
expressions
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
expressions
.
size
();
i
++)
{
...
...
h2/src/main/org/h2/command/dml/SelectUnion.java
浏览文件 @
8cd9dc21
...
@@ -20,6 +20,7 @@ import org.h2.expression.ValueExpression;
...
@@ -20,6 +20,7 @@ import org.h2.expression.ValueExpression;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultTarget
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.table.Column
;
import
org.h2.table.Column
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
...
@@ -118,16 +119,27 @@ public class SelectUnion extends Query {
...
@@ -118,16 +119,27 @@ public class SelectUnion extends Query {
return
new
LocalResult
(
session
,
expressionArray
,
columnCount
);
return
new
LocalResult
(
session
,
expressionArray
,
columnCount
);
}
}
protected
LocalResult
queryWithoutCache
(
int
maxrows
)
{
protected
LocalResult
queryWithoutCache
(
int
maxrows
,
ResultTarget
target
)
{
if
(
maxrows
!=
0
)
{
if
(
maxrows
!=
0
)
{
if
(
limitExpr
!=
null
)
{
if
(
limitExpr
!=
null
)
{
maxrows
=
Math
.
min
(
limitExpr
.
getValue
(
session
).
getInt
(),
maxrows
);
maxrows
=
Math
.
min
(
limitExpr
.
getValue
(
session
).
getInt
(),
maxrows
);
}
}
limitExpr
=
ValueExpression
.
get
(
ValueInt
.
get
(
maxrows
));
limitExpr
=
ValueExpression
.
get
(
ValueInt
.
get
(
maxrows
));
}
}
if
(
SysProperties
.
optimizeInsertFromSelect
)
{
if
(
unionType
==
UNION_ALL
&&
target
!=
null
)
{
if
(
sort
==
null
&&
!
distinct
&&
maxrows
==
0
&&
offsetExpr
==
null
&&
limitExpr
==
null
)
{
left
.
query
(
0
,
target
);
right
.
query
(
0
,
target
);
return
null
;
}
}
}
int
columnCount
=
left
.
getColumnCount
();
int
columnCount
=
left
.
getColumnCount
();
LocalResult
result
=
new
LocalResult
(
session
,
expressionArray
,
columnCount
);
LocalResult
result
=
new
LocalResult
(
session
,
expressionArray
,
columnCount
);
if
(
sort
!=
null
)
{
result
.
setSortOrder
(
sort
);
result
.
setSortOrder
(
sort
);
}
if
(
distinct
)
{
if
(
distinct
)
{
left
.
setDistinct
(
true
);
left
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
right
.
setDistinct
(
true
);
...
@@ -197,6 +209,13 @@ public class SelectUnion extends Query {
...
@@ -197,6 +209,13 @@ public class SelectUnion extends Query {
result
.
setLimit
(
limitExpr
.
getValue
(
session
).
getInt
());
result
.
setLimit
(
limitExpr
.
getValue
(
session
).
getInt
());
}
}
result
.
done
();
result
.
done
();
if
(
target
!=
null
)
{
while
(
result
.
next
())
{
target
.
addRow
(
result
.
currentRow
());
}
result
.
close
();
return
null
;
}
return
result
;
return
result
;
}
}
...
@@ -350,9 +369,9 @@ public class SelectUnion extends Query {
...
@@ -350,9 +369,9 @@ public class SelectUnion extends Query {
return
buff
.
toString
();
return
buff
.
toString
();
}
}
public
ResultInterface
query
(
int
limit
)
{
public
ResultInterface
query
(
int
limit
,
ResultTarget
target
)
{
// union doesn't always know the parameter list of the left and right queries
// union doesn't always know the parameter list of the left and right queries
return
queryWithoutCache
(
limit
);
return
queryWithoutCache
(
limit
,
target
);
}
}
public
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
public
boolean
isEverything
(
ExpressionVisitor
visitor
)
{
...
...
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
8cd9dc21
...
@@ -480,6 +480,14 @@ public class SysProperties {
...
@@ -480,6 +480,14 @@ public class SysProperties {
*/
*/
public
static
final
int
OBJECT_CACHE_SIZE
=
MathUtils
.
nextPowerOf2
(
getIntSetting
(
"h2.objectCacheSize"
,
1024
));
public
static
final
int
OBJECT_CACHE_SIZE
=
MathUtils
.
nextPowerOf2
(
getIntSetting
(
"h2.objectCacheSize"
,
1024
));
/**
* System property <code>h2.optimizeInsertFromSelect</code>
* (default: false).<br />
* Insert into table from query directly bypassing temporary disk storage.
* This also applies to create table as select.
*/
public
static
boolean
optimizeInsertFromSelect
=
getBooleanSetting
(
"h2.optimizeInsertFromSelect"
,
false
);
/**
/**
* System property <code>h2.optimizeDistinct</code> (default: true).<br />
* System property <code>h2.optimizeDistinct</code> (default: true).<br />
* Improve the performance of simple DISTINCT queries if an index is
* Improve the performance of simple DISTINCT queries if an index is
...
...
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
8cd9dc21
...
@@ -25,7 +25,7 @@ import org.h2.value.ValueArray;
...
@@ -25,7 +25,7 @@ import org.h2.value.ValueArray;
* and it is also used directly by the ResultSet class in the embedded mode.
* and it is also used directly by the ResultSet class in the embedded mode.
* If the result does not fit in memory, it is written to a temporary file.
* If the result does not fit in memory, it is written to a temporary file.
*/
*/
public
class
LocalResult
implements
ResultInterface
{
public
class
LocalResult
implements
ResultInterface
,
ResultTarget
{
private
int
maxMemoryRows
;
private
int
maxMemoryRows
;
private
Session
session
;
private
Session
session
;
...
@@ -78,10 +78,10 @@ public class LocalResult implements ResultInterface {
...
@@ -78,10 +78,10 @@ public class LocalResult implements ResultInterface {
* @return the local result set
* @return the local result set
*/
*/
public
static
LocalResult
read
(
Session
session
,
ResultSet
rs
,
int
maxrows
)
{
public
static
LocalResult
read
(
Session
session
,
ResultSet
rs
,
int
maxrows
)
{
try
{
Expression
[]
cols
=
Expression
.
getExpressionColumns
(
session
,
rs
);
Expression
[]
cols
=
Expression
.
getExpressionColumns
(
session
,
rs
);
int
columnCount
=
cols
.
length
;
int
columnCount
=
cols
.
length
;
LocalResult
result
=
new
LocalResult
(
session
,
cols
,
columnCount
);
LocalResult
result
=
new
LocalResult
(
session
,
cols
,
columnCount
);
try
{
for
(
int
i
=
0
;
(
maxrows
==
0
||
i
<
maxrows
)
&&
rs
.
next
();
i
++)
{
for
(
int
i
=
0
;
(
maxrows
==
0
||
i
<
maxrows
)
&&
rs
.
next
();
i
++)
{
Value
[]
list
=
new
Value
[
columnCount
];
Value
[]
list
=
new
Value
[
columnCount
];
for
(
int
j
=
0
;
j
<
columnCount
;
j
++)
{
for
(
int
j
=
0
;
j
<
columnCount
;
j
++)
{
...
@@ -90,11 +90,11 @@ public class LocalResult implements ResultInterface {
...
@@ -90,11 +90,11 @@ public class LocalResult implements ResultInterface {
}
}
result
.
addRow
(
list
);
result
.
addRow
(
list
);
}
}
result
.
done
();
return
result
;
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
throw
DbException
.
convert
(
e
);
throw
DbException
.
convert
(
e
);
}
}
result
.
done
();
return
result
;
}
}
/**
/**
...
...
h2/src/main/org/h2/result/ResultTarget.java
0 → 100644
浏览文件 @
8cd9dc21
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
result
;
import
org.h2.value.Value
;
/**
* A object where rows are written to.
*/
public
interface
ResultTarget
{
/**
* Add the row to the result set.
*
* @param values the values
*/
void
addRow
(
Value
[]
values
);
}
h2/src/test/org/h2/samples/DirectInsert.java
0 → 100644
浏览文件 @
8cd9dc21
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
samples
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.PreparedStatement
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
org.h2.constant.SysProperties
;
import
org.h2.tools.DeleteDbFiles
;
/**
* Demonstrates the benefit of using the CREATE TABLE ... AS SELECT
* optimization.
*/
public
class
DirectInsert
{
/**
* This method is called when executing this sample application from the
* command line.
*
* @param args the command line parameters
*/
public
static
void
main
(
String
...
args
)
throws
Exception
{
Class
.
forName
(
"org.h2.Driver"
);
DeleteDbFiles
.
execute
(
"~"
,
"test"
,
true
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:~/test;LOG=0"
,
"sa"
,
""
);
Statement
stat
=
conn
.
createStatement
();
initialInsert
(
conn
,
stat
,
200000
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
createAsSelect
(
stat
,
true
);
createAsSelect
(
stat
,
false
);
}
}
private
static
void
initialInsert
(
Connection
conn
,
Statement
stat
,
int
len
)
throws
SQLException
{
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(?, 'Test' || SPACE(100))"
);
long
time
=
System
.
currentTimeMillis
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
long
now
=
System
.
currentTimeMillis
();
if
(
now
>
time
+
1000
)
{
time
=
now
;
System
.
out
.
println
(
"Inserting "
+
(
100L
*
i
/
len
)
+
"%"
);
}
prep
.
setInt
(
1
,
i
);
prep
.
execute
();
}
conn
.
commit
();
}
private
static
void
createAsSelect
(
Statement
stat
,
boolean
optimize
)
throws
SQLException
{
SysProperties
.
optimizeInsertFromSelect
=
optimize
;
stat
.
execute
(
"DROP TABLE IF EXISTS TEST2"
);
System
.
out
.
println
(
"CREATE TABLE ... AS SELECT "
+
(
optimize
?
"(optimized)"
:
""
));
long
time
=
System
.
currentTimeMillis
();
stat
.
execute
(
"CREATE TABLE TEST2 AS SELECT * FROM TEST"
);
System
.
out
.
printf
(
"%.3f sec.\n"
,
(
System
.
currentTimeMillis
()
-
time
)
/
1000.0
);
stat
.
execute
(
"INSERT INTO TEST2 SELECT * FROM TEST2"
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论