Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
006fe1b0
Unverified
提交
006fe1b0
authored
6 年前
作者:
Andrei Tokar
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
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
));
}
}
}
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
;
}
}
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
...
...
This diff is collapsed.
Click to expand it.
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
>().
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
...
...
This diff is collapsed.
Click to expand it.
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
;
}
}
...
...
This diff is collapsed.
Click to expand it.
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
())
{
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论