Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ed405433
Unverified
提交
ed405433
authored
6 年前
作者:
Michael Christopher
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1 from h2database/master
Fork Sync
上级
cb513063
1e462004
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
442 行增加
和
189 行删除
+442
-189
Query.java
h2/src/main/org/h2/command/dml/Query.java
+69
-2
Comparison.java
h2/src/main/org/h2/expression/Comparison.java
+13
-6
ConditionAndOr.java
h2/src/main/org/h2/expression/ConditionAndOr.java
+13
-6
ConditionNot.java
h2/src/main/org/h2/expression/ConditionNot.java
+9
-0
Operation.java
h2/src/main/org/h2/expression/Operation.java
+18
-0
FullText.java
h2/src/main/org/h2/fulltext/FullText.java
+4
-4
TraceObject.java
h2/src/main/org/h2/message/TraceObject.java
+3
-1
MVPlainTempResult.java
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
+28
-18
MVSortedTempResult.java
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
+74
-30
MVTempResult.java
h2/src/main/org/h2/mvstore/db/MVTempResult.java
+31
-14
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+69
-93
ResultExternal.java
h2/src/main/org/h2/result/ResultExternal.java
+0
-5
ResultTempTable.java
h2/src/main/org/h2/result/ResultTempTable.java
+0
-5
Data.java
h2/src/main/org/h2/store/Data.java
+1
-1
TestScript.java
h2/src/test/org/h2/test/scripts/TestScript.java
+1
-0
distinct.sql
h2/src/test/org/h2/test/scripts/distinct.sql
+105
-0
testScript.sql
h2/src/test/org/h2/test/scripts/testScript.sql
+4
-4
没有找到文件。
h2/src/main/org/h2/command/dml/Query.java
浏览文件 @
ed405433
...
@@ -12,10 +12,16 @@ import org.h2.api.ErrorCode;
...
@@ -12,10 +12,16 @@ import org.h2.api.ErrorCode;
import
org.h2.command.Prepared
;
import
org.h2.command.Prepared
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.engine.Mode.ModeEnum
;
import
org.h2.expression.Alias
;
import
org.h2.expression.Alias
;
import
org.h2.expression.Comparison
;
import
org.h2.expression.ConditionAndOr
;
import
org.h2.expression.ConditionNot
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.ExpressionColumn
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.expression.ExpressionVisitor
;
import
org.h2.expression.Function
;
import
org.h2.expression.Operation
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.Parameter
;
import
org.h2.expression.ValueExpression
;
import
org.h2.expression.ValueExpression
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
...
@@ -478,8 +484,11 @@ public abstract class Query extends Prepared {
...
@@ -478,8 +484,11 @@ public abstract class Query extends Prepared {
}
}
if
(!
isAlias
)
{
if
(!
isAlias
)
{
if
(
mustBeInResult
)
{
if
(
mustBeInResult
)
{
throw
DbException
.
get
(
ErrorCode
.
ORDER_BY_NOT_IN_RESULT
,
if
(
session
.
getDatabase
().
getMode
().
getEnum
()
!=
ModeEnum
.
MySQL
)
{
e
.
getSQL
());
if
(!
checkOrderOther
(
session
,
e
,
expressionSQL
))
{
throw
DbException
.
get
(
ErrorCode
.
ORDER_BY_NOT_IN_RESULT
,
e
.
getSQL
());
}
}
}
}
expressions
.
add
(
e
);
expressions
.
add
(
e
);
String
sql
=
e
.
getSQL
();
String
sql
=
e
.
getSQL
();
...
@@ -490,6 +499,64 @@ public abstract class Query extends Prepared {
...
@@ -490,6 +499,64 @@ public abstract class Query extends Prepared {
}
}
}
}
/**
* An additional check for expression in ORDER BY list for DISTINCT selects
* that was not matched with selected expressions in regular way. This
* method allows expressions based only on selected expressions in different
* complicated ways with functions, comparisons, or operators.
*
* @param session session
* @param expr expression to check
* @param expressionSQL SQL of allowed expressions
* @return whether the specified expression should be allowed in ORDER BY
* list of DISTINCT select
*/
private
static
boolean
checkOrderOther
(
Session
session
,
Expression
expr
,
ArrayList
<
String
>
expressionSQL
)
{
if
(
expr
.
isConstant
())
{
return
true
;
}
if
(
expressionSQL
!=
null
)
{
String
exprSQL
=
expr
.
getSQL
();
for
(
String
sql:
expressionSQL
)
{
if
(
session
.
getDatabase
().
equalsIdentifiers
(
exprSQL
,
sql
))
{
return
true
;
}
}
}
if
(
expr
instanceof
Function
)
{
Function
function
=
(
Function
)
expr
;
if
(!
function
.
isDeterministic
())
{
return
false
;
}
for
(
Expression
e
:
function
.
getArgs
())
{
if
(!
checkOrderOther
(
session
,
e
,
expressionSQL
))
{
return
false
;
}
}
return
true
;
}
if
(
expr
instanceof
Operation
)
{
Operation
operation
=
(
Operation
)
expr
;
Expression
right
=
operation
.
getRightSubExpression
();
return
checkOrderOther
(
session
,
operation
.
getLeftSubExpression
(),
expressionSQL
)
&&
(
right
==
null
||
checkOrderOther
(
session
,
right
,
expressionSQL
));
}
if
(
expr
instanceof
ConditionAndOr
)
{
ConditionAndOr
condition
=
(
ConditionAndOr
)
expr
;
return
checkOrderOther
(
session
,
condition
.
getLeftSubExpression
(),
expressionSQL
)
&&
checkOrderOther
(
session
,
condition
.
getRightSubExpression
(),
expressionSQL
);
}
if
(
expr
instanceof
ConditionNot
)
{
return
checkOrderOther
(
session
,
((
ConditionNot
)
expr
).
getSubCondition
(),
expressionSQL
);
}
if
(
expr
instanceof
Comparison
)
{
Comparison
condition
=
(
Comparison
)
expr
;
return
checkOrderOther
(
session
,
condition
.
getLeftSubExpression
(),
expressionSQL
)
&&
checkOrderOther
(
session
,
condition
.
getRightSubExpression
(),
expressionSQL
);
}
return
false
;
}
/**
/**
* Create a {@link SortOrder} object given the list of {@link SelectOrderBy}
* Create a {@link SortOrder} object given the list of {@link SelectOrderBy}
* objects. The expression list is extended if necessary.
* objects. The expression list is extended if necessary.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Comparison.java
浏览文件 @
ed405433
...
@@ -597,14 +597,21 @@ public class Comparison extends Condition {
...
@@ -597,14 +597,21 @@ public class Comparison extends Condition {
}
}
/**
/**
* Get the left
or the right
sub-expression of this condition.
* Get the left sub-expression of this condition.
*
*
* @param getLeft true to get the left sub-expression, false to get the
* @return the left sub-expression
* right sub-expression.
* @return the sub-expression
*/
*/
public
Expression
getExpression
(
boolean
getLeft
)
{
public
Expression
getLeftSubExpression
()
{
return
getLeft
?
this
.
left
:
right
;
return
left
;
}
/**
* Get the right sub-expression of this condition.
*
* @return the right sub-expression
*/
public
Expression
getRightSubExpression
()
{
return
right
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/ConditionAndOr.java
浏览文件 @
ed405433
...
@@ -284,14 +284,21 @@ public class ConditionAndOr extends Condition {
...
@@ -284,14 +284,21 @@ public class ConditionAndOr extends Condition {
}
}
/**
/**
* Get the left
or the right
sub-expression of this condition.
* Get the left sub-expression of this condition.
*
*
* @param getLeft true to get the left sub-expression, false to get the
* @return the left sub-expression
* right sub-expression.
* @return the sub-expression
*/
*/
public
Expression
getExpression
(
boolean
getLeft
)
{
public
Expression
getLeftSubExpression
()
{
return
getLeft
?
this
.
left
:
right
;
return
left
;
}
/**
* Get the right sub-expression of this condition.
*
* @return the right sub-expression
*/
public
Expression
getRightSubExpression
()
{
return
right
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/ConditionNot.java
浏览文件 @
ed405433
...
@@ -98,4 +98,13 @@ public class ConditionNot extends Condition {
...
@@ -98,4 +98,13 @@ public class ConditionNot extends Condition {
return
condition
.
getCost
();
return
condition
.
getCost
();
}
}
/**
* Get the sub-expression of this condition.
*
* @return the sub-expression
*/
public
Expression
getSubCondition
()
{
return
condition
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Operation.java
浏览文件 @
ed405433
...
@@ -407,4 +407,22 @@ public class Operation extends Expression {
...
@@ -407,4 +407,22 @@ public class Operation extends Expression {
return
left
.
getCost
()
+
1
+
(
right
==
null
?
0
:
right
.
getCost
());
return
left
.
getCost
()
+
1
+
(
right
==
null
?
0
:
right
.
getCost
());
}
}
/**
* Get the left sub-expression of this operation.
*
* @return the left sub-expression
*/
public
Expression
getLeftSubExpression
()
{
return
left
;
}
/**
* Get the right sub-expression of this operation.
*
* @return the right sub-expression
*/
public
Expression
getRightSubExpression
()
{
return
right
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/fulltext/FullText.java
浏览文件 @
ed405433
...
@@ -669,14 +669,14 @@ public class FullText {
...
@@ -669,14 +669,14 @@ public class FullText {
ArrayList
<
String
>
data
,
Expression
expr
)
{
ArrayList
<
String
>
data
,
Expression
expr
)
{
if
(
expr
instanceof
ConditionAndOr
)
{
if
(
expr
instanceof
ConditionAndOr
)
{
ConditionAndOr
and
=
(
ConditionAndOr
)
expr
;
ConditionAndOr
and
=
(
ConditionAndOr
)
expr
;
Expression
left
=
and
.
get
Expression
(
true
);
Expression
left
=
and
.
get
LeftSubExpression
(
);
Expression
right
=
and
.
get
Expression
(
false
);
Expression
right
=
and
.
get
RightSubExpression
(
);
addColumnData
(
columns
,
data
,
left
);
addColumnData
(
columns
,
data
,
left
);
addColumnData
(
columns
,
data
,
right
);
addColumnData
(
columns
,
data
,
right
);
}
else
{
}
else
{
Comparison
comp
=
(
Comparison
)
expr
;
Comparison
comp
=
(
Comparison
)
expr
;
ExpressionColumn
ec
=
(
ExpressionColumn
)
comp
.
get
Expression
(
true
);
ExpressionColumn
ec
=
(
ExpressionColumn
)
comp
.
get
LeftSubExpression
(
);
ValueExpression
ev
=
(
ValueExpression
)
comp
.
get
Expression
(
false
);
ValueExpression
ev
=
(
ValueExpression
)
comp
.
get
RightSubExpression
(
);
String
columnName
=
ec
.
getColumnName
();
String
columnName
=
ec
.
getColumnName
();
columns
.
add
(
columnName
);
columns
.
add
(
columnName
);
if
(
ev
==
null
)
{
if
(
ev
==
null
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/message/TraceObject.java
浏览文件 @
ed405433
...
@@ -105,6 +105,8 @@ public class TraceObject {
...
@@ -105,6 +105,8 @@ public class TraceObject {
"rs"
,
"rsMeta"
,
"sp"
,
"ex"
,
"stat"
,
"blob"
,
"clob"
,
"pMeta"
,
"ds"
,
"rs"
,
"rsMeta"
,
"sp"
,
"ex"
,
"stat"
,
"blob"
,
"clob"
,
"pMeta"
,
"ds"
,
"xads"
,
"xares"
,
"xid"
,
"ar"
,
"sqlxml"
};
"xads"
,
"xares"
,
"xid"
,
"ar"
,
"sqlxml"
};
private
static
final
SQLException
SQL_OOME
=
DbException
.
SQL_OOME
;
/**
/**
* The trace module used by this object.
* The trace module used by this object.
*/
*/
...
@@ -376,7 +378,7 @@ public class TraceObject {
...
@@ -376,7 +378,7 @@ public class TraceObject {
try
{
try
{
e
=
new
SQLException
(
"GeneralError"
,
"HY000"
,
ErrorCode
.
GENERAL_ERROR_1
,
ex
);
e
=
new
SQLException
(
"GeneralError"
,
"HY000"
,
ErrorCode
.
GENERAL_ERROR_1
,
ex
);
}
catch
(
OutOfMemoryError
|
NoClassDefFoundError
ignored
)
{
}
catch
(
OutOfMemoryError
|
NoClassDefFoundError
ignored
)
{
return
DbException
.
SQL_OOME
;
return
SQL_OOME
;
}
}
}
}
e
.
addSuppressed
(
another
);
e
.
addSuppressed
(
another
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVPlainTempResult.java
浏览文件 @
ed405433
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
*/
*/
package
org
.
h2
.
mvstore
.
db
;
package
org
.
h2
.
mvstore
.
db
;
import
java.util.Arrays
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
...
@@ -14,7 +16,6 @@ import org.h2.mvstore.MVMap.Builder;
...
@@ -14,7 +16,6 @@ import org.h2.mvstore.MVMap.Builder;
import
org.h2.result.ResultExternal
;
import
org.h2.result.ResultExternal
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueLong
;
/**
/**
* Plain temporary result.
* Plain temporary result.
...
@@ -22,14 +23,14 @@ import org.h2.value.ValueLong;
...
@@ -22,14 +23,14 @@ import org.h2.value.ValueLong;
class
MVPlainTempResult
extends
MVTempResult
{
class
MVPlainTempResult
extends
MVTempResult
{
/**
/**
* The type of the
values in the main map and keys in the index
.
* The type of the
distinct values
.
*/
*/
private
final
ValueDataType
value
Type
;
private
final
ValueDataType
distinct
Type
;
/**
/**
* Map with identities of rows as keys rows as values.
* Map with identities of rows as keys rows as values.
*/
*/
private
final
MVMap
<
Value
Long
,
ValueArray
>
map
;
private
final
MVMap
<
Long
,
ValueArray
>
map
;
/**
/**
* Counter for the identities of rows. A separate counter is used instead of
* Counter for the identities of rows. A separate counter is used instead of
...
@@ -47,7 +48,7 @@ class MVPlainTempResult extends MVTempResult {
...
@@ -47,7 +48,7 @@ class MVPlainTempResult extends MVTempResult {
/**
/**
* Cursor for the {@link #next()} method.
* Cursor for the {@link #next()} method.
*/
*/
private
Cursor
<
Value
Long
,
ValueArray
>
cursor
;
private
Cursor
<
Long
,
ValueArray
>
cursor
;
/**
/**
* Creates a shallow copy of the result.
* Creates a shallow copy of the result.
...
@@ -57,7 +58,7 @@ class MVPlainTempResult extends MVTempResult {
...
@@ -57,7 +58,7 @@ class MVPlainTempResult extends MVTempResult {
*/
*/
private
MVPlainTempResult
(
MVPlainTempResult
parent
)
{
private
MVPlainTempResult
(
MVPlainTempResult
parent
)
{
super
(
parent
);
super
(
parent
);
this
.
value
Type
=
null
;
this
.
distinct
Type
=
null
;
this
.
map
=
parent
.
map
;
this
.
map
=
parent
.
map
;
}
}
...
@@ -68,20 +69,25 @@ class MVPlainTempResult extends MVTempResult {
...
@@ -68,20 +69,25 @@ class MVPlainTempResult extends MVTempResult {
* database
* database
* @param expressions
* @param expressions
* column expressions
* column expressions
* @param visibleColumnCount
* count of visible columns
*/
*/
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
)
{
MVPlainTempResult
(
Database
database
,
Expression
[]
expressions
,
int
visibleColumnCount
)
{
super
(
database
);
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
ValueDataType
keyType
=
new
ValueDataType
(
null
,
null
,
null
);
ValueDataType
valueType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
columnCount
]);
valueType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
expressions
.
length
]);
if
(
columnCount
==
visibleColumnCount
)
{
Builder
<
ValueLong
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
ValueLong
,
ValueArray
>().
keyType
(
keyType
)
distinctType
=
valueType
;
.
valueType
(
valueType
);
}
else
{
distinctType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
visibleColumnCount
]);
}
Builder
<
Long
,
ValueArray
>
builder
=
new
MVMap
.
Builder
<
Long
,
ValueArray
>().
valueType
(
valueType
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
}
}
@Override
@Override
public
int
addRow
(
Value
[]
values
)
{
public
int
addRow
(
Value
[]
values
)
{
assert
parent
==
null
&&
index
==
null
;
assert
parent
==
null
&&
index
==
null
;
map
.
put
(
ValueLong
.
get
(
counter
++)
,
ValueArray
.
get
(
values
));
map
.
put
(
counter
++
,
ValueArray
.
get
(
values
));
return
++
rowCount
;
return
++
rowCount
;
}
}
...
@@ -98,12 +104,16 @@ class MVPlainTempResult extends MVTempResult {
...
@@ -98,12 +104,16 @@ class MVPlainTempResult extends MVTempResult {
}
}
private
void
createIndex
()
{
private
void
createIndex
()
{
Builder
<
ValueArray
,
Boolean
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
value
Type
);
Builder
<
ValueArray
,
Boolean
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>().
keyType
(
distinct
Type
);
index
=
store
.
openMap
(
"idx"
,
builder
);
index
=
store
.
openMap
(
"idx"
,
builder
);
Cursor
<
Value
Long
,
ValueArray
>
c
=
map
.
cursor
(
null
);
Cursor
<
Long
,
ValueArray
>
c
=
map
.
cursor
(
null
);
while
(
c
.
hasNext
())
{
while
(
c
.
hasNext
())
{
c
.
next
();
c
.
next
();
index
.
putIfAbsent
(
c
.
getValue
(),
true
);
ValueArray
row
=
c
.
getValue
();
if
(
columnCount
!=
visibleColumnCount
)
{
row
=
ValueArray
.
get
(
Arrays
.
copyOf
(
row
.
getList
(),
visibleColumnCount
));
}
index
.
putIfAbsent
(
row
,
true
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVSortedTempResult.java
浏览文件 @
ed405433
...
@@ -5,10 +5,12 @@
...
@@ -5,10 +5,12 @@
*/
*/
package
org
.
h2
.
mvstore
.
db
;
package
org
.
h2
.
mvstore
.
db
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.BitSet
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.expression.Expression
;
import
org.h2.expression.Expression
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.Cursor
;
import
org.h2.mvstore.Cursor
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap.Builder
;
import
org.h2.mvstore.MVMap.Builder
;
...
@@ -43,6 +45,19 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -43,6 +45,19 @@ class MVSortedTempResult extends MVTempResult {
*/
*/
private
final
MVMap
<
ValueArray
,
Long
>
map
;
private
final
MVMap
<
ValueArray
,
Long
>
map
;
/**
* The type of the distinct values.
*/
private
final
ValueDataType
distinctType
;
/**
* Optional index. This index is created only if result is distinct and
* {@code columnCount != distinctColumnCount} or if
* {@link #contains(Value[])} method is invoked. Only the root result should
* have an index if required.
*/
private
MVMap
<
ValueArray
,
Boolean
>
index
;
/**
/**
* Cursor for the {@link #next()} method.
* Cursor for the {@link #next()} method.
*/
*/
...
@@ -71,6 +86,7 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -71,6 +86,7 @@ class MVSortedTempResult extends MVTempResult {
this
.
distinct
=
parent
.
distinct
;
this
.
distinct
=
parent
.
distinct
;
this
.
indexes
=
parent
.
indexes
;
this
.
indexes
=
parent
.
indexes
;
this
.
map
=
parent
.
map
;
this
.
map
=
parent
.
map
;
this
.
distinctType
=
null
;
this
.
rowCount
=
parent
.
rowCount
;
this
.
rowCount
=
parent
.
rowCount
;
}
}
...
@@ -83,14 +99,17 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -83,14 +99,17 @@ class MVSortedTempResult extends MVTempResult {
* column expressions
* column expressions
* @param distinct
* @param distinct
* whether this result should be distinct
* whether this result should be distinct
* @param visibleColumnCount
* count of visible columns
* @param sort
* @param sort
*
sort order, or {@code null} if this result does not
*
sort order, or {@code null} if this result does not need any
*
need any
sorting
* sorting
*/
*/
MVSortedTempResult
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
SortOrder
sort
)
{
MVSortedTempResult
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
int
visibleColumnCount
,
super
(
database
);
SortOrder
sort
)
{
super
(
database
,
expressions
.
length
,
visibleColumnCount
);
this
.
distinct
=
distinct
;
this
.
distinct
=
distinct
;
int
length
=
expressions
.
length
;
int
length
=
columnCount
;
int
[]
sortTypes
=
new
int
[
length
];
int
[]
sortTypes
=
new
int
[
length
];
int
[]
indexes
;
int
[]
indexes
;
if
(
sort
!=
null
)
{
if
(
sort
!=
null
)
{
...
@@ -147,6 +166,14 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -147,6 +166,14 @@ class MVSortedTempResult extends MVTempResult {
ValueDataType
keyType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
sortTypes
);
ValueDataType
keyType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
sortTypes
);
Builder
<
ValueArray
,
Long
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Long
>().
keyType
(
keyType
);
Builder
<
ValueArray
,
Long
>
builder
=
new
MVMap
.
Builder
<
ValueArray
,
Long
>().
keyType
(
keyType
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
map
=
store
.
openMap
(
"tmp"
,
builder
);
if
(
length
==
visibleColumnCount
)
{
distinctType
=
null
;
}
else
{
distinctType
=
new
ValueDataType
(
database
.
getCompareMode
(),
database
,
new
int
[
visibleColumnCount
]);
if
(
distinct
)
{
createIndex
(
false
);
}
}
}
}
@Override
@Override
...
@@ -154,6 +181,12 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -154,6 +181,12 @@ class MVSortedTempResult extends MVTempResult {
assert
parent
==
null
;
assert
parent
==
null
;
ValueArray
key
=
getKey
(
values
);
ValueArray
key
=
getKey
(
values
);
if
(
distinct
)
{
if
(
distinct
)
{
if
(
columnCount
!=
visibleColumnCount
)
{
ValueArray
distinctRow
=
ValueArray
.
get
(
Arrays
.
copyOf
(
values
,
visibleColumnCount
));
if
(
index
.
putIfAbsent
(
distinctRow
,
true
)
!=
null
)
{
return
rowCount
;
}
}
// Add a row and increment the counter only if row does not exist
// Add a row and increment the counter only if row does not exist
if
(
map
.
putIfAbsent
(
key
,
1L
)
==
null
)
{
if
(
map
.
putIfAbsent
(
key
,
1L
)
==
null
)
{
rowCount
++;
rowCount
++;
...
@@ -172,9 +205,33 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -172,9 +205,33 @@ class MVSortedTempResult extends MVTempResult {
@Override
@Override
public
boolean
contains
(
Value
[]
values
)
{
public
boolean
contains
(
Value
[]
values
)
{
// Only parent result maintains the index
if
(
parent
!=
null
)
{
return
parent
.
contains
(
values
);
}
if
(
columnCount
!=
visibleColumnCount
)
{
if
(
index
==
null
)
{
createIndex
(
true
);
}
return
index
.
containsKey
(
ValueArray
.
get
(
values
));
}
return
map
.
containsKey
(
getKey
(
values
));
return
map
.
containsKey
(
getKey
(
values
));
}
}
private
void
createIndex
(
boolean
fill
)
{
Builder
<
ValueArray
,
Boolean
>
indexBuilder
=
new
MVMap
.
Builder
<
ValueArray
,
Boolean
>()
.
keyType
(
distinctType
);
index
=
store
.
openMap
(
"idx"
,
indexBuilder
);
if
(
fill
)
{
Cursor
<
ValueArray
,
Long
>
c
=
map
.
cursor
(
null
);
while
(
c
.
hasNext
())
{
Value
[]
v
=
getValue
(
c
.
next
().
getList
());
ValueArray
distinctRow
=
ValueArray
.
get
(
Arrays
.
copyOf
(
v
,
visibleColumnCount
));
index
.
putIfAbsent
(
distinctRow
,
true
);
}
}
}
@Override
@Override
public
synchronized
ResultExternal
createShallowCopy
()
{
public
synchronized
ResultExternal
createShallowCopy
()
{
if
(
parent
!=
null
)
{
if
(
parent
!=
null
)
{
...
@@ -198,7 +255,7 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -198,7 +255,7 @@ class MVSortedTempResult extends MVTempResult {
if
(
indexes
!=
null
)
{
if
(
indexes
!=
null
)
{
Value
[]
r
=
new
Value
[
indexes
.
length
];
Value
[]
r
=
new
Value
[
indexes
.
length
];
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
r
[
i
ndexes
[
i
]]
=
values
[
i
];
r
[
i
]
=
values
[
indexes
[
i
]
];
}
}
values
=
r
;
values
=
r
;
}
}
...
@@ -216,7 +273,7 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -216,7 +273,7 @@ class MVSortedTempResult extends MVTempResult {
if
(
indexes
!=
null
)
{
if
(
indexes
!=
null
)
{
Value
[]
r
=
new
Value
[
indexes
.
length
];
Value
[]
r
=
new
Value
[
indexes
.
length
];
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
indexes
.
length
;
i
++)
{
r
[
i
]
=
key
[
indexes
[
i
]
];
r
[
i
ndexes
[
i
]]
=
key
[
i
];
}
}
key
=
r
;
key
=
r
;
}
}
...
@@ -255,27 +312,14 @@ class MVSortedTempResult extends MVTempResult {
...
@@ -255,27 +312,14 @@ class MVSortedTempResult extends MVTempResult {
@Override
@Override
public
int
removeRow
(
Value
[]
values
)
{
public
int
removeRow
(
Value
[]
values
)
{
assert
parent
==
null
;
assert
parent
==
null
&&
distinct
;
ValueArray
key
=
getKey
(
values
);
if
(
columnCount
!=
visibleColumnCount
)
{
if
(
distinct
)
{
throw
DbException
.
getUnsupportedException
(
"removeRow()"
);
// If an entry was removed decrement the counter
if
(
map
.
remove
(
key
)
!=
null
)
{
rowCount
--;
}
}
else
{
Long
old
=
map
.
remove
(
key
);
if
(
old
!=
null
)
{
long
l
=
old
;
if
(
l
>
1
)
{
/*
* We have more than one such row. Decrement its counter by 1 and put this row
* back into map.
*/
map
.
put
(
key
,
l
-
1
);
}
}
// If an entry was removed decrement the counter
if
(
map
.
remove
(
getKey
(
values
))
!=
null
)
{
rowCount
--;
rowCount
--;
}
}
}
return
rowCount
;
return
rowCount
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVTempResult.java
浏览文件 @
ed405433
...
@@ -66,13 +66,17 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -66,13 +66,17 @@ public abstract class MVTempResult implements ResultExternal {
* expressions
* expressions
* @param distinct
* @param distinct
* is output distinct
* is output distinct
* @param visibleColumnCount
* count of visible columns
* @param sort
* @param sort
* sort order, or {@code null}
* sort order, or {@code null}
* @return temporary result
* @return temporary result
*/
*/
public
static
ResultExternal
of
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
SortOrder
sort
)
{
public
static
ResultExternal
of
(
Database
database
,
Expression
[]
expressions
,
boolean
distinct
,
return
distinct
||
sort
!=
null
?
new
MVSortedTempResult
(
database
,
expressions
,
distinct
,
sort
)
int
visibleColumnCount
,
SortOrder
sort
)
{
:
new
MVPlainTempResult
(
database
,
expressions
);
return
distinct
||
sort
!=
null
?
new
MVSortedTempResult
(
database
,
expressions
,
distinct
,
visibleColumnCount
,
sort
)
:
new
MVPlainTempResult
(
database
,
expressions
,
visibleColumnCount
);
}
}
/**
/**
...
@@ -80,6 +84,16 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -80,6 +84,16 @@ public abstract class MVTempResult implements ResultExternal {
*/
*/
final
MVStore
store
;
final
MVStore
store
;
/**
* Count of columns.
*/
final
int
columnCount
;
/**
* Count of visible columns.
*/
final
int
visibleColumnCount
;
/**
/**
* Count of rows. Used only in a root results, copies always have 0 value.
* Count of rows. Used only in a root results, copies always have 0 value.
*/
*/
...
@@ -124,6 +138,8 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -124,6 +138,8 @@ public abstract class MVTempResult implements ResultExternal {
MVTempResult
(
MVTempResult
parent
)
{
MVTempResult
(
MVTempResult
parent
)
{
this
.
parent
=
parent
;
this
.
parent
=
parent
;
this
.
store
=
parent
.
store
;
this
.
store
=
parent
.
store
;
this
.
columnCount
=
parent
.
columnCount
;
this
.
visibleColumnCount
=
parent
.
visibleColumnCount
;
this
.
tempFileDeleter
=
null
;
this
.
tempFileDeleter
=
null
;
this
.
closeable
=
null
;
this
.
closeable
=
null
;
this
.
fileRef
=
null
;
this
.
fileRef
=
null
;
...
@@ -134,8 +150,12 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -134,8 +150,12 @@ public abstract class MVTempResult implements ResultExternal {
*
*
* @param database
* @param database
* database
* database
* @param columnCount
* count of columns
* @param visibleColumnCount
* count of visible columns
*/
*/
MVTempResult
(
Database
database
)
{
MVTempResult
(
Database
database
,
int
columnCount
,
int
visibleColumnCount
)
{
try
{
try
{
String
fileName
=
FileUtils
.
createTempFile
(
"h2tmp"
,
Constants
.
SUFFIX_TEMP_FILE
,
false
,
true
);
String
fileName
=
FileUtils
.
createTempFile
(
"h2tmp"
,
Constants
.
SUFFIX_TEMP_FILE
,
false
,
true
);
Builder
builder
=
new
MVStore
.
Builder
().
fileName
(
fileName
);
Builder
builder
=
new
MVStore
.
Builder
().
fileName
(
fileName
);
...
@@ -144,6 +164,8 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -144,6 +164,8 @@ public abstract class MVTempResult implements ResultExternal {
builder
.
encryptionKey
(
MVTableEngine
.
decodePassword
(
key
));
builder
.
encryptionKey
(
MVTableEngine
.
decodePassword
(
key
));
}
}
store
=
builder
.
open
();
store
=
builder
.
open
();
this
.
columnCount
=
columnCount
;
this
.
visibleColumnCount
=
visibleColumnCount
;
tempFileDeleter
=
database
.
getTempFileDeleter
();
tempFileDeleter
=
database
.
getTempFileDeleter
();
closeable
=
new
CloseImpl
(
store
,
fileName
);
closeable
=
new
CloseImpl
(
store
,
fileName
);
fileRef
=
tempFileDeleter
.
addFile
(
closeable
,
this
);
fileRef
=
tempFileDeleter
.
addFile
(
closeable
,
this
);
...
@@ -186,9 +208,4 @@ public abstract class MVTempResult implements ResultExternal {
...
@@ -186,9 +208,4 @@ public abstract class MVTempResult implements ResultExternal {
tempFileDeleter
.
deleteFile
(
fileRef
,
closeable
);
tempFileDeleter
.
deleteFile
(
fileRef
,
closeable
);
}
}
@Override
public
void
done
()
{
// Do nothing
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
ed405433
...
@@ -42,7 +42,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -42,7 +42,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
private
int
offset
;
private
int
offset
;
private
int
limit
=
-
1
;
private
int
limit
=
-
1
;
private
ResultExternal
external
;
private
ResultExternal
external
;
private
int
diskOffset
;
private
boolean
distinct
;
private
boolean
distinct
;
private
boolean
randomAccess
;
private
boolean
randomAccess
;
private
boolean
closed
;
private
boolean
closed
;
...
@@ -157,7 +156,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -157,7 +156,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
copy
.
offset
=
0
;
copy
.
offset
=
0
;
copy
.
limit
=
-
1
;
copy
.
limit
=
-
1
;
copy
.
external
=
e2
;
copy
.
external
=
e2
;
copy
.
diskOffset
=
this
.
diskOffset
;
return
copy
;
return
copy
;
}
}
...
@@ -194,6 +192,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -194,6 +192,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
if
(!
distinct
)
{
if
(!
distinct
)
{
DbException
.
throwInternalError
();
DbException
.
throwInternalError
();
}
}
assert
values
.
length
==
visibleColumnCount
;
if
(
distinctRows
!=
null
)
{
if
(
distinctRows
!=
null
)
{
ValueArray
array
=
ValueArray
.
get
(
values
);
ValueArray
array
=
ValueArray
.
get
(
values
);
distinctRows
.
remove
(
array
);
distinctRows
.
remove
(
array
);
...
@@ -211,6 +210,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -211,6 +210,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
*/
*/
@Override
@Override
public
boolean
containsDistinct
(
Value
[]
values
)
{
public
boolean
containsDistinct
(
Value
[]
values
)
{
assert
values
.
length
==
visibleColumnCount
;
if
(
external
!=
null
)
{
if
(
external
!=
null
)
{
return
external
.
contains
(
values
);
return
external
.
contains
(
values
);
}
}
...
@@ -231,11 +231,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -231,11 +231,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
currentRow
=
null
;
currentRow
=
null
;
if
(
external
!=
null
)
{
if
(
external
!=
null
)
{
external
.
reset
();
external
.
reset
();
if
(
diskOffset
>
0
)
{
for
(
int
i
=
0
;
i
<
diskOffset
;
i
++)
{
external
.
next
();
}
}
}
}
}
}
...
@@ -293,7 +288,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -293,7 +288,7 @@ public class LocalResult implements ResultInterface, ResultTarget {
private
void
createExternalResult
()
{
private
void
createExternalResult
()
{
Database
database
=
session
.
getDatabase
();
Database
database
=
session
.
getDatabase
();
external
=
database
.
isMVStore
()
external
=
database
.
isMVStore
()
?
MVTempResult
.
of
(
database
,
expressions
,
distinct
,
sort
)
?
MVTempResult
.
of
(
database
,
expressions
,
distinct
,
visibleColumnCount
,
sort
)
:
new
ResultTempTable
(
session
,
expressions
,
distinct
,
sort
);
:
new
ResultTempTable
(
session
,
expressions
,
distinct
,
sort
);
}
}
...
@@ -318,19 +313,19 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -318,19 +313,19 @@ public class LocalResult implements ResultInterface, ResultTarget {
}
else
{
}
else
{
rowCount
=
external
.
addRow
(
values
);
rowCount
=
external
.
addRow
(
values
);
}
}
return
;
}
else
{
}
rows
.
add
(
values
);
rows
.
add
(
values
);
rowCount
++;
rowCount
++;
if
(
rows
.
size
()
>
maxMemoryRows
)
{
if
(
rows
.
size
()
>
maxMemoryRows
)
{
if
(
external
==
null
)
{
createExternalResult
();
}
addRowsToDisk
();
addRowsToDisk
();
}
}
}
}
}
private
void
addRowsToDisk
()
{
private
void
addRowsToDisk
()
{
if
(
external
==
null
)
{
createExternalResult
();
}
rowCount
=
external
.
addRows
(
rows
);
rowCount
=
external
.
addRows
(
rows
);
rows
.
clear
();
rows
.
clear
();
}
}
...
@@ -344,52 +339,76 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -344,52 +339,76 @@ public class LocalResult implements ResultInterface, ResultTarget {
* This method is called after all rows have been added.
* This method is called after all rows have been added.
*/
*/
public
void
done
()
{
public
void
done
()
{
if
(
external
!=
null
)
{
addRowsToDisk
();
}
else
{
if
(
distinct
)
{
if
(
distinct
)
{
if
(
distinctRows
!=
null
)
{
rows
=
distinctRows
.
values
();
rows
=
distinctRows
.
values
();
}
if
(
sort
!=
null
)
{
if
(
offset
>
0
||
limit
>
0
)
{
sort
.
sort
(
rows
,
offset
,
limit
<
0
?
rows
.
size
()
:
limit
);
}
else
{
}
else
{
if
(
external
!=
null
&&
sort
!=
null
)
{
sort
.
sort
(
rows
);
// external sort
ResultExternal
temp
=
external
;
external
=
null
;
temp
.
reset
();
rows
=
Utils
.
newSmallArrayList
();
// TODO use offset directly if possible
while
(
true
)
{
Value
[]
list
=
temp
.
next
();
if
(
list
==
null
)
{
break
;
}
}
if
(
external
==
null
)
{
createExternalResult
();
}
}
rows
.
add
(
list
);
}
if
(
rows
.
size
()
>
maxMemoryRows
)
{
applyOffsetAndLimit
();
rowCount
=
external
.
addRows
(
rows
);
reset
();
}
private
void
applyOffsetAndLimit
()
{
int
offset
=
Math
.
max
(
this
.
offset
,
0
);
int
limit
=
this
.
limit
;
if
(
offset
==
0
&&
limit
<
0
||
rowCount
==
0
)
{
return
;
}
boolean
clearAll
=
offset
>=
rowCount
||
limit
==
0
;
if
(!
clearAll
)
{
int
remaining
=
rowCount
-
offset
;
limit
=
limit
<
0
?
remaining
:
Math
.
min
(
remaining
,
limit
);
if
(
offset
==
0
&&
remaining
<=
limit
)
{
return
;
}
}
else
{
limit
=
0
;
}
distinctRows
=
null
;
rowCount
=
limit
;
if
(
external
==
null
)
{
if
(
clearAll
)
{
rows
.
clear
();
rows
.
clear
();
return
;
}
}
// avoid copying the whole array for each row
rows
=
new
ArrayList
<>(
rows
.
subList
(
offset
,
offset
+
limit
));
}
else
{
if
(
clearAll
)
{
external
.
close
();
external
=
null
;
return
;
}
}
temp
.
close
();
trimExternal
(
offset
,
limit
);
// the remaining data in rows is written in the following
// lines
}
}
}
}
private
void
trimExternal
(
int
offset
,
int
limit
)
{
ResultExternal
temp
=
external
;
external
=
null
;
temp
.
reset
();
while
(--
offset
>=
0
)
{
temp
.
next
();
}
}
if
(
external
!=
null
)
{
while
(--
limit
>=
0
)
{
rows
.
add
(
temp
.
next
());
if
(
rows
.
size
()
>
maxMemoryRows
)
{
addRowsToDisk
();
addRowsToDisk
();
external
.
done
();
}
else
{
if
(
sort
!=
null
)
{
if
(
offset
>
0
||
limit
>
0
)
{
sort
.
sort
(
rows
,
offset
,
limit
<
0
?
rows
.
size
()
:
limit
);
}
else
{
sort
.
sort
(
rows
);
}
}
}
}
if
(
external
!=
null
)
{
addRowsToDisk
();
}
}
applyOffset
();
temp
.
close
();
applyLimit
();
reset
();
}
}
@Override
@Override
...
@@ -411,24 +430,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -411,24 +430,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
this
.
limit
=
limit
;
this
.
limit
=
limit
;
}
}
private
void
applyLimit
()
{
if
(
limit
<
0
)
{
return
;
}
if
(
external
==
null
)
{
if
(
rows
.
size
()
>
limit
)
{
rows
=
new
ArrayList
<>(
rows
.
subList
(
0
,
limit
));
rowCount
=
limit
;
distinctRows
=
null
;
}
}
else
{
if
(
limit
<
rowCount
)
{
rowCount
=
limit
;
distinctRows
=
null
;
}
}
}
@Override
@Override
public
boolean
needToClose
()
{
public
boolean
needToClose
()
{
return
external
!=
null
;
return
external
!=
null
;
...
@@ -502,31 +503,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
...
@@ -502,31 +503,6 @@ public class LocalResult implements ResultInterface, ResultTarget {
this
.
offset
=
offset
;
this
.
offset
=
offset
;
}
}
private
void
applyOffset
()
{
if
(
offset
<=
0
)
{
return
;
}
if
(
external
==
null
)
{
if
(
offset
>=
rows
.
size
())
{
rows
.
clear
();
rowCount
=
0
;
}
else
{
// avoid copying the whole array for each row
int
remove
=
Math
.
min
(
offset
,
rows
.
size
());
rows
=
new
ArrayList
<>(
rows
.
subList
(
remove
,
rows
.
size
()));
rowCount
-=
remove
;
}
}
else
{
if
(
offset
>=
rowCount
)
{
rowCount
=
0
;
}
else
{
diskOffset
=
offset
;
rowCount
-=
offset
;
}
}
distinctRows
=
null
;
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
super
.
toString
()
+
" columns: "
+
visibleColumnCount
+
return
super
.
toString
()
+
" columns: "
+
visibleColumnCount
+
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/ResultExternal.java
浏览文件 @
ed405433
...
@@ -42,11 +42,6 @@ public interface ResultExternal {
...
@@ -42,11 +42,6 @@ public interface ResultExternal {
*/
*/
int
addRows
(
ArrayList
<
Value
[]>
rows
);
int
addRows
(
ArrayList
<
Value
[]>
rows
);
/**
* This method is called after all rows have been added.
*/
void
done
();
/**
/**
* Close this object and delete the temporary file.
* Close this object and delete the temporary file.
*/
*/
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/ResultTempTable.java
浏览文件 @
ed405433
...
@@ -309,11 +309,6 @@ public class ResultTempTable implements ResultExternal {
...
@@ -309,11 +309,6 @@ public class ResultTempTable implements ResultExternal {
}
}
}
}
@Override
public
void
done
()
{
// nothing to do
}
@Override
@Override
public
Value
[]
next
()
{
public
Value
[]
next
()
{
if
(
resultCursor
==
null
)
{
if
(
resultCursor
==
null
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/store/Data.java
浏览文件 @
ed405433
...
@@ -738,7 +738,7 @@ public class Data {
...
@@ -738,7 +738,7 @@ public class Data {
case
Value
.
TIMESTAMP
:
{
case
Value
.
TIMESTAMP
:
{
return
ValueTimestamp
.
fromMillisNanos
(
return
ValueTimestamp
.
fromMillisNanos
(
DateTimeUtils
.
getTimeUTCWithoutDst
(
readVarLong
()),
DateTimeUtils
.
getTimeUTCWithoutDst
(
readVarLong
()),
readVarInt
());
readVarInt
()
%
1_000_000
);
}
}
case
Value
.
TIMESTAMP_TZ
:
{
case
Value
.
TIMESTAMP_TZ
:
{
long
dateValue
=
readVarLong
();
long
dateValue
=
readVarLong
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/TestScript.java
浏览文件 @
ed405433
...
@@ -99,6 +99,7 @@ public class TestScript extends TestDb {
...
@@ -99,6 +99,7 @@ public class TestScript extends TestDb {
testScript
(
"testScript.sql"
);
testScript
(
"testScript.sql"
);
testScript
(
"comments.sql"
);
testScript
(
"comments.sql"
);
testScript
(
"derived-column-names.sql"
);
testScript
(
"derived-column-names.sql"
);
testScript
(
"distinct.sql"
);
testScript
(
"dual.sql"
);
testScript
(
"dual.sql"
);
testScript
(
"indexes.sql"
);
testScript
(
"indexes.sql"
);
testScript
(
"information_schema.sql"
);
testScript
(
"information_schema.sql"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/distinct.sql
0 → 100644
浏览文件 @
ed405433
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE
TABLE
TEST
(
ID
BIGINT
,
NAME
VARCHAR
);
>
ok
INSERT
INTO
TEST
VALUES
(
1
,
'a'
),
(
2
,
'B'
),
(
3
,
'c'
),
(
1
,
'a'
);
>
update
count
:
4
CREATE
TABLE
TEST2
(
ID2
BIGINT
);
>
ok
INSERT
INTO
TEST2
VALUES
(
1
),
(
2
);
>
update
count
:
2
SELECT
DISTINCT
NAME
FROM
TEST
ORDER
BY
NAME
;
>
NAME
>
----
>
B
>
a
>
c
>
rows
(
ordered
):
3
SELECT
DISTINCT
NAME
FROM
TEST
ORDER
BY
LOWER
(
NAME
);
>
NAME
>
----
>
a
>
B
>
c
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
ID
;
>
ID
>
--
>
1
>
2
>
3
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
-
ID
-
1
;
>
ID
>
--
>
3
>
2
>
1
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
(
-
ID
+
10
)
>
0
AND
NOT
(
ID
=
0
),
ID
;
>
ID
>
--
>
1
>
2
>
3
>
rows
(
ordered
):
3
SELECT
DISTINCT
NAME
,
ID
+
1
FROM
TEST
ORDER
BY
UPPER
(
NAME
)
||
(
ID
+
1
);
>
NAME
ID
+
1
>
---- ------
>
a
2
>
B
3
>
c
4
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
NAME
;
>
exception
ORDER_BY_NOT_IN_RESULT
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
CURRENT_TIMESTAMP
;
>
exception
ORDER_BY_NOT_IN_RESULT
SET
MODE
MySQL
;
>
ok
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
NAME
;
>
ID
>
--
>
2
>
1
>
3
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
ORDER
BY
LOWER
(
NAME
);
>
ID
>
--
>
1
>
2
>
3
>
rows
(
ordered
):
3
SELECT
DISTINCT
ID
FROM
TEST
JOIN
TEST2
ON
ID
=
ID2
ORDER
BY
LOWER
(
NAME
);
>
ID
>
--
>
1
>
2
>
rows
(
ordered
):
2
SET
MODE
Regular
;
>
ok
DROP
TABLE
TEST
;
>
ok
DROP
TABLE
TEST2
;
>
ok
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/testScript.sql
浏览文件 @
ed405433
...
@@ -3077,17 +3077,17 @@ SELECT t.f1, t.f2 FROM test t ORDER BY t.f2;
...
@@ -3077,17 +3077,17 @@ SELECT t.f1, t.f2 FROM test t ORDER BY t.f2;
> abc 333
> abc 333
> rows (ordered): 3
> rows (ordered): 3
SELECT t1.f1, t1.f2, t2.f1, t2.f2 FROM test t1, test t2 ORDER BY t2.f2;
SELECT t1.f1, t1.f2, t2.f1, t2.f2 FROM test t1, test t2 ORDER BY t2.f2
, t1.f2
;
> F1 F2 F1 F2
> F1 F2 F1 F2
> --- --- --- ---
> --- --- --- ---
> abc 222 abc 111
> abc 111 abc 111
> abc 111 abc 111
> abc 222 abc 111
> abc 333 abc 111
> abc 333 abc 111
> abc 222 abc 222
> abc 111 abc 222
> abc 111 abc 222
> abc 222 abc 222
> abc 333 abc 222
> abc 333 abc 222
> abc 222 abc 333
> abc 111 abc 333
> abc 111 abc 333
> abc 222 abc 333
> abc 333 abc 333
> abc 333 abc 333
> rows (ordered): 9
> rows (ordered): 9
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论