Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
dcd6f3e6
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
dcd6f3e6
编写于
12月 12, 2021
作者:
M
Minglei Jin
提交者:
GitHub
12月 12, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #9044 from taosdata/hotfix/TS-836
[TS-836]<feature>: getLong return a timestamp with good precision
上级
e7452e15
297c0a97
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
144 addition
and
44 deletion
+144
-44
src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
...bc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
+5
-0
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
...r/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
+13
-3
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
...r/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
+2
-0
src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java
...main/java/com/taosdata/jdbc/enums/TimestampPrecision.java
+4
-5
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java
.../src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java
+33
-7
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java
...tor/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java
+2
-2
src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/GetLongWithDifferentTimestampPrecision.java
...ta/jdbc/cases/GetLongWithDifferentTimestampPrecision.java
+59
-0
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
...c/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
+11
-11
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java
.../test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java
+15
-16
未找到文件。
src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java
浏览文件 @
dcd6f3e6
...
...
@@ -11,6 +11,11 @@ import java.util.Map;
public
abstract
class
AbstractResultSet
extends
WrapperImpl
implements
ResultSet
{
private
int
fetchSize
;
protected
boolean
wasNull
;
protected
int
timestampPrecision
;
public
void
setTimestampPrecision
(
int
timestampPrecision
)
{
this
.
timestampPrecision
=
timestampPrecision
;
}
protected
void
checkAvailability
(
int
columnIndex
,
int
bounds
)
throws
SQLException
{
if
(
isClosed
())
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java
浏览文件 @
dcd6f3e6
...
...
@@ -74,9 +74,8 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public
boolean
next
()
throws
SQLException
{
if
(
this
.
getBatchFetch
())
{
if
(
this
.
blockData
.
forward
())
{
if
(
this
.
blockData
.
forward
())
return
true
;
}
int
code
=
this
.
jniConnector
.
fetchBlock
(
this
.
resultSetPointer
,
this
.
blockData
);
this
.
blockData
.
reset
();
...
...
@@ -214,7 +213,18 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if
(!
lastWasNull
)
{
Object
value
=
this
.
rowData
.
getObject
(
columnIndex
);
if
(
value
instanceof
Timestamp
)
{
res
=
((
Timestamp
)
value
).
getTime
();
Timestamp
ts
=
(
Timestamp
)
value
;
long
epochSec
=
ts
.
getTime
()
/
1000
;
long
nanoAdjustment
=
ts
.
getNanos
();
switch
(
this
.
timestampPrecision
)
{
case
0
:
default
:
// ms
return
ts
.
getTime
();
case
1
:
// us
return
epochSec
*
1000_000L
+
nanoAdjustment
/
1000L
;
case
2
:
// ns
return
epochSec
*
1000_000_000L
+
nanoAdjustment
;
}
}
else
{
int
nativeType
=
this
.
columnMetaDataList
.
get
(
columnIndex
-
1
).
getColType
();
res
=
this
.
rowData
.
getLong
(
columnIndex
,
nativeType
);
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java
浏览文件 @
dcd6f3e6
...
...
@@ -47,6 +47,8 @@ public class TSDBStatement extends AbstractStatement {
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_INVALID_WITH_EXECUTEQUERY
);
}
TSDBResultSet
res
=
new
TSDBResultSet
(
this
,
this
.
connection
.
getConnector
(),
pSql
);
int
timestampPrecision
=
this
.
connection
.
getConnector
().
getResultTimePrecision
(
pSql
);
res
.
setTimestampPrecision
(
timestampPrecision
);
res
.
setBatchFetch
(
this
.
connection
.
getBatchFetch
());
return
res
;
}
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java
浏览文件 @
dcd6f3e6
package
com.taosdata.jdbc.enums
;
public
enum
TimestampPrecision
{
MS
,
US
,
NS
,
UNKNOWN
public
class
TimestampPrecision
{
public
static
final
int
MS
=
0
;
public
static
final
int
US
=
1
;
public
static
final
int
NS
=
2
;
}
src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java
浏览文件 @
dcd6f3e6
...
...
@@ -168,11 +168,22 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case
TIMESTAMP:
{
Long
value
=
row
.
getLong
(
colIndex
);
//TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9
if
(
value
<
1_0000_0000_0000_0L
)
if
(
value
<
1_0000_0000_0000_0L
)
{
this
.
timestampPrecision
=
TimestampPrecision
.
MS
;
return
new
Timestamp
(
value
);
long
epochSec
=
value
/
1000_000L
;
long
nanoAdjustment
=
value
%
1000_000L
*
1000L
;
return
Timestamp
.
from
(
Instant
.
ofEpochSecond
(
epochSec
,
nanoAdjustment
));
}
if
(
value
>=
1_0000_0000_0000_0L
&&
value
<
1_000_000_000_000_000_0
l
)
{
this
.
timestampPrecision
=
TimestampPrecision
.
US
;
long
epochSec
=
value
/
1000_000L
;
long
nanoAdjustment
=
value
%
1000_000L
*
1000L
;
return
Timestamp
.
from
(
Instant
.
ofEpochSecond
(
epochSec
,
nanoAdjustment
));
}
if
(
value
>=
1_000_000_000_000_000_0
l
)
{
this
.
timestampPrecision
=
TimestampPrecision
.
NS
;
long
epochSec
=
value
/
1000_000_000L
;
long
nanoAdjustment
=
value
%
1000_000_000L
;
return
Timestamp
.
from
(
Instant
.
ofEpochSecond
(
epochSec
,
nanoAdjustment
));
}
}
case
UTC:
{
String
value
=
row
.
getString
(
colIndex
);
...
...
@@ -182,12 +193,15 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
if
(
value
.
length
()
>
31
)
{
// ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00
nanoAdjustment
=
fractionalSec
;
this
.
timestampPrecision
=
TimestampPrecision
.
NS
;
}
else
if
(
value
.
length
()
>
28
)
{
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
nanoAdjustment
=
fractionalSec
*
1000L
;
this
.
timestampPrecision
=
TimestampPrecision
.
US
;
}
else
{
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
nanoAdjustment
=
fractionalSec
*
1000_000L
;
this
.
timestampPrecision
=
TimestampPrecision
.
MS
;
}
ZoneOffset
zoneOffset
=
ZoneOffset
.
of
(
value
.
substring
(
value
.
length
()
-
5
));
Instant
instant
=
Instant
.
ofEpochSecond
(
epochSec
,
nanoAdjustment
).
atOffset
(
zoneOffset
).
toInstant
();
...
...
@@ -196,7 +210,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
case
STRING:
default
:
{
String
value
=
row
.
getString
(
colIndex
);
TimestampPrecision
precision
=
Utils
.
guessTimestampPrecision
(
value
);
int
precision
=
Utils
.
guessTimestampPrecision
(
value
);
this
.
timestampPrecision
=
precision
;
if
(
precision
==
TimestampPrecision
.
MS
)
{
// ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
return
row
.
getTimestamp
(
colIndex
);
...
...
@@ -338,8 +354,18 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
wasNull
=
value
==
null
;
if
(
value
==
null
)
return
0
;
if
(
value
instanceof
Timestamp
)
return
((
Timestamp
)
value
).
getTime
();
if
(
value
instanceof
Timestamp
)
{
Timestamp
ts
=
(
Timestamp
)
value
;
switch
(
this
.
timestampPrecision
)
{
case
TimestampPrecision
.
MS
:
default
:
return
ts
.
getTime
();
case
TimestampPrecision
.
US
:
return
ts
.
getTime
()
*
1000
+
ts
.
getNanos
()
/
1000
%
1000
;
case
TimestampPrecision
.
NS
:
return
ts
.
getTime
()
*
1000_000
+
ts
.
getNanos
()
%
1000_000
;
}
}
long
valueAsLong
=
0
;
try
{
valueAsLong
=
Long
.
parseLong
(
value
.
toString
());
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java
浏览文件 @
dcd6f3e6
...
...
@@ -194,14 +194,14 @@ public class Utils {
return
timestamp
.
toLocalDateTime
().
format
(
milliSecFormatter
);
}
public
static
TimestampPrecision
guessTimestampPrecision
(
String
value
)
{
public
static
int
guessTimestampPrecision
(
String
value
)
{
if
(
isMilliSecFormat
(
value
))
return
TimestampPrecision
.
MS
;
if
(
isMicroSecFormat
(
value
))
return
TimestampPrecision
.
US
;
if
(
isNanoSecFormat
(
value
))
return
TimestampPrecision
.
NS
;
return
TimestampPrecision
.
UNKNOWN
;
return
TimestampPrecision
.
MS
;
}
private
static
boolean
isMilliSecFormat
(
String
timestampStr
)
{
...
...
src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/GetLongWithDifferentTimestampPrecision.java
0 → 100644
浏览文件 @
dcd6f3e6
package
com.taosdata.jdbc.cases
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
java.sql.*
;
import
java.text.SimpleDateFormat
;
public
class
GetLongWithDifferentTimestampPrecision
{
private
final
String
host
=
"127.0.0.1"
;
@Test
public
void
testRestful
()
throws
SQLException
{
// given
String
url
=
"jdbc:TAOS-RS://"
+
host
+
":6041/"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"root"
,
"taosdata"
);
long
ts
=
System
.
currentTimeMillis
();
// when and then
assertResultSet
(
conn
,
"ms"
,
ts
,
ts
);
assertResultSet
(
conn
,
"us"
,
ts
,
ts
*
1000
);
assertResultSet
(
conn
,
"ns"
,
ts
,
ts
*
1000_000
);
}
@Test
public
void
testJni
()
throws
SQLException
{
// given
String
url
=
"jdbc:TAOS://"
+
host
+
":6030/"
;
Connection
conn
=
DriverManager
.
getConnection
(
url
,
"root"
,
"taosdata"
);
long
ts
=
System
.
currentTimeMillis
();
// when and then
assertResultSet
(
conn
,
"ms"
,
ts
,
ts
);
assertResultSet
(
conn
,
"us"
,
ts
,
ts
*
1000
);
assertResultSet
(
conn
,
"ns"
,
ts
,
ts
*
1000_000
);
}
private
void
assertResultSet
(
Connection
conn
,
String
precision
,
long
timestamp
,
long
expect
)
throws
SQLException
{
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss.SSS"
);
try
(
Statement
stmt
=
conn
.
createStatement
())
{
stmt
.
execute
(
"drop database if exists test"
);
stmt
.
execute
(
"create database if not exists test precision '"
+
precision
+
"'"
);
stmt
.
execute
(
"create table test.weather(ts timestamp, f1 int)"
);
String
dateTimeStr
=
sdf
.
format
(
new
Date
(
timestamp
));
stmt
.
execute
(
"insert into test.weather values('"
+
dateTimeStr
+
"', 1)"
);
ResultSet
rs
=
stmt
.
executeQuery
(
"select * from test.weather"
);
rs
.
next
();
long
actual
=
rs
.
getLong
(
"ts"
);
Assert
.
assertEquals
(
expect
,
actual
);
stmt
.
execute
(
"drop database if exists test"
);
}
}
}
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java
浏览文件 @
dcd6f3e6
...
...
@@ -9,29 +9,29 @@ import java.util.Random;
@FixMethodOrder
(
MethodSorters
.
NAME_ASCENDING
)
public
class
RestfulJDBCTest
{
// private static final String host = "127.0.0.1";
private
static
final
String
host
=
"master"
;
private
static
final
String
host
=
"127.0.0.1"
;
private
static
final
Random
random
=
new
Random
(
System
.
currentTimeMillis
());
private
static
Connection
connection
;
private
static
final
String
dbname
=
"restful_test"
;
@Test
public
void
testCase001
()
throws
SQLException
{
// given
String
sql
=
"drop database if exists
restful_test"
;
String
sql
=
"drop database if exists
"
+
dbname
;
// when
boolean
execute
=
execute
(
connection
,
sql
);
// then
Assert
.
assertFalse
(
execute
);
// given
sql
=
"create database if not exists
restful_test"
;
sql
=
"create database if not exists
"
+
dbname
;
// when
execute
=
execute
(
connection
,
sql
);
// then
Assert
.
assertFalse
(
execute
);
// given
sql
=
"use
restful_test"
;
sql
=
"use
"
+
dbname
;
// when
execute
=
execute
(
connection
,
sql
);
// then
...
...
@@ -41,7 +41,7 @@ public class RestfulJDBCTest {
@Test
public
void
testCase002
()
throws
SQLException
{
// given
String
sql
=
"create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"
;
String
sql
=
"create table
"
+
dbname
+
".
weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"
;
// when
boolean
execute
=
execute
(
connection
,
sql
);
// then
...
...
@@ -52,7 +52,7 @@ public class RestfulJDBCTest {
public
void
testCase004
()
throws
SQLException
{
for
(
int
i
=
1
;
i
<=
100
;
i
++)
{
// given
String
sql
=
"create table
t"
+
i
+
" using
weather tags('beijing', '"
+
i
+
"')"
;
String
sql
=
"create table
"
+
dbname
+
".t"
+
i
+
" using "
+
dbname
+
".
weather tags('beijing', '"
+
i
+
"')"
;
// when
boolean
execute
=
execute
(
connection
,
sql
);
// then
...
...
@@ -68,7 +68,7 @@ public class RestfulJDBCTest {
// given
long
currentTimeMillis
=
System
.
currentTimeMillis
();
String
sql
=
"insert into t"
+
j
+
" values("
+
currentTimeMillis
+
","
+
(
random
.
nextFloat
()
*
50
)
+
","
+
random
.
nextInt
(
100
)
+
")"
;
String
sql
=
"insert into
"
+
dbname
+
".
t"
+
j
+
" values("
+
currentTimeMillis
+
","
+
(
random
.
nextFloat
()
*
50
)
+
","
+
random
.
nextInt
(
100
)
+
")"
;
// when
int
affectRows
=
executeUpdate
(
connection
,
sql
);
// then
...
...
@@ -83,7 +83,7 @@ public class RestfulJDBCTest {
@Test
public
void
testCase006
()
throws
SQLException
{
// given
String
sql
=
"select * from weather"
;
String
sql
=
"select * from
"
+
dbname
+
".
weather"
;
// when
ResultSet
rs
=
executeQuery
(
connection
,
sql
);
ResultSetMetaData
meta
=
rs
.
getMetaData
();
...
...
@@ -102,7 +102,7 @@ public class RestfulJDBCTest {
@Test
public
void
testCase007
()
throws
SQLException
{
// given
String
sql
=
"drop database
restful_test"
;
String
sql
=
"drop database
"
+
dbname
;
// when
boolean
execute
=
execute
(
connection
,
sql
);
...
...
@@ -143,7 +143,7 @@ public class RestfulJDBCTest {
public
static
void
afterClass
()
throws
SQLException
{
if
(
connection
!=
null
)
{
Statement
stmt
=
connection
.
createStatement
();
stmt
.
execute
(
"drop database if exists
restful_test"
);
stmt
.
execute
(
"drop database if exists
"
+
dbname
);
stmt
.
close
();
connection
.
close
();
}
...
...
src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java
浏览文件 @
dcd6f3e6
...
...
@@ -17,12 +17,25 @@ import java.text.SimpleDateFormat;
public
class
RestfulResultSetTest
{
// private static final String host = "127.0.0.1";
private
static
final
String
host
=
"master"
;
private
static
final
String
host
=
"127.0.0.1"
;
private
static
Connection
conn
;
private
static
Statement
stmt
;
private
static
ResultSet
rs
;
@BeforeClass
public
static
void
beforeClass
()
throws
SQLException
{
conn
=
DriverManager
.
getConnection
(
"jdbc:TAOS-RS://"
+
host
+
":6041/?user=root&password=taosdata"
);
stmt
=
conn
.
createStatement
();
stmt
.
execute
(
"drop database if exists restful_test"
);
stmt
.
execute
(
"create database if not exists restful_test"
);
stmt
.
execute
(
"use restful_test"
);
stmt
.
execute
(
"drop table if exists weather"
);
stmt
.
execute
(
"create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))"
);
stmt
.
execute
(
"insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"
);
rs
=
stmt
.
executeQuery
(
"select * from restful_test.weather"
);
rs
.
next
();
}
@Test
public
void
wasNull
()
throws
SQLException
{
Assert
.
assertFalse
(
rs
.
wasNull
());
...
...
@@ -658,20 +671,6 @@ public class RestfulResultSetTest {
Assert
.
assertTrue
(
rs
.
isWrapperFor
(
RestfulResultSet
.
class
));
}
@BeforeClass
public
static
void
beforeClass
()
throws
SQLException
{
conn
=
DriverManager
.
getConnection
(
"jdbc:TAOS-RS://"
+
host
+
":6041/?user=root&password=taosdata"
);
stmt
=
conn
.
createStatement
();
stmt
.
execute
(
"drop database if exists restful_test"
);
stmt
.
execute
(
"create database if not exists restful_test"
);
stmt
.
execute
(
"use restful_test"
);
stmt
.
execute
(
"drop table if exists weather"
);
stmt
.
execute
(
"create table if not exists weather(f1 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 binary(64), f7 smallint, f8 tinyint, f9 bool, f10 nchar(64))"
);
stmt
.
execute
(
"insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"
);
rs
=
stmt
.
executeQuery
(
"select * from restful_test.weather"
);
rs
.
next
();
}
@AfterClass
public
static
void
afterClass
()
throws
SQLException
{
if
(
rs
!=
null
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录