Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
ea64e353
提交
ea64e353
authored
1月 17, 2019
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix NPE with ENUM in SelectUnion
上级
0347313c
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
85 行增加
和
61 行删除
+85
-61
changelog.html
h2/src/docsrc/html/changelog.html
+6
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+10
-25
SelectUnion.java
h2/src/main/org/h2/command/dml/SelectUnion.java
+3
-9
BinaryOperation.java
h2/src/main/org/h2/expression/BinaryOperation.java
+0
-1
ConditionInConstantSet.java
...n/org/h2/expression/condition/ConditionInConstantSet.java
+6
-18
Value.java
h2/src/main/org/h2/value/Value.java
+45
-8
enum.sql
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
+15
-0
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
ea64e353
...
@@ -21,6 +21,12 @@ Change Log
...
@@ -21,6 +21,12 @@ Change Log
<h2>
Next Version (unreleased)
</h2>
<h2>
Next Version (unreleased)
</h2>
<ul>
<ul>
<li>
Issue #1665: TestCrashAPI: NPE with ENUM in MINUS operator
</li>
<li>
Issue #1602: Combine type, precision, scale, display size and extTypeInfo into one object
</li>
<li>
PR #1671: Assorted changes
</li>
<li>
Issue #1668: MySQL compatibility DATE() function should return NULL on error
<li>
Issue #1668: MySQL compatibility DATE() function should return NULL on error
</li>
</li>
<li>
Issue #1604: TestCrashAPI: PreparedStatement.getGeneratedKeys() is already closed
<li>
Issue #1604: TestCrashAPI: PreparedStatement.getGeneratedKeys() is already closed
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
ea64e353
...
@@ -5841,37 +5841,22 @@ public class Parser {
...
@@ -5841,37 +5841,22 @@ public class Parser {
Expression
expr
=
readExpression
();
Expression
expr
=
readExpression
();
expr
=
expr
.
optimize
(
session
);
expr
=
expr
.
optimize
(
session
);
TypeInfo
type
=
expr
.
getType
();
TypeInfo
type
=
expr
.
getType
();
int
valueType
=
type
.
getValueType
();
long
prec
;
int
scale
,
displaySize
;
Column
column
;
Column
column
;
String
columnName
=
"C"
+
(
i
+
1
);
String
columnName
=
"C"
+
(
i
+
1
);
if
(
rows
.
isEmpty
())
{
if
(
rows
.
isEmpty
())
{
if
(
valueType
==
Value
.
UNKNOWN
)
{
if
(
type
.
getValueType
()
==
Value
.
UNKNOWN
)
{
valueType
=
Value
.
STRING
;
type
=
TypeInfo
.
TYPE_STRING_DEFAULT
;
}
DataType
dt
=
DataType
.
getDataType
(
valueType
);
prec
=
dt
.
defaultPrecision
;
scale
=
dt
.
defaultScale
;
displaySize
=
dt
.
defaultDisplaySize
;
column
=
new
Column
(
columnName
,
valueType
,
prec
,
scale
,
displaySize
);
columns
.
add
(
column
);
}
}
prec
=
type
.
getPrecision
(
);
column
=
new
Column
(
columnName
,
type
);
scale
=
type
.
getScale
(
);
columns
.
add
(
column
);
displaySize
=
type
.
getDisplaySize
();
}
else
{
if
(
i
>=
columns
.
size
())
{
if
(
i
>=
columns
.
size
())
{
throw
DbException
throw
DbException
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
.
get
(
ErrorCode
.
COLUMN_COUNT_DOES_NOT_MATCH
);
}
}
Column
c
=
columns
.
get
(
i
);
type
=
Value
.
getHigherType
(
columns
.
get
(
i
).
getType
(),
type
);
TypeInfo
t
=
c
.
getType
();
column
=
new
Column
(
columnName
,
type
);
valueType
=
Value
.
getHigherOrder
(
t
.
getValueType
(),
valueType
);
prec
=
Math
.
max
(
t
.
getPrecision
(),
prec
);
scale
=
Math
.
max
(
t
.
getScale
(),
scale
);
displaySize
=
Math
.
max
(
t
.
getDisplaySize
(),
displaySize
);
column
=
new
Column
(
columnName
,
valueType
,
prec
,
scale
,
displaySize
);
columns
.
set
(
i
,
column
);
columns
.
set
(
i
,
column
);
}
row
.
add
(
expr
);
row
.
add
(
expr
);
i
++;
i
++;
}
while
(
multiColumn
&&
readIfMore
(
true
));
}
while
(
multiColumn
&&
readIfMore
(
true
));
...
...
h2/src/main/org/h2/command/dml/SelectUnion.java
浏览文件 @
ea64e353
...
@@ -27,7 +27,6 @@ import org.h2.table.ColumnResolver;
...
@@ -27,7 +27,6 @@ import org.h2.table.ColumnResolver;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.util.ColumnNamer
;
import
org.h2.util.ColumnNamer
;
import
org.h2.value.TypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
...
@@ -122,7 +121,7 @@ public class SelectUnion extends Query {
...
@@ -122,7 +121,7 @@ public class SelectUnion extends Query {
Mode
mode
=
session
.
getDatabase
().
getMode
();
Mode
mode
=
session
.
getDatabase
().
getMode
();
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
Expression
e
=
expressions
.
get
(
i
);
Expression
e
=
expressions
.
get
(
i
);
newValues
[
i
]
=
values
[
i
].
convertTo
(
e
.
getType
()
.
getValueType
(),
mode
);
newValues
[
i
]
=
values
[
i
].
convertTo
(
e
.
getType
()
,
mode
,
null
);
}
}
return
newValues
;
return
newValues
;
}
}
...
@@ -329,13 +328,8 @@ public class SelectUnion extends Query {
...
@@ -329,13 +328,8 @@ public class SelectUnion extends Query {
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Expression
l
=
le
.
get
(
i
);
Expression
l
=
le
.
get
(
i
);
Expression
r
=
re
.
get
(
i
);
Expression
r
=
re
.
get
(
i
);
TypeInfo
lType
=
l
.
getType
(),
rType
=
r
.
getType
();
String
columnName
=
columnNamer
.
getColumnName
(
l
,
i
,
l
.
getAlias
());
int
type
=
Value
.
getHigherOrder
(
lType
.
getValueType
(),
rType
.
getValueType
());
Column
col
=
new
Column
(
columnName
,
Value
.
getHigherType
(
l
.
getType
(),
r
.
getType
()));
long
prec
=
Math
.
max
(
lType
.
getPrecision
(),
rType
.
getPrecision
());
int
scale
=
Math
.
max
(
lType
.
getScale
(),
rType
.
getScale
());
int
displaySize
=
Math
.
max
(
lType
.
getDisplaySize
(),
rType
.
getDisplaySize
());
String
columnName
=
columnNamer
.
getColumnName
(
l
,
i
,
l
.
getAlias
());
Column
col
=
new
Column
(
columnName
,
type
,
prec
,
scale
,
displaySize
);
Expression
e
=
new
ExpressionColumn
(
session
.
getDatabase
(),
col
);
Expression
e
=
new
ExpressionColumn
(
session
.
getDatabase
(),
col
);
expressions
.
add
(
e
);
expressions
.
add
(
e
);
}
}
...
...
h2/src/main/org/h2/expression/BinaryOperation.java
浏览文件 @
ea64e353
...
@@ -202,7 +202,6 @@ public class BinaryOperation extends Expression {
...
@@ -202,7 +202,6 @@ public class BinaryOperation extends Expression {
int
dataType
=
Value
.
getHigherOrder
(
l
,
r
);
int
dataType
=
Value
.
getHigherOrder
(
l
,
r
);
if
(
dataType
==
Value
.
ENUM
)
{
if
(
dataType
==
Value
.
ENUM
)
{
type
=
TypeInfo
.
TYPE_INT
;
type
=
TypeInfo
.
TYPE_INT
;
dataType
=
Value
.
INT
;
}
else
{
}
else
{
type
=
TypeInfo
.
getTypeInfo
(
dataType
);
type
=
TypeInfo
.
getTypeInfo
(
dataType
);
if
(
DataType
.
isStringType
(
dataType
)
&&
session
.
getDatabase
().
getMode
().
allowPlusForStringConcat
)
{
if
(
DataType
.
isStringType
(
dataType
)
&&
session
.
getDatabase
().
getMode
().
allowPlusForStringConcat
)
{
...
...
h2/src/main/org/h2/expression/condition/ConditionInConstantSet.java
浏览文件 @
ea64e353
...
@@ -18,7 +18,7 @@ import org.h2.index.IndexCondition;
...
@@ -18,7 +18,7 @@ import org.h2.index.IndexCondition;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.value.
Ext
TypeInfo
;
import
org.h2.value.TypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
...
@@ -36,8 +36,7 @@ public class ConditionInConstantSet extends Condition {
...
@@ -36,8 +36,7 @@ public class ConditionInConstantSet extends Condition {
private
final
ArrayList
<
Expression
>
valueList
;
private
final
ArrayList
<
Expression
>
valueList
;
private
final
TreeSet
<
Value
>
valueSet
;
private
final
TreeSet
<
Value
>
valueSet
;
private
boolean
hasNull
;
private
boolean
hasNull
;
private
final
int
type
;
private
final
TypeInfo
type
;
private
ExtTypeInfo
extTypeInfo
;
/**
/**
* Create a new IN(..) condition.
* Create a new IN(..) condition.
...
@@ -54,17 +53,10 @@ public class ConditionInConstantSet extends Condition {
...
@@ -54,17 +53,10 @@ public class ConditionInConstantSet extends Condition {
this
.
valueList
=
valueList
;
this
.
valueList
=
valueList
;
Database
database
=
session
.
getDatabase
();
Database
database
=
session
.
getDatabase
();
this
.
valueSet
=
new
TreeSet
<>(
database
.
getCompareMode
());
this
.
valueSet
=
new
TreeSet
<>(
database
.
getCompareMode
());
type
=
left
.
getType
()
.
getValueType
()
;
type
=
left
.
getType
();
Mode
mode
=
database
.
getMode
();
Mode
mode
=
database
.
getMode
();
if
(
type
==
Value
.
ENUM
)
{
extTypeInfo
=
((
ExpressionColumn
)
left
).
getColumn
().
getType
().
getExtTypeInfo
();
for
(
Expression
expression
:
valueList
)
{
for
(
Expression
expression
:
valueList
)
{
add
(
extTypeInfo
.
cast
(
expression
.
getValue
(
session
)));
add
(
expression
.
getValue
(
session
).
convertTo
(
type
,
mode
,
null
));
}
}
else
{
for
(
Expression
expression
:
valueList
)
{
add
(
expression
.
getValue
(
session
).
convertTo
(
type
,
mode
));
}
}
}
}
}
...
@@ -173,11 +165,7 @@ public class ConditionInConstantSet extends Condition {
...
@@ -173,11 +165,7 @@ public class ConditionInConstantSet extends Condition {
if
(
add
!=
null
)
{
if
(
add
!=
null
)
{
if
(
add
.
isConstant
())
{
if
(
add
.
isConstant
())
{
valueList
.
add
(
add
);
valueList
.
add
(
add
);
if
(
type
==
Value
.
ENUM
)
{
add
(
add
.
getValue
(
session
).
convertTo
(
type
,
session
.
getDatabase
().
getMode
(),
null
));
add
(
add
.
getValue
(
session
).
convertToEnum
(
extTypeInfo
));
}
else
{
add
(
add
.
getValue
(
session
).
convertTo
(
type
,
session
.
getDatabase
().
getMode
()));
}
return
this
;
return
this
;
}
}
}
}
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
ea64e353
...
@@ -463,14 +463,11 @@ public abstract class Value extends VersionedValue {
...
@@ -463,14 +463,11 @@ public abstract class Value extends VersionedValue {
public
static
int
getHigherOrder
(
int
t1
,
int
t2
)
{
public
static
int
getHigherOrder
(
int
t1
,
int
t2
)
{
if
(
t1
==
Value
.
UNKNOWN
||
t2
==
Value
.
UNKNOWN
)
{
if
(
t1
==
Value
.
UNKNOWN
||
t2
==
Value
.
UNKNOWN
)
{
if
(
t1
==
t2
)
{
if
(
t1
==
t2
)
{
throw
DbException
.
get
(
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, ?"
);
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, ?"
);
}
else
if
(
t1
==
Value
.
NULL
)
{
}
else
if
(
t1
==
Value
.
NULL
)
{
throw
DbException
.
get
(
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"NULL, ?"
);
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"NULL, ?"
);
}
else
if
(
t2
==
Value
.
NULL
)
{
}
else
if
(
t2
==
Value
.
NULL
)
{
throw
DbException
.
get
(
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, NULL"
);
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, NULL"
);
}
}
}
}
if
(
t1
==
t2
)
{
if
(
t1
==
t2
)
{
...
@@ -481,6 +478,34 @@ public abstract class Value extends VersionedValue {
...
@@ -481,6 +478,34 @@ public abstract class Value extends VersionedValue {
return
o1
>
o2
?
t1
:
t2
;
return
o1
>
o2
?
t1
:
t2
;
}
}
/**
* Get the higher data type of two data types. If values need to be
* converted to match the other operands data type, the value with the
* lower order is converted to the value with the higher order.
*
* @param type1 the first data type
* @param type2 the second data type
* @return the higher data type of the two
*/
public
static
TypeInfo
getHigherType
(
TypeInfo
type1
,
TypeInfo
type2
)
{
int
t1
=
type1
.
getValueType
(),
t2
=
type2
.
getValueType
();
if
(
t1
==
Value
.
UNKNOWN
||
t2
==
Value
.
UNKNOWN
)
{
if
(
t1
==
t2
)
{
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, ?"
);
}
else
if
(
t1
==
Value
.
NULL
)
{
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"NULL, ?"
);
}
else
if
(
t2
==
Value
.
NULL
)
{
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"?, NULL"
);
}
}
int
dataType
=
getOrder
(
t1
)
>
getOrder
(
t2
)
?
t1
:
t2
;
long
precision
=
Math
.
max
(
type1
.
getPrecision
(),
type2
.
getPrecision
());
int
scale
=
Math
.
max
(
type1
.
getScale
(),
type2
.
getScale
());
ExtTypeInfo
ext1
=
type1
.
getExtTypeInfo
();
ExtTypeInfo
ext
=
dataType
==
t1
&&
ext1
!=
null
?
ext1
:
dataType
==
t2
?
type2
.
getExtTypeInfo
()
:
null
;
return
TypeInfo
.
getTypeInfo
(
dataType
,
precision
,
scale
,
ext
);
}
/**
/**
* Check if a value is in the cache that is equal to this value. If yes,
* Check if a value is in the cache that is equal to this value. If yes,
* this value should be used to save memory. If the value is not in the
* this value should be used to save memory. If the value is not in the
...
@@ -697,7 +722,7 @@ public abstract class Value extends VersionedValue {
...
@@ -697,7 +722,7 @@ public abstract class Value extends VersionedValue {
}
}
/**
/**
* Co
mpare
a value to the specified type.
* Co
nvert
a value to the specified type.
*
*
* @param targetType the type of the returned value
* @param targetType the type of the returned value
* @param mode the mode
* @param mode the mode
...
@@ -708,7 +733,19 @@ public abstract class Value extends VersionedValue {
...
@@ -708,7 +733,19 @@ public abstract class Value extends VersionedValue {
}
}
/**
/**
* Compare a value to the specified type.
* Convert a value to the specified type.
*
* @param targetType the type of the returned value
* @param mode the conversion mode
* @param column the column (if any), used for to improve the error message if conversion fails
* @return the converted value
*/
public
Value
convertTo
(
TypeInfo
targetType
,
Mode
mode
,
Object
column
)
{
return
convertTo
(
targetType
.
getValueType
(),
-
1
,
mode
,
column
,
targetType
.
getExtTypeInfo
());
}
/**
* Convert a value to the specified type.
*
*
* @param targetType the type of the returned value
* @param targetType the type of the returned value
* @param precision the precision of the column to convert this value to.
* @param precision the precision of the column to convert this value to.
...
...
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
浏览文件 @
ea64e353
...
@@ -284,5 +284,20 @@ CREATE TABLE TEST(E ENUM('a', 'b'));
...
@@ -284,5 +284,20 @@ CREATE TABLE TEST(E ENUM('a', 'b'));
EXPLAIN
SELECT
*
FROM
TEST
WHERE
E
=
'a'
;
EXPLAIN
SELECT
*
FROM
TEST
WHERE
E
=
'a'
;
>>
SELECT
TEST
.
E
FROM
PUBLIC
.
TEST
/* PUBLIC.TEST.tableScan */
WHERE
E
=
'a'
>>
SELECT
TEST
.
E
FROM
PUBLIC
.
TEST
/* PUBLIC.TEST.tableScan */
WHERE
E
=
'a'
INSERT
INTO
TEST
VALUES
(
'a'
);
>
update
count
:
1
(
SELECT
*
FROM
TEST
A
)
UNION
ALL
(
SELECT
*
FROM
TEST
A
);
>
E
>
-
>
a
>
a
>
rows
:
2
(
SELECT
*
FROM
TEST
A
)
MINUS
(
SELECT
*
FROM
TEST
A
);
>
E
>
-
>
rows
:
0
DROP
TABLE
TEST
;
DROP
TABLE
TEST
;
>
ok
>
ok
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论