Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
006fe1b0
Unverified
提交
006fe1b0
authored
7月 26, 2018
作者:
Andrei Tokar
提交者:
GitHub
7月 26, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1328 from h2database/issue#1327
Change MVSecondaryIndex uniqueness check
上级
a55fda66
046cb0a6
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
118 行增加
和
168 行删除
+118
-168
Comparison.java
h2/src/main/org/h2/expression/Comparison.java
+9
-5
ExpressionColumn.java
h2/src/main/org/h2/expression/ExpressionColumn.java
+1
-1
MVPlainTempResult.java
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
+1
-1
MVPrimaryIndex.java
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
+2
-3
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+54
-128
MVSortedTempResult.java
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
+2
-2
MVSpatialIndex.java
h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
+1
-1
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+2
-3
ValueDataType.java
h2/src/main/org/h2/mvstore/db/ValueDataType.java
+33
-2
Recover.java
h2/src/main/org/h2/tools/Recover.java
+3
-12
testScript.sql
h2/src/test/org/h2/test/scripts/testScript.sql
+10
-10
没有找到文件。
h2/src/main/org/h2/expression/Comparison.java
浏览文件 @
006fe1b0
...
@@ -465,12 +465,16 @@ public class Comparison extends Condition {
...
@@ -465,12 +465,16 @@ public class Comparison extends Condition {
}
}
if
(
addIndex
)
{
if
(
addIndex
)
{
if
(
l
!=
null
)
{
if
(
l
!=
null
)
{
filter
.
addIndexCondition
(
if
(
l
.
getType
()
==
right
.
getType
()
||
right
.
getType
()
!=
Value
.
STRING_IGNORECASE
)
{
IndexCondition
.
get
(
compareType
,
l
,
right
));
filter
.
addIndexCondition
(
IndexCondition
.
get
(
compareType
,
l
,
right
));
}
}
else
if
(
r
!=
null
)
{
}
else
if
(
r
!=
null
)
{
int
compareRev
=
getReversedCompareType
(
compareType
);
if
(
r
.
getType
()
==
left
.
getType
()
||
left
.
getType
()
!=
Value
.
STRING_IGNORECASE
)
{
filter
.
addIndexCondition
(
int
compareRev
=
getReversedCompareType
(
compareType
);
IndexCondition
.
get
(
compareRev
,
r
,
left
));
filter
.
addIndexCondition
(
IndexCondition
.
get
(
compareRev
,
r
,
left
));
}
}
}
}
}
}
}
...
...
h2/src/main/org/h2/expression/ExpressionColumn.java
浏览文件 @
006fe1b0
...
@@ -199,7 +199,7 @@ public class ExpressionColumn extends Expression {
...
@@ -199,7 +199,7 @@ public class ExpressionColumn extends Expression {
@Override
@Override
public
int
getType
()
{
public
int
getType
()
{
return
column
.
getType
();
return
column
==
null
?
Value
.
UNKNOWN
:
column
.
getType
();
}
}
@Override
@Override
...
...
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
浏览文件 @
006fe1b0
...
@@ -60,7 +60,7 @@ class MVPlainTempResult extends MVTempResult {
...
@@ -60,7 +60,7 @@ class MVPlainTempResult extends MVTempResult {
*/
*/
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
,
int
visibleColumnCount
)
{
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
,
int
visibleColumnCount
)
{
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
ValueDataType
valueType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
columnCount
]);
ValueDataType
valueType
=
new
ValueDataType
(
database
,
new
int
[
columnCount
]);
Builder
<
Long
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
Long
,
ValueArray
>()
Builder
<
Long
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
Long
,
ValueArray
>()
.
valueType
(
valueType
).
singleWriter
();
.
valueType
(
valueType
).
singleWriter
();
map
=
store
.
openMap
(
"tmp"
,
builder
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
...
...
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
浏览文件 @
006fe1b0
...
@@ -51,9 +51,8 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -51,9 +51,8 @@ public class MVPrimaryIndex extends BaseIndex {
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
sortTypes
[
i
]
=
SortOrder
.
ASCENDING
;
sortTypes
[
i
]
=
SortOrder
.
ASCENDING
;
}
}
ValueDataType
keyType
=
new
ValueDataType
(
null
,
null
,
null
);
ValueDataType
keyType
=
new
ValueDataType
();
ValueDataType
valueType
=
new
ValueDataType
(
db
.
getCompareMode
(),
db
,
ValueDataType
valueType
=
new
ValueDataType
(
db
,
sortTypes
);
sortTypes
);
mapName
=
"table."
+
getId
();
mapName
=
"table."
+
getId
();
Transaction
t
=
mvTable
.
getTransactionBegin
();
Transaction
t
=
mvTable
.
getTransactionBegin
();
dataMap
=
t
.
openMap
(
mapName
,
keyType
,
valueType
);
dataMap
=
t
.
openMap
(
mapName
,
keyType
,
valueType
);
...
...
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
浏览文件 @
006fe1b0
...
@@ -62,9 +62,8 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -62,9 +62,8 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
sortTypes
[
i
]
=
columns
[
i
].
sortType
;
sortTypes
[
i
]
=
columns
[
i
].
sortType
;
}
}
sortTypes
[
keyColumns
-
1
]
=
SortOrder
.
ASCENDING
;
sortTypes
[
keyColumns
-
1
]
=
SortOrder
.
ASCENDING
;
ValueDataType
keyType
=
new
ValueDataType
(
ValueDataType
keyType
=
new
ValueDataType
(
db
,
sortTypes
);
db
.
getCompareMode
(),
db
,
sortTypes
);
ValueDataType
valueType
=
new
ValueDataType
();
ValueDataType
valueType
=
new
ValueDataType
(
null
,
null
,
null
);
Transaction
t
=
mvTable
.
getTransactionBegin
();
Transaction
t
=
mvTable
.
getTransactionBegin
();
dataMap
=
t
.
openMap
(
mapName
,
keyType
,
valueType
);
dataMap
=
t
.
openMap
(
mapName
,
keyType
,
valueType
);
dataMap
.
map
.
setVolatile
(!
indexType
.
isPersistent
());
dataMap
.
map
.
setVolatile
(!
indexType
.
isPersistent
());
...
@@ -128,25 +127,18 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -128,25 +127,18 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
for
(
String
bufferName
:
bufferNames
)
{
for
(
String
bufferName
:
bufferNames
)
{
Iterator
<
ValueArray
>
iter
=
openMap
(
bufferName
).
keyIterator
(
null
);
Iterator
<
ValueArray
>
iter
=
openMap
(
bufferName
).
keyIterator
(
null
);
if
(
iter
.
hasNext
())
{
if
(
iter
.
hasNext
())
{
queue
.
add
(
new
Source
(
iter
));
queue
.
offer
(
new
Source
(
iter
));
}
}
}
}
try
{
try
{
while
(!
queue
.
isEmpty
())
{
while
(!
queue
.
isEmpty
())
{
Source
s
=
queue
.
remove
();
Source
s
=
queue
.
poll
();
ValueArray
rowData
=
s
.
next
();
ValueArray
rowData
=
s
.
next
();
SearchRow
row
=
convertToSearchRow
(
rowData
);
if
(
indexType
.
isUnique
())
{
if
(
indexType
.
isUnique
()
&&
!
mayHaveNullDuplicates
(
row
))
{
Value
[]
array
=
rowData
.
getList
();
checkUnique
(
dataMap
,
rowData
,
Long
.
MIN_VALUE
);
// don't change the original value
array
=
array
.
clone
();
array
[
keyColumns
-
1
]
=
ValueLong
.
MIN
;
ValueArray
unique
=
ValueArray
.
get
(
array
);
SearchRow
row
=
convertToSearchRow
(
rowData
);
if
(!
mayHaveNullDuplicates
(
row
))
{
requireUnique
(
row
,
dataMap
,
unique
);
}
}
}
dataMap
.
putCommitted
(
rowData
,
ValueNull
.
INSTANCE
);
dataMap
.
putCommitted
(
rowData
,
ValueNull
.
INSTANCE
);
...
@@ -169,9 +161,8 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -169,9 +161,8 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
sortTypes
[
i
]
=
indexColumns
[
i
].
sortType
;
sortTypes
[
i
]
=
indexColumns
[
i
].
sortType
;
}
}
sortTypes
[
keyColumns
-
1
]
=
SortOrder
.
ASCENDING
;
sortTypes
[
keyColumns
-
1
]
=
SortOrder
.
ASCENDING
;
ValueDataType
keyType
=
new
ValueDataType
(
ValueDataType
keyType
=
new
ValueDataType
(
database
,
sortTypes
);
database
.
getCompareMode
(),
database
,
sortTypes
);
ValueDataType
valueType
=
new
ValueDataType
();
ValueDataType
valueType
=
new
ValueDataType
(
null
,
null
,
null
);
MVMap
.
Builder
<
ValueArray
,
Value
>
builder
=
MVMap
.
Builder
<
ValueArray
,
Value
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Value
>()
new
MVMap
.
Builder
<
ValueArray
,
Value
>()
.
singleWriter
()
.
singleWriter
()
...
@@ -195,50 +186,35 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -195,50 +186,35 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
public
void
add
(
Session
session
,
Row
row
)
{
public
void
add
(
Session
session
,
Row
row
)
{
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
ValueArray
array
=
convertToKey
(
row
);
ValueArray
array
=
convertToKey
(
row
);
ValueArray
unique
=
null
;
boolean
checkRequired
=
indexType
.
isUnique
()
&&
!
mayHaveNullDuplicates
(
row
);
if
(
indexType
.
isUnique
())
{
if
(
checkRequired
)
{
// this will detect committed entries only
checkUnique
(
map
,
array
,
Long
.
MIN_VALUE
);
unique
=
convertToKey
(
row
);
unique
.
getList
()[
keyColumns
-
1
]
=
ValueLong
.
MIN
;
if
(
mayHaveNullDuplicates
(
row
))
{
// No further unique checks required
unique
=
null
;
}
else
{
requireUnique
(
row
,
map
,
unique
);
}
}
}
try
{
try
{
map
.
put
(
array
,
ValueNull
.
INSTANCE
);
map
.
put
(
array
,
ValueNull
.
INSTANCE
);
}
catch
(
IllegalStateException
e
)
{
}
catch
(
IllegalStateException
e
)
{
throw
mvTable
.
convertException
(
e
);
throw
mvTable
.
convertException
(
e
);
}
}
if
(
unique
!=
null
)
{
// This code expects that mayHaveDuplicates(row) == false
if
(
checkRequired
)
{
Iterator
<
Value
>
it
=
map
.
keyIterator
(
unique
,
null
,
true
);
checkUnique
(
map
,
array
,
row
.
getKey
());
while
(
it
.
hasNext
())
{
ValueArray
k
=
(
ValueArray
)
it
.
next
();
if
(
compareRows
(
row
,
convertToSearchRow
(
k
))
!=
0
)
{
break
;
}
if
(
map
.
isSameTransaction
(
k
))
{
continue
;
}
if
(
map
.
get
(
k
)
!=
null
)
{
// committed
throw
getDuplicateKeyException
(
k
.
toString
());
}
throw
DbException
.
get
(
ErrorCode
.
CONCURRENT_UPDATE_1
,
table
.
getName
());
}
}
}
}
}
private
void
requireUnique
(
SearchRow
row
,
TransactionMap
<
Value
,
Value
>
map
,
ValueArray
unique
)
{
private
void
checkUnique
(
TransactionMap
<
Value
,
Value
>
map
,
ValueArray
row
,
long
newKey
)
{
Value
key
=
map
.
ceilingKey
(
unique
);
Iterator
<
Value
>
it
=
map
.
keyIterator
(
convertToKey
(
row
,
Boolean
.
FALSE
),
convertToKey
(
row
,
Boolean
.
TRUE
),
true
);
if
(
key
!=
null
)
{
while
(
it
.
hasNext
())
{
ValueArray
k
=
(
ValueArray
)
key
;
ValueArray
rowData
=
(
ValueArray
)
it
.
next
();
if
(
compareRows
(
row
,
convertToSearchRow
(
k
))
==
0
)
{
Value
[]
array
=
rowData
.
getList
();
// committed
Value
rowKey
=
array
[
array
.
length
-
1
];
throw
getDuplicateKeyException
(
k
.
toString
());
long
rowId
=
rowKey
.
getLong
();
if
(
newKey
!=
rowId
)
{
if
(
map
.
get
(
rowData
)
!=
null
)
{
// committed
throw
getDuplicateKeyException
(
rowKey
.
toString
());
}
throw
DbException
.
get
(
ErrorCode
.
CONCURRENT_UPDATE_1
,
table
.
getName
());
}
}
}
}
}
}
...
@@ -285,58 +261,23 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -285,58 +261,23 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
}
}
private
Cursor
find
(
Session
session
,
SearchRow
first
,
boolean
bigger
,
SearchRow
last
)
{
private
Cursor
find
(
Session
session
,
SearchRow
first
,
boolean
bigger
,
SearchRow
last
)
{
ValueArray
min
=
convertToKey
(
first
);
ValueArray
min
=
convertToKey
(
convertToKey
(
first
),
bigger
);
if
(
min
!=
null
)
{
ValueArray
max
=
convertToKey
(
convertToKey
(
last
),
Boolean
.
TRUE
);
min
.
getList
()[
keyColumns
-
1
]
=
ValueLong
.
MIN
;
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
return
new
MVStoreCursor
(
session
,
map
.
keyIterator
(
min
,
max
,
false
));
}
private
static
ValueArray
convertToKey
(
ValueArray
r
,
Boolean
minmax
)
{
if
(
r
==
null
)
{
return
null
;
}
}
TransactionMap
<
Value
,
Value
>
map
=
getMap
(
session
);
if
(
bigger
&&
min
!=
null
)
{
Value
[]
values
=
r
.
getList
().
clone
();
// search for the next: first skip 1, then 2, 4, 8, until
ValueArray
row
=
ValueArray
.
get
(
values
);
// we have a higher key; then skip 4, 2,...
if
(
minmax
!=
null
)
{
// (binary search), until 1
values
[
values
.
length
-
1
]
=
ValueLong
.
get
(
minmax
?
Long
.
MAX_VALUE
:
Long
.
MIN_VALUE
);
int
offset
=
1
;
while
(
true
)
{
ValueArray
v
=
(
ValueArray
)
map
.
relativeKey
(
min
,
offset
);
if
(
v
!=
null
)
{
boolean
foundHigher
=
false
;
for
(
int
i
=
0
;
i
<
keyColumns
-
1
;
i
++)
{
int
idx
=
columnIds
[
i
];
Value
b
=
first
.
getValue
(
idx
);
if
(
b
==
null
)
{
break
;
}
Value
a
=
v
.
getList
()[
i
];
if
(
database
.
compare
(
a
,
b
)
>
0
)
{
foundHigher
=
true
;
break
;
}
}
if
(!
foundHigher
)
{
offset
+=
offset
;
min
=
v
;
continue
;
}
}
if
(
offset
>
1
)
{
offset
/=
2
;
continue
;
}
if
(
map
.
get
(
v
)
==
null
)
{
min
=
(
ValueArray
)
map
.
higherKey
(
min
);
if
(
min
==
null
)
{
break
;
}
continue
;
}
min
=
v
;
break
;
}
if
(
min
==
null
)
{
return
new
MVStoreCursor
(
session
,
Collections
.<
Value
>
emptyIterator
(),
null
);
}
}
}
return
new
MVStoreCursor
(
session
,
map
.
keyIterator
(
min
),
last
)
;
return
row
;
}
}
private
ValueArray
convertToKey
(
SearchRow
r
)
{
private
ValueArray
convertToKey
(
SearchRow
r
)
{
...
@@ -349,7 +290,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -349,7 +290,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
int
idx
=
c
.
getColumnId
();
int
idx
=
c
.
getColumnId
();
Value
v
=
r
.
getValue
(
idx
);
Value
v
=
r
.
getValue
(
idx
);
if
(
v
!=
null
)
{
if
(
v
!=
null
)
{
array
[
i
]
=
v
.
convertTo
(
c
.
getType
(),
-
1
,
null
,
database
.
getMode
()
,
c
.
getEnumerators
());
array
[
i
]
=
v
.
convertTo
(
c
.
getType
(),
-
1
,
database
.
getMode
(),
null
,
c
.
getEnumerators
());
}
}
}
}
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
r
.
getKey
());
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
r
.
getKey
());
...
@@ -420,7 +361,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -420,7 +361,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
while
(
true
)
{
while
(
true
)
{
if
(
key
==
null
)
{
if
(
key
==
null
)
{
return
new
MVStoreCursor
(
session
,
return
new
MVStoreCursor
(
session
,
Collections
.<
Value
>
emptyIterator
()
,
null
);
Collections
.<
Value
>
emptyIterator
());
}
}
if
(((
ValueArray
)
key
).
getList
()[
0
]
!=
ValueNull
.
INSTANCE
)
{
if
(((
ValueArray
)
key
).
getList
()[
0
]
!=
ValueNull
.
INSTANCE
)
{
break
;
break
;
...
@@ -428,7 +369,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -428,7 +369,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
key
=
first
?
map
.
higherKey
(
key
)
:
map
.
lowerKey
(
key
);
key
=
first
?
map
.
higherKey
(
key
)
:
map
.
lowerKey
(
key
);
}
}
MVStoreCursor
cursor
=
new
MVStoreCursor
(
session
,
MVStoreCursor
cursor
=
new
MVStoreCursor
(
session
,
Collections
.
singletonList
(
key
).
iterator
()
,
null
);
Collections
.
singletonList
(
key
).
iterator
());
cursor
.
next
();
cursor
.
next
();
return
cursor
;
return
cursor
;
}
}
...
@@ -499,23 +440,20 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -499,23 +440,20 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
private
final
Session
session
;
private
final
Session
session
;
private
final
Iterator
<
Value
>
it
;
private
final
Iterator
<
Value
>
it
;
private
final
SearchRow
last
;
private
ValueArray
current
;
private
Value
current
;
private
SearchRow
searchRow
;
private
Row
row
;
private
Row
row
;
MVStoreCursor
(
Session
session
,
Iterator
<
Value
>
it
,
SearchRow
last
)
{
MVStoreCursor
(
Session
session
,
Iterator
<
Value
>
it
)
{
this
.
session
=
session
;
this
.
session
=
session
;
this
.
it
=
it
;
this
.
it
=
it
;
this
.
last
=
last
;
}
}
@Override
@Override
public
Row
get
()
{
public
Row
get
()
{
if
(
row
==
null
)
{
if
(
row
==
null
)
{
SearchRow
r
=
getSearchRow
();
if
(
current
!=
null
)
{
if
(
r
!=
null
)
{
Value
[]
values
=
current
.
getList
();
row
=
mvTable
.
getRow
(
session
,
r
.
getKey
());
row
=
mvTable
.
getRow
(
session
,
values
[
values
.
length
-
1
].
getLong
());
}
}
}
}
return
row
;
return
row
;
...
@@ -523,24 +461,12 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
...
@@ -523,24 +461,12 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
@Override
@Override
public
SearchRow
getSearchRow
()
{
public
SearchRow
getSearchRow
()
{
if
(
searchRow
==
null
)
{
return
current
==
null
?
null
:
convertToSearchRow
(
current
);
if
(
current
!=
null
)
{
searchRow
=
convertToSearchRow
((
ValueArray
)
current
);
}
}
return
searchRow
;
}
}
@Override
@Override
public
boolean
next
()
{
public
boolean
next
()
{
current
=
it
.
hasNext
()
?
it
.
next
()
:
null
;
current
=
it
.
hasNext
()
?
(
ValueArray
)
it
.
next
()
:
null
;
searchRow
=
null
;
if
(
current
!=
null
)
{
if
(
last
!=
null
&&
compareRows
(
getSearchRow
(),
last
)
>
0
)
{
searchRow
=
null
;
current
=
null
;
}
}
row
=
null
;
row
=
null
;
return
current
!=
null
;
return
current
!=
null
;
}
}
...
...
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
浏览文件 @
006fe1b0
...
@@ -166,12 +166,12 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -166,12 +166,12 @@ class MVSortedTempResult extends MVTempResult {
indexes
=
null
;
indexes
=
null
;
}
}
this
.
indexes
=
indexes
;
this
.
indexes
=
indexes
;
ValueDataType
keyType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
sortTypes
);
ValueDataType
keyType
=
new
ValueDataType
(
database
,
sortTypes
);
Builder
<
ValueArray
,
Long
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Long
>().
keyType
(
keyType
);
Builder
<
ValueArray
,
Long
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Long
>().
keyType
(
keyType
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
if
(
distinct
&&
length
!=
visibleColumnCount
||
distinctIndexes
!=
null
)
{
if
(
distinct
&&
length
!=
visibleColumnCount
||
distinctIndexes
!=
null
)
{
int
count
=
distinctIndexes
!=
null
?
distinctIndexes
.
length
:
visibleColumnCount
;
int
count
=
distinctIndexes
!=
null
?
distinctIndexes
.
length
:
visibleColumnCount
;
ValueDataType
distinctType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
count
]);
ValueDataType
distinctType
=
new
ValueDataType
(
database
,
new
int
[
count
]);
Builder
<
ValueArray
,
Boolean
>
indexBuilder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
distinctType
);
Builder
<
ValueArray
,
Boolean
>
indexBuilder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
distinctType
);
index
=
store
.
openMap
(
"idx"
,
indexBuilder
);
index
=
store
.
openMap
(
"idx"
,
indexBuilder
);
}
}
...
...
h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
浏览文件 @
006fe1b0
...
@@ -93,7 +93,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
...
@@ -93,7 +93,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
checkIndexColumnTypes
(
columns
);
checkIndexColumnTypes
(
columns
);
}
}
String
mapName
=
"index."
+
getId
();
String
mapName
=
"index."
+
getId
();
ValueDataType
vt
=
new
ValueDataType
(
null
,
null
,
null
);
ValueDataType
vt
=
new
ValueDataType
(
db
,
null
);
VersionedValue
.
Type
valueType
=
new
VersionedValue
.
Type
(
vt
);
VersionedValue
.
Type
valueType
=
new
VersionedValue
.
Type
(
vt
);
MVRTreeMap
.
Builder
<
VersionedValue
>
mapBuilder
=
MVRTreeMap
.
Builder
<
VersionedValue
>
mapBuilder
=
new
MVRTreeMap
.
Builder
<
VersionedValue
>().
new
MVRTreeMap
.
Builder
<
VersionedValue
>().
...
...
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
006fe1b0
...
@@ -160,9 +160,8 @@ public class MVTableEngine implements TableEngine {
...
@@ -160,9 +160,8 @@ public class MVTableEngine implements TableEngine {
if
(!
db
.
getSettings
().
reuseSpace
)
{
if
(!
db
.
getSettings
().
reuseSpace
)
{
store
.
setReuseSpace
(
false
);
store
.
setReuseSpace
(
false
);
}
}
this
.
transactionStore
=
new
TransactionStore
(
this
.
transactionStore
=
new
TransactionStore
(
store
,
store
,
new
ValueDataType
(
db
,
null
),
db
.
getLockTimeout
());
new
ValueDataType
(
db
.
getCompareMode
(),
db
,
null
),
db
.
getLockTimeout
());
}
catch
(
IllegalStateException
e
)
{
}
catch
(
IllegalStateException
e
)
{
throw
convertIllegalStateException
(
e
);
throw
convertIllegalStateException
(
e
);
}
}
...
...
h2/src/main/org/h2/mvstore/db/ValueDataType.java
浏览文件 @
006fe1b0
...
@@ -12,7 +12,10 @@ import java.sql.ResultSet;
...
@@ -12,7 +12,10 @@ import java.sql.ResultSet;
import
java.sql.ResultSetMetaData
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Objects
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Mode
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.WriteBuffer
;
...
@@ -33,6 +36,7 @@ import org.h2.value.ValueBytes;
...
@@ -33,6 +36,7 @@ import org.h2.value.ValueBytes;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueDouble
;
import
org.h2.value.ValueDouble
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueFloat
;
import
org.h2.value.ValueFloat
;
import
org.h2.value.ValueGeometry
;
import
org.h2.value.ValueGeometry
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInt
;
...
@@ -73,12 +77,22 @@ public class ValueDataType implements DataType {
...
@@ -73,12 +77,22 @@ public class ValueDataType implements DataType {
final
DataHandler
handler
;
final
DataHandler
handler
;
final
CompareMode
compareMode
;
final
CompareMode
compareMode
;
protected
final
Mode
mode
;
final
int
[]
sortTypes
;
final
int
[]
sortTypes
;
SpatialDataType
spatialType
;
SpatialDataType
spatialType
;
public
ValueDataType
(
CompareMode
compareMode
,
DataHandler
handler
,
public
ValueDataType
()
{
this
(
CompareMode
.
getInstance
(
null
,
0
),
Mode
.
getRegular
(),
null
,
null
);
}
public
ValueDataType
(
Database
database
,
int
[]
sortTypes
)
{
this
(
database
.
getCompareMode
(),
database
.
getMode
(),
database
,
sortTypes
);
}
private
ValueDataType
(
CompareMode
compareMode
,
Mode
mode
,
DataHandler
handler
,
int
[]
sortTypes
)
{
int
[]
sortTypes
)
{
this
.
compareMode
=
compareMode
;
this
.
compareMode
=
compareMode
;
this
.
mode
=
mode
;
this
.
handler
=
handler
;
this
.
handler
=
handler
;
this
.
sortTypes
=
sortTypes
;
this
.
sortTypes
=
sortTypes
;
}
}
...
@@ -103,7 +117,13 @@ public class ValueDataType implements DataType {
...
@@ -103,7 +117,13 @@ public class ValueDataType implements DataType {
int
len
=
Math
.
min
(
al
,
bl
);
int
len
=
Math
.
min
(
al
,
bl
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
sortType
=
sortTypes
==
null
?
SortOrder
.
ASCENDING
:
sortTypes
[
i
];
int
sortType
=
sortTypes
==
null
?
SortOrder
.
ASCENDING
:
sortTypes
[
i
];
int
comp
=
compareValues
(
ax
[
i
],
bx
[
i
],
sortType
);
Value
one
=
ax
[
i
];
Value
two
=
bx
[
i
];
if
(
one
==
null
||
two
==
null
)
{
return
compareValues
(
ax
[
len
-
1
],
bx
[
len
-
1
],
SortOrder
.
ASCENDING
);
}
int
comp
=
compareValues
(
one
,
two
,
sortType
);
if
(
comp
!=
0
)
{
if
(
comp
!=
0
)
{
return
comp
;
return
comp
;
}
}
...
@@ -136,7 +156,18 @@ public class ValueDataType implements DataType {
...
@@ -136,7 +156,18 @@ public class ValueDataType implements DataType {
if
(
aNull
||
bNull
)
{
if
(
aNull
||
bNull
)
{
return
SortOrder
.
compareNull
(
aNull
,
sortType
);
return
SortOrder
.
compareNull
(
aNull
,
sortType
);
}
}
int
t2
=
Value
.
getHigherOrder
(
a
.
getType
(),
b
.
getType
());
if
(
t2
==
Value
.
ENUM
)
{
String
[]
enumerators
=
ValueEnum
.
getEnumeratorsForBinaryOperation
(
a
,
b
);
a
=
a
.
convertToEnum
(
enumerators
);
b
=
b
.
convertToEnum
(
enumerators
);
}
else
{
a
=
a
.
convertTo
(
t2
,
-
1
,
mode
);
b
=
b
.
convertTo
(
t2
,
-
1
,
mode
);
}
int
comp
=
a
.
compareTypeSafe
(
b
,
compareMode
);
int
comp
=
a
.
compareTypeSafe
(
b
,
compareMode
);
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
comp
=
-
comp
;
comp
=
-
comp
;
}
}
...
...
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
006fe1b0
...
@@ -616,18 +616,14 @@ public class Recover extends Tool implements DataHandler {
...
@@ -616,18 +616,14 @@ public class Recover extends Tool implements DataHandler {
}
}
try
{
try
{
// extract the metadata so we can dump the settings
// extract the metadata so we can dump the settings
ValueDataType
type
=
new
ValueDataType
();
for
(
String
mapName
:
mv
.
getMapNames
())
{
for
(
String
mapName
:
mv
.
getMapNames
())
{
if
(!
mapName
.
startsWith
(
"table."
))
{
if
(!
mapName
.
startsWith
(
"table."
))
{
continue
;
continue
;
}
}
String
tableId
=
mapName
.
substring
(
"table."
.
length
());
String
tableId
=
mapName
.
substring
(
"table."
.
length
());
if
(
Integer
.
parseInt
(
tableId
)
==
0
)
{
if
(
Integer
.
parseInt
(
tableId
)
==
0
)
{
ValueDataType
keyType
=
new
ValueDataType
(
TransactionMap
<
Value
,
Value
>
dataMap
=
store
.
begin
().
openMap
(
mapName
,
type
,
type
);
null
,
this
,
null
);
ValueDataType
valueType
=
new
ValueDataType
(
null
,
this
,
null
);
TransactionMap
<
Value
,
Value
>
dataMap
=
store
.
begin
().
openMap
(
mapName
,
keyType
,
valueType
);
Iterator
<
Value
>
dataIt
=
dataMap
.
keyIterator
(
null
);
Iterator
<
Value
>
dataIt
=
dataMap
.
keyIterator
(
null
);
while
(
dataIt
.
hasNext
())
{
while
(
dataIt
.
hasNext
())
{
Value
rowId
=
dataIt
.
next
();
Value
rowId
=
dataIt
.
next
();
...
@@ -660,12 +656,7 @@ public class Recover extends Tool implements DataHandler {
...
@@ -660,12 +656,7 @@ public class Recover extends Tool implements DataHandler {
if
(
Integer
.
parseInt
(
tableId
)
==
0
)
{
if
(
Integer
.
parseInt
(
tableId
)
==
0
)
{
continue
;
continue
;
}
}
ValueDataType
keyType
=
new
ValueDataType
(
TransactionMap
<
Value
,
Value
>
dataMap
=
store
.
begin
().
openMap
(
mapName
,
type
,
type
);
null
,
this
,
null
);
ValueDataType
valueType
=
new
ValueDataType
(
null
,
this
,
null
);
TransactionMap
<
Value
,
Value
>
dataMap
=
store
.
begin
().
openMap
(
mapName
,
keyType
,
valueType
);
Iterator
<
Value
>
dataIt
=
dataMap
.
keyIterator
(
null
);
Iterator
<
Value
>
dataIt
=
dataMap
.
keyIterator
(
null
);
boolean
init
=
false
;
boolean
init
=
false
;
while
(
dataIt
.
hasNext
())
{
while
(
dataIt
.
hasNext
())
{
...
...
h2/src/test/org/h2/test/scripts/testScript.sql
浏览文件 @
006fe1b0
...
@@ -2866,7 +2866,7 @@ CREATE TABLE TEST2(ID INT PRIMARY KEY, NAME VARCHAR(255));
...
@@ -2866,7 +2866,7 @@ CREATE TABLE TEST2(ID INT PRIMARY KEY, NAME VARCHAR(255));
create unique index idx_test2_name on test2(name);
create unique index idx_test2_name on test2(name);
> ok
> ok
INSERT INTO TEST2 VALUES(1, '
H
ElLo
');
INSERT INTO TEST2 VALUES(1, '
h
ElLo
');
> update count: 1
> update count: 1
INSERT INTO TEST2 VALUES(2, '
World
');
INSERT INTO TEST2 VALUES(2, '
World
');
...
@@ -2886,7 +2886,7 @@ select * from test where name='HELLO';
...
@@ -2886,7 +2886,7 @@ select * from test where name='HELLO';
select * from test2 where name='
HELLO
';
select * from test2 where name='
HELLO
';
> ID NAME
> ID NAME
> -- -----
> -- -----
> 1
H
ElLo
> 1
h
ElLo
> rows: 1
> rows: 1
select * from test where name like '
HELLO
';
select * from test where name like '
HELLO
';
...
@@ -2897,26 +2897,26 @@ select * from test where name like 'HELLO';
...
@@ -2897,26 +2897,26 @@ select * from test where name like 'HELLO';
select * from test2 where name like '
HELLO
';
select * from test2 where name like '
HELLO
';
> ID NAME
> ID NAME
> -- -----
> -- -----
> 1
H
ElLo
> 1
h
ElLo
> rows: 1
> rows: 1
explain plan for select * from test2, test where test2.name = test.name;
explain plan for select * from test2, test where test2.name = test.name;
>> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.
IDX_TEST_NAME: NAME = TEST2.NAME
*/ ON 1=1 WHERE TEST2.NAME = TEST.NAME
>> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.
TEST.tableScan
*/ ON 1=1 WHERE TEST2.NAME = TEST.NAME
select * from test2, test where test2.name = test.name;
select * from test2, test where test2.name = test.name;
> ID NAME ID NAME
> ID NAME ID NAME
> -- ----- -- -----
> -- ----- -- -----
> 1
H
ElLo 1 Hello
> 1
h
ElLo 1 Hello
> 2 World 2 World
> 2 World 2 World
> rows: 2
> rows: 2
explain plan for select * from test, test2 where test2.name = test.name;
explain plan for select * from test, test2 where test2.name = test.name;
>> SELECT TEST.ID, TEST.NAME, TEST2.ID, TEST2.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.
IDX_TEST_NAME: NAME = TEST2.NAME
*/ ON 1=1 WHERE TEST2.NAME = TEST.NAME
>> SELECT TEST.ID, TEST.NAME, TEST2.ID, TEST2.NAME FROM PUBLIC.TEST2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.
TEST.tableScan
*/ ON 1=1 WHERE TEST2.NAME = TEST.NAME
select * from test, test2 where test2.name = test.name;
select * from test, test2 where test2.name = test.name;
> ID NAME ID NAME
> ID NAME ID NAME
> -- ----- -- -----
> -- ----- -- -----
> 1 Hello 1
H
ElLo
> 1 Hello 1
h
ElLo
> 2 World 2 World
> 2 World 2 World
> rows: 2
> rows: 2
...
@@ -2924,12 +2924,12 @@ create index idx_test2_name on test2(name);
...
@@ -2924,12 +2924,12 @@ create index idx_test2_name on test2(name);
> ok
> ok
explain plan for select * from test2, test where test2.name = test.name;
explain plan for select * from test2, test where test2.name = test.name;
>> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST
2 /* PUBLIC.TEST2.tableScan */ INNER JOIN PUBLIC.TEST /* PUBLIC.IDX_TEST_NAME: NAME = TEST2
.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME
>> SELECT TEST2.ID, TEST2.NAME, TEST.ID, TEST.NAME FROM PUBLIC.TEST
/* PUBLIC.TEST.tableScan */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.IDX_TEST2_NAME: NAME = TEST
.NAME */ ON 1=1 WHERE TEST2.NAME = TEST.NAME
select * from test2, test where test2.name = test.name;
select * from test2, test where test2.name = test.name;
> ID NAME ID NAME
> ID NAME ID NAME
> -- ----- -- -----
> -- ----- -- -----
> 1
H
ElLo 1 Hello
> 1
h
ElLo 1 Hello
> 2 World 2 World
> 2 World 2 World
> rows: 2
> rows: 2
...
@@ -2939,7 +2939,7 @@ explain plan for select * from test, test2 where test2.name = test.name;
...
@@ -2939,7 +2939,7 @@ explain plan for select * from test, test2 where test2.name = test.name;
select * from test, test2 where test2.name = test.name;
select * from test, test2 where test2.name = test.name;
> ID NAME ID NAME
> ID NAME ID NAME
> -- ----- -- -----
> -- ----- -- -----
> 1 Hello 1
H
ElLo
> 1 Hello 1
h
ElLo
> 2 World 2 World
> 2 World 2 World
> rows: 2
> rows: 2
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论