Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
6e2cfde3
提交
6e2cfde3
authored
3月 25, 2018
作者:
andrei
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'h2database/master' into non_blocking
上级
2067590e
3b852936
隐藏空白字符变更
内嵌
并排
正在显示
32 个修改的文件
包含
759 行增加
和
368 行删除
+759
-368
changelog.html
h2/src/docsrc/html/changelog.html
+28
-2
Parser.java
h2/src/main/org/h2/command/Parser.java
+17
-14
Aggregate.java
h2/src/main/org/h2/expression/Aggregate.java
+67
-92
AggregateData.java
h2/src/main/org/h2/expression/AggregateData.java
+10
-10
AggregateDataCollecting.java
h2/src/main/org/h2/expression/AggregateDataCollecting.java
+59
-0
AggregateDataMedian.java
h2/src/main/org/h2/expression/AggregateDataMedian.java
+3
-24
Operation.java
h2/src/main/org/h2/expression/Operation.java
+5
-1
TableFunction.java
h2/src/main/org/h2/expression/TableFunction.java
+4
-6
JdbcDatabaseMetaData.java
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
+118
-85
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+1
-1
Column.java
h2/src/main/org/h2/table/Column.java
+3
-3
MetaTable.java
h2/src/main/org/h2/table/MetaTable.java
+2
-1
TableView.java
h2/src/main/org/h2/table/TableView.java
+7
-1
SimpleResultSet.java
h2/src/main/org/h2/tools/SimpleResultSet.java
+7
-43
MergedResultSet.java
h2/src/main/org/h2/util/MergedResultSet.java
+11
-61
SimpleColumnInfo.java
h2/src/main/org/h2/util/SimpleColumnInfo.java
+80
-0
DataType.java
h2/src/main/org/h2/value/DataType.java
+5
-0
Value.java
h2/src/main/org/h2/value/Value.java
+10
-1
ValueEnumBase.java
h2/src/main/org/h2/value/ValueEnumBase.java
+1
-1
ValueGeometry.java
h2/src/main/org/h2/value/ValueGeometry.java
+16
-2
TestIndex.java
h2/src/test/org/h2/test/db/TestIndex.java
+27
-0
TestSpatial.java
h2/src/test/org/h2/test/db/TestSpatial.java
+5
-4
TestGetGeneratedKeys.java
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
+4
-0
TestMetaData.java
h2/src/test/org/h2/test/jdbc/TestMetaData.java
+10
-0
TestPreparedStatement.java
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
+1
-1
TestResultSet.java
h2/src/test/org/h2/test/jdbc/TestResultSet.java
+51
-0
enum.sql
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
+90
-0
mergeUsing.sql
h2/src/test/org/h2/test/scripts/dml/mergeUsing.sql
+42
-1
array-agg.sql
...est/org/h2/test/scripts/functions/aggregate/array-agg.sql
+35
-12
group-concat.sql
.../org/h2/test/scripts/functions/aggregate/group-concat.sql
+26
-0
information_schema.sql
h2/src/test/org/h2/test/scripts/information_schema.sql
+12
-0
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+2
-2
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
6e2cfde3
...
...
@@ -21,6 +21,32 @@ Change Log
<h2>
Next Version (unreleased)
</h2>
<ul>
<li>
Issue #992: 1.4.196+ client cannot use DatabaseMetaData with 1.4.195- server
</li>
<li>
Issue #1016: ResultSet.getObject() should return enum value, not ordinal
</li>
<li>
Issue #1012: NPE when querying INFORMATION_SCHEMA.COLUMNS on a view that references an ENUM column
</li>
<li>
Issue #1010: MERGE USING table not found with qualified table
</li>
<li>
PR #1009: Fix ARRAY_AGG with ORDER BY and refactor aggregates
</li>
<li>
Issue #1006: "Empty enums are not allowed" in 1.4.197 (mode=MYSQL)
</li>
<li>
PR #1007: Copy also SRID in ValueGeometry.getGeometry()
</li>
<li>
PR #1004: Preserve type names in more places especially for UUID
</li>
<li>
Issue #1000: Regression in INFORMATION_SCHEMA.CONSTRAINTS.CONSTRAINT_TYPE content
</li>
<li>
Issue #997: Can not delete from tables with enums
</li>
<li>
Issue #994: Too much column in result set for GENERATED_KEYS on table with DEFAULT
</li>
<li>
PR #993: Fix some compiler warnings and improve assert*() methods
</li>
<li>
PR #991: Generate shorter queries in JdbcDatabaseMetaData.getTables() and remove some dead code
</li>
<li>
PR #989: Fix more issues with range table and improve its documentation
</li>
</ul>
...
...
@@ -389,7 +415,7 @@ Change Log
</li>
<li>
PR #743: Change REGEXP_REPLACE mode for MariaDB and PostgreSQL
</li>
<li>
Issue#646 NPE in CREATE VIEW WITH RECURSIVE
&
NON_RECURSIVE CTE
<li>
Issue#646 NPE in CREATE VIEW WITH RECURSIVE
&
amp;
NON_RECURSIVE CTE
</li>
<li>
PR #738: Copy javadoc to *BackwardsCompat to fix building of documentation
</li>
...
...
@@ -696,7 +722,7 @@ changed from Types.OTHER (1111) to Types.TIMESTAMP_WITH_TIMEZONE (2014)
</li>
<li>
Issue #266: Spatial index not updating, fixed by merging PR #267
</li>
<li>
PR #302: add support for "with"-subqueries into "join"
&
"sub-query" statements
<li>
PR #302: add support for "with"-subqueries into "join"
&
amp;
"sub-query" statements
</li>
<li>
Issue #299: Nested derived tables did not always work as expected.
</li>
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
6e2cfde3
...
...
@@ -1150,11 +1150,8 @@ public class Parser {
TableFilter
sourceTableFilter
=
readSimpleTableFilter
(
0
,
excludeIdentifiers
);
command
.
setSourceTableFilter
(
sourceTableFilter
);
StringBuilder
buff
=
new
StringBuilder
(
"SELECT * FROM "
)
.
append
(
sourceTableFilter
.
getTable
().
getName
());
if
(
sourceTableFilter
.
getTableAlias
()
!=
null
)
{
buff
.
append
(
" AS "
).
append
(
sourceTableFilter
.
getTableAlias
());
}
StringBuilder
buff
=
new
StringBuilder
(
"SELECT * FROM "
);
appendTableWithSchemaAndAlias
(
buff
,
sourceTableFilter
.
getTable
(),
sourceTableFilter
.
getTableAlias
());
Prepared
preparedQuery
=
prepare
(
session
,
buff
.
toString
(),
null
/*paramValues*/
);
command
.
setQuery
((
Select
)
preparedQuery
);
...
...
@@ -1197,11 +1194,9 @@ public class Parser {
// build and prepare the targetMatchQuery ready to test each rows
// existence in the target table (using source row to match)
StringBuilder
targetMatchQuerySQL
=
new
StringBuilder
(
"SELECT _ROWID_ FROM "
+
command
.
getTargetTable
().
getName
());
if
(
command
.
getTargetTableFilter
().
getTableAlias
()
!=
null
)
{
targetMatchQuerySQL
.
append
(
" AS "
).
append
(
command
.
getTargetTableFilter
().
getTableAlias
());
}
StringBuilder
targetMatchQuerySQL
=
new
StringBuilder
(
"SELECT _ROWID_ FROM "
);
appendTableWithSchemaAndAlias
(
targetMatchQuerySQL
,
command
.
getTargetTable
(),
command
.
getTargetTableFilter
().
getTableAlias
());
targetMatchQuerySQL
.
append
(
" WHERE "
).
append
(
command
.
getOnCondition
().
getSQL
());
command
.
setTargetMatchQuery
(
...
...
@@ -1210,6 +1205,14 @@ public class Parser {
return
command
;
}
private
static
void
appendTableWithSchemaAndAlias
(
StringBuilder
buff
,
Table
table
,
String
alias
)
{
buff
.
append
(
quoteIdentifier
(
table
.
getSchema
().
getName
()))
.
append
(
'.'
).
append
(
quoteIdentifier
(
table
.
getName
()));
if
(
alias
!=
null
)
{
buff
.
append
(
" AS "
).
append
(
quoteIdentifier
(
alias
));
}
}
private
Insert
parseInsert
()
{
Insert
command
=
new
Insert
(
session
);
currentPrepared
=
command
;
...
...
@@ -2628,7 +2631,7 @@ public class Parser {
readExpression
(),
currentSelect
,
distinct
);
if
(
readIf
(
"ORDER"
))
{
read
(
"BY"
);
r
.
set
GroupConcatOrder
(
parseSimpleOrderList
());
r
.
set
OrderByList
(
parseSimpleOrderList
());
}
if
(
readIf
(
"SEPARATOR"
))
{
...
...
@@ -2642,7 +2645,7 @@ public class Parser {
r
.
setGroupConcatSeparator
(
readExpression
());
if
(
readIf
(
"ORDER"
))
{
read
(
"BY"
);
r
.
set
GroupConcatOrder
(
parseSimpleOrderList
());
r
.
set
OrderByList
(
parseSimpleOrderList
());
}
}
else
{
r
=
null
;
...
...
@@ -2654,7 +2657,7 @@ public class Parser {
readExpression
(),
currentSelect
,
distinct
);
if
(
readIf
(
"ORDER"
))
{
read
(
"BY"
);
r
.
set
ArrayAggOrder
(
parseSimpleOrderList
());
r
.
set
OrderByList
(
parseSimpleOrderList
());
}
}
else
{
boolean
distinct
=
readIf
(
"DISTINCT"
);
...
...
@@ -3027,7 +3030,7 @@ public class Parser {
int
index
=
currentValue
.
getInt
()
-
1
;
if
(
index
<
0
||
index
>=
Constants
.
MAX_PARAMETER_INDEX
)
{
throw
DbException
.
getInvalidValueException
(
"parameter index"
,
index
);
"parameter index"
,
index
+
1
);
}
if
(
indexedParameterList
.
size
()
<=
index
)
{
indexedParameterList
.
ensureCapacity
(
index
+
1
);
...
...
h2/src/main/org/h2/expression/Aggregate.java
浏览文件 @
6e2cfde3
...
...
@@ -6,12 +6,13 @@
package
org
.
h2
.
expression
;
import
java.util.ArrayList
;
import
java.util.
Collection
s
;
import
java.util.
Array
s
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.dml.Select
;
import
org.h2.command.dml.SelectOrderBy
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.index.Cursor
;
import
org.h2.index.Index
;
...
...
@@ -143,10 +144,8 @@ public class Aggregate extends Expression {
private
Expression
on
;
private
Expression
groupConcatSeparator
;
private
ArrayList
<
SelectOrderBy
>
groupConcatOrderList
;
private
ArrayList
<
SelectOrderBy
>
arrayAggOrderList
;
private
SortOrder
groupConcatSort
;
private
SortOrder
arrayOrderSort
;
private
ArrayList
<
SelectOrderBy
>
orderByList
;
private
SortOrder
orderBySort
;
private
int
dataType
,
scale
;
private
long
precision
;
private
int
displaySize
;
...
...
@@ -220,21 +219,12 @@ public class Aggregate extends Expression {
}
/**
* Set the order for GROUP_CONCAT() aggregate.
* Set the order for
ARRAY_AGG() or
GROUP_CONCAT() aggregate.
*
* @param orderBy the order by list
* @param orderBy
List
the order by list
*/
public
void
setGroupConcatOrder
(
ArrayList
<
SelectOrderBy
>
orderBy
)
{
this
.
groupConcatOrderList
=
orderBy
;
}
/**
* Set the order for ARRAY_AGG() aggregate.
*
* @param orderBy the order by list
*/
public
void
setArrayAggOrder
(
ArrayList
<
SelectOrderBy
>
orderBy
)
{
this
.
arrayAggOrderList
=
orderBy
;
public
void
setOrderByList
(
ArrayList
<
SelectOrderBy
>
orderByList
)
{
this
.
orderByList
=
orderByList
;
}
/**
...
...
@@ -255,12 +245,12 @@ public class Aggregate extends Expression {
this
.
filterCondition
=
filterCondition
;
}
private
SortOrder
initOrder
(
ArrayList
<
SelectOrderBy
>
orderList
,
Session
session
)
{
int
size
=
orderList
.
size
();
private
SortOrder
initOrder
(
Session
session
)
{
int
size
=
order
By
List
.
size
();
int
[]
index
=
new
int
[
size
];
int
[]
sortType
=
new
int
[
size
];
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
SelectOrderBy
o
=
orderList
.
get
(
i
);
SelectOrderBy
o
=
order
By
List
.
get
(
i
);
index
[
i
]
=
i
+
1
;
int
order
=
o
.
descending
?
SortOrder
.
DESCENDING
:
SortOrder
.
ASCENDING
;
sortType
[
i
]
=
order
;
...
...
@@ -268,6 +258,26 @@ public class Aggregate extends Expression {
return
new
SortOrder
(
session
.
getDatabase
(),
index
,
sortType
,
null
);
}
private
void
sortWithOrderBy
(
Value
[]
array
)
{
final
SortOrder
sortOrder
=
orderBySort
;
if
(
sortOrder
!=
null
)
{
Arrays
.
sort
(
array
,
new
Comparator
<
Value
>()
{
@Override
public
int
compare
(
Value
v1
,
Value
v2
)
{
return
sortOrder
.
compare
(((
ValueArray
)
v1
).
getList
(),
((
ValueArray
)
v2
).
getList
());
}
});
}
else
{
final
Database
database
=
select
.
getSession
().
getDatabase
();
Arrays
.
sort
(
array
,
new
Comparator
<
Value
>
()
{
@Override
public
int
compare
(
Value
v1
,
Value
v2
)
{
return
database
.
compare
(
v1
,
v2
);
}
});
}
}
@Override
public
void
updateAggregate
(
Session
session
)
{
// TODO aggregates: check nested MIN(MAX(ID)) and so on
...
...
@@ -296,12 +306,12 @@ public class Aggregate extends Expression {
if
(
type
==
AggregateType
.
GROUP_CONCAT
)
{
if
(
v
!=
ValueNull
.
INSTANCE
)
{
v
=
v
.
convertTo
(
Value
.
STRING
);
if
(
groupConcatOrder
List
!=
null
)
{
int
size
=
groupConcatOrder
List
.
size
();
if
(
orderBy
List
!=
null
)
{
int
size
=
orderBy
List
.
size
();
Value
[]
array
=
new
Value
[
1
+
size
];
array
[
0
]
=
v
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
SelectOrderBy
o
=
groupConcatOrder
List
.
get
(
i
);
SelectOrderBy
o
=
orderBy
List
.
get
(
i
);
array
[
i
+
1
]
=
o
.
expression
.
getValue
(
session
);
}
v
=
ValueArray
.
get
(
array
);
...
...
@@ -310,12 +320,12 @@ public class Aggregate extends Expression {
}
if
(
type
==
AggregateType
.
ARRAY_AGG
)
{
if
(
v
!=
ValueNull
.
INSTANCE
)
{
if
(
arrayAggOrder
List
!=
null
)
{
int
size
=
arrayAggOrder
List
.
size
();
if
(
orderBy
List
!=
null
)
{
int
size
=
orderBy
List
.
size
();
Value
[]
array
=
new
Value
[
1
+
size
];
array
[
0
]
=
v
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
SelectOrderBy
o
=
arrayAggOrder
List
.
get
(
i
);
SelectOrderBy
o
=
orderBy
List
.
get
(
i
);
array
[
i
+
1
]
=
o
.
expression
.
getValue
(
session
);
}
v
=
ValueArray
.
get
(
array
);
...
...
@@ -371,27 +381,18 @@ public class Aggregate extends Expression {
if
(
data
==
null
)
{
data
=
AggregateData
.
create
(
type
);
}
Value
v
=
data
.
getValue
(
session
.
getDatabase
(),
dataType
,
distinct
);
if
(
type
==
AggregateType
.
GROUP_CONCAT
)
{
ArrayList
<
Value
>
list
=
((
AggregateDataArrayCollecting
)
data
).
getList
();
if
(
list
==
null
||
list
.
isEmpty
()
)
{
Value
[]
array
=
((
AggregateDataCollecting
)
data
).
getArray
();
if
(
array
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
if
(
groupConcatOrderList
!=
null
)
{
final
SortOrder
sortOrder
=
groupConcatSort
;
Collections
.
sort
(
list
,
new
Comparator
<
Value
>()
{
@Override
public
int
compare
(
Value
v1
,
Value
v2
)
{
Value
[]
a1
=
((
ValueArray
)
v1
).
getList
();
Value
[]
a2
=
((
ValueArray
)
v2
).
getList
();
return
sortOrder
.
compare
(
a1
,
a2
);
}
});
if
(
orderByList
!=
null
||
distinct
)
{
sortWithOrderBy
(
array
);
}
StatementBuilder
buff
=
new
StatementBuilder
();
String
sep
=
groupConcatSeparator
==
null
?
","
:
groupConcatSeparator
.
getValue
(
session
).
getString
();
for
(
Value
val
:
list
)
{
for
(
Value
val
:
array
)
{
String
s
;
if
(
val
.
getType
()
==
Value
.
ARRAY
)
{
s
=
((
ValueArray
)
val
).
getList
()[
0
].
getString
();
...
...
@@ -406,26 +407,23 @@ public class Aggregate extends Expression {
}
buff
.
append
(
s
);
}
v
=
ValueString
.
get
(
buff
.
toString
());
return
ValueString
.
get
(
buff
.
toString
());
}
else
if
(
type
==
AggregateType
.
ARRAY_AGG
)
{
ArrayList
<
Value
>
list
=
((
AggregateDataArrayCollecting
)
data
).
getList
();
if
(
list
==
null
||
list
.
isEmpty
()
)
{
Value
[]
array
=
((
AggregateDataCollecting
)
data
).
getArray
();
if
(
array
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
if
(
arrayAggOrderList
!=
null
)
{
final
SortOrder
sortOrder
=
arrayOrderSort
;
Collections
.
sort
(
list
,
new
Comparator
<
Value
>()
{
@Override
public
int
compare
(
Value
v1
,
Value
v2
)
{
Value
[]
a1
=
((
ValueArray
)
v1
).
getList
();
Value
[]
a2
=
((
ValueArray
)
v2
).
getList
();
return
sortOrder
.
compare
(
a1
,
a2
);
}
});
if
(
orderByList
!=
null
||
distinct
)
{
sortWithOrderBy
(
array
);
}
if
(
orderByList
!=
null
)
{
for
(
int
i
=
0
;
i
<
array
.
length
;
i
++)
{
array
[
i
]
=
((
ValueArray
)
array
[
i
]).
getList
()[
0
];
}
}
v
=
ValueArray
.
get
(
list
.
toArray
(
new
Value
[
list
.
size
()])
);
return
ValueArray
.
get
(
array
);
}
return
v
;
return
data
.
getValue
(
session
.
getDatabase
(),
dataType
,
distinct
)
;
}
@Override
...
...
@@ -438,13 +436,8 @@ public class Aggregate extends Expression {
if
(
on
!=
null
)
{
on
.
mapColumns
(
resolver
,
level
);
}
if
(
groupConcatOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
groupConcatOrderList
)
{
o
.
expression
.
mapColumns
(
resolver
,
level
);
}
}
if
(
arrayAggOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
arrayAggOrderList
)
{
if
(
orderByList
!=
null
)
{
for
(
SelectOrderBy
o
:
orderByList
)
{
o
.
expression
.
mapColumns
(
resolver
,
level
);
}
}
...
...
@@ -465,17 +458,11 @@ public class Aggregate extends Expression {
precision
=
on
.
getPrecision
();
displaySize
=
on
.
getDisplaySize
();
}
if
(
groupConcatOrder
List
!=
null
)
{
for
(
SelectOrderBy
o
:
groupConcatOrder
List
)
{
if
(
orderBy
List
!=
null
)
{
for
(
SelectOrderBy
o
:
orderBy
List
)
{
o
.
expression
=
o
.
expression
.
optimize
(
session
);
}
groupConcatSort
=
initOrder
(
groupConcatOrderList
,
session
);
}
if
(
arrayAggOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
arrayAggOrderList
)
{
o
.
expression
=
o
.
expression
.
optimize
(
session
);
}
arrayOrderSort
=
initOrder
(
arrayAggOrderList
,
session
);
orderBySort
=
initOrder
(
session
);
}
if
(
groupConcatSeparator
!=
null
)
{
groupConcatSeparator
=
groupConcatSeparator
.
optimize
(
session
);
...
...
@@ -564,13 +551,8 @@ public class Aggregate extends Expression {
if
(
on
!=
null
)
{
on
.
setEvaluatable
(
tableFilter
,
b
);
}
if
(
groupConcatOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
groupConcatOrderList
)
{
o
.
expression
.
setEvaluatable
(
tableFilter
,
b
);
}
}
if
(
arrayAggOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
arrayAggOrderList
)
{
if
(
orderByList
!=
null
)
{
for
(
SelectOrderBy
o
:
orderByList
)
{
o
.
expression
.
setEvaluatable
(
tableFilter
,
b
);
}
}
...
...
@@ -603,9 +585,9 @@ public class Aggregate extends Expression {
buff
.
append
(
"DISTINCT "
);
}
buff
.
append
(
on
.
getSQL
());
if
(
groupConcatOrder
List
!=
null
)
{
if
(
orderBy
List
!=
null
)
{
buff
.
append
(
" ORDER BY "
);
for
(
SelectOrderBy
o
:
groupConcatOrder
List
)
{
for
(
SelectOrderBy
o
:
orderBy
List
)
{
buff
.
appendExceptFirst
(
", "
);
buff
.
append
(
o
.
expression
.
getSQL
());
if
(
o
.
descending
)
{
...
...
@@ -629,9 +611,9 @@ public class Aggregate extends Expression {
buff
.
append
(
"DISTINCT "
);
}
buff
.
append
(
on
.
getSQL
());
if
(
arrayAggOrder
List
!=
null
)
{
if
(
orderBy
List
!=
null
)
{
buff
.
append
(
" ORDER BY "
);
for
(
SelectOrderBy
o
:
arrayAggOrder
List
)
{
for
(
SelectOrderBy
o
:
orderBy
List
)
{
buff
.
appendExceptFirst
(
", "
);
buff
.
append
(
o
.
expression
.
getSQL
());
if
(
o
.
descending
)
{
...
...
@@ -765,15 +747,8 @@ public class Aggregate extends Expression {
!
groupConcatSeparator
.
isEverything
(
visitor
))
{
return
false
;
}
if
(
groupConcatOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
groupConcatOrderList
)
{
if
(!
o
.
expression
.
isEverything
(
visitor
))
{
return
false
;
}
}
}
if
(
arrayAggOrderList
!=
null
)
{
for
(
SelectOrderBy
o
:
arrayAggOrderList
)
{
if
(
orderByList
!=
null
)
{
for
(
SelectOrderBy
o
:
orderByList
)
{
if
(!
o
.
expression
.
isEverything
(
visitor
))
{
return
false
;
}
...
...
h2/src/main/org/h2/expression/AggregateData.java
浏览文件 @
6e2cfde3
...
...
@@ -21,21 +21,21 @@ abstract class AggregateData {
* @return the aggregate data object of the specified type
*/
static
AggregateData
create
(
AggregateType
aggregateType
)
{
if
(
aggregateType
==
AggregateType
.
SELECTIVITY
)
{
switch
(
aggregateType
)
{
case
SELECTIVITY:
return
new
AggregateDataSelectivity
();
}
else
if
(
aggregateType
==
AggregateType
.
GROUP_CONCAT
)
{
return
new
AggregateDataArrayCollecting
();
}
else
if
(
aggregateType
==
AggregateType
.
ARRAY_AGG
)
{
return
new
AggregateDataArrayCollecting
();
}
else
if
(
aggregateType
==
AggregateType
.
COUNT_ALL
)
{
case
GROUP_CONCAT:
case
ARRAY_AGG:
return
new
AggregateDataCollecting
();
case
COUNT_ALL:
return
new
AggregateDataCountAll
();
}
else
if
(
aggregateType
==
AggregateType
.
COUNT
)
{
case
COUNT:
return
new
AggregateDataCount
();
}
else
if
(
aggregateType
==
AggregateType
.
HISTOGRAM
)
{
case
HISTOGRAM:
return
new
AggregateDataHistogram
();
}
else
if
(
aggregateType
==
AggregateType
.
MEDIAN
)
{
case
MEDIAN:
return
new
AggregateDataMedian
();
}
else
{
default
:
return
new
AggregateDataDefault
(
aggregateType
);
}
}
...
...
h2/src/main/org/h2/expression/AggregateData
Array
Collecting.java
→
h2/src/main/org/h2/expression/AggregateDataCollecting.java
浏览文件 @
6e2cfde3
...
...
@@ -6,55 +6,54 @@
package
org
.
h2
.
expression
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashSet
;
import
org.h2.engine.Database
;
import
org.h2.util.New
;
import
org.h2.util.ValueHashMap
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* Data stored while calculating a GROUP_CONCAT/ARRAY_AGG aggregate.
* Data stored while calculating an aggregate that needs collecting of all
* values.
*
* <p>
* NULL values are not collected. {@link #getValue(Database, int, boolean)}
* method returns {@code null}. Use {@link #getArray()} for instances of this
* class instead. Notice that subclasses like {@link AggregateDataMedian} may
* override {@link #getValue(Database, int, boolean)} to return useful result.
* </p>
*/
class
AggregateDataArrayCollecting
extends
AggregateData
{
private
ArrayList
<
Value
>
list
;
private
ValueHashMap
<
AggregateDataArrayCollecting
>
distinctValues
;
class
AggregateDataCollecting
extends
AggregateData
{
Collection
<
Value
>
values
;
@Override
void
add
(
Database
database
,
int
dataType
,
boolean
distinct
,
Value
v
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
;
}
if
(
distinct
)
{
if
(
distinctValues
==
null
)
{
distinctValues
=
ValueHashMap
.
newInstance
();
}
distinctValues
.
put
(
v
,
this
);
return
;
}
if
(
list
==
null
)
{
list
=
New
.
arrayList
();
Collection
<
Value
>
c
=
values
;
if
(
c
==
null
)
{
values
=
c
=
distinct
?
new
HashSet
<
Value
>()
:
new
ArrayList
<
Value
>();
}
list
.
add
(
v
);
c
.
add
(
v
);
}
@Override
Value
getValue
(
Database
database
,
int
dataType
,
boolean
distinct
)
{
if
(
distinct
)
{
distinct
(
database
,
dataType
);
}
return
null
;
}
ArrayList
<
Value
>
getList
()
{
return
list
;
}
private
void
distinct
(
Database
database
,
int
dataType
)
{
if
(
distinctValues
==
null
)
{
return
;
}
for
(
Value
v
:
distinctValues
.
keys
())
{
add
(
database
,
dataType
,
false
,
v
);
/**
* Returns array with values or {@code null}.
*
* @return array with values or {@code null}
*/
Value
[]
getArray
()
{
Collection
<
Value
>
values
=
this
.
values
;
if
(
values
==
null
)
{
return
null
;
}
return
values
.
toArray
(
new
Value
[
0
]);
}
}
h2/src/main/org/h2/expression/AggregateDataMedian.java
浏览文件 @
6e2cfde3
...
...
@@ -8,9 +8,7 @@ package org.h2.expression;
import
java.math.BigDecimal
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
...
...
@@ -39,9 +37,7 @@ import org.h2.value.ValueTimestampTimeZone;
/**
* Data stored while calculating a MEDIAN aggregate.
*/
class
AggregateDataMedian
extends
AggregateData
{
private
Collection
<
Value
>
values
;
class
AggregateDataMedian
extends
AggregateDataCollecting
{
private
static
boolean
isNullsLast
(
Index
index
)
{
IndexColumn
ic
=
index
.
getIndexColumns
()[
0
];
int
sortType
=
ic
.
sortType
;
...
...
@@ -168,29 +164,12 @@ class AggregateDataMedian extends AggregateData {
return
v
;
}
@Override
void
add
(
Database
database
,
int
dataType
,
boolean
distinct
,
Value
v
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
;
}
Collection
<
Value
>
c
=
values
;
if
(
c
==
null
)
{
values
=
c
=
distinct
?
new
HashSet
<
Value
>()
:
new
ArrayList
<
Value
>();
}
c
.
add
(
v
);
}
@Override
Value
getValue
(
Database
database
,
int
dataType
,
boolean
distinct
)
{
Collection
<
Value
>
c
=
values
;
// Non-null collection cannot be empty here
if
(
c
==
null
)
{
Value
[]
a
=
getArray
();
if
(
a
==
null
)
{
return
ValueNull
.
INSTANCE
;
}
if
(
distinct
&&
c
instanceof
ArrayList
)
{
c
=
new
HashSet
<>(
c
);
}
Value
[]
a
=
c
.
toArray
(
new
Value
[
0
]);
final
CompareMode
mode
=
database
.
getCompareMode
();
Arrays
.
sort
(
a
,
new
Comparator
<
Value
>()
{
@Override
...
...
h2/src/main/org/h2/expression/Operation.java
浏览文件 @
6e2cfde3
...
...
@@ -186,6 +186,8 @@ public class Operation extends Expression {
dataType
=
left
.
getType
();
if
(
dataType
==
Value
.
UNKNOWN
)
{
dataType
=
Value
.
DECIMAL
;
}
else
if
(
dataType
==
Value
.
ENUM
)
{
dataType
=
Value
.
INT
;
}
break
;
case
CONCAT:
...
...
@@ -315,7 +317,9 @@ public class Operation extends Expression {
DataType
.
getDataType
(
r
).
name
);
}
else
{
dataType
=
Value
.
getHigherOrder
(
l
,
r
);
if
(
DataType
.
isStringType
(
dataType
)
&&
if
(
dataType
==
Value
.
ENUM
)
{
dataType
=
Value
.
INT
;
}
else
if
(
DataType
.
isStringType
(
dataType
)
&&
session
.
getDatabase
().
getMode
().
allowPlusForStringConcat
)
{
opType
=
OpType
.
CONCAT
;
}
...
...
h2/src/main/org/h2/expression/TableFunction.java
浏览文件 @
6e2cfde3
...
...
@@ -135,14 +135,12 @@ public class TableFunction extends Function {
simple
.
setAutoClose
(
false
);
for
(
int
i
=
0
;
i
<
columnCount
;
i
++)
{
String
name
=
rs
.
getColumnName
(
i
);
/*
* TODO Some types, such as Value.BYTES and Value.UUID are mapped to the same
* SQL type and we can lose real type here.
*/
int
sqlType
=
DataType
.
convertTypeToSQLType
(
rs
.
getColumnType
(
i
));
DataType
dataType
=
DataType
.
getDataType
(
rs
.
getColumnType
(
i
));
int
sqlType
=
dataType
.
sqlType
;
String
sqlTypeName
=
dataType
.
name
;
int
precision
=
MathUtils
.
convertLongToInt
(
rs
.
getColumnPrecision
(
i
));
int
scale
=
rs
.
getColumnScale
(
i
);
simple
.
addColumn
(
name
,
sqlType
,
precision
,
scale
);
simple
.
addColumn
(
name
,
sqlType
,
sqlTypeName
,
precision
,
scale
);
}
rs
.
reset
();
for
(
int
i
=
0
;
i
<
maxrows
&&
rs
.
next
();
i
++)
{
...
...
h2/src/main/org/h2/jdbc/JdbcDatabaseMetaData.java
浏览文件 @
6e2cfde3
...
...
@@ -14,11 +14,16 @@ import java.sql.SQLException;
import
java.sql.Types
;
import
java.util.Arrays
;
import
java.util.Properties
;
import
org.h2.command.CommandInterface
;
import
org.h2.engine.Constants
;
import
org.h2.engine.SessionInterface
;
import
org.h2.engine.SessionRemote
;
import
org.h2.engine.SysProperties
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.message.TraceObject
;
import
org.h2.result.ResultInterface
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
...
...
@@ -31,6 +36,11 @@ public class JdbcDatabaseMetaData extends TraceObject implements
private
final
JdbcConnection
conn
;
/**
* Whether database has support for synonyms ({@code null} if not yet known).
*/
private
Boolean
hasSynonyms
;
JdbcDatabaseMetaData
(
JdbcConnection
conn
,
Trace
trace
,
int
id
)
{
setTrace
(
trace
,
TraceObject
.
DATABASE_META_DATA
,
id
);
this
.
conn
=
conn
;
...
...
@@ -105,6 +115,33 @@ public class JdbcDatabaseMetaData extends TraceObject implements
return
Constants
.
getFullVersion
();
}
private
boolean
hasSynonyms
()
{
Boolean
hasSynonyms
=
this
.
hasSynonyms
;
if
(
hasSynonyms
==
null
)
{
SessionInterface
si
=
conn
.
getSession
();
if
(
si
instanceof
SessionRemote
)
{
SessionRemote
sr
=
(
SessionRemote
)
si
;
int
clientVersion
=
sr
.
getClientVersion
();
if
(
clientVersion
>=
Constants
.
TCP_PROTOCOL_VERSION_17
)
{
hasSynonyms
=
true
;
}
else
if
(
clientVersion
<=
Constants
.
TCP_PROTOCOL_VERSION_15
)
{
hasSynonyms
=
false
;
}
else
{
// 1.4.194-1.4.196
CommandInterface
c
=
sr
.
prepareCommand
(
"CALL H2VERSION()"
,
Integer
.
MAX_VALUE
);
ResultInterface
result
=
c
.
executeQuery
(
0
,
false
);
result
.
next
();
String
s
=
result
.
currentRow
()[
0
].
getString
();
result
.
close
();
hasSynonyms
=
"1.4.196"
.
equals
(
s
);
}
}
else
{
hasSynonyms
=
true
;
}
this
.
hasSynonyms
=
hasSynonyms
;
}
return
hasSynonyms
;
}
/**
* Gets the list of tables in the database. The result set is sorted by
* TABLE_TYPE, TABLE_SCHEM, and TABLE_NAME.
...
...
@@ -144,7 +181,7 @@ public class JdbcDatabaseMetaData extends TraceObject implements
}
checkClosed
();
int
typesLength
=
types
!=
null
?
types
.
length
:
0
;
boolean
includeSynonyms
=
types
==
null
||
Arrays
.
asList
(
types
).
contains
(
"SYNONYM"
);
boolean
includeSynonyms
=
hasSynonyms
()
&&
(
types
==
null
||
Arrays
.
asList
(
types
).
contains
(
"SYNONYM"
)
);
// (1024 - 16) is enough for the most cases
StringBuilder
select
=
new
StringBuilder
(
1008
);
...
...
@@ -279,7 +316,72 @@ public class JdbcDatabaseMetaData extends TraceObject implements
+
quote
(
columnNamePattern
)+
");"
);
}
checkClosed
();
String
tableSql
=
"SELECT "
boolean
includeSynonyms
=
hasSynonyms
();
StringBuilder
select
=
new
StringBuilder
(
2432
);
if
(
includeSynonyms
)
{
select
.
append
(
"SELECT "
+
"TABLE_CAT, "
+
"TABLE_SCHEM, "
+
"TABLE_NAME, "
+
"COLUMN_NAME, "
+
"DATA_TYPE, "
+
"TYPE_NAME, "
+
"COLUMN_SIZE, "
+
"BUFFER_LENGTH, "
+
"DECIMAL_DIGITS, "
+
"NUM_PREC_RADIX, "
+
"NULLABLE, "
+
"REMARKS, "
+
"COLUMN_DEF, "
+
"SQL_DATA_TYPE, "
+
"SQL_DATETIME_SUB, "
+
"CHAR_OCTET_LENGTH, "
+
"ORDINAL_POSITION, "
+
"IS_NULLABLE, "
+
"SCOPE_CATALOG, "
+
"SCOPE_SCHEMA, "
+
"SCOPE_TABLE, "
+
"SOURCE_DATA_TYPE, "
+
"IS_AUTOINCREMENT, "
+
"SCOPE_CATLOG "
+
"FROM ("
+
"SELECT "
+
"s.SYNONYM_CATALOG TABLE_CAT, "
+
"s.SYNONYM_SCHEMA TABLE_SCHEM, "
+
"s.SYNONYM_NAME TABLE_NAME, "
+
"c.COLUMN_NAME, "
+
"c.DATA_TYPE, "
+
"c.TYPE_NAME, "
+
"c.CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, "
+
"c.CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, "
+
"c.NUMERIC_SCALE DECIMAL_DIGITS, "
+
"c.NUMERIC_PRECISION_RADIX NUM_PREC_RADIX, "
+
"c.NULLABLE, "
+
"c.REMARKS, "
+
"c.COLUMN_DEFAULT COLUMN_DEF, "
+
"c.DATA_TYPE SQL_DATA_TYPE, "
+
"ZERO() SQL_DATETIME_SUB, "
+
"c.CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH, "
+
"c.ORDINAL_POSITION, "
+
"c.IS_NULLABLE IS_NULLABLE, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATALOG, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_SCHEMA, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_TABLE, "
+
"c.SOURCE_DATA_TYPE, "
+
"CASE WHEN c.SEQUENCE_NAME IS NULL THEN "
+
"CAST(?1 AS VARCHAR) ELSE CAST(?2 AS VARCHAR) END IS_AUTOINCREMENT, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATLOG "
+
"FROM INFORMATION_SCHEMA.COLUMNS c JOIN INFORMATION_SCHEMA.SYNONYMS s ON "
+
"s.SYNONYM_FOR = c.TABLE_NAME "
+
"AND s.SYNONYM_FOR_SCHEMA = c.TABLE_SCHEMA "
+
"WHERE s.SYNONYM_CATALOG LIKE ?3 ESCAPE ?7 "
+
"AND s.SYNONYM_SCHEMA LIKE ?4 ESCAPE ?7 "
+
"AND s.SYNONYM_NAME LIKE ?5 ESCAPE ?7 "
+
"AND c.COLUMN_NAME LIKE ?6 ESCAPE ?7 "
+
"UNION "
);
}
select
.
append
(
"SELECT "
+
"TABLE_CATALOG TABLE_CAT, "
+
"TABLE_SCHEMA TABLE_SCHEM, "
+
"TABLE_NAME, "
...
...
@@ -303,94 +405,25 @@ public class JdbcDatabaseMetaData extends TraceObject implements
+
"CAST(SOURCE_DATA_TYPE AS VARCHAR) SCOPE_TABLE, "
+
"SOURCE_DATA_TYPE, "
+
"CASE WHEN SEQUENCE_NAME IS NULL THEN "
+
"CAST(?
AS VARCHAR) ELSE CAST(?
AS VARCHAR) END IS_AUTOINCREMENT, "
+
"CAST(?
1 AS VARCHAR) ELSE CAST(?2
AS VARCHAR) END IS_AUTOINCREMENT, "
+
"CAST(SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATLOG "
+
"FROM INFORMATION_SCHEMA.COLUMNS "
+
"WHERE TABLE_CATALOG LIKE ? ESCAPE ? "
+
"AND TABLE_SCHEMA LIKE ? ESCAPE ? "
+
"AND TABLE_NAME LIKE ? ESCAPE ? "
+
"AND COLUMN_NAME LIKE ? ESCAPE ? "
+
"ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"
;
String
synonymSql
=
"SELECT "
+
"s.SYNONYM_CATALOG TABLE_CAT, "
+
"s.SYNONYM_SCHEMA TABLE_SCHEM, "
+
"s.SYNONYM_NAME TABLE_NAME, "
+
"c.COLUMN_NAME, "
+
"c.DATA_TYPE, "
+
"c.TYPE_NAME, "
+
"c.CHARACTER_MAXIMUM_LENGTH COLUMN_SIZE, "
+
"c.CHARACTER_MAXIMUM_LENGTH BUFFER_LENGTH, "
+
"c.NUMERIC_SCALE DECIMAL_DIGITS, "
+
"c.NUMERIC_PRECISION_RADIX NUM_PREC_RADIX, "
+
"c.NULLABLE, "
+
"c.REMARKS, "
+
"c.COLUMN_DEFAULT COLUMN_DEF, "
+
"c.DATA_TYPE SQL_DATA_TYPE, "
+
"ZERO() SQL_DATETIME_SUB, "
+
"c.CHARACTER_OCTET_LENGTH CHAR_OCTET_LENGTH, "
+
"c.ORDINAL_POSITION, "
+
"c.IS_NULLABLE IS_NULLABLE, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATALOG, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_SCHEMA, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_TABLE, "
+
"c.SOURCE_DATA_TYPE, "
+
"CASE WHEN c.SEQUENCE_NAME IS NULL THEN "
+
"CAST(? AS VARCHAR) ELSE CAST(? AS VARCHAR) END IS_AUTOINCREMENT, "
+
"CAST(c.SOURCE_DATA_TYPE AS VARCHAR) SCOPE_CATLOG "
+
"FROM INFORMATION_SCHEMA.COLUMNS c JOIN INFORMATION_SCHEMA.SYNONYMS s ON "
+
"s.SYNONYM_FOR = c.TABLE_NAME "
+
"AND s.SYNONYM_FOR_SCHEMA = c.TABLE_SCHEMA "
+
"WHERE s.SYNONYM_CATALOG LIKE ? ESCAPE ? "
+
"AND s.SYNONYM_SCHEMA LIKE ? ESCAPE ? "
+
"AND s.SYNONYM_NAME LIKE ? ESCAPE ? "
+
"AND c.COLUMN_NAME LIKE ? ESCAPE ? "
;
PreparedStatement
prep
=
conn
.
prepareAutoCloseStatement
(
"SELECT "
+
"TABLE_CAT, "
+
"TABLE_SCHEM, "
+
"TABLE_NAME, "
+
"COLUMN_NAME, "
+
"DATA_TYPE, "
+
"TYPE_NAME, "
+
"COLUMN_SIZE, "
+
"BUFFER_LENGTH, "
+
"DECIMAL_DIGITS, "
+
"NUM_PREC_RADIX, "
+
"NULLABLE, "
+
"REMARKS, "
+
"COLUMN_DEF, "
+
"SQL_DATA_TYPE, "
+
"SQL_DATETIME_SUB, "
+
"CHAR_OCTET_LENGTH, "
+
"ORDINAL_POSITION, "
+
"IS_NULLABLE, "
+
"SCOPE_CATALOG, "
+
"SCOPE_SCHEMA, "
+
"SCOPE_TABLE, "
+
"SOURCE_DATA_TYPE, "
+
"IS_AUTOINCREMENT, "
+
"SCOPE_CATLOG "
+
"FROM (("
+
tableSql
+
") UNION ("
+
synonymSql
+
")) ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"
);
+
"WHERE TABLE_CATALOG LIKE ?3 ESCAPE ?7 "
+
"AND TABLE_SCHEMA LIKE ?4 ESCAPE ?7 "
+
"AND TABLE_NAME LIKE ?5 ESCAPE ?7 "
+
"AND COLUMN_NAME LIKE ?6 ESCAPE ?7"
);
if
(
includeSynonyms
)
{
select
.
append
(
')'
);
}
PreparedStatement
prep
=
conn
.
prepareAutoCloseStatement
(
select
.
append
(
" ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"
).
toString
());
prep
.
setString
(
1
,
"NO"
);
prep
.
setString
(
2
,
"YES"
);
prep
.
setString
(
3
,
getCatalogPattern
(
catalogPattern
));
prep
.
setString
(
4
,
"\\"
);
prep
.
setString
(
5
,
getSchemaPattern
(
schemaPattern
));
prep
.
setString
(
6
,
"\\"
);
prep
.
setString
(
7
,
getPattern
(
tableNamePattern
));
prep
.
setString
(
8
,
"\\"
);
prep
.
setString
(
9
,
getPattern
(
columnNamePattern
));
prep
.
setString
(
10
,
"\\"
);
prep
.
setString
(
11
,
"NO"
);
prep
.
setString
(
12
,
"YES"
);
prep
.
setString
(
13
,
getCatalogPattern
(
catalogPattern
));
prep
.
setString
(
14
,
"\\"
);
prep
.
setString
(
15
,
getSchemaPattern
(
schemaPattern
));
prep
.
setString
(
16
,
"\\"
);
prep
.
setString
(
17
,
getPattern
(
tableNamePattern
));
prep
.
setString
(
18
,
"\\"
);
prep
.
setString
(
19
,
getPattern
(
columnNamePattern
));
prep
.
setString
(
20
,
"\\"
);
prep
.
setString
(
4
,
getSchemaPattern
(
schemaPattern
));
prep
.
setString
(
5
,
getPattern
(
tableNamePattern
));
prep
.
setString
(
6
,
getPattern
(
columnNamePattern
));
prep
.
setString
(
7
,
"\\"
);
return
prep
.
executeQuery
();
}
catch
(
Exception
e
)
{
throw
logAndConvert
(
e
);
...
...
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
浏览文件 @
6e2cfde3
...
...
@@ -323,7 +323,7 @@ public final class MVSecondaryIndex extends BaseIndex implements MVIndex {
int
idx
=
c
.
getColumnId
();
Value
v
=
r
.
getValue
(
idx
);
if
(
v
!=
null
)
{
array
[
i
]
=
v
.
convertTo
(
c
.
getType
());
array
[
i
]
=
v
.
convertTo
(
c
.
getType
()
,
-
1
,
null
,
null
,
c
.
getEnumerators
()
);
}
}
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
r
.
getKey
());
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
6e2cfde3
...
...
@@ -334,11 +334,12 @@ public class Column {
synchronized
(
this
)
{
localDefaultExpression
=
defaultExpression
;
}
Mode
mode
=
session
.
getDatabase
().
getMode
();
if
(
value
==
null
)
{
if
(
localDefaultExpression
==
null
)
{
value
=
ValueNull
.
INSTANCE
;
}
else
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
typ
e
);
value
=
convert
(
localDefaultExpression
.
getValue
(
session
),
mod
e
);
if
(!
localDefaultExpression
.
isConstant
())
{
session
.
getGeneratedKeys
().
add
(
this
);
}
...
...
@@ -347,10 +348,9 @@ public class Column {
}
}
}
Mode
mode
=
session
.
getDatabase
().
getMode
();
if
(
value
==
ValueNull
.
INSTANCE
)
{
if
(
convertNullToDefault
)
{
value
=
localDefaultExpression
.
getValue
(
session
).
convertTo
(
typ
e
);
value
=
convert
(
localDefaultExpression
.
getValue
(
session
),
mod
e
);
if
(!
localDefaultExpression
.
isConstant
())
{
session
.
getGeneratedKeys
().
add
(
this
);
}
...
...
h2/src/main/org/h2/table/MetaTable.java
浏览文件 @
6e2cfde3
...
...
@@ -1688,7 +1688,8 @@ public class MetaTable extends Table {
// CONSTRAINT_NAME
identifier
(
constraint
.
getName
()),
// CONSTRAINT_TYPE
constraintType
.
toString
(),
constraintType
==
Constraint
.
Type
.
PRIMARY_KEY
?
constraintType
.
getSqlName
()
:
constraintType
.
name
(),
// TABLE_CATALOG
catalog
,
// TABLE_SCHEMA
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
6e2cfde3
...
...
@@ -193,7 +193,13 @@ public class TableView extends Table {
long
precision
=
expr
.
getPrecision
();
int
scale
=
expr
.
getScale
();
int
displaySize
=
expr
.
getDisplaySize
();
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
);
String
[]
enumerators
=
null
;
if
(
type
==
Value
.
ENUM
)
{
if
(
expr
instanceof
ExpressionColumn
)
{
enumerators
=
((
ExpressionColumn
)
expr
).
getColumn
().
getEnumerators
();
}
}
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
enumerators
);
col
.
setTable
(
this
,
i
);
// Fetch check constraint from view column source
ExpressionColumn
fromColumn
=
null
;
...
...
h2/src/main/org/h2/tools/SimpleResultSet.java
浏览文件 @
6e2cfde3
...
...
@@ -38,6 +38,7 @@ import org.h2.util.Bits;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.SimpleColumnInfo
;
import
org.h2.util.Utils
;
import
org.h2.value.DataType
;
...
...
@@ -67,7 +68,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
private
int
rowId
=
-
1
;
private
boolean
wasNull
;
private
SimpleRowSource
source
;
private
ArrayList
<
Column
>
columns
=
New
.
arrayList
();
private
ArrayList
<
SimpleColumnInfo
>
columns
=
New
.
arrayList
();
private
boolean
autoClose
=
true
;
/**
...
...
@@ -123,13 +124,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
if
(
name
==
null
)
{
name
=
"C"
+
(
columns
.
size
()
+
1
);
}
Column
column
=
new
Column
();
column
.
name
=
name
;
column
.
sqlType
=
sqlType
;
column
.
precision
=
precision
;
column
.
scale
=
scale
;
column
.
sqlTypeName
=
sqlTypeName
;
columns
.
add
(
column
);
columns
.
add
(
new
SimpleColumnInfo
(
name
,
sqlType
,
sqlTypeName
,
precision
,
scale
));
}
/**
...
...
@@ -1012,7 +1007,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
if
(
o
==
null
)
{
return
null
;
}
switch
(
columns
.
get
(
columnIndex
-
1
).
sqlT
ype
)
{
switch
(
columns
.
get
(
columnIndex
-
1
).
t
ype
)
{
case
Types
.
CLOB
:
Clob
c
=
(
Clob
)
o
;
return
c
.
getSubString
(
1
,
MathUtils
.
convertLongToInt
(
c
.
length
()));
...
...
@@ -1868,7 +1863,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
*/
@Override
public
int
getColumnType
(
int
columnIndex
)
throws
SQLException
{
return
getColumn
(
columnIndex
-
1
).
sqlT
ype
;
return
getColumn
(
columnIndex
-
1
).
t
ype
;
}
/**
...
...
@@ -2045,7 +2040,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
*/
@Override
public
String
getColumnTypeName
(
int
columnIndex
)
throws
SQLException
{
return
getColumn
(
columnIndex
-
1
).
sqlT
ypeName
;
return
getColumn
(
columnIndex
-
1
).
t
ypeName
;
}
/**
...
...
@@ -2295,7 +2290,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
return
o
;
}
private
Column
getColumn
(
int
i
)
throws
SQLException
{
private
SimpleColumnInfo
getColumn
(
int
i
)
throws
SQLException
{
checkColumnIndex
(
i
+
1
);
return
columns
.
get
(
i
);
}
...
...
@@ -2355,37 +2350,6 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
return
autoClose
;
}
/**
* This class holds the data of a result column.
*/
static
class
Column
{
/**
* The column label.
*/
String
name
;
/**
* The column type Name
*/
String
sqlTypeName
;
/**
* The SQL type.
*/
int
sqlType
;
/**
* The precision.
*/
int
precision
;
/**
* The scale.
*/
int
scale
;
}
/**
* A simple array implementation,
* backed by an object array
...
...
h2/src/main/org/h2/util/MergedResultSet.java
浏览文件 @
6e2cfde3
...
...
@@ -24,59 +24,9 @@ import org.h2.tools.SimpleResultSet;
* that have {@code NAME} column should also define it with the same type.
*/
public
final
class
MergedResultSet
{
/**
* Metadata of a column.
*/
private
static
final
class
ColumnInfo
{
final
String
name
;
final
int
type
;
final
int
precision
;
final
int
scale
;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
ColumnInfo
(
String
name
,
int
type
,
int
precision
,
int
scale
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
precision
=
precision
;
this
.
scale
=
scale
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
ColumnInfo
other
=
(
ColumnInfo
)
obj
;
return
name
.
equals
(
other
.
name
);
}
@Override
public
int
hashCode
()
{
return
name
.
hashCode
();
}
}
private
final
ArrayList
<
Map
<
ColumnInfo
,
Object
>>
data
=
New
.
arrayList
();
private
final
ArrayList
<
Map
<
SimpleColumnInfo
,
Object
>>
data
=
New
.
arrayList
();
private
final
ArrayList
<
ColumnInfo
>
columns
=
New
.
arrayList
();
private
final
ArrayList
<
Simple
ColumnInfo
>
columns
=
New
.
arrayList
();
/**
* Appends a result set.
...
...
@@ -92,10 +42,10 @@ public final class MergedResultSet {
if
(
cols
==
0
)
{
return
;
}
ColumnInfo
[]
info
=
new
ColumnInfo
[
cols
];
SimpleColumnInfo
[]
info
=
new
Simple
ColumnInfo
[
cols
];
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
new
ColumnInfo
(
meta
.
getColumnName
(
i
),
meta
.
getColumnType
(
i
),
meta
.
getPrecision
(
i
),
meta
.
getScale
(
i
));
SimpleColumnInfo
ci
=
new
SimpleColumnInfo
(
meta
.
getColumnName
(
i
),
meta
.
getColumnType
(
i
),
meta
.
get
ColumnTypeName
(
i
),
meta
.
getPrecision
(
i
),
meta
.
get
Scale
(
i
));
info
[
i
-
1
]
=
ci
;
if
(!
columns
.
contains
(
ci
))
{
columns
.
add
(
ci
);
...
...
@@ -105,9 +55,9 @@ public final class MergedResultSet {
if
(
cols
==
1
)
{
data
.
add
(
Collections
.
singletonMap
(
info
[
0
],
rs
.
getObject
(
1
)));
}
else
{
HashMap
<
ColumnInfo
,
Object
>
map
=
new
HashMap
<>();
HashMap
<
Simple
ColumnInfo
,
Object
>
map
=
new
HashMap
<>();
for
(
int
i
=
1
;
i
<=
cols
;
i
++)
{
ColumnInfo
ci
=
info
[
i
-
1
];
Simple
ColumnInfo
ci
=
info
[
i
-
1
];
map
.
put
(
ci
,
rs
.
getObject
(
i
));
}
data
.
add
(
map
);
...
...
@@ -122,12 +72,12 @@ public final class MergedResultSet {
*/
public
SimpleResultSet
getResult
()
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
for
(
ColumnInfo
ci
:
columns
)
{
rs
.
addColumn
(
ci
.
name
,
ci
.
type
,
ci
.
precision
,
ci
.
scale
);
for
(
Simple
ColumnInfo
ci
:
columns
)
{
rs
.
addColumn
(
ci
.
name
,
ci
.
type
,
ci
.
typeName
,
ci
.
precision
,
ci
.
scale
);
}
for
(
Map
<
ColumnInfo
,
Object
>
map
:
data
)
{
for
(
Map
<
Simple
ColumnInfo
,
Object
>
map
:
data
)
{
Object
[]
row
=
new
Object
[
columns
.
size
()];
for
(
Map
.
Entry
<
ColumnInfo
,
Object
>
entry
:
map
.
entrySet
())
{
for
(
Map
.
Entry
<
Simple
ColumnInfo
,
Object
>
entry
:
map
.
entrySet
())
{
row
[
columns
.
indexOf
(
entry
.
getKey
())]
=
entry
.
getValue
();
}
rs
.
addRow
(
row
);
...
...
h2/src/main/org/h2/util/SimpleColumnInfo.java
0 → 100644
浏览文件 @
6e2cfde3
/*
* 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
.
util
;
/**
* Metadata of a column.
*
* <p>
* Notice: {@linkplain #equals(Object)} and {@linkplain #hashCode()} use only
* {@linkplain #name} field.
* </p>
*/
public
final
class
SimpleColumnInfo
{
/**
* Name of the column.
*/
public
final
String
name
;
/**
* Type of the column, see {@link java.sql.Types}.
*/
public
final
int
type
;
/**
* Type name of the column.
*/
public
final
String
typeName
;
/**
* Precision of the column
*/
public
final
int
precision
;
/**
* Scale of the column.
*/
public
final
int
scale
;
/**
* Creates metadata.
*
* @param name
* name of the column
* @param type
* type of the column, see {@link java.sql.Types}
* @param typeName
* type name of the column
* @param precision
* precision of the column
* @param scale
* scale of the column
*/
public
SimpleColumnInfo
(
String
name
,
int
type
,
String
typeName
,
int
precision
,
int
scale
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
typeName
=
typeName
;
this
.
precision
=
precision
;
this
.
scale
=
scale
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
SimpleColumnInfo
other
=
(
SimpleColumnInfo
)
obj
;
return
name
.
equals
(
other
.
name
);
}
@Override
public
int
hashCode
()
{
return
name
.
hashCode
();
}
}
h2/src/main/org/h2/value/DataType.java
浏览文件 @
6e2cfde3
...
...
@@ -856,6 +856,11 @@ public class DataType {
*/
public
static
int
convertSQLTypeToValueType
(
int
sqlType
,
String
sqlTypeName
)
{
switch
(
sqlType
)
{
case
Types
.
BINARY
:
if
(
sqlTypeName
.
equalsIgnoreCase
(
"UUID"
))
{
return
Value
.
UUID
;
}
break
;
case
Types
.
OTHER
:
case
Types
.
JAVA_OBJECT
:
if
(
sqlTypeName
.
equalsIgnoreCase
(
"geometry"
))
{
...
...
h2/src/main/org/h2/value/Value.java
浏览文件 @
6e2cfde3
...
...
@@ -982,7 +982,16 @@ public abstract class Value {
case
STRING_IGNORECASE:
case
STRING_FIXED:
return
ValueEnum
.
get
(
enumerators
,
getString
());
default
:
case
JAVA_OBJECT:
Object
object
=
JdbcUtils
.
deserialize
(
getBytesNoCopy
(),
getDataHandler
());
if
(
object
instanceof
String
)
{
return
ValueEnum
.
get
(
enumerators
,
(
String
)
object
);
}
else
if
(
object
instanceof
Integer
)
{
return
ValueEnum
.
get
(
enumerators
,
(
int
)
object
);
}
//$FALL-THROUGH$
default
:
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
getString
());
}
...
...
h2/src/main/org/h2/value/ValueEnumBase.java
浏览文件 @
6e2cfde3
...
...
@@ -77,7 +77,7 @@ public class ValueEnumBase extends Value {
@Override
public
Object
getObject
()
{
return
ordina
l
;
return
labe
l
;
}
@Override
...
...
h2/src/main/org/h2/value/ValueGeometry.java
浏览文件 @
6e2cfde3
...
...
@@ -11,6 +11,7 @@ import java.util.Arrays;
import
org.h2.engine.Mode
;
import
org.h2.message.DbException
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.locationtech.jts.geom.CoordinateSequence
;
import
org.locationtech.jts.geom.CoordinateSequenceFilter
;
import
org.locationtech.jts.geom.Envelope
;
...
...
@@ -140,7 +141,20 @@ public class ValueGeometry extends Value {
* @return a copy of the geometry object
*/
public
Geometry
getGeometry
()
{
return
getGeometryNoCopy
().
copy
();
Geometry
geometry
=
getGeometryNoCopy
();
Geometry
copy
=
geometry
.
copy
();
/*
* Geometry factory is not preserved in WKB format, but SRID is preserved.
*
* We use a new factory to read geometries from WKB with default SRID value of
* 0.
*
* Geometry.copy() copies the geometry factory and copied value has SRID form
* the factory instead of original SRID value. So we need to copy SRID here with
* non-recommended (but not deprecated) setSRID() method.
*/
copy
.
setSRID
(
geometry
.
getSRID
());
return
copy
;
}
public
Geometry
getGeometryNoCopy
()
{
...
...
@@ -221,7 +235,7 @@ public class ValueGeometry extends Value {
@Override
public
byte
[]
getBytes
()
{
return
getWKB
(
);
return
Utils
.
cloneByteArray
(
getWKB
()
);
}
@Override
...
...
h2/src/test/org/h2/test/db/TestIndex.java
浏览文件 @
6e2cfde3
...
...
@@ -6,6 +6,7 @@
package
org
.
h2
.
test
.
db
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
...
...
@@ -99,6 +100,9 @@ public class TestIndex extends TestBase {
conn
.
close
();
deleteDb
(
"index"
);
// This test uses own connection
testEnumIndex
();
}
private
void
testOrderIndex
()
throws
SQLException
{
...
...
@@ -750,4 +754,27 @@ public class TestIndex extends TestBase {
assertEquals
(
1
,
testFunctionIndexCounter
);
}
private
void
testEnumIndex
()
throws
SQLException
{
if
(
config
.
memory
||
config
.
networked
)
{
return
;
}
deleteDb
(
"index"
);
String
url
=
"jdbc:h2:"
+
getBaseDir
()
+
"/index;DB_CLOSE_DELAY=0"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"CREATE TABLE TEST(ID INT, V ENUM('A', 'B'), CONSTRAINT PK PRIMARY KEY(ID, V))"
);
stat
.
execute
(
"INSERT INTO TEST VALUES (1, 'A'), (2, 'B')"
);
conn
.
close
();
conn
=
DriverManager
.
getConnection
(
url
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"DELETE FROM TEST WHERE V = 'A'"
);
stat
.
execute
(
"DROP TABLE TEST"
);
conn
.
close
();
deleteDb
(
"index"
);
}
}
h2/src/test/org/h2/test/db/TestSpatial.java
浏览文件 @
6e2cfde3
...
...
@@ -648,13 +648,14 @@ public class TestSpatial extends TestBase {
GeometryFactory
geometryFactory
=
new
GeometryFactory
();
Geometry
geometry
=
geometryFactory
.
createPoint
(
new
Coordinate
(
0
,
0
));
geometry
.
setSRID
(
27572
);
ValueGeometry
valueGeometry
=
ValueGeometry
.
getFromGeometry
(
geometry
);
ValueGeometry
valueGeometry
=
ValueGeometry
.
getFromGeometry
(
geometry
);
Geometry
geometry2
=
geometryFactory
.
createPoint
(
new
Coordinate
(
0
,
0
));
geometry2
.
setSRID
(
5326
);
ValueGeometry
valueGeometry2
=
ValueGeometry
.
getFromGeometry
(
geometry2
);
ValueGeometry
valueGeometry2
=
ValueGeometry
.
getFromGeometry
(
geometry2
);
assertFalse
(
valueGeometry
.
equals
(
valueGeometry2
));
ValueGeometry
valueGeometry3
=
ValueGeometry
.
getFromGeometry
(
geometry
);
assertEquals
(
valueGeometry
,
valueGeometry3
);
assertEquals
(
geometry
.
getSRID
(),
valueGeometry3
.
getGeometry
().
getSRID
());
// Check illegal geometry (no WKB representation)
try
{
ValueGeometry
.
get
(
"POINT EMPTY"
);
...
...
h2/src/test/org/h2/test/jdbc/TestGetGeneratedKeys.java
浏览文件 @
6e2cfde3
...
...
@@ -8,6 +8,7 @@ package org.h2.test.jdbc;
import
java.sql.Connection
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.util.UUID
;
...
...
@@ -127,6 +128,9 @@ public class TestGetGeneratedKeys extends TestBase {
prep
.
addBatch
();
prep
.
executeBatch
();
ResultSet
rs
=
prep
.
getGeneratedKeys
();
ResultSetMetaData
meta
=
rs
.
getMetaData
();
assertEquals
(
"BIGINT"
,
meta
.
getColumnTypeName
(
1
));
assertEquals
(
"UUID"
,
meta
.
getColumnTypeName
(
2
));
rs
.
next
();
assertEquals
(
1L
,
rs
.
getLong
(
1
));
UUID
u1
=
(
UUID
)
rs
.
getObject
(
2
);
...
...
h2/src/test/org/h2/test/jdbc/TestMetaData.java
浏览文件 @
6e2cfde3
...
...
@@ -8,11 +8,14 @@ package org.h2.test.jdbc;
import
java.sql.Connection
;
import
java.sql.DatabaseMetaData
;
import
java.sql.Driver
;
import
java.sql.PreparedStatement
;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
java.sql.Statement
;
import
java.sql.Types
;
import
java.util.UUID
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.SysProperties
;
...
...
@@ -135,6 +138,13 @@ public class TestMetaData extends TestBase {
assertEquals
(
ResultSet
.
HOLD_CURSORS_OVER_COMMIT
,
conn
.
getHoldability
());
assertEquals
(
ResultSet
.
HOLD_CURSORS_OVER_COMMIT
,
rs
.
getHoldability
());
stat
.
executeUpdate
(
"drop table test"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"SELECT X FROM TABLE (X UUID = ?)"
);
prep
.
setObject
(
1
,
UUID
.
randomUUID
());
rs
=
prep
.
executeQuery
();
rsMeta
=
rs
.
getMetaData
();
assertEquals
(
"UUID"
,
rsMeta
.
getColumnTypeName
(
1
));
conn
.
close
();
}
...
...
h2/src/test/org/h2/test/jdbc/TestPreparedStatement.java
浏览文件 @
6e2cfde3
...
...
@@ -476,7 +476,7 @@ public class TestPreparedStatement extends TestBase {
assertEquals
(
goodSizes
[
i
],
rs
.
getString
(
1
));
assertEquals
(
i
,
rs
.
getInt
(
1
));
Object
o
=
rs
.
getObject
(
1
);
assertEquals
(
Integer
.
class
,
o
.
getClass
());
assertEquals
(
String
.
class
,
o
.
getClass
());
}
for
(
int
i
=
0
;
i
<
goodSizes
.
length
;
i
++)
{
...
...
h2/src/test/org/h2/test/jdbc/TestResultSet.java
浏览文件 @
6e2cfde3
...
...
@@ -87,6 +87,7 @@ public class TestResultSet extends TestBase {
testFindColumn
();
testColumnLength
();
testArray
();
testEnum
();
testLimitMaxRows
();
trace
(
"max rows="
+
stat
.
getMaxRows
());
...
...
@@ -1798,6 +1799,56 @@ public class TestResultSet extends TestBase {
stat
.
execute
(
"DROP TABLE TEST"
);
}
private
void
testEnum
()
throws
SQLException
{
trace
(
"Test ENUM"
);
stat
.
execute
(
"CREATE TABLE TEST(ID INT PRIMARY KEY, VALUE ENUM('A', 'B', 'C', 'D', 'E', 'F', 'G'))"
);
PreparedStatement
prep
=
conn
.
prepareStatement
(
"INSERT INTO TEST VALUES(?, ?)"
);
prep
.
setInt
(
1
,
1
);
prep
.
setString
(
2
,
"A"
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
2
);
prep
.
setObject
(
2
,
"B"
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
3
);
prep
.
setInt
(
2
,
2
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
4
);
prep
.
setObject
(
2
,
"D"
,
Types
.
VARCHAR
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
5
);
prep
.
setObject
(
2
,
"E"
,
Types
.
OTHER
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
6
);
prep
.
setObject
(
2
,
5
,
Types
.
OTHER
);
prep
.
executeUpdate
();
prep
.
setInt
(
1
,
7
);
prep
.
setObject
(
2
,
6
,
Types
.
INTEGER
);
prep
.
executeUpdate
();
ResultSet
rs
=
stat
.
executeQuery
(
"SELECT * FROM TEST ORDER BY ID"
);
testEnumResult
(
rs
,
1
,
"A"
,
0
);
testEnumResult
(
rs
,
2
,
"B"
,
1
);
testEnumResult
(
rs
,
3
,
"C"
,
2
);
testEnumResult
(
rs
,
4
,
"D"
,
3
);
testEnumResult
(
rs
,
5
,
"E"
,
4
);
testEnumResult
(
rs
,
6
,
"F"
,
5
);
testEnumResult
(
rs
,
7
,
"G"
,
6
);
assertFalse
(
rs
.
next
());
stat
.
execute
(
"DROP TABLE TEST"
);
}
private
void
testEnumResult
(
ResultSet
rs
,
int
id
,
String
name
,
int
ordinal
)
throws
SQLException
{
assertTrue
(
rs
.
next
());
assertEquals
(
id
,
rs
.
getInt
(
1
));
assertEquals
(
name
,
rs
.
getString
(
2
));
assertEquals
(
name
,
rs
.
getObject
(
2
));
assertEquals
(
name
,
rs
.
getObject
(
2
,
String
.
class
));
assertEquals
(
ordinal
,
rs
.
getInt
(
2
));
assertEquals
((
Integer
)
ordinal
,
rs
.
getObject
(
2
,
Integer
.
class
));
}
private
byte
[]
readAllBytes
(
InputStream
in
)
{
if
(
in
==
null
)
{
return
null
;
...
...
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
浏览文件 @
6e2cfde3
...
...
@@ -162,3 +162,93 @@ drop table card;
drop
type
CARD_SUIT
;
>
ok
CREATE
TABLE
TEST
(
ID
INT
,
E1
ENUM
(
'A'
,
'B'
)
DEFAULT
'A'
,
E2
ENUM
(
'C'
,
'D'
)
DEFAULT
'C'
ON
UPDATE
'D'
);
>
ok
INSERT
INTO
TEST
(
ID
)
VALUES
(
1
);
>
update
count
:
1
SELECT
*
FROM
TEST
;
>
ID
E1
E2
>
-- -- --
>
1
A
C
>
rows
:
1
UPDATE
TEST
SET
E1
=
'B'
;
>
update
count
:
1
SELECT
*
FROM
TEST
;
>
ID
E1
E2
>
-- -- --
>
1
B
D
>
rows
:
1
DROP
TABLE
TEST
;
>
ok
CREATE
TABLE
TEST
(
E
ENUM
(
'A'
,
'B'
));
>
ok
INSERT
INTO
TEST
VALUES
(
'B'
);
>
update
count
:
1
CREATE
VIEW
V
AS
SELECT
*
FROM
TEST
;
>
ok
SELECT
*
FROM
V
;
>
E
>
-
>
B
>
rows
:
1
CREATE
VIEW
V1
AS
SELECT
E
+
2
AS
E
FROM
TEST
;
>
ok
SELECT
*
FROM
V1
;
>
E
>
-
>
3
>
rows
:
1
CREATE
VIEW
V2
AS
SELECT
E
+
E
AS
E
FROM
TEST
;
>
ok
SELECT
*
FROM
V2
;
>
E
>
-
>
2
>
rows
:
1
CREATE
VIEW
V3
AS
SELECT
-
E
AS
E
FROM
TEST
;
>
ok
SELECT
*
FROM
V3
;
>
E
>
--
>
-
1
>
rows
:
1
SELECT
*
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
COLUMN_NAME
=
'E'
ORDER
BY
TABLE_NAME
;
>
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
COLUMN_DEFAULT
IS_NULLABLE
DATA_TYPE
CHARACTER_MAXIMUM_LENGTH
CHARACTER_OCTET_LENGTH
NUMERIC_PRECISION
NUMERIC_PRECISION_RADIX
NUMERIC_SCALE
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------- ----------------
>
SCRIPT
PUBLIC
TEST
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
V
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
>
SCRIPT
PUBLIC
V1
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V2
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
SCRIPT
PUBLIC
V3
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
>
rows
(
ordered
):
5
DROP
VIEW
V
;
>
ok
DROP
VIEW
V1
;
>
ok
DROP
VIEW
V2
;
>
ok
DROP
VIEW
V3
;
>
ok
DROP
TABLE
TEST
;
>
ok
h2/src/test/org/h2/test/scripts/dml/mergeUsing.sql
浏览文件 @
6e2cfde3
...
...
@@ -30,4 +30,45 @@ EXPLAIN PLAN
INSERT
(
ID
,
NAME
)
VALUES
(
S
.
ID
,
S
.
NAME
);
>
PLAN
>
---------------------------------------------------------------------------------------------------------------------------------
>
MERGE
INTO
PUBLIC
.
PARENT
(
ID
,
NAME
)
KEY
(
ID
)
SELECT
X
AS
ID
,
(
'Coco'
||
X
)
AS
NAME
FROM
SYSTEM_RANGE
(
1
,
2
)
/* PUBLIC.RANGE_INDEX */
\ No newline at end of file
>
MERGE
INTO
PUBLIC
.
PARENT
(
ID
,
NAME
)
KEY
(
ID
)
SELECT
X
AS
ID
,
(
'Coco'
||
X
)
AS
NAME
FROM
SYSTEM_RANGE
(
1
,
2
)
/* PUBLIC.RANGE_INDEX */
DROP
TABLE
PARENT
;
>
ok
CREATE
SCHEMA
SOURCESCHEMA
;
>
ok
CREATE
TABLE
SOURCESCHEMA
.
SOURCE
(
ID
INT
PRIMARY
KEY
,
VALUE
INT
);
>
ok
INSERT
INTO
SOURCESCHEMA
.
SOURCE
VALUES
(
1
,
10
),
(
3
,
30
),
(
5
,
50
);
>
update
count
:
3
CREATE
SCHEMA
DESTSCHEMA
;
>
ok
CREATE
TABLE
DESTSCHEMA
.
DESTINATION
(
ID
INT
PRIMARY
KEY
,
VALUE
INT
);
>
ok
INSERT
INTO
DESTSCHEMA
.
DESTINATION
VALUES
(
3
,
300
),
(
6
,
600
);
>
update
count
:
2
MERGE
INTO
DESTSCHEMA
.
DESTINATION
USING
SOURCESCHEMA
.
SOURCE
ON
(
DESTSCHEMA
.
DESTINATION
.
ID
=
SOURCESCHEMA
.
SOURCE
.
ID
)
WHEN
MATCHED
THEN
UPDATE
SET
VALUE
=
SOURCESCHEMA
.
SOURCE
.
VALUE
WHEN
NOT
MATCHED
THEN
INSERT
(
ID
,
VALUE
)
VALUES
(
SOURCESCHEMA
.
SOURCE
.
ID
,
SOURCESCHEMA
.
SOURCE
.
VALUE
);
>
update
count
:
3
SELECT
*
FROM
DESTSCHEMA
.
DESTINATION
;
>
ID
VALUE
>
-- -----
>
1
10
>
3
30
>
5
50
>
6
600
>
rows
:
4
DROP
SCHEMA
SOURCESCHEMA
CASCADE
;
>
ok
DROP
SCHEMA
DESTSCHEMA
CASCADE
;
>
ok
h2/src/test/org/h2/test/scripts/functions/aggregate/array-agg.sql
浏览文件 @
6e2cfde3
...
...
@@ -14,10 +14,9 @@ insert into test values ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'),
select
array_agg
(
v
order
by
v
asc
),
array_agg
(
v
order
by
v
desc
)
filter
(
where
v
>=
'4'
)
from
test
where
v
>=
'2'
;
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
---------------------------------------------------------------- ------------------------------------------------------
------------------------------
>
(
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
------------------------ ------------------------------------------------------
>
(
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
rows
(
ordered
):
1
create
index
test_idx
on
test
(
v
);
...
...
@@ -25,21 +24,45 @@ create index test_idx on test(v);
select
ARRAY_AGG
(
v
order
by
v
asc
),
ARRAY_AGG
(
v
order
by
v
desc
)
filter
(
where
v
>=
'4'
)
from
test
where
v
>=
'2'
;
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
---------------------------------------------------------------- ------------------------------------------------------
------------------------------
>
(
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
------------------------ ------------------------------------------------------
>
(
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
rows
(
ordered
):
1
select
ARRAY_AGG
(
v
order
by
v
asc
),
ARRAY_AGG
(
v
order
by
v
desc
)
filter
(
where
v
>=
'4'
)
from
test
;
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
------------------------------------------------------------------------ ------------------------------------------------------
------------------------------
>
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
ARRAY_AGG
(
V
ORDER
BY
V
)
ARRAY_AGG
(
V
ORDER
BY
V
DESC
)
FILTER
(
WHERE
(
V
>=
'4'
))
>
--------------------------- ------------------------------------------------------
>
(
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
)
(
9
,
8
,
7
,
6
,
5
,
4
)
>
rows
(
ordered
):
1
drop
table
test
;
>
ok
create
table
test
(
id
int
auto_increment
primary
key
,
v
int
);
>
ok
insert
into
test
(
v
)
values
(
7
),
(
2
),
(
8
),
(
3
),
(
7
),
(
3
),
(
9
),
(
-
1
);
>
update
count
:
8
select
array_agg
(
v
)
from
test
;
>
ARRAY_AGG
(
V
)
>
-------------------------
>
(
7
,
2
,
8
,
3
,
7
,
3
,
9
,
-
1
)
>
rows
:
1
select
array_agg
(
distinct
v
)
from
test
;
>
ARRAY_AGG
(
DISTINCT
V
)
>
---------------------
>
(
-
1
,
2
,
3
,
7
,
8
,
9
)
>
rows
:
1
select
array_agg
(
distinct
v
order
by
v
desc
)
from
test
;
>
ARRAY_AGG
(
DISTINCT
V
ORDER
BY
V
DESC
)
>
-------------------------------------
>
(
9
,
8
,
7
,
3
,
2
,
-
1
)
>
rows
(
ordered
):
1
drop
table
test
;
>
ok
h2/src/test/org/h2/test/scripts/functions/aggregate/group-concat.sql
浏览文件 @
6e2cfde3
...
...
@@ -37,6 +37,32 @@ select group_concat(v order by v asc separator '-'),
>
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
9
-
8
-
7
-
6
-
5
-
4
>
rows
(
ordered
):
1
drop
table
test
;
>
ok
create
table
test
(
id
int
auto_increment
primary
key
,
v
int
);
>
ok
insert
into
test
(
v
)
values
(
7
),
(
2
),
(
8
),
(
3
),
(
7
),
(
3
),
(
9
),
(
-
1
);
>
update
count
:
8
select
group_concat
(
v
)
from
test
;
>
GROUP_CONCAT
(
V
)
>
----------------
>
7
,
2
,
8
,
3
,
7
,
3
,
9
,
-
1
>
rows
:
1
select
group_concat
(
distinct
v
)
from
test
;
>
GROUP_CONCAT
(
DISTINCT
V
)
>
------------------------
>
-
1
,
2
,
3
,
7
,
8
,
9
>
rows
:
1
select
group_concat
(
distinct
v
order
by
v
desc
)
from
test
;
>
GROUP_CONCAT
(
DISTINCT
V
ORDER
BY
V
DESC
)
>
----------------------------------------
>
9
,
8
,
7
,
3
,
2
,
-
1
>
rows
(
ordered
):
1
drop
table
test
;
>
ok
h2/src/test/org/h2/test/scripts/information_schema.sql
浏览文件 @
6e2cfde3
...
...
@@ -41,6 +41,18 @@ SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME, IS_DEFERRABLE, INITIALLY_DE
>
FK_2
FOREIGN
KEY
T2
NO
NO
>
rows
(
ordered
):
5
SELECT
CONSTRAINT_NAME
,
CONSTRAINT_TYPE
,
TABLE_NAME
,
COLUMN_LIST
FROM
INFORMATION_SCHEMA
.
CONSTRAINTS
WHERE
CONSTRAINT_CATALOG
=
DATABASE
()
AND
CONSTRAINT_SCHEMA
=
SCHEMA
()
AND
TABLE_CATALOG
=
DATABASE
()
AND
TABLE_SCHEMA
=
SCHEMA
()
ORDER
BY
TABLE_NAME
,
CONSTRAINT_NAME
;
>
CONSTRAINT_NAME
CONSTRAINT_TYPE
TABLE_NAME
COLUMN_LIST
>
--------------- --------------- ---------- -----------
>
PK_1
PRIMARY
KEY
T1
C1
,
C2
>
U_1
UNIQUE
T1
C3
,
C4
>
CH_1
CHECK
T2
null
>
FK_1
REFERENTIAL
T2
C3
,
C4
>
FK_2
REFERENTIAL
T2
C3
,
C4
>
rows
(
ordered
):
5
SELECT
*
FROM
INFORMATION_SCHEMA
.
KEY_COLUMN_USAGE
LIMIT
0
;
>
CONSTRAINT_CATALOG
CONSTRAINT_SCHEMA
CONSTRAINT_NAME
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
ORDINAL_POSITION
POSITION_IN_UNIQUE_CONSTRAINT
>
------------------ ----------------- --------------- ------------- ------------ ---------- ----------- ---------------- -----------------------------
...
...
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
6e2cfde3
...
...
@@ -770,5 +770,5 @@ openoffice organize libre systemtables gmane sea borders announced millennium al
opti excessively
iterators tech enums incompatibilities loses reimplement readme reorganize milli subdirectory
iterators tech enums incompatibilities loses reimplement readme reorganize milli subdirectory
linkplain inspections
geometries sourceschema destschema
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论