Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
eed6fa58
提交
eed6fa58
authored
10月 23, 2007
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
--no commit message
--no commit message
上级
c12cf0a7
隐藏空白字符变更
内嵌
并排
正在显示
35 个修改的文件
包含
199 行增加
和
125 行删除
+199
-125
Parser.java
h2/src/main/org/h2/command/Parser.java
+16
-3
Optimizer.java
h2/src/main/org/h2/command/dml/Optimizer.java
+3
-0
Select.java
h2/src/main/org/h2/command/dml/Select.java
+29
-13
Constants.java
h2/src/main/org/h2/engine/Constants.java
+3
-3
Database.java
h2/src/main/org/h2/engine/Database.java
+2
-1
DatabaseCloser.java
h2/src/main/org/h2/engine/DatabaseCloser.java
+8
-4
Aggregate.java
h2/src/main/org/h2/expression/Aggregate.java
+4
-0
Comparison.java
h2/src/main/org/h2/expression/Comparison.java
+1
-1
Expression.java
h2/src/main/org/h2/expression/Expression.java
+1
-1
ExpressionColumn.java
h2/src/main/org/h2/expression/ExpressionColumn.java
+0
-3
BaseIndex.java
h2/src/main/org/h2/index/BaseIndex.java
+14
-11
BtreeIndex.java
h2/src/main/org/h2/index/BtreeIndex.java
+2
-2
FunctionIndex.java
h2/src/main/org/h2/index/FunctionIndex.java
+1
-1
HashIndex.java
h2/src/main/org/h2/index/HashIndex.java
+1
-1
Index.java
h2/src/main/org/h2/index/Index.java
+1
-1
IndexCondition.java
h2/src/main/org/h2/index/IndexCondition.java
+2
-2
LinearHashIndex.java
h2/src/main/org/h2/index/LinearHashIndex.java
+1
-1
LinkedIndex.java
h2/src/main/org/h2/index/LinkedIndex.java
+1
-1
MetaIndex.java
h2/src/main/org/h2/index/MetaIndex.java
+1
-1
MultiVersionCursor.java
h2/src/main/org/h2/index/MultiVersionCursor.java
+0
-3
MultiVersionIndex.java
h2/src/main/org/h2/index/MultiVersionIndex.java
+2
-17
RangeIndex.java
h2/src/main/org/h2/index/RangeIndex.java
+1
-1
ScanIndex.java
h2/src/main/org/h2/index/ScanIndex.java
+1
-1
TreeIndex.java
h2/src/main/org/h2/index/TreeIndex.java
+1
-1
ViewIndex.java
h2/src/main/org/h2/index/ViewIndex.java
+6
-1
JdbcDatabaseMetaData.java
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
+8
-8
SortOrder.java
h2/src/main/org/h2/result/SortOrder.java
+21
-28
Column.java
h2/src/main/org/h2/table/Column.java
+1
-1
ColumnResolver.java
h2/src/main/org/h2/table/ColumnResolver.java
+4
-0
IndexColumn.java
h2/src/main/org/h2/table/IndexColumn.java
+13
-2
Table.java
h2/src/main/org/h2/table/Table.java
+8
-3
TableFilter.java
h2/src/main/org/h2/table/TableFilter.java
+30
-8
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+2
-1
TestCluster.java
h2/src/test/org/h2/test/db/TestCluster.java
+1
-0
testSimple.in.txt
h2/src/test/org/h2/test/testSimple.in.txt
+9
-0
没有找到文件。
h2/src/main/org/h2/command/Parser.java
浏览文件 @
eed6fa58
...
...
@@ -109,6 +109,7 @@ import org.h2.expression.ValueExpression;
import
org.h2.expression.Wildcard
;
import
org.h2.index.Index
;
import
org.h2.message.Message
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
import
org.h2.schema.Sequence
;
import
org.h2.schema.TriggerObject
;
...
...
@@ -137,6 +138,9 @@ import org.h2.value.ValueString;
import
org.h2.value.ValueTime
;
import
org.h2.value.ValueTimestamp
;
/**
* The parser is used to convert a SQL statement string to an command object.
*/
public
class
Parser
{
// used during the tokenizer phase
...
...
@@ -677,10 +681,19 @@ public class Parser {
column
.
columnName
=
readColumnIdentifier
();
columns
.
add
(
column
);
if
(
readIf
(
"ASC"
))
{
// ignore
// ignore
}
else
if
(
readIf
(
"DESC"
))
{
column
.
sortType
=
SortOrder
.
DESCENDING
;
}
if
(
readIf
(
"NULLS"
))
{
if
(
readIf
(
"FIRST"
))
{
column
.
sortType
|=
SortOrder
.
NULLS_FIRST
;
}
else
{
read
(
"LAST"
);
column
.
sortType
|=
SortOrder
.
NULLS_LAST
;
}
}
else
{
readIf
(
"DESC"
);
column
.
descending
=
true
;
}
}
while
(
readIf
(
","
));
read
(
")"
);
...
...
h2/src/main/org/h2/command/dml/Optimizer.java
浏览文件 @
eed6fa58
...
...
@@ -15,6 +15,9 @@ import org.h2.table.PlanItem;
import
org.h2.table.TableFilter
;
import
org.h2.util.Permutations
;
/**
* The optimizer is responsible to find the best execution plan for a given query.
*/
public
class
Optimizer
{
private
static
final
int
MAX_BRUTE_FORCE_FILTERS
=
7
;
...
...
h2/src/main/org/h2/command/dml/Select.java
浏览文件 @
eed6fa58
...
...
@@ -22,6 +22,7 @@ import org.h2.result.LocalResult;
import
org.h2.result.SortOrder
;
import
org.h2.table.Column
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.Table
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ObjectArray
;
...
...
@@ -32,6 +33,8 @@ import org.h2.value.ValueArray;
import
org.h2.value.ValueNull
;
/**
* This class represents a simple SELECT statement.
*
* visibleColumnCount <= distinctColumnCount <= expressionCount
* Sortable count could include ORDER BY expressions that are not in the select list
* Expression count could include GROUP BY expressions
...
...
@@ -60,6 +63,7 @@ public class Select extends Query {
private
double
cost
;
private
boolean
isQuickQuery
;
private
boolean
isPrepared
,
checkInit
;
private
boolean
sortUsingIndex
;
private
SortOrder
sort
;
public
Select
(
Session
session
)
{
...
...
@@ -190,16 +194,18 @@ public class Select extends Query {
}
}
/**
* Get the index that matches the ORDER BY list, if one exists.
* This is to avoid running a separate ORDER BY if an index can be used.
* This is specially important for large result sets, if only the first few rows are important
* (LIMIT is used)
*
* @return the index if one is found
*/
private
Index
getSortIndex
()
throws
SQLException
{
if
(
sort
==
null
)
{
return
null
;
}
int
[]
sortTypes
=
sort
.
getSortTypes
();
for
(
int
i
=
0
;
i
<
sortTypes
.
length
;
i
++)
{
if
((
sortTypes
[
i
]
&
(
SortOrder
.
DESCENDING
|
SortOrder
.
NULLS_LAST
))
!=
0
)
{
return
null
;
}
}
int
[]
indexes
=
sort
.
getIndexes
();
ObjectArray
sortColumns
=
new
ObjectArray
();
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
...
...
@@ -223,6 +229,7 @@ public class Select extends Query {
}
Column
[]
sortCols
=
new
Column
[
sortColumns
.
size
()];
sortColumns
.
toArray
(
sortCols
);
int
[]
sortTypes
=
sort
.
getSortTypes
();
if
(
sortCols
.
length
==
0
)
{
// sort just on constants - can use scan index
return
topTableFilter
.
getTable
().
getScanIndex
(
session
);
...
...
@@ -237,15 +244,22 @@ public class Select extends Query {
if
(
index
.
getIndexType
().
isHash
())
{
continue
;
}
Column
[]
indexCols
=
index
.
get
Columns
();
IndexColumn
[]
indexCols
=
index
.
getIndex
Columns
();
if
(
indexCols
.
length
<
sortCols
.
length
)
{
continue
;
}
boolean
ok
=
true
;
for
(
int
j
=
0
;
j
<
sortCols
.
length
;
j
++)
{
// the index and the sort order must start with the exact same
// columns
if
(
indexCols
[
j
]
!=
sortCols
[
j
])
{
// the index and the sort order must start
// with the exact same columns
IndexColumn
idxCol
=
indexCols
[
j
];
Column
sortCol
=
sortCols
[
j
];
if
(
idxCol
.
column
!=
sortCol
)
{
ok
=
false
;
break
;
}
if
(
idxCol
.
sortType
!=
sortTypes
[
j
])
{
// TODO NULL FIRST for ascending and NULLS LAST for descending would actually match the default
ok
=
false
;
break
;
}
...
...
@@ -274,7 +288,7 @@ public class Select extends Query {
}
result
.
addRow
(
row
);
rowNumber
++;
if
(
sort
==
null
&&
limitRows
!=
0
&&
result
.
getRowCount
()
>=
limitRows
)
{
if
(
(
sort
==
null
||
sortUsingIndex
)
&&
limitRows
!=
0
&&
result
.
getRowCount
()
>=
limitRows
)
{
break
;
}
if
(
sampleSize
>
0
&&
rowNumber
>=
sampleSize
)
{
...
...
@@ -311,7 +325,9 @@ public class Select extends Query {
}
int
columnCount
=
expressions
.
size
();
LocalResult
result
=
new
LocalResult
(
session
,
expressions
,
visibleColumnCount
);
result
.
setSortOrder
(
sort
);
if
(!
sortUsingIndex
)
{
result
.
setSortOrder
(
sort
);
}
if
(
distinct
)
{
result
.
setDistinct
();
}
...
...
@@ -489,7 +505,7 @@ public class Select extends Query {
Index
current
=
topTableFilter
.
getIndex
();
if
(
index
!=
null
&&
(
current
.
getIndexType
().
isScan
()
||
current
==
index
))
{
topTableFilter
.
setIndex
(
index
);
sort
=
null
;
sort
UsingIndex
=
true
;
}
}
}
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
eed6fa58
...
...
@@ -64,6 +64,9 @@ import org.h2.constant.SysProperties;
*
* @author Thomas
*/
/**
* Constants are fixed values that are used in the whole database code.
*/
public
class
Constants
{
public
static
final
int
BUILD_ID
=
60
;
...
...
@@ -82,9 +85,6 @@ public class Constants {
return
VERSION_MAJOR
+
"."
+
VERSION_MINOR
+
"."
+
BUILD_ID
+
" ("
+
BUILD
+
")"
;
}
public
static
final
int
NULL_SORT_LOW
=
1
,
NULL_SORT_HIGH
=
2
;
public
static
final
int
NULL_SORT_START
=
3
,
NULL_SORT_END
=
4
;
public
static
final
int
NULL_SORT_DEFAULT
=
NULL_SORT_LOW
;
public
static
final
int
DEFAULT_SERVER_PORT
=
9092
;
// this is also in the docs
public
static
final
String
START_URL
=
"jdbc:h2:"
;
public
static
final
String
URL_FORMAT
=
START_URL
+
"{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]"
;
...
...
h2/src/main/org/h2/engine/Database.java
浏览文件 @
eed6fa58
...
...
@@ -59,10 +59,11 @@ import org.h2.value.Value;
import
org.h2.value.ValueInt
;
/**
* There is one database object per open database.
*
* @author Thomas
* @since 2004-04-15 22:49
*/
/*
* MetaData format: int id int headPos (for indexes) int objectType String sql
*/
...
...
h2/src/main/org/h2/engine/DatabaseCloser.java
浏览文件 @
eed6fa58
...
...
@@ -6,6 +6,9 @@ package org.h2.engine;
import
java.lang.ref.WeakReference
;
/**
* This class is reponsible to close a database if the application did not close a connection.
*/
public
class
DatabaseCloser
extends
Thread
{
private
final
boolean
shutdownHook
;
...
...
@@ -52,14 +55,15 @@ public class DatabaseCloser extends Thread {
return
;
}
}
Database
database
=
null
;
synchronized
(
this
)
{
if
(
databaseRef
!=
null
)
{
Database
database
=
(
Database
)
databaseRef
.
get
();
if
(
database
!=
null
)
{
database
.
close
(
shutdownHook
);
}
database
=
(
Database
)
databaseRef
.
get
();
}
}
if
(
database
!=
null
)
{
database
.
close
(
shutdownHook
);
}
}
}
h2/src/main/org/h2/expression/Aggregate.java
浏览文件 @
eed6fa58
...
...
@@ -161,6 +161,10 @@ public class Aggregate extends Expression {
case
MAX:
boolean
first
=
type
==
MIN
;
Index
index
=
getColumnIndex
(
first
);
int
sortType
=
index
.
getIndexColumns
()[
0
].
sortType
;
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
first
=
!
first
;
}
SearchRow
row
=
index
.
findFirstOrLast
(
session
,
first
);
Value
v
;
if
(
row
==
null
)
{
...
...
h2/src/main/org/h2/expression/Comparison.java
浏览文件 @
eed6fa58
...
...
@@ -19,7 +19,7 @@ import org.h2.value.ValueBoolean;
import
org.h2.value.ValueNull
;
/**
*
@author Thomas
*
Example comparison expressions are ID=1, NAME=NAME, NAME IS NULL.
*/
public
class
Comparison
extends
Condition
{
...
...
h2/src/main/org/h2/expression/Expression.java
浏览文件 @
eed6fa58
...
...
@@ -15,7 +15,7 @@ import org.h2.value.Value;
/**
*
@author Thomas
*
An expression is a operation, a value, or a function in a query.
*/
public
abstract
class
Expression
{
...
...
h2/src/main/org/h2/expression/ExpressionColumn.java
浏览文件 @
eed6fa58
...
...
@@ -22,9 +22,6 @@ import org.h2.table.TableFilter;
import
org.h2.value.Value
;
import
org.h2.value.ValueBoolean
;
/**
* @author Thomas
*/
public
class
ExpressionColumn
extends
Expression
{
private
Database
database
;
private
String
schemaName
;
...
...
h2/src/main/org/h2/index/BaseIndex.java
浏览文件 @
eed6fa58
...
...
@@ -14,6 +14,7 @@ import org.h2.message.Message;
import
org.h2.message.Trace
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.SchemaObjectBase
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
...
...
@@ -23,7 +24,7 @@ import org.h2.value.Value;
import
org.h2.value.ValueNull
;
/**
*
@author Thomas
*
Most index implementations extend the base index.
*/
public
abstract
class
BaseIndex
extends
SchemaObjectBase
implements
Index
{
...
...
@@ -90,7 +91,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
public
abstract
void
truncate
(
Session
session
)
throws
SQLException
;
public
abstract
boolean
canGetFirstOrLast
(
boolean
first
);
public
abstract
boolean
canGetFirstOrLast
();
public
abstract
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
...
...
@@ -144,14 +145,14 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
}
public
int
compareRows
(
SearchRow
rowData
,
SearchRow
compare
)
throws
SQLException
{
for
(
int
i
=
0
;
i
<
c
olumns
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
indexC
olumns
.
length
;
i
++)
{
int
index
=
columnIds
[
i
];
Value
v
=
compare
.
getValue
(
index
);
if
(
v
==
null
)
{
// can't compare further
return
0
;
}
int
c
=
compareValues
(
rowData
.
getValue
(
index
),
v
);
int
c
=
compareValues
(
rowData
.
getValue
(
index
),
v
,
indexColumns
[
i
].
sortType
);
if
(
c
!=
0
)
{
return
c
;
}
...
...
@@ -179,17 +180,19 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
return
k1
>
k2
?
1
:
-
1
;
}
private
int
compareValues
(
Value
v1
,
Value
v2
)
throws
SQLException
{
if
(
v1
==
null
)
{
if
(
v2
==
null
)
{
private
int
compareValues
(
Value
a
,
Value
b
,
int
sortType
)
throws
SQLException
{
boolean
aNull
=
a
==
null
,
bNull
=
b
==
null
;
if
(
aNull
||
bNull
)
{
if
(
aNull
==
bNull
)
{
return
0
;
}
return
1
;
return
SortOrder
.
compareNull
(
aNull
,
bNull
,
sortType
)
;
}
if
(
v2
==
null
)
{
return
-
1
;
int
comp
=
database
.
compareTypeSave
(
a
,
b
);
if
((
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
comp
=
-
comp
;
}
return
database
.
compareTypeSave
(
v1
,
v2
)
;
return
comp
;
}
public
int
getColumnIndex
(
Column
col
)
{
...
...
h2/src/main/org/h2/index/BtreeIndex.java
浏览文件 @
eed6fa58
...
...
@@ -25,7 +25,7 @@ import org.h2.value.Value;
import
org.h2.value.ValueNull
;
/**
*
@author Thomas
*
This is the most common type of index, a b tree index.
*/
public
class
BtreeIndex
extends
BaseIndex
implements
RecordReader
{
...
...
@@ -284,7 +284,7 @@ public class BtreeIndex extends BaseIndex implements RecordReader {
return
lastChange
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
true
;
}
...
...
h2/src/main/org/h2/index/FunctionIndex.java
浏览文件 @
eed6fa58
...
...
@@ -65,7 +65,7 @@ public class FunctionIndex extends BaseIndex {
throw
Message
.
getUnsupportedException
();
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/HashIndex.java
浏览文件 @
eed6fa58
...
...
@@ -142,7 +142,7 @@ public class HashIndex extends BaseIndex {
return
true
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/Index.java
浏览文件 @
eed6fa58
...
...
@@ -36,7 +36,7 @@ public interface Index extends SchemaObject {
void
truncate
(
Session
session
)
throws
SQLException
;
boolean
canGetFirstOrLast
(
boolean
first
);
boolean
canGetFirstOrLast
();
SearchRow
findFirstOrLast
(
Session
session
,
boolean
first
)
throws
SQLException
;
...
...
h2/src/main/org/h2/index/IndexCondition.java
浏览文件 @
eed6fa58
...
...
@@ -15,9 +15,9 @@ import org.h2.message.Message;
import
org.h2.table.Column
;
import
org.h2.value.Value
;
/**
* @author Thomas
* A index condition object is made for each condition that can potentially use an index.
* This class does not extend expression, but in general there is one expression that maps to each index condition.
*/
public
class
IndexCondition
{
public
static
final
int
EQUALITY
=
1
,
START
=
2
,
END
=
4
,
RANGE
=
START
|
END
,
ALWAYS_FALSE
=
8
;
...
...
h2/src/main/org/h2/index/LinearHashIndex.java
浏览文件 @
eed6fa58
...
...
@@ -532,7 +532,7 @@ public class LinearHashIndex extends BaseIndex implements RecordReader {
return
bucketSize
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/LinkedIndex.java
浏览文件 @
eed6fa58
...
...
@@ -157,7 +157,7 @@ public class LinkedIndex extends BaseIndex {
return
false
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/MetaIndex.java
浏览文件 @
eed6fa58
...
...
@@ -82,7 +82,7 @@ public class MetaIndex extends BaseIndex {
return
null
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/MultiVersionCursor.java
浏览文件 @
eed6fa58
...
...
@@ -120,9 +120,6 @@ public class MultiVersionCursor implements Cursor {
return
true
;
}
}
int
test
;
this
.
index
.
debug
(
"error"
,
session
,
deltaRow
);
System
.
exit
(
1
);
throw
Message
.
getInternalError
();
}
int
compare
=
index
.
compareRows
(
deltaRow
,
baseRow
);
...
...
h2/src/main/org/h2/index/MultiVersionIndex.java
浏览文件 @
eed6fa58
...
...
@@ -33,8 +33,6 @@ public class MultiVersionIndex implements Index {
}
public
void
add
(
Session
session
,
Row
row
)
throws
SQLException
{
int
test
;
debug
(
"add"
,
session
,
row
);
synchronized
(
sync
)
{
base
.
add
(
session
,
row
);
if
(
removeIfExists
(
session
,
row
))
{
...
...
@@ -53,8 +51,6 @@ debug("add", session, row);
}
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
throws
SQLException
{
int
test
;
debug
(
"find"
,
session
,
first
);
synchronized
(
sync
)
{
Cursor
baseCursor
=
base
.
find
(
session
,
first
,
last
);
Cursor
deltaCursor
=
delta
.
find
(
session
,
first
,
last
);
...
...
@@ -62,7 +58,7 @@ debug("find", session, first);
}
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
// TODO in many cases possible, but more complicated
return
false
;
}
...
...
@@ -80,26 +76,19 @@ debug("find", session, first);
}
private
boolean
removeIfExists
(
Session
session
,
Row
row
)
throws
SQLException
{
int
test
;
debug
(
"removeIfExists "
,
session
,
row
);
// maybe it was inserted by the same session just before
Cursor
c
=
delta
.
find
(
session
,
row
,
row
);
while
(
c
.
next
())
{
Row
r
=
c
.
get
();
if
(
r
.
getPos
()
==
row
.
getPos
())
{
debug
(
" >remove"
,
session
,
null
);
delta
.
remove
(
session
,
row
);
debug
(
" >return true"
,
session
,
null
);
return
true
;
}
}
debug
(
" >return false"
,
session
,
null
);
return
false
;
}
public
void
remove
(
Session
session
,
Row
row
)
throws
SQLException
{
int
test
;
debug
(
"remove"
,
session
,
row
);
synchronized
(
sync
)
{
base
.
remove
(
session
,
row
);
if
(
removeIfExists
(
session
,
row
))
{
...
...
@@ -117,8 +106,6 @@ debug("remove", session, row);
}
public
void
truncate
(
Session
session
)
throws
SQLException
{
int
test
;
debug
(
"truncate"
,
session
,
null
);
synchronized
(
sync
)
{
delta
.
truncate
(
session
);
base
.
truncate
(
session
);
...
...
@@ -126,8 +113,6 @@ debug("truncate", session, null);
}
public
void
commit
(
int
operation
,
Row
row
)
throws
SQLException
{
int
test
;
debug
(
"commit"
,
null
,
row
);
synchronized
(
sync
)
{
removeIfExists
(
null
,
row
);
}
...
...
@@ -273,7 +258,7 @@ debug("commit", null, row);
}
void
debug
(
String
s
,
Session
session
,
SearchRow
row
)
throws
SQLException
{
//
System.out.println(this + " " + s + " sess:" + (session == null ? -1: session.getId()) + " " + (row == null ? "" : row.getValue(0).getString()));
//
System.out.println(this + " " + s + " sess:" + (session == null ? -1: session.getId()) + " " + (row == null ? "" : row.getValue(0).getString()));
}
}
h2/src/main/org/h2/index/RangeIndex.java
浏览文件 @
eed6fa58
...
...
@@ -66,7 +66,7 @@ public class RangeIndex extends BaseIndex {
throw
Message
.
getUnsupportedException
();
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
true
;
}
...
...
h2/src/main/org/h2/index/ScanIndex.java
浏览文件 @
eed6fa58
...
...
@@ -253,7 +253,7 @@ public class ScanIndex extends BaseIndex {
return
false
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/index/TreeIndex.java
浏览文件 @
eed6fa58
...
...
@@ -341,7 +341,7 @@ public class TreeIndex extends BaseIndex {
return
true
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
true
;
}
...
...
h2/src/main/org/h2/index/ViewIndex.java
浏览文件 @
eed6fa58
...
...
@@ -21,6 +21,11 @@ import org.h2.util.ObjectArray;
import
org.h2.util.SmallLRUCache
;
import
org.h2.value.Value
;
/**
* This object represents a virtual index for a query.
* Actually it only represents a prepared statement that is
* a SELECT statement.
*/
public
class
ViewIndex
extends
BaseIndex
{
private
String
querySQL
;
...
...
@@ -233,7 +238,7 @@ public class ViewIndex extends BaseIndex {
return
false
;
}
public
boolean
canGetFirstOrLast
(
boolean
first
)
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
...
...
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
浏览文件 @
eed6fa58
...
...
@@ -420,41 +420,41 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
/**
* Checks is NULL values are sorted high (bigger than any non-null values).
*
* @return
true or
false
* @return false
*/
public
boolean
nullsAreSortedHigh
()
{
debugCodeCall
(
"nullsAreSortedHigh"
);
return
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_HIGH
;
return
false
;
}
/**
* Checks is NULL values are sorted low (smaller than any non-null values).
*
* @return true
or false
* @return true
*/
public
boolean
nullsAreSortedLow
()
{
debugCodeCall
(
"nullsAreSortedLow"
);
return
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_LOW
;
return
true
;
}
/**
* Checks is NULL values are sorted at the beginning (no matter if ASC or DESC is used).
*
* @return
true or
false
* @return false
*/
public
boolean
nullsAreSortedAtStart
()
{
debugCodeCall
(
"nullsAreSortedAtStart"
);
return
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_START
;
return
false
;
}
/**
* Checks is NULL values are sorted at the end (no matter if ASC or DESC is used).
*
* @return
true or
false
* @return false
*/
public
boolean
nullsAreSortedAtEnd
()
{
debugCodeCall
(
"nullsAreSortedAtEnd"
);
return
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_END
;
return
false
;
}
/**
...
...
h2/src/main/org/h2/result/SortOrder.java
浏览文件 @
eed6fa58
...
...
@@ -6,7 +6,6 @@ package org.h2.result;
import
java.sql.SQLException
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.util.ObjectArray
;
...
...
@@ -15,10 +14,10 @@ import org.h2.util.StringUtils;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
*
@author Thomas
*
A sort order represents an ORDER BY clause in a query.
*/
public
class
SortOrder
{
public
static
final
int
ASCENDING
=
0
,
DESCENDING
=
1
;
public
static
final
int
NULLS_FIRST
=
2
,
NULLS_LAST
=
4
;
...
...
@@ -60,39 +59,33 @@ public class SortOrder {
}
return
buff
.
toString
();
}
public
static
int
compareNull
(
boolean
aNull
,
boolean
bNull
,
int
type
)
{
if
((
type
&
NULLS_FIRST
)
!=
0
)
{
return
aNull
?
-
1
:
1
;
}
else
if
((
type
&
NULLS_LAST
)
!=
0
)
{
return
aNull
?
1
:
-
1
;
}
else
{
// see also JdbcDatabaseMetaData.nullsAreSorted*
int
comp
=
aNull
?
-
1
:
1
;
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
}
}
public
int
compare
(
Value
[]
a
,
Value
[]
b
)
throws
SQLException
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
idx
=
indexes
[
i
];
int
type
=
sortTypes
[
i
];
Value
o1
=
a
[
idx
];
Value
o2
=
b
[
idx
];
boolean
b1
=
o1
==
ValueNull
.
INSTANCE
,
b2
=
o2
==
ValueNull
.
INSTANCE
;
if
(
b1
||
b2
)
{
if
(
b1
==
b2
)
{
Value
ao
=
a
[
idx
];
Value
bo
=
b
[
idx
];
boolean
aNull
=
ao
==
ValueNull
.
INSTANCE
,
bNull
=
bo
==
ValueNull
.
INSTANCE
;
if
(
aNull
||
bNull
)
{
if
(
aNull
==
bNull
)
{
continue
;
}
if
((
type
&
NULLS_FIRST
)
!=
0
)
{
return
b1
?
-
1
:
1
;
}
else
if
((
type
&
NULLS_LAST
)
!=
0
)
{
return
b1
?
1
:
-
1
;
}
else
{
// this depends on NULL_SORT_DEFAULT
int
comp
;
if
(
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_LOW
)
{
comp
=
b1
?
-
1
:
1
;
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
}
else
if
(
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_HIGH
)
{
comp
=
b1
?
1
:
-
1
;
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
}
else
if
(
Constants
.
NULL_SORT_DEFAULT
==
Constants
.
NULL_SORT_START
)
{
return
b1
?
1
:
-
1
;
}
else
{
return
b1
?
-
1
:
1
;
}
}
return
compareNull
(
aNull
,
bNull
,
type
);
}
int
comp
=
database
.
compare
(
o1
,
o2
);
int
comp
=
database
.
compare
(
ao
,
bo
);
if
(
comp
!=
0
)
{
return
(
type
&
DESCENDING
)
==
0
?
comp
:
-
comp
;
}
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
eed6fa58
...
...
@@ -33,7 +33,7 @@ import org.h2.value.ValueTimestamp;
import
org.h2.value.ValueUuid
;
/**
*
@author Thomas
*
This class represents a column in a table.
*/
public
class
Column
{
private
final
int
type
;
...
...
h2/src/main/org/h2/table/ColumnResolver.java
浏览文件 @
eed6fa58
...
...
@@ -9,6 +9,10 @@ import java.sql.SQLException;
import
org.h2.command.dml.Select
;
import
org.h2.value.Value
;
/**
* A column resolver is list of column (for example, a table) that can map a
* column name to an actual column.
*/
public
interface
ColumnResolver
{
String
getTableAlias
();
...
...
h2/src/main/org/h2/table/IndexColumn.java
浏览文件 @
eed6fa58
...
...
@@ -6,16 +6,27 @@ package org.h2.table;
import
java.sql.SQLException
;
import
org.h2.result.SortOrder
;
/**
* This represents a column item of an index. This is required because some
* indexes support descending sorted columns.
*/
public
class
IndexColumn
{
public
String
columnName
;
public
Column
column
;
public
boolean
descending
;
public
int
sortType
=
SortOrder
.
ASCENDING
;
public
String
getSQL
()
{
StringBuffer
buff
=
new
StringBuffer
(
column
.
getSQL
());
if
(
descending
)
{
if
(
(
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
buff
.
append
(
" DESC"
);
}
if
((
sortType
&
SortOrder
.
NULLS_FIRST
)
!=
0
)
{
buff
.
append
(
" NULLS FIRST"
);
}
else
if
((
sortType
&
SortOrder
.
NULLS_LAST
)
!=
0
)
{
buff
.
append
(
" NULLS LAST"
);
}
return
buff
.
toString
();
}
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
eed6fa58
...
...
@@ -22,6 +22,7 @@ import org.h2.result.Row;
import
org.h2.result.SearchRow
;
import
org.h2.result.SimpleRow
;
import
org.h2.result.SimpleRowValue
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.Schema
;
import
org.h2.schema.SchemaObjectBase
;
import
org.h2.schema.Sequence
;
...
...
@@ -32,9 +33,8 @@ import org.h2.value.Value;
import
org.h2.value.ValueNull
;
/**
*
@author Thomas
*
A table contains a list of columns and a list of rows.
*/
public
abstract
class
Table
extends
SchemaObjectBase
{
public
static
final
int
TYPE_CACHED
=
0
,
TYPE_MEMORY
=
1
;
...
...
@@ -489,7 +489,12 @@ public abstract class Table extends SchemaObjectBase {
ObjectArray
indexes
=
getIndexes
();
for
(
int
i
=
1
;
indexes
!=
null
&&
i
<
indexes
.
size
();
i
++)
{
Index
index
=
(
Index
)
indexes
.
get
(
i
);
if
(
index
.
canGetFirstOrLast
(
first
))
{
if
(
index
.
canGetFirstOrLast
())
{
IndexColumn
idxCol
=
index
.
getIndexColumns
()[
0
];
if
((
idxCol
.
sortType
&
SortOrder
.
DESCENDING
)
!=
0
&&
(
idxCol
.
sortType
&
SortOrder
.
NULLS_FIRST
)
==
0
)
{
// for descending sorted columns, if the NULLs are at the end, it does not work for some index types
continue
;
}
int
idx
=
index
.
getColumnIndex
(
column
);
if
(
idx
==
0
)
{
return
index
;
...
...
h2/src/main/org/h2/table/TableFilter.java
浏览文件 @
eed6fa58
...
...
@@ -20,13 +20,16 @@ import org.h2.index.IndexCondition;
import
org.h2.message.Message
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.util.ObjectArray
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
import
org.h2.value.ValueInt
;
/**
* @author Thomas
* A table filter represents a table that is used in a query. There is one such object whenever a table
* (or view) is used in a query. For example the following query has 2 table filters:
* SELECT * FROM TEST T1, TEST T2.
*/
public
class
TableFilter
implements
ColumnResolver
{
private
static
final
int
BEFORE_FIRST
=
0
,
FOUND
=
1
,
AFTER_LAST
=
2
,
NULL_ROW
=
3
;
...
...
@@ -35,6 +38,7 @@ public class TableFilter implements ColumnResolver {
private
final
Select
select
;
private
Session
session
;
private
Index
index
;
private
IndexColumn
[]
indexColumns
;
private
Cursor
cursor
;
private
int
scanCount
;
private
boolean
used
;
// used in the plan
...
...
@@ -134,7 +138,7 @@ public class TableFilter implements ColumnResolver {
}
public
void
setPlanItem
(
PlanItem
item
)
{
this
.
index
=
item
.
getIndex
(
);
setIndex
(
item
.
getIndex
()
);
for
(
int
i
=
0
;
joins
!=
null
&&
i
<
joins
.
size
();
i
++)
{
TableFilter
join
=
getTableFilter
(
i
);
if
(
item
.
getJoinPlan
()
!=
null
)
{
...
...
@@ -204,17 +208,24 @@ public class TableFilter implements ColumnResolver {
int
type
=
column
.
getType
();
int
id
=
column
.
getColumnId
();
Value
v
=
condition
.
getCurrentValue
(
session
).
convertTo
(
type
);
if
(
condition
.
isStart
())
{
// TODO index: start.setExpression(id,
// bigger(start.getValue(id), e));
boolean
isStart
=
condition
.
isStart
(),
isEnd
=
condition
.
isEnd
();
IndexColumn
idxCol
=
indexColumns
[
id
];
if
(
idxCol
!=
null
&&
(
idxCol
.
sortType
&
SortOrder
.
DESCENDING
)
!=
0
)
{
// if the index column is sorted the other way, we swap end and start
// NULLS_FIRST / NULLS_LAST is not a problem, as nulls never match anyway
boolean
temp
=
isStart
;
isStart
=
isEnd
;
isEnd
=
temp
;
}
if
(
isStart
)
{
// TODO index: start.setExpression(id, bigger(start.getValue(id), e));
if
(
start
==
null
)
{
start
=
table
.
getTemplateRow
();
}
start
.
setValue
(
id
,
v
);
}
if
(
condition
.
isEnd
())
{
// TODO index: end.setExpression(id,
// smaller(end.getExpression(id), e));
if
(
isEnd
)
{
// TODO index: end.setExpression(id, smaller(end.getExpression(id), e));
if
(
end
==
null
)
{
end
=
table
.
getTemplateRow
();
}
...
...
@@ -459,6 +470,17 @@ public class TableFilter implements ColumnResolver {
public
void
setIndex
(
Index
index
)
{
this
.
index
=
index
;
Column
[]
columns
=
table
.
getColumns
();
indexColumns
=
new
IndexColumn
[
columns
.
length
];
IndexColumn
[]
idxCols
=
index
.
getIndexColumns
();
if
(
idxCols
!=
null
)
{
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
int
idx
=
index
.
getColumnIndex
(
columns
[
i
]);
if
(
idx
>=
0
)
{
indexColumns
[
i
]
=
idxCols
[
idx
];
}
}
}
}
public
void
setUsed
(
boolean
used
)
{
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
eed6fa58
...
...
@@ -7,7 +7,6 @@ package org.h2.test;
import
java.sql.SQLException
;
import
java.util.Properties
;
import
org.h2.constant.SysProperties
;
import
org.h2.server.TcpServer
;
import
org.h2.test.db.TestAutoRecompile
;
import
org.h2.test.db.TestBackup
;
...
...
@@ -142,10 +141,12 @@ java org.h2.test.TestAll timer
/*
----
A file is sent although the Japanese translation has not been completed yet.
----
reverse index
Code coverage
At startup, when corrupted, say if LOG=0 was used before
...
...
h2/src/test/org/h2/test/db/TestCluster.java
浏览文件 @
eed6fa58
...
...
@@ -41,6 +41,7 @@ public class TestCluster extends TestBase {
prep
.
setString
(
2
,
"Data"
+
i
);
prep
.
executeUpdate
();
}
check
(
conn
,
len
);
conn
.
close
();
CreateCluster
.
main
(
new
String
[]
{
"-urlSource"
,
"jdbc:h2:file:"
+
baseDir
+
"/node1/test"
,
"-urlTarget"
,
...
...
h2/src/test/org/h2/test/testSimple.in.txt
浏览文件 @
eed6fa58
CREATE TABLE TEST(ID INT);
INSERT INTO TEST VALUES(1), (2), (3);
create index idxdesc on test(id desc);
select * from test where id between 0 and 1;
> 1;
select * from test where id between 3 and 4;
> 3;
drop table test;
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255));
INSERT INTO TEST VALUES(1, 'Hello'), (2, 'HelloWorld'), (3, 'HelloWorldWorld');
SELECT COUNT(*) FROM TEST WHERE NAME REGEXP 'World';
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论