Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6c3455a1
提交
6c3455a1
authored
2月 06, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
74108a40
隐藏空白字符变更
内嵌
并排
正在显示
27 个修改的文件
包含
630 行增加
和
211 行删除
+630
-211
history.html
h2/src/docsrc/html/history.html
+10
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+52
-2
CreateView.java
h2/src/main/org/h2/command/ddl/CreateView.java
+73
-73
Backup.java
h2/src/main/org/h2/command/dml/Backup.java
+2
-2
Select.java
h2/src/main/org/h2/command/dml/Select.java
+4
-1
SelectUnion.java
h2/src/main/org/h2/command/dml/SelectUnion.java
+7
-0
Constants.java
h2/src/main/org/h2/engine/Constants.java
+2
-2
ConditionIn.java
h2/src/main/org/h2/expression/ConditionIn.java
+2
-0
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+49
-2
FileLister.java
h2/src/main/org/h2/store/FileLister.java
+2
-22
TableData.java
h2/src/main/org/h2/table/TableData.java
+1
-1
TableView.java
h2/src/main/org/h2/table/TableView.java
+17
-1
Backup.java
h2/src/main/org/h2/tools/Backup.java
+43
-1
ChangePassword.java
h2/src/main/org/h2/tools/ChangePassword.java
+28
-26
DeleteDbFiles.java
h2/src/main/org/h2/tools/DeleteDbFiles.java
+16
-11
Recover.java
h2/src/main/org/h2/tools/Recover.java
+48
-2
IOUtils.java
h2/src/main/org/h2/util/IOUtils.java
+2
-2
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+6
-15
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+90
-1
TestLogFile.java
h2/src/test/org/h2/test/db/TestLogFile.java
+2
-2
TestPowerOff.java
h2/src/test/org/h2/test/db/TestPowerOff.java
+2
-2
TestReadOnly.java
h2/src/test/org/h2/test/db/TestReadOnly.java
+2
-2
TestHalt.java
h2/src/test/org/h2/test/synth/TestHalt.java
+45
-20
TestHaltApp.java
h2/src/test/org/h2/test/synth/TestHaltApp.java
+42
-19
TestKillProcess.java
h2/src/test/org/h2/test/synth/TestKillProcess.java
+2
-2
test.in.txt
h2/src/test/org/h2/test/test.in.txt
+79
-0
testSimple.in.txt
h2/src/test/org/h2/test/testSimple.in.txt
+2
-0
没有找到文件。
h2/src/docsrc/html/history.html
浏览文件 @
6c3455a1
...
...
@@ -35,6 +35,14 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h2>
Change Log
</h2>
<h3>
Version 1.0 (Current)
</h3>
<h3>
Version 1.0 / 2007-02-TODO
</h3><ul>
<li>
SCRIPT did not work correctly with BLOB or CLOB data. Fixed.
</li><li>
When a subquery was used in the select list of a query, and GROUP BY was used at the same time,
a NullPointerException could occur. Fixed.
</li><li>
ORDER BY did not work when DISTINCT was used at the same timein some situations. Fixed.
</li><li>
When using IN(...) on a case insensitive column (VARCHAR_IGNORECASE),
an incorrect optimization was made and the result was wrong sometimes.
</li></ul>
<h3>
Version 1.0 / 2007-01-30
</h3><ul>
<li>
Experimental online backup feature using the SQL statement BACKUP TO 'fileName'.
...
...
@@ -1532,6 +1540,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>
Support curtimestamp (like curtime, curdate)
</li><li>
Support ANALYZE {TABLE|INDEX} tablename COMPUTE|ESTIMATE|DELETE STATISTICS ptnOption options
</li><li>
Support Sequoia (Continuent.org)
</li><li>
Dynamic length numbers / special methods for DataPage.writeByte / writeShort / Ronni Nielsen
</li><li>
Pluggable tracing system, ThreadPool, (AvalonDB / deebee / Paul Hammant)
</li></ul>
<h3>
Not Planned
</h3>
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
6c3455a1
...
...
@@ -105,6 +105,7 @@ import org.h2.table.Column;
import
org.h2.table.FunctionTable
;
import
org.h2.table.RangeTable
;
import
org.h2.table.Table
;
import
org.h2.table.TableData
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableView
;
import
org.h2.util.ByteUtils
;
...
...
@@ -361,6 +362,11 @@ public class Parser {
c
=
parserCall
();
}
break
;
case
'W'
:
if
(
readIf
(
"WITH"
))
{
c
=
parserWith
();
}
break
;
default
:
// TODO exception: unknown command
throw
getSyntaxError
();
...
...
@@ -1065,7 +1071,7 @@ public class Parser {
command
.
init
();
return
command
;
}
private
Query
parseQueryWithParams
()
throws
SQLException
{
int
paramIndex
=
parameters
.
size
();
Query
command
=
parseSelectUnion
();
...
...
@@ -3147,19 +3153,58 @@ public class Parser {
command
.
setJavaClassMethod
(
readUniqueIdentifier
());
return
command
;
}
private
Query
parserWith
()
throws
SQLException
{
// String tempViewName = readUniqueIdentifier();
// if(readIf("(")) {
// String[] cols = parseColumnList(false);
// command.setColumnNames(cols);
//
//
// if(recursive) {
// ObjectArray columns = new ObjectArray();
// for(int i=0; i<cols.length; i++) {
// columns.add(new Column(cols[i], Value.STRING, 0, 0));
// }
// recursiveTable = new TableData(getSchema(), viewName, 0, columns, false);
// recursiveTable.setTemporary(true);
// session.addLocalTempTable(recursiveTable);
// }
return
null
;
}
private
CreateView
parseCreateView
(
boolean
force
)
throws
SQLException
{
int
test
;
TableData
recursiveTable
=
null
;
boolean
recursive
=
readIf
(
"RECURSIVE"
);
boolean
ifNotExists
=
readIfNoExists
();
String
viewName
=
readIdentifierWithSchema
();
CreateView
command
=
new
CreateView
(
session
,
getSchema
());
command
.
setViewName
(
viewName
);
command
.
setIfNotExists
(
ifNotExists
);
String
select
=
StringCache
.
getNew
(
sqlCommand
.
substring
(
parseIndex
));
command
.
setComment
(
readCommentIf
());
if
(
readIf
(
"("
))
{
String
[]
cols
=
parseColumnList
(
false
);
command
.
setColumnNames
(
cols
);
if
(
recursive
)
{
ObjectArray
columns
=
new
ObjectArray
();
for
(
int
i
=
0
;
i
<
cols
.
length
;
i
++)
{
columns
.
add
(
new
Column
(
cols
[
i
],
Value
.
STRING
,
0
,
0
));
}
recursiveTable
=
new
TableData
(
getSchema
(),
viewName
,
0
,
columns
,
false
);
recursiveTable
.
setTemporary
(
true
);
session
.
addLocalTempTable
(
recursiveTable
);
}
}
String
select
=
StringCache
.
getNew
(
sqlCommand
.
substring
(
parseIndex
));
read
(
"AS"
);
try
{
Query
query
=
parseSelect
();
...
...
@@ -3172,6 +3217,11 @@ public class Parser {
throw
e
;
}
}
if
(
recursiveTable
!=
null
)
{
session
.
removeLocalTempTable
(
recursiveTable
);
}
return
command
;
}
...
...
h2/src/main/org/h2/command/ddl/CreateView.java
浏览文件 @
6c3455a1
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
command
.
ddl
;
import
java.sql.SQLException
;
import
org.h2.command.dml.Query
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.schema.Schema
;
import
org.h2.table.TableView
;
public
class
CreateView
extends
SchemaCommand
{
private
Query
select
;
private
String
viewName
;
private
boolean
ifNotExists
;
private
String
selectSQL
;
private
String
[]
columnNames
;
private
String
comment
;
public
CreateView
(
Session
session
,
Schema
schema
)
{
super
(
session
,
schema
);
}
public
void
setViewName
(
String
name
)
{
viewName
=
name
;
}
public
void
setSelect
(
Query
select
)
{
this
.
select
=
select
;
}
public
int
update
()
throws
SQLException
{
// TODO rights: what rights are required to create a view?
session
.
commit
();
Database
db
=
session
.
getDatabase
();
if
(
getSchema
().
findTableOrView
(
session
,
viewName
)!=
null
)
{
if
(
ifNotExists
)
{
return
0
;
/*
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
command
.
ddl
;
import
java.sql.SQLException
;
import
org.h2.command.dml.Query
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.schema.Schema
;
import
org.h2.table.TableView
;
public
class
CreateView
extends
SchemaCommand
{
private
Query
select
;
private
String
viewName
;
private
boolean
ifNotExists
;
private
String
selectSQL
;
private
String
[]
columnNames
;
private
String
comment
;
public
CreateView
(
Session
session
,
Schema
schema
)
{
super
(
session
,
schema
);
}
public
void
setViewName
(
String
name
)
{
viewName
=
name
;
}
public
void
setSelect
(
Query
select
)
{
this
.
select
=
select
;
}
public
int
update
()
throws
SQLException
{
// TODO rights: what rights are required to create a view?
session
.
commit
();
Database
db
=
session
.
getDatabase
();
if
(
getSchema
().
findTableOrView
(
session
,
viewName
)!=
null
)
{
if
(
ifNotExists
)
{
return
0
;
}
throw
Message
.
getSQLException
(
Message
.
VIEW_ALREADY_EXISTS_1
,
viewName
);
}
int
id
=
getObjectId
(
true
,
true
);
String
querySQL
;
if
(
select
==
null
)
{
querySQL
=
selectSQL
;
}
else
{
querySQL
=
select
.
getSQL
();
}
throw
Message
.
getSQLException
(
Message
.
VIEW_ALREADY_EXISTS_1
,
viewName
);
TableView
view
=
new
TableView
(
getSchema
(),
id
,
viewName
,
querySQL
,
null
,
columnNames
,
session
);
view
.
setComment
(
comment
);
db
.
addSchemaObject
(
session
,
view
);
return
0
;
}
int
id
=
getObjectId
(
true
,
true
);
String
querySQL
;
if
(
select
==
null
)
{
querySQL
=
selectSQL
;
}
else
{
querySQL
=
select
.
getSQL
();
public
void
setIfNotExists
(
boolean
ifNotExists
)
{
this
.
ifNotExists
=
ifNotExists
;
}
TableView
view
=
new
TableView
(
getSchema
(),
id
,
viewName
,
querySQL
,
null
,
columnNames
,
session
);
view
.
setComment
(
comment
);
db
.
addSchemaObject
(
session
,
view
);
return
0
;
}
public
void
setIfNotExists
(
boolean
ifNotExists
)
{
this
.
ifNotExists
=
ifNotExists
;
}
public
void
setSelectSQL
(
String
selectSQL
)
{
this
.
selectSQL
=
selectSQL
;
}
public
void
setColumnNames
(
String
[]
cols
)
{
this
.
columnNames
=
cols
;
}
public
void
setComment
(
String
comment
)
{
this
.
comment
=
comment
;
public
void
setSelectSQL
(
String
selectSQL
)
{
this
.
selectSQL
=
selectSQL
;
}
public
void
setColumnNames
(
String
[]
cols
)
{
this
.
columnNames
=
cols
;
}
public
void
setComment
(
String
comment
)
{
this
.
comment
=
comment
;
}
}
}
h2/src/main/org/h2/command/dml/Backup.java
浏览文件 @
6c3455a1
...
...
@@ -19,9 +19,9 @@ import org.h2.engine.Database;
import
org.h2.engine.Session
;
import
org.h2.message.Message
;
import
org.h2.store.DiskFile
;
import
org.h2.store.FileLister
;
import
org.h2.store.LogFile
;
import
org.h2.store.LogSystem
;
import
org.h2.tools.FileBase
;
import
org.h2.util.FileUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.ObjectArray
;
...
...
@@ -72,7 +72,7 @@ public class Backup extends Prepared {
backupFile
(
out
,
fn
);
db
.
setProgress
(
DatabaseEventListener
.
STATE_BACKUP_FILE
,
name
,
i
,
max
);
}
ArrayList
fileList
=
File
Base
.
getDatabaseFiles
(
db
.
getDatabasePath
(),
name
,
true
);
ArrayList
fileList
=
File
Lister
.
getDatabaseFiles
(
db
.
getDatabasePath
(),
name
,
true
);
for
(
int
i
=
0
;
i
<
fileList
.
size
();
i
++)
{
fn
=
(
String
)
fileList
.
get
(
i
);
if
(
fn
.
endsWith
(
Constants
.
SUFFIX_HASH_FILE
)
||
fn
.
endsWith
(
Constants
.
SUFFIX_LOB_FILE
))
{
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
6c3455a1
...
...
@@ -473,7 +473,7 @@ public class Select extends Query {
isQuickQuery
=
isEverything
(
optimizable
);
}
cost
=
preparePlan
();
if
(
sort
!=
null
&&
!
isQuickQuery
&&
!
isGroupQuery
)
{
if
(
sort
!=
null
&&
!
isQuickQuery
&&
!
isGroupQuery
&&
!
distinct
)
{
Index
index
=
getSortIndex
();
Index
current
=
topTableFilter
.
getIndex
();
if
(
index
!=
null
&&
(
current
.
indexType
.
isScan
()
||
current
==
index
))
{
...
...
@@ -537,6 +537,9 @@ public class Select extends Query {
}
public
String
getPlan
()
{
if
(
topTableFilter
==
null
)
{
return
sql
;
}
StringBuffer
buff
=
new
StringBuffer
();
Expression
[]
exprList
=
new
Expression
[
expressions
.
size
()];
expressions
.
toArray
(
exprList
);
...
...
h2/src/main/org/h2/command/dml/SelectUnion.java
浏览文件 @
6c3455a1
...
...
@@ -302,4 +302,11 @@ public class SelectUnion extends Query {
return
left
.
isReadOnly
()
&&
right
.
isReadOnly
();
}
public
Query
getLeftQuery
()
{
return
left
;
}
public
Query
getRightQuery
()
{
return
right
;
}
}
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
6c3455a1
...
...
@@ -73,8 +73,8 @@ package org.h2.engine;
*/
public
class
Constants
{
public
static
final
int
BUILD_ID
=
4
1
;
private
static
final
String
BUILD
=
"2007-0
1-30
"
;
public
static
final
int
BUILD_ID
=
4
2
;
private
static
final
String
BUILD
=
"2007-0
2-06
"
;
public
static
final
int
VERSION_MAJOR
=
1
;
public
static
final
int
VERSION_MINOR
=
0
;
...
...
h2/src/main/org/h2/expression/ConditionIn.java
浏览文件 @
6c3455a1
...
...
@@ -95,6 +95,7 @@ public class ConditionIn extends Condition {
return
expr
;
}
if
(
Constants
.
OPTIMIZE_IN
)
{
int
dataType
=
left
.
getType
();
ExpressionVisitor
independent
=
ExpressionVisitor
.
get
(
ExpressionVisitor
.
INDEPENDENT
);
independent
.
queryLevel
=
queryLevel
;
if
(
areAllValues
(
independent
))
{
...
...
@@ -103,6 +104,7 @@ public class ConditionIn extends Condition {
for
(
int
i
=
0
;
i
<
values
.
size
();
i
++)
{
Expression
e
=
(
Expression
)
values
.
get
(
i
);
Value
v
=
e
.
getValue
(
session
);
v
=
v
.
convertTo
(
dataType
);
values
.
set
(
i
,
ValueExpression
.
get
(
v
));
if
(
min
==
null
||
min
.
compareTo
(
v
,
mode
)
>
0
)
{
min
=
v
;
...
...
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
6c3455a1
...
...
@@ -7,6 +7,7 @@ package org.h2.index;
import
java.sql.SQLException
;
import
org.h2.command.dml.Query
;
import
org.h2.command.dml.SelectUnion
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Session
;
import
org.h2.expression.Comparison
;
...
...
@@ -35,10 +36,21 @@ public class ViewIndex extends Index {
private
long
lastEvaluated
;
private
LocalResult
lastResult
;
public
ViewIndex
(
TableView
view
,
String
querySQL
,
ObjectArray
originalParameters
)
{
private
int
todoRecursiveMustBePrivate
;
public
boolean
recursive
;
private
int
recurseLevel
;
private
LocalResult
recursiveResult
;
public
ViewIndex
(
TableView
view
,
String
querySQL
,
ObjectArray
originalParameters
,
boolean
recursive
)
{
super
(
view
,
0
,
null
,
null
,
IndexType
.
createNonUnique
(
false
));
this
.
querySQL
=
querySQL
;
this
.
originalParameters
=
originalParameters
;
int
test
;
this
.
recursive
=
recursive
;
columns
=
new
Column
[
0
];
params
=
new
Parameter
[
0
];
}
public
String
getPlanSQL
()
{
...
...
@@ -76,6 +88,9 @@ public class ViewIndex extends Index {
}
public
double
getCost
(
Session
session
,
int
[]
masks
)
throws
SQLException
{
if
(
recursive
)
{
return
10
;
}
IntArray
masksArray
=
new
IntArray
(
masks
==
null
?
new
int
[
0
]
:
masks
);
CostElement
cachedCost
=
(
CostElement
)
costCache
.
get
(
masksArray
);
if
(
cachedCost
!=
null
)
{
...
...
@@ -85,11 +100,11 @@ public class ViewIndex extends Index {
}
}
Query
query
=
(
Query
)
session
.
prepare
(
querySQL
,
true
);
IntArray
paramIndex
=
new
IntArray
();
if
(
masks
==
null
)
{
columns
=
new
Column
[
0
];
params
=
new
Parameter
[
0
];
}
else
{
IntArray
paramIndex
=
new
IntArray
();
for
(
int
i
=
0
;
i
<
masks
.
length
;
i
++)
{
int
mask
=
masks
[
i
];
if
(
mask
==
0
)
{
...
...
@@ -110,6 +125,9 @@ public class ViewIndex extends Index {
int
comparisonType
=
getComparisonType
(
mask
);
query
.
addGlobalCondition
(
param
,
idx
,
comparisonType
);
}
if
(
recursive
)
{
return
10
;
}
String
sql
=
query
.
getSQL
();
query
=
(
Query
)
session
.
prepare
(
sql
);
}
...
...
@@ -123,6 +141,35 @@ public class ViewIndex extends Index {
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
Query
query
=
(
Query
)
session
.
prepare
(
querySQL
,
true
);
if
(
recursive
)
{
SelectUnion
union
=
(
SelectUnion
)
query
;
Query
left
=
union
.
getLeftQuery
();
Query
right
=
union
.
getRightQuery
();
LocalResult
completeResult
;
if
(
recurseLevel
==
0
)
{
LocalResult
result
=
left
.
query
(
0
);
completeResult
=
result
;
recurseLevel
=
1
;
result
=
left
.
query
(
0
);
while
(
true
)
{
recursiveResult
=
result
;
recurseLevel
++;
result
=
right
.
query
(
0
);
if
(
result
.
getRowCount
()
==
0
)
{
break
;
}
result
=
right
.
query
(
0
);
while
(
result
.
next
())
{
completeResult
.
addRow
(
result
.
currentRow
());
}
}
completeResult
.
done
();
recurseLevel
=
0
;
return
new
ViewCursor
(
table
,
completeResult
);
}
else
{
return
new
ViewCursor
(
table
,
recursiveResult
);
}
}
ObjectArray
paramList
=
query
.
getParameters
();
for
(
int
i
=
0
;
first
!=
null
&&
i
<
first
.
getColumnCount
();
i
++)
{
Value
v
=
first
.
getValue
(
i
);
...
...
h2/src/main/org/h2/
tools/FileBase
.java
→
h2/src/main/org/h2/
store/FileLister
.java
浏览文件 @
6c3455a1
...
...
@@ -2,7 +2,7 @@
* Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
tools
;
package
org
.
h2
.
store
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
...
...
@@ -14,11 +14,7 @@ import org.h2.util.FileUtils;
* @author Thomas
*/
public
abstract
class
FileBase
{
protected
boolean
allFiles
()
{
return
false
;
}
public
class
FileLister
{
/**
* Get the list of database files.
...
...
@@ -71,20 +67,4 @@ public abstract class FileBase {
return
files
;
}
protected
void
processFiles
(
String
dir
,
String
db
,
boolean
log
)
throws
SQLException
{
ArrayList
files
=
getDatabaseFiles
(
dir
,
db
,
allFiles
());
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
process
(
fileName
);
if
(
log
)
{
System
.
out
.
println
(
"processed: "
+
fileName
);
}
}
if
(
files
.
size
()
==
0
&&
log
)
{
System
.
out
.
println
(
"No database files found"
);
}
}
protected
abstract
void
process
(
String
fileName
)
throws
SQLException
;
}
h2/src/main/org/h2/table/TableData.java
浏览文件 @
6c3455a1
...
...
@@ -170,7 +170,7 @@ public class TableData extends Table implements RecordReader {
}
addRowsToIndex
(
session
,
buffer
,
index
);
if
(
Constants
.
CHECK
&&
remaining
!=
0
)
{
throw
Message
.
getInternalError
(
"rowcount remaining="
+
remaining
);
throw
Message
.
getInternalError
(
"rowcount remaining="
+
remaining
+
" "
+
getName
()
);
}
}
catch
(
SQLException
e
)
{
try
{
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
6c3455a1
...
...
@@ -18,6 +18,7 @@ import org.h2.result.Row;
import
org.h2.schema.Schema
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
public
class
TableView
extends
Table
{
...
...
@@ -27,12 +28,15 @@ public class TableView extends Table {
private
boolean
invalid
;
private
Query
viewQuery
;
private
ViewIndex
index
;
private
int
test
;
private
boolean
recursive
;
public
TableView
(
Schema
schema
,
int
id
,
String
name
,
String
querySQL
,
ObjectArray
params
,
String
[]
columnNames
,
Session
session
)
throws
SQLException
{
super
(
schema
,
id
,
name
,
false
);
this
.
querySQL
=
querySQL
;
this
.
columnNames
=
columnNames
;
index
=
new
ViewIndex
(
this
,
querySQL
,
params
);
index
=
new
ViewIndex
(
this
,
querySQL
,
params
,
recursive
);
initColumnsAndTables
(
session
);
}
...
...
@@ -77,6 +81,18 @@ public class TableView extends Table {
tables
=
new
ObjectArray
();
cols
=
new
Column
[
0
];
invalid
=
true
;
int
testing
;
if
(
columnNames
!=
null
)
{
cols
=
new
Column
[
columnNames
.
length
];
for
(
int
i
=
0
;
i
<
columnNames
.
length
;
i
++)
{
cols
[
i
]
=
new
Column
(
columnNames
[
i
],
Value
.
STRING
,
255
,
0
);
}
invalid
=
false
;
index
.
recursive
=
true
;
recursive
=
true
;
}
}
setColumns
(
cols
);
}
...
...
h2/src/main/org/h2/tools/Backup.java
浏览文件 @
6c3455a1
...
...
@@ -5,15 +5,24 @@
package
org
.
h2
.
tools
;
import
java.io.BufferedWriter
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.io.PrintWriter
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipOutputStream
;
import
org.h2.message.Message
;
import
org.h2.store.FileLister
;
import
org.h2.util.FileUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.StringUtils
;
...
...
@@ -152,6 +161,39 @@ public class Backup {
IOUtils
.
closeSilently
(
fileWriter
);
}
}
/**
* INTERNAL
*/
public
static
void
backupFiles
(
String
zipFileName
,
String
directory
,
String
db
)
throws
IOException
,
SQLException
{
File
file
=
new
File
(
zipFileName
);
if
(
file
.
exists
())
{
file
.
delete
();
}
FileOutputStream
out
=
null
;
try
{
out
=
new
FileOutputStream
(
file
);
ZipOutputStream
zipOut
=
new
ZipOutputStream
(
out
);
ArrayList
list
=
FileLister
.
getDatabaseFiles
(
directory
,
db
,
true
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
fileName
=
(
String
)
list
.
get
(
i
);
ZipEntry
entry
=
new
ZipEntry
(
FileUtils
.
getFileName
(
fileName
));
zipOut
.
putNextEntry
(
entry
);
FileInputStream
in
=
null
;
try
{
in
=
new
FileInputStream
(
fileName
);
IOUtils
.
copyAndCloseInput
(
in
,
zipOut
);
}
finally
{
IOUtils
.
closeSilently
(
in
);
}
zipOut
.
closeEntry
();
}
zipOut
.
closeEntry
();
zipOut
.
close
();
}
finally
{
IOUtils
.
closeSilently
(
out
);
}
}
}
h2/src/main/org/h2/tools/ChangePassword.java
浏览文件 @
6c3455a1
...
...
@@ -6,23 +6,24 @@ package org.h2.tools;
import
java.io.IOException
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
org.h2.engine.Database
;
import
org.h2.message.Message
;
import
org.h2.security.SHA256
;
import
org.h2.store.FileLister
;
import
org.h2.store.FileStore
;
import
org.h2.util.FileUtils
;
/**
* A tools to change, remove or set a file password of a database without opening it.
*/
public
class
ChangePassword
extends
FileBase
{
public
class
ChangePassword
{
private
String
dir
;
private
String
cipher
;
private
byte
[]
decrypt
;
private
byte
[]
encrypt
;
private
boolean
testRenameOnly
;
// TODO security: maybe allow functions in the url
// jdbc:h2:test;action=[decrypt|encrypt|check|reindex|recover|compress...]
...
...
@@ -113,35 +114,36 @@ public class ChangePassword extends FileBase {
change
.
encrypt
=
encrypt
;
// first, test only if the file can be renamed (to find errors with locked files early)
change
.
testRenameOnly
=
true
;
change
.
processFiles
(
dir
,
db
,
!
quiet
);
// if this worked, the operation will (hopefully) be successful
// TODO changePassword: this is a workaround! make the operation atomic (all files or none)
change
.
testRenameOnly
=
false
;
change
.
processFiles
(
dir
,
db
,
!
quiet
);
}
protected
void
process
(
String
fileName
)
throws
SQLException
{
if
(
FileUtils
.
isDirectory
(
fileName
))
{
return
;
}
if
(
testRenameOnly
)
{
ArrayList
files
=
FileLister
.
getDatabaseFiles
(
dir
,
db
,
true
);
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
String
temp
=
dir
+
"/temp.db"
;
FileUtils
.
delete
(
temp
);
FileUtils
.
rename
(
fileName
,
temp
);
FileUtils
.
rename
(
temp
,
fileName
);
}
// if this worked, the operation will (hopefully) be successful
// TODO changePassword: this is a workaround! make the operation atomic (all files or none)
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
change
.
process
(
fileName
);
}
if
(
files
.
size
()
==
0
&&
!
quiet
)
{
System
.
out
.
println
(
"No database files found"
);
}
}
private
void
process
(
String
fileName
)
throws
SQLException
{
boolean
textStorage
=
Database
.
isTextStorage
(
fileName
,
false
);
byte
[]
magic
=
Database
.
getMagic
(
textStorage
);
FileStore
in
;
if
(
decrypt
==
null
)
{
in
=
FileStore
.
open
(
null
,
fileName
,
magic
);
}
else
{
boolean
textStorage
=
Database
.
isTextStorage
(
fileName
,
false
);
byte
[]
magic
=
Database
.
getMagic
(
textStorage
);
FileStore
in
;
if
(
decrypt
==
null
)
{
in
=
FileStore
.
open
(
null
,
fileName
,
magic
);
}
else
{
in
=
FileStore
.
open
(
null
,
fileName
,
magic
,
cipher
,
decrypt
);
}
in
.
init
();
copy
(
fileName
,
textStorage
,
in
,
encrypt
);
in
=
FileStore
.
open
(
null
,
fileName
,
magic
,
cipher
,
decrypt
);
}
in
.
init
();
copy
(
fileName
,
textStorage
,
in
,
encrypt
);
}
private
void
copy
(
String
fileName
,
boolean
textStorage
,
FileStore
in
,
byte
[]
key
)
throws
SQLException
{
...
...
h2/src/main/org/h2/tools/DeleteDbFiles.java
浏览文件 @
6c3455a1
...
...
@@ -5,8 +5,10 @@
package
org
.
h2
.
tools
;
import
java.sql.SQLException
;
import
java.util.ArrayList
;
import
org.h2.engine.Constants
;
import
org.h2.store.FileLister
;
import
org.h2.util.FileUtils
;
/**
...
...
@@ -15,10 +17,8 @@ import org.h2.util.FileUtils;
* @author Thomas
*/
public
class
DeleteDbFiles
extends
FileBase
{
public
class
DeleteDbFiles
{
private
boolean
quiet
;
private
void
showUsage
()
{
System
.
out
.
println
(
"java "
+
getClass
().
getName
()+
" [-dir <dir>] [-db <database>] [-quiet]"
);
}
...
...
@@ -70,20 +70,25 @@ public class DeleteDbFiles extends FileBase {
*/
public
static
void
execute
(
String
dir
,
String
db
,
boolean
quiet
)
throws
SQLException
{
DeleteDbFiles
delete
=
new
DeleteDbFiles
();
delete
.
quiet
=
quiet
;
delete
.
processFiles
(
dir
,
db
,
!
quiet
);
ArrayList
files
=
FileLister
.
getDatabaseFiles
(
dir
,
db
,
true
);
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
delete
.
process
(
fileName
,
quiet
);
if
(!
quiet
)
{
System
.
out
.
println
(
"processed: "
+
fileName
);
}
}
if
(
files
.
size
()
==
0
&&
!
quiet
)
{
System
.
out
.
println
(
"No database files found"
);
}
}
pr
otected
void
process
(
String
fileName
)
throws
SQLException
{
pr
ivate
void
process
(
String
fileName
,
boolean
quiet
)
throws
SQLException
{
if
(
quiet
||
fileName
.
endsWith
(
Constants
.
SUFFIX_TEMP_FILE
)
||
fileName
.
endsWith
(
Constants
.
SUFFIX_TRACE_FILE
))
{
FileUtils
.
tryDelete
(
fileName
);
}
else
{
FileUtils
.
delete
(
fileName
);
}
}
protected
boolean
allFiles
()
{
return
true
;
}
}
}
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
6c3455a1
...
...
@@ -32,6 +32,7 @@ import org.h2.security.SHA256;
import
org.h2.store.DataHandler
;
import
org.h2.store.DataPage
;
import
org.h2.store.DiskFile
;
import
org.h2.store.FileLister
;
import
org.h2.store.FileStore
;
import
org.h2.store.FileStoreInputStream
;
import
org.h2.store.LogFile
;
...
...
@@ -112,7 +113,7 @@ public class Recover implements DataHandler {
}
private
void
removePassword
(
String
dir
,
String
db
)
throws
SQLException
{
ArrayList
list
=
File
Base
.
getDatabaseFiles
(
dir
,
db
,
true
);
ArrayList
list
=
File
Lister
.
getDatabaseFiles
(
dir
,
db
,
true
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
fileName
=
(
String
)
list
.
get
(
i
);
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_DATA_FILE
))
{
...
...
@@ -252,7 +253,7 @@ public class Recover implements DataHandler {
}
private
void
process
(
String
dir
,
String
db
)
throws
SQLException
{
ArrayList
list
=
File
Base
.
getDatabaseFiles
(
dir
,
db
,
true
);
ArrayList
list
=
File
Lister
.
getDatabaseFiles
(
dir
,
db
,
true
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
fileName
=
(
String
)
list
.
get
(
i
);
// TODO recover: should create a working SQL script if possible (2 passes)
...
...
@@ -341,6 +342,49 @@ public class Recover implements DataHandler {
}
}
private
void
writeLogRecord
(
PrintWriter
writer
,
DataPage
s
)
{
try
{
recordLength
=
s
.
readInt
();
if
(
recordLength
<=
0
)
{
writeDataError
(
writer
,
"recordLength<0"
,
s
.
getBytes
(),
blockCount
);
return
;
}
Value
[]
data
;
try
{
data
=
new
Value
[
recordLength
];
}
catch
(
OutOfMemoryError
e
)
{
writeDataError
(
writer
,
"out of memory"
,
s
.
getBytes
(),
blockCount
);
return
;
}
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
"// data: "
);
for
(
valueId
=
0
;
valueId
<
recordLength
;
valueId
++)
{
try
{
Value
v
=
s
.
readValue
();
data
[
valueId
]
=
v
;
if
(
valueId
>
0
)
{
sb
.
append
(
", "
);
}
sb
.
append
(
v
.
getSQL
());
}
catch
(
Exception
e
)
{
writeDataError
(
writer
,
"exception "
+
e
,
s
.
getBytes
(),
blockCount
);
continue
;
}
catch
(
OutOfMemoryError
e
)
{
writeDataError
(
writer
,
"out of memory"
,
s
.
getBytes
(),
blockCount
);
continue
;
}
}
writer
.
println
(
sb
.
toString
());
writer
.
flush
();
}
catch
(
IOException
e
)
{
try
{
writeDataError
(
writer
,
"error: "
+
e
.
toString
(),
s
.
getBytes
(),
blockCount
);
}
catch
(
IOException
e2
)
{
writeError
(
writer
,
e
);
}
}
}
private
void
dumpLog
(
String
fileName
)
throws
SQLException
{
PrintWriter
writer
=
null
;
FileStore
store
=
null
;
...
...
@@ -433,9 +477,11 @@ public class Recover implements DataHandler {
break
;
case
'I'
:
writer
.
println
(
"// insert session:"
+
sessionId
+
" storage:"
+
storageId
+
" pos:"
+
recId
+
" blockCount:"
+
blockCount
);
writeLogRecord
(
writer
,
s
);
break
;
case
'D'
:
writer
.
println
(
"// delete session:"
+
sessionId
+
" storage:"
+
storageId
+
" pos:"
+
recId
+
" blockCount:"
+
blockCount
);
writeLogRecord
(
writer
,
s
);
break
;
default
:
writer
.
println
(
"// type?:"
+
type
+
" session:"
+
sessionId
+
" storage:"
+
storageId
+
" pos:"
+
recId
+
" blockCount:"
+
blockCount
);
...
...
h2/src/main/org/h2/util/IOUtils.java
浏览文件 @
6c3455a1
...
...
@@ -183,7 +183,7 @@ public class IOUtils {
}
off
+=
l
;
}
return
off
<
0
?
-
1
:
off
;
return
off
<
=
0
?
-
1
:
off
;
}
public
static
int
readFully
(
Reader
in
,
char
[]
buffer
,
int
max
)
throws
IOException
{
...
...
@@ -202,7 +202,7 @@ public class IOUtils {
}
off
+=
l
;
}
return
off
<
0
?
-
1
:
off
;
return
off
<
=
0
?
-
1
:
off
;
}
public
static
Reader
getReader
(
InputStream
in
)
throws
SQLException
{
...
...
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
6c3455a1
...
...
@@ -512,22 +512,13 @@ public class ValueLob extends Value {
try
{
String
s
;
if
(
type
==
Value
.
CLOB
)
{
if
(
precision
<
Constants
.
DEFAULT_MAX_LENGTH_INPLACE_LOB
)
{
s
=
getString
();
return
StringUtils
.
quoteStringSQL
(
s
);
}
else
{
return
"READ_CLOB('"
+
fileName
+
"', "
+
precision
+
")"
;
// TODO
}
s
=
getString
();
return
StringUtils
.
quoteStringSQL
(
s
);
}
else
{
if
(
precision
<
Constants
.
DEFAULT_MAX_LENGTH_INPLACE_LOB
)
{
byte
[]
buff
=
getBytes
();
s
=
ByteUtils
.
convertBytesToString
(
buff
);
return
"X'"
+
s
+
"'"
;
}
else
{
return
"READ_BLOB('"
+
fileName
+
"', "
+
precision
+
")"
;
}
}
byte
[]
buff
=
getBytes
();
s
=
ByteUtils
.
convertBytesToString
(
buff
);
return
"X'"
+
s
+
"'"
;
}
}
catch
(
SQLException
e
)
{
throw
Message
.
convertToInternal
(
e
);
}
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
6c3455a1
...
...
@@ -65,6 +65,7 @@ start cmd /k "java org.h2.test.TestAll synth >testSynth.txt"
start cmd /k "java org.h2.test.TestAll all >testAll.txt"
start cmd /k "java org.h2.test.TestAll random >testRandom.txt"
start cmd /k "java org.h2.test.TestAll btree >testBtree.txt"
start cmd /k "java org.h2.test.TestAll halt >testHalt.txt"
Test for hot spots:
java -agentlib:yjpagent=sampling,noj2ee,dir=C:\temp\Snapshots org.h2.test.bench.TestPerformance -init -db 1
...
...
@@ -86,7 +87,95 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
TestAll
test
=
new
TestAll
();
test
.
printSystem
();
// improve TestHalt
// run TestHalt
// SELECT (SELECT true)+1 GROUP BY 1;
// DROP TABLE IF EXISTS TESTA, TESTB;
// CREATE TABLE TESTA(ID IDENTITY);
// CREATE TABLE TESTB(ID IDENTITY);
// @LOOP 4 INSERT INTO TESTA() VALUES();
// @LOOP 4 INSERT INTO TESTB() VALUES();
// SELECT TESTA.ID A, TESTB.ID B FROM TESTA, TESTB ORDER BY TESTA.ID, TESTB.ID;
// script.sql /
// UPDATE Supplier_Original_Input SET global_duns = parent_duns
// INSERT INTO SupplierBase (ID, duns, subscriber, watch_list, name, city, state, country, global_duns, Feed, FeedNo, frequency) SELECT ID, duns, subscriber, watch_list, name,city, state, country,global_duns, Feed, FeedNo,frequency FROM Supplier_Original_Input
// number of rows in supplier_original_input is 354704.
// time taken for executing the update statement is 700 seconds.
// deebee.tar.gz
// WHERE FLAG does not use index, but WHERE FLAG=TRUE does
//
// drop table test;
// CREATE TABLE test (id int, flag BIT NOT NULL);
// CREATE INDEX idx_flag ON test(flag);
// CREATE INDEX idx_id ON test(id);
// insert into test values(1, false), (2, true), (3, false), (4, true);
// ALTER TABLE test ALTER COLUMN id SELECTIVITY 100;
// ALTER TABLE test ALTER COLUMN flag SELECTIVITY 1;
// EXPLAIN SELECT * FROM test WHERE id=2 AND flag=true;
// EXPLAIN SELECT * FROM test WHERE id between 2 and 3 AND flag=true;
// EXPLAIN SELECT * FROM test WHERE id=2 AND flag;
//
// ALTER TABLE test ALTER COLUMN id SELECTIVITY 1;
// ALTER TABLE test ALTER COLUMN flag SELECTIVITY 100;
// EXPLAIN SELECT * FROM test WHERE id=2 AND flag=true;
// EXPLAIN SELECT * FROM test WHERE id between 2 and 3 AND flag=true;
// EXPLAIN SELECT * FROM test WHERE id=2 AND flag;
// DROP VIEW IF EXISTS TEST_REC;
// DROP VIEW IF EXISTS TEST_2;
// DROP TABLE IF EXISTS TEST;
//
// CREATE TABLE TEST(ID INT PRIMARY KEY, PARENT INT, NAME VARCHAR(255));
// INSERT INTO TEST VALUES(1, NULL, 'Root');
// INSERT INTO TEST VALUES(2, 1, 'Plant');
// INSERT INTO TEST VALUES(3, 1, 'Animal');
// INSERT INTO TEST VALUES(4, 2, 'Tree');
// INSERT INTO TEST VALUES(5, 2, 'Flower');
// INSERT INTO TEST VALUES(6, 3, 'Elephant');
// INSERT INTO TEST VALUES(7, 3, 'Dog');
//
// CREATE FORCE VIEW TEST_2(ID, PARENT, NAME) AS SELECT ID, PARENT, NAME FROM TEST_REC;
//
// CREATE FORCE VIEW TEST_REC(ID, PARENT, NAME) AS
// SELECT ID, PARENT, NAME FROM TEST T
// WHERE PARENT IS NULL
// UNION ALL
// SELECT T.ID, T.PARENT, T.NAME
// FROM TEST T, TEST_2 R
// WHERE 1=0 AND T.PARENT=R.ID;
//
// SELECT * FROM TEST_REC;
// DROP VIEW IF EXISTS TEST_REC;
// DROP VIEW IF EXISTS TEST_2;
// DROP TABLE IF EXISTS TEST;
//
// CREATE TABLE TEST(ID INT PRIMARY KEY, PARENT INT, NAME VARCHAR(255));
// INSERT INTO TEST VALUES(1, NULL, 'Root');
// INSERT INTO TEST VALUES(2, 1, 'Plant');
// INSERT INTO TEST VALUES(3, 1, 'Animal');
// INSERT INTO TEST VALUES(4, 2, 'Tree');
// INSERT INTO TEST VALUES(5, 2, 'Flower');
// INSERT INTO TEST VALUES(6, 3, 'Elephant');
// INSERT INTO TEST VALUES(7, 3, 'Dog');
//
// CREATE VIEW RECURSIVE TEST_REC(ID, PARENT, NAME, LEVEL) AS
// SELECT ID, PARENT, NAME, 0 FROM TEST T
// WHERE PARENT IS NULL
// UNION ALL
// SELECT T.ID, T.PARENT, T.NAME, CAST(R.LEVEL AS INT)+1
// FROM TEST T, TEST_REC R
// WHERE T.PARENT=R.ID;
//
// SELECT * FROM TEST_REC;
// TODO backup : lobs are not backed up
// DROP TABLE IF EXISTS TEST;
...
...
h2/src/test/org/h2/test/db/TestLogFile.java
浏览文件 @
6c3455a1
...
...
@@ -10,8 +10,8 @@ import java.sql.PreparedStatement;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.store.FileLister
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
public
class
TestLogFile
extends
TestBase
{
...
...
@@ -23,7 +23,7 @@ public class TestLogFile extends TestBase {
conn
.
close
();
}
long
length
=
0
;
ArrayList
files
=
File
Base
.
getDatabaseFiles
(
BASE_DIR
,
"logfile"
,
false
);
ArrayList
files
=
File
Lister
.
getDatabaseFiles
(
BASE_DIR
,
"logfile"
,
false
);
checkSmaller
(
files
.
size
(),
maxFiles
+
2
);
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
...
...
h2/src/test/org/h2/test/db/TestPowerOff.java
浏览文件 @
6c3455a1
...
...
@@ -15,8 +15,8 @@ import java.util.Random;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.store.FileLister
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
import
org.h2.util.FileUtils
;
import
org.h2.util.JdbcUtils
;
...
...
@@ -164,7 +164,7 @@ public class TestPowerOff extends TestBase {
// expected
}
boolean
deleted
=
false
;
ArrayList
files
=
File
Base
.
getDatabaseFiles
(
dir
,
dbName
,
false
);
ArrayList
files
=
File
Lister
.
getDatabaseFiles
(
dir
,
dbName
,
false
);
for
(
int
i
=
0
;
i
<
files
.
size
();
i
++)
{
String
fileName
=
(
String
)
files
.
get
(
i
);
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_INDEX_FILE
))
{
...
...
h2/src/test/org/h2/test/db/TestReadOnly.java
浏览文件 @
6c3455a1
...
...
@@ -10,8 +10,8 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.util.ArrayList
;
import
org.h2.store.FileLister
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
public
class
TestReadOnly
extends
TestBase
{
...
...
@@ -52,7 +52,7 @@ public class TestReadOnly extends TestBase {
}
private
void
setReadOnly
()
throws
SQLException
{
ArrayList
list
=
File
Base
.
getDatabaseFiles
(
TestBase
.
BASE_DIR
,
"readonly"
,
true
);
ArrayList
list
=
File
Lister
.
getDatabaseFiles
(
TestBase
.
BASE_DIR
,
"readonly"
,
true
);
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
fileName
=
(
String
)
list
.
get
(
i
);
File
file
=
new
File
(
fileName
);
...
...
h2/src/test/org/h2/test/synth/TestHalt.java
浏览文件 @
6c3455a1
...
...
@@ -18,6 +18,7 @@ import java.util.LinkedList;
import
java.util.Random
;
import
org.h2.test.TestBase
;
import
org.h2.tools.Backup
;
import
org.h2.tools.DeleteDbFiles
;
import
org.h2.util.IOUtils
;
...
...
@@ -29,6 +30,10 @@ public abstract class TestHalt extends TestBase {
protected
int
operations
,
flags
,
value
;
protected
Connection
conn
;
protected
Random
random
=
new
Random
();
private
int
errorId
;
private
int
sequenceId
;
private
static
final
String
DATABASE_NAME
=
"halt"
;
private
static
final
String
TRACE_FILE_NAME
=
BASE_DIR
+
"/haltTrace.trace.db"
;
abstract
void
testInit
()
throws
Exception
;
abstract
void
testCheckAfterCrash
()
throws
Exception
;
...
...
@@ -52,7 +57,7 @@ public abstract class TestHalt extends TestBase {
Connection
getConnection
()
throws
Exception
{
Class
.
forName
(
"org.h2.Driver"
);
return
DriverManager
.
getConnection
(
"jdbc:h2:
tes
t"
,
"sa"
,
"sa"
);
return
DriverManager
.
getConnection
(
"jdbc:h2:
"
+
BASE_DIR
+
"/hal
t"
,
"sa"
,
"sa"
);
}
protected
void
start
(
String
[]
args
)
throws
Exception
{
...
...
@@ -67,36 +72,40 @@ public abstract class TestHalt extends TestBase {
}
private
void
runRandom
()
throws
Exception
{
log
(
"connecting"
,
null
);
connect
();
try
{
log
(
"connected, operations:"
+
operations
+
" flags:"
+
flags
+
" value:"
+
value
,
null
);
traceOperation
(
"connected, operations:"
+
operations
+
" flags:"
+
flags
+
" value:"
+
value
);
appStart
();
System
.
out
.
println
(
"READY"
);
System
.
out
.
println
(
"READY"
);
System
.
out
.
println
(
"READY"
);
appRun
();
log
(
"done"
,
null
);
traceOperation
(
"done"
);
}
catch
(
Exception
e
)
{
log
(
"run"
,
e
);
trace
(
"run"
,
e
);
}
disconnect
();
}
private
void
connect
()
throws
Exception
{
try
{
traceOperation
(
"connecting"
);
conn
=
getConnection
();
}
catch
(
Exception
e
)
{
log
(
"connect"
,
e
);
trace
(
"connect"
,
e
);
e
.
printStackTrace
();
throw
e
;
}
}
protected
void
log
(
String
s
,
Exception
e
)
{
protected
void
traceOperation
(
String
s
)
{
trace
(
s
,
null
);
}
protected
void
trace
(
String
s
,
Exception
e
)
{
FileWriter
writer
=
null
;
try
{
writer
=
new
FileWriter
(
"log.txt"
,
true
);
writer
=
new
FileWriter
(
TRACE_FILE_NAME
,
true
);
PrintWriter
w
=
new
PrintWriter
(
writer
);
s
=
dateFormat
.
format
(
new
Date
())
+
": "
+
s
;
w
.
println
(
s
);
...
...
@@ -111,12 +120,17 @@ public abstract class TestHalt extends TestBase {
}
private
void
runTest
()
throws
Exception
{
DeleteDbFiles
.
execute
(
null
,
"test"
,
true
);
new
File
(
"log.txt"
).
delete
();
traceOperation
(
"delete database -----------------------------"
);
DeleteDbFiles
.
execute
(
BASE_DIR
,
DATABASE_NAME
,
true
);
new
File
(
TRACE_FILE_NAME
).
delete
();
connect
();
testInit
();
disconnect
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
traceOperation
(
"backing up "
+
sequenceId
);
Backup
.
backupFiles
(
BASE_DIR
+
"/haltSeq"
+
sequenceId
+
".zip"
,
BASE_DIR
,
null
);
sequenceId
++;
// int operations = OP_INSERT;
// OP_DELETE = 1, OP_UPDATE = 2, OP_SELECT = 4;
// int flags = FLAG_NODELAY;
...
...
@@ -126,7 +140,7 @@ public abstract class TestHalt extends TestBase {
// String classPath = "-cp .;D:/data/java/hsqldb.jar;D:/data/java/derby.jar";
String
classPath
=
""
;
String
command
=
"java "
+
classPath
+
" "
+
getClass
().
getName
()
+
" "
+
operations
+
" "
+
flags
+
" "
+
value
;
log
(
"start: "
+
command
);
traceOperation
(
"start: "
+
command
);
Process
p
=
Runtime
.
getRuntime
().
exec
(
command
);
InputStream
in
=
p
.
getInputStream
();
OutputCatcher
catcher
=
new
OutputCatcher
(
in
);
...
...
@@ -135,27 +149,38 @@ public abstract class TestHalt extends TestBase {
if
(
s
==
null
)
{
throw
new
IOException
(
"No reply from process"
);
}
else
if
(
s
.
startsWith
(
"READY"
))
{
log
(
"got reply: "
+
s
);
traceOperation
(
"got reply: "
+
s
);
}
testWaitAfterAppStart
();
p
.
destroy
();
connect
();
testCheckAfterCrash
();
disconnect
();
try
{
traceOperation
(
"backing up "
+
sequenceId
);
Backup
.
backupFiles
(
BASE_DIR
+
"/haltSeq"
+
sequenceId
+
".zip"
,
BASE_DIR
,
null
);
// new File(BASE_DIR + "/haltSeq" + (sequenceId-20) + ".zip").delete();
connect
();
testCheckAfterCrash
();
}
catch
(
Exception
e
)
{
File
zip
=
new
File
(
BASE_DIR
+
"/haltSeq"
+
sequenceId
+
".zip"
);
File
zipId
=
new
File
(
BASE_DIR
+
"/haltSeq"
+
sequenceId
+
"-"
+
errorId
+
".zip"
);
zip
.
renameTo
(
zipId
);
printTime
(
"ERROR: "
+
sequenceId
+
" "
+
errorId
+
" "
+
e
.
toString
());
e
.
printStackTrace
();
errorId
++;
}
finally
{
sequenceId
++;
disconnect
();
}
}
}
protected
void
disconnect
()
{
try
{
traceOperation
(
"disconnect"
);
conn
.
close
();
}
catch
(
Exception
e
)
{
log
(
"disconnect"
,
e
);
trace
(
"disconnect"
,
e
);
}
}
private
void
log
(
String
string
)
{
System
.
out
.
println
(
string
);
}
private
static
class
OutputCatcher
extends
Thread
{
private
InputStream
in
;
...
...
h2/src/test/org/h2/test/synth/TestHaltApp.java
浏览文件 @
6c3455a1
...
...
@@ -17,22 +17,27 @@ public class TestHaltApp extends TestHalt {
new
TestHaltApp
().
start
(
args
);
}
private
void
execute
(
Statement
stat
,
String
sql
)
throws
SQLException
{
traceOperation
(
"execute: "
+
sql
);
stat
.
execute
(
sql
);
}
protected
void
testInit
()
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
try
{
stat
.
execute
(
"DROP TABLE TEST"
);
execute
(
stat
,
"DROP TABLE TEST"
);
}
catch
(
SQLException
e
)
{
// ignore
}
// stat.execute("CREATE TABLE TEST(ID IDENTITY, NAME VARCHAR(255))");
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
stat
.
execute
(
"DROP TABLE IF EXISTS TEST"
+
i
);
stat
.
execute
(
"CREATE TABLE TEST"
+
i
+
"(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
execute
(
stat
,
"DROP TABLE IF EXISTS TEST"
+
i
);
execute
(
stat
,
"CREATE TABLE TEST"
+
i
+
"(ID INT PRIMARY KEY, NAME VARCHAR(255))"
);
}
for
(
int
i
=
0
;
i
<
20
;
i
+=
2
)
{
stat
.
execute
(
"DROP TABLE TEST"
+
i
);
execute
(
stat
,
"DROP TABLE TEST"
+
i
);
}
stat
.
execute
(
"CREATE TABLE TEST(ID BIGINT GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR(255), DATA CLOB)"
);
execute
(
stat
,
"CREATE TABLE TEST(ID BIGINT GENERATED BY DEFAULT AS IDENTITY, NAME VARCHAR(255), DATA CLOB)"
);
}
protected
void
testWaitAfterAppStart
()
throws
Exception
{
...
...
@@ -47,6 +52,7 @@ public class TestHaltApp extends TestHalt {
int
count
=
rs
.
getInt
(
1
);
System
.
out
.
println
(
"count: "
+
count
);
if
(
count
%
2
==
1
)
{
traceOperation
(
"row count: "
+
count
);
throw
new
Exception
(
"Unexpected odd row count"
);
}
}
...
...
@@ -54,17 +60,18 @@ public class TestHaltApp extends TestHalt {
protected
void
appStart
()
throws
SQLException
{
Statement
stat
=
conn
.
createStatement
();
if
((
flags
&
FLAG_NO_DELAY
)
!=
0
)
{
stat
.
execute
(
"SET WRITE_DELAY 0"
);
stat
.
execute
(
"SET MAX_LOG_SIZE 1"
);
execute
(
stat
,
"SET WRITE_DELAY 0"
);
execute
(
stat
,
"SET MAX_LOG_SIZE 1"
);
}
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT COUNT(*) FROM TEST"
);
rs
.
next
();
rowCount
=
rs
.
getInt
(
1
);
log
(
"rows: "
+
rowCount
,
null
);
trace
(
"rows: "
+
rowCount
,
null
);
}
protected
void
appRun
()
throws
SQL
Exception
{
protected
void
appRun
()
throws
Exception
{
conn
.
setAutoCommit
(
false
);
traceOperation
(
"setAutoCommit false"
);
int
rows
=
10000
+
value
;
PreparedStatement
prepInsert
=
conn
.
prepareStatement
(
"INSERT INTO TEST(NAME, DATA) VALUES('Hello World', ?)"
);
PreparedStatement
prepUpdate
=
conn
.
prepareStatement
(
"UPDATE TEST SET NAME = 'Hallo Welt', DATA = ? WHERE ID = ?"
);
...
...
@@ -72,37 +79,53 @@ public class TestHaltApp extends TestHalt {
Statement
stat
=
conn
.
createStatement
();
if
((
operations
&
OP_INSERT
)
!=
0
)
{
if
((
flags
&
FLAG_LOBS
)
!=
0
)
{
prepInsert
.
setString
(
1
,
getRandomString
(
random
.
nextInt
(
200
)));
String
s
=
getRandomString
(
random
.
nextInt
(
200
));
prepInsert
.
setString
(
1
,
s
);
traceOperation
(
"insert "
+
s
);
prepInsert
.
execute
();
}
else
{
stat
.
execute
(
"INSERT INTO TEST(NAME) VALUES('Hello World')"
);
execute
(
stat
,
"INSERT INTO TEST(NAME) VALUES('Hello World')"
);
}
ResultSet
rs
=
stat
.
getGeneratedKeys
();
rs
.
next
();
int
key
=
rs
.
getInt
(
1
);
traceOperation
(
"inserted key: "
+
key
);
rowCount
++;
}
if
((
operations
&
OP_UPDATE
)
!=
0
)
{
if
((
flags
&
FLAG_LOBS
)
!=
0
)
{
prepUpdate
.
setString
(
1
,
getRandomString
(
random
.
nextInt
(
200
)));
prepUpdate
.
setInt
(
2
,
random
.
nextInt
(
rowCount
+
1
));
String
s
=
getRandomString
(
random
.
nextInt
(
200
));
prepUpdate
.
setString
(
1
,
s
);
int
x
=
random
.
nextInt
(
rowCount
+
1
);
prepUpdate
.
setInt
(
2
,
x
);
traceOperation
(
"update "
+
s
+
" "
+
x
);
prepUpdate
.
execute
();
}
else
{
stat
.
execute
(
"UPDATE TEST SET VALUE = 'Hallo Welt' WHERE ID = "
+
random
.
nextInt
(
rowCount
+
1
));
int
x
=
random
.
nextInt
(
rowCount
+
1
);
execute
(
stat
,
"UPDATE TEST SET VALUE = 'Hallo Welt' WHERE ID = "
+
x
);
}
}
if
((
operations
&
OP_DELETE
)
!=
0
)
{
int
uc
=
stat
.
executeUpdate
(
"DELETE FROM TEST WHERE ID = "
+
random
.
nextInt
(
rowCount
+
1
));
rowCount
-=
uc
;
int
x
=
random
.
nextInt
(
rowCount
+
1
);
traceOperation
(
"deleting "
+
x
);
int
uc
=
stat
.
executeUpdate
(
"DELETE FROM TEST WHERE ID = "
+
x
);
traceOperation
(
"updated: "
+
uc
);
rowCount
-=
uc
;
}
log
(
"rows now: "
+
rowCount
,
null
);
traceOperation
(
"rowCount "
+
rowCount
);
trace
(
"rows now: "
+
rowCount
,
null
);
if
(
rowCount
%
2
==
0
)
{
traceOperation
(
"commit "
+
rowCount
);
conn
.
commit
();
log
(
"committed: "
+
rowCount
,
null
);
trace
(
"committed: "
+
rowCount
,
null
);
}
if
((
flags
&
FLAG_NO_DELAY
)
!=
0
)
{
if
(
random
.
nextInt
(
100
)
==
0
)
{
stat
.
execute
(
"CHECKPOINT"
);
execute
(
stat
,
"CHECKPOINT"
);
}
}
}
traceOperation
(
"rollback"
);
conn
.
rollback
();
}
...
...
h2/src/test/org/h2/test/synth/TestKillProcess.java
浏览文件 @
6c3455a1
...
...
@@ -10,8 +10,8 @@ import java.sql.PreparedStatement;
import
java.util.ArrayList
;
import
java.util.Random
;
import
org.h2.store.FileLister
;
import
org.h2.test.TestBase
;
import
org.h2.tools.FileBase
;
public
class
TestKillProcess
{
public
static
void
main
(
String
[]
args
)
throws
Exception
{
...
...
@@ -32,7 +32,7 @@ public class TestKillProcess {
for
(
int
i
=
0
;
;
i
++)
{
long
t
=
System
.
currentTimeMillis
();
if
(
t
>
time
+
1000
)
{
ArrayList
list
=
File
Base
.
getDatabaseFiles
(
BASE_DIR
,
"kill"
,
true
);
ArrayList
list
=
File
Lister
.
getDatabaseFiles
(
BASE_DIR
,
"kill"
,
true
);
System
.
out
.
println
(
"inserting... i:"
+
i
+
" d:"
+
d
+
" files:"
+
list
.
size
());
time
=
t
;
}
...
...
h2/src/test/org/h2/test/test.in.txt
浏览文件 @
6c3455a1
--- special grammar and test cases ---------------------------------------------------------------------------------------------
CREATE TABLE test (family_name VARCHAR_IGNORECASE(63) NOT NULL);
> ok
INSERT INTO test VALUES('Smith'), ('de Smith'), ('el Smith'), ('von Smith');
> update count: 4
SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith');
> FAMILY_NAME
> -----------
> Smith
> de Smith
> rows: 2
SELECT * FROM test WHERE family_name BETWEEN 'D' AND 'T';
> FAMILY_NAME
> -----------
> Smith
> de Smith
> el Smith
> rows: 3
CREATE INDEX family_name ON test(family_name);
> ok
SELECT * FROM test WHERE family_name IN ('de Smith', 'Smith');
> FAMILY_NAME
> -----------
> Smith
> de Smith
> rows: 2
drop table test;
> ok
create memory table test(id int primary key, data clob);
> ok
insert into test values(1, 'abc' || space(20));
> update count: 1
script nopasswords nosettings blocksize 10;
> SCRIPT
> ------------------------------------------------------------------------------------------------------------------
> -- 1 = SELECT COUNT(*) FROM PUBLIC.TEST
> CALL SYSTEM_COMBINE_BLOB(-1)
> CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_BLOB FOR "org.h2.command.dml.Script.combineBlob"
> CREATE ALIAS IF NOT EXISTS SYSTEM_COMBINE_CLOB FOR "org.h2.command.dml.Script.combineClob"
> CREATE MEMORY TABLE PUBLIC.TEST( ID INT NOT NULL, DATA CLOB )
> CREATE PRIMARY KEY ON PUBLIC.TEST(ID)
> CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM(ID INT, PART INT, CDATA VARCHAR, BDATA BINARY, PRIMARY KEY(ID, PART))
> CREATE USER IF NOT EXISTS SA PASSWORD '' ADMIN
> DROP ALIAS IF EXISTS SYSTEM_COMBINE_BLOB
> DROP ALIAS IF EXISTS SYSTEM_COMBINE_CLOB
> DROP TABLE IF EXISTS SYSTEM_LOB_STREAM
> INSERT INTO PUBLIC.TEST(ID, DATA) VALUES(1, SYSTEM_COMBINE_CLOB(0))
> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 0, 'abc ', NULL);
> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 1, ' ', NULL);
> INSERT INTO SYSTEM_LOB_STREAM VALUES(0, 2, ' ', NULL);
> rows: 15
drop table test;
> ok
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));
> ok
INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World');
> update count: 2
SELECT DISTINCT * FROM TEST ORDER BY ID;
> ID NAME
> -- -----
> 1 Hello
> 2 World
> rows (ordered): 2
DROP TABLE TEST;
> ok
create table Foo (A varchar(20), B integer);
> ok
...
...
h2/src/test/org/h2/test/testSimple.in.txt
浏览文件 @
6c3455a1
SELECT (SELECT true)+1 GROUP BY 1;
> 2;
create table FOO (ID int, A number(18, 2));
insert into FOO (ID, A) values (1, 10.0), (2, 20.0);
select SUM (CASE when ID=1 then A ELSE 0 END) col0 from Foo;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论