Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
eea52ad7
提交
eea52ad7
authored
3月 22, 2011
作者:
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 } ()
","
...
...
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
;
...
...
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
;
...
...
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 } ()
","
...
...
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
);
...
...
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
);
}
}
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
);
}
}
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
);
}
/**
...
...
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
;
}
}
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
;
}
}
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
());
}
}
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
);
}
...
...
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
> -
...
...
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
());
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论