Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
95620da6
提交
95620da6
authored
1月 22, 2008
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
40b88b0d
隐藏空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
272 行增加
和
84 行删除
+272
-84
performance.html
h2/src/docsrc/html/performance.html
+17
-14
tutorial.html
h2/src/docsrc/html/tutorial.html
+26
-1
Command.java
h2/src/main/org/h2/command/Command.java
+1
-0
Query.java
h2/src/main/org/h2/command/dml/Query.java
+7
-0
SysProperties.java
h2/src/main/org/h2/constant/SysProperties.java
+7
-7
Database.java
h2/src/main/org/h2/engine/Database.java
+9
-0
Session.java
h2/src/main/org/h2/engine/Session.java
+32
-3
ConditionExists.java
h2/src/main/org/h2/expression/ConditionExists.java
+3
-6
ConditionInSelect.java
h2/src/main/org/h2/expression/ConditionInSelect.java
+19
-22
Function.java
h2/src/main/org/h2/expression/Function.java
+5
-5
FullTextSettings.java
h2/src/main/org/h2/fulltext/FullTextSettings.java
+3
-3
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+1
-1
PageParser.java
h2/src/main/org/h2/server/web/PageParser.java
+6
-4
Column.java
h2/src/main/org/h2/table/Column.java
+1
-1
StringUtils.java
h2/src/main/org/h2/util/StringUtils.java
+5
-0
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+2
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+48
-3
TestBigResult.java
h2/src/test/org/h2/test/db/TestBigResult.java
+24
-0
TestLob.java
h2/src/test/org/h2/test/db/TestLob.java
+18
-0
TestMetaData.java
h2/src/test/org/h2/test/jdbc/TestMetaData.java
+23
-6
test.in.txt
h2/src/test/org/h2/test/test.in.txt
+8
-8
testSimple.in.txt
h2/src/test/org/h2/test/testSimple.in.txt
+7
-0
没有找到文件。
h2/src/docsrc/html/performance.html
浏览文件 @
95620da6
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
<!--
Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
Initial Developer: H2 Group
-->
<html
xmlns=
"http://www.w3.org/1999/xhtml"
lang=
"en"
xml:lang=
"en"
>
...
...
@@ -14,6 +14,8 @@ Performance
<h1>
Performance
</h1>
<a
href=
"#performance_comparison"
>
Performance Comparison
</a><br
/>
<a
href=
"#poleposition_benchmark"
>
PolePosition Benchmark
</a><br
/>
<a
href=
"#application_profiling"
>
Application Profiling
</a><br
/>
<a
href=
"#database_performance_tuning"
>
...
...
@@ -23,7 +25,7 @@ Performance
<h2>
Performance Comparison
</h2>
<p>
In most cases H2 is a lot faster than all other
(open source and not open source) database engines.
(open source and not open source) database engines.
Please note this is mostly a single connection benchmark run on one computer.
</p>
...
...
@@ -109,9 +111,9 @@ The reason is, a backup of the database is created whenever the database is open
<h4>
Derby
</h4>
<p>
Version 10.3.1.4 was used for the test. Derby is clearly the slowest embedded database in this test.
This seems to be a structural problem, because all operations are really slow.
This seems to be a structural problem, because all operations are really slow.
It will not be easy for the developers of Derby to improve the performance to a reasonable level.
A few problems have been identified: Leaving autocommit on is a problem for Derby.
A few problems have been identified: Leaving autocommit on is a problem for Derby.
If it is switched off during the whole test, the results are about 20% better for Derby.
</p>
...
...
@@ -159,7 +161,7 @@ SQLite was not tested because the JDBC driver doesn't support transactions.
<h4>
Number of Connections
</h4>
<p>
This is mostly a single-connection benchmark.
This is mostly a single-connection benchmark.
BenchB uses multiple connections, the other tests one connection.
</p>
...
...
@@ -223,7 +225,7 @@ think about the effect. Many database suggest to 'batch' operations when possibl
This benchmark switches off autocommit when loading the data, and calls commit after each 1000
inserts. However many applications need 'short' transactions at runtime (a commit after each update).
This benchmark commits after each update / delete in the simple benchmark, and after each
business transaction in the other benchmarks. For databases that support delayed commits,
business transaction in the other benchmarks. For databases that support delayed commits,
a delay of one second is used.
</p>
...
...
@@ -243,7 +245,8 @@ That means the Open/Close time listed is for opening a connection
if the database is already in use.
</p>
<h3>
PolePosition Benchmark
</h3>
<br
/><a
name=
"poleposition_benchmark"
></a>
<h2>
PolePosition Benchmark
</h2>
<p>
The PolePosition is an open source benchmark. The algorithms are all quite simple.
It was developed / sponsored by db4o.
...
...
@@ -275,15 +278,15 @@ It was developed / sponsored by db4o.
<br
/><a
name=
"application_profiling"
></a>
<h2>
Application Profiling
</h2>
<h3>
Analyze First
</h3>
<h3>
Analyze First
</h3>
<p>
Before trying to optimize the performance, it is important to know where the time is actually spent.
Before trying to optimize the performance, it is important to know where the time is actually spent.
The same is true for memory problems.
Premature or 'blind' optimization should be avoided, as it is not an efficient way to solve the problem.
There are various ways to analyze the application. In some situations it is possible to
There are various ways to analyze the application. In some situations it is possible to
compare two implementations and use System.currentTimeMillis() to find out which one is faster.
But this does not work for complex applications with many modules, and for memory problems.
A very good tool to measure both the memory and the CPU is the
But this does not work for complex applications with many modules, and for memory problems.
A very good tool to measure both the memory and the CPU is the
<a
href=
"http://www.yourkit.com"
>
YourKit Java Profiler
</a>
. This tool is also used
to optimize the performance and memory footprint of this database engine.
</p>
...
...
@@ -304,7 +307,7 @@ Some virus scanners allow excluding file endings. Make sure files ending with .d
<h3>
Using the Trace Options
</h3>
<p>
If the main performance hot spots are in the database engine, in many cases the performance
can be optimized by creating additional indexes, or changing the schema. Sometimes the
can be optimized by creating additional indexes, or changing the schema. Sometimes the
application does not directly generate the SQL statements, for example if an O/R mapping tool
is used. To view the SQL statements and JDBC API calls, you can use the trace options.
For more information, see
<a
href=
"features.html#trace_options"
>
Using the Trace Options
</a>
.
...
...
h2/src/docsrc/html/tutorial.html
浏览文件 @
95620da6
...
...
@@ -34,6 +34,8 @@ Tutorial
Java Web Start / JNLP
</a><br
/>
<a
href=
"#fulltext"
>
Fulltext Search
</a><br
/>
<a
href=
"#user_defined_variables"
>
User Defined Variables
</a><br
/>
<br
/><a
name=
"tutorial_starting_h2_console"
></a>
<h2>
Starting and Using the H2 Console
</h2>
...
...
@@ -592,4 +594,27 @@ You can also call the index from within a Java application:
org.h2.fulltext.FullTextLucene.search(conn, text, limit, offset)
</pre>
</div></td></tr></table></body></html>
\ No newline at end of file
<br
/><a
name=
"user_defined_variables"
></a>
<h2>
User Defined Variables
</h2>
<p>
This database supports user defined variables. Variables start with @ and can be used whereever
expressions or parameters are used. Variables not persisted and session scoped, that means only visible for
the session where they are defined. A value is usually assigned using the SET command:
</p>
<pre>
SET @USER = 'Joe';
</pre>
<p>
It is also possible to change a value using the SET() method. This is useful in queries:
</p>
<pre>
SET @TOTAL = NULL;
SELECT X, SET(@TOTAL, IFNULL(@TOTAL, 1.) * X) F FROM SYSTEM_RANGE(1, 50);
</pre>
<p>
Variables that are not set evaluate to NULL. The data type of a user defined variable is the data type
of the value assigned to it, that means it is not necessary (or possible) to declare variable names before using them.
There are no restrictions on the assigned values, large objects (LOBs) are supported as well.
</p>
</div></td></tr></table></body></html>
h2/src/main/org/h2/command/Command.java
浏览文件 @
95620da6
...
...
@@ -139,6 +139,7 @@ public abstract class Command implements CommandInterface {
}
private
void
stop
()
throws
SQLException
{
session
.
closeTemporaryResults
();
session
.
setCurrentCommand
(
null
,
0
);
if
(!
isTransactional
())
{
session
.
commit
(
true
);
...
...
h2/src/main/org/h2/command/dml/Query.java
浏览文件 @
95620da6
...
...
@@ -223,12 +223,19 @@ public abstract class Query extends Prepared {
}
}
lastParameters
=
params
;
closeLastResult
();
lastResult
=
queryWithoutCache
(
limit
);
this
.
lastEvaluated
=
now
;
lastLimit
=
limit
;
return
lastResult
;
}
private
void
closeLastResult
()
{
if
(
lastResult
!=
null
)
{
lastResult
.
close
();
}
}
protected
void
initOrder
(
ObjectArray
expressions
,
ObjectArray
expressionSQL
,
ObjectArray
orderList
,
int
visible
,
boolean
mustBeInResult
)
throws
SQLException
{
for
(
int
i
=
0
;
i
<
orderList
.
size
();
i
++)
{
...
...
h2/src/main/org/h2/constant/SysProperties.java
浏览文件 @
95620da6
...
...
@@ -226,10 +226,10 @@ public class SysProperties {
* Optimize IN(...) comparisons.
*/
public
static
final
boolean
OPTIMIZE_IN
=
getBooleanSetting
(
"h2.optimizeIn"
,
true
);
/**
* System property <code>h2.optimizeInJoin</code> (default: false).<br />
* Optimize IN(
SELECT ...) comparisons by converting them to a join
.
* Optimize IN(
...) comparisons by converting them to inner joins
.
*/
public
static
final
boolean
OPTIMIZE_IN_JOIN
=
getBooleanSetting
(
"h2.optimizeInJoin"
,
false
);
...
...
@@ -244,17 +244,17 @@ public class SysProperties {
* Cache subquery results.
*/
public
static
final
boolean
OPTIMIZE_SUBQUERY_CACHE
=
getBooleanSetting
(
"h2.optimizeSubqueryCache"
,
true
);
/**
* System property <code>h2.optimizeNot</code> (default: true).<br />
* Optimize NOT
express
ion.
* Optimize NOT
conditions by removing the NOT and inverting the condit
ion.
*/
public
static
final
boolean
OPTIMIZE_NOT
=
getBooleanSetting
(
"h2.optimizeNot"
,
true
);
/**
* System property <code>h2.optimizeTwoEquals</code> (default: true).<br />
* Optimize expressions of the form A=B AND B=1. In this case, AND A=1 is added so an index on A can be used.
*/
*/
public
static
final
boolean
OPTIMIZE_TWO_EQUALS
=
getBooleanSetting
(
"h2.optimizeTwoEquals"
,
true
);
/**
...
...
@@ -298,10 +298,10 @@ public class SysProperties {
* The default result set fetch size when using the server mode.
*/
public
static
final
int
SERVER_RESULT_SET_FETCH_SIZE
=
getIntSetting
(
"h2.serverResultSetFetchSize"
,
100
);
/**
* System property <code>h2.traceIO</code> (default: false).<br />
* Trace I/O operations.
* Trace
all
I/O operations.
*/
public
static
final
boolean
TRACE_IO
=
getBooleanSetting
(
"h2.traceIO"
,
false
);
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
95620da6
...
...
@@ -60,6 +60,7 @@ import org.h2.util.StringUtils;
import
org.h2.value.CompareMode
;
import
org.h2.value.Value
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueLob
;
/**
* There is one database object per open database.
...
...
@@ -870,6 +871,14 @@ public class Database implements DataHandler {
}
catch
(
SQLException
e
)
{
traceSystem
.
getTrace
(
Trace
.
DATABASE
).
error
(
"close"
,
e
);
}
// remove all session variables
if
(
persistent
)
{
try
{
ValueLob
.
removeAllForTable
(
this
,
ValueLob
.
TABLE_ID_SESSION
);
}
catch
(
SQLException
e
)
{
traceSystem
.
getTrace
(
Trace
.
DATABASE
).
error
(
"close"
,
e
);
}
}
try
{
closeOpenFilesAndUnlock
();
}
catch
(
SQLException
e
)
{
...
...
h2/src/main/org/h2/engine/Session.java
浏览文件 @
95620da6
...
...
@@ -26,6 +26,7 @@ import org.h2.log.UndoLogRecord;
import
org.h2.message.Message
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceSystem
;
import
org.h2.result.LocalResult
;
import
org.h2.result.Row
;
import
org.h2.schema.Schema
;
import
org.h2.store.DataHandler
;
...
...
@@ -33,6 +34,7 @@ import org.h2.table.Table;
import
org.h2.util.ObjectArray
;
import
org.h2.util.ObjectUtils
;
import
org.h2.value.Value
;
import
org.h2.value.ValueLob
;
import
org.h2.value.ValueLong
;
import
org.h2.value.ValueNull
;
...
...
@@ -77,6 +79,7 @@ public class Session implements SessionInterface {
private
long
sessionStart
=
System
.
currentTimeMillis
();
private
long
currentCommandStart
;
private
HashMap
variables
;
private
HashSet
temporaryResults
;
public
Session
()
{
}
...
...
@@ -87,12 +90,22 @@ public class Session implements SessionInterface {
}
}
public
void
setVariable
(
String
name
,
Value
value
)
{
public
void
setVariable
(
String
name
,
Value
value
)
throws
SQLException
{
initVariables
();
Value
old
;
if
(
value
==
ValueNull
.
INSTANCE
)
{
variables
.
remove
(
name
);
old
=
(
Value
)
variables
.
remove
(
name
);
}
else
{
variables
.
put
(
name
,
value
);
if
(
value
instanceof
ValueLob
)
{
// link it, to make sure we have our own file
value
=
value
.
link
(
database
,
ValueLob
.
TABLE_ID_SESSION
);
}
old
=
(
Value
)
variables
.
put
(
name
,
value
);
}
if
(
old
!=
null
)
{
// close the old value (in case it is a lob)
old
.
unlink
();
old
.
close
();
}
}
...
...
@@ -663,4 +676,20 @@ public class Session implements SessionInterface {
}
}
public
void
addTemporaryResult
(
LocalResult
result
)
{
if
(
temporaryResults
==
null
)
{
temporaryResults
=
new
HashSet
();
}
temporaryResults
.
add
(
result
);
}
public
void
closeTemporaryResults
()
{
if
(
temporaryResults
!=
null
)
{
for
(
Iterator
it
=
temporaryResults
.
iterator
();
it
.
hasNext
();)
{
LocalResult
result
=
(
LocalResult
)
it
.
next
();
result
.
close
();
}
}
}
}
h2/src/main/org/h2/expression/ConditionExists.java
浏览文件 @
95620da6
...
...
@@ -28,12 +28,9 @@ public class ConditionExists extends Condition {
public
Value
getValue
(
Session
session
)
throws
SQLException
{
query
.
setSession
(
session
);
LocalResult
result
=
query
.
query
(
1
);
try
{
boolean
r
=
result
.
getRowCount
()
>
0
;
return
ValueBoolean
.
get
(
r
);
}
finally
{
result
.
close
();
}
session
.
addTemporaryResult
(
result
);
boolean
r
=
result
.
getRowCount
()
>
0
;
return
ValueBoolean
.
get
(
r
);
}
public
Expression
optimize
(
Session
session
)
throws
SQLException
{
...
...
h2/src/main/org/h2/expression/ConditionInSelect.java
浏览文件 @
95620da6
...
...
@@ -46,33 +46,30 @@ public class ConditionInSelect extends Condition {
}
query
.
setSession
(
session
);
LocalResult
rows
=
query
.
query
(
0
);
session
.
addTemporaryResult
(
rows
);
boolean
hasNull
=
false
;
boolean
result
=
all
;
try
{
while
(
rows
.
next
())
{
boolean
value
;
Value
r
=
rows
.
currentRow
()[
0
];
if
(
r
==
ValueNull
.
INSTANCE
)
{
value
=
false
;
hasNull
=
true
;
}
else
{
value
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
compareType
);
}
if
(!
value
&&
all
)
{
result
=
false
;
break
;
}
else
if
(
value
&&
!
all
)
{
result
=
true
;
break
;
}
while
(
rows
.
next
())
{
boolean
value
;
Value
r
=
rows
.
currentRow
()[
0
];
if
(
r
==
ValueNull
.
INSTANCE
)
{
value
=
false
;
hasNull
=
true
;
}
else
{
value
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
compareType
);
}
if
(!
result
&&
hasNull
)
{
return
ValueNull
.
INSTANCE
;
if
(!
value
&&
all
)
{
result
=
false
;
break
;
}
else
if
(
value
&&
!
all
)
{
result
=
true
;
break
;
}
return
ValueBoolean
.
get
(
result
);
}
finally
{
rows
.
close
();
}
if
(!
result
&&
hasNull
)
{
return
ValueNull
.
INSTANCE
;
}
return
ValueBoolean
.
get
(
result
);
}
public
void
mapColumns
(
ColumnResolver
resolver
,
int
queryLevel
)
throws
SQLException
{
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
95620da6
...
...
@@ -114,8 +114,8 @@ public class Function extends Expression implements FunctionCall {
datePart
.
put
(
"MONTH"
,
ObjectUtils
.
getInteger
(
Calendar
.
MONTH
));
datePart
.
put
(
"DD"
,
ObjectUtils
.
getInteger
(
Calendar
.
DATE
));
datePart
.
put
(
"DAY"
,
ObjectUtils
.
getInteger
(
Calendar
.
DATE
));
datePart
.
put
(
"HH"
,
ObjectUtils
.
getInteger
(
Calendar
.
HOUR
));
datePart
.
put
(
"HOUR"
,
ObjectUtils
.
getInteger
(
Calendar
.
HOUR
));
datePart
.
put
(
"HH"
,
ObjectUtils
.
getInteger
(
Calendar
.
HOUR
_OF_DAY
));
datePart
.
put
(
"HOUR"
,
ObjectUtils
.
getInteger
(
Calendar
.
HOUR
_OF_DAY
));
datePart
.
put
(
"MI"
,
ObjectUtils
.
getInteger
(
Calendar
.
MINUTE
));
datePart
.
put
(
"MINUTE"
,
ObjectUtils
.
getInteger
(
Calendar
.
MINUTE
));
datePart
.
put
(
"SS"
,
ObjectUtils
.
getInteger
(
Calendar
.
SECOND
));
...
...
@@ -1102,7 +1102,7 @@ public class Function extends Expression implements FunctionCall {
// return (t2 - t1) / 1000;
// case Calendar.MINUTE:
// return (t2 - t1) / 1000 / 60;
// case Calendar.HOUR:
// case Calendar.HOUR
_OF_DAY
:
// return (t2 - t1) / 1000 / 60 / 60;
// case Calendar.DATE:
// return (t2 - t1) / 1000 / 60 / 60 / 24;
...
...
@@ -1170,7 +1170,7 @@ public class Function extends Expression implements FunctionCall {
return
t2
-
t1
;
case
Calendar
.
SECOND
:
case
Calendar
.
MINUTE
:
case
Calendar
.
HOUR
:
{
case
Calendar
.
HOUR
_OF_DAY
:
{
// first 'normalize' the numbers so both are not negative
long
hour
=
60
*
60
*
1000
;
long
add
=
Math
.
min
(
t1
/
hour
*
hour
,
t2
/
hour
*
hour
);
...
...
@@ -1181,7 +1181,7 @@ public class Function extends Expression implements FunctionCall {
return
t2
/
1000
-
t1
/
1000
;
case
Calendar
.
MINUTE
:
return
t2
/
(
60
*
1000
)
-
t1
/
(
60
*
1000
);
case
Calendar
.
HOUR
:
case
Calendar
.
HOUR
_OF_DAY
:
return
t2
/
hour
-
t1
/
hour
;
default
:
throw
Message
.
getInternalError
(
"field:"
+
field
);
...
...
h2/src/main/org/h2/fulltext/FullTextSettings.java
浏览文件 @
95620da6
...
...
@@ -67,11 +67,11 @@ public class FullTextSettings {
private
static
String
getIndexPath
(
Connection
conn
)
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
ResultSet
rs
=
stat
.
executeQuery
(
"CALL
DATABASE_PATH(
)"
);
ResultSet
rs
=
stat
.
executeQuery
(
"CALL
IFNULL(DATABASE_PATH(), 'MEM:' || DATABASE()
)"
);
rs
.
next
();
String
path
=
rs
.
getString
(
1
);
if
(
path
==
null
)
{
throw
new
SQLException
(
"FULLTEXT"
,
"Fulltext search for in-memory databases is not supported."
);
if
(
"MEM:UNNAMED"
.
equals
(
path
)
)
{
throw
new
SQLException
(
"FULLTEXT"
,
"Fulltext search for
private (unnamed)
in-memory databases is not supported."
);
}
rs
.
close
();
return
path
;
...
...
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
95620da6
...
...
@@ -83,7 +83,7 @@ public class LocalResult implements ResultInterface {
}
public
LocalResult
createShallowCopy
(
Session
session
)
{
if
(
disk
==
null
&&
rows
==
null
||
rows
.
size
()
<
rowCount
)
{
if
(
disk
==
null
&&
(
rows
==
null
||
rows
.
size
()
<
rowCount
)
)
{
return
null
;
}
LocalResult
copy
=
new
LocalResult
(
0
);
...
...
h2/src/main/org/h2/server/web/PageParser.java
浏览文件 @
95620da6
...
...
@@ -223,19 +223,21 @@ public class PageParser {
return
escapeHtml
(
s
,
true
);
}
p
ublic
static
String
escapeHtml
(
String
s
,
boolean
convertBreak
)
{
p
rivate
static
String
escapeHtml
(
String
s
,
boolean
convertBreak
)
{
if
(
s
==
null
)
{
return
null
;
}
if
(
s
.
length
()
==
0
)
{
return
" "
;
if
(
convertBreak
)
{
if
(
s
.
length
()
==
0
)
{
return
" "
;
}
}
StringBuffer
buff
=
new
StringBuffer
(
s
.
length
());
boolean
convertSpace
=
true
;
for
(
int
i
=
0
;
i
<
s
.
length
();
i
++)
{
char
c
=
s
.
charAt
(
i
);
if
(
c
==
' '
)
{
if
(
convertSpace
)
{
if
(
convertSpace
&&
convertBreak
)
{
buff
.
append
(
" "
);
}
else
{
buff
.
append
(
' '
);
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
95620da6
...
...
@@ -463,7 +463,7 @@ public class Column {
}
public
String
getDefaultSQL
()
{
return
defaultExpression
==
null
?
""
:
defaultExpression
.
getSQL
();
return
defaultExpression
==
null
?
null
:
defaultExpression
.
getSQL
();
}
public
int
getPrecisionAsInt
()
{
...
...
h2/src/main/org/h2/util/StringUtils.java
浏览文件 @
95620da6
...
...
@@ -608,6 +608,11 @@ public class StringUtils {
return
buff
.
append
(
'\"'
).
toString
();
}
/**
* Check if a String is null or empty (the length is null).
*
* @return true if it is null or empty
*/
public
static
boolean
isNullOrEmpty
(
String
s
)
{
return
s
==
null
||
s
.
length
()
==
0
;
}
...
...
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
95620da6
...
...
@@ -35,6 +35,8 @@ public class ValueLob extends Value {
// TODO lob: concatenate function for blob and clob (to create a large blob from pieces)
// and a getpart function (to get it in pieces) and make sure a file is created!
public
static
final
int
TABLE_ID_SESSION
=
-
1
;
private
final
int
type
;
private
long
precision
;
private
DataHandler
handler
;
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
95620da6
...
...
@@ -150,14 +150,59 @@ java org.h2.test.TestAll timer
/*
CACHE_SIZE_INDEX_DEFAULT
INTERNAL
ErrorCodes doesn't look nice
drop table test;
create table test(id int);
insert into test values(1);
select extract(hour from timestamp '2001-02-03 14:15:16') from test;
select extract(hour from '2001-02-03 14:15:16') from test;
select hour('2001-02-03 14:15:16') from test;
A bug was introduced into the H2 Console's Web Server last year. When
opening the Console (default port 8082), the user is presented with
web page that includes a <select> of Saved Settings
(.h2.server.properties). If the Name of a setting contains consecutive
spaces, the spaces may get escaped to ' '. That causes the name
in HTML to no longer match the name from the properties file. Thus,
the setting cannot be selected by the user.
Noting a 'compatibility' difference between H2 and Oracle or MySQL. In
org.h2.expression.Fucntion.java, you map 'HOUR' to Calendar.HOUR
instead of Calendar.HOUR_OF_DAY. This, given a timestamp at 6pm,
Oracle and MySQL will return 18 whereas H2 will return 6. It seems a
bug in H2 to me, because trying to GROUP on EXTRACT(HOUR FROM...) will
fold all afternoon aggregates into the morning aggregates. Even if it
is a bug in H2, I guess it could be problematic to 'fix it' since
existing users of H2 might rely the 'buggy' behaviour. Could you
change the default to HOUR_OF_DAY and make it an option to keep the
old HOUR behaviour?
flights.zip example usage
light.zip source code and binary jar
copyright 2008
other databases return SQL 'null' if there is no column default defined. The next release of H2 will do the same.
google analytics to web site
quaere:
where(test(a).bigger(b));
where(test(a, BIGGER, b));
where(test(a).bigger(b).and(a).smaller(b));
Roadmap:
History:
The method EXTRACT(HOUR FROM...) returned the wrong values (0 to 11 instead of 0 to 23).
For compatibility with other databases the column default (COLUMN_DEF) for columns without default is now null (it was an empty string).
Statements that contain very large subqueries (where the subquery result does not fit in memory) are now faster.
Variables: large objects (CLOB and BLOB) that don't fit in memory did not work correctly when used as variables.
Fulltext search is now supported in named in-memory databases.
Test Recovery with MAX_LOG_FILE_SIZE=1; test with various log file sizes
...
...
h2/src/test/org/h2/test/db/TestBigResult.java
浏览文件 @
95620da6
...
...
@@ -21,12 +21,36 @@ public class TestBigResult extends TestBase {
if
(
config
.
memory
)
{
return
;
}
testLargeSubquery
();
testLargeUpdateDelete
();
testCloseConnectionDelete
();
testOrderGroup
();
testLimitBufferedResult
();
}
private
void
testLargeSubquery
()
throws
Exception
{
deleteDb
(
"bigResult"
);
Connection
conn
=
getConnection
(
"bigResult"
);
Statement
stat
=
conn
.
createStatement
();
int
len
=
getSize
(
1000
,
4000
);
stat
.
execute
(
"SET MAX_MEMORY_ROWS "
+
(
len
/
10
));
stat
.
execute
(
"CREATE TABLE RECOVERY(TRANSACTION_ID INT, SQL_STMT VARCHAR)"
);
stat
.
execute
(
"INSERT INTO RECOVERY "
+
"SELECT X, CASE MOD(X, 2) WHEN 0 THEN 'commit' ELSE 'begin' END "
+
"FROM SYSTEM_RANGE(1, "
+
len
+
")"
);
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM RECOVERY WHERE SQL_STMT LIKE 'begin%' AND "
+
"TRANSACTION_ID NOT IN(SELECT TRANSACTION_ID FROM RECOVERY "
+
"WHERE SQL_STMT='commit' OR SQL_STMT='rollback')"
);
int
count
=
0
,
last
=
1
;
while
(
rs
.
next
())
{
check
(
last
,
rs
.
getInt
(
1
));
last
+=
2
;
count
++;
}
check
(
len
/
2
,
count
);
conn
.
close
();
}
private
void
testLargeUpdateDelete
()
throws
Exception
{
deleteDb
(
"bigResult"
);
Connection
conn
=
getConnection
(
"bigResult"
);
...
...
h2/src/test/org/h2/test/db/TestLob.java
浏览文件 @
95620da6
...
...
@@ -34,6 +34,7 @@ public class TestLob extends TestBase {
if
(
config
.
memory
)
{
return
;
}
testLobVariable
();
testLobDrop
();
testLobNoClose
();
testLobTransactions
(
10
);
...
...
@@ -54,6 +55,23 @@ public class TestLob extends TestBase {
testJavaObject
();
}
private
void
testLobVariable
()
throws
Exception
{
deleteDb
(
"lob"
);
Connection
conn
=
reconnect
(
null
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID INT, DATA CLOB)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, SPACE(100000))"
);
stat
.
execute
(
"SET @TOTAL = SELECT DATA FROM TEST WHERE ID=1"
);
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"CALL @TOTAL LIKE '%X'"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT, DATA CLOB)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(1, @TOTAL)"
);
stat
.
execute
(
"INSERT INTO TEST VALUES(2, @TOTAL)"
);
stat
.
execute
(
"DROP TABLE TEST"
);
stat
.
execute
(
"CALL @TOTAL LIKE '%X'"
);
conn
.
close
();
}
private
void
testLobDrop
()
throws
Exception
{
if
(
config
.
logMode
==
0
||
config
.
networked
)
{
return
;
...
...
h2/src/test/org/h2/test/jdbc/TestMetaData.java
浏览文件 @
95620da6
...
...
@@ -29,6 +29,7 @@ public class TestMetaData extends TestBase {
deleteDb
(
"metaData"
);
conn
=
getConnection
(
"metaData"
);
testColumnDefault
();
testCrossReferences
();
testProcedureColumns
();
...
...
@@ -190,6 +191,22 @@ public class TestMetaData extends TestBase {
}
private
void
testColumnDefault
()
throws
Exception
{
DatabaseMetaData
meta
=
conn
.
getMetaData
();
ResultSet
rs
;
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(A INT, B INT DEFAULT NULL)"
);
rs
=
meta
.
getColumns
(
null
,
null
,
"TEST"
,
null
);
rs
.
next
();
check
(
"A"
,
rs
.
getString
(
"COLUMN_NAME"
));
check
(
null
,
rs
.
getString
(
"COLUMN_DEF"
));
rs
.
next
();
check
(
"B"
,
rs
.
getString
(
"COLUMN_NAME"
));
check
(
"NULL"
,
rs
.
getString
(
"COLUMN_DEF"
));
checkFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
}
private
void
testProcedureColumns
()
throws
Exception
{
DatabaseMetaData
meta
=
conn
.
getMetaData
();
ResultSet
rs
;
...
...
@@ -550,24 +567,24 @@ public class TestMetaData extends TestBase {
testResultSetOrdered
(
rs
,
new
String
[][]
{
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"ID"
,
""
+
Types
.
INTEGER
,
"INTEGER"
,
"10"
,
"10"
,
"0"
,
"10"
,
""
+
DatabaseMetaData
.
columnNoNulls
,
""
,
""
,
""
+
Types
.
INTEGER
,
"0"
,
"10"
,
"1"
,
"10"
,
""
+
DatabaseMetaData
.
columnNoNulls
,
""
,
null
,
""
+
Types
.
INTEGER
,
"0"
,
"10"
,
"1"
,
"NO"
},
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"TEXT_V"
,
""
+
Types
.
VARCHAR
,
"VARCHAR"
,
"120"
,
"120"
,
"0"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
""
,
""
+
Types
.
VARCHAR
,
"120"
,
"0"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
null
,
""
+
Types
.
VARCHAR
,
"0"
,
"120"
,
"2"
,
"YES"
},
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"DEC_V"
,
""
+
Types
.
DECIMAL
,
"DECIMAL"
,
"12"
,
"12"
,
"3"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
""
,
""
+
Types
.
DECIMAL
,
"0"
,
"12"
,
"3"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
null
,
""
+
Types
.
DECIMAL
,
"0"
,
"12"
,
"3"
,
"YES"
},
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"DATE_V"
,
""
+
Types
.
TIMESTAMP
,
"TIMESTAMP"
,
"23"
,
"23"
,
"10"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
""
,
""
+
Types
.
TIMESTAMP
,
"23"
,
"10"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
null
,
""
+
Types
.
TIMESTAMP
,
"0"
,
"23"
,
"4"
,
"YES"
},
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"BLOB_V"
,
""
+
Types
.
BLOB
,
"BLOB"
,
""
+
Integer
.
MAX_VALUE
,
""
+
Integer
.
MAX_VALUE
,
"0"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
""
,
""
+
Types
.
BLOB
,
"0"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
null
,
""
+
Types
.
BLOB
,
"0"
,
""
+
Integer
.
MAX_VALUE
,
"5"
,
"YES"
},
{
catalog
,
Constants
.
SCHEMA_MAIN
,
"TEST"
,
"CLOB_V"
,
""
+
Types
.
CLOB
,
"CLOB"
,
""
+
Integer
.
MAX_VALUE
,
""
+
Integer
.
MAX_VALUE
,
"0"
,
"10"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
""
,
""
+
Types
.
CLOB
,
"0"
,
""
+
DatabaseMetaData
.
columnNullable
,
""
,
null
,
""
+
Types
.
CLOB
,
"0"
,
""
+
Integer
.
MAX_VALUE
,
"6"
,
"YES"
}
});
/*
* rs=meta.getColumns(null,null,"TEST",null); while(rs.next()) { int
...
...
h2/src/test/org/h2/test/test.in.txt
浏览文件 @
95620da6
...
...
@@ -1056,11 +1056,11 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT REMARKS
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- -------
> SCRIPT PUBLIC ORDERS COMPLETED 4
NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3
YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS NAME 2
YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS ORDERID 1
YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS VERIFIED 5
YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50
> SCRIPT PUBLIC ORDERS COMPLETED 4
null
NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3
null
YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS NAME 2
null
YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS ORDERID 1
null
YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50
> SCRIPT PUBLIC ORDERS VERIFIED 5
null
YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50
> rows: 5
drop table orders;
...
...
@@ -1466,11 +1466,11 @@ select * from test;
select DOMAIN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, PRECISION, SCALE, TYPE_NAME, SELECTIVITY, CHECK_CONSTRAINT, REMARKS, SQL from information_schema.domains;
> DOMAIN_NAME COLUMN_DEFAULT IS_NULLABLE DATA_TYPE PRECISION SCALE TYPE_NAME SELECTIVITY CHECK_CONSTRAINT REMARKS SQL
> ----------- -------------- ----------- --------- ---------- ----- --------- ----------- --------------------------------------------------------------- ------- ------------------------------------------------------------------------------------------------------------------------------
> EMAIL
YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1)
> EMAIL
null
YES 12 200 0 VARCHAR 50 (POSITION('@', VALUE) > 1) CREATE DOMAIN EMAIL AS VARCHAR(200) CHECK (POSITION('@', VALUE) > 1)
> GMAIL '@gmail.com' YES 12 200 0 VARCHAR 50 ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1)) CREATE DOMAIN GMAIL AS VARCHAR(200) DEFAULT '@gmail.com' CHECK ((POSITION('@', VALUE) > 1) AND (POSITION('gmail', VALUE) > 1))
> STRING '' NO 12 255 0 VARCHAR 50 CREATE DOMAIN STRING AS VARCHAR(255) DEFAULT '' NOT NULL
> STRING1
YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR
> STRING2
NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL
> STRING1
null
YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING1 AS VARCHAR
> STRING2
null
NO 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING2 AS VARCHAR NOT NULL
> STRING3 '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING3 AS VARCHAR DEFAULT '<empty>'
> STRING_X '<empty>' YES 12 2147483647 0 VARCHAR 50 CREATE DOMAIN STRING_X AS VARCHAR DEFAULT '<empty>'
> rows: 7
...
...
h2/src/test/org/h2/test/testSimple.in.txt
浏览文件 @
95620da6
select extract(hour from timestamp '2001-02-03 14:15:16');
> 14;
select extract(hour from '2001-02-03 14:15:16');
> 14;
select hour('2001-02-03 14:15:16');
> 14;
CREATE TABLE TEST(A int NOT NULL, B int NOT NULL, C int) ;
ALTER TABLE TEST ADD CONSTRAINT CON UNIQUE(A,B);
ALTER TABLE TEST DROP C;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论