Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
09dac088
提交
09dac088
authored
8月 29, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
da52f772
隐藏空白字符变更
内嵌
并排
正在显示
36 个修改的文件
包含
1245 行增加
和
1205 行删除
+1245
-1205
build.xml
h2/build.xml
+2
-2
download.html
h2/src/docsrc/html/download.html
+13
-12
faq.html
h2/src/docsrc/html/faq.html
+0
-1
features.html
h2/src/docsrc/html/features.html
+3
-0
history.html
h2/src/docsrc/html/history.html
+19
-2
_docs_en.properties
h2/src/docsrc/textbase/_docs_en.properties
+853
-1017
_messages_en.properties
h2/src/docsrc/textbase/_messages_en.properties
+1
-1
Parser.java
h2/src/main/org/h2/command/Parser.java
+14
-4
CreateFunctionAlias.java
h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java
+7
-2
Select.java
h2/src/main/org/h2/command/dml/Select.java
+18
-8
ConstraintReferential.java
h2/src/main/org/h2/constraint/ConstraintReferential.java
+8
-0
Constants.java
h2/src/main/org/h2/engine/Constants.java
+2
-1
FunctionAlias.java
h2/src/main/org/h2/engine/FunctionAlias.java
+58
-48
FunctionCall.java
h2/src/main/org/h2/expression/FunctionCall.java
+1
-1
JavaFunction.java
h2/src/main/org/h2/expression/JavaFunction.java
+1
-1
FunctionIndex.java
h2/src/main/org/h2/index/FunctionIndex.java
+2
-5
MultiVersionCursor.java
h2/src/main/org/h2/index/MultiVersionCursor.java
+0
-4
MultiVersionIndex.java
h2/src/main/org/h2/index/MultiVersionIndex.java
+0
-8
ScanCursor.java
h2/src/main/org/h2/index/ScanCursor.java
+5
-5
ScanIndex.java
h2/src/main/org/h2/index/ScanIndex.java
+17
-10
PgServerThread.java
h2/src/main/org/h2/server/pg/PgServerThread.java
+4
-4
MultiDimension.java
h2/src/main/org/h2/tools/MultiDimension.java
+56
-2
Recover.java
h2/src/main/org/h2/tools/Recover.java
+4
-1
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+3
-3
MemoryFile.java
h2/src/main/org/h2/util/MemoryFile.java
+1
-0
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+5
-27
test.properties
h2/src/test/org/h2/test/bench/test.properties
+3
-3
TestBackup.java
h2/src/test/org/h2/test/db/TestBackup.java
+1
-0
TestLinkedTable.java
h2/src/test/org/h2/test/db/TestLinkedTable.java
+21
-0
TestMultiDimension.java
h2/src/test/org/h2/test/db/TestMultiDimension.java
+43
-8
TestMVCC.java
h2/src/test/org/h2/test/mvcc/TestMVCC.java
+10
-0
test.in.txt
h2/src/test/org/h2/test/test.in.txt
+59
-2
testSimple.in.txt
h2/src/test/org/h2/test/testSimple.in.txt
+2
-2
TestFileLock.java
h2/src/test/org/h2/test/unit/TestFileLock.java
+7
-19
LinkChecker.java
h2/src/tools/org/h2/tools/doc/LinkChecker.java
+1
-1
dictionary.txt
h2/src/tools/org/h2/tools/doc/dictionary.txt
+1
-1
没有找到文件。
h2/build.xml
浏览文件 @
09dac088
...
...
@@ -12,7 +12,7 @@
</path>
<target
name=
"all"
depends=
"jar,javadoc,docs"
>
<delete
includeemptydirs=
"true"
verbose=
"true"
>
<delete
includeemptydirs=
"true"
>
<fileset
dir=
"bin"
includes=
"**/*.txt"
/>
<fileset
dir=
"bin"
includes=
"h2-test.exe"
/>
<fileset
dir=
"bin"
includes=
"org/**/*"
/>
...
...
@@ -119,7 +119,7 @@
<target
name=
"compileTest"
unless=
"java.version.ok"
>
<echo
message=
"Java version is ${java.specification.version} but source code is switched to ${jdk}."
/>
<echo
message=
"Run ant codeswitchJdk.. first."
/>
<echo
message=
"Run ant codeswitchJdk..
.
first."
/>
</target>
<target
name=
"createPatch"
depends=
"clean"
>
...
...
h2/src/docsrc/html/download.html
浏览文件 @
09dac088
...
...
@@ -13,31 +13,32 @@ H2 Database Engine
</head><body
onload=
"frameMe();"
>
<table
class=
"content"
><tr
class=
"content"
><td
class=
"content"
><div
class=
"contentDiv"
>
<h1>
Downloads
</h1>
<h1>
Downloads
</h1>
<h3>
Version 1.0.57 (2008-08-25, Current)
</h3>
<h3>
Version 1.0.57 (2008-08-25, Current)
</h3>
<p>
<a
href=
"http://www.h2database.com/h2-setup-2007-08-25.exe"
>
Windows Installer
</a><br
/>
<a
href=
"http://www.h2database.com/h2-2007-08-25.zip"
>
Platform-Independent Zip
</a><br
/>
<a
href=
"http://www.h2database.com/h2-setup-2007-08-25.exe"
>
Windows Installer
</a><br
/>
<a
href=
"http://www.h2database.com/h2-2007-08-25.zip"
>
Platform-Independent Zip
</a><br
/>
</p>
<h3>
Version 1.0 / 2007-03-04 (Last Stable)
</h3>
<h3>
Version 1.0 / 2007-03-04 (Last Stable)
</h3>
<p>
<a
href=
"http://www.h2database.com/h2-setup-2007-03-04.exe"
>
Windows Installer
</a><br
/>
<a
href=
"http://www.h2database.com/h2-2007-03-04.zip"
>
Platform-Independent Zip
</a><br
/>
<a
href=
"http://www.h2database.com/h2-setup-2007-03-04.exe"
>
Windows Installer
</a><br
/>
<a
href=
"http://www.h2database.com/h2-2007-03-04.zip"
>
Platform-Independent Zip
</a><br
/>
</p>
<h3>
Download Mirror
</h3>
<h3>
Download Mirror
</h3>
<p>
<a
href=
"http://code.google.com/p/h2database/downloads/list"
>
Platform-Independent Zip
</a><br
/>
<a
href=
"http://code.google.com/p/h2database/downloads/list"
>
Platform-Independent Zip
</a><br
/>
</p>
<h3>
Subversion Source Repository
</h3>
<h3>
Subversion Source Repository
</h3>
<p>
<a
href=
"http://code.google.com/p/h2database/source"
>
Google Code
</a>
<a
href=
"http://code.google.com/p/h2database/source"
>
Google Code
</a>
</p>
<p>
For details about changes, see the
<a
href=
"history.html"
>
Change Log
</a>
.
</p>
For details about changes, see the
<a
href=
"history.html"
>
Change Log
</a>
.
</p>
</div></td></tr></table></body></html>
\ No newline at end of file
h2/src/docsrc/html/faq.html
浏览文件 @
09dac088
...
...
@@ -44,7 +44,6 @@ Here is the list of known and confirmed issues as of
<ul>
<li>
Some problems have been found with right outer join. Internally, it is converted to left outer join, which
does not always produce the same results as other databases when used in combination with other joins.
</li><li>
Using a CAST in a GROUP BY expression that is used in a view does not always work.
</li></ul>
<br
/><a
name=
"open_source"
></a>
...
...
h2/src/docsrc/html/features.html
浏览文件 @
09dac088
...
...
@@ -241,6 +241,9 @@ It looks like the development of this database has stopped. The last release was
</tr><tr>
<td><a
href=
"http://appfuse.org"
>
AppFuse
</a></td>
<td>
Helps building web applications.
</td>
</tr><tr>
<td><a
href=
"http://wiki.blojsom.com"
>
Blojsom
</a></td>
<td>
Java-based multi-blog, multi-user software package (Mac OS X Weblog Server)
</td>
</tr><tr>
<td><a
href=
"http://bmarks-portlet.sourceforge.net"
>
Bookmarks Portlet
</a></td>
<td>
JSR168 compliant bookmarks management portlet application.
</td>
...
...
h2/src/docsrc/html/history.html
浏览文件 @
09dac088
...
...
@@ -39,7 +39,22 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>
Version 1.0 (Current)
</h3>
<h3>
Version 1.0.57 (2008-08-25)
</h3><ul>
<h3>
Version 1.0.x (2007-09-x)
</h3><ul>
<li>
A database can now be opened even if class of a user defined function is not in the classpath.
Trying to call the function will throws an exception.
</li><li>
User defined functions and constants may not overload built-in functions and constants.
This didn't work before, but now trying to create such an object didn't fail.
</li><li>
Improved MultiDimension tool (for spatial queries): in the last few releases the tool was actually
slower than using a regular query (because index lookup got faster, and because the tool didn't
support prepared statements) Now the tool generates prepared statements,
and the performance is better again (about 5 times faster for a reasonable amount of data).
</li><li>
Adding a foreign key or when re-enabling referential integrity for a table failed when checking
was enabled and the reference contained NULL.
</li><li>
For PgServer, character encoding other than UTF-8 did not work correctly. Fixed.
</li><li>
Using a function in a GROUP BY expression that is used in a view as a condition did not always work.
</li></ul>
<h3>
Version 1.0.57 (2007-08-25)
</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). This is work-in-progress, use it at your own risk. Feedback is welcome.
...
...
@@ -488,6 +503,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>
Copy database: Tool with config GUI and batch mode, extensible (example: compare)
</li><li>
Document, implement tool for long running transactions using user defined compensation statements
</li><li>
Support SET TABLE DUAL READONLY
</li><li>
Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files
</li><li>
Don't write stack traces for common exceptions like duplicate key to the log by default
</li><li>
Setting for MAX_QUERY_TIME (default no limit?)
</li><li>
GCJ: what is the state now?
...
...
@@ -653,7 +669,6 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>
A way (JDBC driver) to map an URL (jdbc:h2map:c1) to a connection object
</li><li>
Build script for the embedded functionality only (h2embedded.jar)
</li><li>
Option for SCRIPT to only process one or a set of tables, and append to a file
</li><li>
Linked schema using CSV files: one schema for a directory of files; support indexes for CSV files
</li><li>
Support using a unique index for IS NULL (including linked tables)
</li><li>
Support linked tables to the current database
</li><li>
Support dynamic linked schema (automatically adding/updating/removing tables)
...
...
@@ -705,6 +720,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</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><li>
ParameterMetaData should return correct data type where possible (INSERT for example)
</li><li>
Support indexes for views (probably requires materialized views)
</li><li>
Linked tables that point to the same database should share the connection
</li></ul>
<h3>
Not Planned
</h3>
...
...
h2/src/docsrc/textbase/_docs_en.properties
浏览文件 @
09dac088
This source diff could not be displayed because it is too large. You can
view the blob
instead.
h2/src/docsrc/textbase/_messages_en.properties
浏览文件 @
09dac088
...
...
@@ -141,7 +141,7 @@
90118
=
Cannot drop table {0}
90119
=
User data type {0} already exists
90120
=
User data type {0} not found
90121
=
Database
called at VM shutdown; add ";DB_CLOSE_ON_EXIT
\=
FALSE" to the db URL to disable automatic database closing
90121
=
Database
is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT
\=
FALSE" to the db URL)
90122
=
Operation not supported for table {0} when there are views on the table
\:
{1}
90123
=
Cannot mix indexed and non-indexed parameters
90124
=
File not found
\:
{0}
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
09dac088
...
...
@@ -1932,7 +1932,9 @@ public class Parser {
String
name
=
currentToken
;
if
(
currentTokenQuoted
)
{
read
();
if
(
readIf
(
"."
))
{
if
(
readIf
(
"("
))
{
r
=
readFunction
(
name
);
}
else
if
(
readIf
(
"."
))
{
r
=
readTermObjectDot
(
name
);
}
else
{
r
=
new
ExpressionColumn
(
database
,
currentSelect
,
null
,
null
,
name
);
...
...
@@ -3064,7 +3066,7 @@ public class Parser {
}
else
if
(
readIf
(
"VIEW"
))
{
return
parseCreateView
(
force
);
}
else
if
(
readIf
(
"ALIAS"
))
{
return
parseCreateFunctionAlias
();
return
parseCreateFunctionAlias
(
force
);
}
else
if
(
readIf
(
"SEQUENCE"
))
{
return
parseCreateSequence
();
}
else
if
(
readIf
(
"USER"
))
{
...
...
@@ -3243,6 +3245,9 @@ public class Parser {
boolean
ifNotExists
=
readIfNoExists
();
String
constantName
=
readIdentifierWithSchema
();
Schema
schema
=
getSchema
();
if
(
isKeyword
(
constantName
))
{
throw
Message
.
getSQLException
(
ErrorCode
.
CONSTANT_ALREADY_EXISTS_1
,
constantName
);
}
read
(
"VALUE"
);
Expression
expr
=
readExpression
();
CreateConstant
command
=
new
CreateConstant
(
session
,
schema
);
...
...
@@ -3340,10 +3345,15 @@ public class Parser {
return
command
;
}
private
CreateFunctionAlias
parseCreateFunctionAlias
()
throws
SQLException
{
private
CreateFunctionAlias
parseCreateFunctionAlias
(
boolean
force
)
throws
SQLException
{
boolean
ifNotExists
=
readIfNoExists
();
CreateFunctionAlias
command
=
new
CreateFunctionAlias
(
session
);
command
.
setAliasName
(
readUniqueIdentifier
());
command
.
setForce
(
force
);
String
name
=
readUniqueIdentifier
();
if
(
isKeyword
(
name
)
||
Function
.
getFunction
(
database
,
name
)
!=
null
||
Aggregate
.
getAggregateType
(
name
)
>=
0
)
{
throw
Message
.
getSQLException
(
ErrorCode
.
FUNCTION_ALIAS_ALREADY_EXISTS_1
,
name
);
}
command
.
setAliasName
(
name
);
command
.
setIfNotExists
(
ifNotExists
);
read
(
"FOR"
);
command
.
setJavaClassMethod
(
readUniqueIdentifier
());
...
...
h2/src/main/org/h2/command/ddl/CreateFunctionAlias.java
浏览文件 @
09dac088
...
...
@@ -17,7 +17,8 @@ public class CreateFunctionAlias extends DefineCommand {
private
String
aliasName
;
private
String
javaClassMethod
;
private
boolean
ifNotExists
;
private
boolean
force
;
public
CreateFunctionAlias
(
Session
session
)
{
super
(
session
);
}
...
...
@@ -32,7 +33,7 @@ public class CreateFunctionAlias extends DefineCommand {
}
}
else
{
int
id
=
getObjectId
(
false
,
true
);
FunctionAlias
functionAlias
=
new
FunctionAlias
(
db
,
id
,
aliasName
,
javaClassMethod
);
FunctionAlias
functionAlias
=
new
FunctionAlias
(
db
,
id
,
aliasName
,
javaClassMethod
,
force
);
db
.
addDatabaseObject
(
session
,
functionAlias
);
}
return
0
;
...
...
@@ -50,4 +51,8 @@ public class CreateFunctionAlias extends DefineCommand {
this
.
ifNotExists
=
ifNotExists
;
}
public
void
setForce
(
boolean
force
)
{
this
.
force
=
force
;
}
}
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
09dac088
...
...
@@ -594,7 +594,7 @@ public class Select extends Query {
}
}
if
(
having
!=
null
)
{
// could be set
after
addGlobalCondition
// could be set
in
addGlobalCondition
// in this case the query is not run directly, just getPlanSQL is called
Expression
h
=
having
;
buff
.
append
(
"\nHAVING "
+
StringUtils
.
unEnclose
(
h
.
getSQL
()));
...
...
@@ -685,16 +685,26 @@ public class Select extends Query {
col
=
col
.
getNonAliasExpression
();
Expression
comp
=
new
Comparison
(
session
,
comparisonType
,
col
,
expr
);
comp
=
comp
.
optimize
(
session
);
boolean
addToCondition
=
true
;
if
(
isGroupQuery
)
{
if
(
havingIndex
>=
0
)
{
having
=
(
Expression
)
expressions
.
get
(
havingIndex
);
for
(
int
i
=
0
;
groupIndex
!=
null
&&
i
<
groupIndex
.
length
;
i
++)
{
if
(
groupIndex
[
i
]
==
columnId
)
{
addToCondition
=
true
;
break
;
}
}
if
(
having
==
null
)
{
having
=
comp
;
}
else
{
having
=
new
ConditionAndOr
(
ConditionAndOr
.
AND
,
having
,
comp
);
if
(!
addToCondition
)
{
if
(
havingIndex
>=
0
)
{
having
=
(
Expression
)
expressions
.
get
(
havingIndex
);
}
if
(
having
==
null
)
{
having
=
comp
;
}
else
{
having
=
new
ConditionAndOr
(
ConditionAndOr
.
AND
,
having
,
comp
);
}
}
}
else
{
}
if
(
addToCondition
)
{
if
(
condition
==
null
)
{
condition
=
comp
;
}
else
{
...
...
h2/src/main/org/h2/constraint/ConstraintReferential.java
浏览文件 @
09dac088
...
...
@@ -547,6 +547,14 @@ public class ConstraintReferential extends Constraint {
}
buff
.
append
(
" FROM "
);
buff
.
append
(
table
.
getSQL
());
buff
.
append
(
" WHERE "
);
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
if
(
i
>
0
)
{
buff
.
append
(
" AND "
);
}
buff
.
append
(
columns
[
i
].
getSQL
());
buff
.
append
(
" IS NOT NULL "
);
}
buff
.
append
(
" ORDER BY "
);
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
if
(
i
>
0
)
{
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
09dac088
...
...
@@ -57,7 +57,8 @@ import org.h2.constant.SysProperties;
* - Test with hibernate
* - Scan for viruses
* - Newsletter: send to h2database-news@googlegroups.com (http://groups.google.com/group/h2database-news)
* - newsletter: prepare, send (always send to BCC!!)
* - Newsletter: prepare, send (always send to BCC!!)
* - Newsletter: send to google groups, but without 'to unsubscribe...'
* - http://maven.apache.org/guides/mini/guide-ibiblio-upload.html
* - Add to freshmeat, http://code.google.com/p/h2database/downloads/list
*
...
...
h2/src/main/org/h2/engine/FunctionAlias.java
浏览文件 @
09dac088
...
...
@@ -26,9 +26,9 @@ public class FunctionAlias extends DbObjectBase {
private
String
methodName
;
private
Method
javaMethod
;
private
int
paramCount
;
private
final
int
dataType
;
private
int
dataType
;
public
FunctionAlias
(
Database
db
,
int
id
,
String
name
,
String
javaClassMethod
)
throws
SQLException
{
public
FunctionAlias
(
Database
db
,
int
id
,
String
name
,
String
javaClassMethod
,
boolean
force
)
throws
SQLException
{
super
(
db
,
id
,
name
,
Trace
.
FUNCTION
);
int
paren
=
javaClassMethod
.
indexOf
(
'('
);
int
lastDot
=
javaClassMethod
.
lastIndexOf
(
'.'
,
paren
<
0
?
javaClassMethod
.
length
()
:
paren
);
...
...
@@ -37,6 +37,15 @@ public class FunctionAlias extends DbObjectBase {
}
className
=
javaClassMethod
.
substring
(
0
,
lastDot
);
methodName
=
javaClassMethod
.
substring
(
lastDot
+
1
);
if
(!
force
)
{
load
();
}
}
private
synchronized
void
load
()
throws
SQLException
{
if
(
javaMethod
!=
null
)
{
return
;
}
Class
javaClass
;
try
{
javaClass
=
database
.
loadClass
(
className
);
...
...
@@ -94,7 +103,8 @@ public class FunctionAlias extends DbObjectBase {
return
buff
.
toString
();
}
public
Class
[]
getColumnClasses
()
{
public
Class
[]
getColumnClasses
()
throws
SQLException
{
load
();
return
javaMethod
.
getParameterTypes
();
}
...
...
@@ -112,7 +122,7 @@ public class FunctionAlias extends DbObjectBase {
public
String
getCreateSQL
()
{
StringBuffer
buff
=
new
StringBuffer
();
buff
.
append
(
"CREATE ALIAS "
);
buff
.
append
(
"CREATE
FORCE
ALIAS "
);
buff
.
append
(
getSQL
());
buff
.
append
(
" FOR "
);
buff
.
append
(
Parser
.
quoteIdentifier
(
className
+
"."
+
methodName
));
...
...
@@ -137,59 +147,59 @@ public class FunctionAlias extends DbObjectBase {
return
getValue
(
session
,
args
,
false
);
}
public
Value
getValue
(
Session
session
,
Expression
[]
args
,
boolean
columnList
)
throws
SQLException
{
synchronized
(
this
)
{
Class
[]
paramClasses
=
javaMethod
.
getParameterTypes
();
Object
[]
params
=
new
Object
[
paramClasses
.
length
];
int
p
=
0
;
if
(
hasConnectionParam
&&
params
.
length
>
0
)
{
params
[
p
++]
=
session
.
createConnection
(
columnList
);
}
for
(
int
a
=
0
;
a
<
args
.
length
&&
p
<
params
.
length
;
a
++,
p
++)
{
Class
paramClass
=
paramClasses
[
p
];
int
type
=
DataType
.
getTypeFromClass
(
paramClass
);
Value
v
=
args
[
a
].
getValue
(
session
);
v
=
v
.
convertTo
(
type
);
Object
o
=
v
.
getObject
();
if
(
o
==
null
)
{
if
(
paramClass
.
isPrimitive
())
{
if
(
columnList
)
{
// if the column list is requested, the parameters may be null
// need to set to default value otherwise the function can't be called at all
o
=
DataType
.
getDefaultForPrimitiveType
(
paramClass
);
}
else
{
// NULL for a java primitive: return NULL
return
ValueNull
.
INSTANCE
;
}
}
}
else
{
if
(!
paramClass
.
isAssignableFrom
(
o
.
getClass
())
&&
!
paramClass
.
isPrimitive
())
{
o
=
DataType
.
convertTo
(
session
,
session
.
createConnection
(
false
),
v
,
paramClass
);
public
synchronized
Value
getValue
(
Session
session
,
Expression
[]
args
,
boolean
columnList
)
throws
SQLException
{
load
();
Class
[]
paramClasses
=
javaMethod
.
getParameterTypes
();
Object
[]
params
=
new
Object
[
paramClasses
.
length
];
int
p
=
0
;
if
(
hasConnectionParam
&&
params
.
length
>
0
)
{
params
[
p
++]
=
session
.
createConnection
(
columnList
);
}
for
(
int
a
=
0
;
a
<
args
.
length
&&
p
<
params
.
length
;
a
++,
p
++)
{
Class
paramClass
=
paramClasses
[
p
];
int
type
=
DataType
.
getTypeFromClass
(
paramClass
);
Value
v
=
args
[
a
].
getValue
(
session
);
v
=
v
.
convertTo
(
type
);
Object
o
=
v
.
getObject
();
if
(
o
==
null
)
{
if
(
paramClass
.
isPrimitive
())
{
if
(
columnList
)
{
// if the column list is requested, the parameters may be null
// need to set to default value otherwise the function can't be called at all
o
=
DataType
.
getDefaultForPrimitiveType
(
paramClass
);
}
else
{
// NULL for a java primitive: return NULL
return
ValueNull
.
INSTANCE
;
}
}
params
[
p
]
=
o
;
}
else
{
if
(!
paramClass
.
isAssignableFrom
(
o
.
getClass
())
&&
!
paramClass
.
isPrimitive
())
{
o
=
DataType
.
convertTo
(
session
,
session
.
createConnection
(
false
),
v
,
paramClass
);
}
}
boolean
old
=
session
.
getAutoCommit
();
params
[
p
]
=
o
;
}
boolean
old
=
session
.
getAutoCommit
();
try
{
session
.
setAutoCommit
(
false
);
try
{
session
.
setAutoCommit
(
false
);
try
{
Object
returnValue
;
returnValue
=
javaMethod
.
invoke
(
null
,
params
);
if
(
returnValue
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
Value
ret
=
DataType
.
convertToValue
(
session
,
returnValue
,
dataType
);
return
ret
.
convertTo
(
dataType
);
}
catch
(
Exception
e
)
{
throw
Message
.
convert
(
e
);
Object
returnValue
;
returnValue
=
javaMethod
.
invoke
(
null
,
params
);
if
(
returnValue
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
}
finally
{
session
.
setAutoCommit
(
old
);
Value
ret
=
DataType
.
convertToValue
(
session
,
returnValue
,
dataType
);
return
ret
.
convertTo
(
dataType
);
}
catch
(
Exception
e
)
{
throw
Message
.
convert
(
e
);
}
}
finally
{
session
.
setAutoCommit
(
old
);
}
}
public
int
getParameterCount
()
{
public
int
getParameterCount
()
throws
SQLException
{
load
();
return
paramCount
;
}
...
...
h2/src/main/org/h2/expression/FunctionCall.java
浏览文件 @
09dac088
...
...
@@ -13,7 +13,7 @@ import org.h2.value.ValueResultSet;
public
interface
FunctionCall
{
String
getName
();
int
getParameterCount
();
int
getParameterCount
()
throws
SQLException
;
ValueResultSet
getValueForColumnList
(
Session
session
,
Expression
[]
nullArgs
)
throws
SQLException
;
int
getType
();
Expression
optimize
(
Session
session
)
throws
SQLException
;
...
...
h2/src/main/org/h2/expression/JavaFunction.java
浏览文件 @
09dac088
...
...
@@ -96,7 +96,7 @@ public class JavaFunction extends Expression implements FunctionCall {
return
functionAlias
.
getName
();
}
public
int
getParameterCount
()
{
public
int
getParameterCount
()
throws
SQLException
{
return
functionAlias
.
getParameterCount
();
}
...
...
h2/src/main/org/h2/index/FunctionIndex.java
浏览文件 @
09dac088
...
...
@@ -36,11 +36,8 @@ public class FunctionIndex extends BaseIndex {
}
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
if
(
result
==
null
)
{
result
=
functionTable
.
getResult
(
session
);
}
else
{
result
.
reset
();
}
// TODO sometimes result.reset() would be enough (but not when parameters are used)
result
=
functionTable
.
getResult
(
session
);
return
new
FunctionCursor
(
result
);
}
...
...
h2/src/main/org/h2/index/MultiVersionCursor.java
浏览文件 @
09dac088
...
...
@@ -102,10 +102,6 @@ public class MultiVersionCursor implements Cursor {
}
}
int
sessionId
=
deltaRow
.
getSessionId
();
if
(
sessionId
==
0
)
{
int
testing
;
System
.
out
.
println
(
"sessionId==0"
);
}
boolean
isThisSession
=
sessionId
==
session
.
getId
();
boolean
isDeleted
=
deltaRow
.
getDeleted
();
if
(
isThisSession
&&
isDeleted
)
{
...
...
h2/src/main/org/h2/index/MultiVersionIndex.java
浏览文件 @
09dac088
...
...
@@ -92,14 +92,6 @@ public class MultiVersionIndex implements Index {
if
(
removeIfExists
(
session
,
row
))
{
// added and deleted in the same transaction: no change
}
else
{
int
testing
;
if
(
row
.
getSessionId
()
==
0
)
{
System
.
out
.
println
(
"stop! "
+
row
);
System
.
out
.
flush
();
new
Error
().
printStackTrace
();
Runtime
.
getRuntime
().
halt
(
1
);
}
delta
.
add
(
session
,
row
);
}
}
...
...
h2/src/main/org/h2/index/ScanCursor.java
浏览文件 @
09dac088
...
...
@@ -19,14 +19,14 @@ public class ScanCursor implements Cursor {
private
Row
row
;
private
final
Session
session
;
private
final
boolean
multiVersion
;
private
Iterator
del
eted
;
private
Iterator
del
ta
;
ScanCursor
(
Session
session
,
ScanIndex
scan
,
boolean
multiVersion
)
{
this
.
session
=
session
;
this
.
scan
=
scan
;
this
.
multiVersion
=
multiVersion
;
if
(
multiVersion
)
{
del
eted
=
scan
.
getDeleted
();
del
ta
=
scan
.
getDelta
();
}
row
=
null
;
}
...
...
@@ -50,9 +50,9 @@ public class ScanCursor implements Cursor {
public
boolean
next
()
throws
SQLException
{
if
(
multiVersion
)
{
while
(
true
)
{
if
(
del
eted
.
hasNext
())
{
row
=
(
Row
)
del
eted
.
next
();
if
(
row
.
getDeleted
()
&&
row
.
getSessionId
()
==
session
.
getId
())
{
if
(
del
ta
.
hasNext
())
{
row
=
(
Row
)
del
ta
.
next
();
if
(
!
row
.
getDeleted
()
||
row
.
getSessionId
()
==
session
.
getId
())
{
row
=
null
;
continue
;
}
...
...
h2/src/main/org/h2/index/ScanIndex.java
浏览文件 @
09dac088
...
...
@@ -35,7 +35,7 @@ public class ScanIndex extends BaseIndex {
private
boolean
containsLargeObject
;
private
int
rowCountDiff
;
private
HashMap
sessionRowCount
;
private
HashSet
del
eted
;
private
HashSet
del
ta
;
public
ScanIndex
(
TableData
table
,
int
id
,
Column
[]
columns
,
IndexType
indexType
)
throws
SQLException
{
...
...
@@ -127,8 +127,12 @@ public class ScanIndex extends BaseIndex {
}
}
if
(
database
.
isMultiVersion
())
{
if
(
deleted
!=
null
)
{
deleted
.
remove
(
row
);
if
(
delta
==
null
)
{
delta
=
new
HashSet
();
}
boolean
wasDeleted
=
delta
.
remove
(
row
);
if
(!
wasDeleted
)
{
delta
.
add
(
row
);
}
incrementRowCount
(
session
.
getId
(),
1
);
}
...
...
@@ -137,8 +141,8 @@ public class ScanIndex extends BaseIndex {
public
void
commit
(
int
operation
,
Row
row
)
throws
SQLException
{
if
(
database
.
isMultiVersion
())
{
if
(
del
eted
!=
null
&&
operation
==
UndoLogRecord
.
DELETE
)
{
del
eted
.
remove
(
row
);
if
(
del
ta
!=
null
&&
operation
==
UndoLogRecord
.
DELETE
)
{
del
ta
.
remove
(
row
);
}
incrementRowCount
(
row
.
getSessionId
(),
operation
==
UndoLogRecord
.
DELETE
?
1
:
-
1
);
}
...
...
@@ -173,10 +177,13 @@ public class ScanIndex extends BaseIndex {
firstFree
=
key
;
}
if
(
database
.
isMultiVersion
())
{
if
(
deleted
==
null
)
{
deleted
=
new
HashSet
();
if
(
delta
==
null
)
{
delta
=
new
HashSet
();
}
boolean
wasAdded
=
delta
.
remove
(
row
);
if
(!
wasAdded
)
{
delta
.
add
(
row
);
}
deleted
.
add
(
row
);
incrementRowCount
(
session
.
getId
(),
-
1
);
}
rowCount
--;
...
...
@@ -252,8 +259,8 @@ public class ScanIndex extends BaseIndex {
throw
Message
.
getUnsupportedException
();
}
public
Iterator
getDel
eted
()
{
return
del
eted
==
null
?
Collections
.
EMPTY_LIST
.
iterator
()
:
deleted
.
iterator
();
public
Iterator
getDel
ta
()
{
return
del
ta
==
null
?
Collections
.
EMPTY_LIST
.
iterator
()
:
delta
.
iterator
();
}
}
h2/src/main/org/h2/server/pg/PgServerThread.java
浏览文件 @
09dac088
...
...
@@ -90,15 +90,15 @@ public class PgServerThread implements Runnable {
}
private
String
readString
()
throws
IOException
{
StringBuffer
buff
=
new
StringBuffer
();
ByteArrayOutputStream
buff
=
new
ByteArrayOutputStream
();
while
(
true
)
{
int
x
=
dataIn
.
read
();
if
(
x
<=
0
)
{
break
;
}
buff
.
append
((
char
)
x
);
buff
.
write
(
x
);
}
return
buff
.
toString
(
);
return
new
String
(
buff
.
toByteArray
(),
getEncoding
()
);
}
private
int
readInt
()
throws
IOException
{
...
...
@@ -676,7 +676,7 @@ public class PgServerThread implements Runnable {
}
private
void
writeString
(
String
s
)
throws
IOException
{
write
(
s
.
getBytes
(
"UTF-8"
));
write
(
s
.
getBytes
(
getEncoding
()
));
write
(
0
);
}
...
...
h2/src/main/org/h2/tools/MultiDimension.java
浏览文件 @
09dac088
...
...
@@ -4,9 +4,13 @@
*/
package
org
.
h2
.
tools
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
org.h2.util.StringUtils
;
/**
* A tool to help an application execute multi-dimensional range queries.
...
...
@@ -89,10 +93,60 @@ public class MultiDimension {
// return n;
// }
/**
* Generates an optimized multi-dimensional range query.
* The query contains parameters. It can only be used with the H2 database.
*
* @param table the table name
* @param columns the list of columns
* @param scalarColumn the column name of the computed scalar column
* @return the query
*/
public
String
generatePreparedQuery
(
String
table
,
String
scalarColumn
,
String
[]
columns
)
{
StringBuffer
buff
=
new
StringBuffer
(
"SELECT D.* FROM "
);
buff
.
append
(
StringUtils
.
quoteIdentifier
(
table
));
buff
.
append
(
" D, TABLE(_FROM_ BIGINT=?, _TO_ BIGINT=?) WHERE "
);
buff
.
append
(
StringUtils
.
quoteIdentifier
(
scalarColumn
));
buff
.
append
(
" BETWEEN _FROM_ AND _TO_"
);
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
buff
.
append
(
" AND "
);
buff
.
append
(
StringUtils
.
quoteIdentifier
(
columns
[
i
]));
buff
.
append
(
"+1 BETWEEN ?+1 AND ?+1"
);
}
return
buff
.
toString
();
}
/**
* Executes a prepared query that was generated using generatePreparedQuery.
*
* @param prep the prepared statement
* @param min the lower values
* @param max the upper values
* @return the result set
*/
public
ResultSet
getResult
(
PreparedStatement
prep
,
int
[]
min
,
int
[]
max
)
throws
SQLException
{
long
[][]
ranges
=
getMortonRanges
(
min
,
max
);
int
len
=
ranges
.
length
;
Long
[]
from
=
new
Long
[
len
];
Long
[]
to
=
new
Long
[
len
];
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
from
[
i
]
=
new
Long
(
ranges
[
i
][
0
]);
to
[
i
]
=
new
Long
(
ranges
[
i
][
1
]);
}
prep
.
setObject
(
1
,
from
);
prep
.
setObject
(
2
,
to
);
len
=
min
.
length
;
for
(
int
i
=
0
,
idx
=
3
;
i
<
len
;
i
++)
{
prep
.
setInt
(
idx
++,
min
[
i
]);
prep
.
setInt
(
idx
++,
max
[
i
]);
}
return
prep
.
executeQuery
();
}
/**
* Generates an optimized multi-dimensional range query.
* This query is database independent, however the performance is
* not as good as when using generatePreparedQuery
*
* @param table the table name
* @param columns the list of columns
...
...
@@ -101,7 +155,7 @@ public class MultiDimension {
* @param scalarColumn the column name of the computed scalar column
* @return the query
*/
public
String
ge
tMultiDimensional
Query
(
String
table
,
String
scalarColumn
,
String
[]
columns
,
int
[]
min
,
int
[]
max
)
{
public
String
ge
nerate
Query
(
String
table
,
String
scalarColumn
,
String
[]
columns
,
int
[]
min
,
int
[]
max
)
{
long
[][]
ranges
=
getMortonRanges
(
min
,
max
);
StringBuffer
buff
=
new
StringBuffer
(
"SELECT * FROM ("
);
for
(
int
i
=
0
;
i
<
ranges
.
length
;
i
++)
{
...
...
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
09dac088
...
...
@@ -367,6 +367,9 @@ public class Recover implements DataHandler {
}
sb
.
append
(
v
.
getSQL
());
}
catch
(
Exception
e
)
{
if
(
log
)
{
logError
(
"log data"
,
e
);
}
writeDataError
(
writer
,
"exception "
+
e
,
s
.
getBytes
(),
blockCount
);
continue
;
}
catch
(
OutOfMemoryError
e
)
{
...
...
@@ -813,7 +816,7 @@ public class Recover implements DataHandler {
* INTERNAL
*/
public
FileStore
openFile
(
String
name
,
String
mode
,
boolean
mustExist
)
throws
SQLException
{
return
null
;
return
FileStore
.
open
(
this
,
name
,
"rw"
,
Constants
.
MAGIC_FILE_HEADER
.
getBytes
())
;
}
/**
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
09dac088
...
...
@@ -130,7 +130,7 @@ public class DateTimeUtils {
int
s1
=
s
.
indexOf
(
'-'
,
1
);
int
s2
=
s
.
indexOf
(
'-'
,
s1
+
1
);
if
(
s1
<=
0
||
s2
<=
s1
)
{
throw
Message
.
getSQLException
(
errorCode
,
s
);
throw
Message
.
getSQLException
(
errorCode
,
new
String
[]{
s
,
"format yyyy-mm-dd"
}
);
}
year
=
Integer
.
parseInt
(
s
.
substring
(
0
,
s1
));
month
=
Integer
.
parseInt
(
s
.
substring
(
s1
+
1
,
s2
));
...
...
@@ -143,7 +143,7 @@ public class DateTimeUtils {
int
s2
=
s
.
indexOf
(
':'
,
s1
+
1
);
int
s3
=
s
.
indexOf
(
'.'
,
s2
+
1
);
if
(
s1
<=
0
||
s2
<=
s1
)
{
throw
Message
.
getSQLException
(
errorCode
,
s
);
throw
Message
.
getSQLException
(
errorCode
,
new
String
[]{
s
,
"format hh:mm:ss"
}
);
}
if
(
s
.
endsWith
(
"Z"
))
{
...
...
@@ -158,7 +158,7 @@ public class DateTimeUtils {
String
tzName
=
"GMT"
+
s
.
substring
(
timezoneStart
);
tz
=
TimeZone
.
getTimeZone
(
tzName
);
if
(!
tz
.
getID
().
equals
(
tzName
))
{
throw
Message
.
getSQLException
(
errorCode
,
s
+
" "
+
tz
.
getID
()
+
"/"
+
tzName
);
throw
Message
.
getSQLException
(
errorCode
,
new
String
[]{
s
,
tz
.
getID
()
+
" <>"
+
tzName
}
);
}
s
=
s
.
substring
(
0
,
timezoneStart
).
trim
();
}
...
...
h2/src/main/org/h2/util/MemoryFile.java
浏览文件 @
09dac088
...
...
@@ -5,6 +5,7 @@
package
org
.
h2
.
util
;
public
class
MemoryFile
{
private
int
supportCompression
;
private
String
name
;
private
int
length
;
private
byte
[]
data
;
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
09dac088
...
...
@@ -100,29 +100,11 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
problem with news mailing list
CREATE TABLE TEST(BIRTH TIMESTAMP);
INSERT INTO TEST VALUES('2006-04-03 10:20:30'), ('2006-04-03 10:20:31');
SELECT CAST(BIRTH AS DATE) B
FROM TEST GROUP BY CAST(BIRTH AS DATE)
HAVING CAST(BIRTH AS DATE) = '2004-05-05';
SELECT 1 FROM (SELECT CAST(BIRTH AS DATE) B
FROM TEST GROUP BY CAST(BIRTH AS DATE)) A
WHERE A.B = '2004-05-05';
DROP TABLE TEST;
CREATE TABLE TEST (ID integer NOT NULL PRIMARY KEY);
@LOOP 1000 INSERT INTO TEST VALUES(?);
CREATE VIEW TESTVIEW AS SELECT src.ID as VID FROM TEST AS h
INNER JOIN TEST AS src ON h.ID = src.ID GROUP BY src.ID;
-- slow
SELECT COUNT(*) FROM TESTVIEW AS S LEFT JOIN TESTVIEW AS T ON S.VID = T.VID;
DROP VIEW TESTVIEW;
DROP TABLE TEST;
add to maven
shrink newsletter list (migrate to google groups)
see if maven repository is ok, document
http://maven.apache.org/guides/mini/guide-central-repository-upload.html
http://mirrors.ibiblio.org/pub/mirrors/maven2/com/h2database/h2/1.0.57/
add MVCC
...
...
@@ -130,14 +112,10 @@ don't create @~ of not translated
improve documentation of 'mixed mode' usage.
test and document fulltext search
test
performance
and document fulltext search
clustered tables: test, document
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?
pdf: first page looks empty (because the top part is empty) - title on the top?
pdf / openoffice: pictures don't work?
...
...
h2/src/test/org/h2/test/bench/test.properties
浏览文件 @
09dac088
db1
=
H2
(MVCC), org.h2.Driver, jdbc:h2:data/test_mvcc;MVCC=TRUE
, sa, sa
db2
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3
, sa, sa
db1
=
H2
, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3
, sa, sa
#db1 = H2 (MVCC), org.h2.Driver, jdbc:h2:data/test_mvcc;MVCC=TRUE
, sa, sa
#xdb2 = H2 (XTEA), org.h2.Driver, jdbc:h2:data/test_xtea;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=XTEA, sa, sa 123
#xdb3 = H2 (AES), org.h2.Driver, jdbc:h2:data/test_aes;LOCK_TIMEOUT=10000;LOCK_MODE=3;CIPHER=AES, sa, sa 123
#xdb4 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;write_mode_log=rws;write_delay=0, sa, sa
#xdb5 = H2_PG, org.postgresql.Driver, jdbc:postgresql://localhost:5435/h2test, sa, sa
#
db2 = HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa
db2
=
HSQLDB, org.hsqldb.jdbcDriver, jdbc:hsqldb:data/test;hsqldb.default_table_type=cached;sql.enforce_size=true, sa
db3
=
Derby, org.apache.derby.jdbc.EmbeddedDriver, jdbc:derby:data/test;create=true, sa, sa
db4
=
H2, org.h2.Driver, jdbc:h2:tcp://localhost/data/testServer;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
...
...
h2/src/test/org/h2/test/db/TestBackup.java
浏览文件 @
09dac088
...
...
@@ -38,6 +38,7 @@ public class TestBackup extends TestBase {
stat1
.
execute
(
"backup to '"
+
BASE_DIR
+
"/backup.zip'"
);
conn2
.
rollback
();
compareDatabases
(
stat1
,
stat2
);
Restore
.
execute
(
BASE_DIR
+
"/backup.zip"
,
BASE_DIR
,
"restored"
,
true
);
conn3
=
getConnection
(
"restored"
);
...
...
h2/src/test/org/h2/test/db/TestLinkedTable.java
浏览文件 @
09dac088
...
...
@@ -12,11 +12,32 @@ import org.h2.test.TestBase;
public
class
TestLinkedTable
extends
TestBase
{
public
void
test
()
throws
Exception
{
testLinkDrop
();
testLinkSchema
();
testLinkEmitUpdates
();
testLinkTable
();
}
private
void
testLinkDrop
()
throws
Exception
{
Class
.
forName
(
"org.h2.Driver"
);
Connection
connA
=
DriverManager
.
getConnection
(
"jdbc:h2:mem:a"
);
Statement
statA
=
connA
.
createStatement
();
statA
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
Connection
connB
=
DriverManager
.
getConnection
(
"jdbc:h2:mem:b"
);
Statement
statB
=
connB
.
createStatement
();
statB
.
execute
(
"CREATE LINKED TABLE TEST_LINK('', 'jdbc:h2:mem:a', '', '', 'TEST')"
);
connA
.
close
();
// the connection should be closed now
// (and the table should disappear because the last connection was closed)
statB
.
execute
(
"DROP TABLE TEST_LINK"
);
connA
=
DriverManager
.
getConnection
(
"jdbc:h2:mem:a"
);
statA
=
connA
.
createStatement
();
// table should not exist now
statA
.
execute
(
"CREATE TABLE TEST(ID INT)"
);
connA
.
close
();
connB
.
close
();
}
private
void
testLinkEmitUpdates
()
throws
Exception
{
deleteDb
(
"linked1"
);
deleteDb
(
"linked2"
);
...
...
h2/src/test/org/h2/test/db/TestMultiDimension.java
浏览文件 @
09dac088
...
...
@@ -35,9 +35,8 @@ public class TestMultiDimension extends TestBase {
stat
.
execute
(
"CREATE INDEX IDX_X ON TEST(X, Y, Z)"
);
stat
.
execute
(
"CREATE INDEX IDX_XYZ ON TEST(XYZ)"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST(X, Y, Z, DATA) VALUES(?, ?, ?, ?)"
);
// a reasonable value to see the performance difference is 60
int
max
=
10
;
// a reasonable max value to see the performance difference is 60; the higher the bigger the difference
int
max
=
getSize
(
10
,
20
);
long
time
=
System
.
currentTimeMillis
();
for
(
int
x
=
0
;
x
<
max
;
x
++)
{
for
(
int
y
=
0
;
y
<
max
;
y
++)
{
...
...
@@ -59,28 +58,63 @@ public class TestMultiDimension extends TestBase {
}
}
}
stat
.
execute
(
"ANALYZE SAMPLE_SIZE 10000"
);
PreparedStatement
prepRegular
=
conn
.
prepareStatement
(
"SELECT * FROM TEST WHERE X BETWEEN ? AND ? "
+
"AND Y BETWEEN ? AND ? AND Z BETWEEN ? AND ? ORDER BY X, Y, Z"
);
MultiDimension
multi
=
MultiDimension
.
getInstance
();
String
sql
=
multi
.
generatePreparedQuery
(
"TEST"
,
"XYZ"
,
new
String
[]{
"X"
,
"Y"
,
"Z"
});
sql
+=
" ORDER BY X, Y, Z"
;
PreparedStatement
prepMulti
=
conn
.
prepareStatement
(
sql
);
long
timeMulti
=
0
,
timeRegular
=
0
;
int
timeMax
=
getSize
(
100
,
2000
);
for
(
int
i
=
0
;
timeMulti
<
timeMax
;
i
++)
{
int
size
=
rand
.
nextInt
(
max
/
10
);
int
minX
=
rand
.
nextInt
(
max
-
size
);
int
minY
=
rand
.
nextInt
(
max
-
size
);
int
minZ
=
rand
.
nextInt
(
max
-
size
);
int
maxX
=
minX
+
size
,
maxY
=
minY
+
size
,
maxZ
=
minZ
+
size
;
time
=
System
.
currentTimeMillis
();
ResultSet
rs1
=
multi
.
getResult
(
prepMulti
,
new
int
[]{
minX
,
minY
,
minZ
},
new
int
[]{
maxX
,
maxY
,
maxZ
});
timeMulti
+=
System
.
currentTimeMillis
()
-
time
;
time
=
System
.
currentTimeMillis
();
prepRegular
.
setInt
(
1
,
minX
);
prepRegular
.
setInt
(
2
,
maxX
);
prepRegular
.
setInt
(
3
,
minY
);
prepRegular
.
setInt
(
4
,
maxY
);
prepRegular
.
setInt
(
5
,
minZ
);
prepRegular
.
setInt
(
6
,
maxZ
);
ResultSet
rs2
=
prepRegular
.
executeQuery
();
timeRegular
+=
System
.
currentTimeMillis
()
-
time
;
while
(
rs1
.
next
())
{
check
(
rs2
.
next
());
check
(
rs1
.
getInt
(
1
),
rs2
.
getInt
(
1
));
check
(
rs1
.
getInt
(
2
),
rs2
.
getInt
(
2
));
}
checkFalse
(
rs2
.
next
());
}
trace
(
"multi: "
+
timeMulti
+
" regular: "
+
timeRegular
);
for
(
int
i
=
0
;
i
<
50
;
i
++)
{
int
size
=
rand
.
nextInt
(
max
/
10
);
int
minX
=
rand
.
nextInt
(
max
-
size
);
int
minY
=
rand
.
nextInt
(
max
-
size
);
int
minZ
=
rand
.
nextInt
(
max
-
size
);
int
maxX
=
minX
+
size
,
maxY
=
minY
+
size
,
maxZ
=
minZ
+
size
;
long
time1
=
System
.
currentTimeMillis
();
String
query1
=
MultiDimension
.
getInstance
().
ge
tMultiDimensional
Query
(
String
query1
=
MultiDimension
.
getInstance
().
ge
nerate
Query
(
"TEST"
,
"XYZ"
,
new
String
[]{
"X"
,
"Y"
,
"Z"
},
new
int
[]{
minX
,
minY
,
minZ
},
new
int
[]{
minX
+
size
,
minY
+
size
,
minZ
+
size
});
ResultSet
rs1
=
conn
.
createStatement
().
executeQuery
(
query1
+
" ORDER BY X, Y, Z"
);
time1
=
System
.
currentTimeMillis
()
-
time1
;
long
time2
=
System
.
currentTimeMillis
();
String
query2
=
"SELECT * FROM TEST WHERE "
+
"X BETWEEN "
+
minX
+
" AND "
+
maxX
+
" AND "
+
"Y BETWEEN "
+
minY
+
" AND "
+
maxY
+
" AND "
+
"Z BETWEEN "
+
minZ
+
" AND "
+
maxZ
;
PreparedStatement
prep2
=
conn
.
prepareStatement
(
query2
+
" ORDER BY X, Y, Z"
);
ResultSet
rs2
=
prep2
.
executeQuery
();
time2
=
System
.
currentTimeMillis
()
-
time2
;
...
...
@@ -90,7 +124,8 @@ public class TestMultiDimension extends TestBase {
check
(
rs1
.
getInt
(
2
),
rs2
.
getInt
(
2
));
}
checkFalse
(
rs2
.
next
());
trace
(
"t1="
+
time1
+
" t2="
+
time2
+
" size="
+
size
);
// it just has to work, no need to compare the performance
// trace("t1="+time1+" t2="+time2+" size="+size);
}
conn
.
close
();
}
...
...
h2/src/test/org/h2/test/mvcc/TestMVCC.java
浏览文件 @
09dac088
...
...
@@ -43,6 +43,16 @@ public class TestMVCC {
c1
.
setAutoCommit
(
false
);
c2
.
setAutoCommit
(
false
);
s1
.
execute
(
"create table test(id int primary key, name varchar(255))"
);
s2
.
execute
(
"insert into test values(4, 'Hello')"
);
c2
.
rollback
();
test
(
s1
,
"select count(*) from test where name = 'Hello'"
,
"0"
);
test
(
s2
,
"select count(*) from test where name = 'Hello'"
,
"0"
);
c1
.
commit
();
c2
.
commit
();
s1
.
execute
(
"DROP TABLE TEST"
);
s1
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
s1
.
execute
(
"INSERT INTO TEST VALUES(1, 'Test')"
);
c1
.
commit
();
...
...
h2/src/test/org/h2/test/test.in.txt
浏览文件 @
09dac088
--- special grammar and test cases ---------------------------------------------------------------------------------------------
create alias "SYSDATE" for "java.lang.Integer.parseInt(java.lang.String)";
> exception
create alias "MIN" for "java.lang.Integer.parseInt(java.lang.String)";
> exception
create alias "CAST" for "java.lang.Integer.parseInt(java.lang.String)";
> exception
CREATE TABLE PARENT(A INT, B INT, PRIMARY KEY(A, B));
> ok
CREATE TABLE CHILD(A INT, B INT, CONSTRAINT CP FOREIGN KEY(A, B) REFERENCES PARENT(A, B));
> ok
INSERT INTO PARENT VALUES(1, 2);
> update count: 1
INSERT INTO CHILD VALUES(2, NULL), (NULL, 3), (NULL, NULL), (1, 2);
> update count: 4
set autocommit false;
> ok
ALTER TABLE CHILD SET REFERENTIAL_INTEGRITY FALSE;
> ok
ALTER TABLE CHILD SET REFERENTIAL_INTEGRITY TRUE CHECK;
> ok
set autocommit true;
> ok
DROP TABLE CHILD, PARENT;
> ok
CREATE TABLE TEST(BIRTH TIMESTAMP);
> ok
INSERT INTO TEST VALUES('2006-04-03 10:20:30'), ('2006-04-03 10:20:31'), ('2006-05-05 00:00:00'), ('2006-07-03 22:30:00'), ('2006-07-03 22:31:00');
> update count: 5
SELECT * FROM (SELECT CAST(BIRTH AS DATE) B
FROM TEST GROUP BY CAST(BIRTH AS DATE)) A
WHERE A.B >= '2006-05-05';
> B
> ----------
> 2006-05-05
> 2006-07-03
> rows: 2
DROP TABLE TEST;
> ok
CREATE TABLE Parent(ID INT PRIMARY KEY, Name VARCHAR);
> ok
...
...
@@ -35,6 +89,9 @@ ALTER TABLE A ADD CONSTRAINT AC FOREIGN KEY(SK) REFERENCES A(ID);
INSERT INTO A VALUES(1, 1);
> update count: 1
INSERT INTO A VALUES(-2, NULL);
> update count: 1
ALTER TABLE A SET REFERENTIAL_INTEGRITY FALSE;
> ok
...
...
@@ -3925,8 +3982,8 @@ SELECT MY_SQRT(-1.0) MS, SQRT(NULL) S;
SCRIPT NOPASSWORDS NOSETTINGS;
> SCRIPT
> ----------------------------------------------
> CREATE ALIAS MY_SQRT FOR "java.lang.Math.sqrt"
> ----------------------------------------------
------
> CREATE
FORCE
ALIAS MY_SQRT FOR "java.lang.Math.sqrt"
> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN
> rows: 2
...
...
h2/src/test/org/h2/test/testSimple.in.txt
浏览文件 @
09dac088
...
...
@@ -8,8 +8,8 @@ select count(scriptSimple.public.test.id) from scriptSimple.public.test;
update scriptSimple.public.test set scriptSimple.public.test.id=1;
drop table scriptSimple.public.test;
select
timestamp '2007-07-26 18:44:26.109000 +02:00'
;
> 2007
-07-26 18:44:26.109
;
select
year(timestamp '2007-07-26 18:44:26.109000 +02:00')
;
> 2007;
create table test(id int primary key);
begin;
...
...
h2/src/test/org/h2/test/unit/TestFileLock.java
浏览文件 @
09dac088
...
...
@@ -9,8 +9,6 @@ import java.io.File;
import
org.h2.message.TraceSystem
;
import
org.h2.store.FileLock
;
import
org.h2.test.TestBase
;
import
org.h2.util.FileUtils
;
/**
* @author Thomas
...
...
@@ -28,12 +26,17 @@ public class TestFileLock extends TestBase implements Runnable {
public
TestFileLock
()
{}
public
void
test
()
throws
Exception
{
new
File
(
FILE
).
delete
();
test
(
false
);
test
(
true
);
}
void
test
(
boolean
allowSockets
)
throws
Exception
{
int
threadCount
=
getSize
(
3
,
5
);
wait
=
getSize
(
20
,
200
);
Thread
[]
threads
=
new
Thread
[
threadCount
];
new
File
(
FILE
).
delete
();
for
(
int
i
=
0
;
i
<
threadCount
;
i
++)
{
threads
[
i
]
=
new
Thread
(
new
TestFileLock
(
this
,
false
));
threads
[
i
]
=
new
Thread
(
new
TestFileLock
(
this
,
allowSockets
));
threads
[
i
].
start
();
Thread
.
sleep
(
wait
+
(
int
)
(
Math
.
random
()
*
wait
));
}
...
...
@@ -45,21 +48,6 @@ public class TestFileLock extends TestBase implements Runnable {
threads
[
i
].
join
();
}
check
(
locks
,
0
);
FileUtils
.
delete
(
FILE
);
stop
=
false
;
for
(
int
i
=
0
;
i
<
threadCount
;
i
++)
{
threads
[
i
]
=
new
Thread
(
new
TestFileLock
(
this
,
true
));
threads
[
i
].
start
();
Thread
.
sleep
(
wait
+
(
int
)
(
Math
.
random
()
*
wait
));
}
trace
(
"wait"
);
Thread
.
sleep
(
100
);
stop
=
true
;
trace
(
"STOP sockets"
);
for
(
int
i
=
0
;
i
<
threadCount
;
i
++)
{
threads
[
i
].
join
();
}
check
(
locks
,
0
);
}
TestBase
base
;
...
...
h2/src/tools/org/h2/tools/doc/LinkChecker.java
浏览文件 @
09dac088
...
...
@@ -57,7 +57,7 @@ public class LinkChecker {
ArrayList
errors
=
new
ArrayList
();
for
(
Iterator
it
=
links
.
keySet
().
iterator
();
it
.
hasNext
();
)
{
String
link
=
(
String
)
it
.
next
();
if
(!
link
.
startsWith
(
"http"
)
&&
!
link
.
endsWith
(
"h2.pdf"
))
{
if
(!
link
.
startsWith
(
"http"
)
&&
!
link
.
endsWith
(
"h2.pdf"
)
&&
link
.
indexOf
(
"_ja."
)
<
0
)
{
if
(
targets
.
get
(
link
)
==
null
)
{
errors
.
add
(
links
.
get
(
link
)
+
": missing link "
+
link
);
}
...
...
h2/src/tools/org/h2/tools/doc/dictionary.txt
浏览文件 @
09dac088
...
...
@@ -504,4 +504,4 @@ finalizer textbase newsfeeds quicksort
prio zvikico incrementally nocheck differently eng admins problog nio though typepad channels rolling
lightweight builder
tunes elephant codewave incorrectly mytunesrss speeds cte honoured httpdocs department whereever dog dept edh oops flower music appends research plant
testview gaps birth vid
\ No newline at end of file
testview gaps birth vid weblog blojsom unsubscribe
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论