Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
24f47281
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
24f47281
编写于
5月 10, 2021
作者:
D
dapan1121
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'feature/TD-4038' of
https://github.com/taosdata/TDengine
into feature/TD-4038
上级
ecb735de
8223aa41
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
209 addition
and
120 deletion
+209
-120
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+1
-2
src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h
src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h
+2
-2
src/client/src/TSDBJNIConnector.c
src/client/src/TSDBJNIConnector.c
+22
-11
src/client/src/tscPrepare.c
src/client/src/tscPrepare.c
+18
-45
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
...dbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
+3
-3
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
...rc/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
+116
-46
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
...c/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
+2
-2
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java
.../jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java
+43
-7
src/inc/taos.h
src/inc/taos.h
+2
-2
未找到文件。
src/client/inc/tsclient.h
浏览文件 @
24f47281
...
@@ -154,13 +154,12 @@ typedef struct STagCond {
...
@@ -154,13 +154,12 @@ typedef struct STagCond {
typedef
struct
SParamInfo
{
typedef
struct
SParamInfo
{
int32_t
idx
;
int32_t
idx
;
char
type
;
uint8_t
type
;
uint8_t
timePrec
;
uint8_t
timePrec
;
int16_t
bytes
;
int16_t
bytes
;
uint32_t
offset
;
uint32_t
offset
;
}
SParamInfo
;
}
SParamInfo
;
typedef
struct
SBoundColumn
{
typedef
struct
SBoundColumn
{
bool
hasVal
;
// denote if current column has bound or not
bool
hasVal
;
// denote if current column has bound or not
int32_t
offset
;
// all column offset value
int32_t
offset
;
// all column offset value
...
...
src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h
浏览文件 @
24f47281
...
@@ -204,10 +204,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
...
@@ -204,10 +204,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
/*
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: bindColDataImp
* Method: bindColDataImp
* Signature: (J[B[BIIIIJ)J
* Signature: (J[B[B
[B
IIIIJ)J
*/
*/
JNIEXPORT
jlong
JNICALL
Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
JNIEXPORT
jlong
JNICALL
Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(
JNIEnv
*
,
jobject
,
jlong
,
jbyteArray
,
jbyteArray
,
jint
,
jint
,
jint
,
jint
,
jlong
);
(
JNIEnv
*
,
jobject
,
jlong
,
jbyteArray
,
jbyteArray
,
j
byteArray
,
j
int
,
jint
,
jint
,
jint
,
jlong
);
/*
/*
* Class: com_taosdata_jdbc_TSDBJNIConnector
* Class: com_taosdata_jdbc_TSDBJNIConnector
...
...
src/client/src/TSDBJNIConnector.c
浏览文件 @
24f47281
...
@@ -753,7 +753,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
...
@@ -753,7 +753,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
}
}
JNIEXPORT
jlong
JNICALL
Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(
JNIEnv
*
env
,
jobject
jobj
,
jlong
stmt
,
JNIEXPORT
jlong
JNICALL
Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(
JNIEnv
*
env
,
jobject
jobj
,
jlong
stmt
,
jbyteArray
data
,
jbyteArray
length
,
jint
dataType
,
jint
dataBytes
,
jint
numOfRows
,
jint
colIndex
,
jlong
con
)
{
jbyteArray
colDataList
,
jbyteArray
lengthList
,
jbyteArray
nullList
,
jint
dataType
,
jint
dataBytes
,
jint
numOfRows
,
jint
colIndex
,
jlong
con
)
{
TAOS
*
tscon
=
(
TAOS
*
)
con
;
TAOS
*
tscon
=
(
TAOS
*
)
con
;
if
(
tscon
==
NULL
)
{
if
(
tscon
==
NULL
)
{
jniError
(
"jobj:%p, connection already closed"
,
jobj
);
jniError
(
"jobj:%p, connection already closed"
,
jobj
);
...
@@ -767,16 +767,22 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
...
@@ -767,16 +767,22 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
}
}
// todo refactor
// todo refactor
jsize
len
=
(
*
env
)
->
GetArrayLength
(
env
,
data
);
jsize
len
=
(
*
env
)
->
GetArrayLength
(
env
,
colDataList
);
char
*
colBuf
=
(
char
*
)
calloc
(
1
,
sizeof
(
char
)
*
len
);
char
*
colBuf
=
(
char
*
)
calloc
(
1
,
len
);
(
*
env
)
->
GetByteArrayRegion
(
env
,
data
,
0
,
len
,
(
jbyte
*
)
colBuf
);
(
*
env
)
->
GetByteArrayRegion
(
env
,
colDataList
,
0
,
len
,
(
jbyte
*
)
colBuf
);
if
((
*
env
)
->
ExceptionCheck
(
env
))
{
if
((
*
env
)
->
ExceptionCheck
(
env
))
{
// todo handle error
// todo handle error
}
}
len
=
(
*
env
)
->
GetArrayLength
(
env
,
length
);
len
=
(
*
env
)
->
GetArrayLength
(
env
,
lengthList
);
char
*
lengthArray
=
(
char
*
)
calloc
(
1
,
sizeof
(
char
)
*
len
);
char
*
lengthArray
=
(
char
*
)
calloc
(
1
,
len
);
(
*
env
)
->
GetByteArrayRegion
(
env
,
length
,
0
,
len
,
(
jbyte
*
)
lengthArray
);
(
*
env
)
->
GetByteArrayRegion
(
env
,
lengthList
,
0
,
len
,
(
jbyte
*
)
lengthArray
);
if
((
*
env
)
->
ExceptionCheck
(
env
))
{
}
len
=
(
*
env
)
->
GetArrayLength
(
env
,
nullList
);
char
*
nullArray
=
(
char
*
)
calloc
(
1
,
len
);
(
*
env
)
->
GetByteArrayRegion
(
env
,
nullList
,
0
,
len
,
(
jbyte
*
)
nullArray
);
if
((
*
env
)
->
ExceptionCheck
(
env
))
{
if
((
*
env
)
->
ExceptionCheck
(
env
))
{
}
}
...
@@ -785,10 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
...
@@ -785,10 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
b
->
num
=
numOfRows
;
b
->
num
=
numOfRows
;
b
->
buffer_type
=
dataType
;
// todo check data type
b
->
buffer_type
=
dataType
;
// todo check data type
b
->
buffer_length
=
tDataTypes
[
dataType
].
bytes
;
b
->
buffer_length
=
IS_VAR_DATA_TYPE
(
dataType
)
?
dataBytes
:
tDataTypes
[
dataType
].
bytes
;
b
->
is_null
=
calloc
(
numOfRows
,
sizeof
(
int32_t
))
;
b
->
is_null
=
nullArray
;
b
->
buffer
=
colBuf
;
b
->
buffer
=
colBuf
;
b
->
length
=
(
uintptr
_t
*
)
lengthArray
;
b
->
length
=
(
int32
_t
*
)
lengthArray
;
// set the length and is_null array
// set the length and is_null array
switch
(
dataType
)
{
switch
(
dataType
)
{
...
@@ -800,8 +806,13 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
...
@@ -800,8 +806,13 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
int32_t
bytes
=
tDataTypes
[
dataType
].
bytes
;
int32_t
bytes
=
tDataTypes
[
dataType
].
bytes
;
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
b
->
length
[
i
]
=
bytes
;
b
->
length
[
i
]
=
bytes
;
b
->
is_null
[
i
]
=
isNull
(
colBuf
+
bytes
*
i
,
dataType
);
}
}
break
;
}
case
TSDB_DATA_TYPE_NCHAR
:
case
TSDB_DATA_TYPE_BINARY
:
{
// do nothing
}
}
}
}
...
...
src/client/src/tscPrepare.c
浏览文件 @
24f47281
...
@@ -158,7 +158,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
...
@@ -158,7 +158,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
break
;
break
;
default:
default:
tscDebug
(
"0x%"
PRIx64
"
param
%d: type mismatch or invalid"
,
stmt
->
pSql
->
self
,
i
);
tscDebug
(
"0x%"
PRIx64
"
bind column
%d: type mismatch or invalid"
,
stmt
->
pSql
->
self
,
i
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
}
}
}
...
@@ -727,45 +727,14 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
...
@@ -727,45 +727,14 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
static
int
doBindBatchParam
(
STableDataBlocks
*
pBlock
,
SParamInfo
*
param
,
TAOS_MULTI_BIND
*
bind
,
int32_t
rowNum
)
{
static
int
doBindBatchParam
(
STableDataBlocks
*
pBlock
,
SParamInfo
*
param
,
TAOS_MULTI_BIND
*
bind
,
int32_t
rowNum
)
{
if
(
bind
->
buffer_type
!=
param
->
type
)
{
if
(
bind
->
buffer_type
!=
param
->
type
||
!
isValidDataType
(
param
->
type
)
)
{
return
TSDB_CODE_TSC_INVALID_VALUE
;
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
}
short
size
=
0
;
if
(
IS_VAR_DATA_TYPE
(
param
->
type
)
&&
bind
->
length
==
NULL
)
{
switch
(
param
->
type
)
{
tscError
(
"BINARY/NCHAR no length"
);
case
TSDB_DATA_TYPE_BOOL
:
return
TSDB_CODE_TSC_INVALID_VALUE
;
case
TSDB_DATA_TYPE_TINYINT
:
size
=
1
;
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
size
=
2
;
break
;
case
TSDB_DATA_TYPE_INT
:
case
TSDB_DATA_TYPE_FLOAT
:
size
=
4
;
break
;
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_DOUBLE
:
case
TSDB_DATA_TYPE_TIMESTAMP
:
size
=
8
;
break
;
case
TSDB_DATA_TYPE_BINARY
:
case
TSDB_DATA_TYPE_NCHAR
:
if
(
bind
->
length
==
NULL
)
{
tscError
(
"BINARY/NCHAR no length"
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
break
;
default:
assert
(
false
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
}
for
(
int
i
=
0
;
i
<
bind
->
num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
bind
->
num
;
++
i
)
{
char
*
data
=
pBlock
->
pData
+
sizeof
(
SSubmitBlk
)
+
pBlock
->
rowSize
*
(
rowNum
+
i
);
char
*
data
=
pBlock
->
pData
+
sizeof
(
SSubmitBlk
)
+
pBlock
->
rowSize
*
(
rowNum
+
i
);
...
@@ -775,8 +744,8 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
...
@@ -775,8 +744,8 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
continue
;
continue
;
}
}
if
(
size
>
0
)
{
if
(
!
IS_VAR_DATA_TYPE
(
param
->
type
)
)
{
memcpy
(
data
+
param
->
offset
,
bind
->
buffer
+
bind
->
buffer_length
*
i
,
size
);
memcpy
(
data
+
param
->
offset
,
bind
->
buffer
+
bind
->
buffer_length
*
i
,
tDataTypes
[
param
->
type
].
bytes
);
if
(
param
->
offset
==
0
)
{
if
(
param
->
offset
==
0
)
{
if
(
tsCheckTimestamp
(
pBlock
,
data
+
param
->
offset
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
tsCheckTimestamp
(
pBlock
,
data
+
param
->
offset
)
!=
TSDB_CODE_SUCCESS
)
{
...
@@ -786,17 +755,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
...
@@ -786,17 +755,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
}
}
}
else
if
(
param
->
type
==
TSDB_DATA_TYPE_BINARY
)
{
}
else
if
(
param
->
type
==
TSDB_DATA_TYPE_BINARY
)
{
if
(
bind
->
length
[
i
]
>
(
uintptr_t
)
param
->
bytes
)
{
if
(
bind
->
length
[
i
]
>
(
uintptr_t
)
param
->
bytes
)
{
tscError
(
"
invalid binary length"
);
tscError
(
"
binary length too long, ignore it, max:%d, actual:%d"
,
param
->
bytes
,
(
int32_t
)
bind
->
length
[
i
]
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
}
int16_t
bsize
=
(
short
)
bind
->
length
[
i
];
int16_t
bsize
=
(
short
)
bind
->
length
[
i
];
STR_WITH_SIZE_TO_VARSTR
(
data
+
param
->
offset
,
bind
->
buffer
+
bind
->
buffer_length
*
i
,
bsize
);
STR_WITH_SIZE_TO_VARSTR
(
data
+
param
->
offset
,
bind
->
buffer
+
bind
->
buffer_length
*
i
,
bsize
);
}
else
if
(
param
->
type
==
TSDB_DATA_TYPE_NCHAR
)
{
}
else
if
(
param
->
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
bind
->
length
[
i
]
>
(
uintptr_t
)
param
->
bytes
)
{
tscError
(
"nchar string length too long, ignore it, max:%d, actual:%d"
,
param
->
bytes
,
(
int32_t
)
bind
->
length
[
i
]);
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
int32_t
output
=
0
;
int32_t
output
=
0
;
if
(
!
taosMbsToUcs4
(
bind
->
buffer
+
bind
->
buffer_length
*
i
,
bind
->
length
[
i
],
varDataVal
(
data
+
param
->
offset
),
param
->
bytes
-
VARSTR_HEADER_SIZE
,
&
output
))
{
if
(
!
taosMbsToUcs4
(
bind
->
buffer
+
bind
->
buffer_length
*
i
,
bind
->
length
[
i
],
varDataVal
(
data
+
param
->
offset
),
param
->
bytes
-
VARSTR_HEADER_SIZE
,
&
output
))
{
tscError
(
"convert
failed"
);
tscError
(
"convert
nchar string to UCS4_LE failed:%s"
,
(
char
*
)(
bind
->
buffer
+
bind
->
buffer_length
*
i
)
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
}
varDataSetLen
(
data
+
param
->
offset
,
output
);
varDataSetLen
(
data
+
param
->
offset
,
output
);
}
}
}
}
...
@@ -804,8 +779,6 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
...
@@ -804,8 +779,6 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
int
insertStmtBindParam
(
STscStmt
*
stmt
,
TAOS_BIND
*
bind
)
{
static
int
insertStmtBindParam
(
STscStmt
*
stmt
,
TAOS_BIND
*
bind
)
{
SSqlCmd
*
pCmd
=
&
stmt
->
pSql
->
cmd
;
SSqlCmd
*
pCmd
=
&
stmt
->
pSql
->
cmd
;
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
...
@@ -860,7 +833,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
...
@@ -860,7 +833,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
int
code
=
doBindParam
(
pBlock
,
data
,
param
,
&
bind
[
param
->
idx
],
1
);
int
code
=
doBindParam
(
pBlock
,
data
,
param
,
&
bind
[
param
->
idx
],
1
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tscDebug
(
"0x%"
PRIx64
"
param
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
tscDebug
(
"0x%"
PRIx64
"
bind column
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
return
code
;
return
code
;
}
}
}
}
...
@@ -930,7 +903,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
...
@@ -930,7 +903,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
int
code
=
doBindBatchParam
(
pBlock
,
param
,
&
bind
[
param
->
idx
],
pCmd
->
batchSize
);
int
code
=
doBindBatchParam
(
pBlock
,
param
,
&
bind
[
param
->
idx
],
pCmd
->
batchSize
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tscError
(
"0x%"
PRIx64
"
param
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
tscError
(
"0x%"
PRIx64
"
bind column
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
return
code
;
return
code
;
}
}
}
}
...
@@ -941,7 +914,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
...
@@ -941,7 +914,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
int
code
=
doBindBatchParam
(
pBlock
,
param
,
bind
,
pCmd
->
batchSize
);
int
code
=
doBindBatchParam
(
pBlock
,
param
,
bind
,
pCmd
->
batchSize
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tscError
(
"0x%"
PRIx64
"
param
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
tscError
(
"0x%"
PRIx64
"
bind column
%d: type mismatch or invalid"
,
pStmt
->
pSql
->
self
,
param
->
idx
);
return
code
;
return
code
;
}
}
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
浏览文件 @
24f47281
...
@@ -306,11 +306,11 @@ public class TSDBJNIConnector {
...
@@ -306,11 +306,11 @@ public class TSDBJNIConnector {
private
native
int
setBindTableNameImp
(
long
stmt
,
String
name
,
long
conn
);
private
native
int
setBindTableNameImp
(
long
stmt
,
String
name
,
long
conn
);
public
int
bindColumnDataArray
(
long
stmt
,
ByteBuffer
col
List
,
ByteBuffer
length
List
,
int
type
,
int
bytes
,
int
numOfRows
,
int
columnIndex
)
{
public
int
bindColumnDataArray
(
long
stmt
,
ByteBuffer
col
DataList
,
ByteBuffer
lengthList
,
ByteBuffer
isNull
List
,
int
type
,
int
bytes
,
int
numOfRows
,
int
columnIndex
)
{
return
bindColDataImp
(
stmt
,
col
List
.
array
(),
length
List
.
array
(),
type
,
bytes
,
numOfRows
,
columnIndex
,
this
.
taos
);
return
bindColDataImp
(
stmt
,
col
DataList
.
array
(),
lengthList
.
array
(),
isNull
List
.
array
(),
type
,
bytes
,
numOfRows
,
columnIndex
,
this
.
taos
);
}
}
private
native
int
bindColDataImp
(
long
stmt
,
byte
[]
data
,
byte
[]
length
,
int
type
,
int
bytes
,
int
numOfRows
,
int
columnIndex
,
long
conn
);
private
native
int
bindColDataImp
(
long
stmt
,
byte
[]
colDataList
,
byte
[]
lengthList
,
byte
[]
isNullList
,
int
type
,
int
bytes
,
int
numOfRows
,
int
columnIndex
,
long
conn
);
public
int
executeBatch
(
long
stmt
)
{
public
int
executeBatch
(
long
stmt
)
{
return
executeBatchImp
(
stmt
,
this
.
taos
);
return
executeBatchImp
(
stmt
,
this
.
taos
);
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
浏览文件 @
24f47281
...
@@ -18,6 +18,7 @@ import com.taosdata.jdbc.utils.Utils;
...
@@ -18,6 +18,7 @@ import com.taosdata.jdbc.utils.Utils;
import
java.io.InputStream
;
import
java.io.InputStream
;
import
java.io.Reader
;
import
java.io.Reader
;
import
java.io.UnsupportedEncodingException
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.net.URL
;
import
java.net.URL
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
...
@@ -40,8 +41,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
...
@@ -40,8 +41,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
private
boolean
isPrepared
;
private
boolean
isPrepared
;
private
ArrayList
<
ColumnInfo
>
colData
;
private
ArrayList
<
ColumnInfo
>
colData
;
private
int
type
;
private
String
tableName
;
private
String
tableName
;
private
long
nativeStmtHandle
=
0
;
private
long
nativeStmtHandle
=
0
;
...
@@ -540,6 +539,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
...
@@ -540,6 +539,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@SuppressWarnings
(
"rawtypes"
)
@SuppressWarnings
(
"rawtypes"
)
private
ArrayList
data
;
private
ArrayList
data
;
private
int
type
;
private
int
type
;
private
int
bytes
;
private
boolean
typeIsSet
;
private
boolean
typeIsSet
;
public
ColumnInfo
()
{
public
ColumnInfo
()
{
...
@@ -564,60 +564,61 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
...
@@ -564,60 +564,61 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
this
.
tableName
=
name
;
this
.
tableName
=
name
;
}
}
public
<
T
>
void
setValueImpl
(
int
columnIndex
,
ArrayList
<
T
>
list
,
int
type
)
throws
SQLException
{
public
<
T
>
void
setValueImpl
(
int
columnIndex
,
ArrayList
<
T
>
list
,
int
type
,
int
bytes
)
throws
SQLException
{
ColumnInfo
col
=
(
ColumnInfo
)
this
.
colData
.
get
(
columnIndex
);
ColumnInfo
col
=
(
ColumnInfo
)
this
.
colData
.
get
(
columnIndex
);
if
(
col
==
null
)
{
if
(
col
==
null
)
{
ColumnInfo
p
=
new
ColumnInfo
();
ColumnInfo
p
=
new
ColumnInfo
();
p
.
setType
(
type
);
p
.
setType
(
type
);
p
.
bytes
=
bytes
;
p
.
data
=
(
ArrayList
<?>)
list
.
clone
();
p
.
data
=
(
ArrayList
<?>)
list
.
clone
();
this
.
colData
.
set
(
columnIndex
,
p
);
this
.
colData
.
set
(
columnIndex
,
p
);
}
else
{
}
else
{
if
(
col
.
type
!=
type
)
{
if
(
col
.
type
!=
type
)
{
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"column data type mismatch"
);
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"column data type mismatch"
);
}
}
col
.
data
.
addAll
(
list
);
col
.
data
.
addAll
(
list
);
}
}
}
}
public
void
setInt
(
int
columnIndex
,
ArrayList
<
Integer
>
list
)
throws
SQLException
{
public
void
setInt
(
int
columnIndex
,
ArrayList
<
Integer
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_INT
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_INT
,
Integer
.
BYTES
);
}
}
public
void
setFloat
(
int
columnIndex
,
ArrayList
<
Float
>
list
)
throws
SQLException
{
public
void
setFloat
(
int
columnIndex
,
ArrayList
<
Float
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_FLOAT
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_FLOAT
,
Float
.
BYTES
);
}
}
public
void
setTimestamp
(
int
columnIndex
,
ArrayList
<
Long
>
list
)
throws
SQLException
{
public
void
setTimestamp
(
int
columnIndex
,
ArrayList
<
Long
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_TIMESTAMP
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_TIMESTAMP
,
Long
.
BYTES
);
}
}
public
void
setLong
(
int
columnIndex
,
ArrayList
<
Long
>
list
)
throws
SQLException
{
public
void
setLong
(
int
columnIndex
,
ArrayList
<
Long
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BIGINT
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BIGINT
,
Long
.
BYTES
);
}
}
public
void
setDouble
(
int
columnIndex
,
ArrayList
<
Double
>
list
)
throws
SQLException
{
public
void
setDouble
(
int
columnIndex
,
ArrayList
<
Double
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_DOUBLE
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_DOUBLE
,
Double
.
BYTES
);
}
}
public
void
setBoolean
(
int
columnIndex
,
ArrayList
<
Boolean
>
list
)
throws
SQLException
{
public
void
setBoolean
(
int
columnIndex
,
ArrayList
<
Boolean
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BOOL
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BOOL
,
Byte
.
BYTES
);
}
}
public
void
setByte
(
int
columnIndex
,
ArrayList
<
Byte
>
list
)
throws
SQLException
{
public
void
setByte
(
int
columnIndex
,
ArrayList
<
Byte
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_TINYINT
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_TINYINT
,
Byte
.
BYTES
);
}
}
public
void
setShort
(
int
columnIndex
,
ArrayList
<
Short
>
list
)
throws
SQLException
{
public
void
setShort
(
int
columnIndex
,
ArrayList
<
Short
>
list
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_SMALLINT
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_SMALLINT
,
Short
.
BYTES
);
}
}
public
void
setString
(
int
columnIndex
,
ArrayList
<
String
>
list
)
throws
SQLException
{
public
void
setString
(
int
columnIndex
,
ArrayList
<
String
>
list
,
int
size
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BINARY
);
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_BINARY
,
size
);
}
}
public
void
setNString
(
int
columnIndex
,
ArrayList
<
String
>
list
)
throws
SQLException
{
// note: expand the required space for each NChar character
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_NCHAR
);
public
void
setNString
(
int
columnIndex
,
ArrayList
<
String
>
list
,
int
size
)
throws
SQLException
{
setValueImpl
(
columnIndex
,
list
,
TSDBConstants
.
TSDB_DATA_TYPE_NCHAR
,
size
*
Integer
.
BYTES
);
}
}
public
void
columnDataAddBatch
()
{
public
void
columnDataAddBatch
()
{
...
@@ -643,11 +644,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
...
@@ -643,11 +644,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
int
bytes
=
0
;
for
(
int
i
=
0
;
i
<
numOfCols
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numOfCols
;
++
i
)
{
ColumnInfo
col1
=
this
.
colData
.
get
(
i
);
ColumnInfo
col1
=
this
.
colData
.
get
(
i
);
if
(!
col1
.
isTypeSet
())
{
if
(
col1
==
null
||
!
col1
.
isTypeSet
())
{
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"column data not bind"
);
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"column data not bind"
);
}
}
...
@@ -655,51 +654,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
...
@@ -655,51 +654,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"the rows in column data not identical"
);
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"the rows in column data not identical"
);
}
}
ByteBuffer
bbuf
=
null
;
ByteBuffer
colDataList
=
ByteBuffer
.
allocate
(
rows
*
col1
.
bytes
);
colDataList
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
ByteBuffer
lengthBuf
=
ByteBuffer
.
allocate
(
rows
*
Integer
.
BYTES
);
ByteBuffer
lengthList
=
ByteBuffer
.
allocate
(
rows
*
Integer
.
BYTES
);
lengthBuf
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
lengthList
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
ByteBuffer
isNullList
=
ByteBuffer
.
allocate
(
rows
*
Byte
.
BYTES
);
isNullList
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
switch
(
col1
.
type
)
{
switch
(
col1
.
type
)
{
case
TSDBConstants
.
TSDB_DATA_TYPE_INT
:
{
case
TSDBConstants
.
TSDB_DATA_TYPE_INT
:
{
bbuf
=
ByteBuffer
.
allocate
(
rows
*
Integer
.
BYTES
);
bbuf
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Integer
val
=
(
Integer
)
col1
.
data
.
get
(
j
);
Integer
val
=
(
Integer
)
col1
.
data
.
get
(
j
);
if
(
val
==
null
)
{
colDataList
.
putInt
(
val
==
null
?
Integer
.
MIN_VALUE
:
val
);
bbuf
.
putInt
(
j
*
Integer
.
BYTES
,
Integer
.
MIN_VALUE
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
else
{
bbuf
.
putInt
(
j
*
Integer
.
BYTES
,
val
);
}
lengthBuf
.
putInt
(
j
*
Integer
.
BYTES
,
Integer
.
BYTES
);
}
}
bytes
=
Integer
.
BYTES
;
break
;
break
;
}
}
case
TSDBConstants
.
TSDB_DATA_TYPE_TIMESTAMP
:
{
case
TSDBConstants
.
TSDB_DATA_TYPE_TINYINT
:
{
bbuf
=
ByteBuffer
.
allocate
(
rows
*
Long
.
BYTES
);
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
bbuf
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
Byte
val
=
(
Byte
)
col1
.
data
.
get
(
j
);
colDataList
.
put
(
val
==
null
?
0
:
val
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_BOOL
:
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Byte
val
=
(
Byte
)
col1
.
data
.
get
(
j
);
colDataList
.
put
(
val
==
null
?
0
:
val
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_SMALLINT
:
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Short
val
=
(
Short
)
col1
.
data
.
get
(
j
);
colDataList
.
putShort
(
val
==
null
?
0
:
val
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_TIMESTAMP
:
case
TSDBConstants
.
TSDB_DATA_TYPE_BIGINT
:
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Long
val
=
(
Long
)
col1
.
data
.
get
(
j
);
Long
val
=
(
Long
)
col1
.
data
.
get
(
j
);
if
(
val
==
null
)
{
colDataList
.
putLong
(
val
==
null
?
0
:
val
);
bbuf
.
putLong
(
j
*
Long
.
BYTES
,
Long
.
MIN_VALUE
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_FLOAT
:
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Float
val
=
(
Float
)
col1
.
data
.
get
(
j
);
colDataList
.
putFloat
(
val
==
null
?
0
:
val
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_DOUBLE
:
{
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
Double
val
=
(
Double
)
col1
.
data
.
get
(
j
);
colDataList
.
putDouble
(
val
==
null
?
0
:
val
);
isNullList
.
put
((
byte
)
(
val
==
null
?
1
:
0
));
}
break
;
}
case
TSDBConstants
.
TSDB_DATA_TYPE_NCHAR
:
case
TSDBConstants
.
TSDB_DATA_TYPE_BINARY
:
{
String
charset
=
TaosGlobalConfig
.
getCharset
();
for
(
int
j
=
0
;
j
<
rows
;
++
j
)
{
String
val
=
(
String
)
col1
.
data
.
get
(
j
);
if
(
val
!=
null
&&
val
.
length
()
>
col1
.
bytes
)
{
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"string data too long"
);
}
colDataList
.
position
(
j
*
col1
.
bytes
);
// seek to the correct position
if
(
val
!=
null
)
{
byte
[]
b
=
null
;
try
{
if
(
col1
.
type
==
TSDBConstants
.
TSDB_DATA_TYPE_BINARY
)
{
b
=
val
.
getBytes
();
}
else
{
b
=
val
.
getBytes
(
charset
);
}
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
colDataList
.
put
(
b
);
lengthList
.
putInt
(
b
.
length
);
isNullList
.
put
((
byte
)
0
);
}
else
{
}
else
{
bbuf
.
putLong
(
j
*
Long
.
BYTES
,
val
);
lengthList
.
putInt
(
0
);
isNullList
.
put
((
byte
)
1
);
}
}
lengthBuf
.
putInt
(
j
*
Integer
.
BYTES
,
Long
.
BYTES
);
}
}
bytes
=
Long
.
BYTES
;
break
;
break
;
}
}
case
TSDBConstants
.
TSDB_DATA_TYPE_UTINYINT
:
case
TSDBConstants
.
TSDB_DATA_TYPE_USMALLINT
:
case
TSDBConstants
.
TSDB_DATA_TYPE_UINT
:
case
TSDBConstants
.
TSDB_DATA_TYPE_UBIGINT
:
{
throw
TSDBError
.
createSQLException
(
TSDBErrorNumbers
.
ERROR_UNKNOWN
,
"not support data types"
);
}
};
};
connector
.
bindColumnDataArray
(
this
.
nativeStmtHandle
,
bbuf
,
lengthBuf
,
col1
.
type
,
bytes
,
rows
,
i
);
connector
.
bindColumnDataArray
(
this
.
nativeStmtHandle
,
colDataList
,
lengthList
,
isNullList
,
col1
.
type
,
col1
.
bytes
,
rows
,
i
);
}
}
connector
.
executeBatch
(
this
.
nativeStmtHandle
);
connector
.
executeBatch
(
this
.
nativeStmtHandle
);
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
浏览文件 @
24f47281
...
@@ -438,8 +438,8 @@ public class TSDBResultSetBlockData {
...
@@ -438,8 +438,8 @@ public class TSDBResultSetBlockData {
}
}
try
{
try
{
String
ss
=
TaosGlobalConfig
.
getCharset
();
String
charset
=
TaosGlobalConfig
.
getCharset
();
return
new
String
(
dest
,
ss
);
return
new
String
(
dest
,
charset
);
}
catch
(
UnsupportedEncodingException
e
)
{
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java
浏览文件 @
24f47281
...
@@ -11,11 +11,11 @@ public class NullType {
...
@@ -11,11 +11,11 @@ public class NullType {
public
static
boolean
isBooleanNull
(
byte
val
)
{
public
static
boolean
isBooleanNull
(
byte
val
)
{
return
val
==
NullType
.
NULL_BOOL_VAL
;
return
val
==
NullType
.
NULL_BOOL_VAL
;
}
}
public
static
boolean
isTinyIntNull
(
byte
val
)
{
public
static
boolean
isTinyIntNull
(
byte
val
)
{
return
val
==
Byte
.
MIN_VALUE
;
return
val
==
Byte
.
MIN_VALUE
;
}
}
public
static
boolean
isSmallIntNull
(
short
val
)
{
public
static
boolean
isSmallIntNull
(
short
val
)
{
return
val
==
Short
.
MIN_VALUE
;
return
val
==
Short
.
MIN_VALUE
;
}
}
...
@@ -23,19 +23,19 @@ public class NullType {
...
@@ -23,19 +23,19 @@ public class NullType {
public
static
boolean
isIntNull
(
int
val
)
{
public
static
boolean
isIntNull
(
int
val
)
{
return
val
==
Integer
.
MIN_VALUE
;
return
val
==
Integer
.
MIN_VALUE
;
}
}
public
static
boolean
isBigIntNull
(
long
val
)
{
public
static
boolean
isBigIntNull
(
long
val
)
{
return
val
==
Long
.
MIN_VALUE
;
return
val
==
Long
.
MIN_VALUE
;
}
}
public
static
boolean
isFloatNull
(
float
val
)
{
public
static
boolean
isFloatNull
(
float
val
)
{
return
Float
.
isNaN
(
val
);
return
Float
.
isNaN
(
val
);
}
}
public
static
boolean
isDoubleNull
(
double
val
)
{
public
static
boolean
isDoubleNull
(
double
val
)
{
return
Double
.
isNaN
(
val
);
return
Double
.
isNaN
(
val
);
}
}
public
static
boolean
isBinaryNull
(
byte
[]
val
,
int
length
)
{
public
static
boolean
isBinaryNull
(
byte
[]
val
,
int
length
)
{
if
(
length
!=
Byte
.
BYTES
)
{
if
(
length
!=
Byte
.
BYTES
)
{
return
false
;
return
false
;
...
@@ -43,7 +43,7 @@ public class NullType {
...
@@ -43,7 +43,7 @@ public class NullType {
return
val
[
0
]
==
0xFF
;
return
val
[
0
]
==
0xFF
;
}
}
public
static
boolean
isNcharNull
(
byte
[]
val
,
int
length
)
{
public
static
boolean
isNcharNull
(
byte
[]
val
,
int
length
)
{
if
(
length
!=
Integer
.
BYTES
)
{
if
(
length
!=
Integer
.
BYTES
)
{
return
false
;
return
false
;
...
@@ -51,5 +51,41 @@ public class NullType {
...
@@ -51,5 +51,41 @@ public class NullType {
return
(
val
[
0
]
&
val
[
1
]
&
val
[
2
]
&
val
[
3
])
==
0xFF
;
return
(
val
[
0
]
&
val
[
1
]
&
val
[
2
]
&
val
[
3
])
==
0xFF
;
}
}
public
static
byte
getBooleanNull
()
{
return
NullType
.
NULL_BOOL_VAL
;
}
public
static
byte
getTinyintNull
()
{
return
Byte
.
MIN_VALUE
;
}
public
static
int
getIntNull
()
{
return
Integer
.
MIN_VALUE
;
}
public
static
short
getSmallIntNull
()
{
return
Short
.
MIN_VALUE
;
}
public
static
long
getBigIntNull
()
{
return
Long
.
MIN_VALUE
;
}
public
static
int
getFloatNull
()
{
return
0x7FF00000
;
}
public
static
long
getDoubleNull
()
{
return
0x7FFFFF0000000000
L
;
}
public
static
byte
getBinaryNull
()
{
return
(
byte
)
0xFF
;
}
public
static
byte
[]
getNcharNull
()
{
return
new
byte
[]
{(
byte
)
0xFF
,
(
byte
)
0xFF
,
(
byte
)
0xFF
,
(
byte
)
0xFF
};
}
}
}
src/inc/taos.h
浏览文件 @
24f47281
...
@@ -104,8 +104,8 @@ typedef struct TAOS_MULTI_BIND {
...
@@ -104,8 +104,8 @@ typedef struct TAOS_MULTI_BIND {
int
buffer_type
;
int
buffer_type
;
void
*
buffer
;
void
*
buffer
;
uintptr_t
buffer_length
;
uintptr_t
buffer_length
;
uintptr_t
*
length
;
int32_t
*
length
;
int
*
is_null
;
char
*
is_null
;
int
num
;
int
num
;
}
TAOS_MULTI_BIND
;
}
TAOS_MULTI_BIND
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录