Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
a9030639
提交
a9030639
authored
6 年前
作者:
Evgenij Ryazanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix CHAR data type in PostgreSQL mode
上级
32e51b75
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
259 行增加
和
68 行删除
+259
-68
Command.java
h2/src/main/org/h2/command/Command.java
+4
-0
ResultWithPaddedStrings.java
h2/src/main/org/h2/result/ResultWithPaddedStrings.java
+193
-0
Transfer.java
h2/src/main/org/h2/value/Transfer.java
+1
-1
Value.java
h2/src/main/org/h2/value/Value.java
+3
-3
ValueStringFixed.java
h2/src/main/org/h2/value/ValueStringFixed.java
+2
-64
char.sql
h2/src/test/org/h2/test/scripts/datatypes/char.sql
+56
-0
没有找到文件。
h2/src/main/org/h2/command/Command.java
浏览文件 @
a9030639
...
...
@@ -18,6 +18,7 @@ import org.h2.message.DbException;
import
org.h2.message.Trace
;
import
org.h2.result.ResultInterface
;
import
org.h2.result.ResultWithGeneratedKeys
;
import
org.h2.result.ResultWithPaddedStrings
;
import
org.h2.util.MathUtils
;
/**
...
...
@@ -200,6 +201,9 @@ public abstract class Command implements CommandInterface {
try
{
ResultInterface
result
=
query
(
maxrows
);
callStop
=
!
result
.
isLazy
();
if
(
database
.
getMode
().
padFixedLengthStrings
)
{
return
ResultWithPaddedStrings
.
get
(
result
);
}
return
result
;
}
catch
(
DbException
e
)
{
start
=
filterConcurrentUpdate
(
e
,
start
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/result/ResultWithPaddedStrings.java
0 → 100644
浏览文件 @
a9030639
/*
* Copyright 2004-2019 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
.
result
;
import
java.util.Arrays
;
import
org.h2.engine.SessionInterface
;
import
org.h2.util.MathUtils
;
import
org.h2.value.TypeInfo
;
import
org.h2.value.Value
;
import
org.h2.value.ValueString
;
/**
* Result with padded fixed length strings.
*/
public
class
ResultWithPaddedStrings
implements
ResultInterface
{
private
final
ResultInterface
source
;
/**
* Returns wrapped result if necessary, or original result if it does not
* contain visible CHAR columns.
*
* @param source
* source result
* @return wrapped result or original result
*/
public
static
ResultInterface
get
(
ResultInterface
source
)
{
int
count
=
source
.
getVisibleColumnCount
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
if
(
source
.
getColumnType
(
i
).
getValueType
()
==
Value
.
STRING_FIXED
)
{
return
new
ResultWithPaddedStrings
(
source
);
}
}
return
source
;
}
/**
* Creates new instance of result.
*
* @param source
* the source result
*/
private
ResultWithPaddedStrings
(
ResultInterface
source
)
{
this
.
source
=
source
;
}
@Override
public
void
reset
()
{
source
.
reset
();
}
@Override
public
Value
[]
currentRow
()
{
int
count
=
source
.
getVisibleColumnCount
();
Value
[]
row
=
Arrays
.
copyOf
(
source
.
currentRow
(),
count
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
TypeInfo
type
=
source
.
getColumnType
(
i
);
if
(
type
.
getValueType
()
==
Value
.
STRING_FIXED
)
{
long
precision
=
type
.
getPrecision
();
if
(
precision
==
Integer
.
MAX_VALUE
)
{
// CHAR is CHAR(1)
precision
=
1
;
}
String
s
=
row
[
i
].
getString
();
if
(
s
.
length
()
<
precision
)
{
/*
* Use ValueString to avoid truncation of spaces. There is
* no difference between ValueStringFixed and ValueString
* for JDBC layer anyway.
*/
row
[
i
]
=
ValueString
.
get
(
rightPadWithSpaces
(
s
,
MathUtils
.
convertLongToInt
(
precision
)));
}
}
}
return
row
;
}
private
static
String
rightPadWithSpaces
(
String
s
,
int
length
)
{
int
used
=
s
.
length
();
if
(
length
<=
used
)
{
return
s
;
}
char
[]
res
=
new
char
[
length
];
s
.
getChars
(
0
,
used
,
res
,
0
);
Arrays
.
fill
(
res
,
used
,
length
,
' '
);
return
new
String
(
res
);
}
@Override
public
boolean
next
()
{
return
source
.
next
();
}
@Override
public
int
getRowId
()
{
return
source
.
getRowId
();
}
@Override
public
boolean
isAfterLast
()
{
return
source
.
isAfterLast
();
}
@Override
public
int
getVisibleColumnCount
()
{
return
source
.
getVisibleColumnCount
();
}
@Override
public
int
getRowCount
()
{
return
source
.
getRowCount
();
}
@Override
public
boolean
hasNext
()
{
return
source
.
hasNext
();
}
@Override
public
boolean
needToClose
()
{
return
source
.
needToClose
();
}
@Override
public
void
close
()
{
source
.
close
();
}
@Override
public
String
getAlias
(
int
i
)
{
return
source
.
getAlias
(
i
);
}
@Override
public
String
getSchemaName
(
int
i
)
{
return
source
.
getSchemaName
(
i
);
}
@Override
public
String
getTableName
(
int
i
)
{
return
source
.
getTableName
(
i
);
}
@Override
public
String
getColumnName
(
int
i
)
{
return
source
.
getColumnName
(
i
);
}
@Override
public
TypeInfo
getColumnType
(
int
i
)
{
return
source
.
getColumnType
(
i
);
}
@Override
public
boolean
isAutoIncrement
(
int
i
)
{
return
source
.
isAutoIncrement
(
i
);
}
@Override
public
int
getNullable
(
int
i
)
{
return
source
.
getNullable
(
i
);
}
@Override
public
void
setFetchSize
(
int
fetchSize
)
{
source
.
setFetchSize
(
fetchSize
);
}
@Override
public
int
getFetchSize
()
{
return
source
.
getFetchSize
();
}
@Override
public
boolean
isLazy
()
{
return
source
.
isLazy
();
}
@Override
public
boolean
isClosed
()
{
return
source
.
isClosed
();
}
@Override
public
ResultInterface
createShallowCopy
(
SessionInterface
targetSession
)
{
ResultInterface
copy
=
source
.
createShallowCopy
(
targetSession
);
return
copy
!=
null
?
new
ResultWithPaddedStrings
(
copy
)
:
null
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/Transfer.java
浏览文件 @
a9030639
...
...
@@ -622,7 +622,7 @@ public class Transfer {
case
Value
.
STRING_IGNORECASE
:
return
ValueStringIgnoreCase
.
get
(
readString
());
case
Value
.
STRING_FIXED
:
return
ValueStringFixed
.
get
(
readString
()
,
ValueStringFixed
.
PRECISION_DO_NOT_TRIM
,
null
);
return
ValueStringFixed
.
get
(
readString
());
case
Value
.
BLOB
:
{
long
length
=
readLong
();
if
(
version
>=
Constants
.
TCP_PROTOCOL_VERSION_11
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/Value.java
浏览文件 @
a9030639
...
...
@@ -788,7 +788,7 @@ public abstract class Value extends VersionedValue {
case
STRING_IGNORECASE:
return
convertToStringIgnoreCase
(
mode
);
case
STRING_FIXED:
return
convertToStringFixed
(
precision
,
mode
);
return
convertToStringFixed
(
mode
);
case
JAVA_OBJECT:
return
convertToJavaObject
();
case
ENUM:
...
...
@@ -1177,14 +1177,14 @@ public abstract class Value extends VersionedValue {
return
ValueStringIgnoreCase
.
get
(
s
);
}
private
ValueString
convertToStringFixed
(
int
precision
,
Mode
mode
)
{
private
ValueString
convertToStringFixed
(
Mode
mode
)
{
String
s
;
if
(
getValueType
()
==
BYTES
&&
mode
!=
null
&&
mode
.
charToBinaryInUtf8
)
{
s
=
new
String
(
getBytesNoCopy
(),
StandardCharsets
.
UTF_8
);
}
else
{
s
=
getString
();
}
return
ValueStringFixed
.
get
(
s
,
precision
,
mode
);
return
ValueStringFixed
.
get
(
s
);
}
private
ValueJavaObject
convertToJavaObject
()
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueStringFixed.java
浏览文件 @
a9030639
...
...
@@ -5,8 +5,6 @@
*/
package
org
.
h2
.
value
;
import
java.util.Arrays
;
import
org.h2.engine.Mode
;
import
org.h2.engine.SysProperties
;
import
org.h2.util.StringUtils
;
...
...
@@ -15,18 +13,6 @@ import org.h2.util.StringUtils;
*/
public
class
ValueStringFixed
extends
ValueString
{
/**
* Special value for the precision in {@link #get(String, int, Mode)} to indicate that the value
* should <i>not</i> be trimmed.
*/
public
static
final
int
PRECISION_DO_NOT_TRIM
=
Integer
.
MIN_VALUE
;
/**
* Special value for the precision in {@link #get(String, int, Mode)} to indicate
* that the default behaviour should of trimming the value should apply.
*/
public
static
final
int
PRECISION_TRIM
=
-
1
;
private
static
final
ValueStringFixed
EMPTY
=
new
ValueStringFixed
(
""
);
protected
ValueStringFixed
(
String
value
)
{
...
...
@@ -36,6 +22,7 @@ public class ValueStringFixed extends ValueString {
private
static
String
trimRight
(
String
s
)
{
return
trimRight
(
s
,
0
);
}
private
static
String
trimRight
(
String
s
,
int
minLength
)
{
int
endIndex
=
s
.
length
()
-
1
;
int
i
=
endIndex
;
...
...
@@ -46,17 +33,6 @@ public class ValueStringFixed extends ValueString {
return
s
;
}
private
static
String
rightPadWithSpaces
(
String
s
,
int
length
)
{
int
used
=
s
.
length
();
if
(
length
<=
used
)
{
return
s
;
}
char
[]
res
=
new
char
[
length
];
s
.
getChars
(
0
,
used
,
res
,
0
);
Arrays
.
fill
(
res
,
used
,
length
,
' '
);
return
new
String
(
res
);
}
@Override
public
int
getValueType
()
{
return
STRING_FIXED
;
...
...
@@ -70,45 +46,7 @@ public class ValueStringFixed extends ValueString {
* @return the value
*/
public
static
ValueStringFixed
get
(
String
s
)
{
// Use the special precision constant PRECISION_TRIM to indicate
// default H2 behaviour of trimming the value.
return
get
(
s
,
PRECISION_TRIM
,
null
);
}
/**
* Get or create a fixed length string value for the given string.
* <p>
* This method will use a {@link Mode}-specific conversion when <code>mode</code> is not
* <code>null</code>.
* Otherwise it will use the default H2 behaviour of trimming the given string if
* <code>precision</code> is not {@link #PRECISION_DO_NOT_TRIM}.
*
* @param s the string
* @param precision if the {@link Mode#padFixedLengthStrings} indicates that strings should
* be padded, this defines the overall length of the (potentially padded) string.
* If the special constant {@link #PRECISION_DO_NOT_TRIM} is used the value will
* not be trimmed.
* @param mode the database mode
* @return the value
*/
public
static
ValueStringFixed
get
(
String
s
,
int
precision
,
Mode
mode
)
{
// Should fixed strings be padded?
if
(
mode
!=
null
&&
mode
.
padFixedLengthStrings
)
{
if
(
precision
==
Integer
.
MAX_VALUE
)
{
// CHAR without a length specification is identical to CHAR(1)
precision
=
1
;
}
if
(
s
.
length
()
<
precision
)
{
// We have to pad
s
=
rightPadWithSpaces
(
s
,
precision
);
}
else
{
// We should trim, because inserting 'A ' into a CHAR(1) is possible!
s
=
trimRight
(
s
,
precision
);
}
}
else
if
(
precision
!=
PRECISION_DO_NOT_TRIM
)
{
// Default behaviour of H2
s
=
trimRight
(
s
);
}
s
=
trimRight
(
s
);
int
length
=
s
.
length
();
if
(
length
==
0
)
{
return
EMPTY
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/datatypes/char.sql
浏览文件 @
a9030639
...
...
@@ -17,3 +17,59 @@ SELECT COLUMN_NAME, DATA_TYPE, TYPE_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.CO
DROP
TABLE
TEST
;
>
ok
CREATE
TABLE
TEST
(
C
CHAR
(
2
));
>
ok
INSERT
INTO
TEST
VALUES
'aa'
,
'b'
;
>
update
count
:
2
SELECT
*
FROM
TEST
WHERE
C
=
'b'
;
>>
b
SELECT
*
FROM
TEST
WHERE
C
=
'b '
;
>>
b
SELECT
*
FROM
TEST
WHERE
C
=
'b '
;
>>
b
SELECT
C
||
'x'
V
FROM
TEST
;
>
V
>
---
>
aax
>
bx
>
rows
:
2
DROP
TABLE
TEST
;
>
ok
SET
MODE
PostgreSQL
;
>
ok
CREATE
TABLE
TEST
(
C
CHAR
(
2
));
>
ok
INSERT
INTO
TEST
VALUES
'aa'
,
'b'
;
>
update
count
:
2
SELECT
*
FROM
TEST
WHERE
C
=
'b'
;
>>
b
SELECT
*
FROM
TEST
WHERE
C
=
'b '
;
>>
b
SELECT
*
FROM
TEST
WHERE
C
=
'b '
;
>>
b
SELECT
C
||
'x'
V
FROM
TEST
;
>
V
>
---
>
aax
>
bx
>
rows
:
2
DROP
TABLE
TEST
;
>
ok
SET
MODE
Regular
;
>
ok
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论