Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
eea52ad7
提交
eea52ad7
authored
14 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New system function TRUNCATE_VALUE to truncate a value to the required precision.
上级
f3f6c2a9
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
187 行增加
和
26 行删除
+187
-26
help.csv
h2/src/docsrc/help/help.csv
+12
-0
Function.java
h2/src/main/org/h2/expression/Function.java
+8
-2
TableFunction.java
h2/src/main/org/h2/expression/TableFunction.java
+1
-1
help.csv
h2/src/main/org/h2/res/help.csv
+4
-0
Value.java
h2/src/main/org/h2/value/Value.java
+5
-14
ValueArray.java
h2/src/main/org/h2/value/ValueArray.java
+27
-1
ValueBytes.java
h2/src/main/org/h2/value/ValueBytes.java
+10
-0
ValueDecimal.java
h2/src/main/org/h2/value/ValueDecimal.java
+6
-3
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+13
-0
ValueLobDb.java
h2/src/main/org/h2/value/ValueLobDb.java
+13
-0
ValueResultSet.java
h2/src/main/org/h2/value/ValueResultSet.java
+8
-2
ValueString.java
h2/src/main/org/h2/value/ValueString.java
+2
-2
test-1.3.txt
h2/src/test/org/h2/test/test-1.3.txt
+15
-0
TestValue.java
h2/src/test/org/h2/test/unit/TestValue.java
+63
-1
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
eea52ad7
...
...
@@ -3644,6 +3644,18 @@ The value is unique across database restarts (values are not re-used).
CALL TRANSACTION_ID()
"
"Functions (System)","TRUNCATE_VALUE","
TRUNCATE_VALUE(value, precisionInt, forceBoolean)
","
Truncate a value to the required precision.
The precision of the returned value may be a bit larger than requested,
because fixed precision values are not truncated (unlike the numeric TRUNCATE method).
Unlike CAST, the truncating a decimal value may lose precision if the force flag is set to true.
The method returns a value with the same data type as the first parameter.
","
CALL TRUNCATE_VALUE(X, 10, TRUE);
"
"Functions (System)","USER","
{ USER | CURRENT_USER } ()
","
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Function.java
浏览文件 @
eea52ad7
...
...
@@ -95,7 +95,7 @@ public class Function extends Expression implements FunctionCall {
CASE
=
206
,
NEXTVAL
=
207
,
CURRVAL
=
208
,
ARRAY_GET
=
209
,
CSVREAD
=
210
,
CSVWRITE
=
211
,
MEMORY_FREE
=
212
,
MEMORY_USED
=
213
,
LOCK_MODE
=
214
,
SCHEMA
=
215
,
SESSION_ID
=
216
,
ARRAY_LENGTH
=
217
,
LINK_SCHEMA
=
218
,
GREATEST
=
219
,
LEAST
=
220
,
CANCEL_SESSION
=
221
,
SET
=
222
,
TABLE
=
223
,
TABLE_DISTINCT
=
224
,
FILE_READ
=
225
,
TRANSACTION_ID
=
226
;
FILE_READ
=
225
,
TRANSACTION_ID
=
226
,
TRUNCATE_VALUE
=
227
;
private
static
final
int
VAR_ARGS
=
-
1
;
private
static
final
long
PRECISION_UNKNOWN
=
-
1
;
...
...
@@ -297,6 +297,7 @@ public class Function extends Expression implements FunctionCall {
addFunctionWithNull
(
"CASEWHEN"
,
CASEWHEN
,
3
,
Value
.
NULL
);
addFunctionWithNull
(
"CONVERT"
,
CONVERT
,
1
,
Value
.
NULL
);
addFunctionWithNull
(
"CAST"
,
CAST
,
1
,
Value
.
NULL
);
addFunctionWithNull
(
"TRUNCATE_VALUE"
,
TRUNCATE_VALUE
,
3
,
Value
.
NULL
);
addFunctionWithNull
(
"COALESCE"
,
COALESCE
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"NVL"
,
COALESCE
,
VAR_ARGS
,
Value
.
NULL
);
addFunctionWithNull
(
"NULLIF"
,
NULLIF
,
2
,
Value
.
NULL
);
...
...
@@ -715,7 +716,7 @@ public class Function extends Expression implements FunctionCall {
v0
=
v0
.
convertTo
(
dataType
);
Mode
mode
=
database
.
getMode
();
v0
=
v0
.
convertScale
(
mode
.
convertOnlyToSmallerScale
,
scale
);
v0
=
v0
.
convertPrecision
(
getPrecision
());
v0
=
v0
.
convertPrecision
(
getPrecision
()
,
false
);
result
=
v0
;
break
;
}
...
...
@@ -1150,6 +1151,10 @@ public class Function extends Expression implements FunctionCall {
}
break
;
}
case
TRUNCATE_VALUE:
{
result
=
v0
.
convertPrecision
(
v1
.
getLong
(),
v2
.
getBoolean
());
break
;
}
default
:
throw
DbException
.
throwInternalError
(
"type="
+
info
.
type
);
}
...
...
@@ -1678,6 +1683,7 @@ public class Function extends Expression implements FunctionCall {
break
;
case
CAST:
case
CONVERT:
case
TRUNCATE_VALUE:
// data type, precision and scale is already set
t
=
dataType
;
p
=
precision
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/TableFunction.java
浏览文件 @
eea52ad7
...
...
@@ -110,7 +110,7 @@ public class TableFunction extends Function {
Column
c
=
columnList
[
j
];
v
=
l
[
row
];
v
=
c
.
convert
(
v
);
v
=
v
.
convertPrecision
(
c
.
getPrecision
());
v
=
v
.
convertPrecision
(
c
.
getPrecision
()
,
false
);
v
=
v
.
convertScale
(
true
,
c
.
getScale
());
}
r
[
j
]
=
v
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/help.csv
浏览文件 @
eea52ad7
...
...
@@ -1351,6 +1351,10 @@ Returns the result set."
TRANSACTION_ID()
","
Returns the current transaction id for this session."
"Functions (System)","TRUNCATE_VALUE","
TRUNCATE_VALUE(value, precisionInt, forceBoolean)
","
Truncate a value to the required precision."
"Functions (System)","USER","
{ USER | CURRENT_USER } ()
","
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/Value.java
浏览文件 @
eea52ad7
...
...
@@ -910,27 +910,18 @@ public abstract class Value {
}
/**
* Convert the precision to the requested value.
* Convert the precision to the requested value. The precision of the
* returned value may be somewhat larger than requested, because values with
* a fixed precision are not truncated.
*
* @param precision the new precision
* @param force true if losing numeric precision is allowed
* @return the new value
*/
public
Value
convertPrecision
(
long
precision
)
{
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
return
this
;
}
/**
* Trim the value to the requested precision.
* Unlike convertPrecision, this will always work
* (possibly losing precision).
*
* @param precision the maximum precision
* @return the new value
*/
public
Value
trim
(
long
precision
)
{
return
convertPrecision
(
precision
);
}
private
static
byte
convertToByte
(
long
x
)
{
if
(
x
>
Byte
.
MAX_VALUE
||
x
<
Byte
.
MIN_VALUE
)
{
throw
DbException
.
get
(
ErrorCode
.
NUMERIC_VALUE_OUT_OF_RANGE
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueArray.java
浏览文件 @
eea52ad7
...
...
@@ -7,8 +7,10 @@
package
org
.
h2
.
value
;
import
java.sql.PreparedStatement
;
import
java.util.ArrayList
;
import
org.h2.engine.Constants
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.StatementBuilder
;
/**
...
...
@@ -55,7 +57,11 @@ public class ValueArray extends Value {
}
public
long
getPrecision
()
{
return
0
;
long
p
=
0
;
for
(
Value
v
:
values
)
{
p
+=
v
.
getPrecision
();
}
return
p
;
}
public
String
getString
()
{
...
...
@@ -156,4 +162,24 @@ public class ValueArray extends Value {
return
memory
;
}
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(!
force
)
{
return
this
;
}
ArrayList
<
Value
>
list
=
New
.
arrayList
();
for
(
Value
v
:
values
)
{
v
=
v
.
convertPrecision
(
precision
,
true
);
// empty byte arrays or strings have precision 0
// they count as precision 1 here
precision
-=
Math
.
max
(
1
,
v
.
getPrecision
());
if
(
precision
<
0
)
{
break
;
}
list
.
add
(
v
);
}
Value
[]
array
=
new
Value
[
list
.
size
()];
list
.
toArray
(
array
);
return
get
(
array
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueBytes.java
浏览文件 @
eea52ad7
...
...
@@ -117,4 +117,14 @@ public class ValueBytes extends Value {
return
other
instanceof
ValueBytes
&&
Utils
.
compareNotNull
(
value
,
((
ValueBytes
)
other
).
value
)
==
0
;
}
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(
value
.
length
<=
precision
)
{
return
this
;
}
int
len
=
MathUtils
.
convertLongToInt
(
precision
);
byte
[]
buff
=
new
byte
[
len
];
System
.
arraycopy
(
value
,
0
,
buff
,
0
,
len
);
return
get
(
buff
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueDecimal.java
浏览文件 @
eea52ad7
...
...
@@ -184,11 +184,14 @@ public class ValueDecimal extends Value {
return
ValueDecimal
.
get
(
bd
);
}
public
Value
convertPrecision
(
long
newPrecision
)
{
if
(
getPrecision
()
<=
newP
recision
)
{
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(
getPrecision
()
<=
p
recision
)
{
return
this
;
}
throw
DbException
.
get
(
ErrorCode
.
VALUE_TOO_LARGE_FOR_PRECISION_1
,
""
+
newPrecision
);
if
(
force
)
{
return
get
(
BigDecimal
.
valueOf
(
value
.
doubleValue
()));
}
throw
DbException
.
get
(
ErrorCode
.
VALUE_TOO_LARGE_FOR_PRECISION_1
,
""
+
precision
);
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
eea52ad7
...
...
@@ -799,4 +799,17 @@ public class ValueLob extends Value {
return
lob
;
}
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(
this
.
precision
<=
precision
)
{
return
this
;
}
ValueLob
lob
;
if
(
type
==
CLOB
)
{
lob
=
ValueLob
.
createClob
(
getReader
(),
precision
,
handler
);
}
else
{
lob
=
ValueLob
.
createBlob
(
getInputStream
(),
precision
,
handler
);
}
return
lob
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueLobDb.java
浏览文件 @
eea52ad7
...
...
@@ -541,4 +541,17 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
return
(
int
)
m
;
}
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(
this
.
precision
<=
precision
)
{
return
this
;
}
ValueLob
lob
;
if
(
type
==
CLOB
)
{
lob
=
ValueLob
.
createClob
(
getReader
(),
precision
,
handler
);
}
else
{
lob
=
ValueLob
.
createBlob
(
getInputStream
(),
precision
,
handler
);
}
return
lob
;
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueResultSet.java
浏览文件 @
eea52ad7
...
...
@@ -10,7 +10,6 @@ import java.sql.PreparedStatement;
import
java.sql.ResultSet
;
import
java.sql.ResultSetMetaData
;
import
java.sql.SQLException
;
import
org.h2.message.DbException
;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.util.StatementBuilder
;
...
...
@@ -79,7 +78,7 @@ public class ValueResultSet extends Value {
}
public
long
getPrecision
()
{
return
0
;
return
Integer
.
MAX_VALUE
;
}
public
int
getDisplaySize
()
{
...
...
@@ -142,4 +141,11 @@ public class ValueResultSet extends Value {
return
""
;
}
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(!
force
)
{
return
this
;
}
return
ValueResultSet
.
get
(
new
SimpleResultSet
());
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/value/ValueString.java
浏览文件 @
eea52ad7
...
...
@@ -67,7 +67,7 @@ public class ValueString extends Value {
return
value
.
length
()
*
2
+
48
;
}
public
Value
convertPrecision
(
long
precision
)
{
public
Value
convertPrecision
(
long
precision
,
boolean
force
)
{
if
(
precision
==
0
||
value
.
length
()
<=
precision
)
{
return
this
;
}
...
...
@@ -136,7 +136,7 @@ public class ValueString extends Value {
* @param s the string
* @return the value
*/
protected
Value
getNew
(
String
s
)
{
protected
Value
String
getNew
(
String
s
)
{
return
ValueString
.
get
(
s
);
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/test-1.3.txt
浏览文件 @
eea52ad7
--- special grammar and test cases ---------------------------------------------------------------------------------------------
call cast_precision('Test 123', 4, false);
> 'Test'
> ------
> Test
> rows: 1
call cast_precision(1234567890.123456789, 4, false);
> exception
call cast_precision(1234567890.123456789, 4, true);
> 1234567890.1234567
> ------------------
> 1234567890.1234567
> rows: 1
select * from dual where cast('xx' as varchar_ignorecase(1)) = 'X' and cast('x x ' as char(2)) = 'x';
> X
> -
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestValue.java
浏览文件 @
eea52ad7
...
...
@@ -21,10 +21,14 @@ import org.h2.test.TestBase;
import
org.h2.tools.SimpleResultSet
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueBytes
;
import
org.h2.value.ValueDecimal
;
import
org.h2.value.ValueDouble
;
import
org.h2.value.ValueFloat
;
import
org.h2.value.ValueLobDb
;
import
org.h2.value.ValueResultSet
;
import
org.h2.value.ValueString
;
import
org.h2.value.ValueUuid
;
/**
...
...
@@ -42,6 +46,7 @@ public class TestValue extends TestBase {
}
public
void
test
()
throws
SQLException
{
testCastTrim
();
testValueResultSet
();
testDataType
();
testUUID
();
...
...
@@ -52,6 +57,63 @@ public class TestValue extends TestBase {
testModulusOperator
();
}
private
void
testCastTrim
()
{
Value
v
;
String
spaces
=
new
String
(
new
char
[
100
]).
replace
((
char
)
0
,
' '
);
v
=
ValueArray
.
get
(
new
Value
[]{
ValueString
.
get
(
"hello"
),
ValueString
.
get
(
"world"
)});
assertEquals
(
10
,
v
.
getPrecision
());
assertEquals
(
5
,
v
.
convertPrecision
(
5
,
true
).
getPrecision
());
v
=
ValueArray
.
get
(
new
Value
[]{
ValueString
.
get
(
""
),
ValueString
.
get
(
""
)});
assertEquals
(
0
,
v
.
getPrecision
());
assertEquals
(
"('')"
,
v
.
convertPrecision
(
1
,
true
).
toString
());
v
=
ValueBytes
.
get
(
spaces
.
getBytes
());
assertEquals
(
100
,
v
.
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getBytes
().
length
);
assertEquals
(
32
,
v
.
convertPrecision
(
10
,
false
).
getBytes
()[
9
]);
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
true
).
getPrecision
());
v
=
ValueDecimal
.
get
(
new
BigDecimal
(
"1234567890.123456789"
));
assertEquals
(
19
,
v
.
getPrecision
());
assertEquals
(
"1234567890.1234567"
,
v
.
convertPrecision
(
10
,
true
).
getString
());
try
{
v
.
convertPrecision
(
10
,
false
);
}
catch
(
DbException
e
)
{
assertEquals
(
ErrorCode
.
VALUE_TOO_LARGE_FOR_PRECISION_1
,
e
.
getErrorCode
());
}
v
=
ValueLobDb
.
createSmallLob
(
Value
.
CLOB
,
spaces
.
getBytes
(),
100
);
assertEquals
(
100
,
v
.
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getString
().
length
());
assertEquals
(
" "
,
v
.
convertPrecision
(
10
,
false
).
getString
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
true
).
getPrecision
());
v
=
ValueLobDb
.
createSmallLob
(
Value
.
BLOB
,
spaces
.
getBytes
(),
100
);
assertEquals
(
100
,
v
.
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getBytes
().
length
);
assertEquals
(
32
,
v
.
convertPrecision
(
10
,
false
).
getBytes
()[
9
]);
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
true
).
getPrecision
());
ResultSet
rs
=
new
SimpleResultSet
();
v
=
ValueResultSet
.
get
(
rs
);
assertEquals
(
Integer
.
MAX_VALUE
,
v
.
getPrecision
());
assertEquals
(
Integer
.
MAX_VALUE
,
v
.
convertPrecision
(
10
,
false
).
getPrecision
());
assertTrue
(
rs
==
v
.
convertPrecision
(
10
,
false
).
getObject
());
assertFalse
(
rs
==
v
.
convertPrecision
(
10
,
true
).
getObject
());
assertEquals
(
Integer
.
MAX_VALUE
,
v
.
convertPrecision
(
10
,
true
).
getPrecision
());
v
=
ValueString
.
get
(
spaces
);
assertEquals
(
100
,
v
.
getPrecision
());
assertEquals
(
10
,
v
.
convertPrecision
(
10
,
false
).
getPrecision
());
assertEquals
(
" "
,
v
.
convertPrecision
(
10
,
false
).
getString
());
assertEquals
(
" "
,
v
.
convertPrecision
(
10
,
true
).
getString
());
}
private
void
testValueResultSet
()
throws
SQLException
{
SimpleResultSet
rs
=
new
SimpleResultSet
();
rs
.
addColumn
(
"ID"
,
Types
.
INTEGER
,
0
,
0
);
...
...
@@ -67,7 +129,7 @@ public class TestValue extends TestBase {
v
=
ValueResultSet
.
getCopy
(
rs
,
2
);
assertEquals
(
0
,
v
.
hashCode
());
assertEquals
(
Integer
.
MAX_VALUE
,
v
.
getDisplaySize
());
assertEquals
(
0
,
v
.
getPrecision
());
assertEquals
(
Integer
.
MAX_VALUE
,
v
.
getPrecision
());
assertEquals
(
0
,
v
.
getScale
());
assertEquals
(
""
,
v
.
getSQL
());
assertEquals
(
Value
.
RESULT_SET
,
v
.
getType
());
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论