Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
a22f1ea3
Unverified
提交
a22f1ea3
authored
6 年前
作者:
Evgenij Ryazanov
提交者:
GitHub
6 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1611 from katzyn/row
Handle null elements in array and row values in comparison operations properly
上级
eeace0e1
6bc29540
显示空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
535 行增加
和
208 行删除
+535
-208
Database.java
h2/src/main/org/h2/engine/Database.java
+20
-2
Comparison.java
h2/src/main/org/h2/expression/condition/Comparison.java
+75
-32
ConditionIn.java
h2/src/main/org/h2/expression/condition/ConditionIn.java
+10
-13
ConditionInConstantSet.java
...n/org/h2/expression/condition/ConditionInConstantSet.java
+16
-10
ConditionInParameter.java
...ain/org/h2/expression/condition/ConditionInParameter.java
+11
-16
ConditionInSelect.java
...c/main/org/h2/expression/condition/ConditionInSelect.java
+41
-26
LocalResult.java
h2/src/main/org/h2/result/LocalResult.java
+8
-0
LocalResultImpl.java
h2/src/main/org/h2/result/LocalResultImpl.java
+23
-0
Value.java
h2/src/main/org/h2/value/Value.java
+44
-2
ValueArray.java
h2/src/main/org/h2/value/ValueArray.java
+2
-46
ValueCollectionBase.java
h2/src/main/org/h2/value/ValueCollectionBase.java
+126
-0
ValueNull.java
h2/src/main/org/h2/value/ValueNull.java
+5
-0
ValueRow.java
h2/src/main/org/h2/value/ValueRow.java
+2
-47
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+1
-1
TestSubqueryPerformanceOnLazyExecutionMode.java
...2/test/db/TestSubqueryPerformanceOnLazyExecutionMode.java
+6
-1
array.sql
h2/src/test/org/h2/test/scripts/datatypes/array.sql
+63
-0
row.sql
h2/src/test/org/h2/test/scripts/datatypes/row.sql
+63
-0
select.sql
h2/src/test/org/h2/test/scripts/dml/select.sql
+5
-2
TestNestedJoins.java
h2/src/test/org/h2/test/synth/TestNestedJoins.java
+7
-5
TestOuterJoins.java
h2/src/test/org/h2/test/synth/TestOuterJoins.java
+7
-5
没有找到文件。
h2/src/main/org/h2/engine/Database.java
浏览文件 @
a22f1ea3
...
@@ -412,8 +412,8 @@ public class Database implements DataHandler {
...
@@ -412,8 +412,8 @@ public class Database implements DataHandler {
}
}
/**
/**
* Compare two values with the current comparison mode. The values may
not
* Compare two values with the current comparison mode. The values may
have
*
be of the same type
.
*
different data types including NULL
.
*
*
* @param a the first value
* @param a the first value
* @param b the second value
* @param b the second value
...
@@ -424,6 +424,24 @@ public class Database implements DataHandler {
...
@@ -424,6 +424,24 @@ public class Database implements DataHandler {
return
a
.
compareTo
(
b
,
mode
,
compareMode
);
return
a
.
compareTo
(
b
,
mode
,
compareMode
);
}
}
/**
* Compare two values with the current comparison mode. The values may have
* different data types including NULL.
*
* @param v the other value
* @param databaseMode the database mode
* @param compareMode the compare mode
* @param a the first value
* @param b the second value
* @param forEquality perform only check for equality (= or <>)
* @return 0 if both values are equal, -1 if the first value is smaller, 1
* if the second value is larger, {@link Integer#MIN_VALUE} if order
* is not defined due to NULL comparison
*/
public
int
compareWithNull
(
Value
a
,
Value
b
,
boolean
forEquality
)
{
return
a
.
compareWithNull
(
b
,
forEquality
,
mode
,
compareMode
);
}
/**
/**
* Compare two values with the current comparison mode. The values must be
* Compare two values with the current comparison mode. The values must be
* of the same type.
* of the same type.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/condition/Comparison.java
浏览文件 @
a22f1ea3
...
@@ -283,58 +283,101 @@ public class Comparison extends Condition {
...
@@ -283,58 +283,101 @@ public class Comparison extends Condition {
}
}
return
ValueBoolean
.
get
(
result
);
return
ValueBoolean
.
get
(
result
);
}
}
if
(
l
==
ValueNull
.
INSTANCE
)
{
// Optimization: do not evaluate right if not necessary
if
((
compareType
&
NULL_SAFE
)
==
0
)
{
if
(
l
==
ValueNull
.
INSTANCE
&&
(
compareType
&
NULL_SAFE
)
==
0
)
{
return
ValueNull
.
INSTANCE
;
}
}
Value
r
=
right
.
getValue
(
session
);
if
(
r
==
ValueNull
.
INSTANCE
)
{
if
((
compareType
&
NULL_SAFE
)
==
0
)
{
return
ValueNull
.
INSTANCE
;
return
ValueNull
.
INSTANCE
;
}
}
}
return
compare
(
database
,
l
,
right
.
getValue
(
session
),
compareType
);
return
ValueBoolean
.
get
(
compareNotNull
(
database
,
l
,
r
,
compareType
));
}
}
/**
/**
* Compare two values
, given the values are not NULL
.
* Compare two values.
*
*
* @param database the database
* @param database the database
* @param l the first value
* @param l the first value
* @param r the second value
* @param r the second value
* @param compareType the compare type
* @param compareType the compare type
* @return true if the comparison indicated by the comparison type evaluates
* @return result of comparison, either TRUE, FALSE, or NULL
* to true
*/
*/
static
boolean
compareNotNull
(
Database
database
,
Value
l
,
Value
r
,
static
Value
compare
(
Database
database
,
Value
l
,
Value
r
,
int
compareType
)
{
int
compareType
)
{
Value
result
;
boolean
result
;
switch
(
compareType
)
{
switch
(
compareType
)
{
case
EQUAL:
case
EQUAL:
{
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
true
);
if
(
cmp
==
0
)
{
result
=
ValueBoolean
.
TRUE
;
}
else
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
FALSE
;
}
break
;
}
case
EQUAL_NULL_SAFE:
case
EQUAL_NULL_SAFE:
result
=
database
.
areEqual
(
l
,
r
);
result
=
ValueBoolean
.
get
(
database
.
areEqual
(
l
,
r
)
);
break
;
break
;
case
NOT_EQUAL:
case
NOT_EQUAL:
{
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
true
);
if
(
cmp
==
0
)
{
result
=
ValueBoolean
.
FALSE
;
}
else
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
TRUE
;
}
break
;
}
case
NOT_EQUAL_NULL_SAFE:
case
NOT_EQUAL_NULL_SAFE:
result
=
!
database
.
areEqual
(
l
,
r
);
result
=
ValueBoolean
.
get
(!
database
.
areEqual
(
l
,
r
)
);
break
;
break
;
case
BIGGER_EQUAL:
case
BIGGER_EQUAL:
{
result
=
database
.
compare
(
l
,
r
)
>=
0
;
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
false
);
if
(
cmp
>=
0
)
{
result
=
ValueBoolean
.
TRUE
;
}
else
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
FALSE
;
}
break
;
break
;
case
BIGGER:
}
result
=
database
.
compare
(
l
,
r
)
>
0
;
case
BIGGER:
{
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
false
);
if
(
cmp
>
0
)
{
result
=
ValueBoolean
.
TRUE
;
}
else
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
FALSE
;
}
break
;
break
;
case
SMALLER_EQUAL:
}
result
=
database
.
compare
(
l
,
r
)
<=
0
;
case
SMALLER_EQUAL:
{
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
false
);
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
get
(
cmp
<=
0
);
}
break
;
break
;
case
SMALLER:
}
result
=
database
.
compare
(
l
,
r
)
<
0
;
case
SMALLER:
{
int
cmp
=
database
.
compareWithNull
(
l
,
r
,
false
);
if
(
cmp
==
Integer
.
MIN_VALUE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
result
=
ValueBoolean
.
get
(
cmp
<
0
);
}
break
;
break
;
}
case
SPATIAL_INTERSECTS:
{
case
SPATIAL_INTERSECTS:
{
if
(
l
==
ValueNull
.
INSTANCE
||
r
==
ValueNull
.
INSTANCE
)
{
result
=
ValueNull
.
INSTANCE
;
}
else
{
ValueGeometry
lg
=
(
ValueGeometry
)
l
.
convertTo
(
Value
.
GEOMETRY
);
ValueGeometry
lg
=
(
ValueGeometry
)
l
.
convertTo
(
Value
.
GEOMETRY
);
ValueGeometry
rg
=
(
ValueGeometry
)
r
.
convertTo
(
Value
.
GEOMETRY
);
ValueGeometry
rg
=
(
ValueGeometry
)
r
.
convertTo
(
Value
.
GEOMETRY
);
result
=
lg
.
intersectsBoundingBox
(
rg
);
result
=
ValueBoolean
.
get
(
lg
.
intersectsBoundingBox
(
rg
));
}
break
;
break
;
}
}
default
:
default
:
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/condition/ConditionIn.java
浏览文件 @
a22f1ea3
...
@@ -49,8 +49,8 @@ public class ConditionIn extends Condition {
...
@@ -49,8 +49,8 @@ public class ConditionIn extends Condition {
@Override
@Override
public
Value
getValue
(
Session
session
)
{
public
Value
getValue
(
Session
session
)
{
Value
l
=
left
.
getValue
(
session
);
Value
l
=
left
.
getValue
(
session
);
if
(
l
==
ValueNull
.
INSTANCE
)
{
if
(
l
.
containsNull
()
)
{
return
l
;
return
ValueNull
.
INSTANCE
;
}
}
int
size
=
valueList
.
size
();
int
size
=
valueList
.
size
();
if
(
size
==
1
)
{
if
(
size
==
1
)
{
...
@@ -59,24 +59,21 @@ public class ConditionIn extends Condition {
...
@@ -59,24 +59,21 @@ public class ConditionIn extends Condition {
return
ConditionInParameter
.
getValue
(
database
,
l
,
e
.
getValue
(
session
));
return
ConditionInParameter
.
getValue
(
database
,
l
,
e
.
getValue
(
session
));
}
}
}
}
boolean
result
=
false
;
boolean
hasNull
=
false
;
boolean
hasNull
=
false
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Expression
e
=
valueList
.
get
(
i
);
Expression
e
=
valueList
.
get
(
i
);
Value
r
=
e
.
getValue
(
session
);
Value
r
=
e
.
getValue
(
session
);
if
(
r
==
ValueNull
.
INSTANCE
)
{
Value
cmp
=
Comparison
.
compare
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
if
(
cmp
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
hasNull
=
true
;
}
else
{
}
else
if
(
cmp
==
ValueBoolean
.
TRUE
)
{
result
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
return
cmp
;
if
(
result
)
{
break
;
}
}
}
}
}
if
(
!
result
&&
hasNull
)
{
if
(
hasNull
)
{
return
ValueNull
.
INSTANCE
;
return
ValueNull
.
INSTANCE
;
}
}
return
ValueBoolean
.
get
(
result
)
;
return
ValueBoolean
.
FALSE
;
}
}
@Override
@Override
...
@@ -114,7 +111,7 @@ public class ConditionIn extends Condition {
...
@@ -114,7 +111,7 @@ public class ConditionIn extends Condition {
ArrayList
<
Expression
>
list
=
new
ArrayList
<>(
ri
.
getRowCount
());
ArrayList
<
Expression
>
list
=
new
ArrayList
<>(
ri
.
getRowCount
());
while
(
ri
.
next
())
{
while
(
ri
.
next
())
{
Value
v
=
ri
.
currentRow
()[
0
];
Value
v
=
ri
.
currentRow
()[
0
];
if
(
v
!=
ValueNull
.
INSTANCE
)
{
if
(
!
v
.
containsNull
()
)
{
allValuesNull
=
false
;
allValuesNull
=
false
;
}
}
list
.
add
(
ValueExpression
.
get
(
v
));
list
.
add
(
ValueExpression
.
get
(
v
));
...
@@ -129,7 +126,7 @@ public class ConditionIn extends Condition {
...
@@ -129,7 +126,7 @@ public class ConditionIn extends Condition {
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Expression
e
=
valueList
.
get
(
i
);
Expression
e
=
valueList
.
get
(
i
);
e
=
e
.
optimize
(
session
);
e
=
e
.
optimize
(
session
);
if
(
e
.
isConstant
()
&&
e
.
getValue
(
session
)
!=
ValueNull
.
INSTANCE
)
{
if
(
e
.
isConstant
()
&&
!
e
.
getValue
(
session
).
containsNull
()
)
{
allValuesNull
=
false
;
allValuesNull
=
false
;
}
}
if
(
allValuesConstant
&&
!
e
.
isConstant
())
{
if
(
allValuesConstant
&&
!
e
.
isConstant
())
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/condition/ConditionInConstantSet.java
浏览文件 @
a22f1ea3
...
@@ -35,6 +35,7 @@ public class ConditionInConstantSet extends Condition {
...
@@ -35,6 +35,7 @@ public class ConditionInConstantSet extends Condition {
private
Expression
left
;
private
Expression
left
;
private
final
ArrayList
<
Expression
>
valueList
;
private
final
ArrayList
<
Expression
>
valueList
;
private
final
TreeSet
<
Value
>
valueSet
;
private
final
TreeSet
<
Value
>
valueSet
;
private
boolean
hasNull
;
private
final
int
type
;
private
final
int
type
;
private
ExtTypeInfo
extTypeInfo
;
private
ExtTypeInfo
extTypeInfo
;
...
@@ -58,28 +59,33 @@ public class ConditionInConstantSet extends Condition {
...
@@ -58,28 +59,33 @@ public class ConditionInConstantSet extends Condition {
if
(
type
==
Value
.
ENUM
)
{
if
(
type
==
Value
.
ENUM
)
{
extTypeInfo
=
((
ExpressionColumn
)
left
).
getColumn
().
getExtTypeInfo
();
extTypeInfo
=
((
ExpressionColumn
)
left
).
getColumn
().
getExtTypeInfo
();
for
(
Expression
expression
:
valueList
)
{
for
(
Expression
expression
:
valueList
)
{
valueSet
.
add
(
extTypeInfo
.
cast
(
expression
.
getValue
(
session
)));
add
(
extTypeInfo
.
cast
(
expression
.
getValue
(
session
)));
}
}
}
else
{
}
else
{
for
(
Expression
expression
:
valueList
)
{
for
(
Expression
expression
:
valueList
)
{
valueSet
.
add
(
expression
.
getValue
(
session
).
convertTo
(
type
,
mode
));
add
(
expression
.
getValue
(
session
).
convertTo
(
type
,
mode
));
}
}
}
}
}
}
private
void
add
(
Value
v
)
{
if
(
v
.
containsNull
())
{
hasNull
=
true
;
}
else
{
valueSet
.
add
(
v
);
}
}
@Override
@Override
public
Value
getValue
(
Session
session
)
{
public
Value
getValue
(
Session
session
)
{
Value
x
=
left
.
getValue
(
session
);
Value
x
=
left
.
getValue
(
session
);
if
(
x
==
ValueNull
.
INSTANCE
)
{
if
(
x
.
containsNull
()
)
{
return
x
;
return
x
;
}
}
boolean
result
=
valueSet
.
contains
(
x
);
boolean
result
=
valueSet
.
contains
(
x
);
if
(!
result
)
{
if
(!
result
&&
hasNull
)
{
boolean
setHasNull
=
valueSet
.
contains
(
ValueNull
.
INSTANCE
);
if
(
setHasNull
)
{
return
ValueNull
.
INSTANCE
;
return
ValueNull
.
INSTANCE
;
}
}
}
return
ValueBoolean
.
get
(
result
);
return
ValueBoolean
.
get
(
result
);
}
}
...
@@ -168,9 +174,9 @@ public class ConditionInConstantSet extends Condition {
...
@@ -168,9 +174,9 @@ public class ConditionInConstantSet extends Condition {
if
(
add
.
isConstant
())
{
if
(
add
.
isConstant
())
{
valueList
.
add
(
add
);
valueList
.
add
(
add
);
if
(
type
==
Value
.
ENUM
)
{
if
(
type
==
Value
.
ENUM
)
{
valueSet
.
add
(
add
.
getValue
(
session
).
convertToEnum
(
extTypeInfo
));
add
(
add
.
getValue
(
session
).
convertToEnum
(
extTypeInfo
));
}
else
{
}
else
{
valueSet
.
add
(
add
.
getValue
(
session
).
convertTo
(
type
,
session
.
getDatabase
().
getMode
()));
add
(
add
.
getValue
(
session
).
convertTo
(
type
,
session
.
getDatabase
().
getMode
()));
}
}
return
this
;
return
this
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/condition/ConditionInParameter.java
浏览文件 @
a22f1ea3
...
@@ -66,38 +66,33 @@ public class ConditionInParameter extends Condition {
...
@@ -66,38 +66,33 @@ public class ConditionInParameter extends Condition {
private
final
Parameter
parameter
;
private
final
Parameter
parameter
;
static
Value
getValue
(
Database
database
,
Value
l
,
Value
value
)
{
static
Value
getValue
(
Database
database
,
Value
l
,
Value
value
)
{
boolean
result
=
false
;
boolean
hasNull
=
false
;
boolean
hasNull
=
false
;
if
(
value
==
ValueNull
.
INSTANCE
)
{
if
(
value
.
containsNull
()
)
{
hasNull
=
true
;
hasNull
=
true
;
}
else
if
(
value
.
getType
()
==
Value
.
RESULT_SET
)
{
}
else
if
(
value
.
getType
()
==
Value
.
RESULT_SET
)
{
for
(
ResultInterface
ri
=
value
.
getResult
();
ri
.
next
();)
{
for
(
ResultInterface
ri
=
value
.
getResult
();
ri
.
next
();)
{
Value
r
=
ri
.
currentRow
()[
0
];
Value
r
=
ri
.
currentRow
()[
0
];
if
(
r
==
ValueNull
.
INSTANCE
)
{
Value
cmp
=
Comparison
.
compare
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
if
(
cmp
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
hasNull
=
true
;
}
else
{
}
else
if
(
cmp
==
ValueBoolean
.
TRUE
)
{
result
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
return
cmp
;
if
(
result
)
{
break
;
}
}
}
}
}
}
else
{
}
else
{
for
(
Value
r
:
((
ValueArray
)
value
.
convertTo
(
Value
.
ARRAY
)).
getList
())
{
for
(
Value
r
:
((
ValueArray
)
value
.
convertTo
(
Value
.
ARRAY
)).
getList
())
{
if
(
r
==
ValueNull
.
INSTANCE
)
{
Value
cmp
=
Comparison
.
compare
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
if
(
cmp
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
hasNull
=
true
;
}
else
{
}
else
if
(
cmp
==
ValueBoolean
.
TRUE
)
{
result
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
Comparison
.
EQUAL
);
return
cmp
;
if
(
result
)
{
break
;
}
}
}
}
}
}
}
if
(
!
result
&&
hasNull
)
{
if
(
hasNull
)
{
return
ValueNull
.
INSTANCE
;
return
ValueNull
.
INSTANCE
;
}
}
return
ValueBoolean
.
get
(
result
)
;
return
ValueBoolean
.
FALSE
;
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/condition/ConditionInSelect.java
浏览文件 @
a22f1ea3
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
*/
*/
package
org
.
h2
.
expression
.
condition
;
package
org
.
h2
.
expression
.
condition
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Query
;
import
org.h2.command.dml.Query
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
...
@@ -12,15 +13,16 @@ import org.h2.expression.Expression;
...
@@ -12,15 +13,16 @@ 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.index.IndexCondition
;
import
org.h2.index.IndexCondition
;
import
org.h2.message.DbException
;
import
org.h2.result.LocalResult
;
import
org.h2.result.LocalResult
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultInterface
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.util.StringUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueRow
;
/**
/**
* An 'in' condition with a subquery, as in WHERE ID IN(SELECT ...)
* An 'in' condition with a subquery, as in WHERE ID IN(SELECT ...)
...
@@ -52,8 +54,8 @@ public class ConditionInSelect extends Condition {
...
@@ -52,8 +54,8 @@ public class ConditionInSelect extends Condition {
Value
l
=
left
.
getValue
(
session
);
Value
l
=
left
.
getValue
(
session
);
if
(!
rows
.
hasNext
())
{
if
(!
rows
.
hasNext
())
{
return
ValueBoolean
.
get
(
all
);
return
ValueBoolean
.
get
(
all
);
}
else
if
(
l
==
ValueNull
.
INSTANCE
)
{
}
else
if
(
l
.
containsNull
()
)
{
return
l
;
return
ValueNull
.
INSTANCE
;
}
}
if
(!
database
.
getSettings
().
optimizeInSelect
)
{
if
(!
database
.
getSettings
().
optimizeInSelect
)
{
return
getValueSlow
(
rows
,
l
);
return
getValueSlow
(
rows
,
l
);
...
@@ -64,8 +66,8 @@ public class ConditionInSelect extends Condition {
...
@@ -64,8 +66,8 @@ public class ConditionInSelect extends Condition {
}
}
int
columnCount
=
query
.
getColumnCount
();
int
columnCount
=
query
.
getColumnCount
();
if
(
columnCount
!=
1
)
{
if
(
columnCount
!=
1
)
{
l
=
l
.
convertTo
(
Value
.
ARRAY
);
l
=
l
.
convertTo
(
Value
.
ROW
);
Value
[]
leftValue
=
((
Value
Array
)
l
).
getList
();
Value
[]
leftValue
=
((
Value
Row
)
l
).
getList
();
if
(
columnCount
==
leftValue
.
length
&&
rows
.
containsDistinct
(
leftValue
))
{
if
(
columnCount
==
leftValue
.
length
&&
rows
.
containsDistinct
(
leftValue
))
{
return
ValueBoolean
.
TRUE
;
return
ValueBoolean
.
TRUE
;
}
}
...
@@ -74,13 +76,20 @@ public class ConditionInSelect extends Condition {
...
@@ -74,13 +76,20 @@ public class ConditionInSelect extends Condition {
if
(
dataType
==
Value
.
NULL
)
{
if
(
dataType
==
Value
.
NULL
)
{
return
ValueBoolean
.
FALSE
;
return
ValueBoolean
.
FALSE
;
}
}
if
(
l
.
getType
()
==
Value
.
ROW
)
{
Value
[]
leftList
=
((
ValueRow
)
l
).
getList
();
if
(
leftList
.
length
!=
1
)
{
throw
DbException
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
}
l
=
leftList
[
0
];
}
l
=
l
.
convertTo
(
dataType
,
database
.
getMode
());
l
=
l
.
convertTo
(
dataType
,
database
.
getMode
());
if
(
rows
.
containsDistinct
(
new
Value
[]
{
l
}))
{
if
(
rows
.
containsDistinct
(
new
Value
[]
{
l
}))
{
return
ValueBoolean
.
TRUE
;
return
ValueBoolean
.
TRUE
;
}
}
if
(
rows
.
containsDistinct
(
new
Value
[]
{
ValueNull
.
INSTANCE
}))
{
return
ValueNull
.
INSTANCE
;
}
}
if
(
rows
.
containsNull
())
{
return
ValueNull
.
INSTANCE
;
}
}
return
ValueBoolean
.
FALSE
;
return
ValueBoolean
.
FALSE
;
}
}
...
@@ -89,29 +98,35 @@ public class ConditionInSelect extends Condition {
...
@@ -89,29 +98,35 @@ public class ConditionInSelect extends Condition {
// this only returns the correct result if the result has at least one
// this only returns the correct result if the result has at least one
// row, and if l is not null
// row, and if l is not null
boolean
hasNull
=
false
;
boolean
hasNull
=
false
;
boolean
result
=
all
;
if
(
all
)
{
while
(
rows
.
next
())
{
while
(
rows
.
next
())
{
boolean
value
;
Value
cmp
=
compare
(
l
,
rows
);
Value
[]
currentRow
=
rows
.
currentRow
();
if
(
cmp
==
ValueNull
.
INSTANCE
)
{
Value
r
=
query
.
getColumnCount
()
==
1
?
currentRow
[
0
]
:
org
.
h2
.
value
.
ValueArray
.
get
(
currentRow
);
if
(
r
==
ValueNull
.
INSTANCE
)
{
value
=
false
;
hasNull
=
true
;
hasNull
=
true
;
}
else
if
(
cmp
==
ValueBoolean
.
FALSE
)
{
return
cmp
;
}
}
}
else
{
}
else
{
value
=
Comparison
.
compareNotNull
(
database
,
l
,
r
,
compareType
);
while
(
rows
.
next
())
{
Value
cmp
=
compare
(
l
,
rows
);
if
(
cmp
==
ValueNull
.
INSTANCE
)
{
hasNull
=
true
;
}
else
if
(
cmp
==
ValueBoolean
.
TRUE
)
{
return
cmp
;
}
}
if
(!
value
&&
all
)
{
result
=
false
;
break
;
}
else
if
(
value
&&
!
all
)
{
result
=
true
;
break
;
}
}
}
}
if
(
!
result
&&
hasNull
)
{
if
(
hasNull
)
{
return
ValueNull
.
INSTANCE
;
return
ValueNull
.
INSTANCE
;
}
}
return
ValueBoolean
.
get
(
result
);
return
ValueBoolean
.
get
(
all
);
}
private
Value
compare
(
Value
l
,
ResultInterface
rows
)
{
Value
[]
currentRow
=
rows
.
currentRow
();
Value
r
=
l
.
getType
()
!=
Value
.
ROW
&&
query
.
getColumnCount
()
==
1
?
currentRow
[
0
]
:
ValueRow
.
get
(
currentRow
);
return
Comparison
.
compare
(
database
,
l
,
r
,
compareType
);
}
}
@Override
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LocalResult.java
浏览文件 @
a22f1ea3
...
@@ -49,6 +49,14 @@ public interface LocalResult extends ResultInterface, ResultTarget {
...
@@ -49,6 +49,14 @@ public interface LocalResult extends ResultInterface, ResultTarget {
*/
*/
boolean
containsDistinct
(
Value
[]
values
);
boolean
containsDistinct
(
Value
[]
values
);
/**
* Check if this result set contains a NULL value. This method may reset
* this result.
*
* @return true if there is a NULL value
*/
boolean
containsNull
();
/**
/**
* Remove the row from the result set if it exists.
* Remove the row from the result set if it exists.
*
*
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/LocalResultImpl.java
浏览文件 @
a22f1ea3
...
@@ -45,6 +45,7 @@ public class LocalResultImpl implements LocalResult {
...
@@ -45,6 +45,7 @@ public class LocalResultImpl implements LocalResult {
private
int
[]
distinctIndexes
;
private
int
[]
distinctIndexes
;
private
boolean
closed
;
private
boolean
closed
;
private
boolean
containsLobs
;
private
boolean
containsLobs
;
private
Boolean
containsNull
;
/**
/**
* Construct a local result object.
* Construct a local result object.
...
@@ -127,6 +128,7 @@ public class LocalResultImpl implements LocalResult {
...
@@ -127,6 +128,7 @@ public class LocalResultImpl implements LocalResult {
copy
.
offset
=
0
;
copy
.
offset
=
0
;
copy
.
limit
=
-
1
;
copy
.
limit
=
-
1
;
copy
.
external
=
e2
;
copy
.
external
=
e2
;
copy
.
containsNull
=
containsNull
;
return
copy
;
return
copy
;
}
}
...
@@ -212,6 +214,27 @@ public class LocalResultImpl implements LocalResult {
...
@@ -212,6 +214,27 @@ public class LocalResultImpl implements LocalResult {
return
distinctRows
.
get
(
array
)
!=
null
;
return
distinctRows
.
get
(
array
)
!=
null
;
}
}
@Override
public
boolean
containsNull
()
{
Boolean
r
=
containsNull
;
if
(
r
==
null
)
{
r
=
false
;
reset
();
loop:
while
(
next
())
{
Value
[]
row
=
currentRow
;
for
(
int
i
=
0
;
i
<
visibleColumnCount
;
i
++)
{
if
(
row
[
i
].
containsNull
())
{
r
=
true
;
break
loop
;
}
}
}
reset
();
containsNull
=
r
;
}
return
r
;
}
@Override
@Override
public
void
reset
()
{
public
void
reset
()
{
rowId
=
-
1
;
rowId
=
-
1
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/Value.java
浏览文件 @
a22f1ea3
...
@@ -1347,7 +1347,7 @@ public abstract class Value {
...
@@ -1347,7 +1347,7 @@ public abstract class Value {
return
ValueResultSet
.
get
(
result
);
return
ValueResultSet
.
get
(
result
);
}
}
private
DbException
getDataConversionError
(
int
targetType
)
{
DbException
getDataConversionError
(
int
targetType
)
{
DataType
from
=
DataType
.
getDataType
(
getType
());
DataType
from
=
DataType
.
getDataType
(
getType
());
DataType
to
=
DataType
.
getDataType
(
targetType
);
DataType
to
=
DataType
.
getDataType
(
targetType
);
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
(
from
!=
null
?
from
.
name
:
"type="
+
getType
())
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
(
from
!=
null
?
from
.
name
:
"type="
+
getType
())
...
@@ -1372,7 +1372,7 @@ public abstract class Value {
...
@@ -1372,7 +1372,7 @@ public abstract class Value {
* @param v the other value
* @param v the other value
* @param databaseMode the database mode
* @param databaseMode the database mode
* @param compareMode the compare mode
* @param compareMode the compare mode
* @return 0 if both values are equal, -1 if th
e other
value is smaller, and
* @return 0 if both values are equal, -1 if th
is
value is smaller, and
* 1 otherwise
* 1 otherwise
*/
*/
public
final
int
compareTo
(
Value
v
,
Mode
databaseMode
,
CompareMode
compareMode
)
{
public
final
int
compareTo
(
Value
v
,
Mode
databaseMode
,
CompareMode
compareMode
)
{
...
@@ -1401,6 +1401,48 @@ public abstract class Value {
...
@@ -1401,6 +1401,48 @@ public abstract class Value {
return
l
.
compareTypeSafe
(
v
,
compareMode
);
return
l
.
compareTypeSafe
(
v
,
compareMode
);
}
}
/**
* Compare this value against another value using the specified compare
* mode.
*
* @param v the other value
* @param forEquality perform only check for equality
* @param databaseMode the database mode
* @param compareMode the compare mode
* @return 0 if both values are equal, -1 if this value is smaller, 1
* if other value is larger, {@link Integer#MIN_VALUE} if order is
* not defined due to NULL comparison
*/
public
int
compareWithNull
(
Value
v
,
boolean
forEquality
,
Mode
databaseMode
,
CompareMode
compareMode
)
{
if
(
this
==
ValueNull
.
INSTANCE
||
v
==
ValueNull
.
INSTANCE
)
{
return
Integer
.
MIN_VALUE
;
}
Value
l
=
this
;
int
leftType
=
l
.
getType
();
int
rightType
=
v
.
getType
();
if
(
leftType
!=
rightType
||
leftType
==
Value
.
ENUM
)
{
int
dataType
=
Value
.
getHigherOrder
(
leftType
,
rightType
);
if
(
dataType
==
Value
.
ENUM
)
{
ExtTypeInfoEnum
enumerators
=
ExtTypeInfoEnum
.
getEnumeratorsForBinaryOperation
(
l
,
v
);
l
=
l
.
convertToEnum
(
enumerators
);
v
=
v
.
convertToEnum
(
enumerators
);
}
else
{
l
=
l
.
convertTo
(
dataType
,
databaseMode
);
v
=
v
.
convertTo
(
dataType
,
databaseMode
);
}
}
return
l
.
compareTypeSafe
(
v
,
compareMode
);
}
/**
* Returns true if this value is NULL or contains NULL value.
*
* @return true if this value is NULL or contains NULL value
*/
public
boolean
containsNull
()
{
return
false
;
}
public
int
getScale
()
{
public
int
getScale
()
{
return
0
;
return
0
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueArray.java
浏览文件 @
a22f1ea3
...
@@ -10,14 +10,12 @@ import java.sql.PreparedStatement;
...
@@ -10,14 +10,12 @@ import java.sql.PreparedStatement;
import
java.sql.SQLException
;
import
java.sql.SQLException
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
org.h2.engine.Constants
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
import
org.h2.util.MathUtils
;
/**
/**
* Implementation of the ARRAY data type.
* Implementation of the ARRAY data type.
*/
*/
public
class
ValueArray
extends
Value
{
public
class
ValueArray
extends
Value
CollectionBase
{
/**
/**
* Empty array.
* Empty array.
...
@@ -25,12 +23,10 @@ public class ValueArray extends Value {
...
@@ -25,12 +23,10 @@ public class ValueArray extends Value {
private
static
final
Object
EMPTY
=
get
(
new
Value
[
0
]);
private
static
final
Object
EMPTY
=
get
(
new
Value
[
0
]);
private
final
Class
<?>
componentType
;
private
final
Class
<?>
componentType
;
private
final
Value
[]
values
;
private
int
hash
;
private
ValueArray
(
Class
<?>
componentType
,
Value
[]
list
)
{
private
ValueArray
(
Class
<?>
componentType
,
Value
[]
list
)
{
super
(
list
);
this
.
componentType
=
componentType
;
this
.
componentType
=
componentType
;
this
.
values
=
list
;
}
}
/**
/**
...
@@ -65,19 +61,6 @@ public class ValueArray extends Value {
...
@@ -65,19 +61,6 @@ public class ValueArray extends Value {
return
(
ValueArray
)
EMPTY
;
return
(
ValueArray
)
EMPTY
;
}
}
@Override
public
int
hashCode
()
{
if
(
hash
!=
0
)
{
return
hash
;
}
int
h
=
1
;
for
(
Value
v
:
values
)
{
h
=
h
*
31
+
v
.
hashCode
();
}
hash
=
h
;
return
h
;
}
public
Value
[]
getList
()
{
public
Value
[]
getList
()
{
return
values
;
return
values
;
}
}
...
@@ -91,15 +74,6 @@ public class ValueArray extends Value {
...
@@ -91,15 +74,6 @@ public class ValueArray extends Value {
return
componentType
;
return
componentType
;
}
}
@Override
public
long
getPrecision
()
{
long
p
=
0
;
for
(
Value
v
:
values
)
{
p
+=
v
.
getPrecision
();
}
return
p
;
}
@Override
@Override
public
String
getString
()
{
public
String
getString
()
{
StringBuilder
builder
=
new
StringBuilder
().
append
(
'['
);
StringBuilder
builder
=
new
StringBuilder
().
append
(
'['
);
...
@@ -181,15 +155,6 @@ public class ValueArray extends Value {
...
@@ -181,15 +155,6 @@ public class ValueArray extends Value {
return
builder
.
append
(
']'
).
toString
();
return
builder
.
append
(
']'
).
toString
();
}
}
@Override
public
int
getDisplaySize
()
{
long
size
=
0
;
for
(
Value
v
:
values
)
{
size
+=
v
.
getDisplaySize
();
}
return
MathUtils
.
convertLongToInt
(
size
);
}
@Override
@Override
public
boolean
equals
(
Object
other
)
{
public
boolean
equals
(
Object
other
)
{
if
(!(
other
instanceof
ValueArray
))
{
if
(!(
other
instanceof
ValueArray
))
{
...
@@ -211,15 +176,6 @@ public class ValueArray extends Value {
...
@@ -211,15 +176,6 @@ public class ValueArray extends Value {
return
true
;
return
true
;
}
}
@Override
public
int
getMemory
()
{
int
memory
=
32
;
for
(
Value
v
:
values
)
{
memory
+=
v
.
getMemory
()
+
Constants
.
MEMORY_POINTER
;
}
return
memory
;
}
@Override
@Override
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(!
force
)
{
if
(!
force
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueCollectionBase.java
0 → 100644
浏览文件 @
a22f1ea3
/*
* 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
*/
package
org
.
h2
.
value
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Mode
;
import
org.h2.message.DbException
;
import
org.h2.util.MathUtils
;
/**
* Base class for ARRAY and ROW values.
*/
abstract
class
ValueCollectionBase
extends
Value
{
final
Value
[]
values
;
private
int
hash
;
ValueCollectionBase
(
Value
[]
values
)
{
this
.
values
=
values
;
}
@Override
public
int
hashCode
()
{
if
(
hash
!=
0
)
{
return
hash
;
}
int
h
=
getType
();
for
(
Value
v
:
values
)
{
h
=
h
*
31
+
v
.
hashCode
();
}
hash
=
h
;
return
h
;
}
@Override
public
long
getPrecision
()
{
long
p
=
0
;
for
(
Value
v
:
values
)
{
p
+=
v
.
getPrecision
();
}
return
p
;
}
@Override
public
int
getDisplaySize
()
{
long
size
=
0
;
for
(
Value
v
:
values
)
{
size
+=
v
.
getDisplaySize
();
}
return
MathUtils
.
convertLongToInt
(
size
);
}
@Override
public
int
compareWithNull
(
Value
v
,
boolean
forEquality
,
Mode
databaseMode
,
CompareMode
compareMode
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
Integer
.
MIN_VALUE
;
}
ValueCollectionBase
l
=
this
;
int
leftType
=
l
.
getType
();
int
rightType
=
v
.
getType
();
if
(
rightType
!=
ARRAY
&&
rightType
!=
ROW
)
{
throw
v
.
getDataConversionError
(
leftType
);
}
ValueCollectionBase
r
=
(
ValueCollectionBase
)
v
;
Value
[]
leftArray
=
l
.
values
,
rightArray
=
r
.
values
;
int
leftLength
=
leftArray
.
length
,
rightLength
=
rightArray
.
length
;
if
(
leftLength
!=
rightLength
)
{
if
(
leftType
==
ROW
||
rightType
==
ROW
)
{
throw
DbException
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
}
if
(
forEquality
)
{
return
1
;
}
}
if
(
forEquality
)
{
boolean
hasNull
=
false
;
for
(
int
i
=
0
;
i
<
leftLength
;
i
++)
{
Value
v1
=
leftArray
[
i
];
Value
v2
=
rightArray
[
i
];
int
comp
=
v1
.
compareWithNull
(
v2
,
forEquality
,
databaseMode
,
compareMode
);
if
(
comp
!=
0
)
{
if
(
comp
!=
Integer
.
MIN_VALUE
)
{
return
comp
;
}
hasNull
=
true
;
}
}
return
hasNull
?
Integer
.
MIN_VALUE
:
0
;
}
int
len
=
Math
.
min
(
leftLength
,
rightLength
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Value
v1
=
leftArray
[
i
];
Value
v2
=
rightArray
[
i
];
int
comp
=
v1
.
compareWithNull
(
v2
,
forEquality
,
databaseMode
,
compareMode
);
if
(
comp
!=
0
)
{
return
comp
;
}
}
return
Integer
.
compare
(
leftLength
,
rightLength
);
}
@Override
public
boolean
containsNull
()
{
for
(
Value
v
:
values
)
{
if
(
v
.
containsNull
())
{
return
true
;
}
}
return
false
;
}
@Override
public
int
getMemory
()
{
int
memory
=
32
;
for
(
Value
v
:
values
)
{
memory
+=
v
.
getMemory
()
+
Constants
.
MEMORY_POINTER
;
}
return
memory
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueNull.java
浏览文件 @
a22f1ea3
...
@@ -143,6 +143,11 @@ public class ValueNull extends Value {
...
@@ -143,6 +143,11 @@ public class ValueNull extends Value {
throw
DbException
.
throwInternalError
(
"compare null"
);
throw
DbException
.
throwInternalError
(
"compare null"
);
}
}
@Override
public
boolean
containsNull
()
{
return
true
;
}
@Override
@Override
public
long
getPrecision
()
{
public
long
getPrecision
()
{
return
PRECISION
;
return
PRECISION
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueRow.java
浏览文件 @
a22f1ea3
...
@@ -10,26 +10,21 @@ import java.sql.SQLException;
...
@@ -10,26 +10,21 @@ import java.sql.SQLException;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.SysProperties
;
import
org.h2.engine.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.util.MathUtils
;
/**
/**
* Row value.
* Row value.
*/
*/
public
class
ValueRow
extends
Value
{
public
class
ValueRow
extends
Value
CollectionBase
{
/**
/**
* Empty row.
* Empty row.
*/
*/
private
static
final
Object
EMPTY
=
get
(
new
Value
[
0
]);
private
static
final
Object
EMPTY
=
get
(
new
Value
[
0
]);
private
final
Value
[]
values
;
private
int
hash
;
private
ValueRow
(
Value
[]
list
)
{
private
ValueRow
(
Value
[]
list
)
{
this
.
values
=
list
;
super
(
list
)
;
}
}
/**
/**
...
@@ -52,19 +47,6 @@ public class ValueRow extends Value {
...
@@ -52,19 +47,6 @@ public class ValueRow extends Value {
return
(
ValueRow
)
EMPTY
;
return
(
ValueRow
)
EMPTY
;
}
}
@Override
public
int
hashCode
()
{
if
(
hash
!=
0
)
{
return
hash
;
}
int
h
=
1
;
for
(
Value
v
:
values
)
{
h
=
h
*
31
+
v
.
hashCode
();
}
hash
=
h
;
return
h
;
}
public
Value
[]
getList
()
{
public
Value
[]
getList
()
{
return
values
;
return
values
;
}
}
...
@@ -74,15 +56,6 @@ public class ValueRow extends Value {
...
@@ -74,15 +56,6 @@ public class ValueRow extends Value {
return
Value
.
ROW
;
return
Value
.
ROW
;
}
}
@Override
public
long
getPrecision
()
{
long
p
=
0
;
for
(
Value
v
:
values
)
{
p
+=
v
.
getPrecision
();
}
return
p
;
}
@Override
@Override
public
String
getString
()
{
public
String
getString
()
{
StringBuilder
builder
=
new
StringBuilder
(
"ROW ("
);
StringBuilder
builder
=
new
StringBuilder
(
"ROW ("
);
...
@@ -165,15 +138,6 @@ public class ValueRow extends Value {
...
@@ -165,15 +138,6 @@ public class ValueRow extends Value {
return
builder
.
append
(
')'
).
toString
();
return
builder
.
append
(
')'
).
toString
();
}
}
@Override
public
int
getDisplaySize
()
{
long
size
=
0
;
for
(
Value
v
:
values
)
{
size
+=
v
.
getDisplaySize
();
}
return
MathUtils
.
convertLongToInt
(
size
);
}
@Override
@Override
public
boolean
equals
(
Object
other
)
{
public
boolean
equals
(
Object
other
)
{
if
(!(
other
instanceof
ValueRow
))
{
if
(!(
other
instanceof
ValueRow
))
{
...
@@ -195,15 +159,6 @@ public class ValueRow extends Value {
...
@@ -195,15 +159,6 @@ public class ValueRow extends Value {
return
true
;
return
true
;
}
}
@Override
public
int
getMemory
()
{
int
memory
=
32
;
for
(
Value
v
:
values
)
{
memory
+=
v
.
getMemory
()
+
Constants
.
MEMORY_POINTER
;
}
return
memory
;
}
@Override
@Override
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(!
force
)
{
if
(!
force
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
a22f1ea3
...
@@ -74,6 +74,7 @@ import org.h2.test.db.TestSetCollation;
...
@@ -74,6 +74,7 @@ import org.h2.test.db.TestSetCollation;
import
org.h2.test.db.TestSpaceReuse
;
import
org.h2.test.db.TestSpaceReuse
;
import
org.h2.test.db.TestSpatial
;
import
org.h2.test.db.TestSpatial
;
import
org.h2.test.db.TestSpeed
;
import
org.h2.test.db.TestSpeed
;
import
org.h2.test.db.TestSubqueryPerformanceOnLazyExecutionMode
;
import
org.h2.test.db.TestSynonymForTable
;
import
org.h2.test.db.TestSynonymForTable
;
import
org.h2.test.db.TestTableEngines
;
import
org.h2.test.db.TestTableEngines
;
import
org.h2.test.db.TestTempTables
;
import
org.h2.test.db.TestTempTables
;
...
@@ -223,7 +224,6 @@ import org.h2.test.unit.TestSort;
...
@@ -223,7 +224,6 @@ import org.h2.test.unit.TestSort;
import
org.h2.test.unit.TestStreams
;
import
org.h2.test.unit.TestStreams
;
import
org.h2.test.unit.TestStringCache
;
import
org.h2.test.unit.TestStringCache
;
import
org.h2.test.unit.TestStringUtils
;
import
org.h2.test.unit.TestStringUtils
;
import
org.h2.test.unit.TestSubqueryPerformanceOnLazyExecutionMode
;
import
org.h2.test.unit.TestTimeStampWithTimeZone
;
import
org.h2.test.unit.TestTimeStampWithTimeZone
;
import
org.h2.test.unit.TestTools
;
import
org.h2.test.unit.TestTools
;
import
org.h2.test.unit.TestTraceSystem
;
import
org.h2.test.unit.TestTraceSystem
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/
unit
/TestSubqueryPerformanceOnLazyExecutionMode.java
→
h2/src/test/org/h2/test/
db
/TestSubqueryPerformanceOnLazyExecutionMode.java
浏览文件 @
a22f1ea3
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
* Initial Developer: H2 Group
*/
*/
package
org
.
h2
.
test
.
unit
;
package
org
.
h2
.
test
.
db
;
import
org.h2.command.dml.SetTypes
;
import
org.h2.command.dml.SetTypes
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
...
@@ -33,6 +33,11 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
...
@@ -33,6 +33,11 @@ public class TestSubqueryPerformanceOnLazyExecutionMode extends TestDb {
TestBase
.
createCaller
().
init
().
test
();
TestBase
.
createCaller
().
init
().
test
();
}
}
@Override
public
boolean
isEnabled
()
{
return
!
config
.
travis
;
}
@Override
@Override
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
deleteDb
(
"lazySubq"
);
deleteDb
(
"lazySubq"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/datatypes/array.sql
浏览文件 @
a22f1ea3
...
@@ -23,3 +23,66 @@ SELECT ARRAY[10];
...
@@ -23,3 +23,66 @@ SELECT ARRAY[10];
SELECT
ARRAY
[
10
,
20
,
30
];
SELECT
ARRAY
[
10
,
20
,
30
];
>>
[
10
,
20
,
30
]
>>
[
10
,
20
,
30
]
SELECT
ARRAY
[
1
,
NULL
]
IS
NOT
DISTINCT
FROM
ARRAY
[
1
,
NULL
];
>>
TRUE
SELECT
ARRAY
[
1
,
NULL
]
IS
DISTINCT
FROM
ARRAY
[
1
,
NULL
];
>>
FALSE
SELECT
ARRAY
[
1
,
NULL
]
=
ARRAY
[
1
,
NULL
];
>>
null
SELECT
ARRAY
[
1
,
NULL
]
<>
ARRAY
[
1
,
NULL
];
>>
null
SELECT
ARRAY
[
NULL
]
=
ARRAY
[
NULL
,
NULL
];
>>
FALSE
select
ARRAY
[
1
,
NULL
,
2
]
=
ARRAY
[
1
,
NULL
,
1
];
>>
FALSE
select
ARRAY
[
1
,
NULL
,
2
]
<>
ARRAY
[
1
,
NULL
,
1
];
>>
TRUE
SELECT
ARRAY
[
1
,
NULL
]
>
ARRAY
[
1
,
NULL
];
>>
null
SELECT
ARRAY
[
1
,
2
]
>
ARRAY
[
1
,
NULL
];
>>
null
SELECT
ARRAY
[
1
,
2
,
NULL
]
>
ARRAY
[
1
,
1
,
NULL
];
>>
TRUE
SELECT
ARRAY
[
1
,
1
,
NULL
]
>
ARRAY
[
1
,
2
,
NULL
];
>>
FALSE
SELECT
ARRAY
[
1
,
2
,
NULL
]
<
ARRAY
[
1
,
1
,
NULL
];
>>
FALSE
SELECT
ARRAY
[
1
,
1
,
NULL
]
<=
ARRAY
[
1
,
1
,
NULL
];
>>
null
SELECT
ARRAY
[
1
,
NULL
]
IN
(
ARRAY
[
1
,
NULL
]);
>>
null
CREATE
TABLE
TEST
(
A
ARRAY
);
>
ok
INSERT
INTO
TEST
VALUES
(
ARRAY
[
1
,
NULL
]),
(
ARRAY
[
1
,
2
]);
>
update
count
:
2
SELECT
ARRAY
[
1
,
2
]
IN
(
SELECT
A
FROM
TEST
);
>>
TRUE
SELECT
ROW
(
ARRAY
[
1
,
2
])
IN
(
SELECT
A
FROM
TEST
);
>>
TRUE
SELECT
ARRAY
[
1
,
NULL
]
IN
(
SELECT
A
FROM
TEST
);
>>
null
SELECT
ROW
(
ARRAY
[
1
,
NULL
])
IN
(
SELECT
A
FROM
TEST
);
>>
null
DROP
TABLE
TEST
;
>
ok
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/datatypes/row.sql
浏览文件 @
a22f1ea3
...
@@ -8,3 +8,66 @@ SELECT ROW (10);
...
@@ -8,3 +8,66 @@ SELECT ROW (10);
SELECT
(
10
,
20
,
30
);
SELECT
(
10
,
20
,
30
);
>>
ROW
(
10
,
20
,
30
)
>>
ROW
(
10
,
20
,
30
)
SELECT
(
1
,
NULL
)
IS
NOT
DISTINCT
FROM
(
1
,
NULL
);
>>
TRUE
SELECT
(
1
,
NULL
)
IS
DISTINCT
FROM
ROW
(
1
,
NULL
);
>>
FALSE
SELECT
(
1
,
NULL
)
=
(
1
,
NULL
);
>>
null
SELECT
(
1
,
NULL
)
<>
(
1
,
NULL
);
>>
null
SELECT
ROW
(
NULL
)
=
(
NULL
,
NULL
);
>
exception
COLUMN_COUNT_DOES_NOT_MATCH
select
(
1
,
NULL
,
2
)
=
(
1
,
NULL
,
1
);
>>
FALSE
select
(
1
,
NULL
,
2
)
<>
(
1
,
NULL
,
1
);
>>
TRUE
SELECT
(
1
,
NULL
)
>
(
1
,
NULL
);
>>
null
SELECT
(
1
,
2
)
>
(
1
,
NULL
);
>>
null
SELECT
(
1
,
2
,
NULL
)
>
(
1
,
1
,
NULL
);
>>
TRUE
SELECT
(
1
,
1
,
NULL
)
>
(
1
,
2
,
NULL
);
>>
FALSE
SELECT
(
1
,
2
,
NULL
)
<
(
1
,
1
,
NULL
);
>>
FALSE
SELECT
(
1
,
1
,
NULL
)
<=
(
1
,
1
,
NULL
);
>>
null
SELECT
(
1
,
2
)
IN
(
SELECT
1
,
2
);
>>
TRUE
SELECT
(
1
,
2
)
IN
(
SELECT
*
FROM
VALUES
(
1
,
2
),
(
1
,
NULL
));
>>
TRUE
SELECT
(
1
,
2
)
IN
(
SELECT
*
FROM
VALUES
(
1
,
1
),
(
1
,
NULL
));
>>
null
SELECT
(
1
,
2
)
IN
(
SELECT
*
FROM
VALUES
(
1
,
1
),
(
1
,
3
));
>>
FALSE
SELECT
(
1
,
NULL
)
IN
(
SELECT
1
,
NULL
);
>>
null
SELECT
(
1
,
ARRAY
[
1
])
IN
(
SELECT
1
,
ARRAY
[
1
]);
>>
TRUE
SELECT
(
1
,
ARRAY
[
1
])
IN
(
SELECT
1
,
ARRAY
[
2
]);
>>
FALSE
SELECT
(
1
,
ARRAY
[
NULL
])
IN
(
SELECT
1
,
ARRAY
[
NULL
]);
>>
null
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/dml/select.sql
浏览文件 @
a22f1ea3
...
@@ -244,11 +244,11 @@ CREATE TABLE TEST(A INT, B INT);
...
@@ -244,11 +244,11 @@ CREATE TABLE TEST(A INT, B INT);
INSERT
INTO
TEST
VALUES
(
1
,
1
),
(
1
,
2
),
(
2
,
1
),
(
2
,
2
),
(
2
,
3
);
INSERT
INTO
TEST
VALUES
(
1
,
1
),
(
1
,
2
),
(
2
,
1
),
(
2
,
2
),
(
2
,
3
);
>
update
count
:
5
>
update
count
:
5
SELECT
A
,
COUNT
(
B
)
FROM
TEST
GROUP
BY
A
OFFSET
1
;
SELECT
A
,
COUNT
(
B
)
FROM
TEST
GROUP
BY
A
O
RDER
BY
A
O
FFSET
1
;
>
A
COUNT
(
B
)
>
A
COUNT
(
B
)
>
-
--------
>
-
--------
>
2
3
>
2
3
>
rows
:
1
>
rows
(
ordered
)
:
1
DROP
TABLE
TEST
;
DROP
TABLE
TEST
;
>
ok
>
ok
...
@@ -463,3 +463,6 @@ SELECT (3, 4) > ALL (SELECT ID, V FROM TEST);
...
@@ -463,3 +463,6 @@ SELECT (3, 4) > ALL (SELECT ID, V FROM TEST);
DROP
TABLE
TEST
;
DROP
TABLE
TEST
;
>
ok
>
ok
SELECT
1
=
ALL
(
SELECT
*
FROM
VALUES
(
NULL
),
(
1
),
(
2
),
(
NULL
)
ORDER
BY
1
);
>>
FALSE
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/synth/TestNestedJoins.java
浏览文件 @
a22f1ea3
...
@@ -386,15 +386,17 @@ public class TestNestedJoins extends TestDb {
...
@@ -386,15 +386,17 @@ public class TestNestedJoins extends TestDb {
rs
=
stat
.
executeQuery
(
"select distinct t1.a, t2.a, t3.a from t1 "
+
rs
=
stat
.
executeQuery
(
"select distinct t1.a, t2.a, t3.a from t1 "
+
"right outer join t3 on t1.b=t3.a "
+
"right outer join t3 on t1.b=t3.a "
+
"right outer join t2 on t2.b=t1.a"
);
"right outer join t2 on t2.b=t1.a"
);
// expected: 1 1 1; null 2 null
// expected:
assertTrue
(
rs
.
next
());
// null 2 null
assertEquals
(
"1"
,
rs
.
getString
(
1
));
// 1 1 1
assertEquals
(
"1"
,
rs
.
getString
(
2
));
assertEquals
(
"1"
,
rs
.
getString
(
3
));
assertTrue
(
rs
.
next
());
assertTrue
(
rs
.
next
());
assertEquals
(
null
,
rs
.
getString
(
1
));
assertEquals
(
null
,
rs
.
getString
(
1
));
assertEquals
(
"2"
,
rs
.
getString
(
2
));
assertEquals
(
"2"
,
rs
.
getString
(
2
));
assertEquals
(
null
,
rs
.
getString
(
3
));
assertEquals
(
null
,
rs
.
getString
(
3
));
assertTrue
(
rs
.
next
());
assertEquals
(
"1"
,
rs
.
getString
(
1
));
assertEquals
(
"1"
,
rs
.
getString
(
2
));
assertEquals
(
"1"
,
rs
.
getString
(
3
));
assertFalse
(
rs
.
next
());
assertFalse
(
rs
.
next
());
stat
.
execute
(
"drop table t1, t2, t3, t4"
);
stat
.
execute
(
"drop table t1, t2, t3, t4"
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/synth/TestOuterJoins.java
浏览文件 @
a22f1ea3
...
@@ -339,15 +339,17 @@ public class TestOuterJoins extends TestDb {
...
@@ -339,15 +339,17 @@ public class TestOuterJoins extends TestDb {
"ON T2.B = T1.A"
,
sql
);
"ON T2.B = T1.A"
,
sql
);
rs
=
stat
.
executeQuery
(
"select distinct t1.a, t2.a, t3.a from t1 "
+
rs
=
stat
.
executeQuery
(
"select distinct t1.a, t2.a, t3.a from t1 "
+
"right outer join t3 on t1.b=t3.a right outer join t2 on t2.b=t1.a"
);
"right outer join t3 on t1.b=t3.a right outer join t2 on t2.b=t1.a"
);
// expected: 1 1 1; null 2 null
// expected:
assertTrue
(
rs
.
next
());
// null 2 null
assertEquals
(
"1"
,
rs
.
getString
(
1
));
// 1 1 1
assertEquals
(
"1"
,
rs
.
getString
(
2
));
assertEquals
(
"1"
,
rs
.
getString
(
3
));
assertTrue
(
rs
.
next
());
assertTrue
(
rs
.
next
());
assertEquals
(
null
,
rs
.
getString
(
1
));
assertEquals
(
null
,
rs
.
getString
(
1
));
assertEquals
(
"2"
,
rs
.
getString
(
2
));
assertEquals
(
"2"
,
rs
.
getString
(
2
));
assertEquals
(
null
,
rs
.
getString
(
3
));
assertEquals
(
null
,
rs
.
getString
(
3
));
assertTrue
(
rs
.
next
());
assertEquals
(
"1"
,
rs
.
getString
(
1
));
assertEquals
(
"1"
,
rs
.
getString
(
2
));
assertEquals
(
"1"
,
rs
.
getString
(
3
));
assertFalse
(
rs
.
next
());
assertFalse
(
rs
.
next
());
stat
.
execute
(
"drop table t1, t2, t3, t4"
);
stat
.
execute
(
"drop table t1, t2, t3, t4"
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论