Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
92d7f561
Unverified
提交
92d7f561
authored
9月 13, 2018
作者:
Evgenij Ryazanov
提交者:
GitHub
9月 13, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1441 from katzyn/ExtTypeInfo
Add GEOMETRY type subtypes with type and SRID constraints
上级
c734f793
6eca7a26
隐藏空白字符变更
内嵌
并排
正在显示
32 个修改的文件
包含
894 行增加
和
359 行删除
+894
-359
help.csv
h2/src/docsrc/help/help.csv
+16
-2
changelog.html
h2/src/docsrc/html/changelog.html
+12
-0
Parser.java
h2/src/main/org/h2/command/Parser.java
+49
-22
CreateTable.java
h2/src/main/org/h2/command/ddl/CreateTable.java
+11
-8
Comparison.java
h2/src/main/org/h2/expression/Comparison.java
+1
-1
ConditionInConstantSet.java
h2/src/main/org/h2/expression/ConditionInConstantSet.java
+5
-4
ExpressionColumn.java
h2/src/main/org/h2/expression/ExpressionColumn.java
+6
-3
Function.java
h2/src/main/org/h2/expression/Function.java
+5
-4
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+1
-1
Column.java
h2/src/main/org/h2/table/Column.java
+24
-37
TableView.java
h2/src/main/org/h2/table/TableView.java
+6
-4
EWKBUtils.java
h2/src/main/org/h2/util/geometry/EWKBUtils.java
+30
-3
EWKTUtils.java
h2/src/main/org/h2/util/geometry/EWKTUtils.java
+111
-8
GeometryUtils.java
h2/src/main/org/h2/util/geometry/GeometryUtils.java
+36
-7
DataType.java
h2/src/main/org/h2/value/DataType.java
+22
-1
ExtTypeInfo.java
h2/src/main/org/h2/value/ExtTypeInfo.java
+34
-0
ExtTypeInfoEnum.java
h2/src/main/org/h2/value/ExtTypeInfoEnum.java
+184
-0
ExtTypeInfoGeometry.java
h2/src/main/org/h2/value/ExtTypeInfoGeometry.java
+71
-0
Value.java
h2/src/main/org/h2/value/Value.java
+21
-17
ValueEnum.java
h2/src/main/org/h2/value/ValueEnum.java
+7
-183
ValueEnumBase.java
h2/src/main/org/h2/value/ValueEnumBase.java
+11
-0
ValueGeometry.java
h2/src/main/org/h2/value/ValueGeometry.java
+64
-30
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+2
-3
ValueLobDb.java
h2/src/main/org/h2/value/ValueLobDb.java
+2
-3
ValueNull.java
h2/src/main/org/h2/value/ValueNull.java
+1
-1
TestSpatial.java
h2/src/test/org/h2/test/db/TestSpatial.java
+1
-1
TestCustomDataTypesHandler.java
h2/src/test/org/h2/test/jdbc/TestCustomDataTypesHandler.java
+2
-1
enum.sql
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
+17
-8
geometry.sql
h2/src/test/org/h2/test/scripts/datatypes/geometry.sql
+96
-0
dropDomain.sql
h2/src/test/org/h2/test/scripts/ddl/dropDomain.sql
+5
-5
TestGeometryUtils.java
h2/src/test/org/h2/test/unit/TestGeometryUtils.java
+40
-2
dictionary.txt
h2/src/tools/org/h2/build/doc/dictionary.txt
+1
-0
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
92d7f561
...
...
@@ -3037,20 +3037,34 @@ ENUM('clubs', 'diamonds', 'hearts', 'spades')
"
"Data Types","GEOMETRY Type","
GEOMETRY
[({ sridInt | { {POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING
|MULTIPOLYGON|GEOMETRYCOLLECTION} [Z|M|ZM] [, sridInt]} })]
","
A spatial geometry type.
Mapped to ""org.locationtech.jts.geom.Geometry"" if JTS library is in classpath.
If additional constraints are not specified this type accepts all supported types of geometries.
A constraint with required geometry type and dimension system can be set by specifying name of the type and
dimension system. A whitespace between them is optional.
2D dimension system does not have a name and assumed if only a geometry type name is specified.
POINT means 2D point, POINT Z or POINTZ means 3D point.
A constraint with required spatial reference system identifier (SRID) can be set by specifying this identifier.
Both constraints for type and SRID can be specified together.
Mapped to ""org.locationtech.jts.geom.Geometry"" if JTS library is in classpath and to ""java.lang.String"" otherwise.
May be represented in textual format using the WKT (well-known text) or EWKT (extended well-known text) format.
Values are stored internally in EWKB (extended well-known binary) format.
Only a subset of EWKB and EWKT features is supported.
Supported objects are POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, and GEOMETRYCOLLECTION.
Supported dimension systems are
XY (2D), XYZ, XYM, and XYZM
.
Supported dimension systems are
2D (XY), Z (XYZ), M (XYM), and ZM (XYZM)
.
SRID (spatial reference system identifier) is supported.
Use a quoted string containing a WKT/EWKT formatted string or ""PreparedStatement.setObject()"" to store values,
and ""ResultSet.getObject(..)"" or ""ResultSet.getString(..)"" to retrieve the values.
","
GEOMETRY
GEOMETRY(POINT)
GEOMETRY(POINT Z)
GEOMETRY(POINT Z, 4326)
GEOMETRY(4326)
"
"Data Types","INTERVAL Type","
...
...
h2/src/docsrc/html/changelog.html
浏览文件 @
92d7f561
...
...
@@ -21,6 +21,18 @@ Change Log
<h2>
Next Version (unreleased)
</h2>
<ul>
<li>
PR #1441: Add GEOMETRY type subtypes with type and SRID constraints
</li>
<li>
PR #1434: Add support for ENUM in CAST and other changes
</li>
<li>
PR #1431: Fix some inconsistencies in documentation and improve mvn build
</li>
<li>
PR #1428: Add support for M and ZM dimensions to GEOMETRY data type
</li>
<li>
Issue #1405: Introduce LocalResult factory
</li>
<li>
PR #1422: Add ENVELOPE aggregate function
</li>
<li>
Issue #1421: Remove old-style outer join
</li>
<li>
PR #1419: Assorted minor changes
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
92d7f561
...
...
@@ -194,14 +194,17 @@ import org.h2.util.ParserUtil;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.h2.util.geometry.EWKTUtils
;
import
org.h2.value.CompareMode
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.ExtTypeInfoEnum
;
import
org.h2.value.ExtTypeInfoGeometry
;
import
org.h2.value.Value
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueBytes
;
import
org.h2.value.ValueDate
;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueInterval
;
import
org.h2.value.ValueLong
;
...
...
@@ -4862,7 +4865,7 @@ public class Parser {
}
long
precision
=
-
1
;
int
displaySize
=
-
1
;
String
[]
enumerators
=
null
;
ExtTypeInfo
extTypeInfo
=
null
;
int
scale
=
-
1
;
String
comment
=
null
;
Column
templateColumn
=
null
;
...
...
@@ -4879,7 +4882,7 @@ public class Parser {
precision
=
templateColumn
.
getPrecision
();
displaySize
=
templateColumn
.
getDisplaySize
();
scale
=
templateColumn
.
getScale
();
e
numerators
=
templateColumn
.
getEnumerators
();
e
xtTypeInfo
=
templateColumn
.
getExtTypeInfo
();
}
else
{
Mode
mode
=
database
.
getMode
();
dataType
=
DataType
.
getTypeByName
(
original
,
mode
);
...
...
@@ -5007,25 +5010,49 @@ public class Parser {
original
=
original
+
'('
+
p
+
')'
;
}
}
else
if
(
dataType
.
type
==
Value
.
ENUM
)
{
if
(
readIf
(
OPEN_PAREN
))
{
java
.
util
.
List
<
String
>
enumeratorList
=
new
ArrayList
<>();
original
+=
'('
;
String
enumerator0
=
readString
();
enumeratorList
.
add
(
enumerator0
);
original
+=
"'"
+
enumerator0
+
"'"
;
while
(
readIfMore
(
true
))
{
original
+=
','
;
String
enumeratorN
=
readString
();
original
+=
"'"
+
enumeratorN
+
"'"
;
enumeratorList
.
add
(
enumeratorN
);
}
original
+=
')'
;
enumerators
=
enumeratorList
.
toArray
(
new
String
[
0
]);
if
(
extTypeInfo
==
null
)
{
String
[]
enumerators
=
null
;
if
(
readIf
(
OPEN_PAREN
))
{
java
.
util
.
List
<
String
>
enumeratorList
=
new
ArrayList
<>();
String
enumerator0
=
readString
();
enumeratorList
.
add
(
enumerator0
);
while
(
readIfMore
(
true
))
{
String
enumeratorN
=
readString
();
enumeratorList
.
add
(
enumeratorN
);
}
enumerators
=
enumeratorList
.
toArray
(
new
String
[
0
]);
}
try
{
extTypeInfo
=
new
ExtTypeInfoEnum
(
enumerators
);
}
catch
(
DbException
e
)
{
throw
e
.
addSQL
(
original
);
}
original
+=
extTypeInfo
.
getCreateSQL
();
}
try
{
ValueEnum
.
check
(
enumerators
);
}
catch
(
DbException
e
)
{
throw
e
.
addSQL
(
original
);
}
else
if
(
dataType
.
type
==
Value
.
GEOMETRY
)
{
if
(
extTypeInfo
==
null
)
{
if
(
readIf
(
OPEN_PAREN
))
{
int
type
=
0
;
if
(
currentTokenType
==
IDENTIFIER
&&
!
currentTokenQuoted
)
{
try
{
type
=
EWKTUtils
.
parseGeometryType
(
currentToken
);
read
();
if
(
type
/
1_000
==
0
&&
currentTokenType
==
IDENTIFIER
&&
!
currentTokenQuoted
)
{
type
+=
EWKTUtils
.
parseDimensionSystem
(
currentToken
)
*
1_000
;
read
();
}
}
catch
(
IllegalArgumentException
ex
)
{
throw
getSyntaxError
();
}
}
Integer
srid
=
null
;
if
(
type
==
0
||
readIf
(
COMMA
))
{
srid
=
readInt
();
}
read
(
CLOSE_PAREN
);
extTypeInfo
=
new
ExtTypeInfoGeometry
(
type
,
srid
);
original
+=
extTypeInfo
.
getCreateSQL
();
}
}
}
else
if
(
readIf
(
OPEN_PAREN
))
{
// Support for MySQL: INT(11), MEDIUMINT(8) and so on.
...
...
@@ -5049,7 +5076,7 @@ public class Parser {
}
Column
column
=
new
Column
(
columnName
,
type
,
precision
,
scale
,
displaySize
,
e
numerators
);
displaySize
,
e
xtTypeInfo
);
if
(
templateColumn
!=
null
)
{
column
.
setNullable
(
templateColumn
.
isNullable
());
column
.
setDefaultExpression
(
session
,
...
...
h2/src/main/org/h2/command/ddl/CreateTable.java
浏览文件 @
92d7f561
...
...
@@ -23,6 +23,7 @@ import org.h2.table.Column;
import
org.h2.table.Table
;
import
org.h2.util.ColumnNamer
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
/**
...
...
@@ -197,18 +198,20 @@ public class CreateTable extends CommandWithColumns {
if
(
scale
>
precision
)
{
precision
=
scale
;
}
String
[]
enumerators
=
null
;
if
(
dt
.
type
==
Value
.
ENUM
)
{
/**
* Only columns of tables may be enumerated.
*/
if
(!(
expr
instanceof
ExpressionColumn
))
{
ExtTypeInfo
extTypeInfo
=
null
;
int
t
=
dt
.
type
;
if
(
DataType
.
isExtInfoType
(
t
))
{
if
(
expr
instanceof
ExpressionColumn
)
{
extTypeInfo
=
((
ExpressionColumn
)
expr
).
getColumn
().
getExtTypeInfo
();
}
else
if
(
t
==
Value
.
ENUM
)
{
/*
* Only columns of tables may be enumerated.
*/
throw
DbException
.
get
(
ErrorCode
.
GENERAL_ERROR_1
,
"Unable to resolve enumerators of expression"
);
}
enumerators
=
((
ExpressionColumn
)
expr
).
getColumn
().
getEnumerators
();
}
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
numerators
);
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
xtTypeInfo
);
addColumn
(
col
);
}
}
...
...
h2/src/main/org/h2/expression/Comparison.java
浏览文件 @
92d7f561
...
...
@@ -210,7 +210,7 @@ public class Comparison extends Condition {
Column
column
=
((
ExpressionColumn
)
left
).
getColumn
();
right
=
ValueExpression
.
get
(
r
.
convertTo
(
resType
,
MathUtils
.
convertLongToInt
(
left
.
getPrecision
()),
session
.
getDatabase
().
getMode
(),
column
,
column
.
getE
numerators
()));
session
.
getDatabase
().
getMode
(),
column
,
column
.
getE
xtTypeInfo
()));
}
}
else
if
(
right
instanceof
Parameter
)
{
((
Parameter
)
right
).
setColumn
(
...
...
h2/src/main/org/h2/expression/ConditionInConstantSet.java
浏览文件 @
92d7f561
...
...
@@ -16,6 +16,7 @@ import org.h2.message.DbException;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.TableFilter
;
import
org.h2.util.StatementBuilder
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueNull
;
...
...
@@ -34,7 +35,7 @@ public class ConditionInConstantSet extends Condition {
private
final
ArrayList
<
Expression
>
valueList
;
private
final
TreeSet
<
Value
>
valueSet
;
private
final
int
type
;
private
String
[]
enumerators
;
private
ExtTypeInfo
extTypeInfo
;
/**
* Create a new IN(..) condition.
...
...
@@ -54,9 +55,9 @@ public class ConditionInConstantSet extends Condition {
type
=
left
.
getType
();
Mode
mode
=
database
.
getMode
();
if
(
type
==
Value
.
ENUM
)
{
e
numerators
=
((
ExpressionColumn
)
left
).
getColumn
().
getEnumerators
();
e
xtTypeInfo
=
((
ExpressionColumn
)
left
).
getColumn
().
getExtTypeInfo
();
for
(
Expression
expression
:
valueList
)
{
valueSet
.
add
(
ex
pression
.
getValue
(
session
).
convertToEnum
(
enumerators
));
valueSet
.
add
(
ex
tTypeInfo
.
cast
(
expression
.
getValue
(
session
)
));
}
}
else
{
for
(
Expression
expression
:
valueList
)
{
...
...
@@ -170,7 +171,7 @@ public class ConditionInConstantSet extends Condition {
if
(
add
.
isConstant
())
{
valueList
.
add
(
add
);
if
(
type
==
Value
.
ENUM
)
{
valueSet
.
add
(
add
.
getValue
(
session
).
convertToEnum
(
e
numerators
));
valueSet
.
add
(
add
.
getValue
(
session
).
convertToEnum
(
e
xtTypeInfo
));
}
else
{
valueSet
.
add
(
add
.
getValue
(
session
).
convertTo
(
type
,
session
.
getDatabase
().
getMode
()));
}
...
...
h2/src/main/org/h2/expression/ExpressionColumn.java
浏览文件 @
92d7f561
...
...
@@ -19,9 +19,9 @@ import org.h2.table.Column;
import
org.h2.table.ColumnResolver
;
import
org.h2.table.Table
;
import
org.h2.table.TableFilter
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueBoolean
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueNull
;
/**
...
...
@@ -191,8 +191,11 @@ public class ExpressionColumn extends Expression {
throw
DbException
.
get
(
ErrorCode
.
MUST_GROUP_BY_COLUMN_1
,
getSQL
());
}
}
if
(
column
.
getEnumerators
()
!=
null
&&
value
!=
ValueNull
.
INSTANCE
)
{
return
ValueEnum
.
get
(
column
.
getEnumerators
(),
value
.
getInt
());
if
(
value
!=
ValueNull
.
INSTANCE
)
{
ExtTypeInfo
extTypeInfo
=
column
.
getExtTypeInfo
();
if
(
extTypeInfo
!=
null
)
{
return
extTypeInfo
.
cast
(
value
);
}
}
return
value
;
}
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
92d7f561
...
...
@@ -56,6 +56,7 @@ import org.h2.util.ToChar;
import
org.h2.util.ToDateParser
;
import
org.h2.util.Utils
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueBoolean
;
...
...
@@ -162,7 +163,7 @@ public class Function extends Expression implements FunctionCall {
protected
int
scale
;
protected
long
precision
=
PRECISION_UNKNOWN
;
protected
int
displaySize
;
protected
String
[]
enumerators
;
protected
ExtTypeInfo
extTypeInfo
;
private
final
Database
database
;
...
...
@@ -894,7 +895,7 @@ public class Function extends Expression implements FunctionCall {
case
CAST:
case
CONVERT:
{
Mode
mode
=
database
.
getMode
();
v0
=
v0
.
convertTo
(
dataType
,
MathUtils
.
convertLongToInt
(
precision
),
mode
,
null
,
e
numerators
);
v0
=
v0
.
convertTo
(
dataType
,
MathUtils
.
convertLongToInt
(
precision
),
mode
,
null
,
e
xtTypeInfo
);
v0
=
v0
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
scale
);
v0
=
v0
.
convertPrecision
(
getPrecision
(),
false
);
result
=
v0
;
...
...
@@ -2200,7 +2201,7 @@ public class Function extends Expression implements FunctionCall {
precision
=
col
.
getPrecision
();
displaySize
=
col
.
getDisplaySize
();
scale
=
col
.
getScale
();
e
numerators
=
col
.
getEnumerators
();
e
xtTypeInfo
=
col
.
getExtTypeInfo
();
}
@Override
...
...
@@ -2601,7 +2602,7 @@ public class Function extends Expression implements FunctionCall {
case
CAST:
{
buff
.
append
(
args
[
0
].
getSQL
()).
append
(
" AS "
).
append
(
new
Column
(
null
,
dataType
,
precision
,
scale
,
displaySize
,
e
numerators
).
getCreateSQL
());
scale
,
displaySize
,
e
xtTypeInfo
).
getCreateSQL
());
break
;
}
case
CONVERT:
{
...
...
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
浏览文件 @
92d7f561
...
...
@@ -288,7 +288,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
(),
-
1
,
database
.
getMode
(),
null
,
c
.
getE
numerators
());
array
[
i
]
=
v
.
convertTo
(
c
.
getType
(),
-
1
,
database
.
getMode
(),
null
,
c
.
getE
xtTypeInfo
());
}
}
array
[
keyColumns
-
1
]
=
key
!=
null
?
key
:
ValueLong
.
get
(
r
.
getKey
());
...
...
h2/src/main/org/h2/table/Column.java
浏览文件 @
92d7f561
...
...
@@ -6,7 +6,8 @@
package
org
.
h2
.
table
;
import
java.sql.ResultSetMetaData
;
import
java.util.Arrays
;
import
java.util.Objects
;
import
org.h2.api.ErrorCode
;
import
org.h2.command.Parser
;
import
org.h2.engine.Constants
;
...
...
@@ -25,8 +26,8 @@ import org.h2.schema.Sequence;
import
org.h2.util.MathUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueEnum
;
import
org.h2.value.ValueInt
;
import
org.h2.value.ValueLong
;
import
org.h2.value.ValueNull
;
...
...
@@ -65,7 +66,7 @@ public class Column {
private
final
int
type
;
private
long
precision
;
private
int
scale
;
private
String
[]
enumerators
;
private
ExtTypeInfo
extTypeInfo
;
private
int
displaySize
;
private
Table
table
;
private
String
name
;
...
...
@@ -99,8 +100,7 @@ public class Column {
this
(
name
,
type
,
precision
,
scale
,
displaySize
,
null
);
}
public
Column
(
String
name
,
int
type
,
long
precision
,
int
scale
,
int
displaySize
,
String
[]
enumerators
)
{
public
Column
(
String
name
,
int
type
,
long
precision
,
int
scale
,
int
displaySize
,
ExtTypeInfo
extTypeInfo
)
{
this
.
name
=
name
;
this
.
type
=
type
;
if
(
precision
==
-
1
&&
scale
==
-
1
&&
displaySize
==
-
1
&&
type
!=
Value
.
UNKNOWN
)
{
...
...
@@ -112,7 +112,7 @@ public class Column {
this
.
precision
=
precision
;
this
.
scale
=
scale
;
this
.
displaySize
=
displaySize
;
this
.
e
numerators
=
enumerators
;
this
.
e
xtTypeInfo
=
extTypeInfo
;
}
@Override
...
...
@@ -141,12 +141,8 @@ public class Column {
return
table
.
getId
()
^
name
.
hashCode
();
}
public
boolean
isEnumerated
()
{
return
type
==
Value
.
ENUM
;
}
public
Column
getClone
()
{
Column
newColumn
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
numerators
);
Column
newColumn
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
xtTypeInfo
);
newColumn
.
copy
(
this
);
return
newColumn
;
}
...
...
@@ -172,7 +168,7 @@ public class Column {
*/
public
Value
convert
(
Value
v
,
Mode
mode
)
{
try
{
return
v
.
convertTo
(
type
,
MathUtils
.
convertLongToInt
(
precision
),
mode
,
this
,
getEnumerators
()
);
return
v
.
convertTo
(
type
,
MathUtils
.
convertLongToInt
(
precision
),
mode
,
this
,
extTypeInfo
);
}
catch
(
DbException
e
)
{
if
(
e
.
getErrorCode
()
==
ErrorCode
.
DATA_CONVERSION_ERROR_1
)
{
String
target
=
(
table
==
null
?
""
:
table
.
getName
()
+
": "
)
+
...
...
@@ -300,12 +296,12 @@ public class Column {
nullable
=
b
;
}
public
String
[]
getEnumerators
()
{
return
e
numerators
;
public
ExtTypeInfo
getExtTypeInfo
()
{
return
e
xtTypeInfo
;
}
public
void
setE
numerators
(
String
[]
enumerators
)
{
this
.
e
numerators
=
enumerators
;
public
void
setE
xtTypeInfo
(
ExtTypeInfo
extTypeInfo
)
{
this
.
e
xtTypeInfo
=
extTypeInfo
;
}
public
boolean
getVisible
()
{
...
...
@@ -406,17 +402,8 @@ public class Column {
getCreateSQL
(),
s
+
" ("
+
value
.
getPrecision
()
+
")"
);
}
}
if
(
isEnumerated
()
&&
value
!=
ValueNull
.
INSTANCE
)
{
if
(!
ValueEnum
.
isValid
(
enumerators
,
value
))
{
String
s
=
value
.
getTraceSQL
();
if
(
s
.
length
()
>
127
)
{
s
=
s
.
substring
(
0
,
128
)
+
"..."
;
}
throw
DbException
.
get
(
ErrorCode
.
ENUM_VALUE_NOT_PERMITTED
,
getCreateSQL
(),
s
);
}
value
=
ValueEnum
.
get
(
enumerators
,
value
.
getInt
());
if
(
value
!=
ValueNull
.
INSTANCE
&&
DataType
.
isExtInfoType
(
type
)
&&
extTypeInfo
!=
null
)
{
value
=
extTypeInfo
.
cast
(
value
);
}
updateSequenceIfRequired
(
session
,
value
);
return
value
;
...
...
@@ -522,15 +509,13 @@ public class Column {
case
Value
.
DECIMAL
:
buff
.
append
(
'('
).
append
(
precision
).
append
(
", "
).
append
(
scale
).
append
(
')'
);
break
;
case
Value
.
ENUM
:
buff
.
append
(
'('
);
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
buff
.
append
(
'\''
).
append
(
enumerators
[
i
]).
append
(
'\''
);
if
(
i
<
enumerators
.
length
-
1
)
{
buff
.
append
(
','
);
}
case
Value
.
GEOMETRY
:
if
(
extTypeInfo
==
null
)
{
break
;
}
buff
.
append
(
')'
);
//$FALL-THROUGH$
case
Value
.
ENUM
:
buff
.
append
(
extTypeInfo
.
getCreateSQL
());
break
;
case
Value
.
BYTES
:
case
Value
.
STRING
:
...
...
@@ -862,6 +847,9 @@ public class Column {
if
(
onUpdateExpression
!=
null
||
newColumn
.
onUpdateExpression
!=
null
)
{
return
false
;
}
if
(!
Objects
.
equals
(
extTypeInfo
,
newColumn
.
extTypeInfo
))
{
return
false
;
}
return
true
;
}
...
...
@@ -876,8 +864,7 @@ public class Column {
displaySize
=
source
.
displaySize
;
name
=
source
.
name
;
precision
=
source
.
precision
;
enumerators
=
source
.
enumerators
==
null
?
null
:
Arrays
.
copyOf
(
source
.
enumerators
,
source
.
enumerators
.
length
);
extTypeInfo
=
source
.
extTypeInfo
;
scale
=
source
.
scale
;
// table is not set
// columnId is not set
...
...
h2/src/main/org/h2/table/TableView.java
浏览文件 @
92d7f561
...
...
@@ -38,6 +38,8 @@ import org.h2.util.ColumnNamer;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
import
org.h2.util.Utils
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
/**
...
...
@@ -194,13 +196,13 @@ public class TableView extends Table {
long
precision
=
expr
.
getPrecision
();
int
scale
=
expr
.
getScale
();
int
displaySize
=
expr
.
getDisplaySize
();
String
[]
enumerators
=
null
;
if
(
type
==
Value
.
ENUM
)
{
ExtTypeInfo
extTypeInfo
=
null
;
if
(
DataType
.
isExtInfoType
(
type
)
)
{
if
(
expr
instanceof
ExpressionColumn
)
{
e
numerators
=
((
ExpressionColumn
)
expr
).
getColumn
().
getEnumerators
();
e
xtTypeInfo
=
((
ExpressionColumn
)
expr
).
getColumn
().
getExtTypeInfo
();
}
}
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
numerators
);
Column
col
=
new
Column
(
name
,
type
,
precision
,
scale
,
displaySize
,
e
xtTypeInfo
);
col
.
setTable
(
this
,
i
);
// Fetch check constraint from view column source
ExpressionColumn
fromColumn
=
null
;
...
...
h2/src/main/org/h2/util/geometry/EWKBUtils.java
浏览文件 @
92d7f561
...
...
@@ -233,17 +233,17 @@ public final class EWKBUtils {
/**
* Geometry type mask that indicates presence of dimension Z.
*/
p
rivate
static
final
int
EWKB_Z
=
0x8000_0000
;
p
ublic
static
final
int
EWKB_Z
=
0x8000_0000
;
/**
* Geometry type mask that indicates presence of dimension M.
*/
p
rivate
static
final
int
EWKB_M
=
0x4000_0000
;
p
ublic
static
final
int
EWKB_M
=
0x4000_0000
;
/**
* Geometry type mask that indicates presence of SRID.
*/
p
rivate
static
final
int
EWKB_SRID
=
0x2000_0000
;
p
ublic
static
final
int
EWKB_SRID
=
0x2000_0000
;
/**
* Converts any supported EWKB to EWKB representation that is used by this
...
...
@@ -296,6 +296,32 @@ public final class EWKBUtils {
}
}
/**
* Converts geometry type with flags to a dimension system.
*
* @param type
* geometry type with flags
* @return dimension system
*/
public
static
int
type2dimensionSystem
(
int
type
)
{
// PostGIS extensions
boolean
useZ
=
(
type
&
EWKB_Z
)
!=
0
;
boolean
useM
=
(
type
&
EWKB_M
)
!=
0
;
// OGC 06-103r4
type
&=
0xffff
;
switch
(
type
/
1_000
)
{
case
DIMENSION_SYSTEM_XYZ:
useZ
=
true
;
break
;
case
DIMENSION_SYSTEM_XYZM:
useZ
=
true
;
//$FALL-THROUGH$
case
DIMENSION_SYSTEM_XYM:
useM
=
true
;
}
return
(
useZ
?
DIMENSION_SYSTEM_XYZ
:
0
)
|
(
useM
?
DIMENSION_SYSTEM_XYM
:
0
);
}
/**
* Parses a EWKB.
*
...
...
@@ -340,6 +366,7 @@ public final class EWKBUtils {
case
DIMENSION_SYSTEM_XYM:
useM
=
true
;
}
target
.
dimensionSystem
((
useZ
?
DIMENSION_SYSTEM_XYZ
:
0
)
|
(
useM
?
DIMENSION_SYSTEM_XYM
:
0
));
type
%=
1_000
;
switch
(
type
)
{
case
POINT:
...
...
h2/src/main/org/h2/util/geometry/EWKTUtils.java
浏览文件 @
92d7f561
...
...
@@ -41,6 +41,30 @@ import org.h2.util.geometry.GeometryUtils.Target;
*/
public
final
class
EWKTUtils
{
/**
* 0-based type names of geometries, subtract 1 from type code to get index
* in this array.
*/
private
static
final
String
[]
TYPES
=
{
//
"POINT"
,
//
"LINESTRING"
,
//
"POLYGON"
,
//
"MULTIPOINT"
,
//
"MULTILINESTRING"
,
//
"MULTIPOLYGON"
,
//
"GEOMETRYCOLLECTION"
,
//
};
/**
* Names of dimension systems.
*/
private
static
final
String
[]
DIMENSION_SYSTEMS
=
{
//
"XY"
,
//
"Z"
,
//
"M"
,
//
"ZM"
,
//
};
/**
* Converter output target that writes a EWKT.
*/
...
...
@@ -249,10 +273,19 @@ public final class EWKTUtils {
}
int
readSRID
()
{
skipWS
();
int
srid
;
if
(
ewkt
.
startsWith
(
"SRID="
))
{
if
(
ewkt
.
regionMatches
(
true
,
offset
,
"SRID="
,
0
,
5
))
{
offset
+=
5
;
int
idx
=
ewkt
.
indexOf
(
';'
,
5
);
srid
=
Integer
.
parseInt
(
ewkt
.
substring
(
5
,
idx
));
if
(
idx
<
0
)
{
throw
new
IllegalArgumentException
();
}
int
end
=
idx
;
while
(
ewkt
.
charAt
(
end
-
1
)
<=
' '
)
{
end
--;
}
srid
=
Integer
.
parseInt
(
ewkt
.
substring
(
offset
,
end
).
trim
());
offset
=
idx
+
1
;
}
else
{
srid
=
0
;
...
...
@@ -319,7 +352,7 @@ public final class EWKTUtils {
int
o
=
offset
;
skipWS
();
int
len
=
ewkt
.
length
();
if
(
offset
>
len
-
2
)
{
if
(
offset
>
=
len
)
{
throw
new
IllegalArgumentException
();
}
int
result
;
...
...
@@ -333,12 +366,16 @@ public final class EWKTUtils {
case
'Z'
:
case
'z'
:
offset
++;
ch
=
ewkt
.
charAt
(
offset
);
if
(
ch
==
'M'
||
ch
==
'm'
)
{
offset
++;
result
=
DIMENSION_SYSTEM_XYZM
;
}
else
{
if
(
offset
>=
len
)
{
result
=
DIMENSION_SYSTEM_XYZ
;
}
else
{
ch
=
ewkt
.
charAt
(
offset
);
if
(
ch
==
'M'
||
ch
==
'm'
)
{
offset
++;
result
=
DIMENSION_SYSTEM_XYZM
;
}
else
{
result
=
DIMENSION_SYSTEM_XYZ
;
}
}
break
;
default
:
...
...
@@ -580,6 +617,71 @@ public final class EWKTUtils {
parseEWKT
(
new
EWKTSource
(
ewkt
),
target
,
0
,
0
);
}
/**
* Parses geometry type and dimension system from the given string.
*
* @param s
* string to parse
* @return geometry type and dimension system in OGC geometry code format
* (type + dimensionSystem * 1000)
* @throws IllegalArgumentException
* if input is not valid
*/
public
static
int
parseGeometryType
(
String
s
)
{
EWKTSource
source
=
new
EWKTSource
(
s
);
int
type
=
source
.
readType
();
int
dimensionSystem
=
0
;
if
(
source
.
hasData
())
{
dimensionSystem
=
source
.
readDimensionSystem
();
if
(
source
.
hasData
())
{
throw
new
IllegalArgumentException
();
}
}
return
dimensionSystem
*
1_000
+
type
;
}
/**
* Parses a dimension system from the given string.
*
* @param s
* string to parse
* @return dimension system, one of XYZ, XYM, or XYZM
* @see GeometryUtils#DIMENSION_SYSTEM_XYZ
* @see GeometryUtils#DIMENSION_SYSTEM_XYM
* @see GeometryUtils#DIMENSION_SYSTEM_XYZM
* @throws IllegalArgumentException
* if input is not valid
*/
public
static
int
parseDimensionSystem
(
String
s
)
{
EWKTSource
source
=
new
EWKTSource
(
s
);
int
dimensionSystem
=
source
.
readDimensionSystem
();
if
(
source
.
hasData
()
||
dimensionSystem
==
DIMENSION_SYSTEM_XY
)
{
throw
new
IllegalArgumentException
();
}
return
dimensionSystem
;
}
/**
* Formats type and dimension system as a string.
*
* @param type
* OGC geometry code format (type + dimensionSystem * 1000)
* @return formatted string
* @throws IllegalArgumentException
* if type is not valid
*/
public
static
String
formatGeometryTypeAndDimensionSystem
(
int
type
)
{
int
t
=
type
%
1_000
,
d
=
type
/
1_000
;
if
(
t
<
POINT
||
t
>
GEOMETRY_COLLECTION
||
d
<
DIMENSION_SYSTEM_XY
||
d
>
DIMENSION_SYSTEM_XYZM
)
{
throw
new
IllegalArgumentException
();
}
String
result
=
TYPES
[
t
-
1
];
if
(
d
!=
DIMENSION_SYSTEM_XY
)
{
result
=
result
+
' '
+
DIMENSION_SYSTEMS
[
d
];
}
return
result
;
}
/**
* Parses a EWKB.
*
...
...
@@ -613,6 +715,7 @@ public final class EWKTUtils {
type
=
POLYGON
;
break
;
}
target
.
dimensionSystem
(
dimensionSystem
);
switch
(
type
)
{
case
POINT:
{
if
(
parentType
!=
0
&&
parentType
!=
MULTI_POINT
&&
parentType
!=
GEOMETRY_COLLECTION
)
{
...
...
h2/src/main/org/h2/util/geometry/GeometryUtils.java
浏览文件 @
92d7f561
...
...
@@ -27,6 +27,15 @@ public final class GeometryUtils {
protected
void
init
(
int
srid
)
{
}
/**
* Invoked to add dimension system requirement.
*
* @param dimensionSystem
* dimension system
*/
protected
void
dimensionSystem
(
int
dimensionSystem
)
{
}
/**
* Invoked before writing a POINT.
*/
...
...
@@ -238,6 +247,16 @@ public final class GeometryUtils {
public
DimensionSystemTarget
()
{
}
@Override
protected
void
dimensionSystem
(
int
dimensionSystem
)
{
if
((
dimensionSystem
&
DIMENSION_SYSTEM_XYZ
)
!=
0
)
{
hasZ
=
true
;
}
if
((
dimensionSystem
&
DIMENSION_SYSTEM_XYM
)
!=
0
)
{
hasM
=
true
;
}
}
@Override
protected
void
addCoordinate
(
double
x
,
double
y
,
double
z
,
double
m
,
int
index
,
int
total
)
{
if
(!
hasZ
&&
!
Double
.
isNaN
(
z
))
{
...
...
@@ -288,6 +307,16 @@ public final class GeometryUtils {
public
EnvelopeAndDimensionSystemTarget
()
{
}
@Override
protected
void
dimensionSystem
(
int
dimensionSystem
)
{
if
((
dimensionSystem
&
DIMENSION_SYSTEM_XYZ
)
!=
0
)
{
hasZ
=
true
;
}
if
((
dimensionSystem
&
DIMENSION_SYSTEM_XYM
)
!=
0
)
{
hasM
=
true
;
}
}
@Override
protected
void
startPoint
()
{
enabled
=
true
;
...
...
@@ -362,37 +391,37 @@ public final class GeometryUtils {
/**
* POINT geometry type.
*/
static
final
int
POINT
=
1
;
public
static
final
int
POINT
=
1
;
/**
* LINESTRING geometry type.
*/
static
final
int
LINE_STRING
=
2
;
public
static
final
int
LINE_STRING
=
2
;
/**
* POLYGON geometry type.
*/
static
final
int
POLYGON
=
3
;
public
static
final
int
POLYGON
=
3
;
/**
* MULTIPOINT geometry type.
*/
static
final
int
MULTI_POINT
=
4
;
public
static
final
int
MULTI_POINT
=
4
;
/**
* MULTILINESTRING geometry type.
*/
static
final
int
MULTI_LINE_STRING
=
5
;
public
static
final
int
MULTI_LINE_STRING
=
5
;
/**
* MULTIPOLYGON geometry type.
*/
static
final
int
MULTI_POLYGON
=
6
;
public
static
final
int
MULTI_POLYGON
=
6
;
/**
* GEOMETRYCOLLECTION geometry type.
*/
static
final
int
GEOMETRY_COLLECTION
=
7
;
public
static
final
int
GEOMETRY_COLLECTION
=
7
;
/**
* Number of X coordinate.
...
...
h2/src/main/org/h2/value/DataType.java
浏览文件 @
92d7f561
...
...
@@ -358,7 +358,7 @@ public class DataType {
104
);
add
(
Value
.
GEOMETRY
,
Types
.
OTHER
,
create
String
(
false
),
create
Geometry
(
),
new
String
[]{
"GEOMETRY"
},
32
);
...
...
@@ -548,6 +548,17 @@ public class DataType {
return
t
;
}
private
static
DataType
createGeometry
()
{
DataType
dataType
=
new
DataType
();
dataType
.
prefix
=
"'"
;
dataType
.
suffix
=
"'"
;
dataType
.
params
=
"TYPE,SRID"
;
dataType
.
maxPrecision
=
Integer
.
MAX_VALUE
;
dataType
.
defaultPrecision
=
Integer
.
MAX_VALUE
;
dataType
.
defaultDisplaySize
=
Integer
.
MAX_VALUE
;
return
dataType
;
}
/**
* Get the list of data types.
*
...
...
@@ -1403,6 +1414,16 @@ public class DataType {
return
type
==
Value
.
STRING
||
type
==
Value
.
STRING_FIXED
||
type
==
Value
.
STRING_IGNORECASE
;
}
/**
* Check if the given type may have extended type information.
*
* @param type the value type
* @return true if the value type may have extended type information
*/
public
static
boolean
isExtInfoType
(
int
type
)
{
return
type
==
Value
.
GEOMETRY
||
type
==
Value
.
ENUM
;
}
/**
* Check if the given value type supports the add operation.
*
...
...
h2/src/main/org/h2/value/ExtTypeInfo.java
0 → 100644
浏览文件 @
92d7f561
/*
* 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
;
/**
* Extended parameters of a data type.
*/
public
abstract
class
ExtTypeInfo
{
/**
* Casts a specified value to this data type.
*
* @param value
* value to cast
* @return casted value
*/
public
abstract
Value
cast
(
Value
value
);
/**
* Returns SQL including parentheses that should be appended to a type name.
*
* @return SQL including parentheses that should be appended to a type name
*/
public
abstract
String
getCreateSQL
();
@Override
public
String
toString
()
{
return
getCreateSQL
();
}
}
h2/src/main/org/h2/value/ExtTypeInfoEnum.java
0 → 100644
浏览文件 @
92d7f561
/*
* 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
java.util.Arrays
;
import
java.util.Locale
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
/**
* Extended parameters of the ENUM data type.
*/
public
final
class
ExtTypeInfoEnum
extends
ExtTypeInfo
{
private
final
String
[]
enumerators
,
cleaned
;
/**
* Returns enumerators for the two specified values for a binary operation.
*
* @param left
* left (first) operand
* @param right
* right (second) operand
* @return enumerators from the left or the right value, or an empty array
* if both values do not have enumerators
*/
public
static
ExtTypeInfoEnum
getEnumeratorsForBinaryOperation
(
Value
left
,
Value
right
)
{
if
(
left
.
getType
()
==
Value
.
ENUM
)
{
return
((
ValueEnum
)
left
).
getEnumerators
();
}
else
if
(
right
.
getType
()
==
Value
.
ENUM
)
{
return
((
ValueEnum
)
right
).
getEnumerators
();
}
else
{
throw
DbException
.
get
(
ErrorCode
.
UNKNOWN_DATA_TYPE_1
,
"type1="
+
left
.
getType
()
+
", type2="
+
right
.
getType
());
}
}
private
static
String
sanitize
(
String
label
)
{
return
label
==
null
?
null
:
label
.
trim
().
toUpperCase
(
Locale
.
ENGLISH
);
}
private
static
String
toSQL
(
String
[]
enumerators
)
{
StringBuilder
result
=
new
StringBuilder
();
result
.
append
(
'('
);
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
if
(
i
!=
0
)
{
result
.
append
(
", "
);
}
result
.
append
(
'\''
);
String
s
=
enumerators
[
i
];
for
(
int
j
=
0
;
j
<
s
.
length
();
j
++)
{
char
c
=
s
.
charAt
(
j
);
if
(
c
==
'\''
)
{
result
.
append
(
'\''
);
}
result
.
append
(
c
);
}
result
.
append
(
'\''
);
}
result
.
append
(
')'
);
return
result
.
toString
();
}
/**
* Creates new instance of extended parameters of the ENUM data type.
*
* @param enumerators
* the enumerators. May not be modified by caller or this class.
*/
public
ExtTypeInfoEnum
(
String
[]
enumerators
)
{
if
(
enumerators
==
null
||
enumerators
.
length
==
0
)
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_EMPTY
);
}
final
String
[]
cleaned
=
new
String
[
enumerators
.
length
];
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
String
l
=
sanitize
(
enumerators
[
i
]);
if
(
l
==
null
||
l
.
isEmpty
())
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_EMPTY
);
}
for
(
int
j
=
0
;
j
<
i
;
j
++)
{
if
(
l
.
equals
(
cleaned
[
j
]))
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_DUPLICATE
,
toSQL
(
enumerators
));
}
}
cleaned
[
i
]
=
l
;
}
this
.
enumerators
=
enumerators
;
this
.
cleaned
=
Arrays
.
equals
(
cleaned
,
enumerators
)
?
enumerators
:
cleaned
;
}
@Override
public
Value
cast
(
Value
value
)
{
switch
(
value
.
getType
())
{
case
Value
.
ENUM
:
if
(
value
instanceof
ValueEnum
&&
((
ValueEnum
)
value
).
getEnumerators
().
equals
(
this
))
{
return
value
;
}
//$FALL-THROUGH$
case
Value
.
STRING
:
case
Value
.
STRING_FIXED
:
case
Value
.
STRING_IGNORECASE
:
ValueEnum
v
=
getValueOrNull
(
value
.
getString
());
if
(
v
!=
null
)
{
return
v
;
}
break
;
default
:
int
ordinal
=
value
.
getInt
();
if
(
ordinal
>=
0
&&
ordinal
<
enumerators
.
length
)
{
return
new
ValueEnum
(
this
,
enumerators
[
ordinal
],
ordinal
);
}
}
String
s
=
value
.
getTraceSQL
();
if
(
s
.
length
()
>
127
)
{
s
=
s
.
substring
(
0
,
128
)
+
"..."
;
}
throw
DbException
.
get
(
ErrorCode
.
ENUM_VALUE_NOT_PERMITTED
,
toString
(),
s
);
}
/**
* Returns an enumerator with specified 0-based ordinal value.
*
* @param ordinal
* ordinal value of an enumerator
* @return the enumerator with specified ordinal value
*/
public
String
getEnumerator
(
int
ordinal
)
{
return
enumerators
[
ordinal
];
}
public
ValueEnum
getValue
(
int
ordinal
)
{
if
(
ordinal
<
0
||
ordinal
>=
enumerators
.
length
)
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_VALUE_NOT_PERMITTED
,
enumerators
.
toString
(),
Integer
.
toString
(
ordinal
));
}
return
new
ValueEnum
(
this
,
enumerators
[
ordinal
],
ordinal
);
}
public
ValueEnum
getValue
(
String
label
)
{
ValueEnum
value
=
getValueOrNull
(
label
);
if
(
value
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_VALUE_NOT_PERMITTED
,
toString
(),
label
);
}
return
value
;
}
private
ValueEnum
getValueOrNull
(
String
label
)
{
String
l
=
sanitize
(
label
);
if
(
l
!=
null
)
{
for
(
int
ordinal
=
0
;
ordinal
<
cleaned
.
length
;
ordinal
++)
{
if
(
l
.
equals
(
cleaned
[
ordinal
]))
{
return
new
ValueEnum
(
this
,
enumerators
[
ordinal
],
ordinal
);
}
}
}
return
null
;
}
@Override
public
int
hashCode
()
{
return
Arrays
.
hashCode
(
enumerators
)
+
203_117
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
obj
.
getClass
()
!=
ExtTypeInfoEnum
.
class
)
{
return
false
;
}
return
Arrays
.
equals
(
enumerators
,
((
ExtTypeInfoEnum
)
obj
).
enumerators
);
}
@Override
public
String
getCreateSQL
()
{
return
toSQL
(
enumerators
);
}
}
h2/src/main/org/h2/value/ExtTypeInfoGeometry.java
0 → 100644
浏览文件 @
92d7f561
/*
* 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.message.DbException
;
import
org.h2.util.geometry.EWKTUtils
;
/**
* Extended parameters of the GEOMETRY data type.
*/
public
final
class
ExtTypeInfoGeometry
extends
ExtTypeInfo
{
private
final
int
type
;
private
final
Integer
srid
;
private
static
String
toSQL
(
int
type
,
Integer
srid
)
{
if
(
type
==
0
&&
srid
==
null
)
{
return
""
;
}
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
'('
);
if
(
type
!=
0
)
{
builder
.
append
(
EWKTUtils
.
formatGeometryTypeAndDimensionSystem
(
type
));
}
if
(
srid
!=
null
)
{
if
(
type
!=
0
)
{
builder
.
append
(
", "
);
}
builder
.
append
((
int
)
srid
);
}
return
builder
.
append
(
')'
).
toString
();
}
/**
* Creates new instance of extended parameters of the GEOMETRY data type.
*
* @param type
* the type and dimension system of geometries, or 0 if not
* constrained
* @param srid
* the SRID of geometries, or {@code null} if not constrained
*/
public
ExtTypeInfoGeometry
(
int
type
,
Integer
srid
)
{
this
.
type
=
type
;
this
.
srid
=
srid
;
}
@Override
public
Value
cast
(
Value
value
)
{
if
(
value
.
getType
()
!=
Value
.
GEOMETRY
)
{
value
=
value
.
convertTo
(
Value
.
GEOMETRY
);
}
ValueGeometry
g
=
(
ValueGeometry
)
value
;
if
(
type
!=
0
&&
g
.
getTypeAndDimensionSystem
()
!=
type
||
srid
!=
null
&&
g
.
getSRID
()
!=
srid
)
{
throw
DbException
.
get
(
ErrorCode
.
CHECK_CONSTRAINT_VIOLATED_1
,
toSQL
(
g
.
getTypeAndDimensionSystem
(),
g
.
getSRID
())
+
" <> "
+
toString
());
}
return
g
;
}
@Override
public
String
getCreateSQL
()
{
return
toSQL
(
type
,
srid
);
}
}
h2/src/main/org/h2/value/Value.java
浏览文件 @
92d7f561
...
...
@@ -677,10 +677,10 @@ public abstract class Value {
/**
* Convert value to ENUM value
* @param enumerators
allowed values for the ENUM to which the value is converted
* @param enumerators
the extended type information for the ENUM data type
* @return value represented as ENUM
*/
public
final
Value
convertToEnum
(
String
[]
enumerators
)
{
public
final
Value
convertToEnum
(
ExtTypeInfo
enumerators
)
{
// Use -1 to indicate "default behaviour" where value conversion should not
// depend on any datatype precision.
return
convertTo
(
ENUM
,
-
1
,
null
,
null
,
enumerators
);
...
...
@@ -706,11 +706,10 @@ public abstract class Value {
* the precision plays no role when converting the value
* @param mode the conversion mode
* @param column the column (if any), used for to improve the error message if conversion fails
* @param enumerators the ENUM datatype enumerators (if any),
* for dealing with ENUM conversions
* @param extTypeInfo the extended data type information, or null
* @return the converted value
*/
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
// converting NULL is done in ValueNull
// converting BLOB to CLOB and vice versa is done in ValueLob
if
(
getType
()
==
targetType
)
{
...
...
@@ -755,7 +754,7 @@ public abstract class Value {
case
JAVA_OBJECT:
return
convertToJavaObject
();
case
ENUM:
return
convertToEnumInternal
(
enumerators
);
return
convertToEnumInternal
(
(
ExtTypeInfoEnum
)
extTypeInfo
);
case
BLOB:
return
convertToBlob
();
case
CLOB:
...
...
@@ -763,7 +762,7 @@ public abstract class Value {
case
UUID:
return
convertToUuid
();
case
GEOMETRY:
return
convertToGeometry
();
return
convertToGeometry
(
(
ExtTypeInfoGeometry
)
extTypeInfo
);
case
Value
.
INTERVAL_YEAR
:
case
Value
.
INTERVAL_MONTH
:
case
Value
.
INTERVAL_YEAR_TO_MONTH
:
...
...
@@ -1158,24 +1157,24 @@ public abstract class Value {
return
ValueJavaObject
.
getNoCopy
(
null
,
StringUtils
.
convertHexToBytes
(
getString
().
trim
()),
getDataHandler
());
}
private
ValueEnum
convertToEnumInternal
(
String
[]
enumerators
)
{
private
ValueEnum
convertToEnumInternal
(
ExtTypeInfoEnum
extTypeInfo
)
{
switch
(
getType
())
{
case
BYTE:
case
SHORT:
case
INT:
case
LONG:
case
DECIMAL:
return
ValueEnum
.
get
(
enumerators
,
getInt
());
return
extTypeInfo
.
getValue
(
getInt
());
case
STRING:
case
STRING_IGNORECASE:
case
STRING_FIXED:
return
ValueEnum
.
get
(
enumerators
,
getString
());
return
extTypeInfo
.
getValue
(
getString
());
case
JAVA_OBJECT:
Object
object
=
JdbcUtils
.
deserialize
(
getBytesNoCopy
(),
getDataHandler
());
if
(
object
instanceof
String
)
{
return
ValueEnum
.
get
(
enumerators
,
(
String
)
object
);
return
extTypeInfo
.
getValue
(
(
String
)
object
);
}
else
if
(
object
instanceof
Integer
)
{
return
ValueEnum
.
get
(
enumerators
,
(
int
)
object
);
return
extTypeInfo
.
getValue
(
(
int
)
object
);
}
//$FALL-THROUGH$
}
...
...
@@ -1212,20 +1211,25 @@ public abstract class Value {
return
ValueUuid
.
get
(
getString
());
}
private
ValueGeometry
convertToGeometry
()
{
private
Value
convertToGeometry
(
ExtTypeInfoGeometry
extTypeInfo
)
{
ValueGeometry
result
;
switch
(
getType
())
{
case
BYTES:
return
ValueGeometry
.
getFromEWKB
(
getBytesNoCopy
());
result
=
ValueGeometry
.
getFromEWKB
(
getBytesNoCopy
());
break
;
case
JAVA_OBJECT:
Object
object
=
JdbcUtils
.
deserialize
(
getBytesNoCopy
(),
getDataHandler
());
if
(
DataType
.
isGeometry
(
object
))
{
return
ValueGeometry
.
getFromGeometry
(
object
);
result
=
ValueGeometry
.
getFromGeometry
(
object
);
break
;
}
//$FALL-THROUGH$
case
TIMESTAMP_TZ:
throw
getDataConversionError
(
GEOMETRY
);
default
:
result
=
ValueGeometry
.
get
(
getString
());
}
return
ValueGeometry
.
get
(
getString
())
;
return
extTypeInfo
!=
null
?
extTypeInfo
.
cast
(
result
)
:
result
;
}
private
ValueInterval
convertToIntervalYearMonth
(
int
targetType
)
{
...
...
@@ -1337,7 +1341,7 @@ public abstract class Value {
if
(
leftType
!=
rightType
||
leftType
==
Value
.
ENUM
)
{
int
dataType
=
Value
.
getHigherOrder
(
leftType
,
rightType
);
if
(
dataType
==
Value
.
ENUM
)
{
String
[]
enumerators
=
Value
Enum
.
getEnumeratorsForBinaryOperation
(
l
,
v
);
ExtTypeInfoEnum
enumerators
=
ExtTypeInfo
Enum
.
getEnumeratorsForBinaryOperation
(
l
,
v
);
l
=
l
.
convertToEnum
(
enumerators
);
v
=
v
.
convertToEnum
(
enumerators
);
}
else
{
...
...
h2/src/main/org/h2/value/ValueEnum.java
浏览文件 @
92d7f561
...
...
@@ -5,196 +5,20 @@
*/
package
org
.
h2
.
value
;
import
java.util.Locale
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
/**
* ENUM value.
*/
public
class
ValueEnum
extends
ValueEnumBase
{
private
enum
Validation
{
DUPLICATE
,
EMPTY
,
INVALID
,
VALID
}
private
final
String
[]
enumerators
;
private
final
ExtTypeInfoEnum
enumerators
;
private
ValueEnum
(
final
String
[]
enumerators
,
final
int
ordinal
)
{
super
(
enumerators
[
ordinal
]
,
ordinal
);
ValueEnum
(
ExtTypeInfoEnum
enumerators
,
String
label
,
int
ordinal
)
{
super
(
label
,
ordinal
);
this
.
enumerators
=
enumerators
;
}
/**
* Check for any violations, such as empty
* values, duplicate values.
*
* @param enumerators the enumerators
*/
public
static
void
check
(
final
String
[]
enumerators
)
{
switch
(
validate
(
enumerators
))
{
case
VALID:
return
;
case
EMPTY:
throw
DbException
.
get
(
ErrorCode
.
ENUM_EMPTY
);
case
DUPLICATE:
throw
DbException
.
get
(
ErrorCode
.
ENUM_DUPLICATE
,
toString
(
enumerators
));
default
:
throw
DbException
.
get
(
ErrorCode
.
INVALID_VALUE_2
,
toString
(
enumerators
));
}
}
private
static
void
check
(
final
String
[]
enumerators
,
final
Value
value
)
{
check
(
enumerators
);
if
(
validate
(
enumerators
,
value
)
!=
Validation
.
VALID
)
{
throw
DbException
.
get
(
ErrorCode
.
ENUM_VALUE_NOT_PERMITTED
,
toString
(
enumerators
),
value
.
toString
());
}
}
/**
* Create an ENUM value from the provided enumerators
* and value.
*
* @param enumerators the enumerators
* @param value a value
* @return the ENUM value
*/
public
static
ValueEnum
get
(
final
String
[]
enumerators
,
int
value
)
{
check
(
enumerators
,
ValueInt
.
get
(
value
));
return
new
ValueEnum
(
enumerators
,
value
);
}
public
static
ValueEnum
get
(
final
String
[]
enumerators
,
String
value
)
{
check
(
enumerators
,
ValueString
.
get
(
value
));
final
String
cleanLabel
=
sanitize
(
value
);
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
if
(
cleanLabel
.
equals
(
sanitize
(
enumerators
[
i
])))
{
return
new
ValueEnum
(
enumerators
,
i
);
}
}
throw
DbException
.
get
(
ErrorCode
.
GENERAL_ERROR_1
,
"Unexpected error"
);
}
/**
* Returns enumerators for the two specified values for a binary operation.
*
* @param left
* left (first) operand
* @param right
* right (second) operand
* @return enumerators from the left or the right value, or an empty array if
* both values do not have enumerators
*/
public
static
String
[]
getEnumeratorsForBinaryOperation
(
Value
left
,
Value
right
)
{
if
(
left
.
getType
()
==
Value
.
ENUM
)
{
return
((
ValueEnum
)
left
).
getEnumerators
();
}
else
if
(
right
.
getType
()
==
Value
.
ENUM
)
{
return
((
ValueEnum
)
right
).
getEnumerators
();
}
else
{
return
new
String
[
0
];
}
}
public
String
[]
getEnumerators
()
{
public
ExtTypeInfoEnum
getEnumerators
()
{
return
enumerators
;
}
/**
* Evaluates whether a valid ENUM can be constructed
* from the provided enumerators and value.
*
* @param enumerators the enumerators
* @param value the value
* @return whether a valid ENUM can be constructed from the provided values
*/
public
static
boolean
isValid
(
final
String
enumerators
[],
final
Value
value
)
{
return
validate
(
enumerators
,
value
).
equals
(
Validation
.
VALID
);
}
private
static
String
sanitize
(
final
String
label
)
{
return
label
==
null
?
null
:
label
.
trim
().
toUpperCase
(
Locale
.
ENGLISH
);
}
private
static
String
[]
sanitize
(
final
String
[]
enumerators
)
{
if
(
enumerators
==
null
||
enumerators
.
length
==
0
)
{
return
null
;
}
final
String
[]
clean
=
new
String
[
enumerators
.
length
];
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
clean
[
i
]
=
sanitize
(
enumerators
[
i
]);
}
return
clean
;
}
private
static
String
toString
(
final
String
[]
enumerators
)
{
String
result
=
"("
;
for
(
int
i
=
0
;
i
<
enumerators
.
length
;
i
++)
{
result
+=
"'"
+
enumerators
[
i
]
+
"'"
;
if
(
i
<
enumerators
.
length
-
1
)
{
result
+=
", "
;
}
}
result
+=
")"
;
return
result
;
}
private
static
Validation
validate
(
final
String
[]
enumerators
)
{
final
String
[]
cleaned
=
sanitize
(
enumerators
);
if
(
cleaned
==
null
||
cleaned
.
length
==
0
)
{
return
Validation
.
EMPTY
;
}
for
(
int
i
=
0
;
i
<
cleaned
.
length
;
i
++)
{
if
(
cleaned
[
i
]
==
null
||
cleaned
[
i
].
equals
(
""
))
{
return
Validation
.
EMPTY
;
}
if
(
i
<
cleaned
.
length
-
1
)
{
for
(
int
j
=
i
+
1
;
j
<
cleaned
.
length
;
j
++)
{
if
(
cleaned
[
i
].
equals
(
cleaned
[
j
]))
{
return
Validation
.
DUPLICATE
;
}
}
}
}
return
Validation
.
VALID
;
}
private
static
Validation
validate
(
final
String
[]
enumerators
,
final
Value
value
)
{
final
Validation
validation
=
validate
(
enumerators
);
if
(!
validation
.
equals
(
Validation
.
VALID
))
{
return
validation
;
}
if
(
DataType
.
isStringType
(
value
.
getType
()))
{
final
String
cleanLabel
=
sanitize
(
value
.
getString
());
for
(
String
enumerator
:
enumerators
)
{
if
(
cleanLabel
.
equals
(
sanitize
(
enumerator
)))
{
return
Validation
.
VALID
;
}
}
return
Validation
.
INVALID
;
}
else
{
final
int
ordinal
=
value
.
getInt
();
if
(
ordinal
<
0
||
ordinal
>=
enumerators
.
length
)
{
return
Validation
.
INVALID
;
}
return
Validation
.
VALID
;
}
}
}
h2/src/main/org/h2/value/ValueEnumBase.java
浏览文件 @
92d7f561
...
...
@@ -8,6 +8,8 @@ package org.h2.value;
import
java.sql.PreparedStatement
;
import
java.sql.SQLException
;
import
org.h2.engine.Mode
;
/**
* Base implementation of the ENUM data type.
*
...
...
@@ -137,4 +139,13 @@ public class ValueEnumBase extends Value {
final
Value
iv
=
v
.
convertTo
(
Value
.
INT
);
return
convertTo
(
Value
.
INT
).
subtract
(
iv
);
}
@Override
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
if
(
targetType
==
Value
.
ENUM
)
{
return
extTypeInfo
.
cast
(
this
);
}
return
super
.
convertTo
(
targetType
,
precision
,
mode
,
column
,
extTypeInfo
);
}
}
h2/src/main/org/h2/value/ValueGeometry.java
浏览文件 @
92d7f561
...
...
@@ -5,6 +5,7 @@
*/
package
org
.
h2
.
value
;
import
static
org
.
h2
.
util
.
geometry
.
EWKBUtils
.
EWKB_SRID
;
import
java.sql.PreparedStatement
;
import
java.sql.SQLException
;
import
java.util.Arrays
;
...
...
@@ -18,6 +19,7 @@ import org.h2.util.geometry.EWKBUtils;
import
org.h2.util.geometry.EWKTUtils
;
import
org.h2.util.geometry.GeometryUtils
;
import
org.h2.util.geometry.GeometryUtils.EnvelopeAndDimensionSystemTarget
;
import
org.h2.util.geometry.GeometryUtils.EnvelopeTarget
;
import
org.h2.util.geometry.JTSUtils
;
import
org.locationtech.jts.geom.Geometry
;
...
...
@@ -30,6 +32,8 @@ import org.locationtech.jts.geom.Geometry;
*/
public
class
ValueGeometry
extends
Value
{
private
static
final
double
[]
UNKNOWN_ENVELOPE
=
new
double
[
0
];
/**
* As conversion from/to WKB cost a significant amount of CPU cycles, WKB
* are kept in ValueGeometry instance.
...
...
@@ -43,9 +47,15 @@ public class ValueGeometry extends Value {
private
final
int
hashCode
;
/**
* Dimension system. -1 if not known yet.
* Geometry type and dimension system in OGC geometry code format (type +
* dimensionSystem * 1000).
*/
private
final
int
typeAndDimensionSystem
;
/**
* Spatial reference system identifier.
*/
private
int
dimensionSystem
;
private
final
int
srid
;
/**
* The envelope of the value. Calculated only on request.
...
...
@@ -62,14 +72,18 @@ public class ValueGeometry extends Value {
* Create a new geometry object.
*
* @param bytes the EWKB bytes
* @param dimensionSystem dimension system
* @param envelope the envelope
*/
private
ValueGeometry
(
byte
[]
bytes
,
int
dimensionSystem
,
double
[]
envelope
)
{
private
ValueGeometry
(
byte
[]
bytes
,
double
[]
envelope
)
{
if
(
bytes
.
length
<
9
||
bytes
[
0
]
!=
0
)
{
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
StringUtils
.
convertBytesToHex
(
bytes
));
}
this
.
bytes
=
bytes
;
this
.
hashCode
=
Arrays
.
hashCode
(
bytes
);
this
.
dimensionSystem
=
dimensionSystem
;
this
.
envelope
=
envelope
;
int
t
=
Bits
.
readInt
(
bytes
,
1
);
srid
=
(
t
&
EWKB_SRID
)
!=
0
?
Bits
.
readInt
(
bytes
,
5
)
:
0
;
typeAndDimensionSystem
=
(
t
&
0xffff
)
%
1_000
+
EWKBUtils
.
type2dimensionSystem
(
t
)
*
1_000
;
hashCode
=
Arrays
.
hashCode
(
bytes
);
}
/**
...
...
@@ -84,9 +98,8 @@ public class ValueGeometry extends Value {
EnvelopeAndDimensionSystemTarget
target
=
new
EnvelopeAndDimensionSystemTarget
();
Geometry
g
=
(
Geometry
)
o
;
JTSUtils
.
parseGeometry
(
g
,
target
);
int
dimensionSystem
=
target
.
getDimensionSystem
();
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
JTSUtils
.
geometry2ewkb
(
g
,
dimensionSystem
),
dimensionSystem
,
target
.
getEnvelope
()));
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
//
JTSUtils
.
geometry2ewkb
(
g
,
target
.
getDimensionSystem
()),
target
.
getEnvelope
()));
}
catch
(
RuntimeException
ex
)
{
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
String
.
valueOf
(
o
));
}
...
...
@@ -102,9 +115,8 @@ public class ValueGeometry extends Value {
try
{
EnvelopeAndDimensionSystemTarget
target
=
new
EnvelopeAndDimensionSystemTarget
();
EWKTUtils
.
parseEWKT
(
s
,
target
);
int
dimensionSystem
=
target
.
getDimensionSystem
();
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
EWKTUtils
.
ewkt2ewkb
(
s
,
dimensionSystem
),
dimensionSystem
,
target
.
getEnvelope
()));
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
//
EWKTUtils
.
ewkt2ewkb
(
s
,
target
.
getDimensionSystem
()),
target
.
getEnvelope
()));
}
catch
(
RuntimeException
ex
)
{
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
s
);
}
...
...
@@ -129,7 +141,7 @@ public class ValueGeometry extends Value {
* @return the value
*/
public
static
ValueGeometry
get
(
byte
[]
bytes
)
{
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
bytes
,
-
1
,
null
));
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
bytes
,
UNKNOWN_ENVELOPE
));
}
/**
...
...
@@ -142,9 +154,8 @@ public class ValueGeometry extends Value {
try
{
EnvelopeAndDimensionSystemTarget
target
=
new
EnvelopeAndDimensionSystemTarget
();
EWKBUtils
.
parseEWKB
(
bytes
,
target
);
int
dimensionSystem
=
target
.
getDimensionSystem
();
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
EWKBUtils
.
ewkb2ewkb
(
bytes
,
dimensionSystem
),
dimensionSystem
,
target
.
getEnvelope
()));
return
(
ValueGeometry
)
Value
.
cache
(
new
ValueGeometry
(
//
EWKBUtils
.
ewkb2ewkb
(
bytes
,
target
.
getDimensionSystem
()),
target
.
getEnvelope
()));
}
catch
(
RuntimeException
ex
)
{
throw
DbException
.
get
(
ErrorCode
.
DATA_CONVERSION_ERROR_1
,
StringUtils
.
convertBytesToHex
(
bytes
));
}
...
...
@@ -158,8 +169,7 @@ public class ValueGeometry extends Value {
*/
public
static
Value
fromEnvelope
(
double
[]
envelope
)
{
return
envelope
!=
null
?
Value
.
cache
(
new
ValueGeometry
(
EWKBUtils
.
envelope2wkb
(
envelope
),
GeometryUtils
.
DIMENSION_SYSTEM_XY
,
envelope
))
?
Value
.
cache
(
new
ValueGeometry
(
EWKBUtils
.
envelope2wkb
(
envelope
),
envelope
))
:
ValueNull
.
INSTANCE
;
}
...
...
@@ -180,13 +190,23 @@ public class ValueGeometry extends Value {
return
((
Geometry
)
geometry
).
copy
();
}
private
void
calculateInfo
()
{
if
(
dimensionSystem
<
0
)
{
EnvelopeAndDimensionSystemTarget
target
=
new
EnvelopeAndDimensionSystemTarget
();
EWKBUtils
.
parseEWKB
(
bytes
,
target
);
envelope
=
target
.
getEnvelope
();
dimensionSystem
=
target
.
getDimensionSystem
();
}
/**
* Returns geometry type and dimension system in OGC geometry code format
* (type + dimensionSystem * 1000).
*
* @return geometry type and dimension system
*/
public
int
getTypeAndDimensionSystem
()
{
return
typeAndDimensionSystem
;
}
/**
* Returns geometry type.
*
* @return geometry type and dimension system
*/
public
int
getGeometryType
()
{
return
typeAndDimensionSystem
%
1_000
;
}
/**
...
...
@@ -195,8 +215,16 @@ public class ValueGeometry extends Value {
* @return dimension system
*/
public
int
getDimensionSystem
()
{
calculateInfo
();
return
dimensionSystem
;
return
typeAndDimensionSystem
/
1_000
;
}
/**
* Return a spatial reference system identifier.
*
* @return spatial reference system identifier
*/
public
int
getSRID
()
{
return
srid
;
}
/**
...
...
@@ -205,7 +233,11 @@ public class ValueGeometry extends Value {
* @return envelope of this geometry
*/
public
double
[]
getEnvelopeNoCopy
()
{
calculateInfo
();
if
(
envelope
==
UNKNOWN_ENVELOPE
)
{
EnvelopeTarget
target
=
new
EnvelopeTarget
();
EWKBUtils
.
parseEWKB
(
bytes
,
target
);
envelope
=
target
.
getEnvelope
();
}
return
envelope
;
}
...
...
@@ -318,8 +350,10 @@ public class ValueGeometry extends Value {
}
@Override
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
if
(
targetType
==
Value
.
JAVA_OBJECT
)
{
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
if
(
targetType
==
Value
.
GEOMETRY
)
{
return
extTypeInfo
!=
null
?
extTypeInfo
.
cast
(
this
)
:
this
;
}
else
if
(
targetType
==
Value
.
JAVA_OBJECT
)
{
return
this
;
}
return
super
.
convertTo
(
targetType
,
precision
,
mode
,
column
,
null
);
...
...
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
92d7f561
...
...
@@ -371,12 +371,11 @@ public class ValueLob extends Value {
* the precision plays no role when converting the value
* @param mode the database mode
* @param column the column (if any), used for to improve the error message if conversion fails
* @param enumerators the ENUM datatype enumerators (if any),
* for dealing with ENUM conversions
* @param extTypeInfo the extended data type information, or null
* @return the converted value
*/
@Override
public
Value
convertTo
(
int
t
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
public
Value
convertTo
(
int
t
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
if
(
t
==
valueType
)
{
return
this
;
}
else
if
(
t
==
Value
.
CLOB
)
{
...
...
h2/src/main/org/h2/value/ValueLobDb.java
浏览文件 @
92d7f561
...
...
@@ -206,12 +206,11 @@ public class ValueLobDb extends Value {
* @param precision the precision
* @param mode the mode
* @param column the column (if any), used for to improve the error message if conversion fails
* @param enumerators the ENUM datatype enumerators (if any),
* for dealing with ENUM conversions
* @param extTypeInfo the extended data type information, or null
* @return the converted value
*/
@Override
public
Value
convertTo
(
int
t
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
public
Value
convertTo
(
int
t
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
if
(
t
==
valueType
)
{
return
this
;
}
else
if
(
t
==
Value
.
CLOB
)
{
...
...
h2/src/main/org/h2/value/ValueNull.java
浏览文件 @
92d7f561
...
...
@@ -134,7 +134,7 @@ public class ValueNull extends Value {
}
@Override
public
Value
convertTo
(
int
type
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
public
Value
convertTo
(
int
type
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
return
this
;
}
...
...
h2/src/test/org/h2/test/db/TestSpatial.java
浏览文件 @
92d7f561
...
...
@@ -641,7 +641,7 @@ public class TestSpatial extends TestDb {
}
private
void
checkSRID
(
byte
[]
bytes
,
int
srid
)
{
Point
point
=
(
Point
)
ValueGeometry
.
get
(
bytes
).
getGeometry
();
Point
point
=
(
Point
)
ValueGeometry
.
get
FromEWKB
(
bytes
).
getGeometry
();
assertEquals
(
1.1
,
point
.
getX
());
assertEquals
(
1.2
,
point
.
getY
());
assertEquals
(
srid
,
point
.
getSRID
());
...
...
h2/src/test/org/h2/test/jdbc/TestCustomDataTypesHandler.java
浏览文件 @
92d7f561
...
...
@@ -25,6 +25,7 @@ import org.h2.util.JdbcUtils;
import
org.h2.util.StringUtils
;
import
org.h2.value.CompareMode
;
import
org.h2.value.DataType
;
import
org.h2.value.ExtTypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueBytes
;
import
org.h2.value.ValueDouble
;
...
...
@@ -394,7 +395,7 @@ public class TestCustomDataTypesHandler extends TestDb {
}
@Override
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
String
[]
enumerators
)
{
public
Value
convertTo
(
int
targetType
,
int
precision
,
Mode
mode
,
Object
column
,
ExtTypeInfo
extTypeInfo
)
{
if
(
getType
()
==
targetType
)
{
return
this
;
}
...
...
h2/src/test/org/h2/test/scripts/datatypes/enum.sql
浏览文件 @
92d7f561
...
...
@@ -26,6 +26,12 @@ select * from card;
>
4
null
>
rows
:
3
alter
table
card
alter
column
suit
enum
(
'a'
,
'b'
,
'c'
,
'd'
);
>
exception
ENUM_VALUE_NOT_PERMITTED
alter
table
card
alter
column
suit
enum
(
'
''
none
''
'
,
'hearts'
,
'clubs'
,
'spades'
,
'diamonds'
);
>
ok
select
*
from
card
order
by
suit
;
>
RANK
SUIT
>
---- ------
...
...
@@ -50,7 +56,10 @@ select rank from card where suit = 'diamonds';
>>
8
select
column_type
from
information_schema
.
columns
where
COLUMN_NAME
=
'SUIT'
;
>>
ENUM
(
'hearts'
,
'clubs'
,
'spades'
,
'diamonds'
)
>>
ENUM
(
'
''
none
''
'
,
'hearts'
,
'clubs'
,
'spades'
,
'diamonds'
)
alter
table
card
alter
column
suit
enum
(
'hearts'
,
'clubs'
,
'spades'
,
'diamonds'
);
>
ok
--- ENUM integer-based operations
...
...
@@ -242,13 +251,13 @@ SELECT * FROM V3;
>>
-
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
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
IS_VISIBLE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ ------------- ------------------ ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------- ---------------- ----------
>
SCRIPT
PUBLIC
TEST
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
TRUE
>
SCRIPT
PUBLIC
V
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
TRUE
>
SCRIPT
PUBLIC
V1
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
SCRIPT
PUBLIC
V2
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
SCRIPT
PUBLIC
V3
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
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
DATETIME_PRECISION
INTERVAL_TYPE
INTERVAL_PRECISION
CHARACTER_SET_NAME
COLLATION_NAME
TYPE_NAME
NULLABLE
IS_COMPUTED
SELECTIVITY
CHECK_CONSTRAINT
SEQUENCE_NAME
REMARKS
SOURCE_DATA_TYPE
COLUMN_TYPE
COLUMN_ON_UPDATE
IS_VISIBLE
>
------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ ------------- ------------------ ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- -------------
-
---------------- ----------
>
SCRIPT
PUBLIC
TEST
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
TRUE
>
SCRIPT
PUBLIC
V
E
1
null
YES
1111
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
ENUM
1
FALSE
50
null
null
ENUM
(
'A'
,
'B'
)
null
TRUE
>
SCRIPT
PUBLIC
V1
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
SCRIPT
PUBLIC
V2
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
SCRIPT
PUBLIC
V3
E
1
null
YES
4
2147483647
2147483647
2147483647
10
0
null
null
null
Unicode
OFF
INTEGER
1
FALSE
50
null
null
INTEGER
null
TRUE
>
rows
(
ordered
):
5
DROP
VIEW
V
;
...
...
h2/src/test/org/h2/test/scripts/datatypes/geometry.sql
浏览文件 @
92d7f561
...
...
@@ -2,3 +2,99 @@
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE
TABLE
TEST
(
G
GEOMETRY
,
G_S
GEOMETRY
(
1
),
P
GEOMETRY
(
POINT
),
P_S
GEOMETRY
(
POINT
,
1
),
PZ1
GEOMETRY
(
POINT
Z
),
PZ2
GEOMETRY
(
POINTZ
),
PZ1_S
GEOMETRY
(
POINT
Z
,
1
),
PZ2_S
GEOMETRY
(
POINTZ
,
1
),
PM
GEOMETRY
(
POINT
M
),
PZM
GEOMETRY
(
POINT
ZM
),
PZM_S
GEOMETRY
(
POINT
ZM
,
-
100
),
LS
GEOMETRY
(
LINESTRING
),
PG
GEOMETRY
(
POLYGON
),
MP
GEOMETRY
(
MULTIPOINT
),
MLS
GEOMETRY
(
MULTILINESTRING
),
MPG
GEOMETRY
(
MULTIPOLYGON
),
GC
GEOMETRY
(
GEOMETRYCOLLECTION
));
>
ok
INSERT
INTO
TEST
VALUES
(
'POINT EMPTY'
,
'SRID=1;POINT EMPTY'
,
'POINT EMPTY'
,
'SRID=1;POINT EMPTY'
,
'POINT Z EMPTY'
,
'POINT Z EMPTY'
,
'SRID=1;POINT Z EMPTY'
,
'SRID=1;POINTZ EMPTY'
,
'POINT M EMPTY'
,
'POINT ZM EMPTY'
,
'SRID=-100;POINT ZM EMPTY'
,
'LINESTRING EMPTY'
,
'POLYGON EMPTY'
,
'MULTIPOINT EMPTY'
,
'MULTILINESTRING EMPTY'
,
'MULTIPOLYGON EMPTY'
,
'GEOMETRYCOLLECTION EMPTY'
);
>
update
count
:
1
SELECT
COLUMN_NAME
,
TYPE_NAME
,
COLUMN_TYPE
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
TABLE_NAME
=
'TEST'
ORDER
BY
ORDINAL_POSITION
;
>
COLUMN_NAME
TYPE_NAME
COLUMN_TYPE
>
----------- --------- ----------------------------
>
G
GEOMETRY
GEOMETRY
>
G_S
GEOMETRY
GEOMETRY
(
1
)
>
P
GEOMETRY
GEOMETRY
(
POINT
)
>
P_S
GEOMETRY
GEOMETRY
(
POINT
,
1
)
>
PZ1
GEOMETRY
GEOMETRY
(
POINT
Z
)
>
PZ2
GEOMETRY
GEOMETRY
(
POINT
Z
)
>
PZ1_S
GEOMETRY
GEOMETRY
(
POINT
Z
,
1
)
>
PZ2_S
GEOMETRY
GEOMETRY
(
POINT
Z
,
1
)
>
PM
GEOMETRY
GEOMETRY
(
POINT
M
)
>
PZM
GEOMETRY
GEOMETRY
(
POINT
ZM
)
>
PZM_S
GEOMETRY
GEOMETRY
(
POINT
ZM
,
-
100
)
>
LS
GEOMETRY
GEOMETRY
(
LINESTRING
)
>
PG
GEOMETRY
GEOMETRY
(
POLYGON
)
>
MP
GEOMETRY
GEOMETRY
(
MULTIPOINT
)
>
MLS
GEOMETRY
GEOMETRY
(
MULTILINESTRING
)
>
MPG
GEOMETRY
GEOMETRY
(
MULTIPOLYGON
)
>
GC
GEOMETRY
GEOMETRY
(
GEOMETRYCOLLECTION
)
>
rows
(
ordered
):
17
UPDATE
TEST
SET
G
=
'SRID=10;LINESTRING EMPTY'
;
>
update
count
:
1
UPDATE
TEST
SET
GC
=
'SRID=8;GEOMETRYCOLLECTION(POINT (1 1))'
;
>
update
count
:
1
UPDATE
TEST
SET
G_S
=
'POINT (1 1)'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
UPDATE
TEST
SET
P
=
'POINT Z EMPTY'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
UPDATE
TEST
SET
P
=
'POLYGON EMPTY'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
UPDATE
TEST
SET
PZ1
=
'POINT EMPTY'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
SELECT
*
FROM
TEST
;
>
G
G_S
P
P_S
PZ1
PZ2
PZ1_S
PZ2_S
PM
PZM
PZM_S
LS
PG
MP
MLS
MPG
GC
>
------------------------ ------------------ ----------- ------------------ ------------- ------------- -------------------- -------------------- ------------- -------------- ------------------------ ---------------- ------------- ---------------- --------------------- ------------------ ---------------------------------------
>
SRID
=
10
;
LINESTRING
EMPTY
SRID
=
1
;
POINT
EMPTY
POINT
EMPTY
SRID
=
1
;
POINT
EMPTY
POINT
Z
EMPTY
POINT
Z
EMPTY
SRID
=
1
;
POINT
Z
EMPTY
SRID
=
1
;
POINT
Z
EMPTY
POINT
M
EMPTY
POINT
ZM
EMPTY
SRID
=-
100
;
POINT
ZM
EMPTY
LINESTRING
EMPTY
POLYGON
EMPTY
MULTIPOINT
EMPTY
MULTILINESTRING
EMPTY
MULTIPOLYGON
EMPTY
SRID
=
8
;
GEOMETRYCOLLECTION
(
POINT
(
1
1
))
>
rows
:
1
SELECT
G
FROM
TEST
WHERE
P_S
=
'SRID=1;POINT EMPTY'
;
>>
SRID
=
10
;
LINESTRING
EMPTY
SELECT
G
FROM
TEST
WHERE
P_S
=
'GEOMETRYCOLLECTION Z EMPTY'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
CREATE
SPATIAL
INDEX
IDX
ON
TEST
(
GC
);
>
ok
SELECT
P
FROM
TEST
WHERE
GC
=
'SRID=8;GEOMETRYCOLLECTION (POINT (1 1))'
;
>>
POINT
EMPTY
SELECT
P
FROM
TEST
WHERE
GC
=
'SRID=8;GEOMETRYCOLLECTION Z (POINT (1 1 1))'
;
>
exception
CHECK_CONSTRAINT_VIOLATED_1
SELECT
CAST
(
'POINT EMPTY'
AS
GEOMETRY
(
POINT
));
>>
POINT
EMPTY
SELECT
CAST
(
'POINT EMPTY'
AS
GEOMETRY
(
POINT
Z
));
>
exception
CHECK_CONSTRAINT_VIOLATED_1
SELECT
CAST
(
'POINT EMPTY'
AS
GEOMETRY
(
POINT
,
0
));
>>
POINT
EMPTY
SELECT
CAST
(
'POINT EMPTY'
AS
GEOMETRY
(
POINT
,
1
));
>
exception
CHECK_CONSTRAINT_VIOLATED_1
SELECT
CAST
(
'POINT EMPTY'
AS
GEOMETRY
(
POLYGON
));
>
exception
CHECK_CONSTRAINT_VIOLATED_1
DROP
TABLE
TEST
;
>
ok
h2/src/test/org/h2/test/scripts/ddl/dropDomain.sql
浏览文件 @
92d7f561
...
...
@@ -36,12 +36,12 @@ DROP DOMAIN E_NN CASCADE;
SELECT
COLUMN_NAME
,
NULLABLE
,
COLUMN_TYPE
FROM
INFORMATION_SCHEMA
.
COLUMNS
WHERE
TABLE_NAME
=
'TEST'
ORDER
BY
ORDINAL_POSITION
;
>
COLUMN_NAME
NULLABLE
COLUMN_TYPE
>
----------- -------- ----------------------
>
----------- -------- ----------------------
-
>
I
0
INT
NOT
NULL
>
E1
1
ENUM
(
'A'
,
'B'
)
>
E2
0
ENUM
(
'A'
,
'B'
)
NOT
NULL
>
E3
0
ENUM
(
'A'
,
'B'
)
NOT
NULL
>
E4
1
ENUM
(
'A'
,
'B'
)
>
E1
1
ENUM
(
'A'
,
'B'
)
>
E2
0
ENUM
(
'A'
,
'B'
)
NOT
NULL
>
E3
0
ENUM
(
'A'
,
'B'
)
NOT
NULL
>
E4
1
ENUM
(
'A'
,
'B'
)
>
rows
(
ordered
):
5
DROP
TABLE
TEST
;
...
...
h2/src/test/org/h2/test/unit/TestGeometryUtils.java
浏览文件 @
92d7f561
...
...
@@ -8,6 +8,8 @@ package org.h2.test.unit;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
DIMENSION_SYSTEM_XY
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
DIMENSION_SYSTEM_XYM
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
DIMENSION_SYSTEM_XYZ
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
DIMENSION_SYSTEM_XYZM
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
GEOMETRY_COLLECTION
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
M
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
MAX_X
;
import
static
org
.
h2
.
util
.
geometry
.
GeometryUtils
.
MAX_Y
;
...
...
@@ -33,6 +35,7 @@ import org.h2.util.geometry.GeometryUtils.EnvelopeAndDimensionSystemTarget;
import
org.h2.util.geometry.GeometryUtils.Target
;
import
org.h2.util.geometry.JTSUtils
;
import
org.h2.util.geometry.JTSUtils.GeometryTarget
;
import
org.h2.value.ValueGeometry
;
import
org.locationtech.jts.geom.CoordinateSequence
;
import
org.locationtech.jts.geom.Envelope
;
import
org.locationtech.jts.geom.Geometry
;
...
...
@@ -234,8 +237,11 @@ public class TestGeometryUtils extends TestBase {
testEnvelope
(
envelopeFromJTS
,
target
.
getEnvelope
());
// Test dimensions
testDimensions
(
numOfDimensions
>
2
?
GeometryUtils
.
DIMENSION_SYSTEM_XYZ
:
GeometryUtils
.
DIMENSION_SYSTEM_XY
,
wkbFromJTS
);
int
expectedDimensionSystem
=
numOfDimensions
>
2
?
GeometryUtils
.
DIMENSION_SYSTEM_XYZ
:
GeometryUtils
.
DIMENSION_SYSTEM_XY
;
testDimensions
(
expectedDimensionSystem
,
wkbFromJTS
);
testValueGeometryProperties
(
wkbFromJTS
);
}
private
void
testEnvelope
(
Envelope
envelopeFromJTS
,
double
[]
envelopeFromH2
)
{
...
...
@@ -274,6 +280,7 @@ public class TestGeometryUtils extends TestBase {
testDimensionMCheckPoint
(
cs
);
assertEquals
(
ewkb
,
JTSUtils
.
geometry2ewkb
(
p
));
testDimensions
(
GeometryUtils
.
DIMENSION_SYSTEM_XYM
,
ewkb
);
testValueGeometryProperties
(
ewkb
);
if
(
JTSUtils
.
M_IS_SUPPORTED
)
{
p
=
(
Point
)
new
WKTReader
().
read
(
"POINT M (1 2 3)"
);
...
...
@@ -310,6 +317,7 @@ public class TestGeometryUtils extends TestBase {
testDimensionZMCheckPoint
(
cs
);
assertEquals
(
ewkb
,
JTSUtils
.
geometry2ewkb
(
p
));
testDimensions
(
GeometryUtils
.
DIMENSION_SYSTEM_XYZM
,
ewkb
);
testValueGeometryProperties
(
ewkb
);
if
(
JTSUtils
.
M_IS_SUPPORTED
)
{
p
=
(
Point
)
new
WKTReader
().
read
(
"POINT ZM (1 2 3 4)"
);
...
...
@@ -333,6 +341,32 @@ public class TestGeometryUtils extends TestBase {
assertEquals
(
4
,
cs
.
getOrdinate
(
0
,
M
));
}
private
void
testValueGeometryProperties
(
byte
[]
ewkb
)
{
ValueGeometry
vg
=
ValueGeometry
.
getFromEWKB
(
ewkb
);
DimensionSystemTarget
target
=
new
DimensionSystemTarget
();
EWKBUtils
.
parseEWKB
(
ewkb
,
target
);
int
dimensionSystem
=
target
.
getDimensionSystem
();
assertEquals
(
dimensionSystem
,
vg
.
getDimensionSystem
());
String
formattedType
=
EWKTUtils
.
formatGeometryTypeAndDimensionSystem
(
vg
.
getTypeAndDimensionSystem
());
assertTrue
(
EWKTUtils
.
ewkb2ewkt
(
ewkb
).
startsWith
(
formattedType
));
switch
(
dimensionSystem
)
{
case
DIMENSION_SYSTEM_XY:
assertTrue
(
formattedType
.
indexOf
(
' '
)
<
0
);
break
;
case
DIMENSION_SYSTEM_XYZ:
assertTrue
(
formattedType
.
endsWith
(
" Z"
));
break
;
case
DIMENSION_SYSTEM_XYM:
assertTrue
(
formattedType
.
endsWith
(
" M"
));
break
;
case
DIMENSION_SYSTEM_XYZM:
assertTrue
(
formattedType
.
endsWith
(
" ZM"
));
break
;
}
assertEquals
(
vg
.
getTypeAndDimensionSystem
(),
vg
.
getGeometryType
()
+
vg
.
getDimensionSystem
()
*
1_000
);
assertEquals
(
0
,
vg
.
getSRID
());
}
private
void
testFiniteOnly
()
{
for
(
int
i
=
0
;
i
<
NON_FINITE
.
length
;
i
++)
{
testFiniteOnly
(
NON_FINITE
[
i
],
new
EWKBTarget
(
new
ByteArrayOutputStream
(),
NON_FINITE_DIMENSIONS
[
i
]));
...
...
@@ -381,6 +415,10 @@ public class TestGeometryUtils extends TestBase {
assertEquals
(
10
,
gc
.
getSRID
());
assertEquals
(
10
,
gc
.
getGeometryN
(
0
).
getSRID
());
assertEquals
(
ewkb
,
JTSUtils
.
geometry2ewkb
(
gc
));
ValueGeometry
vg
=
ValueGeometry
.
getFromEWKB
(
ewkb
);
assertEquals
(
10
,
vg
.
getSRID
());
assertEquals
(
GEOMETRY_COLLECTION
,
vg
.
getTypeAndDimensionSystem
());
assertEquals
(
"SRID=-1;POINT EMPTY"
,
EWKTUtils
.
ewkb2ewkt
(
EWKTUtils
.
ewkt2ewkb
(
" srid=-1 ; POINT EMPTY "
)));
}
private
void
testDimensions
(
int
expected
,
byte
[]
ewkb
)
{
...
...
h2/src/tools/org/h2/build/doc/dictionary.txt
浏览文件 @
92d7f561
...
...
@@ -795,3 +795,4 @@ minxd maxxd minyd maxyd bminxd bmaxxd bminyd bmaxyd
interior envelopes multilinestring multipoint packed exterior normalization awkward determination subgeometries
xym normalizes coord setz xyzm geometrycollection multipolygon mixup rings polygons rejection finite
pointzm pointz pointm dimensionality redefine forum measures
mpg casted pzm mls constrained
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论