Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6b606ae5
提交
6b606ae5
authored
8月 23, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
43fa251a
隐藏空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
319 行增加
和
151 行删除
+319
-151
features.html
h2/src/docsrc/html/features.html
+1
-1
history.html
h2/src/docsrc/html/history.html
+5
-3
mainWeb.html
h2/src/docsrc/html/mainWeb.html
+19
-18
Query.java
h2/src/main/org/h2/command/dml/Query.java
+4
-2
MultiVersionCursor.java
h2/src/main/org/h2/index/MultiVersionCursor.java
+92
-82
MultiVersionIndex.java
h2/src/main/org/h2/index/MultiVersionIndex.java
+10
-11
ScanCursor.java
h2/src/main/org/h2/index/ScanCursor.java
+11
-2
ScanIndex.java
h2/src/main/org/h2/index/ScanIndex.java
+24
-2
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+6
-0
TableData.java
h2/src/main/org/h2/table/TableData.java
+6
-0
TableView.java
h2/src/main/org/h2/table/TableView.java
+21
-3
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+8
-17
test.properties
h2/src/test/org/h2/test/bench/test.properties
+4
-4
TestView.java
h2/src/test/org/h2/test/db/TestView.java
+32
-0
TestMVCC.java
h2/src/test/org/h2/test/mvcc/TestMVCC.java
+74
-5
dictionary.txt
h2/src/tools/org/h2/tools/doc/dictionary.txt
+2
-1
没有找到文件。
h2/src/docsrc/html/features.html
浏览文件 @
6b606ae5
...
...
@@ -282,7 +282,7 @@ It looks like the development of this database has stopped. The last release was
<td>
Simple, small and fast object relational mapping.
</td>
</tr><tr>
<td><a
href=
"http://docs.codewave.de/mytunesrss3/"
>
MyTunesRss
</a></td>
<td>
MyTunesRSS lets you listen to your music where
e
ver you are.
</td>
<td>
MyTunesRSS lets you listen to your music wherever you are.
</td>
</tr><tr>
<td><a
href=
"http://www.polepos.org"
>
PolePosition
</a></td>
<td>
Open source database benchmark.
</td>
...
...
h2/src/docsrc/html/history.html
浏览文件 @
6b606ae5
...
...
@@ -42,11 +42,11 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>
Version 1.0 / TODO (Build xx)
</h3><ul>
<li>
New experimental feature MVCC (multi version concurrency control).
Can be set as a option when opening the database (jdbc:h2:test;MVCC=TRUE)
or as a system property (-Dh2.mvcc=true).
or as a system property (-Dh2.mvcc=true). This is work-in-progress, use it at your own risk. Feedback is welcome.
</li><li>
Creating more than 10 views that depend on each other was very slow. Reconnecting was slow as well. Fixed.
</li><li>
When used as as Servlet, the H2 Console did not work with SSL (using Tomcat). Fixed.
</li><li>
When altering a table with foreign key constraint, if there was no manual index created
for the referenced columns, the automatically created index was dropped while still being used.
Fixed.
for the referenced columns, the automatically created index was dropped while still being used. Fixed.
</li><li>
Check and foreign key constraints now checks if the existing data is consistent (this can be disabled by appending NOCHECK).
It is also possible to check existing data when re-enabling referential integrity for a table.
</li><li>
Some unit tests failed on Linux because the file system works differently. The unit tests are fixed and should work now.
...
...
@@ -1137,6 +1137,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>
Provide a simple, lightweight O/R mapping tool
</li><li>
Provide an Java SQL builder with standard and H2 syntax
</li><li>
Data compression for in-memory database
</li><li>
Trace: write os, file system, vm,... when opening the database
</li><li>
Trace: write dangerous operations (set log 0,...) in every case (including when opening the database)
</li></ul>
<h3>
Not Planned
</h3>
...
...
h2/src/docsrc/html/mainWeb.html
浏览文件 @
6b606ae5
...
...
@@ -53,25 +53,26 @@ Welcome to H2, the free SQL database. The main feature of H2 are:
<tr><td
style=
"border: 0px; background-color: #eee;"
>
<h3>
Support
</h3>
<p>
<a
href=
"http://groups.google.com/group/h2-database"
target=
"_top"
>
Google Group: Help and Discussion
</a><br
/><br
/>
Or send an e-mail to:
<br
/>
<script
type=
"text/javascript"
>
<!--
var
a
=
'-support.png'
;
var
b
=
'mail'
;
var
c
=
'support '
;
var
d
=
'db'
;
var
e
=
'at '
;
var
f
=
'.com'
;
var
g
=
'h2database'
;
var
alt
=
'mail address: '
+
d
+
c
+
e
+
g
+
f
+
'(without spaces)'
;
document
.
write
(
'<'
+
'a h'
+
'ref="em'
+
'ail:'
+
d
+
c
+
e
+
g
+
f
+
'">'
+
d
+
c
+
e
+
g
+
f
);
//-->
</script>
</p>
<a
href=
"http://groups.google.com/group/h2-database"
target=
"_top"
>
English Google Group
</a><br
/>
<a
href=
"http://groups.google.co.jp/group/h2-database-jp"
target=
"_top"
>
Japanese Google Group
</a><br
/><br
/>
Or send an e-mail to:
<br
/>
<script
type=
"text/javascript"
>
<!--
var
a
=
'-support.png'
;
var
b
=
'mail'
;
var
c
=
'support '
;
var
d
=
'db'
;
var
e
=
'at '
;
var
f
=
'.com'
;
var
g
=
'h2database'
;
var
alt
=
'mail address: '
+
d
+
c
+
e
+
g
+
f
+
'(without spaces)'
;
document
.
write
(
'<'
+
'a h'
+
'ref="em'
+
'ail:'
+
d
+
c
+
e
+
g
+
f
+
'">'
+
d
+
c
+
e
+
g
+
f
);
//-->
</script>
</p>
</td></tr>
</table>
</td></tr>
</table>
</td></tr>
<tr><td
colspan=
"3"
style=
"border: 0px"
>
</td></tr>
...
...
h2/src/main/org/h2/command/dml/Query.java
浏览文件 @
6b606ae5
...
...
@@ -9,6 +9,7 @@ import java.util.HashSet;
import
org.h2.command.Prepared
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.expression.Alias
;
import
org.h2.expression.Expression
;
...
...
@@ -51,15 +52,16 @@ public abstract class Query extends Prepared {
}
public
final
boolean
sameResultAsLast
(
Session
session
,
Value
[]
params
,
Value
[]
lastParams
,
long
lastEvaluated
)
throws
SQLException
{
Database
db
=
session
.
getDatabase
();
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
{
if
(!
session
.
getDatabase
()
.
areEqual
(
lastParams
[
i
],
params
[
i
]))
{
if
(!
db
.
areEqual
(
lastParams
[
i
],
params
[
i
]))
{
return
false
;
}
}
if
(!
isEverything
(
ExpressionVisitor
.
DETERMINISTIC
)
||
!
isEverything
(
ExpressionVisitor
.
INDEPENDENT
))
{
return
false
;
}
if
(
getMaxDataModificationId
()
>
lastEvaluated
)
{
if
(
db
.
getModificationDataId
()
>
lastEvaluated
&&
getMaxDataModificationId
()
>
lastEvaluated
)
{
return
false
;
}
return
true
;
...
...
h2/src/main/org/h2/index/MultiVersionCursor.java
浏览文件 @
6b606ae5
...
...
@@ -31,120 +31,130 @@ public class MultiVersionCursor implements Cursor {
}
private
void
loadNext
(
boolean
base
)
throws
SQLException
{
if
(
base
)
{
if
(
baseCursor
.
next
())
{
baseRow
=
baseCursor
.
getSearchRow
();
}
else
{
baseRow
=
null
;
}
}
else
{
if
(
deltaCursor
.
next
())
{
deltaRow
=
deltaCursor
.
get
();
synchronized
(
index
)
{
if
(
base
)
{
if
(
baseCursor
.
next
())
{
baseRow
=
baseCursor
.
getSearchRow
();
}
else
{
baseRow
=
null
;
}
}
else
{
deltaRow
=
null
;
if
(
deltaCursor
.
next
())
{
deltaRow
=
deltaCursor
.
get
();
}
else
{
deltaRow
=
null
;
}
}
}
}
public
Row
get
()
throws
SQLException
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
synchronized
(
index
)
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
}
return
onBase
?
baseCursor
.
get
()
:
deltaCursor
.
get
();
}
return
onBase
?
baseCursor
.
get
()
:
deltaCursor
.
get
();
}
public
int
getPos
()
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
synchronized
(
index
)
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
}
return
onBase
?
baseCursor
.
getPos
()
:
deltaCursor
.
getPos
();
}
return
onBase
?
baseCursor
.
getPos
()
:
deltaCursor
.
getPos
();
}
public
SearchRow
getSearchRow
()
throws
SQLException
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
synchronized
(
index
)
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
}
return
onBase
?
baseCursor
.
getSearchRow
()
:
deltaCursor
.
getSearchRow
();
}
return
onBase
?
baseCursor
.
getSearchRow
()
:
deltaCursor
.
getSearchRow
();
}
public
boolean
next
()
throws
SQLException
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
}
while
(
true
)
{
if
(
needNewDelta
)
{
loadNext
(
false
);
needNewDelta
=
false
;
}
if
(
needNewBase
)
{
loadNext
(
true
);
needNewBase
=
false
;
synchronized
(
index
)
{
if
(
SysProperties
.
CHECK
&&
end
)
{
throw
Message
.
getInternalError
();
}
if
(
deltaRow
==
null
)
{
if
(
baseRow
==
null
)
{
end
=
true
;
return
false
;
}
else
{
onBase
=
true
;
needNewBase
=
true
;
return
true
;
while
(
true
)
{
if
(
needNewDelta
)
{
loadNext
(
false
);
needNewDelta
=
false
;
}
}
boolean
isThisSession
=
deltaRow
.
getSessionId
()
==
session
.
getId
();
boolean
isDeleted
=
deltaRow
.
getDeleted
();
if
(
isThisSession
&&
isDeleted
)
{
needNewDelta
=
true
;
continue
;
}
if
(
baseRow
==
null
)
{
if
(
isDeleted
)
{
if
(
isThisSession
)
{
if
(
needNewBase
)
{
loadNext
(
true
);
needNewBase
=
false
;
}
if
(
deltaRow
==
null
)
{
if
(
baseRow
==
null
)
{
end
=
true
;
return
false
;
}
else
{
// the row was deleted by another session: return it
onBase
=
false
;
needNewDelta
=
true
;
onBase
=
true
;
needNewBase
=
true
;
return
true
;
}
}
throw
Message
.
getInternalError
();
}
int
compare
=
index
.
compareRows
(
deltaRow
,
baseRow
);
if
(
compare
==
0
)
{
compare
=
index
.
compareKeys
(
deltaRow
,
baseRow
);
}
if
(
compare
==
0
)
{
if
(
isDeleted
)
{
if
(
isThisSession
)
{
throw
Message
.
getInternalError
();
}
else
{
// another session updated the row: must be deleted in base as well
throw
Message
.
getInternalError
();
boolean
isThisSession
=
deltaRow
.
getSessionId
()
==
session
.
getId
();
boolean
isDeleted
=
deltaRow
.
getDeleted
();
if
(
isThisSession
&&
isDeleted
)
{
needNewDelta
=
true
;
continue
;
}
if
(
baseRow
==
null
)
{
if
(
isDeleted
)
{
if
(
isThisSession
)
{
end
=
true
;
return
false
;
}
else
{
// the row was deleted by another session: return it
onBase
=
false
;
needNewDelta
=
true
;
return
true
;
}
}
}
else
{
if
(
isThisSession
)
{
onBase
=
false
;
needNewBase
=
true
;
needNewDelta
=
true
;
return
true
;
throw
Message
.
getInternalError
();
}
int
compare
=
index
.
compareRows
(
deltaRow
,
baseRow
);
if
(
compare
==
0
)
{
compare
=
index
.
compareKeys
(
deltaRow
,
baseRow
);
}
if
(
compare
==
0
)
{
if
(
isDeleted
)
{
if
(
isThisSession
)
{
throw
Message
.
getInternalError
();
}
else
{
// another session updated the row: must be deleted in base as well
throw
Message
.
getInternalError
();
}
}
else
{
// another session inserted the row: ignore
needNewBase
=
true
;
needNewDelta
=
true
;
continue
;
if
(
isThisSession
)
{
onBase
=
false
;
needNewBase
=
true
;
needNewDelta
=
true
;
return
true
;
}
else
{
// another session inserted the row: ignore
needNewBase
=
true
;
needNewDelta
=
true
;
continue
;
}
}
}
}
if
(
compare
>
0
)
{
needNewBase
=
true
;
if
(
compare
>
0
)
{
needNewBase
=
true
;
return
true
;
}
if
(!
isDeleted
)
{
throw
Message
.
getInternalError
();
}
needNewDelta
=
true
;
return
true
;
}
if
(!
isDeleted
)
{
throw
Message
.
getInternalError
();
}
needNewDelta
=
true
;
return
true
;
}
}
}
h2/src/main/org/h2/index/MultiVersionIndex.java
浏览文件 @
6b606ae5
...
...
@@ -29,7 +29,7 @@ public class MultiVersionIndex implements Index {
this
.
delta
=
new
TreeIndex
(
table
,
-
1
,
"DELTA"
,
base
.
getColumns
(),
deltaIndexType
);
}
public
void
add
(
Session
session
,
Row
row
)
throws
SQLException
{
public
synchronized
void
add
(
Session
session
,
Row
row
)
throws
SQLException
{
base
.
add
(
session
,
row
);
// for example rolling back an delete operation
removeIfExists
(
session
,
row
);
...
...
@@ -39,11 +39,11 @@ public class MultiVersionIndex implements Index {
}
}
public
void
close
(
Session
session
)
throws
SQLException
{
public
synchronized
void
close
(
Session
session
)
throws
SQLException
{
base
.
close
(
session
);
}
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
public
synchronized
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
Cursor
baseCursor
=
base
.
find
(
session
,
first
,
last
);
Cursor
deltaCursor
=
delta
.
find
(
session
,
first
,
last
);
return
new
MultiVersionCursor
(
session
,
this
,
baseCursor
,
deltaCursor
);
...
...
@@ -53,7 +53,7 @@ public class MultiVersionIndex implements Index {
return
false
;
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
synchronized
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
}
...
...
@@ -65,7 +65,7 @@ public class MultiVersionIndex implements Index {
return
base
.
needRebuild
();
}
private
boolean
removeIfExists
(
Session
session
,
Row
row
)
throws
SQLException
{
private
synchronized
boolean
removeIfExists
(
Session
session
,
Row
row
)
throws
SQLException
{
// maybe it was inserted by the same session just before
Cursor
c
=
delta
.
find
(
session
,
row
,
row
);
while
(
c
.
next
())
{
...
...
@@ -78,7 +78,7 @@ public class MultiVersionIndex implements Index {
return
false
;
}
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
public
synchronized
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
base
.
remove
(
session
,
row
);
if
(
removeIfExists
(
session
,
row
))
{
// added and deleted in the same transaction: no change
...
...
@@ -87,16 +87,16 @@ public class MultiVersionIndex implements Index {
}
}
public
void
remove
(
Session
session
)
throws
SQLException
{
public
synchronized
void
remove
(
Session
session
)
throws
SQLException
{
base
.
remove
(
session
);
}
public
void
truncate
(
Session
session
)
throws
SQLException
{
public
synchronized
void
truncate
(
Session
session
)
throws
SQLException
{
delta
.
truncate
(
session
);
base
.
truncate
(
session
);
}
public
void
commit
(
int
operation
,
Row
row
)
throws
SQLException
{
public
synchronized
void
commit
(
int
operation
,
Row
row
)
throws
SQLException
{
removeIfExists
(
null
,
row
);
}
...
...
@@ -153,7 +153,6 @@ public class MultiVersionIndex implements Index {
}
public
long
getRowCount
(
Session
session
)
{
// TODO
return
base
.
getRowCount
(
session
);
}
...
...
@@ -169,7 +168,7 @@ public class MultiVersionIndex implements Index {
return
base
.
isNull
(
newRow
);
}
public
void
removeChildrenAndResources
(
Session
session
)
throws
SQLException
{
public
synchronized
void
removeChildrenAndResources
(
Session
session
)
throws
SQLException
{
table
.
removeIndex
(
this
);
remove
(
session
);
}
...
...
h2/src/main/org/h2/index/ScanCursor.java
浏览文件 @
6b606ae5
...
...
@@ -5,6 +5,7 @@
package
org
.
h2
.
index
;
import
java.sql.SQLException
;
import
java.util.Iterator
;
import
org.h2.engine.Session
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
...
...
@@ -18,11 +19,15 @@ public class ScanCursor implements Cursor {
private
Row
row
;
private
final
Session
session
;
private
final
boolean
multiVersion
;
private
Iterator
deleted
;
ScanCursor
(
Session
session
,
ScanIndex
scan
,
boolean
multiVersion
)
{
this
.
session
=
session
;
this
.
scan
=
scan
;
this
.
multiVersion
=
multiVersion
;
if
(
multiVersion
)
{
deleted
=
scan
.
getDeleted
();
}
row
=
null
;
}
...
...
@@ -45,11 +50,15 @@ public class ScanCursor implements Cursor {
public
boolean
next
()
throws
SQLException
{
if
(
multiVersion
)
{
while
(
true
)
{
row
=
scan
.
getNextRow
(
session
,
row
);
if
(
deleted
.
hasNext
())
{
row
=
(
Row
)
deleted
.
next
();
}
else
{
row
=
scan
.
getNextRow
(
session
,
row
);
}
if
(
row
==
null
)
{
break
;
}
if
(
row
.
getSessionId
()
==
0
||
row
.
getSessionId
()
==
session
.
getId
())
{
if
(
row
.
getSessionId
()
==
0
||
row
.
getSessionId
()
==
session
.
getId
()
||
row
.
getDeleted
()
)
{
break
;
}
}
...
...
h2/src/main/org/h2/index/ScanIndex.java
浏览文件 @
6b606ae5
...
...
@@ -5,7 +5,10 @@
package
org
.
h2
.
index
;
import
java.sql.SQLException
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
...
...
@@ -32,6 +35,7 @@ public class ScanIndex extends BaseIndex {
private
boolean
containsLargeObject
;
private
int
rowCountDiff
;
private
HashMap
sessionRowCount
;
private
HashSet
deleted
;
public
ScanIndex
(
TableData
table
,
int
id
,
Column
[]
columns
,
IndexType
indexType
)
throws
SQLException
{
...
...
@@ -122,12 +126,20 @@ public class ScanIndex extends BaseIndex {
rows
.
set
(
key
,
row
);
}
}
incrementRowCount
(
session
.
getId
(),
1
);
if
(
database
.
isMultiVersion
())
{
if
(
deleted
!=
null
)
{
deleted
.
add
(
row
);
}
incrementRowCount
(
session
.
getId
(),
1
);
}
rowCount
++;
}
public
void
commit
(
int
operation
,
Row
row
)
throws
SQLException
{
if
(
database
.
isMultiVersion
())
{
if
(
deleted
!=
null
&&
operation
==
UndoLogRecord
.
DELETE
)
{
deleted
.
remove
(
row
);
}
incrementRowCount
(
row
.
getSessionId
(),
operation
==
UndoLogRecord
.
DELETE
?
1
:
-
1
);
}
}
...
...
@@ -160,7 +172,13 @@ public class ScanIndex extends BaseIndex {
rows
.
set
(
key
,
free
);
firstFree
=
key
;
}
incrementRowCount
(
session
.
getId
(),
-
1
);
if
(
database
.
isMultiVersion
())
{
if
(
deleted
==
null
)
{
deleted
=
new
HashSet
();
}
deleted
.
add
(
row
);
incrementRowCount
(
session
.
getId
(),
-
1
);
}
rowCount
--;
}
...
...
@@ -234,4 +252,8 @@ public class ScanIndex extends BaseIndex {
throw
Message
.
getUnsupportedException
();
}
public
Iterator
getDeleted
()
{
return
deleted
==
null
?
Collections
.
EMPTY_LIST
.
iterator
()
:
deleted
.
iterator
();
}
}
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
6b606ae5
...
...
@@ -30,6 +30,7 @@ public class ViewIndex extends BaseIndex {
private
int
[]
masks
;
private
String
planSQL
;
private
Query
query
;
private
Session
session
;
public
ViewIndex
(
TableView
view
,
String
querySQL
,
ObjectArray
originalParameters
,
boolean
recursive
)
{
super
(
view
,
0
,
null
,
null
,
IndexType
.
createNonUnique
(
false
));
...
...
@@ -45,10 +46,15 @@ public class ViewIndex extends BaseIndex {
this
.
originalParameters
=
index
.
originalParameters
;
this
.
recursive
=
index
.
recursive
;
this
.
masks
=
masks
;
this
.
session
=
session
;
columns
=
new
Column
[
0
];
query
=
getQuery
(
session
,
masks
);
planSQL
=
query
.
getPlanSQL
();
}
public
Session
getSession
()
{
return
session
;
}
public
String
getPlanSQL
()
{
return
planSQL
;
...
...
h2/src/main/org/h2/table/TableData.java
浏览文件 @
6b606ae5
...
...
@@ -259,6 +259,12 @@ public class TableData extends Table implements RecordReader {
public
void
removeRow
(
Session
session
,
Row
row
)
throws
SQLException
{
lastModificationId
=
database
.
getNextModificationDataId
();
if
(
database
.
isMultiVersion
())
{
if
(
row
.
getDeleted
())
{
int
testingWrongExceptionConcurrentUpdateOrSo
;
throw
Message
.
getSQLException
(
ErrorCode
.
LOCK_TIMEOUT_1
);
}
}
for
(
int
i
=
indexes
.
size
()
-
1
;
i
>=
0
;
i
--)
{
Index
index
=
(
Index
)
indexes
.
get
(
i
);
index
.
remove
(
session
,
row
);
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
6b606ae5
...
...
@@ -8,6 +8,7 @@ import java.sql.SQLException;
import
org.h2.command.Prepared
;
import
org.h2.command.dml.Query
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Session
;
import
org.h2.expression.Expression
;
import
org.h2.index.Index
;
...
...
@@ -16,7 +17,9 @@ import org.h2.index.ViewIndex;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.util.IntArray
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.SmallLRUCache
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
...
...
@@ -28,7 +31,10 @@ public class TableView extends Table {
private
Query
viewQuery
;
private
ViewIndex
index
;
private
boolean
recursive
;
private
SQLException
createException
;
private
SQLException
createException
;
private
SmallLRUCache
indexCache
=
new
SmallLRUCache
(
Constants
.
VIEW_INDEX_CACHE_SIZE
);
private
long
lastModificationCheck
;
private
long
maxDataModificationId
;
public
TableView
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
ObjectArray
params
,
String
[]
columnNames
,
Session
session
,
boolean
recursive
)
throws
SQLException
{
super
(
schema
,
id
,
name
,
false
);
...
...
@@ -101,7 +107,12 @@ public class TableView extends Table {
public
PlanItem
getBestPlanItem
(
Session
session
,
int
[]
masks
)
throws
SQLException
{
PlanItem
item
=
new
PlanItem
();
item
.
cost
=
index
.
getCost
(
session
,
masks
);
Index
i2
=
new
ViewIndex
(
this
,
index
,
session
,
masks
);
IntArray
masksArray
=
new
IntArray
(
masks
==
null
?
new
int
[
0
]
:
masks
);
ViewIndex
i2
=
(
ViewIndex
)
indexCache
.
get
(
masksArray
);
if
(
i2
==
null
||
i2
.
getSession
()
!=
session
)
{
i2
=
new
ViewIndex
(
this
,
index
,
session
,
masks
);
indexCache
.
put
(
masksArray
,
i2
);
}
item
.
setIndex
(
i2
);
return
item
;
}
...
...
@@ -233,7 +244,14 @@ public class TableView extends Table {
if
(
viewQuery
==
null
)
{
return
Long
.
MAX_VALUE
;
}
return
viewQuery
.
getMaxDataModificationId
();
// if nothing was modified in the database since the last check, and the last is known, then we don't need to check again
// this speeds up nested views
long
dbMod
=
database
.
getModificationDataId
();
if
(
dbMod
>
lastModificationCheck
&&
maxDataModificationId
<=
dbMod
)
{
maxDataModificationId
=
viewQuery
.
getMaxDataModificationId
();
lastModificationCheck
=
dbMod
;
}
return
maxDataModificationId
;
}
public
Index
getUniqueIndex
()
{
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
6b606ae5
...
...
@@ -95,39 +95,29 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
test
.
printSystem
();
int
testMVCC
;
System
.
setProperty
(
"h2.mvcc"
,
"true"
);
//
int testMVCC;
//
System.setProperty("h2.mvcc", "true");
/*
add link to:
http://zvikico.typepad.com/problog/2007/08/h2-database-eng.html
m2-repo
m.i.a.
documented?:
problem: new table created with constraints (so pointing to the same index), then constraint deleted: index is deleted (even though it is used).
Another problem: two constraints using the same index, one constraint is deleted.
Possible solution: never delete indexes? What about unique indexes? Create another index if one exists but it belongs to a constraint?
only admins can use nested tables:
CREATE USER TEST PASSWORD 'TEST';
SELECT * FROM (SELECT * FROM DUAL);
m2-repo
add MVCC
improve documentation of 'mixed mode' usage.
test and document fulltext search
improve documentation of mixed mode
clustered tables (test)
clustered tables: test, document
add to maven
Switching off and switching on constraints could be made transactional.
Add version number. Install directory: h2-1.0, jar file: h2-1.0.jar
search for japanese: works, but is it ok?
...
...
@@ -652,6 +642,7 @@ SELECT COUNT(*) AS A FROM TEST GROUP BY ID HAVING A>0;
new
TestTransaction
().
runTest
(
this
);
new
TestTriggersConstraints
().
runTest
(
this
);
new
TestTwoPhaseCommit
().
runTest
(
this
);
new
TestView
().
runTest
(
this
);
// server
new
TestNestedLoop
().
runTest
(
this
);
...
...
h2/src/test/org/h2/test/bench/test.properties
浏览文件 @
6b606ae5
...
...
@@ -26,9 +26,9 @@ postgresql.datetime = TIMESTAMP
derby.datetime
=
TIMESTAMP
oracle.datetime
=
TIMESTAMP
#
test1 = org.h2.test.bench.BenchSimple
#
test2 = org.h2.test.bench.BenchA
#
test3 = org.h2.test.bench.BenchB
test
1
=
org.h2.test.bench.BenchC
test1
=
org.h2.test.bench.BenchSimple
test2
=
org.h2.test.bench.BenchA
test3
=
org.h2.test.bench.BenchB
test
4
=
org.h2.test.bench.BenchC
size
=
400
h2/src/test/org/h2/test/db/TestView.java
0 → 100644
浏览文件 @
6b606ae5
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
org.h2.test.TestBase
;
public
class
TestView
extends
TestBase
{
public
void
test
()
throws
Exception
{
deleteDb
(
"view"
);
Connection
conn
=
getConnection
(
"view"
);
Statement
s
=
conn
.
createStatement
();
s
.
execute
(
"create table t0(id int primary key)"
);
s
.
execute
(
"insert into t0 values(1), (2), (3)"
);
for
(
int
i
=
0
;
i
<
30
;
i
++)
{
s
.
execute
(
"create view t"
+
(
i
+
1
)
+
" as select * from t"
+
i
);
s
.
execute
(
"select * from t"
+
(
i
+
1
));
ResultSet
rs
=
s
.
executeQuery
(
"select count(*) from t"
+
(
i
+
1
)
+
" where id=2"
);
check
(
rs
.
next
());
check
(
rs
.
getInt
(
1
),
1
);
}
conn
.
close
();
conn
=
getConnection
(
"view"
);
conn
.
close
();
deleteDb
(
"view"
);
}
}
h2/src/test/org/h2/test/mvcc/TestMVCC.java
浏览文件 @
6b606ae5
...
...
@@ -19,6 +19,7 @@ public class TestMVCC {
}
void
test
()
throws
Exception
{
// TODO Prio 1: exception when deleting / updating the same in two transactions
// TODO Prio 1: document: exclusive table lock still used when altering tables, adding indexes, select ... for update; table level locks are checked
// TODO Prio 1: make unit test work
// TODO Prio 1: free up disk space (for deleted rows and old versions of updated rows) on commit
...
...
@@ -43,6 +44,24 @@ public class TestMVCC {
c1
.
setAutoCommit
(
false
);
c2
.
setAutoCommit
(
false
);
s1
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
s1
.
execute
(
"INSERT INTO TEST VALUES(1)"
);
c1
.
commit
();
// test(s2, "SELECT COUNT(*) FROM TEST", "1");
System
.
out
.
println
(
s1
.
executeUpdate
(
"DELETE FROM TEST"
));
ResultSet
rs
=
s2
.
executeQuery
(
"SELECT * FROM TEST"
);
while
(
rs
.
next
())
{
System
.
out
.
println
(
" "
+
rs
.
getString
(
1
));
}
//
test
(
s2
,
"SELECT COUNT(*) FROM TEST"
,
"1"
);
System
.
out
.
println
(
s2
.
executeUpdate
(
"DELETE FROM TEST"
));
test
(
s1
,
"SELECT COUNT(*) FROM TEST"
,
"0"
);
test
(
s2
,
"SELECT COUNT(*) FROM TEST"
,
"0"
);
c1
.
commit
();
c2
.
commit
();
s1
.
execute
(
"DROP TABLE TEST"
);
s1
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
s1
.
execute
(
"INSERT INTO TEST VALUES(1)"
);
c1
.
commit
();
...
...
@@ -98,19 +117,69 @@ public class TestMVCC {
c1
.
commit
();
Random
random
=
new
Random
(
1
);
s1
.
execute
(
"CREATE TABLE TEST(ID INT IDENTITY, NAME VARCHAR)"
);
Statement
s
;
Connection
c
;
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
if
(
random
.
nextBoolean
())
{
s
=
s1
;
c
=
c1
;
}
else
{
s
=
s2
;
c
=
c2
;
}
switch
(
random
.
nextInt
(
5
))
{
case
0
:
s
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello')"
);
break
;
case
1
:
s
.
execute
(
"UPDATE TEST SET NAME="
+
i
+
" WHERE ID="
+
random
.
nextInt
(
i
));
break
;
case
2
:
s
.
execute
(
"DELETE FROM TEST WHERE ID="
+
random
.
nextInt
(
i
));
break
;
case
3
:
c
.
commit
();
break
;
case
4
:
c
.
rollback
();
break
;
}
s1
.
execute
(
"SELECT * FROM TEST ORDER BY ID"
);
s2
.
execute
(
"SELECT * FROM TEST ORDER BY ID"
);
}
s1
.
execute
(
"DROP TABLE TEST"
);
c1
.
commit
();
c2
.
commit
();
random
=
new
Random
(
1
);
s1
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)"
);
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
switch
(
random
.
nextInt
(
3
))
{
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
if
(
random
.
nextBoolean
())
{
s
=
s1
;
c
=
c1
;
}
else
{
s
=
s2
;
c
=
c2
;
}
switch
(
random
.
nextInt
(
5
))
{
case
0
:
s
1
.
execute
(
"INSERT INTO TEST VALUES("
+
i
+
", 'Hello')"
);
s
.
execute
(
"INSERT INTO TEST VALUES("
+
i
+
", 'Hello')"
);
break
;
case
1
:
s
1
.
execute
(
"UPDATE TEST SET NAME="
+
i
+
" WHERE ID="
+
random
.
nextInt
(
i
));
s
.
execute
(
"UPDATE TEST SET NAME="
+
i
+
" WHERE ID="
+
random
.
nextInt
(
i
));
break
;
case
2
:
s1
.
execute
(
"DELETE FROM TEST WHERE ID="
+
random
.
nextInt
(
i
));
s
.
execute
(
"DELETE FROM TEST WHERE ID="
+
random
.
nextInt
(
i
));
break
;
case
3
:
c
.
commit
();
break
;
case
4
:
c
.
rollback
();
break
;
}
s1
.
execute
(
"SELECT * FROM TEST ORDER BY ID"
);
s2
.
execute
(
"SELECT * FROM TEST ORDER BY ID"
);
}
s1
.
execute
(
"DROP TABLE TEST"
);
...
...
h2/src/tools/org/h2/tools/doc/dictionary.txt
浏览文件 @
6b606ae5
...
...
@@ -502,4 +502,5 @@ resizing translator liqui prepends liquibase typo restarting refactorings manage
mathematicians instantiation homepage supporter grained tilde subscribe baseline wrapped bundle finer relying dangerous
finalizer textbase newsfeeds quicksort
prio zvikico incrementally nocheck differently eng admins problog nio though typepad channels rolling
lightweight builder
\ No newline at end of file
lightweight builder
tunes elephant codewave incorrectly mytunesrss speeds cte honoured httpdocs department whereever dog dept edh oops flower music appends research plant
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论