Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
171b112a
提交
171b112a
authored
7月 13, 2018
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix MVTempResult implementations for results with invisible columns
上级
48534662
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
136 行增加
和
42 行删除
+136
-42
MVPlainTempResult.java
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
+28
-18
MVSortedTempResult.java
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
+70
-10
MVTempResult.java
h2/src/main/org/h2/mvstore/db/MVTempResult.java
+31
-9
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+3
-1
testScript.sql
h2/src/test/org/h2/test/scripts/testScript.sql
+4
-4
没有找到文件。
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
浏览文件 @
171b112a
...
...
@@ -5,6 +5,8 @@
*/
package
org
.
h2
.
mvstore
.
db
;
import
java.util.Arrays
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
...
...
@@ -14,7 +16,6 @@ import org.h2.mvstore.MVMap.Builder;
import
org.h2.result.ResultExternal
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueLong
;
/**
* Plain temporary result.
...
...
@@ -22,14 +23,14 @@ import org.h2.value.ValueLong;
class
MVPlainTempResult
extends
MVTempResult
{
/**
* The type of the
values in the main map and keys in the index
.
* The type of the
distinct values
.
*/
private
final
ValueDataType
value
Type
;
private
final
ValueDataType
distinct
Type
;
/**
* Map with identities of rows as keys rows as values.
*/
private
final
MVMap
<
Value
Long
,
ValueArray
>
map
;
private
final
MVMap
<
Long
,
ValueArray
>
map
;
/**
* Counter for the identities of rows. A separate counter is used instead of
...
...
@@ -47,7 +48,7 @@ class MVPlainTempResult extends MVTempResult {
/**
* Cursor for the {@link #next()} method.
*/
private
Cursor
<
Value
Long
,
ValueArray
>
cursor
;
private
Cursor
<
Long
,
ValueArray
>
cursor
;
/**
* Creates a shallow copy of the result.
...
...
@@ -57,7 +58,7 @@ class MVPlainTempResult extends MVTempResult {
*/
private
MVPlainTempResult
(
MVPlainTempResult
parent
)
{
super
(
parent
);
this
.
value
Type
=
null
;
this
.
distinct
Type
=
null
;
this
.
map
=
parent
.
map
;
}
...
...
@@ -68,20 +69,25 @@ class MVPlainTempResult extends MVTempResult {
* database
* @param expressions
* column expressions
* @param visibleColumnCount
* count of visible columns
*/
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
)
{
super
(
database
);
ValueDataType
keyType
=
new
ValueDataType
(
null
,
null
,
null
);
valueType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
expressions
.
length
]);
Builder
<
ValueLong
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
ValueLong
,
ValueArray
>().
keyType
(
keyType
)
.
valueType
(
valueType
);
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
,
int
visibleColumnCount
)
{
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
ValueDataType
valueType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
columnCount
]);
if
(
columnCount
==
visibleColumnCount
)
{
distinctType
=
valueType
;
}
else
{
distinctType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
visibleColumnCount
]);
}
Builder
<
Long
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
Long
,
ValueArray
>().
valueType
(
valueType
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
}
@Override
public
int
addRow
(
Value
[]
values
)
{
assert
parent
==
null
&&
index
==
null
;
map
.
put
(
ValueLong
.
get
(
counter
++)
,
ValueArray
.
get
(
values
));
map
.
put
(
counter
++
,
ValueArray
.
get
(
values
));
return
++
rowCount
;
}
...
...
@@ -98,12 +104,16 @@ class MVPlainTempResult extends MVTempResult {
}
private
void
createIndex
()
{
Builder
<
ValueArray
,
Boolean
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
value
Type
);
Builder
<
ValueArray
,
Boolean
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
distinct
Type
);
index
=
store
.
openMap
(
"idx"
,
builder
);
Cursor
<
Value
Long
,
ValueArray
>
c
=
map
.
cursor
(
null
);
Cursor
<
Long
,
ValueArray
>
c
=
map
.
cursor
(
null
);
while
(
c
.
hasNext
())
{
c
.
next
();
index
.
putIfAbsent
(
c
.
getValue
(),
true
);
ValueArray
row
=
c
.
getValue
();
if
(
columnCount
!=
visibleColumnCount
)
{
row
=
ValueArray
.
get
(
Arrays
.
copyOf
(
row
.
getList
(),
visibleColumnCount
));
}
index
.
putIfAbsent
(
row
,
true
);
}
}
...
...
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
浏览文件 @
171b112a
...
...
@@ -5,10 +5,12 @@
*/
package
org
.
h2
.
mvstore
.
db
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.Cursor
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap.Builder
;
...
...
@@ -43,6 +45,19 @@ class MVSortedTempResult extends MVTempResult {
*/
private
final
MVMap
<
ValueArray
,
Long
>
map
;
/**
* The type of the distinct values.
*/
private
final
ValueDataType
distinctType
;
/**
* Optional index. This index is created only if result is distinct and
* {@code columnCount != distinctColumnCount} or if
* {@link #contains(Value[])} method is invoked. Only the root result should
* have an index if required.
*/
private
MVMap
<
ValueArray
,
Boolean
>
index
;
/**
* Cursor for the {@link #next()} method.
*/
...
...
@@ -71,6 +86,7 @@ class MVSortedTempResult extends MVTempResult {
this
.
distinct
=
parent
.
distinct
;
this
.
indexes
=
parent
.
indexes
;
this
.
map
=
parent
.
map
;
this
.
distinctType
=
null
;
this
.
rowCount
=
parent
.
rowCount
;
}
...
...
@@ -83,14 +99,17 @@ class MVSortedTempResult extends MVTempResult {
* column expressions
* @param distinct
* whether this result should be distinct
* @param visibleColumnCount
* count of visible columns
* @param sort
*
sort order, or {@code null} if this result does not
*
need any
sorting
*
sort order, or {@code null} if this result does not need any
* sorting
*/
MVSortedTempResult
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
SortOrder
sort
)
{
super
(
database
);
MVSortedTempResult
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
int
visibleColumnCount
,
SortOrder
sort
)
{
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
this
.
distinct
=
distinct
;
int
length
=
expressions
.
length
;
int
length
=
columnCount
;
int
[]
sortTypes
=
new
int
[
length
];
int
[]
indexes
;
if
(
sort
!=
null
)
{
...
...
@@ -147,6 +166,14 @@ class MVSortedTempResult extends MVTempResult {
ValueDataType
keyType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
sortTypes
);
Builder
<
ValueArray
,
Long
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Long
>().
keyType
(
keyType
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
if
(
length
==
visibleColumnCount
)
{
distinctType
=
null
;
}
else
{
distinctType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
visibleColumnCount
]);
if
(
distinct
)
{
createIndex
(
false
);
}
}
}
@Override
...
...
@@ -154,6 +181,12 @@ class MVSortedTempResult extends MVTempResult {
assert
parent
==
null
;
ValueArray
key
=
getKey
(
values
);
if
(
distinct
)
{
if
(
columnCount
!=
visibleColumnCount
)
{
ValueArray
distinctRow
=
ValueArray
.
get
(
Arrays
.
copyOf
(
values
,
visibleColumnCount
));
if
(
index
.
putIfAbsent
(
distinctRow
,
true
)
!=
null
)
{
return
rowCount
;
}
}
// Add a row and increment the counter only if row does not exist
if
(
map
.
putIfAbsent
(
key
,
1L
)
==
null
)
{
rowCount
++;
...
...
@@ -172,9 +205,33 @@ class MVSortedTempResult extends MVTempResult {
@Override
public
boolean
contains
(
Value
[]
values
)
{
// Only parent result maintains the index
if
(
parent
!=
null
)
{
return
parent
.
contains
(
values
);
}
if
(
columnCount
!=
visibleColumnCount
)
{
if
(
index
==
null
)
{
createIndex
(
true
);
}
return
index
.
containsKey
(
ValueArray
.
get
(
values
));
}
return
map
.
containsKey
(
getKey
(
values
));
}
private
void
createIndex
(
boolean
fill
)
{
Builder
<
ValueArray
,
Boolean
>
indexBuilder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>()
.
keyType
(
distinctType
);
index
=
store
.
openMap
(
"idx"
,
indexBuilder
);
if
(
fill
)
{
Cursor
<
ValueArray
,
Long
>
c
=
map
.
cursor
(
null
);
while
(
c
.
hasNext
())
{
Value
[]
v
=
getValue
(
c
.
next
().
getList
());
ValueArray
distinctRow
=
ValueArray
.
get
(
Arrays
.
copyOf
(
v
,
visibleColumnCount
));
index
.
putIfAbsent
(
distinctRow
,
true
);
}
}
}
@Override
public
synchronized
ResultExternal
createShallowCopy
()
{
if
(
parent
!=
null
)
{
...
...
@@ -198,7 +255,7 @@ class MVSortedTempResult extends MVTempResult {
if
(
indexes
!=
null
)
{
Value
[]
r
=
new
Value
[
indexes
.
length
];
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
r
[
i
ndexes
[
i
]]
=
values
[
i
];
r
[
i
]
=
values
[
indexes
[
i
]
];
}
values
=
r
;
}
...
...
@@ -216,7 +273,7 @@ class MVSortedTempResult extends MVTempResult {
if
(
indexes
!=
null
)
{
Value
[]
r
=
new
Value
[
indexes
.
length
];
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
r
[
i
]
=
key
[
indexes
[
i
]
];
r
[
i
ndexes
[
i
]]
=
key
[
i
];
}
key
=
r
;
}
...
...
@@ -256,6 +313,9 @@ class MVSortedTempResult extends MVTempResult {
@Override
public
int
removeRow
(
Value
[]
values
)
{
assert
parent
==
null
&&
distinct
;
if
(
columnCount
!=
visibleColumnCount
)
{
throw
DbException
.
getUnsupportedException
(
"removeRow()"
);
}
// If an entry was removed decrement the counter
if
(
map
.
remove
(
getKey
(
values
))
!=
null
)
{
rowCount
--;
...
...
h2/src/main/org/h2/mvstore/db/MVTempResult.java
浏览文件 @
171b112a
...
...
@@ -66,13 +66,17 @@ public abstract class MVTempResult implements ResultExternal {
* expressions
* @param distinct
* is output distinct
* @param visibleColumnCount
* count of visible columns
* @param sort
* sort order, or {@code null}
* @return temporary result
*/
public
static
ResultExternal
of
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
SortOrder
sort
)
{
return
distinct
||
sort
!=
null
?
new
MVSortedTempResult
(
database
,
expressions
,
distinct
,
sort
)
:
new
MVPlainTempResult
(
database
,
expressions
);
public
static
ResultExternal
of
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
int
visibleColumnCount
,
SortOrder
sort
)
{
return
distinct
||
sort
!=
null
?
new
MVSortedTempResult
(
database
,
expressions
,
distinct
,
visibleColumnCount
,
sort
)
:
new
MVPlainTempResult
(
database
,
expressions
,
visibleColumnCount
);
}
/**
...
...
@@ -80,6 +84,16 @@ public abstract class MVTempResult implements ResultExternal {
*/
final
MVStore
store
;
/**
* Count of columns.
*/
final
int
columnCount
;
/**
* Count of visible columns.
*/
final
int
visibleColumnCount
;
/**
* Count of rows. Used only in a root results, copies always have 0 value.
*/
...
...
@@ -124,6 +138,8 @@ public abstract class MVTempResult implements ResultExternal {
MVTempResult
(
MVTempResult
parent
)
{
this
.
parent
=
parent
;
this
.
store
=
parent
.
store
;
this
.
columnCount
=
parent
.
columnCount
;
this
.
visibleColumnCount
=
parent
.
visibleColumnCount
;
this
.
tempFileDeleter
=
null
;
this
.
closeable
=
null
;
this
.
fileRef
=
null
;
...
...
@@ -134,8 +150,12 @@ public abstract class MVTempResult implements ResultExternal {
*
* @param database
* database
* @param columnCount
* count of columns
* @param visibleColumnCount
* count of visible columns
*/
MVTempResult
(
Database
database
)
{
MVTempResult
(
Database
database
,
int
columnCount
,
int
visibleColumnCount
)
{
try
{
String
fileName
=
FileUtils
.
createTempFile
(
"h2tmp"
,
Constants
.
SUFFIX_TEMP_FILE
,
false
,
true
);
Builder
builder
=
new
MVStore
.
Builder
().
fileName
(
fileName
);
...
...
@@ -144,6 +164,8 @@ public abstract class MVTempResult implements ResultExternal {
builder
.
encryptionKey
(
MVTableEngine
.
decodePassword
(
key
));
}
store
=
builder
.
open
();
this
.
columnCount
=
columnCount
;
this
.
visibleColumnCount
=
visibleColumnCount
;
tempFileDeleter
=
database
.
getTempFileDeleter
();
closeable
=
new
CloseImpl
(
store
,
fileName
);
fileRef
=
tempFileDeleter
.
addFile
(
closeable
,
this
);
...
...
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
171b112a
...
...
@@ -192,6 +192,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
if
(!
distinct
)
{
DbException
.
throwInternalError
();
}
assert
values
.
length
==
visibleColumnCount
;
if
(
distinctRows
!=
null
)
{
ValueArray
array
=
ValueArray
.
get
(
values
);
distinctRows
.
remove
(
array
);
...
...
@@ -209,6 +210,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
*/
@Override
public
boolean
containsDistinct
(
Value
[]
values
)
{
assert
values
.
length
==
visibleColumnCount
;
if
(
external
!=
null
)
{
return
external
.
contains
(
values
);
}
...
...
@@ -286,7 +288,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
private
void
createExternalResult
()
{
Database
database
=
session
.
getDatabase
();
external
=
database
.
isMVStore
()
?
MVTempResult
.
of
(
database
,
expressions
,
distinct
,
sort
)
?
MVTempResult
.
of
(
database
,
expressions
,
distinct
,
visibleColumnCount
,
sort
)
:
new
ResultTempTable
(
session
,
expressions
,
distinct
,
sort
);
}
...
...
h2/src/test/org/h2/test/scripts/testScript.sql
浏览文件 @
171b112a
...
...
@@ -3077,17 +3077,17 @@ SELECT t.f1, t.f2 FROM test t ORDER BY t.f2;
> abc 333
> rows (ordered): 3
SELECT t1.f1, t1.f2, t2.f1, t2.f2 FROM test t1, test t2 ORDER BY t2.f2;
SELECT t1.f1, t1.f2, t2.f1, t2.f2 FROM test t1, test t2 ORDER BY t2.f2
, t1.f2
;
> F1 F2 F1 F2
> --- --- --- ---
> abc 222 abc 111
> abc 111 abc 111
> abc 222 abc 111
> abc 333 abc 111
> abc 222 abc 222
> abc 111 abc 222
> abc 222 abc 222
> abc 333 abc 222
> abc 222 abc 333
> abc 111 abc 333
> abc 222 abc 333
> abc 333 abc 333
> rows (ordered): 9
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论