Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
23d68f4f
提交
23d68f4f
authored
3月 23, 2008
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
02b91ecc
隐藏空白字符变更
内嵌
并排
正在显示
45 个修改的文件
包含
376 行增加
和
129 行删除
+376
-129
advanced.html
h2/src/docsrc/html/advanced.html
+20
-2
RuleList.java
h2/src/main/org/h2/bnf/RuleList.java
+2
-2
Parser.java
h2/src/main/org/h2/command/Parser.java
+14
-13
CreateView.java
h2/src/main/org/h2/command/ddl/CreateView.java
+2
-2
AlterSequence.java
h2/src/main/org/h2/command/dml/AlterSequence.java
+8
-1
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+8
-0
Aggregate.java
h2/src/main/org/h2/expression/Aggregate.java
+4
-2
BaseIndex.java
h2/src/main/org/h2/index/BaseIndex.java
+2
-1
BtreeCursor.java
h2/src/main/org/h2/index/BtreeCursor.java
+6
-1
BtreeIndex.java
h2/src/main/org/h2/index/BtreeIndex.java
+17
-3
BtreeLeaf.java
h2/src/main/org/h2/index/BtreeLeaf.java
+36
-10
BtreeNode.java
h2/src/main/org/h2/index/BtreeNode.java
+33
-17
BtreePage.java
h2/src/main/org/h2/index/BtreePage.java
+2
-1
Cursor.java
h2/src/main/org/h2/index/Cursor.java
+8
-0
FunctionCursor.java
h2/src/main/org/h2/index/FunctionCursor.java
+4
-0
FunctionIndex.java
h2/src/main/org/h2/index/FunctionIndex.java
+1
-1
HashCursor.java
h2/src/main/org/h2/index/HashCursor.java
+6
-0
HashIndex.java
h2/src/main/org/h2/index/HashIndex.java
+1
-1
Index.java
h2/src/main/org/h2/index/Index.java
+2
-2
LinkedCursor.java
h2/src/main/org/h2/index/LinkedCursor.java
+4
-0
LinkedIndex.java
h2/src/main/org/h2/index/LinkedIndex.java
+1
-1
MetaCursor.java
h2/src/main/org/h2/index/MetaCursor.java
+4
-0
MetaIndex.java
h2/src/main/org/h2/index/MetaIndex.java
+1
-1
MultiVersionCursor.java
h2/src/main/org/h2/index/MultiVersionCursor.java
+5
-0
MultiVersionIndex.java
h2/src/main/org/h2/index/MultiVersionIndex.java
+1
-1
RangeCursor.java
h2/src/main/org/h2/index/RangeCursor.java
+4
-0
RangeIndex.java
h2/src/main/org/h2/index/RangeIndex.java
+3
-4
ScanCursor.java
h2/src/main/org/h2/index/ScanCursor.java
+6
-0
ScanIndex.java
h2/src/main/org/h2/index/ScanIndex.java
+1
-1
TreeCursor.java
h2/src/main/org/h2/index/TreeCursor.java
+6
-0
TreeIndex.java
h2/src/main/org/h2/index/TreeIndex.java
+39
-4
ViewCursor.java
h2/src/main/org/h2/index/ViewCursor.java
+4
-0
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+1
-1
JdbcDatabaseMetaData.java
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
+5
-4
TraceObject.java
h2/src/main/org/h2/message/TraceObject.java
+6
-3
SortOrder.java
h2/src/main/org/h2/result/SortOrder.java
+3
-1
Sequence.java
h2/src/main/org/h2/schema/Sequence.java
+5
-5
DbContextRule.java
h2/src/main/org/h2/server/web/DbContextRule.java
+4
-1
FileSystemMemory.java
h2/src/main/org/h2/store/fs/FileSystemMemory.java
+10
-11
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+1
-0
Table.java
h2/src/main/org/h2/table/Table.java
+0
-7
Recover.java
h2/src/main/org/h2/tools/Recover.java
+11
-3
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+3
-22
TestOptimizations.java
h2/src/test/org/h2/test/db/TestOptimizations.java
+58
-0
TestSequence.java
h2/src/test/org/h2/test/db/TestSequence.java
+14
-0
没有找到文件。
h2/src/docsrc/html/advanced.html
浏览文件 @
23d68f4f
...
@@ -495,9 +495,27 @@ The database can be used from Microsoft .NET even without using Java, by using I
...
@@ -495,9 +495,27 @@ The database can be used from Microsoft .NET even without using Java, by using I
</li></ul>
</li></ul>
<p>
<p>
If you want your C# application use H2, you need to add the h2.dll and the
If you want your C# application use H2, you need to add the h2.dll and the
IKVM.OpenJDK.ClassLibrary.dll to your C# solution. See also the short
IKVM.OpenJDK.ClassLibrary.dll to your C# solution. Here some sample code:
<a
href=
"http://groups.google.com/group/h2-database/browse_thread/thread/400bc5a9bc9de3fd"
>
C# source code example
</a>
.
</p>
</p>
<pre>
using System;
using java.sql;
class Test
{
static public void Main()
{
org.h2.Driver.load();
Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "sa");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT 'Hello World'");
while (rs.next())
{
Console.WriteLine(rs.getString(1));
}
}
}
</pre>
<br
/><a
name=
"acid"
></a>
<br
/><a
name=
"acid"
></a>
<h2>
ACID
</h2>
<h2>
ACID
</h2>
...
...
h2/src/main/org/h2/bnf/RuleList.java
浏览文件 @
23d68f4f
...
@@ -116,9 +116,9 @@ public class RuleList implements Rule {
...
@@ -116,9 +116,9 @@ public class RuleList implements Rule {
}
}
public
void
addNextTokenList
(
String
query
,
Sentence
sentence
)
{
public
void
addNextTokenList
(
String
query
,
Sentence
sentence
)
{
if
(
sentence
.
stop
())
{
//
if (sentence.stop()) {
//
//
}
//
}
if
(
or
)
{
if
(
or
)
{
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
get
(
i
).
addNextTokenList
(
query
,
sentence
);
get
(
i
).
addNextTokenList
(
query
,
sentence
);
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
23d68f4f
...
@@ -3386,19 +3386,20 @@ public class Parser {
...
@@ -3386,19 +3386,20 @@ public class Parser {
CreateSequence
command
=
new
CreateSequence
(
session
,
getSchema
());
CreateSequence
command
=
new
CreateSequence
(
session
,
getSchema
());
command
.
setIfNotExists
(
ifNotExists
);
command
.
setIfNotExists
(
ifNotExists
);
command
.
setSequenceName
(
sequenceName
);
command
.
setSequenceName
(
sequenceName
);
if
(
readIf
(
"START"
))
{
while
(
true
)
{
readIf
(
"WITH"
);
if
(
readIf
(
"START"
))
{
command
.
setStartWith
(
readExpression
());
readIf
(
"WITH"
);
}
command
.
setStartWith
(
readExpression
());
if
(
readIf
(
"INCREMENT"
))
{
}
else
if
(
readIf
(
"INCREMENT"
))
{
readIf
(
"BY"
);
readIf
(
"BY"
);
command
.
setIncrement
(
readExpression
());
command
.
setIncrement
(
readExpression
());
}
}
else
if
(
readIf
(
"CACHE"
))
{
if
(
readIf
(
"CACHE"
))
{
command
.
setCacheSize
(
readExpression
());
command
.
setCacheSize
(
readExpression
());
}
else
if
(
readIf
(
"BELONGS_TO_TABLE"
))
{
}
command
.
setBelongsToTable
(
true
);
if
(
readIf
(
"BELONGS_TO_TABLE"
))
{
}
else
{
command
.
setBelongsToTable
(
true
);
break
;
}
}
}
return
command
;
return
command
;
}
}
...
...
h2/src/main/org/h2/command/ddl/CreateView.java
浏览文件 @
23d68f4f
...
@@ -62,8 +62,8 @@ public class CreateView extends SchemaCommand {
...
@@ -62,8 +62,8 @@ public class CreateView extends SchemaCommand {
}
else
{
}
else
{
querySQL
=
select
.
getSQL
();
querySQL
=
select
.
getSQL
();
}
}
Session
s
=
db
.
getSystemSession
();
Session
s
ysSession
=
db
.
getSystemSession
();
TableView
view
=
new
TableView
(
getSchema
(),
id
,
viewName
,
querySQL
,
null
,
columnNames
,
s
,
recursive
);
TableView
view
=
new
TableView
(
getSchema
(),
id
,
viewName
,
querySQL
,
null
,
columnNames
,
s
ysSession
,
recursive
);
view
.
setComment
(
comment
);
view
.
setComment
(
comment
);
db
.
addSchemaObject
(
session
,
view
);
db
.
addSchemaObject
(
session
,
view
);
return
0
;
return
0
;
...
...
h2/src/main/org/h2/command/dml/AlterSequence.java
浏览文件 @
23d68f4f
...
@@ -75,7 +75,14 @@ public class AlterSequence extends SchemaCommand {
...
@@ -75,7 +75,14 @@ public class AlterSequence extends SchemaCommand {
}
}
sequence
.
setIncrement
(
incrementValue
);
sequence
.
setIncrement
(
incrementValue
);
}
}
db
.
update
(
session
,
sequence
);
// need to use the system session, so that the update
// can be committed immediately - not committing it
// would keep other transactions from using the sequence
Session
sysSession
=
db
.
getSystemSession
();
synchronized
(
sysSession
)
{
db
.
update
(
sysSession
,
sequence
);
sysSession
.
commit
(
true
);
}
return
0
;
return
0
;
}
}
...
...
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
23d68f4f
...
@@ -386,6 +386,14 @@ public class SysProperties {
...
@@ -386,6 +386,14 @@ public class SysProperties {
* The default result set fetch size when using the server mode.
* The default result set fetch size when using the server mode.
*/
*/
public
static
final
int
SERVER_RESULT_SET_FETCH_SIZE
=
getIntSetting
(
"h2.serverResultSetFetchSize"
,
100
);
public
static
final
int
SERVER_RESULT_SET_FETCH_SIZE
=
getIntSetting
(
"h2.serverResultSetFetchSize"
,
100
);
/**
* System property <code>h2.sortNullsHigh</code> (default: false).<br />
* Invert the default sorting behavior for NULL values, such that NULL values
* are sorted to the end of a result set in an ascending sort and to the beginning
* of a result set in a descending sort.
*/
public
static
final
boolean
SORT_NULLS_HIGH
=
getBooleanSetting
(
"h2.sortNullsHigh"
,
false
);
/**
/**
* System property <code>h2.traceIO</code> (default: false).<br />
* System property <code>h2.traceIO</code> (default: false).<br />
...
...
h2/src/main/org/h2/expression/Aggregate.java
浏览文件 @
23d68f4f
...
@@ -15,6 +15,7 @@ import org.h2.constant.ErrorCode;
...
@@ -15,6 +15,7 @@ import org.h2.constant.ErrorCode;
import
org.h2.constant.SysProperties
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
import
org.h2.index.Index
;
import
org.h2.message.Message
;
import
org.h2.message.Message
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
...
@@ -167,11 +168,12 @@ public class Aggregate extends Expression {
...
@@ -167,11 +168,12 @@ public class Aggregate extends Expression {
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
first
=
!
first
;
first
=
!
first
;
}
}
SearchRow
row
=
index
.
findFirstOrLast
(
session
,
first
);
Cursor
cursor
=
index
.
findFirstOrLast
(
session
,
first
);
Value
v
;
Value
v
;
if
(
row
==
null
)
{
if
(
cursor
==
null
)
{
v
=
ValueNull
.
INSTANCE
;
v
=
ValueNull
.
INSTANCE
;
}
else
{
}
else
{
SearchRow
row
=
cursor
.
getSearchRow
();
v
=
row
.
getValue
(
index
.
getColumns
()[
0
].
getColumnId
());
v
=
row
.
getValue
(
index
.
getColumns
()[
0
].
getColumnId
());
}
}
return
v
;
return
v
;
...
...
h2/src/main/org/h2/index/BaseIndex.java
浏览文件 @
23d68f4f
...
@@ -119,8 +119,9 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
...
@@ -119,8 +119,9 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
*
*
* @param session the session
* @param session the session
* @param first true for the first value, false for the last
* @param first true for the first value, false for the last
* @return a cursor or null
*/
*/
public
abstract
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
public
abstract
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
/**
/**
* Check if this index needs to be re-built.
* Check if this index needs to be re-built.
...
...
h2/src/main/org/h2/index/BtreeCursor.java
浏览文件 @
23d68f4f
...
@@ -90,5 +90,10 @@ public class BtreeCursor implements Cursor {
...
@@ -90,5 +90,10 @@ public class BtreeCursor implements Cursor {
}
}
return
currentSearchRow
!=
null
;
return
currentSearchRow
!=
null
;
}
}
public
boolean
previous
()
throws
SQLException
{
top
.
page
.
previous
(
this
,
top
.
position
);
return
currentSearchRow
!=
null
;
}
}
}
h2/src/main/org/h2/index/BtreeIndex.java
浏览文件 @
23d68f4f
...
@@ -334,7 +334,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
...
@@ -334,7 +334,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
return
true
;
return
true
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
if
(
first
)
{
if
(
first
)
{
// TODO optimization: this loops through NULL elements
// TODO optimization: this loops through NULL elements
Cursor
cursor
=
find
(
session
,
null
,
false
,
null
);
Cursor
cursor
=
find
(
session
,
null
,
false
,
null
);
...
@@ -342,12 +342,26 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
...
@@ -342,12 +342,26 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
SearchRow
row
=
cursor
.
getSearchRow
();
SearchRow
row
=
cursor
.
getSearchRow
();
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
row
;
return
cursor
;
}
}
}
}
return
null
;
return
null
;
}
else
{
}
else
{
return
getRoot
(
session
).
getLast
(
session
);
BtreePage
root
=
getRoot
(
session
);
BtreeCursor
cursor
=
new
BtreeCursor
(
session
,
this
,
null
);
root
.
last
(
cursor
);
// TODO optimization: this loops through NULL elements
do
{
SearchRow
row
=
cursor
.
getSearchRow
();
if
(
row
==
null
)
{
break
;
}
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
cursor
;
}
}
while
(
cursor
.
previous
());
return
null
;
}
}
}
}
...
...
h2/src/main/org/h2/index/BtreeLeaf.java
浏览文件 @
23d68f4f
...
@@ -182,6 +182,18 @@ public class BtreeLeaf extends BtreePage {
...
@@ -182,6 +182,18 @@ public class BtreeLeaf extends BtreePage {
cursor
.
pop
();
cursor
.
pop
();
nextUpper
(
cursor
);
nextUpper
(
cursor
);
}
}
public
void
previous
(
BtreeCursor
cursor
,
int
i
)
throws
SQLException
{
i
--;
if
(
i
>=
0
)
{
SearchRow
r
=
(
SearchRow
)
pageData
.
get
(
i
);
cursor
.
setCurrentRow
(
r
);
cursor
.
setStackPosition
(
i
);
return
;
}
cursor
.
pop
();
previousUpper
(
cursor
);
}
public
void
first
(
BtreeCursor
cursor
)
throws
SQLException
{
public
void
first
(
BtreeCursor
cursor
)
throws
SQLException
{
if
(
pageData
.
size
()
==
0
)
{
if
(
pageData
.
size
()
==
0
)
{
...
@@ -195,6 +207,20 @@ public class BtreeLeaf extends BtreePage {
...
@@ -195,6 +207,20 @@ public class BtreeLeaf extends BtreePage {
SearchRow
row
=
(
SearchRow
)
pageData
.
get
(
0
);
SearchRow
row
=
(
SearchRow
)
pageData
.
get
(
0
);
cursor
.
setCurrentRow
(
row
);
cursor
.
setCurrentRow
(
row
);
}
}
public
void
last
(
BtreeCursor
cursor
)
throws
SQLException
{
int
last
=
pageData
.
size
()
-
1
;
if
(
last
<
0
)
{
if
(!
Constants
.
ALLOW_EMPTY_BTREE_PAGES
&&
!
root
)
{
throw
Message
.
getInternalError
(
"Empty btree page"
);
}
previousUpper
(
cursor
);
return
;
}
cursor
.
push
(
this
,
last
);
SearchRow
row
=
(
SearchRow
)
pageData
.
get
(
last
);
cursor
.
setCurrentRow
(
row
);
}
private
void
nextUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
private
void
nextUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
BtreePosition
upper
=
cursor
.
pop
();
BtreePosition
upper
=
cursor
.
pop
();
...
@@ -205,6 +231,16 @@ public class BtreeLeaf extends BtreePage {
...
@@ -205,6 +231,16 @@ public class BtreeLeaf extends BtreePage {
upper
.
page
.
next
(
cursor
,
upper
.
position
);
upper
.
page
.
next
(
cursor
,
upper
.
position
);
}
}
}
}
private
void
previousUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
BtreePosition
upper
=
cursor
.
pop
();
if
(
upper
==
null
)
{
cursor
.
setCurrentRow
(
null
);
}
else
{
cursor
.
push
(
upper
.
page
,
upper
.
position
);
upper
.
page
.
previous
(
cursor
,
upper
.
position
);
}
}
public
void
prepareWrite
()
throws
SQLException
{
public
void
prepareWrite
()
throws
SQLException
{
if
(
getRealByteCount
()
>=
DiskFile
.
BLOCK_SIZE
*
BLOCKS_PER_PAGE
)
{
if
(
getRealByteCount
()
>=
DiskFile
.
BLOCK_SIZE
*
BLOCKS_PER_PAGE
)
{
...
@@ -263,16 +299,6 @@ public class BtreeLeaf extends BtreePage {
...
@@ -263,16 +299,6 @@ public class BtreeLeaf extends BtreePage {
return
size
;
return
size
;
}
}
SearchRow
getLast
(
Session
session
)
throws
SQLException
{
if
(
pageData
.
size
()
==
0
)
{
if
(!
Constants
.
ALLOW_EMPTY_BTREE_PAGES
&&
!
root
)
{
throw
Message
.
getInternalError
(
"Empty btree page"
);
}
return
null
;
}
return
(
SearchRow
)
pageData
.
get
(
pageData
.
size
()
-
1
);
}
SearchRow
getFirst
(
Session
session
)
throws
SQLException
{
SearchRow
getFirst
(
Session
session
)
throws
SQLException
{
if
(
pageData
.
size
()
==
0
)
{
if
(
pageData
.
size
()
==
0
)
{
if
(!
Constants
.
ALLOW_EMPTY_BTREE_PAGES
&&
!
root
)
{
if
(!
Constants
.
ALLOW_EMPTY_BTREE_PAGES
&&
!
root
)
{
...
...
h2/src/main/org/h2/index/BtreeNode.java
浏览文件 @
23d68f4f
...
@@ -63,9 +63,9 @@ public class BtreeNode extends BtreePage {
...
@@ -63,9 +63,9 @@ public class BtreeNode extends BtreePage {
SearchRow
r
=
(
SearchRow
)
pageData
.
get
(
i
);
SearchRow
r
=
(
SearchRow
)
pageData
.
get
(
i
);
if
(
r
==
null
)
{
if
(
r
==
null
)
{
int
p
=
pageChildren
.
get
(
i
+
1
);
int
p
=
pageChildren
.
get
(
i
+
1
);
Session
session
=
index
.
getDatabase
().
getSystemSession
();
Session
s
ysS
ession
=
index
.
getDatabase
().
getSystemSession
();
BtreePage
page
=
index
.
getPage
(
session
,
p
);
BtreePage
page
=
index
.
getPage
(
s
ysS
ession
,
p
);
r
=
page
.
getFirst
(
session
);
r
=
page
.
getFirst
(
s
ysS
ession
);
pageData
.
set
(
i
,
r
);
pageData
.
set
(
i
,
r
);
}
}
return
r
;
return
r
;
...
@@ -272,6 +272,17 @@ public class BtreeNode extends BtreePage {
...
@@ -272,6 +272,17 @@ public class BtreeNode extends BtreePage {
}
}
nextUpper
(
cursor
);
nextUpper
(
cursor
);
}
}
public
void
previous
(
BtreeCursor
cursor
,
int
i
)
throws
SQLException
{
i
--;
if
(
i
>=
0
)
{
cursor
.
setStackPosition
(
i
);
BtreePage
page
=
index
.
getPage
(
cursor
.
getSession
(),
pageChildren
.
get
(
i
));
page
.
last
(
cursor
);
return
;
}
previousUpper
(
cursor
);
}
private
void
nextUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
private
void
nextUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
cursor
.
pop
();
cursor
.
pop
();
...
@@ -283,12 +294,30 @@ public class BtreeNode extends BtreePage {
...
@@ -283,12 +294,30 @@ public class BtreeNode extends BtreePage {
upper
.
page
.
next
(
cursor
,
upper
.
position
);
upper
.
page
.
next
(
cursor
,
upper
.
position
);
}
}
}
}
private
void
previousUpper
(
BtreeCursor
cursor
)
throws
SQLException
{
cursor
.
pop
();
BtreePosition
upper
=
cursor
.
pop
();
if
(
upper
==
null
)
{
cursor
.
setCurrentRow
(
null
);
}
else
{
cursor
.
push
(
upper
.
page
,
upper
.
position
);
upper
.
page
.
previous
(
cursor
,
upper
.
position
);
}
}
public
void
first
(
BtreeCursor
cursor
)
throws
SQLException
{
public
void
first
(
BtreeCursor
cursor
)
throws
SQLException
{
cursor
.
push
(
this
,
0
);
cursor
.
push
(
this
,
0
);
BtreePage
page
=
index
.
getPage
(
cursor
.
getSession
(),
pageChildren
.
get
(
0
));
BtreePage
page
=
index
.
getPage
(
cursor
.
getSession
(),
pageChildren
.
get
(
0
));
page
.
first
(
cursor
);
page
.
first
(
cursor
);
}
}
public
void
last
(
BtreeCursor
cursor
)
throws
SQLException
{
int
last
=
pageChildren
.
size
()
-
1
;
cursor
.
push
(
this
,
last
);
BtreePage
page
=
index
.
getPage
(
cursor
.
getSession
(),
pageChildren
.
get
(
last
));
page
.
last
(
cursor
);
}
public
void
prepareWrite
()
throws
SQLException
{
public
void
prepareWrite
()
throws
SQLException
{
if
(
getRealByteCount
()
>=
DiskFile
.
BLOCK_SIZE
*
BLOCKS_PER_PAGE
)
{
if
(
getRealByteCount
()
>=
DiskFile
.
BLOCK_SIZE
*
BLOCKS_PER_PAGE
)
{
...
@@ -339,19 +368,6 @@ public class BtreeNode extends BtreePage {
...
@@ -339,19 +368,6 @@ public class BtreeNode extends BtreePage {
return
size
+
index
.
getRecordOverhead
();
return
size
+
index
.
getRecordOverhead
();
}
}
SearchRow
getLast
(
Session
session
)
throws
SQLException
{
if
(!
Constants
.
ALLOW_EMPTY_BTREE_PAGES
&&
pageChildren
.
size
()
==
0
)
{
throw
Message
.
getInternalError
(
"Empty btree page"
);
}
for
(
int
i
=
pageChildren
.
size
()
-
1
;
i
>=
0
;
i
--)
{
BtreePage
page
=
index
.
getPage
(
session
,
pageChildren
.
get
(
i
));
if
(
page
!=
null
)
{
return
page
.
getLast
(
session
);
}
}
return
null
;
}
SearchRow
getFirst
(
Session
session
)
throws
SQLException
{
SearchRow
getFirst
(
Session
session
)
throws
SQLException
{
for
(
int
i
=
0
;
i
<
pageChildren
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
pageChildren
.
size
();
i
++)
{
BtreePage
page
=
index
.
getPage
(
session
,
pageChildren
.
get
(
i
));
BtreePage
page
=
index
.
getPage
(
session
,
pageChildren
.
get
(
i
));
...
...
h2/src/main/org/h2/index/BtreePage.java
浏览文件 @
23d68f4f
...
@@ -56,9 +56,10 @@ public abstract class BtreePage extends Record {
...
@@ -56,9 +56,10 @@ public abstract class BtreePage extends Record {
abstract
BtreePage
split
(
Session
session
,
int
splitPoint
)
throws
SQLException
;
abstract
BtreePage
split
(
Session
session
,
int
splitPoint
)
throws
SQLException
;
abstract
boolean
findFirst
(
BtreeCursor
cursor
,
SearchRow
row
,
boolean
bigger
)
throws
SQLException
;
abstract
boolean
findFirst
(
BtreeCursor
cursor
,
SearchRow
row
,
boolean
bigger
)
throws
SQLException
;
abstract
SearchRow
getFirst
(
Session
session
)
throws
SQLException
;
abstract
SearchRow
getFirst
(
Session
session
)
throws
SQLException
;
abstract
SearchRow
getLast
(
Session
session
)
throws
SQLException
;
abstract
void
next
(
BtreeCursor
cursor
,
int
i
)
throws
SQLException
;
abstract
void
next
(
BtreeCursor
cursor
,
int
i
)
throws
SQLException
;
abstract
void
previous
(
BtreeCursor
cursor
,
int
i
)
throws
SQLException
;
abstract
void
first
(
BtreeCursor
cursor
)
throws
SQLException
;
abstract
void
first
(
BtreeCursor
cursor
)
throws
SQLException
;
abstract
void
last
(
BtreeCursor
cursor
)
throws
SQLException
;
abstract
int
getRealByteCount
()
throws
SQLException
;
abstract
int
getRealByteCount
()
throws
SQLException
;
BtreePage
(
BtreeIndex
index
)
{
BtreePage
(
BtreeIndex
index
)
{
...
...
h2/src/main/org/h2/index/Cursor.java
浏览文件 @
23d68f4f
...
@@ -50,5 +50,13 @@ public interface Cursor {
...
@@ -50,5 +50,13 @@ public interface Cursor {
* @return true if another row is available
* @return true if another row is available
*/
*/
boolean
next
()
throws
SQLException
;
boolean
next
()
throws
SQLException
;
/**
* Skip to the previous row if one is available.
* No filtering is made here.
*
* @return true if another row is available
*/
boolean
previous
()
throws
SQLException
;
}
}
h2/src/main/org/h2/index/FunctionCursor.java
浏览文件 @
23d68f4f
...
@@ -44,5 +44,9 @@ public class FunctionCursor implements Cursor {
...
@@ -44,5 +44,9 @@ public class FunctionCursor implements Cursor {
}
}
return
row
!=
null
;
return
row
!=
null
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/FunctionIndex.java
浏览文件 @
23d68f4f
...
@@ -76,7 +76,7 @@ public class FunctionIndex extends BaseIndex {
...
@@ -76,7 +76,7 @@ public class FunctionIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/index/HashCursor.java
浏览文件 @
23d68f4f
...
@@ -7,6 +7,7 @@ package org.h2.index;
...
@@ -7,6 +7,7 @@ package org.h2.index;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
...
@@ -42,4 +43,9 @@ public class HashCursor implements Cursor {
...
@@ -42,4 +43,9 @@ public class HashCursor implements Cursor {
end
=
true
;
end
=
true
;
return
true
;
return
true
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/HashIndex.java
浏览文件 @
23d68f4f
...
@@ -147,7 +147,7 @@ public class HashIndex extends BaseIndex {
...
@@ -147,7 +147,7 @@ public class HashIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/index/Index.java
浏览文件 @
23d68f4f
...
@@ -130,9 +130,9 @@ public interface Index extends SchemaObject {
...
@@ -130,9 +130,9 @@ public interface Index extends SchemaObject {
* @param session the session
* @param session the session
* @param first true if the first (lowest for ascending indexes) or last
* @param first true if the first (lowest for ascending indexes) or last
* value should be returned
* value should be returned
* @return
the search row with the value
* @return
a cursor or null
*/
*/
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
/**
/**
* Check if the index needs to be rebuilt.
* Check if the index needs to be rebuilt.
...
...
h2/src/main/org/h2/index/LinkedCursor.java
浏览文件 @
23d68f4f
...
@@ -61,5 +61,9 @@ public class LinkedCursor implements Cursor {
...
@@ -61,5 +61,9 @@ public class LinkedCursor implements Cursor {
}
}
return
true
;
return
true
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/LinkedIndex.java
浏览文件 @
23d68f4f
...
@@ -162,7 +162,7 @@ public class LinkedIndex extends BaseIndex {
...
@@ -162,7 +162,7 @@ public class LinkedIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
// TODO optimization: could get the first or last value (in any case;
// TODO optimization: could get the first or last value (in any case;
// maybe not optimized)
// maybe not optimized)
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
...
...
h2/src/main/org/h2/index/MetaCursor.java
浏览文件 @
23d68f4f
...
@@ -42,5 +42,9 @@ public class MetaCursor implements Cursor {
...
@@ -42,5 +42,9 @@ public class MetaCursor implements Cursor {
current
=
(
Row
)
(
index
>=
rows
.
size
()
?
null
:
rows
.
get
(
index
++));
current
=
(
Row
)
(
index
>=
rows
.
size
()
?
null
:
rows
.
get
(
index
++));
return
current
!=
null
;
return
current
!=
null
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/MetaIndex.java
浏览文件 @
23d68f4f
...
@@ -85,7 +85,7 @@ public class MetaIndex extends BaseIndex {
...
@@ -85,7 +85,7 @@ public class MetaIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/index/MultiVersionCursor.java
浏览文件 @
23d68f4f
...
@@ -167,4 +167,9 @@ public class MultiVersionCursor implements Cursor {
...
@@ -167,4 +167,9 @@ public class MultiVersionCursor implements Cursor {
}
}
}
}
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/MultiVersionIndex.java
浏览文件 @
23d68f4f
...
@@ -78,7 +78,7 @@ public class MultiVersionIndex implements Index {
...
@@ -78,7 +78,7 @@ public class MultiVersionIndex implements Index {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/index/RangeCursor.java
浏览文件 @
23d68f4f
...
@@ -51,5 +51,9 @@ public class RangeCursor implements Cursor {
...
@@ -51,5 +51,9 @@ public class RangeCursor implements Cursor {
currentRow
=
new
Row
(
new
Value
[]{
ValueLong
.
get
(
current
)},
0
);
currentRow
=
new
Row
(
new
Value
[]{
ValueLong
.
get
(
current
)},
0
);
return
current
<=
max
;
return
current
<=
max
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/RangeIndex.java
浏览文件 @
23d68f4f
...
@@ -13,8 +13,6 @@ import org.h2.result.Row;
...
@@ -13,8 +13,6 @@ import org.h2.result.Row;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.RangeTable
;
import
org.h2.table.RangeTable
;
import
org.h2.value.Value
;
import
org.h2.value.ValueLong
;
/**
/**
* An index for the SYSTEM_RANGE table.
* An index for the SYSTEM_RANGE table.
...
@@ -75,8 +73,9 @@ public class RangeIndex extends BaseIndex {
...
@@ -75,8 +73,9 @@ public class RangeIndex extends BaseIndex {
return
true
;
return
true
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
return
new
Row
(
new
Value
[]
{
ValueLong
.
get
(
first
?
min
:
max
)
},
0
);
long
pos
=
first
?
min
:
max
;
return
new
RangeCursor
(
pos
,
pos
);
}
}
}
}
h2/src/main/org/h2/index/ScanCursor.java
浏览文件 @
23d68f4f
...
@@ -8,6 +8,7 @@ package org.h2.index;
...
@@ -8,6 +8,7 @@ package org.h2.index;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
...
@@ -70,4 +71,9 @@ public class ScanCursor implements Cursor {
...
@@ -70,4 +71,9 @@ public class ScanCursor implements Cursor {
row
=
scan
.
getNextRow
(
session
,
row
);
row
=
scan
.
getNextRow
(
session
,
row
);
return
row
!=
null
;
return
row
!=
null
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/ScanIndex.java
浏览文件 @
23d68f4f
...
@@ -258,7 +258,7 @@ public class ScanIndex extends BaseIndex {
...
@@ -258,7 +258,7 @@ public class ScanIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/index/TreeCursor.java
浏览文件 @
23d68f4f
...
@@ -58,5 +58,11 @@ public class TreeCursor implements Cursor {
...
@@ -58,5 +58,11 @@ public class TreeCursor implements Cursor {
}
}
return
node
!=
null
;
return
node
!=
null
;
}
}
public
boolean
previous
()
throws
SQLException
{
node
=
tree
.
previous
(
node
);
return
node
!=
null
;
}
}
}
h2/src/main/org/h2/index/TreeIndex.java
浏览文件 @
23d68f4f
...
@@ -336,6 +336,29 @@ public class TreeIndex extends BaseIndex {
...
@@ -336,6 +336,29 @@ public class TreeIndex extends BaseIndex {
}
}
return
x
;
return
x
;
}
}
public
TreeNode
previous
(
TreeNode
x
)
{
if
(
x
==
null
)
{
return
null
;
}
TreeNode
l
=
x
.
left
;
if
(
l
!=
null
)
{
x
=
l
;
TreeNode
r
=
x
.
right
;
while
(
r
!=
null
)
{
x
=
r
;
r
=
x
.
right
;
}
return
x
;
}
TreeNode
ch
=
x
;
x
=
x
.
parent
;
while
(
x
!=
null
&&
ch
==
x
.
left
)
{
ch
=
x
;
x
=
x
.
parent
;
}
return
x
;
}
public
void
checkRename
()
throws
SQLException
{
public
void
checkRename
()
throws
SQLException
{
}
}
...
@@ -348,7 +371,7 @@ public class TreeIndex extends BaseIndex {
...
@@ -348,7 +371,7 @@ public class TreeIndex extends BaseIndex {
return
true
;
return
true
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
if
(
first
)
{
if
(
first
)
{
// TODO optimization: this loops through NULL values
// TODO optimization: this loops through NULL values
Cursor
cursor
=
find
(
session
,
null
,
null
);
Cursor
cursor
=
find
(
session
,
null
,
null
);
...
@@ -356,7 +379,7 @@ public class TreeIndex extends BaseIndex {
...
@@ -356,7 +379,7 @@ public class TreeIndex extends BaseIndex {
SearchRow
row
=
cursor
.
getSearchRow
();
SearchRow
row
=
cursor
.
getSearchRow
();
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
row
;
return
cursor
;
}
}
}
}
return
null
;
return
null
;
...
@@ -369,9 +392,21 @@ public class TreeIndex extends BaseIndex {
...
@@ -369,9 +392,21 @@ public class TreeIndex extends BaseIndex {
}
}
x
=
n
;
x
=
n
;
}
}
if
(
x
!
=
null
)
{
if
(
x
=
=
null
)
{
return
x
.
row
;
return
null
;
}
}
TreeCursor
cursor
=
new
TreeCursor
(
this
,
x
,
null
,
null
);
// TODO optimization: this loops through NULL elements
do
{
SearchRow
row
=
cursor
.
getSearchRow
();
if
(
row
==
null
)
{
break
;
}
Value
v
=
row
.
getValue
(
columnIds
[
0
]);
if
(
v
!=
ValueNull
.
INSTANCE
)
{
return
cursor
;
}
}
while
(
cursor
.
previous
());
return
null
;
return
null
;
}
}
}
}
...
...
h2/src/main/org/h2/index/ViewCursor.java
浏览文件 @
23d68f4f
...
@@ -56,5 +56,9 @@ public class ViewCursor implements Cursor {
...
@@ -56,5 +56,9 @@ public class ViewCursor implements Cursor {
}
}
return
true
;
return
true
;
}
}
public
boolean
previous
()
{
throw
Message
.
getInternalError
();
}
}
}
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
23d68f4f
...
@@ -243,7 +243,7 @@ public class ViewIndex extends BaseIndex {
...
@@ -243,7 +243,7 @@ public class ViewIndex extends BaseIndex {
return
false
;
return
false
;
}
}
public
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
{
throw
Message
.
getUnsupportedException
();
throw
Message
.
getUnsupportedException
();
}
}
...
...
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
浏览文件 @
23d68f4f
...
@@ -16,6 +16,7 @@ import java.sql.RowIdLifetime;
...
@@ -16,6 +16,7 @@ import java.sql.RowIdLifetime;
//#endif
//#endif
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.message.Message
;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
import
org.h2.message.Trace
;
...
@@ -434,21 +435,21 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
...
@@ -434,21 +435,21 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
/**
/**
* Checks is NULL values are sorted high (bigger than any non-null values).
* Checks is NULL values are sorted high (bigger than any non-null values).
*
*
* @return false
* @return false
by default; true if the system property h2.sortNullsHigh is set to true
*/
*/
public
boolean
nullsAreSortedHigh
()
{
public
boolean
nullsAreSortedHigh
()
{
debugCodeCall
(
"nullsAreSortedHigh"
);
debugCodeCall
(
"nullsAreSortedHigh"
);
return
false
;
return
SysProperties
.
SORT_NULLS_HIGH
;
}
}
/**
/**
* Checks is NULL values are sorted low (smaller than any non-null values).
* Checks is NULL values are sorted low (smaller than any non-null values).
*
*
* @return true
* @return true
by default; false if the system property h2.sortNullsHigh is set to true
*/
*/
public
boolean
nullsAreSortedLow
()
{
public
boolean
nullsAreSortedLow
()
{
debugCodeCall
(
"nullsAreSortedLow"
);
debugCodeCall
(
"nullsAreSortedLow"
);
return
true
;
return
!
SysProperties
.
SORT_NULLS_HIGH
;
}
}
/**
/**
...
...
h2/src/main/org/h2/message/TraceObject.java
浏览文件 @
23d68f4f
...
@@ -210,14 +210,17 @@ public class TraceObject {
...
@@ -210,14 +210,17 @@ public class TraceObject {
buff
.
append
(
" {"
);
buff
.
append
(
" {"
);
for
(
int
i
=
0
;
i
<
params
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
params
.
size
();
i
++)
{
try
{
try
{
ParameterInterface
p
=
(
ParameterInterface
)
params
.
get
(
i
);
String
s
=
p
.
getParamValue
().
getSQL
();
if
(
i
>
0
)
{
if
(
i
>
0
)
{
buff
.
append
(
", "
);
buff
.
append
(
", "
);
}
}
buff
.
append
(
i
+
1
);
buff
.
append
(
i
+
1
);
buff
.
append
(
": "
);
buff
.
append
(
": "
);
buff
.
append
(
s
);
ParameterInterface
p
=
(
ParameterInterface
)
params
.
get
(
i
);
if
(
p
==
null
)
{
buff
.
append
(
"unset"
);
}
else
{
buff
.
append
(
p
.
getParamValue
().
getSQL
());
}
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
buff
.
append
(
"/* "
);
buff
.
append
(
"/* "
);
buff
.
append
(
i
+
1
);
buff
.
append
(
i
+
1
);
...
...
h2/src/main/org/h2/result/SortOrder.java
浏览文件 @
23d68f4f
...
@@ -7,6 +7,7 @@ package org.h2.result;
...
@@ -7,6 +7,7 @@ package org.h2.result;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
org.h2.constant.SysProperties
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectArray
;
...
@@ -21,6 +22,7 @@ import org.h2.value.ValueNull;
...
@@ -21,6 +22,7 @@ import org.h2.value.ValueNull;
public
class
SortOrder
{
public
class
SortOrder
{
public
static
final
int
ASCENDING
=
0
,
DESCENDING
=
1
;
public
static
final
int
ASCENDING
=
0
,
DESCENDING
=
1
;
public
static
final
int
NULLS_FIRST
=
2
,
NULLS_LAST
=
4
;
public
static
final
int
NULLS_FIRST
=
2
,
NULLS_LAST
=
4
;
private
static
final
int
DEFAULT_NULL_SORT
=
SysProperties
.
SORT_NULLS_HIGH
?
1
:
-
1
;
private
Database
database
;
private
Database
database
;
private
int
len
;
private
int
len
;
...
@@ -67,7 +69,7 @@ public class SortOrder {
...
@@ -67,7 +69,7 @@ public class SortOrder {
return
aNull
?
1
:
-
1
;
return
aNull
?
1
:
-
1
;
}
else
{
}
else
{
// see also JdbcDatabaseMetaData.nullsAreSorted*
// see also JdbcDatabaseMetaData.nullsAreSorted*
int
comp
=
aNull
?
-
1
:
1
;
int
comp
=
aNull
?
DEFAULT_NULL_SORT
:
-
DEFAULT_NULL_SORT
;
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
}
}
}
}
...
...
h2/src/main/org/h2/schema/Sequence.java
浏览文件 @
23d68f4f
...
@@ -92,21 +92,21 @@ public class Sequence extends SchemaObjectBase {
...
@@ -92,21 +92,21 @@ public class Sequence extends SchemaObjectBase {
return
v
;
return
v
;
}
}
public
void
flush
()
throws
SQLException
{
public
synchronized
void
flush
()
throws
SQLException
{
// can not use the session, because it must be committed immediately
// can not use the session, because it must be committed immediately
// otherwise other threads can not access the sys table.
// otherwise other threads can not access the sys table.
Session
s
=
database
.
getSystemSession
();
Session
s
ysSession
=
database
.
getSystemSession
();
synchronized
(
this
)
{
synchronized
(
sysSession
)
{
// just for this case, use the value with the margin for the script
// just for this case, use the value with the margin for the script
long
realValue
=
value
;
long
realValue
=
value
;
try
{
try
{
value
=
valueWithMargin
;
value
=
valueWithMargin
;
database
.
update
(
s
,
this
);
database
.
update
(
s
ysSession
,
this
);
}
finally
{
}
finally
{
value
=
realValue
;
value
=
realValue
;
}
}
sysSession
.
commit
(
false
);
}
}
s
.
commit
(
false
);
}
}
public
void
close
()
throws
SQLException
{
public
void
close
()
throws
SQLException
{
...
...
h2/src/main/org/h2/server/web/DbContextRule.java
浏览文件 @
23d68f4f
...
@@ -163,7 +163,10 @@ public class DbContextRule implements Rule {
...
@@ -163,7 +163,10 @@ public class DbContextRule implements Rule {
}
}
}
}
}
}
String
q
=
StringUtils
.
toUpperEnglish
(
query
.
trim
());
String
q
=
StringUtils
.
toUpperEnglish
(
query
);
if
(
q
.
trim
().
length
()
==
0
)
{
q
=
q
.
trim
();
}
DbTableOrView
[]
tables
=
schema
.
tables
;
DbTableOrView
[]
tables
=
schema
.
tables
;
for
(
int
i
=
0
;
i
<
tables
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
tables
.
length
;
i
++)
{
DbTableOrView
table
=
tables
[
i
];
DbTableOrView
table
=
tables
[
i
];
...
...
h2/src/main/org/h2/store/fs/FileSystemMemory.java
浏览文件 @
23d68f4f
...
@@ -75,12 +75,7 @@ public class FileSystemMemory extends FileSystem {
...
@@ -75,12 +75,7 @@ public class FileSystemMemory extends FileSystem {
public
String
createTempFile
(
String
name
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
public
String
createTempFile
(
String
name
,
String
suffix
,
boolean
deleteOnExit
,
boolean
inTempDir
)
throws
IOException
{
name
+=
"."
;
name
+=
"."
;
for
(
int
i
=
0
;;
i
++)
{
for
(
int
i
=
0
;;
i
++)
{
String
n
=
name
+
Math
.
abs
(
RandomUtils
.
getSecureLong
())
+
suffix
;
int
test
;
// String n = name + RandomUtils.getSecureLong() + suffix;
String
n
=
name
+
i
+
suffix
;
if
(!
exists
(
n
))
{
if
(!
exists
(
n
))
{
// creates the file (not thread safe)
// creates the file (not thread safe)
getMemoryFile
(
n
);
getMemoryFile
(
n
);
...
@@ -166,18 +161,24 @@ public class FileSystemMemory extends FileSystem {
...
@@ -166,18 +161,24 @@ public class FileSystemMemory extends FileSystem {
public
OutputStream
openFileOutputStream
(
String
fileName
,
boolean
append
)
throws
SQLException
{
public
OutputStream
openFileOutputStream
(
String
fileName
,
boolean
append
)
throws
SQLException
{
try
{
try
{
return
new
FileObjectOutputStream
(
getMemoryFile
(
fileName
),
append
);
FileObjectMemory
obj
=
getMemoryFile
(
fileName
);
obj
.
seek
(
0
);
return
new
FileObjectOutputStream
(
obj
,
append
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
Message
.
convertIOException
(
e
,
fileName
);
throw
Message
.
convertIOException
(
e
,
fileName
);
}
}
}
}
public
InputStream
openFileInputStream
(
String
fileName
)
throws
IOException
{
public
InputStream
openFileInputStream
(
String
fileName
)
throws
IOException
{
return
new
FileObjectInputStream
(
getMemoryFile
(
fileName
));
FileObjectMemory
obj
=
getMemoryFile
(
fileName
);
obj
.
seek
(
0
);
return
new
FileObjectInputStream
(
obj
);
}
}
public
FileObject
openFileObject
(
String
fileName
,
String
mode
)
throws
IOException
{
public
FileObject
openFileObject
(
String
fileName
,
String
mode
)
throws
IOException
{
return
getMemoryFile
(
fileName
);
FileObjectMemory
obj
=
getMemoryFile
(
fileName
);
obj
.
seek
(
0
);
return
obj
;
}
}
private
FileObjectMemory
getMemoryFile
(
String
fileName
)
{
private
FileObjectMemory
getMemoryFile
(
String
fileName
)
{
...
@@ -188,8 +189,6 @@ public class FileSystemMemory extends FileSystem {
...
@@ -188,8 +189,6 @@ public class FileSystemMemory extends FileSystem {
m
=
new
FileObjectMemory
(
fileName
,
compress
);
m
=
new
FileObjectMemory
(
fileName
,
compress
);
MEMORY_FILES
.
put
(
fileName
,
m
);
MEMORY_FILES
.
put
(
fileName
,
m
);
}
}
// TODO the memory file only supports one pointer
m
.
seek
(
0
);
return
m
;
return
m
;
}
}
}
}
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
23d68f4f
...
@@ -747,6 +747,7 @@ public class MetaTable extends Table {
...
@@ -747,6 +747,7 @@ public class MetaTable extends Table {
add
(
rows
,
new
String
[]{
"h2.scriptDirectory"
,
SysProperties
.
scriptDirectory
});
add
(
rows
,
new
String
[]{
"h2.scriptDirectory"
,
SysProperties
.
scriptDirectory
});
add
(
rows
,
new
String
[]{
"h2.serverCachedObjects"
,
""
+
SysProperties
.
SERVER_CACHED_OBJECTS
});
add
(
rows
,
new
String
[]{
"h2.serverCachedObjects"
,
""
+
SysProperties
.
SERVER_CACHED_OBJECTS
});
add
(
rows
,
new
String
[]{
"h2.serverResultSetFetchSize"
,
""
+
SysProperties
.
SERVER_RESULT_SET_FETCH_SIZE
});
add
(
rows
,
new
String
[]{
"h2.serverResultSetFetchSize"
,
""
+
SysProperties
.
SERVER_RESULT_SET_FETCH_SIZE
});
add
(
rows
,
new
String
[]{
"h2.sortNullsHigh"
,
""
+
SysProperties
.
SORT_NULLS_HIGH
});
DiskFile
dataFile
=
database
.
getDataFile
();
DiskFile
dataFile
=
database
.
getDataFile
();
if
(
dataFile
!=
null
)
{
if
(
dataFile
!=
null
)
{
add
(
rows
,
new
String
[]
{
"CACHE_TYPE"
,
dataFile
.
getCache
().
getTypeName
()
});
add
(
rows
,
new
String
[]
{
"CACHE_TYPE"
,
dataFile
.
getCache
().
getTypeName
()
});
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
23d68f4f
...
@@ -27,7 +27,6 @@ import org.h2.result.RowList;
...
@@ -27,7 +27,6 @@ import org.h2.result.RowList;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SimpleRow
;
import
org.h2.result.SimpleRow
;
import
org.h2.result.SimpleRowValue
;
import
org.h2.result.SimpleRowValue
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Schema
;
import
org.h2.schema.SchemaObjectBase
;
import
org.h2.schema.SchemaObjectBase
;
import
org.h2.schema.Sequence
;
import
org.h2.schema.Sequence
;
...
@@ -643,12 +642,6 @@ public abstract class Table extends SchemaObjectBase {
...
@@ -643,12 +642,6 @@ public abstract class Table extends SchemaObjectBase {
for
(
int
i
=
1
;
indexes
!=
null
&&
i
<
indexes
.
size
();
i
++)
{
for
(
int
i
=
1
;
indexes
!=
null
&&
i
<
indexes
.
size
();
i
++)
{
Index
index
=
(
Index
)
indexes
.
get
(
i
);
Index
index
=
(
Index
)
indexes
.
get
(
i
);
if
(
index
.
canGetFirstOrLast
())
{
if
(
index
.
canGetFirstOrLast
())
{
IndexColumn
idxCol
=
index
.
getIndexColumns
()[
0
];
if
((
idxCol
.
sortType
&
SortOrder
.
DESCENDING
)
!=
0
&&
(
idxCol
.
sortType
&
SortOrder
.
NULLS_FIRST
)
==
0
)
{
// for descending sorted columns, if the NULLs
// are at the end, it does not work for some index types
continue
;
}
int
idx
=
index
.
getColumnIndex
(
column
);
int
idx
=
index
.
getColumnIndex
(
column
);
if
(
idx
==
0
)
{
if
(
idx
==
0
)
{
return
index
;
return
index
;
...
...
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
23d68f4f
...
@@ -311,7 +311,7 @@ public class Recover implements DataHandler {
...
@@ -311,7 +311,7 @@ public class Recover implements DataHandler {
}
}
private
void
writeDataError
(
PrintWriter
writer
,
String
error
,
byte
[]
data
,
int
dumpBlocks
)
throws
IOException
{
private
void
writeDataError
(
PrintWriter
writer
,
String
error
,
byte
[]
data
,
int
dumpBlocks
)
throws
IOException
{
writer
.
println
(
"-- ERROR:"
+
error
+
" block:"
+
block
+
" blockCount:"
+
blockCount
+
" storageId:"
writer
.
println
(
"-- ERROR:
"
+
error
+
" block:"
+
block
+
" blockCount:"
+
blockCount
+
" storageId:"
+
storageId
+
" recordLength: "
+
recordLength
+
" valueId:"
+
valueId
);
+
storageId
+
" recordLength: "
+
recordLength
+
" valueId:"
+
valueId
);
StringBuffer
sb
=
new
StringBuffer
();
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
i
=
0
;
i
<
dumpBlocks
*
DiskFile
.
BLOCK_SIZE
;
i
++)
{
for
(
int
i
=
0
;
i
<
dumpBlocks
*
DiskFile
.
BLOCK_SIZE
;
i
++)
{
...
@@ -720,7 +720,7 @@ public class Recover implements DataHandler {
...
@@ -720,7 +720,7 @@ public class Recover implements DataHandler {
writeDataError
(
writer
,
"blockCount<0"
,
s
.
getBytes
(),
1
);
writeDataError
(
writer
,
"blockCount<0"
,
s
.
getBytes
(),
1
);
blockCount
=
1
;
blockCount
=
1
;
continue
;
continue
;
}
else
if
((
blockCount
*
blockSize
)
>=
Integer
.
MAX_VALUE
/
4
)
{
}
else
if
((
blockCount
*
blockSize
)
>=
Integer
.
MAX_VALUE
/
4
||
(
blockCount
*
blockSize
)
<
0
)
{
writeDataError
(
writer
,
"blockCount="
+
blockCount
,
s
.
getBytes
(),
1
);
writeDataError
(
writer
,
"blockCount="
+
blockCount
,
s
.
getBytes
(),
1
);
blockCount
=
1
;
blockCount
=
1
;
continue
;
continue
;
...
@@ -737,8 +737,16 @@ public class Recover implements DataHandler {
...
@@ -737,8 +737,16 @@ public class Recover implements DataHandler {
if
((
blockCount
*
blockSize
)
<
0
)
{
if
((
blockCount
*
blockSize
)
<
0
)
{
writeDataError
(
writer
,
"wrong blockCount"
,
s
.
getBytes
(),
1
);
writeDataError
(
writer
,
"wrong blockCount"
,
s
.
getBytes
(),
1
);
blockCount
=
1
;
blockCount
=
1
;
continue
;
}
else
{
}
else
{
store
.
readFully
(
s
.
getBytes
(),
blockSize
,
blockCount
*
blockSize
-
blockSize
);
try
{
store
.
readFully
(
s
.
getBytes
(),
blockSize
,
blockCount
*
blockSize
-
blockSize
);
}
catch
(
Throwable
e
)
{
writeDataError
(
writer
,
"eof"
,
s
.
getBytes
(),
1
);
blockCount
=
1
;
store
=
FileStore
.
open
(
null
,
fileName
,
"r"
,
magic
);
continue
;
}
}
}
}
}
try
{
try
{
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
23d68f4f
...
@@ -238,6 +238,9 @@ The recovery tool didn't work correctly for tables without rows.
...
@@ -238,6 +238,9 @@ The recovery tool didn't work correctly for tables without rows.
For years below 1, the YEAR method didn't return the correct value,
For years below 1, the YEAR method didn't return the correct value,
and the conversion from date and timestamp to varchar was incorrect.
and the conversion from date and timestamp to varchar was incorrect.
CSVWRITE caused a NullPointerException when not specifying a nullString.
CSVWRITE caused a NullPointerException when not specifying a nullString.
New system property h2.sortNullsHigh to invert the default sorting behavior
for NULL. The default didn't change.
Altering a sequence didn't unlock the system table when autocommit switched off.
Roadmap:
Roadmap:
...
@@ -558,28 +561,6 @@ Use a default delay of 1 second before closing a database.
...
@@ -558,28 +561,6 @@ Use a default delay of 1 second before closing a database.
new
TestValue
().
runTest
(
this
);
new
TestValue
().
runTest
(
this
);
new
TestValueHashMap
().
runTest
(
this
);
new
TestValueHashMap
().
runTest
(
this
);
new
TestValueMemory
().
runTest
(
this
);
new
TestValueMemory
().
runTest
(
this
);
new
TestFile
().
runTest
(
this
);
new
TestFileLock
().
runTest
(
this
);
new
TestFtp
().
runTest
(
this
);
new
TestFileSystem
().
runTest
(
this
);
new
TestIntArray
().
runTest
(
this
);
new
TestIntIntHashMap
().
runTest
(
this
);
new
TestMultiThreadedKernel
().
runTest
(
this
);
new
TestOverflow
().
runTest
(
this
);
new
TestPattern
().
runTest
(
this
);
new
TestReader
().
runTest
(
this
);
new
TestRecovery
().
runTest
(
this
);
new
TestSampleApps
().
runTest
(
this
);
new
TestScriptReader
().
runTest
(
this
);
runTest
(
"org.h2.test.unit.TestServlet"
);
new
TestSecurity
().
runTest
(
this
);
new
TestStreams
().
runTest
(
this
);
new
TestStringCache
().
runTest
(
this
);
new
TestStringUtils
().
runTest
(
this
);
new
TestTools
().
runTest
(
this
);
new
TestValue
().
runTest
(
this
);
new
TestValueHashMap
().
runTest
(
this
);
new
TestValueMemory
().
runTest
(
this
);
afterTest
();
afterTest
();
}
}
...
...
h2/src/test/org/h2/test/db/TestOptimizations.java
浏览文件 @
23d68f4f
...
@@ -23,6 +23,7 @@ import org.h2.test.TestBase;
...
@@ -23,6 +23,7 @@ import org.h2.test.TestBase;
public
class
TestOptimizations
extends
TestBase
{
public
class
TestOptimizations
extends
TestBase
{
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
testMinMaxNullOptimization
();
if
(
config
.
networked
)
{
if
(
config
.
networked
)
{
return
;
return
;
}
}
...
@@ -36,6 +37,63 @@ public class TestOptimizations extends TestBase {
...
@@ -36,6 +37,63 @@ public class TestOptimizations extends TestBase {
testMinMaxCountOptimization
(
true
);
testMinMaxCountOptimization
(
true
);
testMinMaxCountOptimization
(
false
);
testMinMaxCountOptimization
(
false
);
}
}
private
void
testMinMaxNullOptimization
()
throws
Exception
{
deleteDb
(
"optimizations"
);
Connection
conn
=
getConnection
(
"optimizations"
);
Statement
stat
=
conn
.
createStatement
();
Random
random
=
new
Random
(
1
);
int
len
=
getSize
(
50
,
500
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
stat
.
execute
(
"drop table if exists test"
);
stat
.
execute
(
"create table test(x int)"
);
if
(
random
.
nextBoolean
())
{
int
count
=
random
.
nextBoolean
()
?
1
:
1
+
random
.
nextInt
(
len
);
if
(
count
>
0
)
{
stat
.
execute
(
"insert into test select null from system_range(1, "
+
count
+
")"
);
}
}
int
maxExpected
=
-
1
;
int
minExpected
=
-
1
;
if
(
random
.
nextInt
(
10
)
!=
1
)
{
minExpected
=
1
;
maxExpected
=
1
+
random
.
nextInt
(
len
);
stat
.
execute
(
"insert into test select x from system_range(1, "
+
maxExpected
+
")"
);
}
String
sql
=
"create index idx on test(x"
;
if
(
random
.
nextBoolean
())
{
sql
+=
" desc"
;
}
if
(
random
.
nextBoolean
())
{
if
(
random
.
nextBoolean
())
{
sql
+=
" nulls first"
;
}
else
{
sql
+=
" nulls last"
;
}
}
sql
+=
")"
;
stat
.
execute
(
sql
);
ResultSet
rs
=
stat
.
executeQuery
(
"explain select min(x), max(x) from test"
);
rs
.
next
();
if
(!
config
.
mvcc
)
{
String
plan
=
rs
.
getString
(
1
);
check
(
plan
.
indexOf
(
"direct"
)
>
0
);
}
rs
=
stat
.
executeQuery
(
"select min(x), max(x) from test"
);
rs
.
next
();
int
min
=
rs
.
getInt
(
1
);
if
(
rs
.
wasNull
())
{
min
=
-
1
;
}
int
max
=
rs
.
getInt
(
2
);
if
(
rs
.
wasNull
())
{
max
=
-
1
;
}
check
(
minExpected
,
min
);
check
(
maxExpected
,
max
);
}
conn
.
close
();
}
private
void
testMultiColumnRangeQuery
()
throws
Exception
{
private
void
testMultiColumnRangeQuery
()
throws
Exception
{
deleteDb
(
"optimizations"
);
deleteDb
(
"optimizations"
);
...
...
h2/src/test/org/h2/test/db/TestSequence.java
浏览文件 @
23d68f4f
...
@@ -17,9 +17,23 @@ import org.h2.test.TestBase;
...
@@ -17,9 +17,23 @@ import org.h2.test.TestBase;
public
class
TestSequence
extends
TestBase
{
public
class
TestSequence
extends
TestBase
{
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
testAlterSequence
();
testCache
();
testCache
();
testTwo
();
testTwo
();
}
}
private
void
testAlterSequence
()
throws
Exception
{
deleteDb
(
"sequence"
);
Connection
conn
=
getConnection
(
"sequence"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create sequence test"
);
conn
.
setAutoCommit
(
false
);
stat
.
execute
(
"alter sequence test restart with 1"
);
for
(
int
i
=
0
;
i
<
40
;
i
++)
{
stat
.
execute
(
"select nextval('test')"
);
}
conn
.
close
();
}
private
void
testCache
()
throws
Exception
{
private
void
testCache
()
throws
Exception
{
if
(
config
.
memory
)
{
if
(
config
.
memory
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论